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.detail.web;
017    
018    import java.math.BigDecimal;
019    import java.util.ArrayList;
020    import java.util.HashMap;
021    import java.util.LinkedList;
022    import java.util.List;
023    import java.util.Map;
024    
025    import javax.servlet.http.HttpServletRequest;
026    import javax.servlet.http.HttpServletResponse;
027    
028    import org.apache.commons.lang.StringUtils;
029    import org.apache.log4j.Logger;
030    import org.apache.struts.action.ActionForm;
031    import org.apache.struts.action.ActionForward;
032    import org.apache.struts.action.ActionMapping;
033    import org.json.simple.JSONArray;
034    import org.json.simple.JSONValue;
035    import org.kuali.hr.job.Job;
036    import org.kuali.hr.lm.leaveSummary.LeaveSummary;
037    import org.kuali.hr.lm.leaveblock.LeaveBlock;
038    import org.kuali.hr.lm.leavecalendar.validation.LeaveCalendarValidationUtil;
039    import org.kuali.hr.time.assignment.Assignment;
040    import org.kuali.hr.time.assignment.AssignmentDescriptionKey;
041    import org.kuali.hr.time.calendar.CalendarEntries;
042    import org.kuali.hr.time.detail.validation.TimeDetailValidationUtil;
043    import org.kuali.hr.time.earncode.EarnCode;
044    import org.kuali.hr.time.paytype.PayType;
045    import org.kuali.hr.time.service.base.TkServiceLocator;
046    import org.kuali.hr.time.timesheet.TimesheetDocument;
047    import org.kuali.hr.time.timesheet.web.TimesheetAction;
048    import org.kuali.hr.time.util.TKContext;
049    import org.kuali.hr.time.util.TKUtils;
050    import org.kuali.rice.kns.web.struts.form.KualiMaintenanceForm;
051    import org.kuali.rice.krad.util.ObjectUtils;
052    
053    public class TimeDetailWSAction extends TimesheetAction {
054    
055        private static final Logger LOG = Logger.getLogger(TimeDetailWSAction.class);
056    
057        @Override
058        public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
059            return super.execute(mapping, form, request, response);
060        }
061    
062        /**
063         * This is an ajax call triggered after a user submits the time entry form.
064         * If there is any error, it will return error messages as a json object.
065         *
066         * @param mapping
067         * @param form
068         * @param request
069         * @param response
070         * @return jsonObj
071         * @throws Exception
072         */
073        @SuppressWarnings("unchecked")
074        public ActionForward validateTimeEntry(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
075            TimeDetailActionFormBase tdaf = (TimeDetailActionFormBase) form;
076            JSONArray errorMsgList = new JSONArray();
077            List<String> errors;
078            
079            EarnCode ec = TkServiceLocator.getEarnCodeService().getEarnCode(tdaf.getSelectedEarnCode(), tdaf.getTimesheetDocument().getAsOfDate());
080            if(ec != null 
081                            && (ec.getLeavePlan() != null || ec.getEligibleForAccrual().equals("N"))) {     // leave blocks changes
082                    errors = this.validateLeaveEntry(tdaf);
083            } else {        // time blocks changes
084                    errors = TimeDetailValidationUtil.validateTimeEntryDetails(tdaf);
085            }
086            
087    //        List<String> errors = TimeDetailValidationService.validateTimeEntryDetails(tdaf);
088            errorMsgList.addAll(errors);
089    
090            tdaf.setOutputString(JSONValue.toJSONString(errorMsgList));
091            return mapping.findForward("ws");
092        }
093    
094        public List<String> validateLeaveEntry(TimeDetailActionFormBase tdaf) throws Exception {
095            List<String> errorMsgList = new ArrayList<String>();
096            CalendarEntries payCalendarEntry = tdaf.getPayCalendarDates();
097            if(ObjectUtils.isNotNull(payCalendarEntry)) {
098                            LeaveSummary ls = TkServiceLocator.getLeaveSummaryService().getLeaveSummary(TKContext.getTargetPrincipalId(), tdaf.getPayCalendarDates());
099                            LeaveBlock lb = null;
100                            if(StringUtils.isNotEmpty(tdaf.getLmLeaveBlockId())) {
101                                    lb = TkServiceLocator.getLeaveBlockService().getLeaveBlock(tdaf.getLmLeaveBlockId());
102                            }
103                            
104                            BigDecimal leaveAmount = tdaf.getLeaveAmount();
105                            if(leaveAmount == null) {
106                            Long startTime = TKUtils.convertDateStringToTimestampWithoutZone(tdaf.getStartDate(), tdaf.getStartTime()).getTime();
107                            Long endTime = TKUtils.convertDateStringToTimestampWithoutZone(tdaf.getEndDate(), tdaf.getEndTime()).getTime();
108                            leaveAmount = TKUtils.getHoursBetween(startTime, endTime);
109                            }
110                            
111                            // Validate LeaveBlock timings and all that
112                            errorMsgList.addAll(LeaveCalendarValidationUtil.validateParametersForLeaveEntry(tdaf.getSelectedEarnCode(), tdaf.getPayCalendarDates(),
113                                            tdaf.getStartDate(), tdaf.getEndDate(), tdaf.getStartTime(), tdaf.getEndTime(), tdaf.getSelectedAssignment(), null, tdaf.getLmLeaveBlockId()));
114                            
115                            errorMsgList.addAll(LeaveCalendarValidationUtil.validateAvailableLeaveBalanceForUsage(tdaf.getSelectedEarnCode(), 
116                                            tdaf.getStartDate(), tdaf.getEndDate(), leaveAmount, lb));
117                            //Validate leave block does not exceed max usage. Leave Calendar Validators at this point rely on a leave summary.
118                    errorMsgList.addAll(LeaveCalendarValidationUtil.validateLeaveAccrualRuleMaxUsage(ls, tdaf.getSelectedEarnCode(),
119                        tdaf.getStartDate(), tdaf.getEndDate(), leaveAmount, lb));
120                    }
121                    return errorMsgList;
122        }
123        
124        
125        //this is an ajax call for the assignment maintenance page
126        public ActionForward getDepartmentForJobNumber(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
127            KualiMaintenanceForm kualiForm = (KualiMaintenanceForm) form;
128    
129            String principalId = (String) request.getAttribute("principalId");
130            Long jobNumber = (Long) request.getAttribute("jobNumber");
131    
132            Job job = TkServiceLocator.getJobService().getJob(principalId, jobNumber, TKUtils.getCurrentDate());
133            kualiForm.setAnnotation(job.getDept());
134    
135            return mapping.findForward("ws");
136        }
137    
138        public ActionForward getEarnCodeJson(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
139            TimeDetailWSActionForm tdaf = (TimeDetailWSActionForm) form;
140            List<Map<String, Object>> earnCodeList = new LinkedList<Map<String, Object>>();
141    
142            if (StringUtils.isNotBlank(tdaf.getSelectedAssignment())) {
143                List<Assignment> assignments = tdaf.getTimesheetDocument().getAssignments();
144                AssignmentDescriptionKey key = new AssignmentDescriptionKey(tdaf.getSelectedAssignment());
145                Map<String, EarnCode> regEarnCodes = getRegularEarnCodes(tdaf.getTimesheetDocument());
146                for (Assignment assignment : assignments) {
147                    if (assignment.getJobNumber().equals(key.getJobNumber()) &&
148                            assignment.getWorkArea().equals(key.getWorkArea()) &&
149                            assignment.getTask().equals(key.getTask())) {
150                        List<EarnCode> earnCodes = new ArrayList<EarnCode>();
151                        if (tdaf.isTimeBlockReadOnly()) {
152                            if (regEarnCodes.containsKey(assignment.getAssignmentKey())) {
153                                earnCodes.add(regEarnCodes.get(assignment.getAssignmentKey()));
154                            }
155                        } else {
156                            earnCodes.addAll(TkServiceLocator.getEarnCodeService()
157                                    .getEarnCodesForTime(assignment, tdaf.getTimesheetDocument().getAsOfDate(), tdaf.isTimeBlockReadOnly()));
158                        }
159                        for (EarnCode earnCode : earnCodes) {
160                            Map<String, Object> earnCodeMap = new HashMap<String, Object>();
161                            earnCodeMap.put("assignment", assignment.getAssignmentKey());
162                            earnCodeMap.put("earnCode", earnCode.getEarnCode());
163                            earnCodeMap.put("desc", earnCode.getDescription());
164                            earnCodeMap.put("type", earnCode.getEarnCodeType());
165                            // for leave blocks
166                            earnCodeMap.put("leavePlan", earnCode.getLeavePlan());
167                            if(StringUtils.isNotEmpty(earnCode.getLeavePlan())) {
168                                earnCodeMap.put("fractionalTimeAllowed", earnCode.getFractionalTimeAllowed());
169                                earnCodeMap.put("unitOfTime", ActionFormUtils.getUnitOfTimeForEarnCode(earnCode));
170                            }
171                            earnCodeMap.put("eligibleForAccrual", earnCode.getEligibleForAccrual());
172                            earnCodeList.add(earnCodeMap);
173                        }
174                    }
175                }
176            }
177            LOG.info(tdaf.toString());
178            tdaf.setOutputString(JSONValue.toJSONString(earnCodeList));
179            return mapping.findForward("ws");
180        }
181    
182        private Map<String, EarnCode> getRegularEarnCodes(TimesheetDocument td) {
183            Map<String, EarnCode> regEarnCodes = new HashMap<String, EarnCode>();
184            if (td != null) {
185                for (Assignment a : td.getAssignments()) {
186                    if (a.getJob() != null
187                            && a.getJob().getPayTypeObj() != null) {
188                        PayType payType = a.getJob().getPayTypeObj();
189                        EarnCode ec = payType.getRegEarnCodeObj();
190                        if (ec == null
191                                && StringUtils.isNotEmpty(payType.getRegEarnCode()))  {
192                            ec = TkServiceLocator.getEarnCodeService().getEarnCode(payType.getRegEarnCode(), payType.getEffectiveDate());
193                        }
194                        regEarnCodes.put(a.getAssignmentKey(), ec);
195                    }
196                }
197            }
198            return regEarnCodes;
199        }
200    
201        private List<Map<String, Object>> getAssignmentsForRegEarnCode(TimesheetDocument td, String earnCode) {
202            List<Map<String, Object>> assignments = new ArrayList<Map<String, Object>>();
203            if (td != null) {
204                for (Assignment a : td.getAssignments()) {
205                    Map<String, Object> assignment = new HashMap<String, Object>();
206                    if (earnCode.equals(a.getJob().getPayTypeObj().getRegEarnCode())) {
207                        assignment.put("assignment", a.getAssignmentKey());
208                        assignments.add(assignment);
209                    }
210                }
211            }
212            return assignments;
213        }
214    
215        public ActionForward getValidAssignments(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
216            TimeDetailWSActionForm tdaf = (TimeDetailWSActionForm) form;
217    
218            String earnCode = tdaf.getSelectedEarnCode();
219    
220            List<Map<String, Object>> assignments = new ArrayList<Map<String, Object>>();
221            if (tdaf.getTimesheetDocument() != null && StringUtils.isNotEmpty(earnCode)) {
222                assignments = getAssignmentsForRegEarnCode(tdaf.getTimesheetDocument(), earnCode);
223            }
224            tdaf.setOutputString(JSONValue.toJSONString(assignments));
225            return mapping.findForward("ws");
226        }
227    
228        public ActionForward getOvertimeEarnCodes(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
229            TimeDetailWSActionForm tdaf = (TimeDetailWSActionForm) form;
230            List<EarnCode> overtimeEarnCodes = TkServiceLocator.getEarnCodeService().getOvertimeEarnCodes(TKUtils.getCurrentDate());
231            List<Map<String, Object>> overtimeEarnCodeList = new LinkedList<Map<String, Object>>();
232    
233            for (EarnCode earnCode : overtimeEarnCodes) {
234                Map<String, Object> earnCodeMap = new HashMap<String, Object>();
235                earnCodeMap.put("earnCode", earnCode.getEarnCode());
236                earnCodeMap.put("desc", earnCode.getDescription());
237    
238                overtimeEarnCodeList.add(earnCodeMap);
239            }
240    
241            LOG.info(tdaf.toString());
242            tdaf.setOutputString(JSONValue.toJSONString(overtimeEarnCodeList));
243            return mapping.findForward("ws");
244        }
245    
246    }