View Javadoc

1   /**
2    * Copyright 2004-2013 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.hr.time.clocklog.service;
17  
18  import org.apache.commons.collections.CollectionUtils;
19  import org.apache.commons.lang.StringUtils;
20  import org.kuali.hr.time.assignment.Assignment;
21  import org.kuali.hr.time.calendar.CalendarEntries;
22  import org.kuali.hr.time.clocklog.ClockLog;
23  import org.kuali.hr.time.clocklog.dao.ClockLogDao;
24  import org.kuali.hr.time.service.base.TkServiceLocator;
25  import org.kuali.hr.time.timeblock.TimeBlock;
26  import org.kuali.hr.time.timesheet.TimesheetDocument;
27  import org.kuali.hr.time.util.TKContext;
28  import org.kuali.hr.time.util.TkConstants;
29  
30  import java.math.BigDecimal;
31  import java.sql.Timestamp;
32  import java.util.ArrayList;
33  import java.util.HashSet;
34  import java.util.List;
35  import java.util.Set;
36  
37  public class ClockLogServiceImpl implements ClockLogService {
38  
39      private ClockLogDao clockLogDao;
40  
41      public ClockLogServiceImpl() {
42      }
43  
44      public void saveClockLog(ClockLog clockLog) {
45          clockLogDao.saveOrUpdate(clockLog);
46      }
47  
48      @Override
49      public ClockLog processClockLog(Timestamp clockTimeStamp, Assignment assignment,CalendarEntries pe, String ip, java.sql.Date asOfDate, TimesheetDocument td, String clockAction, String principalId) {
50          return processClockLog(clockTimeStamp, assignment, pe, ip, asOfDate, td, clockAction, principalId, TKContext.getPrincipalId());
51      }
52  
53      @Override
54      public ClockLog processClockLog(Timestamp clockTimeStamp, Assignment assignment,CalendarEntries pe, String ip, java.sql.Date asOfDate, TimesheetDocument td, String clockAction, String principalId, String userPrincipalId) {
55          // process rules
56          Timestamp roundedClockTimestamp = TkServiceLocator.getGracePeriodService().processGracePeriodRule(clockTimeStamp, new java.sql.Date(pe.getBeginPeriodDateTime().getTime()));
57  
58          ClockLog clockLog = TkServiceLocator.getClockLogService().buildClockLog(roundedClockTimestamp, new Timestamp(System.currentTimeMillis()), assignment, td, clockAction, ip, userPrincipalId);
59          TkServiceLocator.getClockLocationRuleService().processClockLocationRule(clockLog, asOfDate);
60  
61          // If the clock action is clock out or lunch out, create a time block besides the clock log
62          if (StringUtils.equals(clockAction, TkConstants.CLOCK_OUT) || StringUtils.equals(clockAction, TkConstants.LUNCH_OUT)) {
63              processTimeBlock(clockLog, assignment, pe, td, clockAction, principalId);
64          } else {
65              //Save current clock log to get id for timeblock building
66              TkServiceLocator.getClockLogService().saveClockLog(clockLog);
67          }
68  
69          return clockLog;
70      }
71  
72      private void processTimeBlock(ClockLog clockLog, Assignment assignment, CalendarEntries pe, TimesheetDocument td, String clockAction, String principalId) {
73          ClockLog lastLog = null;
74          Timestamp lastClockTimestamp = null;
75          String beginClockLogId = null;
76          String endClockLogId = null;
77  
78          if (StringUtils.equals(clockAction, TkConstants.LUNCH_OUT)) {
79              lastLog = TkServiceLocator.getClockLogService().getLastClockLog(principalId, TkConstants.CLOCK_IN);
80          } else if (StringUtils.equals(clockAction, TkConstants.CLOCK_OUT)) {
81              lastLog = TkServiceLocator.getClockLogService().getLastClockLog(principalId);
82          }
83          if (lastLog != null) {
84              lastClockTimestamp = lastLog.getClockTimestamp();
85              beginClockLogId = lastLog.getTkClockLogId();
86          }
87          //Save current clock log to get id for timeblock building
88          TkServiceLocator.getClockLogService().saveClockLog(clockLog);
89          endClockLogId = clockLog.getTkClockLogId();
90  
91          long beginTime = lastClockTimestamp.getTime();
92          Timestamp beginTimestamp = new Timestamp(beginTime);
93          Timestamp endTimestamp = clockLog.getClockTimestamp();
94  
95          // New Time Blocks, pointer reference
96          List<TimeBlock> newTimeBlocks = td.getTimeBlocks();
97          List<TimeBlock> referenceTimeBlocks = new ArrayList<TimeBlock>(td.getTimeBlocks().size());
98          for (TimeBlock tb : td.getTimeBlocks()) {
99              referenceTimeBlocks.add(tb.copy());
100         }
101 
102         // Add TimeBlocks after we store our reference object!
103         List<TimeBlock> aList = TkServiceLocator.getTimeBlockService().buildTimeBlocks(assignment, assignment.getJob().getPayTypeObj().getRegEarnCode(), td, beginTimestamp, endTimestamp, BigDecimal.ZERO, BigDecimal.ZERO, true, false);
104         for (TimeBlock tb : aList) {
105             tb.setClockLogBeginId(beginClockLogId);
106             tb.setClockLogEndId(endClockLogId);
107         }
108         newTimeBlocks.addAll(aList);
109 
110         //reset time block
111         TkServiceLocator.getTimesheetService().resetTimeBlock(newTimeBlocks);
112 
113         //apply any rules for this action
114         TkServiceLocator.getTkRuleControllerService().applyRules(TkConstants.ACTIONS.CLOCK_OUT, newTimeBlocks, pe, td, principalId);
115 
116         //call persist method that only saves added/deleted/changed timeblocks
117         TkServiceLocator.getTimeBlockService().saveTimeBlocks(referenceTimeBlocks, newTimeBlocks);
118     }
119 
120     @Override
121     public ClockLog buildClockLog(Timestamp clockTimestamp, Timestamp originalTimestamp, Assignment assignment, TimesheetDocument timesheetDocument, String clockAction, String ip) {
122         return buildClockLog(clockTimestamp, originalTimestamp, assignment, timesheetDocument, clockAction, ip, TKContext.getPrincipalId());
123     }
124 
125     @Override
126     public ClockLog buildClockLog(Timestamp clockTimestamp, Timestamp originalTimestamp, Assignment assignment, TimesheetDocument timesheetDocument, String clockAction, String ip, String userPrincipalId) {
127         String principalId = timesheetDocument.getPrincipalId();
128 
129         ClockLog clockLog = new ClockLog();
130         clockLog.setPrincipalId(principalId);
131         //        AssignmentDescriptionKey assignmentDesc = TkServiceLocator.getAssignmentService().getAssignmentDescriptionKey(selectedAssign);
132         //        Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(timesheetDocument, selectedAssign);
133         clockLog.setJob(timesheetDocument.getJob(assignment.getJobNumber()));
134         clockLog.setJobNumber(assignment.getJobNumber());
135         clockLog.setWorkArea(assignment.getWorkArea());
136         clockLog.setTask(assignment.getTask());
137         clockLog.setClockTimestampTimezone(TkServiceLocator.getTimezoneService().getUserTimezone());
138         clockLog.setClockTimestamp(clockTimestamp);
139         clockLog.setClockAction(clockAction);
140         clockLog.setIpAddress(ip);
141         clockLog.setUserPrincipalId(userPrincipalId);
142         // timestamp should be the original time without Grace Period rule applied
143         clockLog.setTimestamp(originalTimestamp);
144 
145         return clockLog;
146     }
147 
148     public void setClockLogDao(ClockLogDao clockLogDao) {
149         this.clockLogDao = clockLogDao;
150     }
151 
152     public ClockLog getLastClockLog(String principalId) {
153         return clockLogDao.getLastClockLog(principalId);
154     }
155 
156     public ClockLog getLastClockLog(String principalId, String clockAction) {
157         return clockLogDao.getLastClockLog(principalId, clockAction);
158     }
159 
160     public List<ClockLog> getOpenClockLogs(  CalendarEntries payCalendarEntry) {
161         return clockLogDao.getOpenClockLogs(payCalendarEntry);
162     }
163 
164     @Override
165     public ClockLog getClockLog(String tkClockLogId) {
166         return clockLogDao.getClockLog(tkClockLogId);
167     }
168 
169     public List<String> getUnapprovedIPWarning(List<TimeBlock> timeBlocks) {
170 		 List<String> warningMessages = new ArrayList<String>();
171 		 if (CollectionUtils.isNotEmpty(timeBlocks)) {
172 		     Set<String> aSet = new HashSet<String>();
173 		     for(TimeBlock tb : timeBlocks) {
174 		    	 if(tb.getClockLogCreated()) {
175 		    		 if(StringUtils.isNotEmpty(tb.getClockLogBeginId())){
176 		    			 ClockLog cl = TkServiceLocator.getClockLogService().getClockLog(tb.getClockLogBeginId());
177 		    			 if(cl.getUnapprovedIP()) {
178 		    				 aSet.add(buildUnapprovedIPWarning(cl));
179 		    			 }
180 		    		 }
181 		    		 if(StringUtils.isNotEmpty(tb.getClockLogEndId())){
182 		    			 ClockLog cl = TkServiceLocator.getClockLogService().getClockLog(tb.getClockLogEndId());
183 		    			 if(cl.getUnapprovedIP()) {
184 		    				 aSet.add(buildUnapprovedIPWarning(cl));
185 		    			 }
186 		    		 }		
187 		    	 }
188 		     }
189 		     warningMessages.addAll(aSet);
190 		}
191 		
192 		return warningMessages;
193     }
194 
195 	public String buildUnapprovedIPWarning(ClockLog cl) {
196 		String warning = "Warning: Action '" + TkConstants.CLOCK_ACTION_STRINGS.get(cl.getClockAction()) + "' taken at " 
197 			+ cl.getClockTimestamp() + " was from an unapproved IP address - " + cl.getIpAddress();
198 		return warning;
199 	}
200 
201 }