1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.kpme.tklm.time.batch;
17
18
19 import org.apache.commons.lang.StringUtils;
20 import org.joda.time.DateTime;
21 import org.joda.time.LocalDate;
22 import org.joda.time.Period;
23 import org.kuali.kpme.core.api.assignment.Assignment;
24 import org.kuali.kpme.core.api.calendar.Calendar;
25 import org.kuali.kpme.core.api.calendar.entry.CalendarEntry;
26 import org.kuali.kpme.core.api.namespace.KPMENamespace;
27 import org.kuali.kpme.core.batch.BatchJob;
28 import org.kuali.kpme.core.batch.BatchJobUtil;
29 import org.kuali.kpme.core.role.KPMERole;
30 import org.kuali.kpme.core.service.HrServiceLocator;
31 import org.kuali.kpme.core.util.TKUtils;
32 import org.kuali.kpme.tklm.api.common.TkConstants;
33 import org.kuali.kpme.tklm.api.time.clocklog.ClockLog;
34 import org.kuali.kpme.tklm.time.clocklog.ClockLogBo;
35 import org.kuali.kpme.tklm.time.clocklog.exception.InvalidClockLogException;
36 import org.kuali.kpme.tklm.time.service.TkServiceLocator;
37 import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
38 import org.kuali.rice.core.api.config.property.ConfigContext;
39 import org.kuali.rice.kew.api.KewApiServiceLocator;
40 import org.kuali.rice.kew.api.note.Note;
41 import org.kuali.rice.kim.api.identity.Person;
42 import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
43 import org.kuali.rice.kim.api.role.RoleMember;
44 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
45 import org.quartz.JobExecutionContext;
46 import org.quartz.JobExecutionException;
47
48 import java.math.BigDecimal;
49 import java.text.SimpleDateFormat;
50 import java.util.List;
51 import java.util.HashSet;
52 import java.util.Set;
53
54 public class ClockedInEmployeeJob extends BatchJob {
55
56
57 public void execute(JobExecutionContext context) throws JobExecutionException {
58
59 BigDecimal hourLimit = getHourLimit();
60 String jobAction = getJobAction();
61 String batchJobPrincipalId = BatchJobUtil.getBatchUserPrincipalId();
62
63
64
65
66
67 DateTime asOfDate = new LocalDate().toDateTimeAtStartOfDay();
68 List<CalendarEntry> calendarEntries = HrServiceLocator.getCalendarEntryService().getCurrentCalendarEntriesNeedsScheduled(30, asOfDate);
69
70 for (CalendarEntry calendarEntry : calendarEntries) {
71 Calendar calendar = HrServiceLocator.getCalendarService().getCalendar(calendarEntry.getHrCalendarId());
72 if (StringUtils.equals(calendar.getCalendarTypes(), "Pay")) {
73 DateTime beginDate = calendarEntry.getBeginPeriodFullDateTime();
74 DateTime endDate = calendarEntry.getEndPeriodFullDateTime();
75
76 List<TimesheetDocumentHeader> timesheetDocumentHeaders = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate);
77
78 for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) {
79 String principalId = timesheetDocumentHeader.getPrincipalId();
80 List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAllAssignmentsByCalEntryForTimeCalendar(principalId, calendarEntry);
81 for (Assignment assignment : assignments) {
82 String groupKeyCode = assignment.getGroupKeyCode();
83 String jobNumber = String.valueOf(assignment.getJobNumber());
84 String workArea = String.valueOf(assignment.getWorkArea());
85 String task = String.valueOf(assignment.getTask());
86 ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog(groupKeyCode, principalId, jobNumber, workArea, task, calendarEntry);
87 if (lastClockLog != null && TkConstants.ON_THE_CLOCK_CODES.contains(lastClockLog.getClockAction())) {
88 DateTime lastClockLogDateTime = lastClockLog.getClockDateTime();
89 DateTime currentDate = new DateTime();
90
91 Period p = new Period(lastClockLogDateTime, currentDate);
92 BigDecimal hoursBetween = new BigDecimal(p.getHours());
93 BigDecimal dayHours = new BigDecimal(p.getDays() * 24);
94 hoursBetween = hoursBetween.add(dayHours);
95
96 if (hoursBetween.compareTo(hourLimit) > 0) {
97 if (jobAction.equals("NOTIFY")) {
98
99
100 for (Person approver : getApprovers(assignment.getWorkArea())) {
101 EntityNamePrincipalName employee = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(principalId);
102 String approverSubject = "Employee Clocked In Over " + hourLimit.toString() + " Hours Notification";
103 StringBuilder approverNotification = new StringBuilder();
104 approverNotification.append(employee.getPrincipalName() + " (" + principalId + ") has been clocked in since ");
105 SimpleDateFormat sdf = new SimpleDateFormat("EEEE, MMMM d yyyy HH:mm a");
106 String dateTime = sdf.format(new java.sql.Date(lastClockLog.getClockDateTime().getMillis()));
107 approverNotification.append(dateTime);
108 approverNotification.append(" for work area " + assignment.getWorkAreaObj().getDescription());
109 HrServiceLocator.getKPMENotificationService().sendNotification(approverSubject, approverNotification.toString(), approver.getPrincipalId());
110 }
111
112
113
114
115
116
117
118
119
120
121
122 } else if (jobAction.equals("CLOCK_OUT")) {
123
124
125 ClockLog clockOut = null;
126 try {
127 clockOut = TkServiceLocator.getClockLogService().processClockLog(principalId, timesheetDocumentHeader.getDocumentId(), currentDate, assignment, calendarEntry, TKUtils.getIPNumber(),
128 currentDate.toLocalDate(), "CO", true, batchJobPrincipalId);
129
130 TkServiceLocator.getClockLogService().saveClockLog(clockOut);
131 }
132 catch (InvalidClockLogException e)
133 {
134 throw new RuntimeException("Could not take the action as Action taken from an invalid IP address.");
135 }
136
137
138 String employeeSubject = "You have been clocked out of " + assignment.getAssignmentDescription();
139 StringBuilder employeeNotification = new StringBuilder();
140 employeeNotification.append("You have been Clocked out of " + assignment.getAssignmentDescription() + " on " + clockOut.getClockDateTime());
141 HrServiceLocator.getKPMENotificationService().sendNotification(employeeSubject, employeeNotification.toString(), principalId);
142
143
144
145 Note.Builder builder = Note.Builder.create(timesheetDocumentHeader.getDocumentId(), batchJobPrincipalId);
146 builder.setCreateDate(new DateTime());
147 builder.setText("Clock out from " + assignment.getAssignmentDescription() + " on " + clockOut.getClockDateTime() + " was initiated by the Clocked In Employee Batch Job");
148 KewApiServiceLocator.getNoteService().createNote(builder.build());
149 }
150
151
152 }
153 }
154 }
155 }
156 }
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174 }
175
176 private Set<Person> getApprovers(Long workArea) {
177 Set<Person> approvers = new HashSet<Person>();
178 DateTime date = LocalDate.now().toDateTimeAtStartOfDay();
179 List<RoleMember> roleMembers = HrServiceLocator.getKPMERoleService().getRoleMembersInWorkArea(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER.getRoleName(), workArea, date, true);
180
181 for (RoleMember roleMember : roleMembers) {
182 Person person = KimApiServiceLocator.getPersonService().getPerson(roleMember.getMemberId());
183 if (person != null) {
184 approvers.add(person);
185 }
186 }
187
188 return approvers;
189 }
190
191 private BigDecimal getHourLimit() {
192 String hourLimitString = ConfigContext.getCurrentContextConfig().getProperty("kpme.batch.clockedInEmployee.hourLimit");
193 BigDecimal hourLimit = new BigDecimal(hourLimitString);
194 return hourLimit;
195 }
196
197 private String getJobAction() {
198 return ConfigContext.getCurrentContextConfig().getProperty("kpme.batch.clockedInEmployee.jobAction");
199 }
200 }