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.ec.service.impl;
017    
018    import java.util.ArrayList;
019    import java.util.HashMap;
020    import java.util.List;
021    import java.util.Map;
022    import java.util.Set;
023    
024    import org.kuali.kfs.integration.ld.LaborLedgerBalance;
025    import org.kuali.kfs.module.ec.businessobject.EffortCertificationDetailBuild;
026    import org.kuali.kfs.module.ec.businessobject.EffortCertificationDocumentBuild;
027    import org.kuali.kfs.module.ec.businessobject.EffortCertificationReportDefinition;
028    import org.kuali.kfs.module.ec.service.EffortCertificationDetailBuildService;
029    import org.kuali.kfs.module.ec.service.EffortCertificationDocumentBuildService;
030    import org.kuali.kfs.module.ec.util.LedgerBalanceConsolidationHelper;
031    import org.kuali.kfs.module.ec.util.PayrollAmountHolder;
032    import org.kuali.rice.kns.bo.PersistableBusinessObject;
033    import org.kuali.rice.kns.service.BusinessObjectService;
034    import org.kuali.rice.kns.util.KualiDecimal;
035    import org.springframework.transaction.annotation.Transactional;
036    
037    /**
038     * This class Provide the facility used to generate documents (build) from the labor ledger balances
039     */
040    @Transactional
041    public class EffortCertificationDocumentBuildServiceImpl implements EffortCertificationDocumentBuildService {
042        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EffortCertificationDocumentBuildServiceImpl.class);
043    
044        private EffortCertificationDetailBuildService effortCertificationDetailBuildService;
045        private BusinessObjectService businessObjectService;
046    
047        /**
048         * @see org.kuali.kfs.module.ec.service.EffortCertificationDocumentBuildService#removeExistingDocumentBuild(java.util.Map)
049         */
050        public void removeExistingDocumentBuild(Map<String, String> fieldValues) {
051            List<PersistableBusinessObject> documents = (List<PersistableBusinessObject>) businessObjectService.findMatching(EffortCertificationDocumentBuild.class, fieldValues);
052            businessObjectService.delete(documents);
053        }
054    
055        /**
056         * @see org.kuali.kfs.module.ec.service.EffortCertificationDocumentBuildService#generateDocumentBuild(org.kuali.kfs.module.ec.businessobject.EffortCertificationReportDefinition,
057         *      java.util.List, java.util.Map)
058         */
059        public List<EffortCertificationDocumentBuild> generateDocumentBuildList(Integer postingYear, EffortCertificationReportDefinition reportDefinition, List<LaborLedgerBalance> ledgerBalances) {
060            List<EffortCertificationDocumentBuild> documentList = new ArrayList<EffortCertificationDocumentBuild>();
061    
062            Map<String, List<LaborLedgerBalance>> ledgerBalanceGroups = buildLedgerBalanceGroups(ledgerBalances);
063            for (String key : ledgerBalanceGroups.keySet()) {
064                List<LaborLedgerBalance> balanceList = ledgerBalanceGroups.get(key);
065    
066                EffortCertificationDocumentBuild document = this.generateDocumentBuild(postingYear, reportDefinition, balanceList);
067                documentList.add(document);
068            }
069    
070            return documentList;
071        }
072    
073        /**
074         * @see org.kuali.kfs.module.ec.service.EffortCertificationDocumentBuildService#generateDocumentBuild(org.kuali.kfs.module.ec.businessobject.EffortCertificationReportDefinition,
075         *      java.util.List, java.util.Map)
076         */
077        public EffortCertificationDocumentBuild generateDocumentBuild(Integer postingYear, EffortCertificationReportDefinition reportDefinition, List<LaborLedgerBalance> ledgerBalances) {
078            Map<Integer, Set<String>> reportPeriods = reportDefinition.getReportPeriods();
079    
080            KualiDecimal totalAmount = LedgerBalanceConsolidationHelper.calculateTotalAmountWithinReportPeriod(ledgerBalances, reportPeriods);
081            PayrollAmountHolder payrollAmountHolder = new PayrollAmountHolder(totalAmount, KualiDecimal.ZERO, 0);
082    
083            LaborLedgerBalance headOfBalanceList = ledgerBalances.get(0);
084            EffortCertificationDocumentBuild document = populateDocument(reportDefinition, headOfBalanceList);
085            List<EffortCertificationDetailBuild> detailLineList = document.getEffortCertificationDetailLinesBuild();
086    
087            for (LaborLedgerBalance balance : ledgerBalances) {
088                EffortCertificationDetailBuild detailLine = effortCertificationDetailBuildService.generateDetailBuild(postingYear, balance, reportDefinition);
089                detailLine.setEffortCertificationBuildNumber(document.getEffortCertificationBuildNumber());
090    
091                payrollAmountHolder.setPayrollAmount(detailLine.getEffortCertificationPayrollAmount());
092                PayrollAmountHolder.calculatePayrollPercent(payrollAmountHolder);
093    
094                detailLine.setEffortCertificationCalculatedOverallPercent(payrollAmountHolder.getPayrollPercent());
095                detailLine.setEffortCertificationUpdatedOverallPercent(payrollAmountHolder.getPayrollPercent());
096    
097                this.updateDetailLineList(detailLineList, detailLine);
098            }
099    
100            return document;
101        }
102    
103        /**
104         * populate a dument build object through the given information
105         * 
106         * @param reportDefinition the given report definition
107         * @param ledgerBalance the given ledger balance
108         * @return a dument build object populated with the given information
109         */
110        protected static EffortCertificationDocumentBuild populateDocument(EffortCertificationReportDefinition reportDefinition, LaborLedgerBalance ledgerBalance) {
111            EffortCertificationDocumentBuild document = new EffortCertificationDocumentBuild();
112    
113            document.setEffortCertificationBuildNumber(null);
114            document.setEffortCertificationDocumentCode(false);
115    
116            document.setEffortCertificationReportNumber(reportDefinition.getEffortCertificationReportNumber());
117            document.setUniversityFiscalYear(reportDefinition.getUniversityFiscalYear());
118            document.setEmplid(ledgerBalance.getEmplid());
119    
120            return document;
121        }
122    
123        /**
124         * group the given ledger balances according to the combination of the values in the specified fields
125         * 
126         * @param ledgerBalances the given ledger balances
127         * @return the map holding ledger balance groups
128         */
129        protected Map<String, List<LaborLedgerBalance>> buildLedgerBalanceGroups(List<LaborLedgerBalance> ledgerBalances) {
130            Map<String, List<LaborLedgerBalance>> ledgerBalanceGroups = new HashMap<String, List<LaborLedgerBalance>>();
131    
132            for (LaborLedgerBalance balance : ledgerBalances) {
133                String consolidationKeys = balance.getEmplid();
134                LedgerBalanceConsolidationHelper.groupLedgerBalancesByKeys(ledgerBalanceGroups, balance, consolidationKeys);
135            }
136            return ledgerBalanceGroups;
137        }
138    
139        
140    
141        /**
142         * update the given detail line if the given detail line is in the list; otherwise, add the given line into the list
143         * 
144         * @param detailLineList the given list of detail lines
145         * @param detailLine the given detail line
146         */
147        protected void updateDetailLineList(List<EffortCertificationDetailBuild> detailLineList, EffortCertificationDetailBuild detailLine) {
148            int index = detailLineList.indexOf(detailLine);
149            if (index >= 0) {
150                EffortCertificationDetailBuild existingDetailLine = detailLineList.get(index);
151    
152                int calculatedOverallPercent = existingDetailLine.getEffortCertificationCalculatedOverallPercent() + detailLine.getEffortCertificationCalculatedOverallPercent();
153                existingDetailLine.setEffortCertificationCalculatedOverallPercent(calculatedOverallPercent);
154    
155                int updatedOverallPercent = existingDetailLine.getEffortCertificationUpdatedOverallPercent() + detailLine.getEffortCertificationUpdatedOverallPercent();
156                existingDetailLine.setEffortCertificationUpdatedOverallPercent(updatedOverallPercent);
157    
158                KualiDecimal originalPayrollAmount = existingDetailLine.getEffortCertificationOriginalPayrollAmount().add(detailLine.getEffortCertificationOriginalPayrollAmount());
159                existingDetailLine.setEffortCertificationOriginalPayrollAmount(originalPayrollAmount);
160    
161                KualiDecimal payrollAmount = existingDetailLine.getEffortCertificationPayrollAmount().add(detailLine.getEffortCertificationPayrollAmount());
162                existingDetailLine.setEffortCertificationPayrollAmount(payrollAmount);
163    
164            }
165            else {
166                detailLineList.add(detailLine);
167            }
168        }
169    
170        /**
171         * Sets the effortCertificationDetailBuildService attribute value.
172         * 
173         * @param effortCertificationDetailBuildService The effortCertificationDetailBuildService to set.
174         */
175        public void setEffortCertificationDetailBuildService(EffortCertificationDetailBuildService effortCertificationDetailBuildService) {
176            this.effortCertificationDetailBuildService = effortCertificationDetailBuildService;
177        }
178    
179        /**
180         * Sets the businessObjectService attribute value.
181         * 
182         * @param businessObjectService The businessObjectService to set.
183         */
184        public void setBusinessObjectService(BusinessObjectService businessObjectService) {
185            this.businessObjectService = businessObjectService;
186        }
187    }