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.service.TkServiceLocator;
36  import org.kuali.kpme.tklm.time.workflow.TimesheetDocumentHeader;
37  import org.kuali.rice.core.api.config.property.ConfigContext;
38  import org.kuali.rice.kew.api.KewApiServiceLocator;
39  import org.kuali.rice.kew.api.note.Note;
40  import org.kuali.rice.kim.api.identity.Person;
41  import org.kuali.rice.kim.api.identity.principal.EntityNamePrincipalName;
42  import org.kuali.rice.kim.api.role.RoleMember;
43  import org.kuali.rice.kim.api.services.KimApiServiceLocator;
44  import org.quartz.JobExecutionContext;
45  import org.quartz.JobExecutionException;
46  
47  import java.math.BigDecimal;
48  import java.text.SimpleDateFormat;
49  import java.util.List;
50  import java.util.HashSet;
51  import java.util.Set;
52  
53  public class ClockedInEmployeeJob extends BatchJob {
54  
55  
56      public void execute(JobExecutionContext context) throws JobExecutionException {
57          //Get Configuration Settings
58          BigDecimal hourLimit = getHourLimit();
59          String jobAction = getJobAction();
60          String batchJobPrincipalId = BatchJobUtil.getBatchUserPrincipalId();
61  
62  
63          // code to send one email per approver
64          // Map<String, Map<String, String>> notificationMap = new HashMap<String, Map<String, String>>();
65  
66          DateTime asOfDate = new LocalDate().toDateTimeAtStartOfDay();
67          List<CalendarEntry> calendarEntries = HrServiceLocator.getCalendarEntryService().getCurrentCalendarEntriesNeedsScheduled(30, asOfDate);
68  
69          for (CalendarEntry calendarEntry : calendarEntries) {
70              Calendar calendar = HrServiceLocator.getCalendarService().getCalendar(calendarEntry.getHrCalendarId());
71              if (StringUtils.equals(calendar.getCalendarTypes(), "Pay")) {
72                  DateTime beginDate = calendarEntry.getBeginPeriodFullDateTime();
73                  DateTime endDate = calendarEntry.getEndPeriodFullDateTime();
74  
75                  List<TimesheetDocumentHeader> timesheetDocumentHeaders = TkServiceLocator.getTimesheetDocumentHeaderService().getDocumentHeaders(beginDate, endDate);
76  
77                  for (TimesheetDocumentHeader timesheetDocumentHeader : timesheetDocumentHeaders) {
78                      String principalId = timesheetDocumentHeader.getPrincipalId();
79                      List<Assignment> assignments = HrServiceLocator.getAssignmentService().getAllAssignmentsByCalEntryForTimeCalendar(principalId, calendarEntry);
80                      for (Assignment assignment : assignments) {
81                      	String groupKeyCode = assignment.getGroupKeyCode();
82                          String jobNumber = String.valueOf(assignment.getJobNumber());
83                          String workArea = String.valueOf(assignment.getWorkArea());
84                          String task = String.valueOf(assignment.getTask());
85                          ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog(groupKeyCode, principalId, jobNumber, workArea, task, calendarEntry);
86                          if (lastClockLog != null && TkConstants.ON_THE_CLOCK_CODES.contains(lastClockLog.getClockAction())) {
87                              DateTime lastClockLogDateTime = lastClockLog.getClockDateTime();
88                              DateTime currentDate = new DateTime();
89  
90                              Period p = new Period(lastClockLogDateTime, currentDate);
91                              BigDecimal hoursBetween = new BigDecimal(p.getHours());
92                              BigDecimal dayHours = new BigDecimal(p.getDays() * 24);
93                              hoursBetween = hoursBetween.add(dayHours);
94  
95                              if (hoursBetween.compareTo(hourLimit) > 0) {
96                                  if (jobAction.equals("NOTIFY")) {
97  
98                                      //code to send one notification per employee to all approvers of employee
99                                      for (Person approver : getApprovers(assignment.getWorkArea())) {
100                                         EntityNamePrincipalName employee = KimApiServiceLocator.getIdentityService().getDefaultNamesForPrincipalId(principalId);
101                                         String approverSubject = "Employee Clocked In Over " + hourLimit.toString() + " Hours Notification";
102                                         StringBuilder approverNotification = new StringBuilder();
103                                         approverNotification.append(employee.getPrincipalName() + " (" + principalId + ") has been clocked in since ");
104                                         SimpleDateFormat sdf = new SimpleDateFormat("EEEE, MMMM d yyyy HH:mm a");
105                                         String dateTime = sdf.format(new java.sql.Date(lastClockLog.getClockDateTime().getMillis()));
106                                         approverNotification.append(dateTime);
107                                         approverNotification.append(" for work area " + assignment.getWorkAreaObj().getDescription());
108                                         HrServiceLocator.getKPMENotificationService().sendNotification(approverSubject, approverNotification.toString(), approver.getPrincipalId());
109                                     }
110 
111                                 /* Code to send one email per approver - Create notification
112                                 Map<String, String> hourInfo = new HashMap<String, String>();
113                                 hourInfo.put(principalId, hoursBetween.toString());
114                                 for (Person person : getApprovers(lastClockLog.getWorkArea())) {
115                                     if (notificationMap.containsKey(person.getPrincipalId())) {
116                                         notificationMap.get(person.getPrincipalId()).put(principalId, hoursBetween.toString());
117                                     } else {
118                                         notificationMap.put(person.getPrincipalId(), hourInfo);
119                                     }
120                                 } */
121                                 } else if (jobAction.equals("CLOCK_OUT")) {
122                                     //Clock User Out
123                                     ClockLog clockOut = TkServiceLocator.getClockLogService().processClockLog(principalId, timesheetDocumentHeader.getDocumentId(), currentDate, assignment, calendarEntry, TKUtils.getIPNumber(),
124                                             currentDate.toLocalDate(), "CO", true, batchJobPrincipalId);
125 
126                                     TkServiceLocator.getClockLogService().saveClockLog(clockOut);
127 
128                                     // Notify User
129                                     String employeeSubject = "You have been clocked out of " + assignment.getAssignmentDescription();
130                                     StringBuilder employeeNotification = new StringBuilder();
131                                     employeeNotification.append("You have been Clocked out of " + assignment.getAssignmentDescription() + " on " + clockOut.getClockDateTime());
132                                     HrServiceLocator.getKPMENotificationService().sendNotification(employeeSubject, employeeNotification.toString(), principalId);
133 
134 
135                                     //add Note to time sheet
136                                     Note.Builder builder = Note.Builder.create(timesheetDocumentHeader.getDocumentId(), batchJobPrincipalId);
137                                     builder.setCreateDate(new DateTime());
138                                     builder.setText("Clock out from " + assignment.getAssignmentDescription() + " on " + clockOut.getClockDateTime() + " was initiated by the Clocked In Employee Batch Job");
139                                     KewApiServiceLocator.getNoteService().createNote(builder.build());
140                                 }
141 
142 
143                             }
144                         }
145                     }
146                 }
147             }
148         }
149 
150         /* code to send one email per approver
151         for (Map.Entry<String, Map<String, String>> approverEntry : notificationMap.entrySet()) {
152             String subject = "Users clocked in over " + hourLimit.toString() + " hours";
153             StringBuilder notification = new StringBuilder();
154             notification.append("The following users have been clocked in for over " + hourLimit.toString() + " hours:");
155             notification.append(SystemUtils.LINE_SEPARATOR);
156             for (Map.Entry<String, String> employeeEntry : approverEntry.getValue().entrySet()) {
157                 notification.append(KimApiServiceLocator.getPersonService().getPerson(employeeEntry.getKey()).getPrincipalName());
158                 notification.append(" (" + employeeEntry.getKey() + ") : " + employeeEntry.getValue() + " hours");
159                 notification.append(SystemUtils.LINE_SEPARATOR);
160             }
161             HrServiceLocator.getKPMENotificationService().sendNotification(subject, notification.toString(), approverEntry.getKey());
162         }
163         */
164 
165     }
166 
167     private Set<Person> getApprovers(Long workArea) {
168         Set<Person> approvers = new HashSet<Person>();
169         DateTime date = LocalDate.now().toDateTimeAtStartOfDay();
170         List<RoleMember> roleMembers = HrServiceLocator.getKPMERoleService().getRoleMembersInWorkArea(KPMENamespace.KPME_HR.getNamespaceCode(), KPMERole.APPROVER.getRoleName(), workArea, date, true);
171 
172         for (RoleMember roleMember : roleMembers) {
173             Person person = KimApiServiceLocator.getPersonService().getPerson(roleMember.getMemberId());
174             if (person != null) {
175                 approvers.add(person);
176             }
177         }
178 
179         return approvers;
180     }
181 
182     private BigDecimal getHourLimit() {
183         String hourLimitString = ConfigContext.getCurrentContextConfig().getProperty("kpme.batch.clockedInEmployee.hourLimit");
184         BigDecimal hourLimit = new BigDecimal(hourLimitString);
185         return hourLimit;
186     }
187 
188     private String getJobAction() {
189         return ConfigContext.getCurrentContextConfig().getProperty("kpme.batch.clockedInEmployee.jobAction");
190     }
191 }