/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.ld.util; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.ojb.broker.query.ReportQueryByCriteria; import org.kuali.kfs.module.ld.businessobject.LedgerBalance; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.ObjectUtil; /** * Utility class for helping DAOs deal with building queries for the consolidation option */ public class ConsolidationUtil { private static final org.apache.commons.logging.Log LOG = org.apache.commons.logging.LogFactory.getLog(ConsolidationUtil.class); /** * wrap the given field name with SQL function "sum" * * @param fieldName the given field name * @return the wrapped field name with SQL function "sum" */ public static final String sum(String fieldName) { return "sum(" + fieldName + ")"; } /** * This method builds the atrribute list used by balance searching * * @param extendedFields extra fields * @return List an attribute list */ public static Collection<String> buildAttributeCollection(String... extendedFields) { return buildAttributeCollection(Arrays.asList(extendedFields)); } /** * This method builds the atrribute list used by balance searching * * @param extendedFields extra fields * @return Collection an attribute list */ public static Collection<String> buildAttributeCollection(Collection<String> extendedFields) { Collection<String> attributeList = buildGroupByCollection(); attributeList.add(sum(KFSPropertyConstants.ACCOUNT_LINE_ANNUAL_BALANCE_AMOUNT)); attributeList.add(sum(KFSPropertyConstants.FINANCIAL_BEGINNING_BALANCE_LINE_AMOUNT)); attributeList.add(sum(KFSPropertyConstants.CONTRACTS_GRANTS_BEGINNING_BALANCE_AMOUNT)); // add the entended elements into the list attributeList.addAll(extendedFields); return attributeList; } /** * Utility class for helping DAOs deal with building queries for the consolidation option * * @param query Query to make consolidated * @param extraFields fields included in the query * @param ignoredFields to omit from the query */ public static void buildConsolidatedQuery(ReportQueryByCriteria query, String... extraFields) { Collection<String> attributeList = buildAttributeCollection(extraFields); Collection<String> groupByList = buildGroupByCollection(); attributeList.remove(KFSPropertyConstants.SUB_ACCOUNT_NUMBER); groupByList.remove(KFSPropertyConstants.SUB_ACCOUNT_NUMBER); attributeList.remove(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE); groupByList.remove(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE); attributeList.remove(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE); groupByList.remove(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE); // set the selection attributes String[] attributes = (String[]) attributeList.toArray(new String[attributeList.size()]); query.setAttributes(attributes); if (LOG.isDebugEnabled()) { LOG.debug("Built Attributes for Query: " + attributeList.toString()); } // add the group criteria into the selection statement String[] groupBy = (String[]) groupByList.toArray(new String[attributeList.size()]); query.addGroupBy(groupBy); if (LOG.isDebugEnabled()) { LOG.debug("Built GroupBy for Query: " + groupByList.toString()); } } /** * This method builds group by attribute list used by balance searching * * @return extraFields * @return Collection an group by attribute list */ public static Collection<String> buildGroupByCollection(Collection<String> extraFields) { Collection<String> retval = new ArrayList(); retval.add(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR); retval.add(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE); retval.add(KFSPropertyConstants.ACCOUNT_NUMBER); retval.add(KFSPropertyConstants.SUB_ACCOUNT_NUMBER); retval.add(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE); retval.add(KFSPropertyConstants.FINANCIAL_OBJECT_CODE); retval.add(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE); retval.add(KFSPropertyConstants.FINANCIAL_OBJECT_TYPE_CODE); retval.add(KFSPropertyConstants.EMPLID); retval.add(KFSPropertyConstants.POSITION_NUMBER); retval.addAll(extraFields); return retval; } /** * This method builds group by attribute list used by balance searching * * @return extraFields * @return Collection an group by attribute list */ public static Collection<String> buildGroupByCollection(String... extraFields) { return buildGroupByCollection(Arrays.asList(extraFields)); } /** * Consolidates a collection of actual balances with a collection of A2 balances. The A2 balances are changed to AC, then * matched by balance key with balances from the actual collection. * * @param actualBalances - collection of actual balances (consolidatedBalanceTypeCode) * @param effortBalances - collection of effort balances ('A2') * @param consolidatedBalanceTypeCode - balance type to change A2 records to * @return Collection<LedgerBalance> - collection with consolidated balance records */ public static Collection<LedgerBalance> consolidateA2Balances(Collection<LedgerBalance> actualBalances, Collection<LedgerBalance> effortBalances, String consolidatedBalanceTypeCode, List<String> consolidationKeyList) { Map<String, LedgerBalance> consolidatedBalanceMap = new HashMap<String, LedgerBalance>(); for (LedgerBalance effortBalance : effortBalances) { effortBalance.setBalanceTypeCode(consolidatedBalanceTypeCode); String consolidationKey = ObjectUtil.buildPropertyMap(effortBalance, consolidationKeyList).toString(); if(consolidatedBalanceMap.containsKey(consolidationKey)) { LedgerBalance ledgerBalance = consolidatedBalanceMap.get(consolidationKey); sumLedgerBalances(ledgerBalance, effortBalance); } else { consolidatedBalanceMap.put(consolidationKey, effortBalance); } } for (LedgerBalance actualBalance : actualBalances) { actualBalance.setBalanceTypeCode(consolidatedBalanceTypeCode); String consolidationKey = ObjectUtil.buildPropertyMap(actualBalance, consolidationKeyList).toString(); if(consolidatedBalanceMap.containsKey(consolidationKey)) { LedgerBalance ledgerBalance = consolidatedBalanceMap.get(consolidationKey); sumLedgerBalances(ledgerBalance, actualBalance); } else { consolidatedBalanceMap.put(consolidationKey, actualBalance); } } return consolidatedBalanceMap.values(); } /** * Adds the amounts fields of the second balance record to the first. * * @param balance1 - LedgerBalance * @param balance2 - LedgerBalance */ public static void sumLedgerBalances(LedgerBalance balance1, LedgerBalance balance2) { balance1.setAccountLineAnnualBalanceAmount(balance1.getAccountLineAnnualBalanceAmount().add(balance2.getAccountLineAnnualBalanceAmount())); balance1.setBeginningBalanceLineAmount(balance1.getBeginningBalanceLineAmount().add(balance2.getBeginningBalanceLineAmount())); balance1.setContractsGrantsBeginningBalanceAmount(balance1.getContractsGrantsBeginningBalanceAmount().add(balance2.getContractsGrantsBeginningBalanceAmount())); balance1.setMonth1Amount(balance1.getMonth1Amount().add(balance2.getMonth1Amount())); balance1.setMonth2Amount(balance1.getMonth2Amount().add(balance2.getMonth2Amount())); balance1.setMonth3Amount(balance1.getMonth3Amount().add(balance2.getMonth3Amount())); balance1.setMonth4Amount(balance1.getMonth4Amount().add(balance2.getMonth4Amount())); balance1.setMonth5Amount(balance1.getMonth5Amount().add(balance2.getMonth5Amount())); balance1.setMonth6Amount(balance1.getMonth6Amount().add(balance2.getMonth6Amount())); balance1.setMonth7Amount(balance1.getMonth7Amount().add(balance2.getMonth7Amount())); balance1.setMonth8Amount(balance1.getMonth8Amount().add(balance2.getMonth8Amount())); balance1.setMonth9Amount(balance1.getMonth9Amount().add(balance2.getMonth9Amount())); balance1.setMonth10Amount(balance1.getMonth10Amount().add(balance2.getMonth10Amount())); balance1.setMonth11Amount(balance1.getMonth11Amount().add(balance2.getMonth11Amount())); balance1.setMonth12Amount(balance1.getMonth12Amount().add(balance2.getMonth12Amount())); balance1.setMonth13Amount(balance1.getMonth13Amount().add(balance2.getMonth13Amount())); } /** * wrap the attribute name based on the given flag: isAttributeNameNeeded * * @param attributeName the given attribute name * @param isAttributeNameNeeded the flag that indicates if the attribute name needs to be wrapped with consolidation * @return the attribute name as it is if isAttributeNameNeeded is true; otherwise, the attribute name wrapped with * consolidation string */ public static String wrapAttributeName(String attributeName, boolean isAttributeNameNeeded) { return isAttributeNameNeeded ? attributeName : ConsolidationUtil.sum(attributeName); } }