001    /**
002     * Copyright 2004-2013 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.kuali.hr.time.mobile.service;
017    
018    import java.sql.Date;
019    import java.sql.Timestamp;
020    import java.util.ArrayList;
021    import java.util.HashMap;
022    import java.util.List;
023    import java.util.Map;
024    
025    import org.apache.commons.lang.StringUtils;
026    import org.kuali.hr.time.assignment.Assignment;
027    import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
028    import org.kuali.hr.time.calendar.CalendarEntries;
029    import org.kuali.hr.time.clocklog.ClockLog;
030    import org.kuali.hr.time.service.base.TkServiceLocator;
031    import org.kuali.hr.time.timesheet.TimesheetDocument;
032    import org.kuali.hr.time.util.TKContext;
033    import org.kuali.hr.time.util.TKUser;
034    import org.kuali.hr.time.util.TKUtils;
035    import org.kuali.hr.time.util.TkConstants;
036    import org.kuali.rice.kew.api.exception.WorkflowException;
037    import org.kuali.rice.kim.api.identity.Person;
038    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
039    
040    import com.google.gson.Gson;
041    
042    public class TkMobileServiceImpl implements TkMobileService {
043    
044            @Override
045            public String getClockEntryInfo(String principalId) {
046                    ClockEntryInfo clockEntryInfo = new ClockEntryInfo();
047                    ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog(principalId);
048                    if(lastClockLog != null){
049                            clockEntryInfo.setLastClockLogDescription(getLastClockLogDescription(principalId));
050                    }
051                    List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, TKUtils.getCurrentDate());
052    
053                    for(Assignment assignment : assignments){
054                            if(assignment.isSynchronous()){
055                                    String key = new AssignmentDescriptionKey(assignment).toAssignmentKeyString();
056                                    String desc = assignment.getAssignmentDescription();
057                                    clockEntryInfo.getAssignKeyToAssignmentDescriptions().put(key, desc);
058                            }
059                    }
060                    List<String> clockActions = getClockActions(principalId);
061                    clockEntryInfo.setClockActions(clockActions);
062                    return new Gson().toJson(clockEntryInfo);
063            }
064    
065            @Override
066            public Map<String,List<String>> addClockAction(String principalId, String assignmentKey, String clockAction) {
067                    HashMap<String,List<String>> errorWarningMap = new HashMap<String,List<String>>();
068    
069            // Set person on the context
070            // This is primary for getting the assignment, since we get the assignment by using the target principal id on the context
071            TKUser.setTargetPerson(principalId);
072    
073                    Assignment assignment = TkServiceLocator.getAssignmentService().getAssignment(new AssignmentDescriptionKey(assignmentKey), TKUtils.getCurrentDate());
074            Date currentDate = TKUtils.getCurrentDate();
075            CalendarEntries calendarEntries = TkServiceLocator.getCalendarService().getCurrentCalendarDates(principalId,  currentDate);
076            TimesheetDocument td;
077                    try {
078                            td = TkServiceLocator.getTimesheetService().openTimesheetDocument(principalId, calendarEntries);
079                    } catch (WorkflowException e) {
080                            throw new RuntimeException("Could not open timesheet");
081                    }
082            
083                    String ip = TKUtils.getIPAddressFromRequest(TKContext.getHttpServletRequest());
084            Timestamp currentTs = new Timestamp(System.currentTimeMillis());
085    
086            // processClockLog is the correct method to use. It creates and persists a clock log and a time block if necessary.
087            // buildClockLog just creates a clock log object.
088            TkServiceLocator.getClockLogService().processClockLog(currentTs, assignment, td.getCalendarEntry(), ip,
089                    new java.sql.Date(currentTs.getTime()), td, getCurrentClockAction(), principalId);
090    
091            // TODO: not sure what we want to return for the errorWarningMap
092    
093                    return errorWarningMap;
094            }
095            
096            private String getLastClockLogDescription(String principalId){
097                    ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog(principalId);
098                    if(lastClockLog != null){
099                            String lastClockDescription;
100                            if(StringUtils.equals(lastClockLog.getClockAction(), "CI")){
101                                    lastClockDescription = "Clocked in since : ";
102                            } else if(StringUtils.equals(lastClockLog.getClockAction(), "CO")){
103                                    lastClockDescription = "Clocked out since : ";
104                            } else if(StringUtils.equals(lastClockLog.getClockAction(), "LI")){
105                                    lastClockDescription = "Returned from lunch since :";
106                            } else {
107                                    lastClockDescription = "At lunch since :";
108                            }
109                            //TODO convert for timezone
110                            
111                            lastClockDescription += TKUtils.formatDateTime(lastClockLog.getClockTimestamp());
112                            return lastClockDescription;
113                    }
114                    return "";
115            }
116            
117            private List<String> getClockActions(String principalId){
118                    ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog(principalId);
119                    List<String> clockActions = new ArrayList<String>();
120                    if(lastClockLog != null){
121                            if(StringUtils.equals(lastClockLog.getClockAction(), "CI")){
122                                    clockActions.add("Clock Out");
123                                    clockActions.add("Lunch Out");
124                            } else if(StringUtils.equals(lastClockLog.getClockAction(), "CO")){
125                                    clockActions.add("Clock In");
126                            } else if(StringUtils.equals(lastClockLog.getClockAction(), "LI")){
127                                    clockActions.add("Clock Out");
128                            } else {
129                                    clockActions.add("Lunch In");
130                            }
131                    }
132                    return clockActions;
133            }
134    
135        private String getCurrentClockAction() {
136            ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog(TKContext.getTargetPrincipalId());
137            String currentClockAction = "";
138            if(lastClockLog != null){
139                            if(StringUtils.equals(lastClockLog.getClockAction(), TkConstants.CLOCK_IN)){
140                                    currentClockAction = TkConstants.CLOCK_OUT;
141                            } else if(StringUtils.equals(lastClockLog.getClockAction(), TkConstants.CLOCK_OUT)){
142                                    currentClockAction = TkConstants.CLOCK_IN;
143                            } else if(StringUtils.equals(lastClockLog.getClockAction(), TkConstants.LUNCH_IN)){
144                                    currentClockAction = TkConstants.LUNCH_OUT;
145                            } else {
146                                    currentClockAction = TkConstants.LUNCH_IN;
147                            }
148                    }
149                    return currentClockAction;
150        }
151    
152    }