View Javadoc
1   /**
2    * Copyright 2004-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
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          //Get Configuration Settings
59          BigDecimal hourLimit = getHourLimit();
60          String jobAction = getJobAction();
61          String batchJobPrincipalId = BatchJobUtil.getBatchUserPrincipalId();
62  
63  
64          // code to send one email per approver
65          // Map<String, Map<String, String>> notificationMap = new HashMap<String, Map<String, String>>();
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                                      //code to send one notification per employee to all approvers of employee
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                                 /* Code to send one email per approver - Create notification
113                                 Map<String, String> hourInfo = new HashMap<String, String>();
114                                 hourInfo.put(principalId, hoursBetween.toString());
115                                 for (Person person : getApprovers(lastClockLog.getWorkArea())) {
116                                     if (notificationMap.containsKey(person.getPrincipalId())) {
117                                         notificationMap.get(person.getPrincipalId()).put(principalId, hoursBetween.toString());
118                                     } else {
119                                         notificationMap.put(person.getPrincipalId(), hourInfo);
120                                     }
121                                 } */
122                                 } else if (jobAction.equals("CLOCK_OUT")) {
123                                     //Clock User Out
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                                     // Notify User
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                                     //add Note to time sheet
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         /* code to send one email per approver
160         for (Map.Entry<String, Map<String, String>> approverEntry : notificationMap.entrySet()) {
161             String subject = "Users clocked in over " + hourLimit.toString() + " hours";
162             StringBuilder notification = new StringBuilder();
163             notification.append("The following users have been clocked in for over " + hourLimit.toString() + " hours:");
164             notification.append(SystemUtils.LINE_SEPARATOR);
165             for (Map.Entry<String, String> employeeEntry : approverEntry.getValue().entrySet()) {
166                 notification.append(KimApiServiceLocator.getPersonService().getPerson(employeeEntry.getKey()).getPrincipalName());
167                 notification.append(" (" + employeeEntry.getKey() + ") : " + employeeEntry.getValue() + " hours");
168                 notification.append(SystemUtils.LINE_SEPARATOR);
169             }
170             HrServiceLocator.getKPMENotificationService().sendNotification(subject, notification.toString(), approverEntry.getKey());
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 }