1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.util;
17
18 import java.sql.Time;
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.Comparator;
22 import java.util.List;
23 import java.util.ListIterator;
24
25 import org.apache.commons.collections.CollectionUtils;
26 import org.joda.time.DateTime;
27 import org.joda.time.DateTimeZone;
28 import org.joda.time.Interval;
29 import org.joda.time.LocalDateTime;
30 import org.joda.time.LocalTime;
31 import org.kuali.hr.time.calendar.Calendar;
32 import org.kuali.hr.time.calendar.CalendarEntries;
33 import org.kuali.hr.time.flsa.FlsaDay;
34 import org.kuali.hr.time.flsa.FlsaWeek;
35 import org.kuali.hr.time.service.base.TkServiceLocator;
36 import org.kuali.hr.time.timeblock.TimeBlock;
37 import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
38
39 public class TkTimeBlockAggregate {
40 private List<List<TimeBlock>> dayTimeBlockList = new ArrayList<List<TimeBlock>>();
41 private CalendarEntries payCalendarEntry;
42 private Calendar payCalendar;
43
44
45
46
47
48
49
50 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntries payCalendarEntry){
51 this(timeBlocks, payCalendarEntry, TkServiceLocator.getCalendarService().getCalendar(payCalendarEntry.getHrCalendarId()));
52 }
53
54
55
56
57
58
59
60
61 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntries payCalendarEntry, Calendar payCalendar) {
62 this(timeBlocks, payCalendarEntry, payCalendar, false);
63 }
64
65
66
67
68
69
70
71
72
73 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntries payCalendarEntry, Calendar payCalendar, boolean useUserTimeZone) {
74 this.payCalendarEntry = payCalendarEntry;
75 this.payCalendar = payCalendar;
76
77 List<Interval> dayIntervals = null;
78 if (useUserTimeZone) {
79 dayIntervals = TKUtils.getDaySpanForCalendarEntry(payCalendarEntry);
80 } else {
81 dayIntervals = TKUtils.getDaySpanForCalendarEntry(payCalendarEntry, TKUtils.getSystemDateTimeZone());
82 }
83 for(Interval dayInt : dayIntervals){
84 List<TimeBlock> dayTimeBlocks = new ArrayList<TimeBlock>();
85 for(TimeBlock timeBlock : timeBlocks){
86
87
88
89
90
91
92 DateTime beginTime = useUserTimeZone ? timeBlock.getBeginTimeDisplay() : new DateTime(timeBlock.getBeginTimestamp(), TKUtils.getSystemDateTimeZone());
93 DateTime endTime = useUserTimeZone ? timeBlock.getEndTimeDisplay() : new DateTime(timeBlock.getEndTimestamp(), TKUtils.getSystemDateTimeZone());
94 if(dayInt.contains(beginTime)){
95 if(dayInt.contains(endTime) || endTime.compareTo(dayInt.getEnd()) == 0){
96
97 if(beginTime.getHourOfDay() < dayInt.getStart().getHourOfDay()) {
98 timeBlock.setPushBackward(true);
99 }
100
101 dayTimeBlocks.add(timeBlock);
102 }
103 }
104 }
105 dayTimeBlockList.add(dayTimeBlocks);
106 }
107 }
108
109 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntries payCalendarEntry, Calendar payCalendar, boolean useUserTimeZone, List<Interval> dayIntervals) {
110 this.payCalendarEntry = payCalendarEntry;
111 this.payCalendar = payCalendar;
112
113 for(Interval dayInt : dayIntervals){
114 List<TimeBlock> dayTimeBlocks = new ArrayList<TimeBlock>();
115 for(TimeBlock timeBlock : timeBlocks){
116
117
118
119
120
121
122 DateTime beginTime = useUserTimeZone ? timeBlock.getBeginTimeDisplay() : new DateTime(timeBlock.getBeginTimestamp(), TKUtils.getSystemDateTimeZone());
123 DateTime endTime = useUserTimeZone ? timeBlock.getEndTimeDisplay() : new DateTime(timeBlock.getEndTimestamp(), TKUtils.getSystemDateTimeZone());
124 if(dayInt.contains(beginTime)){
125 if(dayInt.contains(endTime) || endTime.compareTo(dayInt.getEnd()) == 0){
126
127 if(beginTime.getHourOfDay() < dayInt.getStart().getHourOfDay()) {
128 timeBlock.setPushBackward(true);
129 }
130
131 dayTimeBlocks.add(timeBlock);
132 }
133 }
134 }
135 dayTimeBlockList.add(dayTimeBlocks);
136 }
137
138 }
139
140
141 public List<TimeBlock> getFlattenedTimeBlockList(){
142 List<TimeBlock> lstTimeBlocks = new ArrayList<TimeBlock>();
143 for(List<TimeBlock> timeBlocks : dayTimeBlockList){
144 lstTimeBlocks.addAll(timeBlocks);
145 }
146
147 Collections.sort(lstTimeBlocks, new Comparator<TimeBlock>() {
148 public int compare(TimeBlock tb1, TimeBlock tb2) {
149 if (tb1 != null && tb2 != null)
150 return tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
151 return 0;
152 }
153 });
154
155 return lstTimeBlocks;
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 public List<List<TimeBlock>> getWeekTimeBlocks(int week){
173 int startIndex = week*7;
174 int endIndex = (week*7)+7;
175 endIndex = endIndex > dayTimeBlockList.size() ? dayTimeBlockList.size() : endIndex;
176
177
178 List<List<TimeBlock>> wList = dayTimeBlockList.subList(startIndex, endIndex);
179 for (List<TimeBlock> dList : wList) {
180 Collections.sort(dList, new Comparator<TimeBlock>() {
181 public int compare(TimeBlock tb1, TimeBlock tb2) {
182 if (tb1 != null && tb2 != null)
183 return tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
184 return 0;
185 }
186 });
187 }
188
189 return wList;
190 }
191
192
193
194
195
196
197
198
199
200 public List<FlsaWeek> getFlsaWeeks(DateTimeZone zone){
201 int flsaDayConstant = payCalendar.getFlsaBeginDayConstant();
202 Time flsaBeginTime = payCalendar.getFlsaBeginTime();
203
204
205
206 LocalTime flsaBeginLocalTime = LocalTime.fromDateFields(flsaBeginTime);
207
208
209
210
211
212 LocalDateTime startLDT = payCalendarEntry.getBeginLocalDateTime();
213
214
215
216 List<FlsaWeek> flsaWeeks = new ArrayList<FlsaWeek>();
217 List<TimeBlock> flatSortedBlockList = getFlattenedTimeBlockList();
218 FlsaWeek currentWeek = new FlsaWeek(flsaDayConstant, flsaBeginLocalTime, LocalTime.fromDateFields(payCalendarEntry.getBeginPeriodDateTime()));
219 FlsaDay flsaDay = new FlsaDay(startLDT, flatSortedBlockList, zone);
220 currentWeek.addFlsaDay(flsaDay);
221 flsaWeeks.add(currentWeek);
222
223 for (int i = 1; i < dayTimeBlockList.size(); i++) {
224 LocalDateTime currentDate = startLDT.plusDays(i);
225 flsaDay = new FlsaDay(currentDate, flatSortedBlockList, zone);
226
227 if (currentDate.getDayOfWeek() == flsaDayConstant) {
228 currentWeek = new FlsaWeek(flsaDayConstant, flsaBeginLocalTime, flsaBeginLocalTime);
229 flsaWeeks.add(currentWeek);
230 }
231
232 currentWeek.addFlsaDay(flsaDay);
233 }
234
235 return flsaWeeks;
236 }
237
238 public List<List<FlsaWeek>> getFlsaWeeks(DateTimeZone zone, String principalId) {
239 List<List<FlsaWeek>> flsaWeeks = new ArrayList<List<FlsaWeek>>();
240
241 List<FlsaWeek> currentWeeks = getFlsaWeeks(zone);
242
243 for (ListIterator<FlsaWeek> weekIterator = currentWeeks.listIterator(); weekIterator.hasNext(); ) {
244 List<FlsaWeek> flsaWeek = new ArrayList<FlsaWeek>();
245
246 int index = weekIterator.nextIndex();
247 FlsaWeek currentWeek = weekIterator.next();
248
249 if (index == 0 && !currentWeek.isFirstWeekFull()) {
250 CalendarEntries previousCalendarEntry = TkServiceLocator.getCalendarEntriesService().getPreviousCalendarEntriesByCalendarId(payCalendar.getHrCalendarId(), payCalendarEntry);
251 if (previousCalendarEntry != null) {
252 TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, previousCalendarEntry.getBeginPeriodDateTime(), previousCalendarEntry.getEndPeriodDateTime());
253 if (timesheetDocumentHeader != null) {
254 List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(timesheetDocumentHeader.getDocumentId());
255 if (CollectionUtils.isNotEmpty(timeBlocks)) {
256 TkTimeBlockAggregate previousAggregate = new TkTimeBlockAggregate(timeBlocks, previousCalendarEntry, payCalendar, true);
257 List<FlsaWeek> previousWeek = previousAggregate.getFlsaWeeks(zone);
258 if (CollectionUtils.isNotEmpty(previousWeek)) {
259 flsaWeek.add(previousWeek.get(previousWeek.size() - 1));
260 }
261 }
262 }
263 }
264 }
265
266 flsaWeek.add(currentWeek);
267
268 if (index == currentWeeks.size() - 1 && !currentWeek.isLastWeekFull()) {
269 CalendarEntries nextCalendarEntry = TkServiceLocator.getCalendarEntriesService().getNextCalendarEntriesByCalendarId(payCalendar.getHrCalendarId(), payCalendarEntry);
270 if (nextCalendarEntry != null) {
271 TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, nextCalendarEntry.getBeginPeriodDateTime(), nextCalendarEntry.getEndPeriodDateTime());
272 if (timesheetDocumentHeader != null) {
273 List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(timesheetDocumentHeader.getDocumentId());
274 if (CollectionUtils.isNotEmpty(timeBlocks)) {
275 TkTimeBlockAggregate nextAggregate = new TkTimeBlockAggregate(timeBlocks, nextCalendarEntry, payCalendar, true);
276 List<FlsaWeek> nextWeek = nextAggregate.getFlsaWeeks(zone);
277 if (CollectionUtils.isNotEmpty(nextWeek)) {
278 flsaWeek.add(nextWeek.get(0));
279 }
280 }
281 }
282 }
283 }
284
285 flsaWeeks.add(flsaWeek);
286 }
287
288 return flsaWeeks;
289 }
290
291
292
293
294 public int numberOfAggregatedWeeks() {
295 int weeks = 0;
296
297 if (this.dayTimeBlockList.size() > 0) {
298 weeks = this.dayTimeBlockList.size() / 7;
299 if (this.dayTimeBlockList.size() % 7 > 0)
300 weeks++;
301 }
302
303 return weeks;
304 }
305
306 public List<List<TimeBlock>> getDayTimeBlockList() {
307 return dayTimeBlockList;
308 }
309
310 public CalendarEntries getPayCalendarEntry() {
311 return payCalendarEntry;
312 }
313
314 public void setPayCalendarEntry(CalendarEntries payCalendarEntry) {
315 this.payCalendarEntry = payCalendarEntry;
316 }
317
318 public Calendar getPayCalendar() {
319 return payCalendar;
320 }
321
322 public void setPayCalendar(Calendar payCalendar) {
323 this.payCalendar = payCalendar;
324 }
325
326 }