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.Set;
24
25 import org.apache.commons.lang.StringUtils;
26 import org.joda.time.DateTime;
27 import org.joda.time.DateTimeZone;
28 import org.joda.time.LocalTime;
29 import org.kuali.hr.time.clocklog.ClockLog;
30 import org.kuali.hr.time.service.base.TkServiceLocator;
31 import org.kuali.hr.time.timesheet.TimesheetDocument;
32 import org.kuali.hr.time.util.TKUtils;
33 import org.kuali.hr.time.util.TkConstants;
34 import org.kuali.rice.krad.document.Document;
35 import org.kuali.rice.krad.rules.TransactionalDocumentRuleBase;
36 import org.kuali.rice.krad.util.GlobalVariables;
37
38 public class MissedPunchValidation extends TransactionalDocumentRuleBase {
39
40
41
42
43
44
45
46
47
48 boolean validateClockAction(MissedPunchDocument mp, ClockLog lastClock) {
49 boolean valid = true;
50 Set<String> validActions = (lastClock != null) ? TkConstants.CLOCK_ACTION_TRANSITION_MAP.get(lastClock.getClockAction()) : new HashSet<String>();
51
52
53
54 if(lastClock != null
55 && (lastClock.getClockAction().equals(TkConstants.CLOCK_IN) || lastClock.getClockAction().equals(TkConstants.LUNCH_IN))) {
56 MissedPunchDocument mpd = TkServiceLocator.getMissedPunchService().getMissedPunchByClockLogId(lastClock.getTkClockLogId());
57 if(mpd != null) {
58 GlobalVariables.getMessageMap().putError("document.clockAction", "clock.mp.onlyOne.action");
59 return false;
60 }
61 }
62 if (!StringUtils.equals("A", mp.getDocumentStatus()) && !validActions.contains(mp.getClockAction())) {
63 GlobalVariables.getMessageMap().putError("document.clockAction", "clock.mp.invalid.action");
64 valid = false;
65 }
66
67 return valid;
68 }
69
70
71
72
73
74
75
76
77
78
79
80 boolean validateClockTime(MissedPunchDocument mp, ClockLog lastClock) throws ParseException {
81 boolean valid = true;
82
83 if (lastClock == null)
84 return valid;
85
86
87 if(mp.getActionTime() == null || mp.getActionDate() == null)
88 return false;
89
90 DateTime clockLogDateTime = new DateTime(lastClock.getClockTimestamp().getTime());
91 DateTime boundaryMax = clockLogDateTime.plusDays(1);
92 DateTime nowTime = new DateTime(TKUtils.getCurrentDate());
93
94 SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
95 String s = formatter.format(mp.getActionDate());
96 Date tempDate = formatter.parse(s);
97 Timestamp dateLocal = new Timestamp(tempDate.getTime());
98 LocalTime timeLocal = new LocalTime(mp.getActionTime().getTime());
99 DateTime actionDateTime = new DateTime(dateLocal.getTime());
100 actionDateTime = actionDateTime.plus(timeLocal.getMillisOfDay());
101
102
103 Timestamp ts = new Timestamp(actionDateTime.getMillis());
104 ClockLog lastLog = TkServiceLocator.getClockLogService().getLastClockLog(mp.getPrincipalId());
105 Long zoneOffset = TkServiceLocator.getTimezoneService().getTimezoneOffsetFromServerTime(DateTimeZone.forID(lastLog.getClockTimestampTimezone()));
106 Timestamp actionTime = new Timestamp(ts.getTime()-zoneOffset);
107 DateTime newDateTime = new DateTime(actionTime.getTime());
108
109
110 if(actionDateTime.getYear()> nowTime.getYear()
111 || (actionDateTime.getYear()==nowTime.getYear() && actionDateTime.getDayOfYear() > nowTime.getDayOfYear())) {
112 GlobalVariables.getMessageMap().putError("document.actionDate", "clock.mp.future.date");
113 return false;
114 }
115
116
117 if(actionDateTime.getMillis() > nowTime.getMillis()) {
118 GlobalVariables.getMessageMap().putError("document.actionTime", "clock.mp.future.time");
119 return false;
120 }
121
122 if ( ((!StringUtils.equals(lastClock.getClockAction(), TkConstants.CLOCK_OUT) && actionDateTime.isAfter(boundaryMax))
123 || newDateTime.isBefore(clockLogDateTime)) && StringUtils.equals(mp.getDocumentStatus(),"R")) {
124 GlobalVariables.getMessageMap().putError("document.actionTime", "clock.mp.invalid.datetime");
125 valid = false;
126 }
127
128 return valid;
129 }
130
131
132 boolean validateTimeSheet(MissedPunchDocument mp) {
133 boolean valid = true;
134 TimesheetDocument tsd = TkServiceLocator.getTimesheetService().getTimesheetDocument(mp.getTimesheetDocumentId());
135 if(tsd != null
136 && (tsd.getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.ENROUTE)
137 || tsd.getDocumentHeader().getDocumentStatus().equals(TkConstants.ROUTE_STATUS.FINAL))) {
138 GlobalVariables.getMessageMap().putError("document.timesheetDocumentId", "clock.mp.invalid.timesheet");
139 valid = false;
140 }
141
142 return valid;
143 }
144 @Override
145 public boolean processRouteDocument(Document document) {
146 boolean ret = super.processRouteDocument(document);
147 MissedPunchDocument mpDoc = (MissedPunchDocument)document;
148 if(!validateTimeSheet(mpDoc)) {
149 return false;
150 }
151 ClockLog lastClock = TkServiceLocator.getClockLogService().getLastClockLog(mpDoc.getPrincipalId());
152 ret &= validateClockAction(mpDoc, lastClock);
153 try {
154 ret &= validateClockTime(mpDoc, lastClock);
155 } catch (ParseException e) {
156
157 e.printStackTrace();
158 }
159
160 return ret;
161 }
162 }