1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.timeblock.service;
17
18 import java.math.BigDecimal;
19 import java.sql.Date;
20 import java.sql.Timestamp;
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.apache.commons.lang.StringUtils;
25 import org.apache.log4j.Logger;
26 import org.joda.time.DateTime;
27 import org.joda.time.DateTimeConstants;
28 import org.joda.time.DateTimeZone;
29 import org.joda.time.Interval;
30 import org.kuali.hr.job.Job;
31 import org.kuali.hr.lm.earncodesec.EarnCodeSecurity;
32 import org.kuali.hr.time.assignment.Assignment;
33 import org.kuali.hr.time.earncode.EarnCode;
34 import org.kuali.hr.time.paytype.PayType;
35 import org.kuali.hr.time.service.base.TkServiceLocator;
36 import org.kuali.hr.time.timeblock.TimeBlock;
37 import org.kuali.hr.time.timeblock.TimeBlockHistory;
38 import org.kuali.hr.time.timeblock.TimeHourDetail;
39 import org.kuali.hr.time.timeblock.dao.TimeBlockDao;
40 import org.kuali.hr.time.timesheet.TimesheetDocument;
41 import org.kuali.hr.time.util.TKContext;
42 import org.kuali.hr.time.util.TKUtils;
43 import org.kuali.hr.time.util.TkConstants;
44 import org.kuali.rice.krad.service.KRADServiceLocator;
45 import org.kuali.rice.krad.util.GlobalVariables;
46
47 public class TimeBlockServiceImpl implements TimeBlockService {
48
49 private static final Logger LOG = Logger.getLogger(TimeBlockServiceImpl.class);
50 private TimeBlockDao timeBlockDao;
51
52 public void setTimeBlockDao(TimeBlockDao timeBlockDao) {
53 this.timeBlockDao = timeBlockDao;
54 }
55
56
57 public List<TimeBlock> buildTimeBlocksSpanDates(Assignment assignment, String earnCode, TimesheetDocument timesheetDocument,
58 Timestamp beginTimestamp, Timestamp endTimestamp, BigDecimal hours, BigDecimal amount,
59 Boolean isClockLogCreated, Boolean isLunchDeleted, String spanningWeeks, String userPrincipalId) {
60 DateTimeZone zone = TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
61 DateTime beginDt = new DateTime(beginTimestamp.getTime(), zone);
62 DateTime endDt = beginDt.toLocalDate().toDateTime((new DateTime(endTimestamp.getTime(), zone)).toLocalTime(), zone);
63 if (endDt.isBefore(beginDt)) endDt = endDt.plusDays(1);
64
65 List<Interval> dayInt = TKUtils.getDaySpanForCalendarEntry(timesheetDocument.getCalendarEntry());
66 TimeBlock firstTimeBlock = new TimeBlock();
67 List<TimeBlock> lstTimeBlocks = new ArrayList<TimeBlock>();
68 for (Interval dayIn : dayInt) {
69 if (dayIn.contains(beginDt)) {
70 if (dayIn.contains(endDt) || dayIn.getEnd().equals(endDt)) {
71
72 if (StringUtils.isEmpty(spanningWeeks) &&
73 (dayIn.getStart().getDayOfWeek() == DateTimeConstants.SATURDAY ||dayIn.getStart().getDayOfWeek() == DateTimeConstants.SUNDAY)) {
74
75 } else {
76 firstTimeBlock = createTimeBlock(timesheetDocument, beginTimestamp, new Timestamp(endDt.getMillis()), assignment, earnCode, hours, amount, false, isLunchDeleted, userPrincipalId);
77 lstTimeBlocks.add(firstTimeBlock);
78 }
79 } else {
80
81
82 }
83 }
84 }
85
86 DateTime endTime = new DateTime(endTimestamp.getTime(), zone);
87 DateTime endOfFirstDay = new DateTime(firstTimeBlock.getEndTimestamp(), zone);
88 long diffInMillis = endOfFirstDay.minus(beginDt.getMillis()).getMillis();
89 DateTime currTime = beginDt.plusDays(1);
90 while (currTime.isBefore(endTime) || currTime.isEqual(endTime)) {
91
92 if (StringUtils.isEmpty(spanningWeeks) &&
93 (currTime.getDayOfWeek() == DateTimeConstants.SATURDAY || currTime.getDayOfWeek() == DateTimeConstants.SUNDAY)) {
94
95 } else {
96 Timestamp begin = new Timestamp(currTime.getMillis());
97 Timestamp end = new Timestamp((currTime.plus(diffInMillis).getMillis()));
98 TimeBlock tb = createTimeBlock(timesheetDocument, begin, end, assignment, earnCode, hours, amount, false, isLunchDeleted, userPrincipalId);
99 lstTimeBlocks.add(tb);
100 }
101 currTime = currTime.plusDays(1);
102 }
103 return lstTimeBlocks;
104 }
105
106
107 public List<TimeBlock> buildTimeBlocks(Assignment assignment, String earnCode, TimesheetDocument timesheetDocument,
108 Timestamp beginTimestamp, Timestamp endTimestamp, BigDecimal hours, BigDecimal amount,
109 Boolean isClockLogCreated, Boolean isLunchDeleted, String userPrincipalId) {
110
111
112
113 Interval firstDay = null;
114 List<Interval> dayIntervals = TKUtils.getDaySpanForCalendarEntry(timesheetDocument.getCalendarEntry());
115 List<TimeBlock> lstTimeBlocks = new ArrayList<TimeBlock>();
116 Timestamp beginTemp = beginTimestamp;
117
118 for (Interval dayInt : dayIntervals) {
119
120 if (firstDay != null) {
121 if(!dayInt.contains(endTimestamp.getTime())){
122 beginTemp = new Timestamp(dayInt.getStartMillis());
123 } else if((dayInt.getStartMillis() - endTimestamp.getTime()) != 0){
124 TimeBlock tb = createTimeBlock(timesheetDocument, new Timestamp(dayInt.getStartMillis()), endTimestamp, assignment, earnCode, hours, amount, isClockLogCreated, isLunchDeleted, userPrincipalId);
125 lstTimeBlocks.add(tb);
126 break;
127 }
128 }
129 if (dayInt.contains(beginTemp.getTime())) {
130 firstDay = dayInt;
131
132
133
134 if (dayInt.contains(endTimestamp.getTime()) || (endTimestamp.getTime() == dayInt.getEnd().getMillis())) {
135
136 TimeBlock tb = createTimeBlock(timesheetDocument, beginTemp, endTimestamp, assignment, earnCode, hours, amount, isClockLogCreated, isLunchDeleted, userPrincipalId);
137 tb.setBeginTimestamp(beginTemp);
138 tb.setEndTimestamp(endTimestamp);
139 lstTimeBlocks.add(tb);
140 break;
141 } else {
142
143 TimeBlock tb = createTimeBlock(timesheetDocument, beginTemp, new Timestamp(dayInt.getEndMillis()), assignment, earnCode, hours, amount, isClockLogCreated, isLunchDeleted, userPrincipalId);
144 tb.setBeginTimestamp(beginTemp);
145 tb.setEndTimestamp(new Timestamp(firstDay.getEndMillis()));
146 lstTimeBlocks.add(tb);
147 }
148 }
149 }
150 return lstTimeBlocks;
151 }
152
153 public void saveTimeBlocks(List<TimeBlock> oldTimeBlocks, List<TimeBlock> newTimeBlocks, String userPrincipalId) {
154 List<TimeBlock> alteredTimeBlocks = new ArrayList<TimeBlock>();
155 for (TimeBlock tb : newTimeBlocks) {
156 boolean persist = true;
157 for (TimeBlock tbOld : oldTimeBlocks) {
158 if (tb.equals(tbOld)) {
159 persist = false;
160 break;
161 }
162 }
163 if (persist) {
164 alteredTimeBlocks.add(tb);
165 }
166 }
167
168 for (TimeBlock timeBlock : alteredTimeBlocks) {
169 TkServiceLocator.getTimeHourDetailService().removeTimeHourDetails(timeBlock.getTkTimeBlockId());
170 timeBlock.setUserPrincipalId(userPrincipalId);
171 }
172
173 List<TimeBlock> savedTimeBlocks = (List<TimeBlock>) KRADServiceLocator.getBusinessObjectService().save(alteredTimeBlocks);
174
175 for (TimeBlock timeBlock : savedTimeBlocks) {
176 timeBlock.setTimeBlockHistories(createTimeBlockHistories(timeBlock, TkConstants.ACTIONS.ADD_TIME_BLOCK));
177 KRADServiceLocator.getBusinessObjectService().save(timeBlock.getTimeBlockHistories());
178 }
179 }
180
181 public void saveTimeBlocks(List<TimeBlock> tbList) {
182 for (TimeBlock tb : tbList) {
183 TkServiceLocator.getTimeHourDetailService().removeTimeHourDetails(tb.getTkTimeBlockId());
184 timeBlockDao.saveOrUpdate(tb);
185 for(TimeBlockHistory tbh : tb.getTimeBlockHistories()){
186 TkServiceLocator.getTimeBlockHistoryService().saveTimeBlockHistory(tbh);
187 }
188 }
189 }
190
191 public void updateTimeBlock(TimeBlock tb) {
192 timeBlockDao.saveOrUpdate(tb);
193 }
194
195
196 public TimeBlock createTimeBlock(TimesheetDocument timesheetDocument, Timestamp beginTime, Timestamp endTime, Assignment assignment, String earnCode, BigDecimal hours, BigDecimal amount, Boolean clockLogCreated, Boolean lunchDeleted, String userPrincipalId) {
197 DateTimeZone timezone = TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback();
198 EarnCode earnCodeObj = TkServiceLocator.getEarnCodeService().getEarnCode(earnCode, timesheetDocument.getAsOfDate());
199
200 TimeBlock tb = new TimeBlock();
201 tb.setDocumentId(timesheetDocument.getDocumentHeader().getDocumentId());
202 tb.setPrincipalId(timesheetDocument.getPrincipalId());
203 tb.setJobNumber(assignment.getJobNumber());
204 tb.setWorkArea(assignment.getWorkArea());
205 tb.setTask(assignment.getTask());
206 tb.setEarnCode(earnCode);
207 tb.setBeginTimestamp(beginTime);
208 tb.setBeginTimestampTimezone(timezone.getID());
209 tb.setEndTimestamp(endTime);
210 tb.setEndTimestampTimezone(timezone.getID());
211 tb.setBeginTimeDisplay(new DateTime(tb.getBeginTimestamp(), timezone));
212 tb.setEndTimeDisplay(new DateTime(tb.getEndTimestamp(), timezone));
213
214 if(hours == null || hours.compareTo(BigDecimal.ZERO) == 0) {
215 hours = TKUtils.getHoursBetween(beginTime.getTime(), endTime.getTime());
216 }
217 tb.setAmount(amount);
218
219
220
221 if (earnCodeObj.getInflateMinHours() != null) {
222 if ((earnCodeObj.getInflateMinHours().compareTo(BigDecimal.ZERO) != 0) &&
223 earnCodeObj.getInflateMinHours().compareTo(hours) > 0) {
224 hours = earnCodeObj.getInflateMinHours();
225 }
226 }
227
228 if (earnCodeObj.getInflateFactor() != null) {
229 if ((earnCodeObj.getInflateFactor().compareTo(new BigDecimal(1.0)) != 0)
230 && (earnCodeObj.getInflateFactor().compareTo(BigDecimal.ZERO)!= 0) ) {
231 hours = earnCodeObj.getInflateFactor().multiply(hours, TkConstants.MATH_CONTEXT).setScale(TkConstants.BIG_DECIMAL_SCALE);
232 }
233 }
234
235 tb.setEarnCodeType(earnCodeObj.getEarnCodeType());
236 tb.setHours(hours);
237 tb.setClockLogCreated(clockLogCreated);
238 tb.setUserPrincipalId(userPrincipalId);
239 tb.setTimestamp(new Timestamp(System.currentTimeMillis()));
240 tb.setLunchDeleted(lunchDeleted);
241
242 tb.setTimeHourDetails(this.createTimeHourDetails(tb.getEarnCode(), tb.getHours(), tb.getAmount(), tb.getTkTimeBlockId()));
243
244 return tb;
245 }
246
247 public TimeBlock getTimeBlock(String tkTimeBlockId) {
248 return timeBlockDao.getTimeBlock(tkTimeBlockId);
249 }
250
251 @Override
252 public void deleteTimeBlock(TimeBlock timeBlock) {
253 timeBlockDao.deleteTimeBlock(timeBlock);
254
255 }
256
257 public void resetTimeHourDetail(List<TimeBlock> origTimeBlocks) {
258 for (TimeBlock tb : origTimeBlocks) {
259 tb.setTimeHourDetails(createTimeHourDetails(tb.getEarnCode(), tb.getHours(), tb.getAmount(), tb.getTkTimeBlockId()));
260
261 for(TimeBlockHistory tbh : tb.getTimeBlockHistories()) {
262 TkServiceLocator.getTimeBlockHistoryService().addTimeBlockHistoryDetails(tbh,tb);
263 }
264 }
265 }
266
267 private List<TimeHourDetail> createTimeHourDetails(String earnCode, BigDecimal hours, BigDecimal amount, String timeBlockId) {
268 List<TimeHourDetail> timeHourDetails = new ArrayList<TimeHourDetail>();
269
270 TimeHourDetail timeHourDetail = new TimeHourDetail();
271 timeHourDetail.setEarnCode(earnCode);
272 timeHourDetail.setHours(hours);
273 timeHourDetail.setAmount(amount);
274 timeHourDetail.setTkTimeBlockId(timeBlockId);
275 timeHourDetails.add(timeHourDetail);
276
277 return timeHourDetails;
278 }
279
280 public List<TimeBlockHistory> createTimeBlockHistories(TimeBlock tb, String actionHistory) {
281 List<TimeBlockHistory> tbhs = new ArrayList<TimeBlockHistory>();
282
283 TimeBlockHistory tbh = new TimeBlockHistory(tb);
284 tbh.setActionHistory(actionHistory);
285
286 TkServiceLocator.getTimeBlockHistoryService().addTimeBlockHistoryDetails(tbh, tb);
287
288 tbhs.add(tbh);
289
290 return tbhs;
291 }
292
293
294
295 public List<TimeBlock> getTimeBlocks(String documentId) {
296 List<TimeBlock> timeBlocks = timeBlockDao.getTimeBlocks(documentId);
297 TkServiceLocator.getTimezoneService().translateForTimezone(timeBlocks);
298 for(TimeBlock tb : timeBlocks) {
299 String earnCodeType = TkServiceLocator.getEarnCodeService().getEarnCodeType(tb.getEarnCode(), new java.sql.Date(tb.getBeginTimestamp().getTime()));
300 tb.setEarnCodeType(earnCodeType);
301 }
302
303 return timeBlocks;
304 }
305
306 public List<TimeBlock> getTimeBlocksForAssignment(Assignment assign) {
307 List<TimeBlock> timeBlocks = new ArrayList<TimeBlock>();
308 if(assign != null) {
309 timeBlocks = timeBlockDao.getTimeBlocksForAssignment(assign);
310 }
311 TkServiceLocator.getTimezoneService().translateForTimezone(timeBlocks);
312 for(TimeBlock tb : timeBlocks) {
313 String earnCodeType = TkServiceLocator.getEarnCodeService().getEarnCodeType(tb.getEarnCode(), new java.sql.Date(tb.getBeginTimestamp().getTime()));
314 tb.setEarnCodeType(earnCodeType);
315 }
316 return timeBlocks;
317 }
318
319
320 @Override
321 public void deleteTimeBlocksAssociatedWithDocumentId(String documentId) {
322 timeBlockDao.deleteTimeBlocksAssociatedWithDocumentId(documentId);
323 }
324
325 @Override
326
327 public Boolean isTimeBlockEditable(TimeBlock tb) {
328 String userId = GlobalVariables.getUserSession().getPrincipalId();
329
330 if(userId != null) {
331
332 if(TKContext.getUser().isSystemAdmin()) {
333 return true;
334 }
335
336 if(TKContext.getUser().isTimesheetApprover() && TKContext.getUser().getApproverWorkAreas().contains(tb.getWorkArea())
337 || TKContext.getUser().isTimesheetReviewer() && TKContext.getUser().getReviewerWorkAreas().contains(tb.getWorkArea())) {
338 Job job = TkServiceLocator.getJobService().getJob(TKContext.getTargetPrincipalId(),tb.getJobNumber(), tb.getEndDate());
339 PayType payType = TkServiceLocator.getPayTypeService().getPayType(job.getHrPayType(), tb.getEndDate());
340 if(StringUtils.equals(payType.getRegEarnCode(), tb.getEarnCode())){
341 return true;
342 }
343
344 List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurities(job.getDept(), job.getHrSalGroup(), job.getLocation(), tb.getEndDate());
345 for(EarnCodeSecurity dec : deptEarnCodes){
346 if(dec.isApprover() && StringUtils.equals(dec.getEarnCode(), tb.getEarnCode())){
347 return true;
348 }
349 }
350 }
351
352 if(userId.equals(TKContext.getTargetPrincipalId())) {
353 Job job = TkServiceLocator.getJobService().getJob(TKContext.getTargetPrincipalId(),tb.getJobNumber(), tb.getEndDate());
354 PayType payType = TkServiceLocator.getPayTypeService().getPayType(job.getHrPayType(), tb.getEndDate());
355 if(StringUtils.equals(payType.getRegEarnCode(), tb.getEarnCode())){
356 return true;
357 }
358
359 List<EarnCodeSecurity> deptEarnCodes = TkServiceLocator.getEarnCodeSecurityService().getEarnCodeSecurities(job.getDept(), job.getHrSalGroup(), job.getLocation(), tb.getEndDate());
360 for(EarnCodeSecurity dec : deptEarnCodes){
361 if(dec.isEmployee() && StringUtils.equals(dec.getEarnCode(), tb.getEarnCode())){
362 return true;
363 }
364 }
365
366 }
367
368
369 }
370 return false;
371 }
372
373 @Override
374 public List<TimeBlock> getTimeBlocksForClockLogEndId(String tkClockLogId) {
375 return timeBlockDao.getTimeBlocksForClockLogEndId(tkClockLogId);
376 }
377 @Override
378 public List<TimeBlock> getTimeBlocksForClockLogBeginId(String tkClockLogId) {
379 return timeBlockDao.getTimeBlocksForClockLogBeginId(tkClockLogId);
380 }
381
382 public List<TimeBlock> getTimeBlocks(){
383 return timeBlockDao.getTimeBlocks();
384 }
385
386 public List<TimeBlock> getLatestEndTimestamp(){
387 return timeBlockDao.getLatestEndTimestamp();
388 }
389
390 @Override
391 public List<TimeBlock> getOvernightTimeBlocks(String clockLogEndId) {
392 return timeBlockDao.getOvernightTimeBlocks(clockLogEndId);
393 }
394
395 @Override
396 public void deleteLunchDeduction(String tkTimeHourDetailId) {
397 TimeHourDetail thd = TkServiceLocator.getTimeHourDetailService().getTimeHourDetail(tkTimeHourDetailId);
398 TimeBlock tb = getTimeBlock(thd.getTkTimeBlockId());
399
400
401 tb.setLunchDeleted(true);
402
403 timeBlockDao.saveOrUpdate(tb);
404
405 TkServiceLocator.getTimeHourDetailService().removeTimeHourDetail(thd.getTkTimeHourDetailId());
406 }
407 @Override
408 public List<TimeBlock> getTimeBlocksWithEarnCode(String earnCode, Date effDate) {
409 return timeBlockDao.getTimeBlocksWithEarnCode(earnCode, effDate);
410 }
411 }