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 public 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 = TKUtils.getDaySpanForCalendarEntry(payCalendarEntry);
78 for(Interval dayInt : dayIntervals){
79 List<TimeBlock> dayTimeBlocks = new ArrayList<TimeBlock>();
80 for(TimeBlock timeBlock : timeBlocks){
81
82
83
84
85
86
87 DateTime beginTime = useUserTimeZone ? timeBlock.getBeginTimeDisplay() : new DateTime(timeBlock.getBeginTimestamp(), TKUtils.getSystemDateTimeZone());
88 DateTime endTime = useUserTimeZone ? timeBlock.getEndTimeDisplay() : new DateTime(timeBlock.getEndTimestamp(), TKUtils.getSystemDateTimeZone());
89 if(dayInt.contains(beginTime)){
90 if(dayInt.contains(endTime) || endTime.compareTo(dayInt.getEnd()) == 0){
91
92 if(beginTime.getHourOfDay() < dayInt.getStart().getHourOfDay()) {
93 timeBlock.setPushBackward(true);
94 }
95
96 dayTimeBlocks.add(timeBlock);
97 }
98 }
99 }
100 dayTimeBlockList.add(dayTimeBlocks);
101 }
102 }
103
104 public TkTimeBlockAggregate(List<TimeBlock> timeBlocks, CalendarEntries payCalendarEntry, Calendar payCalendar, boolean useUserTimeZone, List<Interval> dayIntervals) {
105 this.payCalendarEntry = payCalendarEntry;
106 this.payCalendar = payCalendar;
107
108 for(Interval dayInt : dayIntervals){
109 List<TimeBlock> dayTimeBlocks = new ArrayList<TimeBlock>();
110 for(TimeBlock timeBlock : timeBlocks){
111
112
113
114
115
116
117 DateTime beginTime = useUserTimeZone ? timeBlock.getBeginTimeDisplay() : new DateTime(timeBlock.getBeginTimestamp(), TKUtils.getSystemDateTimeZone());
118 DateTime endTime = useUserTimeZone ? timeBlock.getEndTimeDisplay() : new DateTime(timeBlock.getEndTimestamp(), TKUtils.getSystemDateTimeZone());
119 if(dayInt.contains(beginTime)){
120 if(dayInt.contains(endTime) || endTime.compareTo(dayInt.getEnd()) == 0){
121
122 if(beginTime.getHourOfDay() < dayInt.getStart().getHourOfDay()) {
123 timeBlock.setPushBackward(true);
124 }
125
126 dayTimeBlocks.add(timeBlock);
127 }
128 }
129 }
130 dayTimeBlockList.add(dayTimeBlocks);
131 }
132
133 }
134
135
136 public List<TimeBlock> getFlattenedTimeBlockList(){
137 List<TimeBlock> lstTimeBlocks = new ArrayList<TimeBlock>();
138 for(List<TimeBlock> timeBlocks : dayTimeBlockList){
139 lstTimeBlocks.addAll(timeBlocks);
140 }
141
142 Collections.sort(lstTimeBlocks, new Comparator<TimeBlock>() {
143 public int compare(TimeBlock tb1, TimeBlock tb2) {
144 if (tb1 != null && tb2 != null)
145 return tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
146 return 0;
147 }
148 });
149
150 return lstTimeBlocks;
151 }
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 public List<List<TimeBlock>> getWeekTimeBlocks(int week){
168 int startIndex = week*7;
169 int endIndex = (week*7)+7;
170 endIndex = endIndex > dayTimeBlockList.size() ? dayTimeBlockList.size() : endIndex;
171
172
173 List<List<TimeBlock>> wList = dayTimeBlockList.subList(startIndex, endIndex);
174 for (List<TimeBlock> dList : wList) {
175 Collections.sort(dList, new Comparator<TimeBlock>() {
176 public int compare(TimeBlock tb1, TimeBlock tb2) {
177 if (tb1 != null && tb2 != null)
178 return tb1.getBeginTimestamp().compareTo(tb2.getBeginTimestamp());
179 return 0;
180 }
181 });
182 }
183
184 return wList;
185 }
186
187
188
189
190
191
192
193
194
195 public List<FlsaWeek> getFlsaWeeks(DateTimeZone zone){
196 int flsaDayConstant = payCalendar.getFlsaBeginDayConstant();
197 Time flsaBeginTime = payCalendar.getFlsaBeginTime();
198
199
200
201 LocalTime flsaBeginLocalTime = LocalTime.fromDateFields(flsaBeginTime);
202
203
204
205
206
207 LocalDateTime startLDT = payCalendarEntry.getBeginLocalDateTime();
208
209
210
211 List<FlsaWeek> flsaWeeks = new ArrayList<FlsaWeek>();
212 List<TimeBlock> flatSortedBlockList = getFlattenedTimeBlockList();
213 FlsaWeek currentWeek = new FlsaWeek(flsaDayConstant, flsaBeginLocalTime, LocalTime.fromDateFields(payCalendarEntry.getBeginPeriodDateTime()));
214 FlsaDay flsaDay = new FlsaDay(startLDT, flatSortedBlockList, zone);
215 currentWeek.addFlsaDay(flsaDay);
216 flsaWeeks.add(currentWeek);
217
218 for (int i = 1; i < dayTimeBlockList.size(); i++) {
219 LocalDateTime currentDate = startLDT.plusDays(i);
220 flsaDay = new FlsaDay(currentDate, flatSortedBlockList, zone);
221
222 if (currentDate.getDayOfWeek() == flsaDayConstant) {
223 currentWeek = new FlsaWeek(flsaDayConstant, flsaBeginLocalTime, flsaBeginLocalTime);
224 flsaWeeks.add(currentWeek);
225 }
226
227 currentWeek.addFlsaDay(flsaDay);
228 }
229
230 return flsaWeeks;
231 }
232
233 public List<List<FlsaWeek>> getFlsaWeeks(DateTimeZone zone, String principalId) {
234 List<List<FlsaWeek>> flsaWeeks = new ArrayList<List<FlsaWeek>>();
235
236 List<FlsaWeek> currentWeeks = getFlsaWeeks(zone);
237
238 for (ListIterator<FlsaWeek> weekIterator = currentWeeks.listIterator(); weekIterator.hasNext(); ) {
239 List<FlsaWeek> flsaWeek = new ArrayList<FlsaWeek>();
240
241 int index = weekIterator.nextIndex();
242 FlsaWeek currentWeek = weekIterator.next();
243
244 if (index == 0 && !currentWeek.isFirstWeekFull()) {
245 CalendarEntries previousCalendarEntry = TkServiceLocator.getCalendarEntriesService().getPreviousCalendarEntriesByCalendarId(payCalendar.getHrCalendarId(), payCalendarEntry);
246 if (previousCalendarEntry != null) {
247 TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, previousCalendarEntry.getBeginPeriodDateTime(), previousCalendarEntry.getEndPeriodDateTime());
248 if (timesheetDocumentHeader != null) {
249 List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(timesheetDocumentHeader.getDocumentId());
250 if (CollectionUtils.isNotEmpty(timeBlocks)) {
251 TkTimeBlockAggregate previousAggregate = new TkTimeBlockAggregate(timeBlocks, previousCalendarEntry, payCalendar, true);
252 List<FlsaWeek> previousWeek = previousAggregate.getFlsaWeeks(zone);
253 if (CollectionUtils.isNotEmpty(previousWeek)) {
254 flsaWeek.add(previousWeek.get(previousWeek.size() - 1));
255 }
256 }
257 }
258 }
259 }
260
261 flsaWeek.add(currentWeek);
262
263 if (index == currentWeeks.size() - 1 && !currentWeek.isLastWeekFull()) {
264 CalendarEntries nextCalendarEntry = TkServiceLocator.getCalendarEntriesService().getNextCalendarEntriesByCalendarId(payCalendar.getHrCalendarId(), payCalendarEntry);
265 if (nextCalendarEntry != null) {
266 TimesheetDocumentHeader timesheetDocumentHeader = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeader(principalId, nextCalendarEntry.getBeginPeriodDateTime(), nextCalendarEntry.getEndPeriodDateTime());
267 if (timesheetDocumentHeader != null) {
268 List<TimeBlock> timeBlocks = TkServiceLocator.getTimeBlockService().getTimeBlocks(timesheetDocumentHeader.getDocumentId());
269 if (CollectionUtils.isNotEmpty(timeBlocks)) {
270 TkTimeBlockAggregate nextAggregate = new TkTimeBlockAggregate(timeBlocks, nextCalendarEntry, payCalendar, true);
271 List<FlsaWeek> nextWeek = nextAggregate.getFlsaWeeks(zone);
272 if (CollectionUtils.isNotEmpty(nextWeek)) {
273 flsaWeek.add(nextWeek.get(0));
274 }
275 }
276 }
277 }
278 }
279
280 flsaWeeks.add(flsaWeek);
281 }
282
283 return flsaWeeks;
284 }
285
286
287
288
289 public int numberOfAggregatedWeeks() {
290 int weeks = 0;
291
292 if (this.dayTimeBlockList.size() > 0) {
293 weeks = this.dayTimeBlockList.size() / 7;
294 if (this.dayTimeBlockList.size() % 7 > 0)
295 weeks++;
296 }
297
298 return weeks;
299 }
300
301 public List<List<TimeBlock>> getDayTimeBlockList() {
302 return dayTimeBlockList;
303 }
304
305 public CalendarEntries getPayCalendarEntry() {
306 return payCalendarEntry;
307 }
308
309 public void setPayCalendarEntry(CalendarEntries payCalendarEntry) {
310 this.payCalendarEntry = payCalendarEntry;
311 }
312
313 public Calendar getPayCalendar() {
314 return payCalendar;
315 }
316
317 public void setPayCalendar(Calendar payCalendar) {
318 this.payCalendar = payCalendar;
319 }
320
321 }