1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.timesummary.service;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.joda.time.DateTimeFieldType;
20 import org.joda.time.LocalDateTime;
21 import org.kuali.hr.job.Job;
22 import org.kuali.hr.time.assignment.Assignment;
23 import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
24 import org.kuali.hr.time.calendar.Calendar;
25 import org.kuali.hr.time.calendar.CalendarEntries;
26 import org.kuali.hr.time.earncode.EarnCode;
27 import org.kuali.hr.time.earngroup.EarnGroup;
28 import org.kuali.hr.time.flsa.FlsaDay;
29 import org.kuali.hr.time.flsa.FlsaWeek;
30 import org.kuali.hr.time.service.base.TkServiceLocator;
31 import org.kuali.hr.time.timeblock.TimeBlock;
32 import org.kuali.hr.time.timeblock.TimeHourDetail;
33 import org.kuali.hr.time.timesheet.TimesheetDocument;
34 import org.kuali.hr.time.timesummary.AssignmentRow;
35 import org.kuali.hr.time.timesummary.EarnCodeSection;
36 import org.kuali.hr.time.timesummary.EarnGroupSection;
37 import org.kuali.hr.time.timesummary.TimeSummary;
38 import org.kuali.hr.time.util.TKUtils;
39 import org.kuali.hr.time.util.TkConstants;
40 import org.kuali.hr.time.util.TkTimeBlockAggregate;
41 import org.kuali.hr.time.workarea.WorkArea;
42
43 import java.math.BigDecimal;
44 import java.util.*;
45
46 public class TimeSummaryServiceImpl implements TimeSummaryService {
47 private static final String OTHER_EARN_GROUP = "Other";
48
49 @Override
50 public TimeSummary getTimeSummary(TimesheetDocument timesheetDocument) {
51 TimeSummary timeSummary = new TimeSummary();
52
53 if(timesheetDocument.getTimeBlocks() == null) {
54 return timeSummary;
55 }
56
57 List<Boolean> dayArrangements = new ArrayList<Boolean>();
58
59 timeSummary.setSummaryHeader(getHeaderForSummary(timesheetDocument.getPayCalendarEntry(), dayArrangements));
60 TkTimeBlockAggregate tkTimeBlockAggregate = new TkTimeBlockAggregate(timesheetDocument.getTimeBlocks(), timesheetDocument.getPayCalendarEntry(), TkServiceLocator.getCalendarService().getCalendar(timesheetDocument.getPayCalendarEntry().getHrCalendarId()), true);
61 timeSummary.setWorkedHours(getWorkedHours(tkTimeBlockAggregate));
62
63 List<EarnGroupSection> earnGroupSections = getEarnGroupSections(tkTimeBlockAggregate, timeSummary.getSummaryHeader().size()+1,
64 dayArrangements, timesheetDocument.getAsOfDate(), timesheetDocument.getDocEndDate());
65 timeSummary.setSections(earnGroupSections);
66
67 return timeSummary;
68 }
69
70
71
72
73
74
75
76
77
78 public List<EarnGroupSection> getEarnGroupSections(TkTimeBlockAggregate tkTimeBlockAggregate, int numEntries, List<Boolean> dayArrangements, Date asOfDate , Date docEndDate){
79 List<EarnGroupSection> earnGroupSections = new ArrayList<EarnGroupSection>();
80 List<FlsaWeek> flsaWeeks = tkTimeBlockAggregate.getFlsaWeeks(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback());
81 Map<String, EarnCodeSection> earnCodeToEarnCodeSection = new HashMap<String, EarnCodeSection>();
82 Map<String, EarnGroupSection> earnGroupToEarnGroupSection = new HashMap<String, EarnGroupSection>();
83
84 int dayCount = 0;
85
86
87
88 List<FlsaWeek> trimmedFlsaWeeks = new ArrayList<FlsaWeek>();
89 for(FlsaWeek flsaWeek : flsaWeeks){
90 if(flsaWeek.getFlsaDays().size() > 0){
91 trimmedFlsaWeeks.add(flsaWeek);
92 }
93 }
94
95
96
97 for(FlsaWeek flsaWeek : trimmedFlsaWeeks){
98 int weekSize = 0;
99 List<FlsaDay> flsaDays = flsaWeek.getFlsaDays();
100 for(FlsaDay flsaDay : flsaDays){
101 Map<String, List<TimeBlock>> earnCodeToTimeBlocks = flsaDay.getEarnCodeToTimeBlocks();
102
103 for(String earnCode : earnCodeToTimeBlocks.keySet()){
104 for(TimeBlock timeBlock : earnCodeToTimeBlocks.get(earnCode)){
105 for(TimeHourDetail thd : timeBlock.getTimeHourDetails()){
106 if(StringUtils.equals(TkConstants.LUNCH_EARN_CODE, thd.getEarnCode())){
107 continue;
108 }
109 EarnCodeSection earnCodeSection = earnCodeToEarnCodeSection.get(thd.getEarnCode());
110 if(earnCodeSection == null){
111 earnCodeSection = new EarnCodeSection();
112 earnCodeSection.setEarnCode(thd.getEarnCode());
113 EarnCode earnCodeObj = TkServiceLocator.getEarnCodeService().getEarnCode(thd.getEarnCode(), TKUtils.getTimelessDate(asOfDate));
114 earnCodeSection.setDescription(earnCodeObj.getDescription());
115 earnCodeSection.setIsAmountEarnCode((earnCodeObj.getRecordMethod()!= null && earnCodeObj.getRecordMethod().equalsIgnoreCase(TkConstants.EARN_CODE_AMOUNT)) ? true : false);
116 for(int i = 0;i<(numEntries-1);i++){
117 earnCodeSection.getTotals().add(BigDecimal.ZERO);
118 }
119
120 earnCodeToEarnCodeSection.put(thd.getEarnCode(), earnCodeSection);
121 }
122 String assignKey = timeBlock.getAssignmentKey();
123 AssignmentRow assignRow = earnCodeSection.getAssignKeyToAssignmentRowMap().get(assignKey);
124 if(assignRow == null){
125 assignRow = new AssignmentRow();
126 assignRow.setAssignmentKey(assignKey);
127 AssignmentDescriptionKey assignmentKey = TkServiceLocator.getAssignmentService().getAssignmentDescriptionKey(assignKey);
128 Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(timeBlock.getPrincipalId(), assignmentKey, TKUtils.getTimelessDate(asOfDate));
129
130 if(assignment == null) {
131 assignment = TkServiceLocator.getAssignmentService().getAssignment(timeBlock.getPrincipalId(), assignmentKey, TKUtils.getTimelessDate(docEndDate));
132 }
133
134 if(assignment != null){
135 if(assignment.getJob() == null){
136 Job aJob = TkServiceLocator.getJobService().getJob(assignment.getPrincipalId(),assignment.getJobNumber(),TKUtils.getTimelessDate(assignment.getEffectiveDate()));
137 assignment.setJob(aJob);
138 }
139 if(assignment.getWorkAreaObj() == null){
140 WorkArea aWorkArea = TkServiceLocator.getWorkAreaService().getWorkArea(assignment.getWorkArea(), TKUtils.getTimelessDate(assignment.getEffectiveDate()));
141 assignment.setWorkAreaObj(aWorkArea);
142 }
143 assignRow.setDescr(assignment.getAssignmentDescription());
144 }
145 for(int i = 0;i<(numEntries-1);i++){
146 assignRow.getTotal().add(BigDecimal.ZERO);
147 assignRow.getAmount().add(BigDecimal.ZERO);
148 }
149 assignRow.setEarnCodeSection(earnCodeSection);
150 earnCodeSection.addAssignmentRow(assignRow);
151 }
152 assignRow.addToTotal(dayCount, thd.getHours());
153 assignRow.addToAmount(dayCount, thd.getAmount());
154 }
155 }
156 }
157 dayCount++;
158 weekSize++;
159 }
160
161 for(EarnCodeSection earnCodeSection : earnCodeToEarnCodeSection.values()){
162 earnCodeSection.addWeeklyTotal(dayCount, weekSize);
163 }
164 weekSize = 0;
165
166 dayCount++;
167 }
168
169 dayCount = 0;
170
171 for(EarnCodeSection earnCodeSection : earnCodeToEarnCodeSection.values()){
172 String earnCode = earnCodeSection.getEarnCode();
173 EarnGroup earnGroupObj = TkServiceLocator.getEarnGroupService().getEarnGroupSummaryForEarnCode(earnCode, TKUtils.getTimelessDate(asOfDate));
174 String earnGroup = null;
175 if(earnGroupObj == null){
176 earnGroup = OTHER_EARN_GROUP;
177 } else{
178 earnGroup = earnGroupObj.getDescr();
179 }
180
181 EarnGroupSection earnGroupSection = earnGroupToEarnGroupSection.get(earnGroup);
182 if(earnGroupSection == null){
183 earnGroupSection = new EarnGroupSection();
184 earnGroupSection.setEarnGroup(earnGroup);
185 for(int i =0;i<(numEntries-1);i++){
186 earnGroupSection.getTotals().add(BigDecimal.ZERO);
187 }
188 earnGroupToEarnGroupSection.put(earnGroup, earnGroupSection);
189 }
190 earnGroupSection.addEarnCodeSection(earnCodeSection, dayArrangements);
191
192 }
193 for(EarnGroupSection earnGroupSection : earnGroupToEarnGroupSection.values()){
194 earnGroupSections.add(earnGroupSection);
195 }
196 return earnGroupSections;
197 }
198
199
200
201
202
203
204 protected List<String> getSummaryHeader(CalendarEntries payCalEntry){
205 List<String> summaryHeader = new ArrayList<String>();
206 int dayCount = 0;
207 Date beginDateTime = payCalEntry.getBeginPeriodDateTime();
208 Date endDateTime = payCalEntry.getEndPeriodDateTime();
209 boolean virtualDays = false;
210 LocalDateTime endDate = payCalEntry.getEndLocalDateTime();
211
212 if (endDate.get(DateTimeFieldType.hourOfDay()) != 0 || endDate.get(DateTimeFieldType.minuteOfHour()) != 0 ||
213 endDate.get(DateTimeFieldType.secondOfMinute()) != 0){
214 virtualDays = true;
215 }
216
217 Date currDateTime = beginDateTime;
218 java.util.Calendar cal = GregorianCalendar.getInstance();
219
220 while(currDateTime.before(endDateTime)){
221 LocalDateTime currDate = new LocalDateTime(currDateTime);
222 summaryHeader.add(makeHeaderDiplayString(currDate, virtualDays));
223
224 dayCount++;
225 if((dayCount % 7) == 0){
226 summaryHeader.add("Week "+ ((dayCount / 7)));
227 }
228 cal.setTime(currDateTime);
229 cal.add(java.util.Calendar.HOUR, 24);
230 currDateTime = cal.getTime();
231 }
232
233 summaryHeader.add("Period Total");
234 return summaryHeader;
235 }
236
237
238
239
240
241
242
243
244
245
246 private List<BigDecimal> getWorkedHours(TkTimeBlockAggregate aggregate) {
247 List<BigDecimal> hours = new ArrayList<BigDecimal>();
248 BigDecimal periodTotal = TkConstants.BIG_DECIMAL_SCALED_ZERO;
249 for (FlsaWeek week : aggregate.getFlsaWeeks(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback())) {
250 BigDecimal weeklyTotal = TkConstants.BIG_DECIMAL_SCALED_ZERO;
251 for (FlsaDay day : week.getFlsaDays()) {
252 BigDecimal totalForDay = TkConstants.BIG_DECIMAL_SCALED_ZERO;
253 for (TimeBlock block : day.getAppliedTimeBlocks()) {
254 totalForDay = totalForDay.add(block.getHours(), TkConstants.MATH_CONTEXT);
255 weeklyTotal = weeklyTotal.add(block.getHours(), TkConstants.MATH_CONTEXT);
256 periodTotal = periodTotal.add(block.getHours(), TkConstants.MATH_CONTEXT);
257 }
258 hours.add(totalForDay);
259 }
260 hours.add(weeklyTotal);
261 }
262 hours.add(periodTotal);
263
264 return hours;
265 }
266
267
268
269
270
271
272
273
274
275
276
277 @Override
278 public List<String> getHeaderForSummary(CalendarEntries cal, List<Boolean> dayArrangements) {
279 List<String> header = new ArrayList<String>();
280
281
282 int flsaBeginDay = this.getPayCalendarForEntry(cal).getFlsaBeginDayConstant();
283 boolean virtualDays = false;
284 LocalDateTime startDate = cal.getBeginLocalDateTime();
285 LocalDateTime endDate = cal.getEndLocalDateTime();
286
287
288
289
290 if (endDate.get(DateTimeFieldType.hourOfDay()) != 0 || endDate.get(DateTimeFieldType.minuteOfHour()) != 0 ||
291 endDate.get(DateTimeFieldType.secondOfMinute()) != 0)
292 {
293 endDate = endDate.plusDays(1);
294 virtualDays = true;
295 }
296
297 boolean afterFirstDay = false;
298 int week = 1;
299 for (LocalDateTime currentDate = startDate; currentDate.compareTo(endDate) < 0; currentDate = currentDate.plusDays(1)) {
300
301 if (currentDate.getDayOfWeek() == flsaBeginDay && afterFirstDay) {
302 header.add("Week " + week);
303 dayArrangements.add(false);
304 week++;
305 }
306
307 header.add(makeHeaderDiplayString(currentDate, virtualDays));
308 dayArrangements.add(true);
309
310
311 afterFirstDay = true;
312 }
313
314
315
316
317 if (!header.get(header.size()-1).startsWith("Week")) {
318 dayArrangements.add(false);
319 header.add("Week " + week);
320 }
321
322
323 header.add("Period Total");
324 dayArrangements.add(false);
325 return header;
326 }
327
328
329
330
331
332
333
334 private String makeHeaderDiplayString(LocalDateTime currentDate, boolean virtualDays) {
335 StringBuilder display = new StringBuilder();
336
337 display.append(currentDate.toString("E"));
338 if (virtualDays) {
339 LocalDateTime nextDate = currentDate.plusDays(1);
340 display.append(" - ");
341 display.append(nextDate.toString("E"));
342 }
343
344 display.append("<br />");
345
346 display.append(currentDate.toString(TkConstants.DT_ABBREV_DATE_FORMAT));
347 if (virtualDays) {
348 LocalDateTime nextDate = currentDate.plusDays(1);
349 display.append(" - ");
350 display.append(nextDate.toString(TkConstants.DT_ABBREV_DATE_FORMAT));
351 }
352
353 return display.toString();
354 }
355
356
357
358
359
360 private Calendar getPayCalendarForEntry(CalendarEntries calEntry) {
361 Calendar cal = null;
362
363 if (calEntry != null) {
364 cal = TkServiceLocator.getCalendarService().getCalendar(calEntry.getHrCalendarId());
365 }
366
367 return cal;
368 }
369
370 }