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.lm.leavecode.service;
017    
018    import com.google.common.collect.Ordering;
019    import org.apache.commons.lang.StringUtils;
020    import org.apache.log4j.Logger;
021    import org.kuali.hr.lm.LMConstants;
022    import org.kuali.hr.lm.leavecode.LeaveCode;
023    import org.kuali.hr.lm.leavecode.dao.LeaveCodeDao;
024    import org.kuali.hr.time.principal.PrincipalHRAttributes;
025    import org.kuali.hr.time.roles.TkUserRoles;
026    import org.kuali.hr.time.service.base.TkServiceLocator;
027    import org.kuali.hr.time.util.TKContext;
028    import org.kuali.hr.time.util.TKUser;
029    import org.kuali.hr.time.util.TKUtils;
030    import org.kuali.rice.krad.util.GlobalVariables;
031    
032    import java.math.BigDecimal;
033    import java.sql.Date;
034    import java.util.*;
035    
036    public class LeaveCodeServiceImpl implements LeaveCodeService {
037    
038            private static final Logger LOG = Logger
039                            .getLogger(LeaveCodeServiceImpl.class);
040            private LeaveCodeDao leaveCodeDao;
041    
042            public LeaveCodeDao getLeaveCodeDao() {
043                    return leaveCodeDao;
044            }
045    
046            public void setLeaveCodeDao(LeaveCodeDao leaveCodeDao) {
047                    this.leaveCodeDao = leaveCodeDao;
048            }
049    
050            @Override
051            public LeaveCode getLeaveCode(String lmLeaveCodeId) {
052                    return getLeaveCodeDao().getLeaveCode(lmLeaveCodeId);
053            }
054    
055            @Override
056        public List<LeaveCode> getLeaveCodes(String principalId, Date asOfDate) {
057            String leavePlan = null;
058            List<LeaveCode> leaveCodes = new ArrayList<LeaveCode>();
059            PrincipalHRAttributes hrAttribute = TkServiceLocator.getPrincipalHRAttributeService().getPrincipalCalendar(principalId, asOfDate);
060            if(hrAttribute != null) {
061                    leavePlan = hrAttribute.getLeavePlan();
062                    if (StringUtils.isBlank(leavePlan)) {
063                            throw new RuntimeException("No leave plan defined for " + principalId + " in principal hr attributes");
064                    }
065                    
066                List<LeaveCode> unfilteredLeaveCodes = leaveCodeDao.getLeaveCodes(leavePlan, asOfDate);
067                TKUser user = TKContext.getUser();
068    
069                for (LeaveCode leaveCode : unfilteredLeaveCodes) {
070                    //if employee add this leave code
071                    //TODO how do we know this is an approver for them
072                    if ((leaveCode.getEmployee() && TkUserRoles.getUserRoles(GlobalVariables.getUserSession().getPrincipalId()).isActiveEmployee()) ||
073                            (leaveCode.getApprover() && user.isApprover())) {
074                        leaveCodes.add(leaveCode);
075                    }
076                }
077    
078            }
079    
080            return leaveCodes;
081        }
082    
083            @Override
084            public Map<String, String> getLeaveCodesForDisplay(String principalId) {
085                    List<LeaveCode> leaveCodes = getLeaveCodes(principalId,
086                                    TKUtils.getCurrentDate());
087                    
088                    // KPME1449, chen, only display leaveCodes which are 'allow_scheduled_leave flag = Y'
089                    for (LeaveCode leaveCode : leaveCodes) {
090                            if ( !leaveCode.getAllowScheduledLeave().equalsIgnoreCase("Y")) {
091                                    leaveCodes.remove(leaveCode);
092                            }
093                    } // kpme1449
094    
095                    Comparator<LeaveCode> leaveCodeComparator = new Comparator<LeaveCode>() {
096                            @Override
097                            public int compare(LeaveCode leaveCode, LeaveCode leaveCode1) {
098                                    return leaveCode.getLeaveCode().compareToIgnoreCase(
099                                                    leaveCode1.getLeaveCode());
100                            }
101                    };
102                    // Order by leaveCode ascending
103                    Ordering<LeaveCode> ordering = Ordering.from(leaveCodeComparator);
104    
105                    Map<String, String> leaveCodesForDisplay = new LinkedHashMap<String, String>();
106                    for (LeaveCode leaveCode : ordering.sortedCopy(leaveCodes)) {
107                            leaveCodesForDisplay.put(leaveCode.getLeaveCodeKeyForDisplay(),
108                                            leaveCode.getLeaveCodeValueForDisplay());
109                    }
110    
111                    return leaveCodesForDisplay;
112            }
113    
114            @Override
115            public LeaveCode getLeaveCode(String leaveCode, Date effectiveDate) {
116                    return leaveCodeDao.getLeaveCode(leaveCode, effectiveDate);
117            }
118            
119            @Override
120            public BigDecimal roundHrsWithLeaveCode(BigDecimal hours, LeaveCode leaveCode) {
121                    String roundOption = LMConstants.ROUND_OPTION_MAP.get(leaveCode.getRoundingOption());
122                    BigDecimal fractScale = new BigDecimal(leaveCode.getFractionalTimeAllowed());
123                    if(roundOption == null) {
124                            throw new RuntimeException("Rounding option of Leave Code " + leaveCode.getLeaveCode() + " is not recognized.");
125                    }
126                    BigDecimal roundedHours = hours;
127                    if(roundOption.equals("Traditional")) {
128                            roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_HALF_EVEN);
129                    } else if(roundOption.equals("Truncate")) {
130                            roundedHours = hours.setScale(fractScale.scale(), BigDecimal.ROUND_DOWN);
131                    }
132                    return roundedHours;
133            }
134    }