001    /**
002     * Copyright 2004-2014 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.kpme.pm.position.web;
017    
018    import java.math.BigDecimal;
019    
020    import org.apache.commons.collections.CollectionUtils;
021    import org.apache.commons.lang.StringUtils;
022    import org.kuali.kpme.core.bo.HrBusinessObject;
023    import org.kuali.kpme.core.bo.HrBusinessObjectMaintainableImpl;
024    import org.kuali.kpme.core.util.ValidationUtils;
025    import org.kuali.kpme.pm.classification.Classification;
026    import org.kuali.kpme.pm.classification.duty.ClassificationDuty;
027    import org.kuali.kpme.pm.classification.flag.ClassificationFlag;
028    import org.kuali.kpme.pm.classification.qual.ClassificationQualification;
029    import org.kuali.kpme.pm.position.Position;
030    import org.kuali.kpme.pm.position.PositionDuty;
031    import org.kuali.kpme.pm.position.PositionQualification;
032    import org.kuali.kpme.pm.position.PstnFlag;
033    import org.kuali.kpme.pm.position.funding.PositionFunding;
034    import org.kuali.kpme.pm.positionflag.PositionFlag;
035    import org.kuali.kpme.pm.service.base.PmServiceLocator;
036    import org.kuali.rice.krad.maintenance.MaintenanceDocument;
037    import org.kuali.rice.krad.uif.container.CollectionGroup;
038    import org.kuali.rice.krad.uif.view.View;
039    import org.kuali.rice.krad.util.GlobalVariables;
040    import org.kuali.rice.krad.util.KRADConstants;
041    import org.kuali.rice.krad.web.form.MaintenanceDocumentForm;
042    
043    public class PositionMaintainableServiceImpl extends HrBusinessObjectMaintainableImpl {
044    
045            private static final long serialVersionUID = 1L;
046    
047            @Override
048            public HrBusinessObject getObjectById(String id) {
049                    return PmServiceLocator.getPositionService().getPosition(id);
050            }
051            
052            @Override
053            public void customSaveLogic(HrBusinessObject hrObj){
054                    Position aPosition = (Position) hrObj;
055                    for(PositionQualification aQual : aPosition.getQualificationList()) {
056                            aQual.setHrPositionId(aPosition.getHrPositionId());
057                            aQual.setPmQualificationId(null);
058                    }
059                    for(PositionDuty aDuty : aPosition.getDutyList()) {
060                            aDuty.setHrPositionId(aPosition.getHrPositionId());
061                            aDuty.setPmDutyId(null);
062                    }
063                    for(PstnFlag aFlag : aPosition.getFlagList()) {
064                            aFlag.setHrPositionId(aPosition.getHrPositionId());
065                            aFlag.setPmFlagId(null);
066                    }
067                    for(PositionFunding aFunding : aPosition.getFundingList()) {
068                            aFunding.setHrPositionId(aPosition.getHrPositionId());
069                            aFunding.setPmPositionFunctionId(null);
070                    }
071                    
072            }
073            
074            @Override
075        protected boolean performAddLineValidation(View view, CollectionGroup collectionGroup, Object model,
076                Object addLine) {
077            boolean isValid = super.performAddLineValidation(view, collectionGroup, model, addLine);
078            if (model instanceof MaintenanceDocumentForm) {
079                    MaintenanceDocumentForm maintenanceForm = (MaintenanceDocumentForm) model;
080                    MaintenanceDocument document = maintenanceForm.getDocument();
081                    if (document.getNewMaintainableObject().getDataObject() instanceof Position) {
082                            Position aPosition = (Position) document.getNewMaintainableObject().getDataObject();
083                            // Duty line validation
084                            if (addLine instanceof PositionDuty) {
085                                    PositionDuty pd = (PositionDuty) addLine;
086                                    boolean results = this.validateDutyListPercentage(pd, aPosition);
087                                    if(!results) {
088                                            return false;
089                                    }
090                            }
091                            // Funding line validation
092                            if (addLine instanceof PositionFunding) {
093                                    PositionFunding pf = (PositionFunding) addLine;
094                                    boolean results = this.validateAddFundingLine(pf, aPosition);
095                                    if(!results) {
096                                            return false;
097                                    }
098                            }
099                    }
100            }
101    
102            return isValid;
103        }
104            
105            private boolean validateDutyListPercentage(PositionDuty pd, Position aPosition) {
106                    if(CollectionUtils.isNotEmpty(aPosition.getDutyList()) && pd.getPercentage() != null) {
107                            BigDecimal sum = pd.getPercentage();
108                            for(PositionDuty aDuty : aPosition.getDutyList()) {
109                                    if(aDuty != null && aDuty.getPercentage() != null) {
110                                            sum = sum.add(aDuty.getPercentage());
111                                    }
112                            }
113                            if(sum.compareTo(new BigDecimal(100)) > 0) {
114                                    GlobalVariables.getMessageMap().putError("Position-duties", "duty.percentage.exceedsMaximum", sum.toString());
115                                    return false;
116                            }
117                    }               
118                    return true;
119            }
120            
121            protected boolean validateAddFundingLine(PositionFunding pf, Position aPosition) {
122            if(pf.getEffectiveDate() != null && aPosition.getEffectiveDate() != null) {
123                    if(pf.getEffectiveDate().compareTo(aPosition.getEffectiveDate()) < 0) {
124                            String[] parameters = new String[2];
125                            parameters[0] = pf.getEffectiveDate().toString();
126                            parameters[1] = aPosition.getEffectiveDate().toString();
127                            // using section id as the error key because KRAD does not support error matching on property names for collections as in 2.3M2
128                            GlobalVariables.getMessageMap().putError("Position-fundings","error.funding.effdt.invalid", parameters);
129                                    return false;
130                    }
131            }
132            if(StringUtils.isNotEmpty(pf.getAccount())) {
133                    boolean results = ValidationUtils.validateAccount(pf.getChart(), pf.getAccount());
134                    if(!results) {
135                            GlobalVariables.getMessageMap().putError("Position-fundings", "error.existence", "Account '" + pf.getAccount() + "'");
136                            return results;
137                    }
138            }
139            if(StringUtils.isNotEmpty(pf.getSubAccount())) {
140                    boolean results = ValidationUtils.validateSubAccount(pf.getSubAccount(), pf.getAccount(), pf.getChart());
141                    if(!results) {
142                                     GlobalVariables.getMessageMap().putError("Position-fundings","error.existence", "SubAccount '" + pf.getSubAccount() + "'");
143                                     return results;
144                    }
145            }
146            if(StringUtils.isNotEmpty(pf.getObjectCode())) {
147                    boolean results = ValidationUtils.validateObjectCode(pf.getObjectCode(), pf.getChart(), Integer.valueOf(pf.getEffectiveLocalDate().getYear()));
148                    if(!results) {
149                             GlobalVariables.getMessageMap().putError("Position-fundings","error.existence", "ObjectCode '" + pf.getObjectCode() + "'");
150                             return results;
151                    }
152            }
153            if(StringUtils.isNotEmpty(pf.getSubObjectCode())) {
154                    boolean results = ValidationUtils.validateSubObjectCode(String.valueOf(pf.getEffectiveLocalDate().getYear()),
155                                    pf.getChart(),
156                                    pf.getAccount(),
157                                    pf.getObjectCode(),
158                                    pf.getSubObjectCode());
159                    if(!results) {
160                             GlobalVariables.getMessageMap().putError("Position-fundings","error.existence", "SubObjectCode '" + pf.getSubObjectCode() + "'");
161                             return results;
162                    }
163            }
164            return true;
165        
166            }
167    
168    }