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.util;
017    
018    import java.util.ArrayList;
019    import java.util.Collection;
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.sys.ObjectUtil;
026    import org.kuali.rice.kns.util.KualiDecimal;
027    
028    /**
029     * To provide a set of utilities to consolidate/group the specified ledger balances and build a returning ledger balance Map.
030     */
031    public class LedgerBalanceConsolidationHelper {
032    
033        /**
034         * consolidate the amount of the given ledger balance into the balance with the same values of specified key fields
035         * 
036         * @param ledgerBalanceMap the hash map that contains the consolidated balance records. Its key can be the combined string value
037         *        of the given consolidation keys.
038         * @param ledgerBalance the given ledger balance to be consolidated
039         * @param consolidationKeys the given key field names used to build the keys of ledgerBalanceMap
040         */
041        public static void consolidateLedgerBalances(Map<String, LaborLedgerBalance> ledgerBalanceMap, LaborLedgerBalance ledgerBalance, List<String> consolidationKeys) {
042            String consolidationKeyFieldsAsString = ObjectUtil.concatPropertyAsString(ledgerBalance, consolidationKeys);
043            
044            consolidateLedgerBalances(ledgerBalanceMap, ledgerBalance, consolidationKeyFieldsAsString);
045        }
046        
047        /**
048         * consolidate the amount of the given ledger balance into the balance with the same values of specified key fields
049         * 
050         * @param ledgerBalanceMap the hash map that contains the consolidated balance records. Its key can be the combined string value
051         *        of the given consolidation keys.
052         * @param ledgerBalance the given ledger balance to be consolidated
053         * @param consolidationKeys the given key field names used to build the keys of ledgerBalanceMap
054         */
055        public static void consolidateLedgerBalances(Map<String, LaborLedgerBalance> ledgerBalanceMap, LaborLedgerBalance ledgerBalance, String consolidationKeyFieldsAsString) {
056            if (ledgerBalanceMap.containsKey(consolidationKeyFieldsAsString)) {
057                LaborLedgerBalance existingBalance = ledgerBalanceMap.get(consolidationKeyFieldsAsString);
058                addLedgerBalanceAmounts(existingBalance, ledgerBalance);
059            }
060            else {
061                ledgerBalanceMap.put(consolidationKeyFieldsAsString, ledgerBalance);
062            }
063        }
064    
065        /**
066         * consolidate the amounts of the given ledger balances into the balances with the same values of specified key fields
067         * 
068         * @param ledgerBalanceMap the hash map that contains the consolidated balance records. Its key can be the combined string value
069         *        of the given consolidation keys.
070         * @param ledgerBalances the given ledger balances to be consolidated
071         * @param consolidationKeys the given key field names used to build the keys of ledgerBalanceMap
072         */
073        public static void consolidateLedgerBalances(Map<String, LaborLedgerBalance> ledgerBalanceMap, Collection<LaborLedgerBalance> ledgerBalances, List<String> consolidationKeys) {
074            for (LaborLedgerBalance balance : ledgerBalances) {
075                consolidateLedgerBalances(ledgerBalanceMap, balance, consolidationKeys);
076            }
077        }
078    
079        /**
080         * group the given ledger balance into the list of balances with the same values of specified key fields
081         * 
082         * @param ledgerBalanceMap the hash map that contains a set of ledger balance lists. Its key can be the combined string value of
083         *        the given consolidation keys.
084         * @param ledgerBalance the given ledger balance to be grouped
085         * @param consolidationKeys the given key field names used to build the keys of ledgerBalanceMap
086         */
087        public static void groupLedgerBalancesByKeys(Map<String, List<LaborLedgerBalance>> ledgerBalanceMap, LaborLedgerBalance ledgerBalance, List<String> consolidationKeys) {
088            String consolidationKeyFieldsAsString = ObjectUtil.concatPropertyAsString(ledgerBalance, consolidationKeys);
089            groupLedgerBalancesByKeys(ledgerBalanceMap, ledgerBalance, consolidationKeyFieldsAsString);
090        }
091        
092        /**
093         * group the given ledger balance into the list of balances with the same values of specified key fields
094         * 
095         * @param ledgerBalanceMap the hash map that contains a set of ledger balance lists. Its key can be the combined string value of
096         *        the given consolidation keys.
097         * @param ledgerBalance the given ledger balance to be grouped
098         * @param consolidationKeys the given key field names used to build the keys of ledgerBalanceMap
099         */
100        public static void groupLedgerBalancesByKeys(Map<String, List<LaborLedgerBalance>> ledgerBalanceMap, LaborLedgerBalance ledgerBalance, String consolidationKeyFieldsAsString) {
101            if (ledgerBalanceMap.containsKey(consolidationKeyFieldsAsString)) {
102                List<LaborLedgerBalance> balanceList = ledgerBalanceMap.get(consolidationKeyFieldsAsString);
103                balanceList.add(ledgerBalance);
104            }
105            else {
106                List<LaborLedgerBalance> balanceList = new ArrayList<LaborLedgerBalance>();
107                balanceList.add(ledgerBalance);
108                ledgerBalanceMap.put(consolidationKeyFieldsAsString, balanceList);
109            }
110        }
111    
112        /**
113         * group the given ledger balances into the lists of balances with the same values of specified key fields
114         * 
115         * @param ledgerBalanceMap the hash map that contains a set of ledger balance lists. Its key can be the combined string value of
116         *        the given consolidation keys.
117         * @param ledgerBalance the given ledger balances to be grouped
118         * @param consolidationKeys the given key field names used to build the keys of ledgerBalanceMap
119         */
120        public static void groupLedgerBalancesByKeys(Map<String, List<LaborLedgerBalance>> ledgerBalanceMap, Collection<LaborLedgerBalance> ledgerBalances, List<String> consolidationKeys) {
121            for (LaborLedgerBalance balance : ledgerBalances) {
122                groupLedgerBalancesByKeys(ledgerBalanceMap, balance, consolidationKeys);
123            }
124        }
125    
126        /**
127         * add the monthly amounts of the second ledger balance with those of the first one
128         * 
129         * @param ledgerBalance the given ledger balance, which holds the summerized monthly amounts
130         * @param anotherLedgerBalance the given ledger balance, which contributes monthly amounts
131         */
132        public static void addLedgerBalanceAmounts(LaborLedgerBalance ledgerBalance, LaborLedgerBalance anotherLedgerBalance) {
133            if (anotherLedgerBalance == null) {
134                return;
135            }
136    
137            if (ledgerBalance == null) {
138                ledgerBalance = anotherLedgerBalance;
139                return;
140            }
141    
142            for (AccountingPeriodMonth period : AccountingPeriodMonth.values()) {
143                KualiDecimal amount = anotherLedgerBalance.getAmountByPeriod(period.periodCode);
144                ledgerBalance.addAmount(period.periodCode, amount);
145            }
146        }
147    
148        /**
149         * summurize the balance amounts of a given ledger balance within the specified report periods
150         * 
151         * @param ledgerBalance the given labor ledger balance
152         * @param reportPeriods the given report periods
153         * @return the total amounts of the given balance within the specified report periods
154         */
155        public static KualiDecimal calculateTotalAmountWithinReportPeriod(LaborLedgerBalance ledgerBalance, Map<Integer, Set<String>> reportPeriods) {
156            Integer fiscalYear = ledgerBalance.getUniversityFiscalYear();
157            KualiDecimal totalAmount = KualiDecimal.ZERO;
158    
159            Set<String> periodCodes = reportPeriods.get(fiscalYear);
160            for (String period : periodCodes) {
161                totalAmount = totalAmount.add(ledgerBalance.getAmountByPeriod(period));
162            }
163            return totalAmount;
164        }
165    
166        /**
167         * summurize the balance amounts of the given ledger balances within the specified report periods
168         * 
169         * @param ledgerBalance the given labor ledger balances
170         * @param reportPeriods the given report periods
171         * @return the total amounts of the given balances within the specified report periods
172         */
173        public static KualiDecimal calculateTotalAmountWithinReportPeriod(Collection<LaborLedgerBalance> ledgerBalances, Map<Integer, Set<String>> reportPeriods) {
174            KualiDecimal totalAmount = KualiDecimal.ZERO;
175    
176            for (LaborLedgerBalance ledgerBalance : ledgerBalances) {
177                KualiDecimal totalAmountForOneBalance = calculateTotalAmountWithinReportPeriod(ledgerBalance, reportPeriods);
178                totalAmount = totalAmount.add(totalAmountForOneBalance);
179            }
180            return totalAmount;
181        }
182    }