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