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    
024    import org.apache.commons.lang.StringUtils;
025    import org.kuali.hr.time.assignment.Assignment;
026    import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
027    import org.kuali.hr.time.calendar.CalendarEntries;
028    import org.kuali.hr.time.clocklog.ClockLog;
029    import org.kuali.hr.time.service.base.TkServiceLocator;
030    import org.kuali.hr.time.timesheet.TimesheetDocument;
031    import org.kuali.hr.time.util.TKContext;
032    import org.kuali.hr.time.util.TKUser;
033    import org.kuali.hr.time.util.TKUtils;
034    import org.kuali.hr.time.util.TkConstants;
035    import org.kuali.rice.kew.api.exception.WorkflowException;
036    import org.kuali.rice.kim.api.identity.Person;
037    import org.kuali.rice.kim.api.services.KimApiServiceLocator;
038    
039    import com.google.gson.Gson;
040    
041    public class TkMobileServiceImpl implements TkMobileService {
042    
043            @Override
044            public String getClockEntryInfo(String principalId) {
045                    ClockEntryInfo clockEntryInfo = new ClockEntryInfo();
046                    ClockLog lastClockLog = TkServiceLocator.getClockLogService().getLastClockLog(principalId);
047                    if(lastClockLog != null){
048                            clockEntryInfo.setLastClockLogDescription(getLastClockLogDescription(principalId));
049                    }
050                    List<Assignment> assignments = TkServiceLocator.getAssignmentService().getAssignments(principalId, TKUtils.getCurrentDate());
051    
052                    for(Assignment assignment : assignments){
053                            if(assignment.isSynchronous()){
054                                    String key = new AssignmentDescriptionKey(assignment).toAssignmentKeyString();
055                                    String desc = assignment.getAssignmentDescription();
056                                    clockEntryInfo.getAssignKeyToAssignmentDescriptions().put(key, desc);
057                            }
058                    }
059                    List<String> clockActions = getClockActions(principalId);
060                    clockEntryInfo.setClockActions(clockActions);
061                    return new Gson().toJson(clockEntryInfo);
062            }
063    
064            @Override
065            public HashMap<String,List<String>> addClockAction(String principalId, String assignmentKey, String clockAction) {
066                    HashMap<String,List<String>> errorWarningMap = new HashMap<String,List<String>>();
067    
068            // Set person on the context
069            // This is primary for getting the assignment, since we get the assignment by using the target principal id on the context
070            Person person = KimApiServiceLocator.getPersonService().getPerson(principalId);
071            TKUser.setTargetPerson(person);
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    }