001    /*
002     * Copyright 2011 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.kfs.module.bc.service.impl;
017    
018    import java.util.HashMap;
019    import java.util.List;
020    import java.util.Map;
021    
022    import org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition;
023    import org.kuali.kfs.module.bc.businessobject.PendingBudgetConstructionAppointmentFunding;
024    import org.kuali.kfs.module.bc.businessobject.Position;
025    import org.kuali.kfs.module.bc.document.dataaccess.BudgetConstructionDao;
026    import org.kuali.kfs.module.bc.exception.BudgetPositionAlreadyExistsException;
027    import org.kuali.kfs.module.bc.service.BudgetConstructionPositionService;
028    import org.kuali.kfs.module.bc.service.HumanResourcesPayrollService;
029    import org.kuali.kfs.sys.KFSPropertyConstants;
030    import org.kuali.kfs.sys.service.NonTransactional;
031    import org.kuali.rice.kns.service.BusinessObjectService;
032    import org.springframework.transaction.annotation.Propagation;
033    import org.springframework.transaction.annotation.Transactional;
034    
035    
036    /**
037     * Implementation of BudgetConstructionPositionService that uses the HumanResourcesPayrollService
038     * 
039     * @see org.kuali.kfs.module.bc.service.BudgetConstructionPositionService
040     * @see org.kuali.kfs.module.bc.service.HumanResourcesPayrollService
041     */
042    public class BudgetConstructionPositionServiceImpl implements BudgetConstructionPositionService {
043        private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(BudgetConstructionPositionServiceImpl.class);
044    
045        private HumanResourcesPayrollService humanResourcesPayrollService;
046        private BusinessObjectService businessObjectService;
047        private BudgetConstructionDao budgetConstructionDao;
048    
049        /**
050         * @see org.kuali.kfs.module.bc.service.BudgetConstructionPositionService#pullNewPositionFromExternal(java.lang.Integer,
051         *      java.lang.String)
052         */
053        @Transactional
054        public synchronized void pullNewPositionFromExternal(Integer universityFiscalYear, String positionNumber) throws BudgetPositionAlreadyExistsException {
055            // call humanResourcesPayrollService service to pull record
056            Position position = humanResourcesPayrollService.getPosition(universityFiscalYear, positionNumber);
057    
058            // check if position already exists in budget position table, if not add position
059            BudgetConstructionPosition retrievedPosition = getByPrimaryId(universityFiscalYear.toString(), positionNumber);
060            if (retrievedPosition != null) {
061                throw new BudgetPositionAlreadyExistsException(universityFiscalYear, positionNumber);
062            }
063            else {
064                retrievedPosition = new BudgetConstructionPosition();
065            }
066            
067            // populate BudgetConstructionPosition
068            BudgetConstructionPosition budgetConstructionPosition = buildBudgetPosition(position, retrievedPosition);
069    
070            // insert position record
071            businessObjectService.save(budgetConstructionPosition);
072        }
073    
074        /**
075         * @see org.kuali.kfs.module.bc.service.BudgetConstructionPositionService#refreshPositionFromExternal(java.lang.Integer,
076         *      java.lang.String)
077         */
078        @Transactional(propagation = Propagation.REQUIRES_NEW)
079        public synchronized void refreshPositionFromExternal(Integer universityFiscalYear, String positionNumber) {
080            // call humanResourcesPayrollService service to pull record
081            Position position = humanResourcesPayrollService.getPosition(universityFiscalYear, positionNumber);
082    
083            // update budget record
084            BudgetConstructionPosition retrievedPosition = getByPrimaryId(universityFiscalYear.toString(), positionNumber);
085            
086            // populate BudgetConstructionPosition
087            BudgetConstructionPosition budgetConstructionPosition = buildBudgetPosition(position, retrievedPosition);
088    
089            // update position record
090            businessObjectService.save(budgetConstructionPosition);
091    
092            // update funding position change indicators
093            updateFundingPositionChangeIndicators(universityFiscalYear, positionNumber);
094        }
095    
096        /**
097         * Retrieves all funding lines for the position that are not marked as delete and sets the position change indicator fields to
098         * true.
099         * 
100         * @param universityFiscalYear budget fiscal year for the position
101         * @param positionNumber position number for the record
102         */
103        protected void updateFundingPositionChangeIndicators(Integer universityFiscalYear, String positionNumber) {
104            // retrieve funding records for the position
105            List<PendingBudgetConstructionAppointmentFunding> allPositionFunding = budgetConstructionDao.getAllFundingForPosition(universityFiscalYear, positionNumber);
106    
107            // update indicators if the line is not marked for delete
108            for (PendingBudgetConstructionAppointmentFunding appointmentFunding : allPositionFunding) {
109                if (!appointmentFunding.isAppointmentFundingDeleteIndicator()) {
110                    appointmentFunding.setPositionObjectChangeIndicator(true);
111                    appointmentFunding.setPositionSalaryChangeIndicator(true);
112                    appointmentFunding.setVersionNumber(appointmentFunding.getVersionNumber());
113                    
114                    businessObjectService.save(appointmentFunding);
115                }
116            }
117        }
118    
119        /**
120         * Populates a new <code>BudgetConstructionPosition</code> object from a <code>Position</code> object.
121         * 
122         * @param position object to copy
123         * @param budgetConstructionPosition bc position to populate
124         * @return BudgetConstructionPosition populated from <code>Position</code>
125         * @see org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition
126         * @see org.kuali.kfs.module.bc.businessobject.Position
127         */
128        protected BudgetConstructionPosition buildBudgetPosition(Position position, BudgetConstructionPosition budgetConstructionPosition) {
129            budgetConstructionPosition.setBudgetedPosition(position.isBudgetedPosition());
130            budgetConstructionPosition.setConfidentialPosition(position.isConfidentialPosition());
131            budgetConstructionPosition.setIuDefaultObjectCode(position.getIuDefaultObjectCode());
132            budgetConstructionPosition.setIuNormalWorkMonths(position.getIuNormalWorkMonths());
133            budgetConstructionPosition.setIuPayMonths(position.getIuPayMonths());
134            budgetConstructionPosition.setIuPositionType(position.getIuPositionType());
135            budgetConstructionPosition.setJobCode(position.getJobCode());
136            budgetConstructionPosition.setJobCodeDescription(position.getJobCodeDescription());
137            budgetConstructionPosition.setPositionDepartmentIdentifier(position.getPositionDepartmentIdentifier());
138            budgetConstructionPosition.setPositionDescription(position.getPositionDescription());
139            budgetConstructionPosition.setPositionEffectiveDate(position.getPositionEffectiveDate());
140            budgetConstructionPosition.setPositionEffectiveStatus(position.getPositionEffectiveStatus());
141            budgetConstructionPosition.setPositionFullTimeEquivalency(position.getPositionFullTimeEquivalency());
142            budgetConstructionPosition.setPositionGradeDefault(position.getPositionGradeDefault());
143            budgetConstructionPosition.setPositionNumber(position.getPositionNumber());
144            budgetConstructionPosition.setPositionRegularTemporary(position.getPositionRegularTemporary());
145            budgetConstructionPosition.setPositionSalaryPlanDefault(position.getPositionSalaryPlanDefault());
146            budgetConstructionPosition.setPositionStandardHoursDefault(position.getPositionStandardHoursDefault());
147            budgetConstructionPosition.setPositionStatus(position.getPositionStatus());
148            budgetConstructionPosition.setPositionUnionCode(position.getPositionUnionCode());
149            budgetConstructionPosition.setResponsibilityCenterCode(position.getResponsibilityCenterCode());
150            budgetConstructionPosition.setSetidDepartment(position.getSetidDepartment());
151            budgetConstructionPosition.setSetidJobCode(position.getSetidJobCode());
152            budgetConstructionPosition.setSetidSalary(position.getSetidSalary());
153            budgetConstructionPosition.setUniversityFiscalYear(position.getUniversityFiscalYear());
154    
155            return budgetConstructionPosition;
156        }
157    
158        /**
159         * @see org.kuali.kfs.module.bc.service.BudgetConstructionPositionService#getByPrimaryId(java.lang.String, java.lang.String)
160         */
161        @NonTransactional
162        public BudgetConstructionPosition getByPrimaryId(String fiscalYear, String positionNumber) {
163            Map<String, Object> primaryKeys = new HashMap<String, Object>();
164            primaryKeys.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, fiscalYear);
165            primaryKeys.put(KFSPropertyConstants.POSITION_NUMBER, positionNumber);
166    
167            return (BudgetConstructionPosition) businessObjectService.findByPrimaryKey(BudgetConstructionPosition.class, primaryKeys);
168        }
169    
170        /**
171         * @see org.kuali.kfs.module.bc.service.BudgetConstructionPositionService#isBudgetingPosition(org.kuali.kfs.module.bc.businessobject.BudgetConstructionPosition)
172         */
173        @NonTransactional
174        public boolean isBudgetablePosition(BudgetConstructionPosition budgetConstructionPosition) {
175            return budgetConstructionPosition != null && budgetConstructionPosition.isBudgetedPosition() && budgetConstructionPosition.isEffective();
176        }
177    
178        /**
179         * Sets the businessObjectService attribute value.
180         * 
181         * @param businessObjectService The businessObjectService to set.
182         */
183        @NonTransactional
184        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
185            this.businessObjectService = businessObjectService;
186        }
187    
188        /**
189         * Sets the humanResourcesPayrollService attribute value.
190         * 
191         * @param humanResourcesPayrollService The humanResourcesPayrollService to set.
192         */
193        @NonTransactional
194        public void setHumanResourcesPayrollService(HumanResourcesPayrollService humanResourcesPayrollService) {
195            this.humanResourcesPayrollService = humanResourcesPayrollService;
196        }
197    
198        /**
199         * Sets the budgetConstructionDao attribute value.
200         * 
201         * @param budgetConstructionDao The budgetConstructionDao to set.
202         */
203        @NonTransactional
204        public void setBudgetConstructionDao(BudgetConstructionDao budgetConstructionDao) {
205            this.budgetConstructionDao = budgetConstructionDao;
206        }
207    }