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 }