1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.tklm.time.util;
17
18 import java.math.BigDecimal;
19 import java.sql.Time;
20 import java.sql.Timestamp;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.List;
25 import java.util.ListIterator;
26
27 import org.apache.commons.collections.CollectionUtils;
28 import org.joda.time.DateTime;
29 import org.joda.time.DateTimeConstants;
30 import org.joda.time.DateTimeZone;
31 import org.joda.time.Interval;
32 import org.joda.time.LocalDateTime;
33 import org.joda.time.LocalTime;
34 import org.kuali.kpme.core.assignment.Assignment;
35 import org.kuali.kpme.core.calendar.Calendar;
36 import org.kuali.kpme.core.calendar.entry.CalendarEntry;
37 import org.kuali.kpme.core.earncode.EarnCode;
38 import org.kuali.kpme.core.service.HrServiceLocator;
39 import org.kuali.kpme.core.util.TKUtils;
40 import org.kuali.kpme.tklm.api.time.util.TkTimeBlockAggregateContract;
41 import org.kuali.kpme.tklm.leave.block.LeaveBlock;
42 import org.kuali.kpme.tklm.leave.block.LeaveBlockAggregate;
43 import org.kuali.kpme.tklm.leave.service.LmServiceLocator;
44 import org.kuali.kpme.tklm.time.flsa.FlsaDay;
45 import org.kuali.kpme.tklm.time.flsa.FlsaWeek;
46 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
47 import org.kuali.kpme.tklm.time.timeblock.TimeBlock;
48 import org.kuali.kpme.tklm.time.timehourdetail.TimeHourDetail;
49 import org.kuali.kpme.tklm.time.timesheet.TimesheetDocument;
50 import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
51
52 public class TkTimeBlockAggregate implements TkTimeBlockAggregateContract {
53 private List<List<TimeBlock>> dayTimeBlockList = new ArrayList<List<TimeBlock>>();
54 private List<List<LeaveBlock>> dayLeaveBlockList = new ArrayList<List<LeaveBlock>>();
55 private CalendarEntry payCalendarEntry;
56 private Calendar payCalendar;
57
58
59
60
61
62
63
64 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntry payCalendarEntry){
65 this(timeBlocks, payCalendarEntry, HrServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId()));
66 }
67
68
69
70
71
72
73
74
75 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntry payCalendarEntry, Calendar payCalendar) {
76 this(timeBlocks, payCalendarEntry, payCalendar, false);
77 }
78
79
80
81
82
83
84
85
86
87 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntry payCalendarEntry, Calendar payCalendar, boolean useUserTimeZone) {
88 this(timeBlocks, payCalendarEntry, payCalendar, useUserTimeZone,
89 useUserTimeZone ? TKUtils.getDaySpanForCalendarEntry(payCalendarEntry) : TKUtils.getDaySpanForCalendarEntry(payCalendarEntry, TKUtils.getSystemDateTimeZone()));
90 }
91
92 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntry payCalendarEntry, Calendar payCalendar, boolean useUserTimeZone, List<Interval> dayIntervals) {
93 this.payCalendarEntry = payCalendarEntry;
94 this.payCalendar = payCalendar;
95
96 for(Interval dayInt : dayIntervals){
97 List<TimeBlock> dayTimeBlocks = new ArrayList<TimeBlock>();
98 for(TimeBlock timeBlock : timeBlocks){
99
100
101
102
103
104
105 DateTime beginTime = useUserTimeZone ? timeBlock.getBeginTimeDisplay() : timeBlock.getBeginDateTime().withZone(TKUtils.getSystemDateTimeZone());
106 DateTime endTime = useUserTimeZone ? timeBlock.getEndTimeDisplay() : timeBlock.getEndDateTime().withZone(TKUtils.getSystemDateTimeZone());
107 if(dayInt.contains(beginTime)){
108 if(dayInt.contains(endTime) || endTime.compareTo(dayInt.getEnd()) == 0){
109
110 if(beginTime.getHourOfDay() < dayInt.getStart().getHourOfDay()) {
111 timeBlock.setPushBackward(true);
112 }
113
114 dayTimeBlocks.add(timeBlock);
115 }
116 }
117 }
118 dayTimeBlockList.add(dayTimeBlocks);
119 }
120 }
121
122
123
124
125
126
127
128
129 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, List<LeaveBlock> leaveBlocks, CalendarEntry payCalendarEntry){
130 this(timeBlocks, leaveBlocks, payCalendarEntry, HrServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId()));
131 }
132
133
134
135
136
137
138
139
140
141 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, List<LeaveBlock> leaveBlocks, CalendarEntry payCalendarEntry, Calendar payCalendar) {
142 this(timeBlocks, leaveBlocks, payCalendarEntry, payCalendar, false);
143 }
144
145
146
147
148
149
150
151
152
153 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, List<LeaveBlock> leaveBlocks, CalendarEntry payCalendarEntry, Calendar payCalendar, boolean useUserTimeZone) {
154 this(timeBlocks, leaveBlocks, payCalendarEntry, payCalendar, useUserTimeZone,
155 useUserTimeZone ? TKUtils.getDaySpanForCalendarEntry(payCalendarEntry) : TKUtils.getDaySpanForCalendarEntry(payCalendarEntry, TKUtils.getSystemDateTimeZone()));
156 }
157
158 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, List<LeaveBlock> leaveBlocks, CalendarEntry payCalendarEntry, Calendar payCalendar, boolean useUserTimeZone, List<Interval> dayIntervals) {
159 this.payCalendarEntry = payCalendarEntry;
160 this.payCalendar = payCalendar;
161
162 for(Interval dayInt : dayIntervals){
163 List<TimeBlock> dayTimeBlocks = new ArrayList<TimeBlock>();
164 for(TimeBlock timeBlock : timeBlocks){
165
166
167
168
169
170
171 DateTime beginTime = useUserTimeZone ? timeBlock.getBeginTimeDisplay() : new DateTime(timeBlock.getBeginTimestamp(), TKUtils.getSystemDateTimeZone());
172 DateTime endTime = useUserTimeZone ? timeBlock.getEndTimeDisplay() : new DateTime(timeBlock.getEndTimestamp(), TKUtils.getSystemDateTimeZone());
173 if(dayInt.contains(beginTime)){
174 if(dayInt.contains(endTime) || endTime.compareTo(dayInt.getEnd()) == 0){
175
176 if(beginTime.getHourOfDay() < dayInt.getStart().getHourOfDay()) {
177 timeBlock.setPushBackward(true);
178 }
179
180 dayTimeBlocks.add(timeBlock);
181 }
182 }
183 }
184 dayTimeBlockList.add(dayTimeBlocks);
185
186 List<LeaveBlock> dayLeaveBlocks = new ArrayList<LeaveBlock>();
187 for(LeaveBlock leaveBlock : leaveBlocks){
188
189
190
191
192
193
194 DateTimeZone dateTimeZone = HrServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
195 DateTime beginTime = new DateTime(leaveBlock.getLeaveDate(), useUserTimeZone ? dateTimeZone : TKUtils.getSystemDateTimeZone());
196 DateTime endTime = new DateTime(leaveBlock.getLeaveDate(), useUserTimeZone ? dateTimeZone : TKUtils.getSystemDateTimeZone());
197 if(dayInt.contains(beginTime)){
198 if(dayInt.contains(endTime) || endTime.compareTo(dayInt.getEnd()) == 0){
199 dayLeaveBlocks.add(leaveBlock);
200 }
201 }
202 }
203 dayLeaveBlockList.add(dayLeaveBlocks);
204 }
205 }
206
207 public List<TimeBlock> getFlattenedTimeBlockList(){
208 List<TimeBlock> lstTimeBlocks = new ArrayList<TimeBlock>();
209 for(List<TimeBlock> timeBlocks : dayTimeBlockList){
210 lstTimeBlocks.addAll(timeBlocks);
211 }
212
213 Collections.sort(lstTimeBlocks, new Comparator<TimeBlock>() {
214 public int compare(TimeBlock tb1, TimeBlock tb2) {
215 if (tb1 != null && tb2 != null)
216 return tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
217 return 0;
218 }
219 });
220
221 return lstTimeBlocks;
222 }
223
224 public List<LeaveBlock> getFlattenedLeaveBlockList(){
225 List<LeaveBlock> lstLeaveBlocks = new ArrayList<LeaveBlock>();
226 for(List<LeaveBlock> leaveBlocks : dayLeaveBlockList){
227 lstLeaveBlocks.addAll(leaveBlocks);
228 }
229
230 Collections.sort(lstLeaveBlocks, new Comparator<LeaveBlock>() {
231 public int compare(LeaveBlock lb1, LeaveBlock lb2) {
232 if (lb1 != null && lb2 != null)
233 return lb1.getLeaveDate().compareTo(lb2.getLeaveDate());
234 return 0;
235 }
236 });
237
238 return lstLeaveBlocks;
239 }
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 public List<List<TimeBlock>> getWeekTimeBlocks(int week){
256 int startIndex = week*7;
257 int endIndex = (week*7)+7;
258 endIndex = endIndex > dayTimeBlockList.size() ? dayTimeBlockList.size() : endIndex;
259
260
261 List<List<TimeBlock>> wList = dayTimeBlockList.subList(startIndex, endIndex);
262 for (List<TimeBlock> dList : wList) {
263 Collections.sort(dList, new Comparator<TimeBlock>() {
264 public int compare(TimeBlock tb1, TimeBlock tb2) {
265 if (tb1 != null && tb2 != null)
266 return tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
267 return 0;
268 }
269 });
270 }
271
272 return wList;
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 public List<List<LeaveBlock>> getWeekLeaveBlocks(int week){
290 int startIndex = week*7;
291 int endIndex = (week*7)+7;
292 endIndex = endIndex > dayLeaveBlockList.size() ? dayLeaveBlockList.size() : endIndex;
293
294
295 List<List<LeaveBlock>> wList = dayLeaveBlockList.subList(startIndex, endIndex);
296 for (List<LeaveBlock> dList : wList) {
297 Collections.sort(dList, new Comparator<LeaveBlock>() {
298 public int compare(LeaveBlock lb1, LeaveBlock lb2) {
299 if (lb1 != null && lb2 != null)
300 return lb1.getLeaveDate().compareTo(lb2.getLeaveDate());
301 return 0;
302 }
303 });
304 }
305
306 return wList;
307 }
308
309
310
311
312
313
314
315
316
317 public List<FlsaWeek> getFlsaWeeks(DateTimeZone zone, int flsaDayConstant, boolean isFlsaDayPassed){
318 if(!isFlsaDayPassed) {
319 flsaDayConstant = payCalendar.getFlsaBeginDayConstant();
320 }
321
322 Time flsaBeginTime = payCalendar.getFlsaBeginTime();
323
324
325
326 LocalTime flsaBeginLocalTime = LocalTime.fromDateFields(flsaBeginTime);
327
328
329
330
331
332 LocalDateTime startLDT = payCalendarEntry.getBeginPeriodLocalDateTime();
333
334 List<FlsaWeek> flsaWeeks = new ArrayList<FlsaWeek>();
335 List<TimeBlock> flattenedTimeBlocks = getFlattenedTimeBlockList();
336 List<LeaveBlock> flattenedLeaveBlocks = getFlattenedLeaveBlockList();
337 FlsaWeek currentWeek = new FlsaWeek(flsaDayConstant, flsaBeginLocalTime, payCalendarEntry.getBeginPeriodFullDateTime().toLocalTime());
338 FlsaDay flsaDay = new FlsaDay(startLDT, flattenedTimeBlocks, flattenedLeaveBlocks, zone);
339 currentWeek.addFlsaDay(flsaDay);
340 flsaWeeks.add(currentWeek);
341
342 for (int i = 1; i < dayTimeBlockList.size(); i++) {
343 LocalDateTime currentDate = startLDT.plusDays(i);
344 flsaDay = new FlsaDay(currentDate, flattenedTimeBlocks, flattenedLeaveBlocks, zone);
345
346 if (currentDate.getDayOfWeek() == flsaDayConstant) {
347 currentWeek = new FlsaWeek(flsaDayConstant, flsaBeginLocalTime, flsaBeginLocalTime);
348 flsaWeeks.add(currentWeek);
349 }
350
351 currentWeek.addFlsaDay(flsaDay);
352 }
353
354 return flsaWeeks;
355 }
356
357 public List<List<FlsaWeek>> getFlsaWeeks(DateTimeZone zone, String principalId) {
358 List<List<FlsaWeek>> flsaWeeks = new ArrayList<List<FlsaWeek>>();
359
360 List<FlsaWeek> currentWeeks = getFlsaWeeks(zone, 0, false);
361
362 for (ListIterator<FlsaWeek> weekIterator = currentWeeks.listIterator(); weekIterator.hasNext(); ) {
363 List<FlsaWeek> flsaWeek = new ArrayList<FlsaWeek>();
364
365 int index = weekIterator.nextIndex();
366 FlsaWeek currentWeek = weekIterator.next();
367
368 if (index == 0 && !currentWeek.isFirstWeekFull()) {
369 CalendarEntry previousCalendarEntry = HrServiceLocator.getCalendarEntryService().getPreviousCalendarEntryByCalendarId(payCalendar.getHrCalendarId(), payCalendarEntry);
370 if (previousCalendarEntry != null) {
371 TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, previousCalendarEntry.getBeginPeriodFullDateTime(), previousCalendarEntry.getEndPeriodFullDateTime());
372 if (timesheetDocumentHeader != null) {
373 TimesheetDocument timesheetDocument = TkServiceLocator.getTimesheetService().getTimesheetDocument(timesheetDocumentHeader.getDocumentId());
374 List<String> assignmentKeys = new ArrayList<String>();
375 for(Assignment assignment : timesheetDocument.getAssignments()) {
376 assignmentKeys.add(assignment.getAssignmentKey());
377 }
378
379 List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(timesheetDocumentHeader.getDocumentId());
380 List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksForTimeCalendar(principalId, previousCalendarEntry.getBeginPeriodFullDateTime().toLocalDate(), previousCalendarEntry.getEndPeriodFullDateTime().toLocalDate(), assignmentKeys);
381 if (CollectionUtils.isNotEmpty(timeBlocks)) {
382 TkTimeBlockAggregate previousAggregate = new TkTimeBlockAggregate(timeBlocks, leaveBlocks, previousCalendarEntry, payCalendar, true);
383 List<FlsaWeek> previousWeek = previousAggregate.getFlsaWeeks(zone, 0, false);
384 if (CollectionUtils.isNotEmpty(previousWeek)) {
385 flsaWeek.add(previousWeek.get(previousWeek.size() - 1));
386 }
387 }
388 }
389 }
390 }
391
392 flsaWeek.add(currentWeek);
393
394 if (index == currentWeeks.size() - 1 && !currentWeek.isLastWeekFull()) {
395 CalendarEntry nextCalendarEntry = HrServiceLocator.getCalendarEntryService().getNextCalendarEntryByCalendarId(payCalendar.getHrCalendarId(), payCalendarEntry);
396 if (nextCalendarEntry != null) {
397 TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, nextCalendarEntry.getBeginPeriodFullDateTime(), nextCalendarEntry.getEndPeriodFullDateTime());
398 if (timesheetDocumentHeader != null) {
399 TimesheetDocument timesheetDocument = TkServiceLocator.getTimesheetService().getTimesheetDocument(timesheetDocumentHeader.getDocumentId());
400 List<String> assignmentKeys = new ArrayList<String>();
401 for(Assignment assignment : timesheetDocument.getAssignments()) {
402 assignmentKeys.add(assignment.getAssignmentKey());
403 }
404
405 List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(timesheetDocumentHeader.getDocumentId());
406 List<LeaveBlock> leaveBlocks = LmServiceLocator.getLeaveBlockService().getLeaveBlocksForTimeCalendar(principalId, nextCalendarEntry.getBeginPeriodFullDateTime().toLocalDate(), nextCalendarEntry.getEndPeriodFullDateTime().toLocalDate(), assignmentKeys);
407 if (CollectionUtils.isNotEmpty(timeBlocks)) {
408 TkTimeBlockAggregate nextAggregate = new TkTimeBlockAggregate(timeBlocks, leaveBlocks, nextCalendarEntry, payCalendar, true);
409 List<FlsaWeek> nextWeek = nextAggregate.getFlsaWeeks(zone, 0, false);
410 if (CollectionUtils.isNotEmpty(nextWeek)) {
411 flsaWeek.add(nextWeek.get(0));
412 }
413 }
414 }
415 }
416 }
417
418 flsaWeeks.add(flsaWeek);
419 }
420
421 return flsaWeeks;
422 }
423
424
425
426
427 public int numberOfAggregatedWeeks() {
428 int weeks = 0;
429
430 if (this.dayTimeBlockList.size() > 0) {
431 weeks = this.dayTimeBlockList.size() / 7;
432 if (this.dayTimeBlockList.size() % 7 > 0)
433 weeks++;
434 }
435
436 return weeks;
437 }
438
439 public List<List<TimeBlock>> getDayTimeBlockList() {
440 return dayTimeBlockList;
441 }
442
443 public List<List<LeaveBlock>> getDayLeaveBlockList() {
444 return dayLeaveBlockList;
445 }
446
447 public CalendarEntry getPayCalendarEntry() {
448 return payCalendarEntry;
449 }
450
451 public void setPayCalendarEntry(CalendarEntry payCalendarEntry) {
452 this.payCalendarEntry = payCalendarEntry;
453 }
454
455 public Calendar getPayCalendar() {
456 return payCalendar;
457 }
458
459 public void setPayCalendar(Calendar payCalendar) {
460 this.payCalendar = payCalendar;
461 }
462
463
464 public static TkTimeBlockAggregate combineTimeAndLeaveAggregates(TkTimeBlockAggregate tbAggregate, LeaveBlockAggregate lbAggregate) {
465 if (tbAggregate != null
466 && lbAggregate != null
467 && tbAggregate.getDayTimeBlockList().size() == lbAggregate.getDayLeaveBlockList().size()) {
468 for (int i = 0; i < tbAggregate.getDayTimeBlockList().size(); i++) {
469 List<LeaveBlock> leaveBlocks = lbAggregate.getDayLeaveBlockList().get(i);
470 if (CollectionUtils.isNotEmpty(leaveBlocks)) {
471 for (LeaveBlock lb : leaveBlocks) {
472
473
474 TimeBlock timeBlock = new TimeBlock();
475 timeBlock.setHours(lb.getLeaveAmount().negate());
476 timeBlock.setBeginTimestamp(new Timestamp(lb.getLeaveDate().getTime()));
477 timeBlock.setEndTimestamp(new Timestamp(new DateTime(lb.getLeaveDate()).plusMinutes(timeBlock.getHours().intValue()).getMillis()));
478 timeBlock.setAssignmentKey(lb.getAssignmentKey());
479 timeBlock.setJobNumber(lb.getJobNumber());
480 timeBlock.setWorkArea(lb.getWorkArea());
481 timeBlock.setTask(lb.getTask());
482 timeBlock.setEarnCode(lb.getEarnCode());
483
484 EarnCode earnCodeObj = HrServiceLocator.getEarnCodeService().getEarnCode(lb.getEarnCode(), lb.getLeaveLocalDate());
485 if(earnCodeObj != null) {
486 timeBlock.setEarnCodeType(earnCodeObj.getEarnCodeType());
487 }
488 timeBlock.setPrincipalId(lb.getPrincipalId());
489 timeBlock.setWorkArea(lb.getWorkArea());
490 TimeHourDetail timeHourDetail = new TimeHourDetail();
491 timeHourDetail.setEarnCode(timeBlock.getEarnCode());
492 timeHourDetail.setHours(timeBlock.getHours());
493 timeHourDetail.setAmount(BigDecimal.ZERO);
494 timeBlock.addTimeHourDetail(timeHourDetail);
495 tbAggregate.getDayTimeBlockList().get(i).add(timeBlock);
496 }
497 }
498
499 }
500 }
501 return tbAggregate;
502 }
503
504 }