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.ld.util; 017 018 import java.util.ArrayList; 019 import java.util.Arrays; 020 import java.util.Collection; 021 import java.util.HashMap; 022 import java.util.List; 023 import java.util.Map; 024 025 import org.apache.commons.lang.StringUtils; 026 import org.apache.ojb.broker.query.ReportQueryByCriteria; 027 import org.kuali.kfs.module.ld.LaborConstants; 028 import org.kuali.kfs.module.ld.businessobject.LedgerBalance; 029 import org.kuali.kfs.sys.KFSPropertyConstants; 030 import org.kuali.kfs.sys.ObjectUtil; 031 032 /** 033 * Utility class for helping DAOs deal with building queries for the consolidation option 034 */ 035 public class ConsolidationUtil { 036 private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory.getLog(ConsolidationUtil.class); 037 038 /** 039 * wrap the given field name with SQL function "sum" 040 * 041 * @param fieldName the given field name 042 * @return the wrapped field name with SQL function "sum" 043 */ 044 public static final String sum(String fieldName) { 045 return "sum(" + fieldName + ")"; 046 } 047 048 /** 049 * This method builds the atrribute list used by balance searching 050 * 051 * @param extendedFields extra fields 052 * @return List an attribute list 053 */ 054 public static Collection<String> buildAttributeCollection(String... extendedFields) { 055 return buildAttributeCollection(Arrays.asList(extendedFields)); 056 } 057 058 /** 059 * This method builds the atrribute list used by balance searching 060 * 061 * @param extendedFields extra fields 062 * @return Collection an attribute list 063 */ 064 public static Collection<String> buildAttributeCollection(Collection<String> extendedFields) { 065 Collection<String> attributeList = buildGroupByCollection(); 066 067 attributeList.add(sum(KFSPropertyConstants.ACCOUNT_LINE_ANNUAL_BALANCE_AMOUNT)); 068 attributeList.add(sum(KFSPropertyConstants.FINANCIAL_BEGINNING_BALANCE_LINE_AMOUNT)); 069 attributeList.add(sum(KFSPropertyConstants.CONTRACTS_GRANTS_BEGINNING_BALANCE_AMOUNT)); 070 071 // add the entended elements into the list 072 attributeList.addAll(extendedFields); 073 return attributeList; 074 } 075 076 /** 077 * Utility class for helping DAOs deal with building queries for the consolidation option 078 * 079 * @param query Query to make consolidated 080 * @param extraFields fields included in the query 081 * @param ignoredFields to omit from the query 082 */ 083 public static void buildConsolidatedQuery(ReportQueryByCriteria query, String... extraFields) { 084 Collection<String> attributeList = buildAttributeCollection(extraFields); 085 Collection<String> groupByList = buildGroupByCollection(); 086 087 attributeList.remove(KFSPropertyConstants.SUB_ACCOUNT_NUMBER); 088 groupByList.remove(KFSPropertyConstants.SUB_ACCOUNT_NUMBER); 089 attributeList.remove(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE); 090 groupByList.remove(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE); 091 attributeList.remove(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE); 092 groupByList.remove(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE); 093 094 // set the selection attributes 095 String[] attributes = (String[]) attributeList.toArray(new String[attributeList.size()]); 096 query.setAttributes(attributes); 097 LOG.debug("Built Attributes for Query: " + attributeList.toString()); 098 099 // add the group criteria into the selection statement 100 String[] groupBy = (String[]) groupByList.toArray(new String[attributeList.size()]); 101 query.addGroupBy(groupBy); 102 LOG.debug("Built GroupBy for Query: " + groupByList.toString()); 103 } 104 105 /** 106 * This method builds group by attribute list used by balance searching 107 * 108 * @return extraFields 109 * @return Collection an group by attribute list 110 */ 111 public static Collection<String> buildGroupByCollection(Collection<String> extraFields) { 112 Collection<String> retval = new ArrayList(); 113 retval.add(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR); 114 retval.add(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE); 115 retval.add(KFSPropertyConstants.ACCOUNT_NUMBER); 116 retval.add(KFSPropertyConstants.SUB_ACCOUNT_NUMBER); 117 retval.add(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE); 118 retval.add(KFSPropertyConstants.FINANCIAL_OBJECT_CODE); 119 retval.add(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE); 120 retval.add(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE); 121 retval.add(KFSPropertyConstants.EMPLID); 122 retval.add(KFSPropertyConstants.POSITION_NUMBER); 123 retval.addAll(extraFields); 124 return retval; 125 } 126 127 /** 128 * This method builds group by attribute list used by balance searching 129 * 130 * @return extraFields 131 * @return Collection an group by attribute list 132 */ 133 public static Collection<String> buildGroupByCollection(String... extraFields) { 134 return buildGroupByCollection(Arrays.asList(extraFields)); 135 } 136 137 /** 138 * Consolidates a collection of actual balances with a collection of A2 balances. The A2 balances are changed to AC, then 139 * matched by balance key with balances from the actual collection. 140 * 141 * @param actualBalances - collection of actual balances (consolidatedBalanceTypeCode) 142 * @param effortBalances - collection of effort balances ('A2') 143 * @param consolidatedBalanceTypeCode - balance type to change A2 records to 144 * @return Collection<LedgerBalance> - collection with consolidated balance records 145 */ 146 public static Collection<LedgerBalance> consolidateA2Balances(Collection<LedgerBalance> actualBalances, Collection<LedgerBalance> effortBalances, String consolidatedBalanceTypeCode, List<String> consolidationKeyList) { 147 Map<String, LedgerBalance> consolidatedBalanceMap = new HashMap<String, LedgerBalance>(); 148 for (LedgerBalance effortBalance : effortBalances) { 149 effortBalance.setBalanceTypeCode(consolidatedBalanceTypeCode); 150 String consolidationKey = ObjectUtil.buildPropertyMap(effortBalance, consolidationKeyList).toString(); 151 152 if(consolidatedBalanceMap.containsKey(consolidationKey)) { 153 LedgerBalance ledgerBalance = consolidatedBalanceMap.get(consolidationKey); 154 sumLedgerBalances(ledgerBalance, effortBalance); 155 } 156 else { 157 consolidatedBalanceMap.put(consolidationKey, effortBalance); 158 } 159 } 160 161 for (LedgerBalance actualBalance : actualBalances) { 162 actualBalance.setBalanceTypeCode(consolidatedBalanceTypeCode); 163 String consolidationKey = ObjectUtil.buildPropertyMap(actualBalance, consolidationKeyList).toString(); 164 165 if(consolidatedBalanceMap.containsKey(consolidationKey)) { 166 LedgerBalance ledgerBalance = consolidatedBalanceMap.get(consolidationKey); 167 sumLedgerBalances(ledgerBalance, actualBalance); 168 } 169 else { 170 consolidatedBalanceMap.put(consolidationKey, actualBalance); 171 } 172 } 173 174 return consolidatedBalanceMap.values(); 175 } 176 177 /** 178 * Adds the amounts fields of the second balance record to the first. 179 * 180 * @param balance1 - LedgerBalance 181 * @param balance2 - LedgerBalance 182 */ 183 public static void sumLedgerBalances(LedgerBalance balance1, LedgerBalance balance2) { 184 balance1.setAccountLineAnnualBalanceAmount(balance1.getAccountLineAnnualBalanceAmount().add(balance2.getAccountLineAnnualBalanceAmount())); 185 balance1.setBeginningBalanceLineAmount(balance1.getBeginningBalanceLineAmount().add(balance2.getBeginningBalanceLineAmount())); 186 balance1.setContractsGrantsBeginningBalanceAmount(balance1.getContractsGrantsBeginningBalanceAmount().add(balance2.getContractsGrantsBeginningBalanceAmount())); 187 balance1.setMonth1Amount(balance1.getMonth1Amount().add(balance2.getMonth1Amount())); 188 balance1.setMonth2Amount(balance1.getMonth2Amount().add(balance2.getMonth2Amount())); 189 balance1.setMonth3Amount(balance1.getMonth3Amount().add(balance2.getMonth3Amount())); 190 balance1.setMonth4Amount(balance1.getMonth4Amount().add(balance2.getMonth4Amount())); 191 balance1.setMonth5Amount(balance1.getMonth5Amount().add(balance2.getMonth5Amount())); 192 balance1.setMonth6Amount(balance1.getMonth6Amount().add(balance2.getMonth6Amount())); 193 balance1.setMonth7Amount(balance1.getMonth7Amount().add(balance2.getMonth7Amount())); 194 balance1.setMonth8Amount(balance1.getMonth8Amount().add(balance2.getMonth8Amount())); 195 balance1.setMonth9Amount(balance1.getMonth9Amount().add(balance2.getMonth9Amount())); 196 balance1.setMonth10Amount(balance1.getMonth10Amount().add(balance2.getMonth10Amount())); 197 balance1.setMonth11Amount(balance1.getMonth11Amount().add(balance2.getMonth11Amount())); 198 balance1.setMonth12Amount(balance1.getMonth12Amount().add(balance2.getMonth12Amount())); 199 balance1.setMonth13Amount(balance1.getMonth13Amount().add(balance2.getMonth13Amount())); 200 } 201 202 /** 203 * wrap the attribute name based on the given flag: isAttributeNameNeeded 204 * 205 * @param attributeName the given attribute name 206 * @param isAttributeNameNeeded the flag that indicates if the attribute name needs to be wrapped with consolidation 207 * @return the attribute name as it is if isAttributeNameNeeded is true; otherwise, the attribute name wrapped with 208 * consolidation string 209 */ 210 public static String wrapAttributeName(String attributeName, boolean isAttributeNameNeeded) { 211 return isAttributeNameNeeded ? attributeName : ConsolidationUtil.sum(attributeName); 212 } 213 }