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.businessobject.lookup;
017
018 import static org.kuali.kfs.module.ld.LaborConstants.BalanceInquiries.BALANCE_TYPE_AC_AND_A21;
019
020 import java.util.ArrayList;
021 import java.util.Collection;
022 import java.util.Collections;
023 import java.util.HashMap;
024 import java.util.Iterator;
025 import java.util.List;
026 import java.util.Map;
027
028 import org.apache.commons.lang.StringUtils;
029 import org.apache.commons.logging.Log;
030 import org.apache.commons.logging.LogFactory;
031 import org.kuali.kfs.gl.Constant;
032 import org.kuali.kfs.gl.OJBUtility;
033 import org.kuali.kfs.module.ld.businessobject.LedgerBalance;
034 import org.kuali.kfs.module.ld.businessobject.inquiry.AbstractLaborInquirableImpl;
035 import org.kuali.kfs.module.ld.businessobject.inquiry.LedgerBalanceInquirableImpl;
036 import org.kuali.kfs.module.ld.businessobject.inquiry.PositionDataDetailsInquirableImpl;
037 import org.kuali.kfs.module.ld.service.LaborInquiryOptionsService;
038 import org.kuali.kfs.module.ld.service.LaborLedgerBalanceService;
039 import org.kuali.kfs.module.ld.util.ConsolidationUtil;
040 import org.kuali.kfs.sys.KFSConstants;
041 import org.kuali.kfs.sys.KFSPropertyConstants;
042 import org.kuali.rice.kns.bo.BusinessObject;
043 import org.kuali.rice.kns.lookup.AbstractLookupableHelperServiceImpl;
044 import org.kuali.rice.kns.lookup.CollectionIncomplete;
045 import org.kuali.rice.kns.lookup.HtmlData;
046 import org.kuali.rice.kns.lookup.HtmlData.AnchorHtmlData;
047 import org.kuali.rice.kns.util.BeanPropertyComparator;
048 import org.kuali.rice.kns.util.GlobalVariables;
049 import org.kuali.rice.kns.util.KNSConstants;
050 import org.kuali.rice.kns.util.KualiDecimal;
051
052 /**
053 * Service implementation of LedgerBalanceLookupableHelperService. The class is the front-end for all Ledger balance inquiry
054 * processing.
055 */
056 public class LedgerBalanceLookupableHelperServiceImpl extends AbstractLookupableHelperServiceImpl {
057 private static final Log LOG = LogFactory.getLog(LedgerBalanceLookupableHelperServiceImpl.class);
058
059 private LaborLedgerBalanceService balanceService;
060 private LaborInquiryOptionsService laborInquiryOptionsService;
061
062 /**
063 * @see org.kuali.rice.kns.lookup.Lookupable#getInquiryUrl(org.kuali.rice.kns.bo.BusinessObject, java.lang.String)
064 */
065 @Override
066 public HtmlData getInquiryUrl(BusinessObject bo, String propertyName) {
067 if (KFSPropertyConstants.POSITION_NUMBER.equals(propertyName)) {
068 LedgerBalance balance = (LedgerBalance) bo;
069 AbstractLaborInquirableImpl positionDataDetailsInquirable = new PositionDataDetailsInquirableImpl();
070
071 Map<String, String> fieldValues = new HashMap<String, String>();
072 fieldValues.put(propertyName, balance.getPositionNumber());
073
074 BusinessObject positionData = positionDataDetailsInquirable.getBusinessObject(fieldValues);
075
076 return positionData == null ? new AnchorHtmlData(KFSConstants.EMPTY_STRING, KFSConstants.EMPTY_STRING) : positionDataDetailsInquirable.getInquiryUrl(positionData, propertyName);
077 }
078 return (new LedgerBalanceInquirableImpl()).getInquiryUrl(bo, propertyName);
079 }
080
081 /**
082 * @see org.kuali.rice.kns.lookup.Lookupable#getSearchResults(java.util.Map)
083 */
084 @Override
085 public List<? extends BusinessObject> getSearchResults(Map<String, String> fieldValues) {
086 String wildCards = "";
087 for (int i = 0; i < KNSConstants.QUERY_CHARACTERS.length; i++) {
088 wildCards += KNSConstants.QUERY_CHARACTERS[i];
089 }
090
091 if (wildCards.indexOf(fieldValues.get(KFSPropertyConstants.EMPLID).toString().trim()) != -1) {
092 // StringUtils.indexOfAny(fieldValues.get(KFSPropertyConstants.EMPLID).toString().trim(), KFSConstants.QUERY_CHARACTERS)
093 // != 0) {
094 List emptySearchResults = new ArrayList();
095 Long actualCountIfTruncated = new Long(0);
096 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.EMPLID, KFSConstants.WILDCARD_NOT_ALLOWED_ON_FIELD, "Employee ID field ");
097 return new CollectionIncomplete(emptySearchResults, actualCountIfTruncated);
098 }
099
100 setBackLocation((String) fieldValues.get(KFSConstants.BACK_LOCATION));
101 setDocFormKey((String) fieldValues.get(KFSConstants.DOC_FORM_KEY));
102
103 // get the pending entry option. This method must be prior to the get search results
104 String pendingEntryOption = laborInquiryOptionsService.getSelectedPendingEntryOption(fieldValues);
105
106 // test if the consolidation option is selected or not
107 boolean isConsolidated = laborInquiryOptionsService.isConsolidationSelected(fieldValues);
108
109 // get the input balance type code
110 String balanceTypeCode = fieldValues.get(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE);
111 boolean isA21Balance = StringUtils.isNotEmpty(balanceTypeCode) && BALANCE_TYPE_AC_AND_A21.equals(balanceTypeCode.trim());
112
113 // get the ledger balances with actual balance type code
114 if (isA21Balance) {
115 fieldValues.put(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE, KFSConstants.BALANCE_TYPE_ACTUAL);
116 }
117 Integer recordCountForActualBalance = balanceService.getBalanceRecordCount(fieldValues, isConsolidated);
118 Iterator actualBalanceIterator = balanceService.findBalance(fieldValues, isConsolidated);
119 Collection searchResultsCollection = buildBalanceCollection(actualBalanceIterator, isConsolidated, pendingEntryOption);
120 laborInquiryOptionsService.updateLedgerBalanceByPendingLedgerEntry(searchResultsCollection, fieldValues, pendingEntryOption, isConsolidated);
121
122 // get the search result collection
123 Integer recordCountForEffortBalance = 0;
124 if (isA21Balance) {
125 fieldValues.put(KFSPropertyConstants.FINANCIAL_BALANCE_TYPE_CODE, KFSConstants.BALANCE_TYPE_A21);
126 recordCountForEffortBalance = balanceService.getBalanceRecordCount(fieldValues, isConsolidated);
127
128 Iterator effortBalanceIterator = balanceService.findBalance(fieldValues, isConsolidated);
129 Collection effortBalances = buildBalanceCollection(effortBalanceIterator, isConsolidated, pendingEntryOption);
130 laborInquiryOptionsService.updateLedgerBalanceByPendingLedgerEntry(effortBalances, fieldValues, pendingEntryOption, isConsolidated);
131
132 List<String> consolidationKeyList = LedgerBalance.getPrimaryKeyList();
133 searchResultsCollection = ConsolidationUtil.consolidateA2Balances(searchResultsCollection, effortBalances, BALANCE_TYPE_AC_AND_A21, consolidationKeyList);
134 }
135
136 // get the actual size of all qualified search results
137 Integer recordCount = recordCountForActualBalance + recordCountForEffortBalance;
138 Long actualSize = OJBUtility.getResultActualSize(searchResultsCollection, recordCount, fieldValues, new LedgerBalance());
139
140 return this.buildSearchResultList(searchResultsCollection, actualSize);
141 }
142
143 /**
144 * This method builds the balance collection based on the input iterator
145 *
146 * @param iterator the iterator of search results of balance
147 * @param isConsolidated determine if the consolidated result is desired
148 * @param pendingEntryOption the given pending entry option that can be no, approved or all
149 * @return the balance collection
150 */
151 protected Collection buildBalanceCollection(Iterator iterator, boolean isConsolidated, String pendingEntryOption) {
152 Collection balanceCollection = null;
153
154 if (isConsolidated) {
155 balanceCollection = buildConsolidatedBalanceCollection(iterator, pendingEntryOption);
156 }
157 else {
158 balanceCollection = buildDetailedBalanceCollection(iterator, pendingEntryOption);
159 }
160 return balanceCollection;
161 }
162
163 /**
164 * This method builds the balance collection with consolidation option from an iterator
165 *
166 * @param iterator
167 * @param pendingEntryOption the selected pending entry option
168 * @return the consolidated balance collection
169 */
170 protected Collection buildConsolidatedBalanceCollection(Iterator iterator, String pendingEntryOption) {
171 Collection balanceCollection = new ArrayList();
172
173 while (iterator.hasNext()) {
174 Object collectionEntry = iterator.next();
175
176 if (collectionEntry.getClass().isArray()) {
177 int i = 0;
178 Object[] array = (Object[]) collectionEntry;
179 LedgerBalance balance = new LedgerBalance();
180
181 if (LedgerBalance.class.isAssignableFrom(getBusinessObjectClass())) {
182 try {
183 balance = (LedgerBalance) getBusinessObjectClass().newInstance();
184 }
185 catch (Exception e) {
186 LOG.warn("Using " + LedgerBalance.class + " for results because I couldn't instantiate the " + getBusinessObjectClass());
187 }
188 }
189 else {
190 LOG.warn("Using " + LedgerBalance.class + " for results because I couldn't instantiate the " + getBusinessObjectClass());
191 }
192
193 balance.setUniversityFiscalYear(new Integer(array[i++].toString()));
194 balance.setChartOfAccountsCode(array[i++].toString());
195 balance.setAccountNumber(array[i++].toString());
196
197 String subAccountNumber = Constant.CONSOLIDATED_SUB_ACCOUNT_NUMBER;
198 balance.setSubAccountNumber(subAccountNumber);
199
200 balance.setBalanceTypeCode(array[i++].toString());
201 balance.setFinancialObjectCode(array[i++].toString());
202
203 balance.setEmplid(array[i++].toString());
204 balance.setPositionNumber(array[i++].toString());
205
206 balance.setFinancialSubObjectCode(Constant.CONSOLIDATED_SUB_OBJECT_CODE);
207 balance.setFinancialObjectTypeCode(Constant.CONSOLIDATED_OBJECT_TYPE_CODE);
208
209 balance.setAccountLineAnnualBalanceAmount(new KualiDecimal(array[i++].toString()));
210 balance.setBeginningBalanceLineAmount(new KualiDecimal(array[i++].toString()));
211 balance.setContractsGrantsBeginningBalanceAmount(new KualiDecimal(array[i++].toString()));
212
213 balance.setMonth1Amount(new KualiDecimal(array[i++].toString()));
214 balance.setMonth2Amount(new KualiDecimal(array[i++].toString()));
215 balance.setMonth3Amount(new KualiDecimal(array[i++].toString()));
216 balance.setMonth4Amount(new KualiDecimal(array[i++].toString()));
217 balance.setMonth5Amount(new KualiDecimal(array[i++].toString()));
218 balance.setMonth6Amount(new KualiDecimal(array[i++].toString()));
219 balance.setMonth7Amount(new KualiDecimal(array[i++].toString()));
220 balance.setMonth8Amount(new KualiDecimal(array[i++].toString()));
221 balance.setMonth9Amount(new KualiDecimal(array[i++].toString()));
222
223 balance.setMonth10Amount(new KualiDecimal(array[i++].toString()));
224 balance.setMonth11Amount(new KualiDecimal(array[i++].toString()));
225 balance.setMonth12Amount(new KualiDecimal(array[i++].toString()));
226 balance.setMonth13Amount(new KualiDecimal(array[i].toString()));
227
228 balance.getDummyBusinessObject().setPendingEntryOption(pendingEntryOption);
229 balance.getDummyBusinessObject().setConsolidationOption(Constant.CONSOLIDATION);
230
231 balanceCollection.add(balance);
232 }
233 }
234 return balanceCollection;
235 }
236
237 /**
238 * This method builds the balance collection with detail option from an iterator
239 *
240 * @param iterator the balance iterator
241 * @param pendingEntryOption the selected pending entry option
242 * @return the detailed balance collection
243 */
244 protected Collection buildDetailedBalanceCollection(Iterator iterator, String pendingEntryOption) {
245 Collection balanceCollection = new ArrayList();
246
247 while (iterator.hasNext()) {
248 LedgerBalance copyBalance = (LedgerBalance) (iterator.next());
249
250 LedgerBalance balance = new LedgerBalance();
251 if (LedgerBalance.class.isAssignableFrom(getBusinessObjectClass())) {
252 try {
253 balance = (LedgerBalance) getBusinessObjectClass().newInstance();
254 }
255 catch (Exception e) {
256 LOG.warn("Using " + LedgerBalance.class + " for results because I couldn't instantiate the " + getBusinessObjectClass());
257 }
258 }
259 else {
260 LOG.warn("Using " + LedgerBalance.class + " for results because I couldn't instantiate the " + getBusinessObjectClass());
261 }
262
263 balance.setUniversityFiscalYear(copyBalance.getUniversityFiscalYear());
264 balance.setChartOfAccountsCode(copyBalance.getChartOfAccountsCode());
265 balance.setAccountNumber(copyBalance.getAccountNumber());
266 balance.setSubAccountNumber(copyBalance.getSubAccountNumber());
267 balance.setBalanceTypeCode(copyBalance.getBalanceTypeCode());
268 balance.setFinancialObjectCode(copyBalance.getFinancialObjectCode());
269 balance.setEmplid(copyBalance.getEmplid());
270 balance.setObjectId(copyBalance.getObjectId());
271 balance.setPositionNumber(copyBalance.getPositionNumber());
272 balance.setFinancialSubObjectCode(copyBalance.getFinancialSubObjectCode());
273 balance.setFinancialObjectTypeCode(copyBalance.getFinancialObjectTypeCode());
274 balance.setAccountLineAnnualBalanceAmount(copyBalance.getAccountLineAnnualBalanceAmount());
275 balance.setBeginningBalanceLineAmount(copyBalance.getBeginningBalanceLineAmount());
276 balance.setContractsGrantsBeginningBalanceAmount(copyBalance.getContractsGrantsBeginningBalanceAmount());
277 balance.setMonth1Amount(copyBalance.getMonth1Amount());
278 balance.setMonth2Amount(copyBalance.getMonth2Amount());
279 balance.setMonth3Amount(copyBalance.getMonth3Amount());
280 balance.setMonth4Amount(copyBalance.getMonth4Amount());
281 balance.setMonth5Amount(copyBalance.getMonth5Amount());
282 balance.setMonth6Amount(copyBalance.getMonth6Amount());
283 balance.setMonth7Amount(copyBalance.getMonth7Amount());
284 balance.setMonth8Amount(copyBalance.getMonth8Amount());
285 balance.setMonth9Amount(copyBalance.getMonth9Amount());
286 balance.setMonth10Amount(copyBalance.getMonth10Amount());
287 balance.setMonth11Amount(copyBalance.getMonth11Amount());
288 balance.setMonth12Amount(copyBalance.getMonth12Amount());
289 balance.setMonth13Amount(copyBalance.getMonth13Amount());
290
291 balance.getDummyBusinessObject().setPendingEntryOption(pendingEntryOption);
292 balance.getDummyBusinessObject().setConsolidationOption(Constant.DETAIL);
293
294 balanceCollection.add(balance);
295 }
296 return balanceCollection;
297 }
298
299 /**
300 * build the serach result list from the given collection and the number of all qualified search results
301 *
302 * @param searchResultsCollection the given search results, which may be a subset of the qualified search results
303 * @param actualSize the number of all qualified search results
304 * @return the serach result list with the given results and actual size
305 */
306 protected List buildSearchResultList(Collection searchResultsCollection, Long actualSize) {
307 CollectionIncomplete results = new CollectionIncomplete(searchResultsCollection, actualSize);
308
309 // sort list if default sort column given
310 List searchResults = (List) results;
311 List defaultSortColumns = getDefaultSortColumns();
312 if (defaultSortColumns.size() > 0) {
313 Collections.sort(results, new BeanPropertyComparator(defaultSortColumns, true));
314 }
315 return searchResults;
316 }
317
318 /**
319 * Sets the laborInquiryOptionsService attribute value.
320 *
321 * @param laborInquiryOptionsService The laborInquiryOptionsService to set.
322 */
323 public void setLaborInquiryOptionsService(LaborInquiryOptionsService laborInquiryOptionsService) {
324 this.laborInquiryOptionsService = laborInquiryOptionsService;
325 }
326
327 /**
328 * Sets the balanceService attribute value.
329 *
330 * @param balanceService The balanceService to set.
331 */
332 public void setBalanceService(LaborLedgerBalanceService balanceService) {
333 this.balanceService = balanceService;
334 }
335
336 /**
337 * Gets the balanceService attribute.
338 *
339 * @return Returns the balanceService.
340 */
341 public LaborLedgerBalanceService getBalanceService() {
342 return balanceService;
343 }
344 }