1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.hr.time.missedpunch;
17
18 import java.sql.Timestamp;
19 import java.text.ParseException;
20 import java.text.SimpleDateFormat;
21 import java.util.Date;
22 import java.util.HashSet;
23 import java.util.List;
24 import java.util.Set;
25
26 import org.apache.commons.lang.StringUtils;
27 import org.joda.time.DateTime;
28 import org.joda.time.DateTimeZone;
29 import org.joda.time.LocalTime;
30 import org.kuali.hr.time.assignment.Assignment;
31 import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
32 import org.kuali.hr.time.clocklog.ClockLog;
33 import org.kuali.hr.time.service.base.TkServiceLocator;
34 import org.kuali.hr.time.timesheet.TimesheetDocument;
35 import org.kuali.hr.time.util.TKContext;
36 import org.kuali.hr.time.util.TKUtils;
37 import org.kuali.hr.time.util.TkConstants;
38 import org.kuali.rice.kew.api.KewApiServiceLocator;
39 import org.kuali.rice.kew.api.document.DocumentStatus;
40 import org.kuali.rice.krad.document.Document;
41 import org.kuali.rice.krad.rules.TransactionalDocumentRuleBase;
42 import org.kuali.rice.krad.util.GlobalVariables;
43
44 public class MissedPunchValidation extends TransactionalDocumentRuleBase {
45
46 @Override
47 protected boolean processCustomRouteDocumentBusinessRules(Document document) {
48 boolean valid = true;
49
50 MissedPunchDocument missedPunchDocument = (MissedPunchDocument) document;
51 DocumentStatus documentStatus = KewApiServiceLocator.getWorkflowDocumentService().getDocumentStatus(missedPunchDocument.getDocumentNumber());
52
53 if (DocumentStatus.INITIATED.equals(DocumentStatus.fromCode(documentStatus.getCode()))
54 || DocumentStatus.SAVED.equals(DocumentStatus.fromCode(documentStatus.getCode()))) {
55 valid &= validateTimeSheet(missedPunchDocument);
56 valid &= validateAssignment(missedPunchDocument);
57
58 if (valid) {
59 ClockLog lastClock = TkServiceLocator.getClockLogService().getLastClockLog(missedPunchDocument.getPrincipalId());
60 try {
61 valid &= validateClockAction(missedPunchDocument, lastClock);
62 valid &= validateClockTime(missedPunchDocument, lastClock);
63 } catch (ParseException e) {
64 e.printStackTrace();
65 }
66 }
67 }
68
69 return valid;
70 }
71
72
73 boolean validateTimeSheet(MissedPunchDocument mp) {
74 boolean valid = true;
75 TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(mp.getTimesheetDocumentId());
76 if(tsd != null
77 && (tsd.getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.ENROUTE)
78 || tsd.getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.FINAL))) {
79 GlobalVariables.getMessageMap().putError("document.timesheetDocumentId", "clock.mp.invalid.timesheet");
80 valid = false;
81 }
82
83 return valid;
84 }
85
86
87
88
89
90
91
92
93
94 boolean validateClockAction(MissedPunchDocument mp, ClockLog lastClock) {
95 boolean valid = true;
96 Set<String> validActions = (lastClock != null) ? TkConstants.CLOCK_ACTION_TRANSITION_MAP.get(lastClock.getClockAction()) : new HashSet<String>();
97
98
99 if (mp.getClockAction().equals(TkConstants.CLOCK_OUT) || mp.getClockAction().equals(TkConstants.LUNCH_OUT)) {
100 ClockLog lci = TkServiceLocator.getClockLogService().getLastClockLog(mp.getPrincipalId(),TkConstants.CLOCK_IN);
101 ClockLog lli = TkServiceLocator.getClockLogService().getLastClockLog(mp.getPrincipalId(),TkConstants.LUNCH_IN);
102 if (lci != null) {
103 MissedPunchDocument mpd = TkServiceLocator.getMissedPunchService().getMissedPunchByClockLogId(lci.getTkClockLogId());
104 if(mpd != null) {
105 GlobalVariables.getMessageMap().putError("document.clockAction", "clock.mp.onlyOne.action");
106 return false;
107 }
108 } else if(lli != null) {
109 MissedPunchDocument mpd = TkServiceLocator.getMissedPunchService().getMissedPunchByClockLogId(lli.getTkClockLogId());
110 if(mpd != null) {
111 GlobalVariables.getMessageMap().putError("document.clockAction", "clock.mp.onlyOne.action");
112 return false;
113 }
114 }
115 }
116
117
118
119
120
121
122
123
124
125
126
127 if (!StringUtils.equals("A", mp.getDocumentStatus()) && !validActions.contains(mp.getClockAction())) {
128 GlobalVariables.getMessageMap().putError("document.clockAction", "clock.mp.invalid.action");
129 valid = false;
130 }
131
132 return valid;
133 }
134
135
136
137
138
139
140
141
142
143
144
145
146 boolean validateClockTime(MissedPunchDocument mp, ClockLog lastClock) throws ParseException {
147 boolean valid = true;
148
149 if (lastClock == null) {
150 return valid;
151 }
152
153
154 if(mp.getActionTime() == null || mp.getActionDate() == null)
155 return false;
156
157 DateTime clockLogDateTime = new DateTime(lastClock.getClockTimestamp().getTime());
158 DateTime boundaryMax = clockLogDateTime.plusDays(1);
159 DateTime nowTime = new DateTime(TKUtils.getCurrentDate());
160 long offset = TkServiceLocator.getTimezoneService().getTimezoneOffsetFromServerTime(TkServiceLocator.getTimezoneService().getUserTimezoneWithFallback());
161 long dateTimeLocal = new LocalTime(mp.getActionTime()).getMillisOfDay() + mp.getActionDate().getTime() - offset;
162
163
164 DateTime actionDateTime = new DateTime(dateTimeLocal);
165
166
167 if(actionDateTime.getYear()> nowTime.getYear()
168 || (actionDateTime.getYear()==nowTime.getYear() && actionDateTime.getDayOfYear() > nowTime.getDayOfYear())) {
169 GlobalVariables.getMessageMap().putError("document.actionDate", "clock.mp.future.date");
170 return false;
171 }
172
173
174 if(actionDateTime.getMillis() > nowTime.getMillis()) {
175 GlobalVariables.getMessageMap().putError("document.actionTime", "clock.mp.future.time");
176 return false;
177 }
178
179 if ((!StringUtils.equals(lastClock.getClockAction(), TkConstants.CLOCK_OUT) && actionDateTime.isAfter(boundaryMax))
180 || actionDateTime.isBefore(clockLogDateTime)) {
181 GlobalVariables.getMessageMap().putError("document.actionTime", "clock.mp.invalid.datetime");
182 valid = false;
183 }
184
185 return valid;
186 }
187
188
189
190
191
192
193
194
195
196 boolean validateAssignment(MissedPunchDocument mp) {
197 boolean valid = true;
198
199 String assignment = mp.getAssignment();
200
201 if (mp.getAssignment() == null) {
202 GlobalVariables.getMessageMap().putError("document.assignment", "clock.mp.assignment.required");
203 valid = false;
204 }
205
206 if (valid)
207 {
208 AssignmentDescriptionKey key = new AssignmentDescriptionKey(assignment);
209 if (key != null) {
210 Assignment assignmentObj = TkServiceLocator.getAssignmentService().getAssignment(mp.getPrincipalId(), key, new java.sql.Date(mp.getActionDate().getTime()));
211 if (assignmentObj == null) {
212 GlobalVariables.getMessageMap().putError("document.assignment", "clock.mp.assignment.active");
213 valid = false;
214 }
215 }
216 else {
217 valid = false;
218 }
219 }
220
221 return valid;
222 }
223 }