1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.lm.leaveblock.service;
17
18 import java.math.BigDecimal;
19 import java.sql.Timestamp;
20 import java.util.*;
21
22 import org.apache.commons.collections.CollectionUtils;
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.commons.lang.time.DateUtils;
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.lm.LMConstants;
31 import org.kuali.hr.lm.leaveblock.LeaveBlock;
32 import org.kuali.hr.lm.leaveblock.LeaveBlockHistory;
33 import org.kuali.hr.lm.leaveblock.dao.LeaveBlockDao;
34 import org.kuali.hr.lm.workflow.LeaveCalendarDocumentHeader;
35 import org.kuali.hr.time.assignment.Assignment;
36 import org.kuali.hr.time.calendar.CalendarEntries;
37 import org.kuali.hr.time.earncode.EarnCode;
38 import org.kuali.hr.time.service.base.TkServiceLocator;
39 import org.kuali.hr.time.util.TKContext;
40 import org.kuali.hr.time.util.TKUtils;
41 import org.kuali.hr.time.util.TkConstants;
42 import org.kuali.hr.time.workflow.TimesheetDocumentHeader;
43 import org.kuali.rice.krad.service.KRADServiceLocator;
44
45 public class LeaveBlockServiceImpl implements LeaveBlockService {
46
47 private static final Logger LOG = Logger.getLogger(LeaveBlockServiceImpl.class);
48
49 private LeaveBlockDao leaveBlockDao;
50
51 @Override
52 public LeaveBlock getLeaveBlock(String leaveBlockId) {
53 return leaveBlockDao.getLeaveBlock(leaveBlockId);
54 }
55
56 public LeaveBlockDao getLeaveBlockDao() {
57 return leaveBlockDao;
58 }
59
60 public void setLeaveBlockDao(LeaveBlockDao leaveBlockDao) {
61 this.leaveBlockDao = leaveBlockDao;
62 }
63
64 public List<LeaveBlock> getLeaveBlocksForDocumentId(String documentId) {
65 return leaveBlockDao.getLeaveBlocksForDocumentId(documentId);
66 }
67
68
69 @Override
70 public List<LeaveBlock> getLeaveBlocks(String principalId, Date beginDate,
71 Date endDate) {
72 return leaveBlockDao.getLeaveBlocks(principalId, beginDate, endDate);
73 }
74
75 @Override
76 public List<LeaveBlock> getLeaveBlocksWithAccrualCategory(String principalId, Date beginDate,
77 Date endDate, String accrualCategory) {
78 return leaveBlockDao.getLeaveBlocksWithAccrualCategory(principalId, beginDate, endDate, accrualCategory);
79 }
80
81 @Override
82 public List<LeaveBlock> getLeaveBlocksWithType(String principalId, Date beginDate,
83 Date endDate, String leaveBlockType) {
84 return leaveBlockDao.getLeaveBlocksWithType(principalId, beginDate, endDate, leaveBlockType);
85 }
86
87 @Override
88 public List<LeaveBlock> getLeaveBlocksSinceCarryOver(String principalId, Map<String, LeaveBlock> carryOver, DateTime endDate, boolean includeAllAccrualCategories) {
89 return leaveBlockDao.getLeaveBlocksSinceCarryOver(principalId, carryOver, endDate, includeAllAccrualCategories);
90 }
91
92 @Override
93 public Map<String, LeaveBlock> getLastCarryOverBlocks(String principalId, Date asOfDate) {
94 if (StringUtils.isEmpty(principalId)) {
95 return Collections.emptyMap();
96 }
97 return leaveBlockDao.getLastCarryOverBlocks(principalId, LMConstants.LEAVE_BLOCK_TYPE.CARRY_OVER, asOfDate);
98 }
99
100 @Override
101 public void saveLeaveBlocks(List<LeaveBlock> leaveBlocks) {
102 KRADServiceLocator.getBusinessObjectService().save(leaveBlocks);
103
104 List<LeaveBlockHistory> leaveBlockHistories = new ArrayList<LeaveBlockHistory>();
105 for (LeaveBlock leaveBlock : leaveBlocks) {
106 LeaveBlockHistory lbh = new LeaveBlockHistory(leaveBlock);
107 lbh.setAction(LMConstants.ACTION.ADD);
108 leaveBlockHistories.add(lbh);
109 }
110
111 KRADServiceLocator.getBusinessObjectService().save(leaveBlockHistories);
112 }
113
114 @Override
115 public void deleteLeaveBlock(String leaveBlockId, String principalId) {
116 LeaveBlock leaveBlock = getLeaveBlock(leaveBlockId);
117
118
119
120
121
122 LeaveBlockHistory leaveBlockHistory = new LeaveBlockHistory(leaveBlock);
123 leaveBlockHistory.setPrincipalIdDeleted(principalId);
124 leaveBlockHistory.setTimestampDeleted(new Timestamp(System.currentTimeMillis()));
125 leaveBlockHistory.setAction(LMConstants.ACTION.DELETE);
126
127
128 KRADServiceLocator.getBusinessObjectService().delete(leaveBlock);
129
130
131 KRADServiceLocator.getBusinessObjectService().save(leaveBlockHistory);
132
133
134 }
135
136 @Override
137 public void saveLeaveBlock(LeaveBlock leaveBlock, String principalId) {
138
139
140 KRADServiceLocator.getBusinessObjectService().delete(leaveBlock);
141
142
143 leaveBlock.setLmLeaveBlockId(null);
144 leaveBlock.setTimestamp(new Timestamp(System.currentTimeMillis()));
145 leaveBlock.setPrincipalIdModified(principalId);
146 KRADServiceLocator.getBusinessObjectService().save(leaveBlock);
147
148
149 LeaveBlockHistory lbh = new LeaveBlockHistory(leaveBlock);
150 lbh.setAction(LMConstants.ACTION.MODIFIED);
151 TkServiceLocator.getLeaveBlockHistoryService().saveLeaveBlockHistory(lbh);
152
153 }
154
155 @Override
156 public void addLeaveBlocks(DateTime beginDate, DateTime endDate, CalendarEntries ce, String selectedEarnCode,
157 BigDecimal hours, String description, Assignment selectedAssignment, String spanningWeeks, String leaveBlockType, String principalId) {
158 DateTime calBeginDateTime = beginDate;
159 DateTime calEndDateTime = endDate;
160 if(ce != null) {
161 calBeginDateTime = ce.getBeginLocalDateTime().toDateTime();
162 calEndDateTime = ce.getEndLocalDateTime().toDateTime();
163 } else {
164 throw new RuntimeException("Calendar Entry parameter is null.");
165 }
166 Interval calendarInterval = new Interval(calBeginDateTime, calEndDateTime);
167
168
169
170 List<Interval> leaveBlockIntervals = TKUtils.createDaySpan(beginDate.toDateMidnight().toDateTime(), endDate.plusDays(1).toDateMidnight().toDateTime(), TKUtils.getSystemDateTimeZone());
171
172 List<LeaveBlock> currentLeaveBlocks = getLeaveBlocks(principalId, calBeginDateTime.toDate(), calEndDateTime.toDate());
173
174
175 LeaveCalendarDocumentHeader lcdh = TkServiceLocator.getLeaveCalendarDocumentHeaderService()
176 .getDocumentHeader(principalId, ce.getBeginLocalDateTime().toDateTime().toDate(), ce.getEndLocalDateTime().toDateTime().toDate());
177 String docId = lcdh == null ? null : lcdh.getDocumentId();
178
179
180 for (Interval leaveBlockInt : leaveBlockIntervals) {
181 if (calendarInterval.contains(leaveBlockInt)) {
182
183 if (StringUtils.isEmpty(spanningWeeks) &&
184 (leaveBlockInt.getStart().getDayOfWeek() == DateTimeConstants.SATURDAY ||leaveBlockInt.getStart().getDayOfWeek() == DateTimeConstants.SUNDAY)) {
185
186
187 } else {
188
189
190
191 java.sql.Date sqlDate = new java.sql.Date(ce.getEndLocalDateTime().toDateTime().toDate().getTime());
192 if ((leaveBlockType.equals(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR)
193 || leaveBlockType.equals((LMConstants.LEAVE_BLOCK_TYPE.TIME_CALENDAR)))
194 && BigDecimal.ZERO.compareTo(hours) < 0) {
195 hours = hours.negate();
196 }
197
198 CalendarEntries calendarEntry = TkServiceLocator.getCalendarEntriesService().getCurrentCalendarEntriesByCalendarId(ce.getHrCalendarId(), TKUtils.getCurrentDate());
199 Date leaveBlockDate = new DateTime(leaveBlockInt.getStartMillis()).toDate();
200
201 String requestStatus = LMConstants.REQUEST_STATUS.USAGE;
202 if (TkServiceLocator.getLeaveApprovalService().isActiveAssignmentFoundOnJobFlsaStatus(principalId, TkConstants.FLSA_STATUS_NON_EXEMPT, true)) {
203 TimesheetDocumentHeader tdh = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeaderForDate(principalId, leaveBlockDate);
204 if (tdh != null) {
205 if (DateUtils.isSameDay(leaveBlockDate, tdh.getEndDate()) || leaveBlockDate.after(tdh.getEndDate())) {
206 requestStatus = LMConstants.REQUEST_STATUS.PLANNED;
207 }
208 } else {
209 requestStatus = LMConstants.REQUEST_STATUS.PLANNED;
210 }
211 } else {
212 if (DateUtils.isSameDay(leaveBlockDate, calendarEntry.getEndPeriodDateTime()) || leaveBlockDate.after(calendarEntry.getEndPeriodDateTime())) {
213 requestStatus = LMConstants.REQUEST_STATUS.PLANNED;
214 }
215 }
216
217 EarnCode earnCodeObj = TkServiceLocator.getEarnCodeService().getEarnCode(selectedEarnCode, sqlDate);
218 LeaveBlock leaveBlock = new LeaveBlock.Builder(new DateTime(leaveBlockInt.getStartMillis()), docId, principalId, selectedEarnCode, hours)
219 .description(description)
220 .principalIdModified(principalId)
221 .timestamp(TKUtils.getCurrentTimestamp())
222 .scheduleTimeOffId("0")
223 .accrualCategory(earnCodeObj.getAccrualCategory())
224 .workArea(selectedAssignment.getWorkArea())
225 .jobNumber(selectedAssignment.getJobNumber())
226 .task(selectedAssignment.getTask())
227 .requestStatus(requestStatus)
228 .leaveBlockType(leaveBlockType)
229 .build();
230 if (!currentLeaveBlocks.contains(leaveBlock)) {
231 currentLeaveBlocks.add(leaveBlock);
232 }
233 }
234 }
235 }
236
237 saveLeaveBlocks(currentLeaveBlocks);
238 }
239
240
241 @Override
242 public void updateLeaveBlock(LeaveBlock leaveBlock, String principalId) {
243
244 if ((LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR.equals(leaveBlock.getLeaveBlockType())
245 || LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR.equals(leaveBlock.getLeaveBlockType()))
246 && BigDecimal.ZERO.compareTo(leaveBlock.getLeaveAmount()) < 0) {
247 leaveBlock.setLeaveAmount(leaveBlock.getLeaveAmount().negate());
248 }
249
250
251 LeaveBlockHistory leaveBlockHistory = new LeaveBlockHistory(leaveBlock);
252 leaveBlockHistory.setPrincipalIdDeleted(principalId);
253 leaveBlockHistory.setTimestampDeleted(new Timestamp(System.currentTimeMillis()));
254 leaveBlockHistory.setAction(LMConstants.ACTION.MODIFIED);
255
256 KRADServiceLocator.getBusinessObjectService().save(leaveBlock);
257
258
259 KRADServiceLocator.getBusinessObjectService().save(leaveBlockHistory);
260 }
261
262 public static List<Interval> createDaySpan(DateTime beginDateTime, DateTime endDateTime, DateTimeZone zone) {
263 beginDateTime = beginDateTime.toDateTime(zone);
264 endDateTime = endDateTime.toDateTime(zone);
265 List<Interval> dayIntervals = new ArrayList<Interval>();
266
267 DateTime currDateTime = beginDateTime;
268 while (currDateTime.isBefore(endDateTime)) {
269 DateTime prevDateTime = currDateTime;
270 currDateTime = currDateTime.plusDays(1);
271 Interval daySpan = new Interval(prevDateTime, currDateTime);
272 dayIntervals.add(daySpan);
273 }
274
275 return dayIntervals;
276 }
277
278 @Override
279 public List<LeaveBlock> getLeaveBlocks(String principalId, String leaveBlockType, String requestStatus, Date currentDate) {
280 return leaveBlockDao.getLeaveBlocks(principalId, leaveBlockType, requestStatus, currentDate);
281 }
282
283 @Override
284 public List<LeaveBlock> getLeaveBlocksForDate(String principalId, Date leaveDate) {
285 return leaveBlockDao.getLeaveBlocksForDate(principalId, leaveDate);
286 }
287
288 @Override
289 public List<LeaveBlock> getNotAccrualGeneratedLeaveBlocksForDate(String principalId, Date leaveDate) {
290 return leaveBlockDao.getNotAccrualGeneratedLeaveBlocksForDate(principalId, leaveDate);
291 }
292
293 public List<LeaveBlock> getLeaveBlocksForTimeCalendar(String principalId, Date beginDate, Date endDate, List<String> assignmentKeys) {
294 List<LeaveBlock> col = leaveBlockDao.getCalendarLeaveBlocks(principalId, beginDate, endDate);
295 List<LeaveBlock> leaveBlocks = filterLeaveBlocksForTimeCalendar(col, assignmentKeys);
296 return leaveBlocks;
297 }
298
299 public List<LeaveBlock> getLeaveBlocksForLeaveCalendar(String principalId, Date beginDate, Date endDate, List<String> assignmentKeys) {
300 List<LeaveBlock> col = leaveBlockDao.getLeaveBlocks(principalId, beginDate, endDate);
301 List<LeaveBlock> leaveBlocks = filterLeaveBlocksForLeaveCalendar(col, assignmentKeys);
302 return leaveBlocks;
303 }
304
305 public List<LeaveBlock> filterLeaveBlocksForTimeCalendar(List<LeaveBlock> lbs, List<String> assignmentKeys) {
306 if(CollectionUtils.isEmpty(assignmentKeys)) {
307 return lbs;
308 }
309 List<LeaveBlock> results = new ArrayList<LeaveBlock> ();
310 for(LeaveBlock lb : lbs) {
311 if(lb != null) {
312 if (StringUtils.equals(lb.getLeaveBlockType(), LMConstants.LEAVE_BLOCK_TYPE.ACCRUAL_SERVICE)
313 && StringUtils.isNotEmpty(lb.getScheduleTimeOffId())
314 && lb.getLeaveAmount().compareTo(BigDecimal.ZERO) < 0) {
315
316 results.add(lb);
317 } else if(StringUtils.isNotEmpty(lb.getAssignmentKey()) && assignmentKeys.contains(lb.getAssignmentKey())) {
318 if (StringUtils.equals(lb.getLeaveBlockType(), LMConstants.LEAVE_BLOCK_TYPE.LEAVE_CALENDAR)) {
319
320 if (StringUtils.equals(lb.getRequestStatus(), LMConstants.REQUEST_STATUS.APPROVED)) {
321 results.add(lb);
322 }
323 } else if(StringUtils.equals(lb.getLeaveBlockType(), LMConstants.LEAVE_BLOCK_TYPE.TIME_CALENDAR)) {
324 results.add(lb);
325 }
326 }
327 }
328 }
329 return results;
330 }
331
332 public List<LeaveBlock> filterLeaveBlocksForLeaveCalendar(List<LeaveBlock> lbs, List<String> assignmentKeys) {
333 if(CollectionUtils.isEmpty(assignmentKeys)) {
334 return lbs;
335 }
336 List<LeaveBlock> leaveBlocks = new ArrayList<LeaveBlock>();
337 for(LeaveBlock lb : lbs) {
338 if(lb != null) {
339 if(lb.getLeaveBlockType().equals(LMConstants.LEAVE_BLOCK_TYPE.TIME_CALENDAR)) {
340 if(StringUtils.isNotEmpty(lb.getAssignmentKey()) && assignmentKeys.contains(lb.getAssignmentKey())) {
341 leaveBlocks.add(lb);
342 }
343 } else {
344 leaveBlocks.add(lb);
345 }
346 }
347 }
348 return leaveBlocks;
349 }
350
351 @Override
352 public void deleteLeaveBlocksForDocumentId(String documentId){
353 leaveBlockDao.deleteLeaveBlocksForDocumentId(documentId);
354 }
355
356
357 @Override
358 public List<LeaveBlock> getAccrualGeneratedLeaveBlocks(String principalId, Date beginDate, Date endDate) {
359 return leaveBlockDao.getAccrualGeneratedLeaveBlocks(principalId, beginDate, endDate);
360 }
361
362 @Override
363 public List<LeaveBlock> getSSTOLeaveBlocks(String principalId, String sstoId, Date accruledDate) {
364 return leaveBlockDao.getSSTOLeaveBlocks(principalId, sstoId, accruledDate);
365 }
366
367 @Override
368 public List<LeaveBlock> getABELeaveBlocksSinceTime(String principalId, Timestamp lastRanTime) {
369 return leaveBlockDao.getABELeaveBlocksSinceTime(principalId, lastRanTime);
370 }
371 }