/* * 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.fp.document.web.struts; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.kuali.kfs.fp.businessobject.CapitalAccountingLines; import org.kuali.kfs.fp.businessobject.CapitalAssetAccountsGroupDetails; import org.kuali.kfs.fp.businessobject.CapitalAssetInformation; import org.kuali.kfs.fp.businessobject.CapitalAssetInformationDetail; import org.kuali.kfs.fp.document.CapitalAccountingLinesDocumentBase; import org.kuali.kfs.fp.document.CapitalAssetEditable; import org.kuali.kfs.fp.document.CapitalAssetInformationDocumentBase; import org.kuali.kfs.integration.cab.CapitalAssetBuilderModuleService; import org.kuali.kfs.integration.cam.businessobject.Asset; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSKeyConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.businessobject.AccountingLine; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.document.AccountingDocument; import org.kuali.kfs.sys.service.SegmentedLookupResultsService; import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentActionBase; import org.kuali.kfs.sys.web.struts.KualiAccountingDocumentFormBase; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.kns.util.WebUtils; import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase; import org.kuali.rice.kns.web.struts.form.KualiForm; import org.kuali.rice.krad.bo.PersistableBusinessObject; import org.kuali.rice.krad.util.GlobalVariables; import org.kuali.rice.krad.util.ObjectUtils; /** * This is the action class for the CapitalAssetInformationActionBase. */ public abstract class CapitalAssetInformationActionBase extends KualiAccountingDocumentActionBase { protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(CapitalAssetInformationActionBase.class); /** * Multi-value asset lookup is implemented through the integration package by module's service * to gather the results. The results are processed for any capital accounting lines where * the line is marked for selection. After the capital assets are populated with the * selected asset numbers, the system control amount is redistributed equally among the assets * when the distribution method is "distribute cost equally". * * @see org.kuali.rice.kns.web.struts.action.KualiAction#refresh(org.apache.struts.action.ActionMapping, * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public ActionForward refresh(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { super.refresh(mapping, form, request, response); //process the multiple value lookup data CapitalAssetInformationFormBase capitalAssetInformationFormBase = (CapitalAssetInformationFormBase) form; Collection<PersistableBusinessObject> rawValues = null; Map<String, Set<String>> segmentedSelection = new HashMap<String, Set<String>>(); // If multiple asset lookup was used to select the assets, then.... if (StringUtils.equals(KFSConstants.MULTIPLE_VALUE, capitalAssetInformationFormBase.getRefreshCaller())) { String lookupResultsSequenceNumber = capitalAssetInformationFormBase.getLookupResultsSequenceNumber(); if (StringUtils.isNotBlank(lookupResultsSequenceNumber)) { // actually returning from a multiple value lookup Set<String> selectedIds = SpringContext.getBean(SegmentedLookupResultsService.class).retrieveSetOfSelectedObjectIds(lookupResultsSequenceNumber, GlobalVariables.getUserSession().getPerson().getPrincipalId()); for (String selectedId : selectedIds) { String selectedObjId = StringUtils.substringBefore(selectedId, "."); if (!segmentedSelection.containsKey(selectedObjId)) { segmentedSelection.put(selectedObjId, new HashSet<String>()); } } // Retrieving selected data from table. if (LOG.isDebugEnabled()) { LOG.debug("Asking segmentation service for object ids " + segmentedSelection.keySet()); } rawValues = SpringContext.getBean(SegmentedLookupResultsService.class).retrieveSelectedResultBOs(lookupResultsSequenceNumber, segmentedSelection.keySet(), Asset.class, GlobalVariables.getUserSession().getPerson().getPrincipalId()); } if (rawValues == null || rawValues.size() == 0) { //redistribute capital asset amount to its group accounting lines on refresh DistributeCapitalAssetAmountToGroupAccountingLines((KualiAccountingDocumentFormBase) form); return mapping.findForward(KFSConstants.MAPPING_BASIC); } KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; CapitalAccountingLinesFormBase calfb = (CapitalAccountingLinesFormBase) form; CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { selectedCapitalAccountingLines.add(capitalAccountingLine); } } //process the data and create assets only for those accounting lines //where capital accounting line is "selected" and its amount is greater than already allocated. if (rawValues != null) { for (PersistableBusinessObject bo : rawValues) { Asset asset = (Asset) bo; // boolean addIt = true; boolean addIt = modifyAssetAlreadyExists(capitalAssetInformation, asset.getCapitalAssetNumber()); // If it doesn't already exist in the list add it. if (addIt) { createNewModifyCapitalAsset(selectedCapitalAccountingLines, capitalAssetInformation, calfb.getDocument().getDocumentNumber(), KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR, getNextCapitalAssetLineNumber(kualiAccountingDocumentFormBase), asset.getCapitalAssetNumber()); } } checkCapitalAccountingLinesSelected(calfb); // remove the blank capital asset modify records now... removeEmptyCapitalAssetModify(capitalAssetInformation); //now redistribute the amount for all assets if needed.... redistributeModifyCapitalAssetAmount(mapping, form, request, response); } } //redistribute capital asset amount to its group accounting lines on refresh DistributeCapitalAssetAmountToGroupAccountingLines((KualiAccountingDocumentFormBase) form); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * Remove if and any blank capital asset modify lines. * @param capitalAssetInformation */ protected void removeEmptyCapitalAssetModify(List<CapitalAssetInformation> capitalAssetInformation) { List<CapitalAssetInformation> removeCapitalAssetModify = new ArrayList<CapitalAssetInformation>(); for (CapitalAssetInformation capitalAssetRecord : capitalAssetInformation) { if (ObjectUtils.isNull(capitalAssetRecord.getCapitalAssetNumber()) && KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equalsIgnoreCase(capitalAssetRecord.getCapitalAssetActionIndicator())) { removeCapitalAssetModify.add(capitalAssetRecord); } } if (!removeCapitalAssetModify.isEmpty()) { capitalAssetInformation.removeAll(removeCapitalAssetModify); } } /** * sums the capital assets amount distributed so far for a given capital accounting line * * @param currentCapitalAssetInformation * @param existingCapitalAsset * @return capitalAssetsAmount amount that has been distributed for the specific capital accounting line */ protected KualiDecimal getCapitalAssetsAmountAllocated(List<CapitalAssetInformation> currentCapitalAssetInformation, CapitalAccountingLines capitalAccountingLine) { //check the capital assets records totals KualiDecimal capitalAssetsAmount = KualiDecimal.ZERO; for (CapitalAssetInformation capitalAsset : currentCapitalAssetInformation) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { capitalAssetsAmount = capitalAssetsAmount.add(groupAccountLine.getAmount()); } } } return capitalAssetsAmount; } /** * checks the capital asset information list for the specific capital asset number * that was returned as part of the multi-value lookup. * * @param capitalAssetInformation * @param capitalAssetNumber * @return true if asset does not exist in the list else return false */ protected boolean modifyAssetAlreadyExists(List<CapitalAssetInformation> capitalAssetInformation, Long capitalAssetNumber) { boolean addIt = true; KualiDecimal capitalAssetCreatedAmount = KualiDecimal.ZERO; for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator()) && ObjectUtils.isNotNull(capitalAsset.getCapitalAssetNumber()) && capitalAsset.getCapitalAssetNumber().compareTo(capitalAssetNumber) == 0) { addIt = false; break; } } return addIt; } /** * checks if the selected capital accounting lines have a capital asset created by checking the * accounts associated with the capital asset information. * * @param capitalAccountingLine * @param capitalAsset * @return true if capital accounting line has a capital asset else return false. */ protected boolean capitalAssetExists(List<CapitalAccountingLines> capitalAccountingLines, CapitalAssetInformation capitalAsset, String actionTypeCode) { boolean exists = true; List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for(CapitalAccountingLines capitalAccountLine : capitalAccountingLines) { for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountLine.getFinancialObjectCode())) { return exists; } } } return false; } /** * * @param form */ protected void redistributeCostEquallyForModifiedAssets(ActionForm form) { KualiDecimal remainingAmountToDistribute = KualiDecimal.ZERO; CapitalAccountingLinesFormBase calfb = (CapitalAccountingLinesFormBase) form; CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); String distributionCode = calfb.getCapitalAccountingLine().getDistributionCode(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { selectedCapitalAccountingLines.add(capitalAccountingLine); remainingAmountToDistribute = remainingAmountToDistribute.add(capitalAccountingLine.getAmount()); } } KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); redistributeAmountsForAccountingsLineForModifyAssets(selectedCapitalAccountingLines, capitalAssetInformation, remainingAmountToDistribute); //now process any capital assets that has distribution set to "by amount" redistributeAmountsForAccountingsLineForModifyAssetsByAmounts(selectedCapitalAccountingLines, capitalAssetInformation, remainingAmountToDistribute); } /** * * @param accountingLine * @param capitalAssetInformation * @param remainingAmountToDistribute */ protected void redistributeAmountsForAccountingsLineForModifyAssets(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation, KualiDecimal remainingAmountToDistribute) { //get the total capital assets quantity int totalQuantity = getNumberOfModifiedAssetsExist(selectedCapitalAccountingLines, capitalAssetInformation); if (totalQuantity > 0) { KualiDecimal equalModifyAssetAmount = remainingAmountToDistribute.divide(new KualiDecimal(totalQuantity), true); int lastAssetIndex = 0; CapitalAssetInformation lastCapitalAsset = new CapitalAssetInformation(); if (equalModifyAssetAmount.compareTo(KualiDecimal.ZERO) != 0) { for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator()) && (ObjectUtils.isNotNull(capitalAsset.getCapitalAssetNumber())) && (KFSConstants.CapitalAssets.DISTRIBUTE_COST_EQUALLY_CODE.equalsIgnoreCase(capitalAsset.getDistributionAmountCode()))) { if (capitalAssetExists(selectedCapitalAccountingLines, capitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR)) { capitalAsset.setCapitalAssetQuantity(1); redistributeEqualAmounts(selectedCapitalAccountingLines, capitalAsset, equalModifyAssetAmount, totalQuantity); lastAssetIndex++; //get a reference to the last capital create asset to fix any variances... lastCapitalAsset = capitalAsset; } } } } //apply any variance left to the last KualiDecimal varianceForAssets = remainingAmountToDistribute.subtract(equalModifyAssetAmount.multiply(new KualiDecimal(lastAssetIndex))); if (varianceForAssets.isNonZero()) { lastCapitalAsset.setCapitalAssetLineAmount(lastCapitalAsset.getCapitalAssetLineAmount().add(varianceForAssets)); redistributeEqualAmountsOnLastCapitalAsset(selectedCapitalAccountingLines, lastCapitalAsset, capitalAssetInformation, KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR); } } } /** * for modified assets the amount is distributed * @param selectedCapitalAccountingLines * @param capitalAssetInformation */ protected void redistributeAmountsForAccountingsLineForModifyAssetsByAmounts(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation, KualiDecimal remainingAmountToDistribute) { KualiDecimal appliedAccountingLinesTotal = KualiDecimal.ZERO; CapitalAssetAccountsGroupDetails lastAccountingLine = new CapitalAssetAccountsGroupDetails(); for (CapitalAccountingLines capitalAccountLine : selectedCapitalAccountingLines) { for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.DISTRIBUTE_COST_BY_INDIVIDUAL_ASSET_AMOUNT_CODE.equalsIgnoreCase(capitalAsset.getDistributionAmountCode())) { if (capitalAsset.getCapitalAssetLineAmount().compareTo(getAccountingLinesTotalAmount(capitalAsset)) != 0) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountLine.getFinancialObjectCode())) { //found the accounting line groupAccountLine.setAmount((capitalAsset.getCapitalAssetLineAmount().multiply(capitalAccountLine.getAccountLinePercent())).divide(new KualiDecimal(100))); } } } } } } } /** * redistributes the amounts to the capital asset and its related group accounting lines. * Adjusts any variance to the last capital asset accounting line. * * @param selectedCapitalAccountingLines * @param capitalAsset * @param amount * @param totalQuantity */ protected void redistributeEqualAmounts(List<CapitalAccountingLines> selectedCapitalAccountingLines, CapitalAssetInformation capitalAsset, KualiDecimal amount, int totalQuantity) { int assetQuantity = 0; KualiDecimal totalCapitalAssetQuantity = new KualiDecimal(totalQuantity); if (ObjectUtils.isNotNull(capitalAsset.getCapitalAssetQuantity())) { assetQuantity = capitalAsset.getCapitalAssetQuantity(); } capitalAsset.setCapitalAssetLineAmount(capitalAsset.getCapitalAssetLineAmount().add(amount.multiply(new KualiDecimal(assetQuantity)))); int lastAccountIndex = 0; KualiDecimal appliedAccountingLinesTotal = KualiDecimal.ZERO; CapitalAssetAccountsGroupDetails lastLine = new CapitalAssetAccountsGroupDetails(); List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { KualiDecimal capitalAccountingLineAmount = getCapitalAssetAccountLineAmount(selectedCapitalAccountingLines, groupAccountLine, capitalAsset); KualiDecimal calculatedLineAmount = capitalAccountingLineAmount.divide(totalCapitalAssetQuantity, true); groupAccountLine.setAmount(calculatedLineAmount.multiply(new KualiDecimal(assetQuantity))); appliedAccountingLinesTotal = appliedAccountingLinesTotal.add(groupAccountLine.getAmount()); lastAccountIndex++; lastLine = groupAccountLine; } //apply any variance left to the last KualiDecimal varianceForLines = capitalAsset.getCapitalAssetLineAmount().subtract(appliedAccountingLinesTotal); if (varianceForLines.isNonZero()) { lastLine.setAmount(lastLine.getAmount().add(varianceForLines)); } } /** * redistributes the amounts to the capital asset and its related group accounting lines. * Adjusts any variance to the last capital asset accounting line. * * @param selectedCapitalAccountingLines * @param capitalAsset * @param capitalAssetInformation * @param actionTypeCode */ protected void redistributeEqualAmountsOnLastCapitalAsset(List<CapitalAccountingLines> selectedCapitalAccountingLines, CapitalAssetInformation lastCapitalAsset, List<CapitalAssetInformation> capitalAssetInformation, String actionTypeCode) { for (CapitalAccountingLines capitalAccountingLine : selectedCapitalAccountingLines ) { KualiDecimal lineAmount = capitalAccountingLine.getAmount(); KualiDecimal distributedAmount = getAccountingLinesDistributedAmount(capitalAccountingLine, capitalAssetInformation, actionTypeCode); KualiDecimal difference = lineAmount.subtract(distributedAmount); if (!difference.isZero()) { adjustAccountingLineAmountOnLastCapitalAsset(capitalAccountingLine, lastCapitalAsset, difference); } } } /** * Gets the amount on the capital assets line for the selected capital accounting line by * finding the group accounting line. When group accounting line is found in the selected * capital accounting lines, the amount from that capital accounting line is returned. * @param selectedCapitalAccountingLines * @param groupAccountLine * @return lineAmount */ protected KualiDecimal getCapitalAssetAccountLineAmount(List<CapitalAccountingLines> selectedCapitalAccountingLines, CapitalAssetAccountsGroupDetails groupAccountLine, CapitalAssetInformation capitalAsset) { KualiDecimal lineAmount = KualiDecimal.ZERO; for (CapitalAccountingLines capitalAccountingLine : selectedCapitalAccountingLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { return capitalAccountingLine.getAmount(); } } return lineAmount; } /** * * @param capitalAccountingLines * @param capitalAssetInformation */ protected void redistributeIndividualAmountsForAccountingLinesForModifyAssets(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation) { for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator())) { if (capitalAssetExists(selectedCapitalAccountingLines, capitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR)) { redistributeIndividualAmounts(selectedCapitalAccountingLines, capitalAsset); } } } } /** * checks the capital accounting line's amount to the sum of the distributed * accounting lines amounts and adjusts if there are any variances.. * * @param selectedCapitalAccountingLines * @param capitalAssetInformation */ protected void adjustCapitalAssetsAccountingLinesAmounts(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation) { for (CapitalAccountingLines capitalAcctLine : selectedCapitalAccountingLines) { adjustAccountingLinesAmounts(capitalAcctLine, capitalAssetInformation); } } /** * for each capital account line, compares its amounts to the accounting lines * on capital assets and adjusts its accounting lines amounts for any variances. * * @param capitalAcctLine * @param capitalAssetInformation */ protected void adjustAccountingLinesAmounts(CapitalAccountingLines capitalAcctLine, List<CapitalAssetInformation> capitalAssetInformation) { CapitalAssetAccountsGroupDetails lastAcctLine = null; KualiDecimal totalAccountsAmount = KualiDecimal.ZERO; for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (capitalAsset.getCapitalAssetLineAmount().compareTo(getAccountingLinesTotalAmount(capitalAsset)) != 0) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAcctLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAcctLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAcctLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAcctLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAcctLine.getFinancialObjectCode())) { totalAccountsAmount = totalAccountsAmount.add(groupAccountLine.getAmount()); lastAcctLine = groupAccountLine; } } } } KualiDecimal variance = capitalAcctLine.getAmount().subtract(totalAccountsAmount); if (variance.isNonZero() && ObjectUtils.isNotNull(lastAcctLine)) { lastAcctLine.setAmount(lastAcctLine.getAmount().add(variance)); } } /** * adjusts variances on capital assets where distribution method is set * as "distribute evenly" and capital asset amount is odd value. Reduce the * capital asset amount line by 0.01 and then adjust the account amounts. Finally * any variance between capital accounting lines and capital assets is added * to the last capital asset and its accounting lines. * * @param capitalAssetInformation */ protected void adjustVarianceOnCapitalAssets(List<CapitalAssetInformation> capitalAssetInformation) { KualiDecimal adjustedCapitalAssetBalance = KualiDecimal.ZERO; CapitalAssetInformation lastCapitalAsset = null; for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { //look at only cost equall assets... if (KFSConstants.CapitalAssets.DISTRIBUTE_COST_EQUALLY_CODE.equalsIgnoreCase(capitalAsset.getDistributionAmountCode())) { if (capitalAsset.getCapitalAssetLineAmount().mod(new KualiDecimal(2)) != KualiDecimal.ZERO) { capitalAsset.setCapitalAssetLineAmount(capitalAsset.getCapitalAssetLineAmount().subtract(new KualiDecimal(0.01))); adjustedCapitalAssetBalance = adjustedCapitalAssetBalance.add(new KualiDecimal(0.01)); lastCapitalAsset = capitalAsset; } } } if (ObjectUtils.isNotNull(lastCapitalAsset) && adjustedCapitalAssetBalance.isNonZero()) { lastCapitalAsset.setCapitalAssetLineAmount(lastCapitalAsset.getCapitalAssetLineAmount().add(adjustedCapitalAssetBalance)); } } /** * * @param capitalAccountingLines * @param capitalAssetInformation */ protected void redistributeIndividualAmountsForAccountingLinesForCreateAssets(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation) { for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator())) { if (capitalAssetExists(selectedCapitalAccountingLines, capitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR)) { redistributeIndividualAmounts(selectedCapitalAccountingLines, capitalAsset); } } } } /** * * @param selectedCapitalAccountingLines * @param capitalAsset */ protected void redistributeIndividualAmounts(List<CapitalAccountingLines> selectedCapitalAccountingLines, CapitalAssetInformation capitalAsset) { KualiDecimal capitalAssetAmount = capitalAsset.getCapitalAssetLineAmount(); KualiDecimal totalCapitalAccountsAmount = getTotalCapitalAccountsAmounts(selectedCapitalAccountingLines); CapitalAssetAccountsGroupDetails lastAccountLine = new CapitalAssetAccountsGroupDetails(); int lastAccountLineIndex = 0; KualiDecimal distributedAmount = KualiDecimal.ZERO; List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { BigDecimal linePercent = getCapitalAccountingLinePercent(selectedCapitalAccountingLines, groupAccountLine, totalCapitalAccountsAmount); groupAccountLine.setAmount(new KualiDecimal(capitalAssetAmount.bigDecimalValue().multiply(linePercent))); lastAccountLine = groupAccountLine; distributedAmount = distributedAmount.add(groupAccountLine.getAmount()); lastAccountLineIndex++; } lastAccountLine.setAmount(lastAccountLine.getAmount().add(capitalAssetAmount.subtract(distributedAmount))); } /** * * @param selectedCapitalAccountingLines * @param groupAccountLine * @param totalCapitalAccountsAmount * @return percent */ protected BigDecimal getCapitalAccountingLinePercent(List<CapitalAccountingLines> selectedCapitalAccountingLines, CapitalAssetAccountsGroupDetails groupAccountLine, KualiDecimal totalCapitalAccountsAmount) { for (CapitalAccountingLines capitalAccountingLine : selectedCapitalAccountingLines) { if (groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { return (capitalAccountingLine.getAmount().bigDecimalValue().divide(totalCapitalAccountsAmount.bigDecimalValue(), KFSConstants.CapitalAssets.CAPITAL_ACCOUNT_LINE_PERCENT_SCALE, KFSConstants.CapitalAssets.PERCENT_SCALE)); } } return BigDecimal.ZERO; } /** * * @param capitalAccountingLines * @param capitalAssetInformation * @param remainingAmountToDistribute */ protected void redistributeEqualAmountsForAccountingLineForCreateAssets(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation, KualiDecimal remainingAmountToDistribute) { //get the total capital assets quantity int totalQuantity = getTotalQuantityOfCreateAssets(selectedCapitalAccountingLines, capitalAssetInformation); if (totalQuantity > 0) { KualiDecimal equalCreateAssetAmount = remainingAmountToDistribute.divide(new KualiDecimal(totalQuantity), true); int lastAssetIndex = 0; CapitalAssetInformation lastCapitalAsset = new CapitalAssetInformation(); if (equalCreateAssetAmount.compareTo(KualiDecimal.ZERO) != 0) { for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator()) && (KFSConstants.CapitalAssets.DISTRIBUTE_COST_EQUALLY_CODE.equalsIgnoreCase(capitalAsset.getDistributionAmountCode()))) { if (capitalAssetExists(selectedCapitalAccountingLines, capitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR)) { redistributeEqualAmounts(selectedCapitalAccountingLines, capitalAsset, equalCreateAssetAmount, totalQuantity); if (ObjectUtils.isNotNull(capitalAsset.getCapitalAssetQuantity())) { lastAssetIndex = lastAssetIndex + capitalAsset.getCapitalAssetQuantity(); } //get a reference to the last capital create asset to fix any variances... lastCapitalAsset = capitalAsset; } } } } //apply any variance left to the last KualiDecimal varianceForAssets = remainingAmountToDistribute.subtract(equalCreateAssetAmount.multiply(new KualiDecimal(lastAssetIndex))); if (varianceForAssets.isNonZero()) { lastCapitalAsset.setCapitalAssetLineAmount(lastCapitalAsset.getCapitalAssetLineAmount().add(varianceForAssets)); redistributeEqualAmountsOnLastCapitalAsset(selectedCapitalAccountingLines, lastCapitalAsset, capitalAssetInformation, KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR); } } } /** * * @param selectedCapitalAccountingLines * @param capitalAssetInformation * @return createAssetsCount count of create assets */ protected int getTotalQuantityOfCreateAssets(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation) { int totalQuantity = 0; for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator())) { if (capitalAssetExists(selectedCapitalAccountingLines, capitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR)) { if (ObjectUtils.isNotNull(capitalAsset.getCapitalAssetQuantity())) { totalQuantity += capitalAsset.getCapitalAssetQuantity(); } } } } return totalQuantity; } /** * * @param selectedCapitalAccountingLines * @param capitalAssetInformation * @return createAssetsCount count of create assets */ protected int numberOfCreateAssetsExist(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation) { int createAssetsCount = 0; for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator())) { if (capitalAssetExists(selectedCapitalAccountingLines, capitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR)) { createAssetsCount++; } } } if (createAssetsCount == 0) { return 1; } return createAssetsCount; } /** * * @param selectedCapitalAccountingLines * @param capitalAssetInformation * @return modifiedAssetsCount number of modified assets */ protected int getNumberOfModifiedAssetsExist(List<CapitalAccountingLines> selectedCapitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation) { int modifiedAssetsCount = 0; for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator()) && ObjectUtils.isNotNull(capitalAsset.getCapitalAssetNumber())) { if (capitalAssetExists(selectedCapitalAccountingLines, capitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR)) { modifiedAssetsCount++; } } } if (modifiedAssetsCount == 0) { return 1; } return modifiedAssetsCount; } /** * Clear the capital asset information that the user has entered * * @param mapping * @param form * @param request * @param response * @return action forward string * @throws Exception */ public ActionForward clearCapitalAssetInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("clearCapitalAssetInfo() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int clearIndex = getSelectedLine(request); this.resetCapitalAssetInfo(capitalAssetInformation.get(clearIndex)); //now process the remaining capital asset records processRemainingCapitalAssetInfo(form, capitalAssetInformation); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * clear up the modify capital asset information. The amount field is reset to 0 * Processes any remaining capital assets so that it recalculates the system control * and system control remaining amounts. * * @param mapping * @param form * @param request * @param response * @return action forward string * @throws Exception */ public ActionForward clearCapitalAssetModify(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("clearCapitalAssetModify() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int clearIndex = getSelectedLine(request); capitalAssetInformation.get(clearIndex).setCapitalAssetLineAmount(KualiDecimal.ZERO); //zero out the amount distribute on the accounting lines... for (CapitalAssetAccountsGroupDetails groupAccountLine : capitalAssetInformation.get(clearIndex).getCapitalAssetAccountsGroupDetails()) { groupAccountLine.setAmount(KualiDecimal.ZERO); } //now process the remaining capital asset records processRemainingCapitalAssetInfo(form, capitalAssetInformation); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * inserts capital asset information into capital assets list. * Also recalculates the system control and system control remaining amounts. * Puts a global error message if the user does not enter capital asset quantity. * If the quantity is > 1, it will insert that many tag/location detail records for this * capital asset item. * * @param mapping * @param form * @param request * @param response * @return action forward string * @throws Exception */ public ActionForward insertCapitalAssetInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("insertCapitalAssetInfo() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int addIndex = getSelectedLine(request); if (capitalAssetInformation.get(addIndex).getCapitalAssetQuantity() == null || capitalAssetInformation.get(addIndex).getCapitalAssetQuantity() <= 0) { GlobalVariables.getMessageMap().putError(KFSConstants.EDIT_CAPITAL_ASSET_INFORMATION_ERRORS, KFSKeyConstants.ERROR_DOCUMENT_CAPITAL_ASSET_QUANTITY_REQUIRED); } else { this.addCapitalAssetInfoDetailLines(capitalAssetInformation.get(addIndex)); } /* DistributeCapitalAssetAmountToGroupAccountingLines(kualiAccountingDocumentFormBase); CapitalAccountingLinesFormBase capitalAccountingLinesFormBase = (CapitalAccountingLinesFormBase) kualiAccountingDocumentFormBase; checkSelectForCapitalAccountingLines(capitalAccountingLinesFormBase); checkCapitalAccountingLinesSelected(capitalAccountingLinesFormBase); calculatePercentsForSelectedCapitalAccountingLines(capitalAccountingLinesFormBase); CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) capitalAccountingLinesFormBase.getFinancialDocument(); String distributionAmountCode = capitalAccountingLinesFormBase.getCapitalAccountingLine().getDistributionCode(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { capitalAccountingLine.setDistributionAmountCode(KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR); selectedCapitalAccountingLines.add(capitalAccountingLine); } } //redistribute the capital asset modify amount to the group accounting lines //based on amount. redistributeToGroupAccountingLinesFromAssetsByAmounts(selectedCapitalAccountingLines, capitalAssetInformation.get(addIndex)); */ //now process the remaining capital asset records processRemainingCapitalAssetInfo(form, capitalAssetInformation); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * inserts capital asset information into capital assets list. * Also recalculates the system control and system control remaining amounts. * Puts a global error message if the user does not enter capital asset quantity. * If the quantity is > 1, it will insert that many tag/location detail records for this * capital asset item. * * @param mapping * @param form * @param request * @param response * @return action forward string * @throws Exception */ public ActionForward addCapitalAssetTagLocationInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("addCapitalAssetTagLocationInfo() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int addIndex = getSelectedLine(request); if (capitalAssetInformation.get(addIndex).getCapitalAssetQuantity() == null || capitalAssetInformation.get(addIndex).getCapitalAssetQuantity() <= 0) { GlobalVariables.getMessageMap().putError(KFSConstants.EDIT_CAPITAL_ASSET_INFORMATION_ERRORS, KFSKeyConstants.ERROR_DOCUMENT_CAPITAL_ASSET_QUANTITY_REQUIRED); } else { this.addCapitalAssetInfoDetailLines(capitalAssetInformation.get(addIndex)); } //now process the remaining capital asset records processRemainingCapitalAssetInfo(form, capitalAssetInformation); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * refreshes capital asset modify information to the modify capital assets list. * Also recalculates the system control and system control remaining amounts. * Puts a global error message if the user does not enter capital asset number. * * @param mapping * @param form * @param request * @param response * @return action forward string * @throws Exception */ public ActionForward refreshCapitalAssetModify(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("refreshCapitalAssetModify() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int refreshIndex = getSelectedLine(request); if (capitalAssetInformation.get(refreshIndex).getCapitalAssetNumber() == null) { GlobalVariables.getMessageMap().putError(KFSConstants.EDIT_CAPITAL_ASSET_MODIFY_ERRORS, KFSKeyConstants.ERROR_DOCUMENT_CAPITAL_ASSET_NUMBER_REQUIRED); } //now process the remaining capital asset records processRemainingCapitalAssetInfo(form, capitalAssetInformation); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * deletes the capital asset information */ public ActionForward deleteCapitalAssetInfo(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("deleteCapitalAssetInfoDetail() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int lineIndexForCapitalAssetInfo = this.getLineToDelete(request); if (capitalAssetInformation.get(lineIndexForCapitalAssetInfo).getCapitalAssetInformationDetails() != null && capitalAssetInformation.get(lineIndexForCapitalAssetInfo).getCapitalAssetInformationDetails().size() > 0) { capitalAssetInformation.get(lineIndexForCapitalAssetInfo).getCapitalAssetInformationDetails().clear(); } if (capitalAssetInformation.get(lineIndexForCapitalAssetInfo).getCapitalAssetAccountsGroupDetails() != null && capitalAssetInformation.get(lineIndexForCapitalAssetInfo).getCapitalAssetAccountsGroupDetails().size() > 0) { capitalAssetInformation.get(lineIndexForCapitalAssetInfo).getCapitalAssetAccountsGroupDetails().clear(); } capitalAssetInformation.remove(lineIndexForCapitalAssetInfo); //now process the remaining capital asset records processRemainingCapitalAssetInfo(form, capitalAssetInformation); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * deletes the capital asset information */ public ActionForward deleteCapitalAssetModify(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("deleteCapitalAssetModify() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int lineIndexForCapitalAssetInfo = this.getLineToDelete(request); capitalAssetInformation.remove(lineIndexForCapitalAssetInfo); //now process the remaining capital asset records processRemainingCapitalAssetInfo(form, capitalAssetInformation); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * process any remaining capital asset info in the list to check and calculate the * remaining distributed amount. Also checks to make sure if "select Lines" is to be * checked on/off * @param form * @param capitalAssetInformation */ protected void processRemainingCapitalAssetInfo(ActionForm form, List<CapitalAssetInformation> capitalAssetInformation) { CapitalAccountingLinesFormBase calfb = (CapitalAccountingLinesFormBase) form; //recalculate the amount remaining to be distributed and save the value on the form calculateRemainingDistributedAmount(calfb, capitalAssetInformation); //set the amountDistributed property to true if the total amount of all the capital assets //for a given capital accounting line is greater or equal to the line amount. checkCapitalAccountingLinesSelected(calfb); //redistribute each capital asset amount to its group accounting lines... KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; DistributeCapitalAssetAmountToGroupAccountingLines(kualiAccountingDocumentFormBase); setTabStatesForCapitalAssets(form); } /** * delete a detail line from the capital asset information */ public ActionForward deleteCapitalAssetInfoDetailLine(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("deleteCapitalAssetInfoDetailLine() - start"); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); if (capitalAssetInformation == null) { return mapping.findForward(KFSConstants.MAPPING_BASIC); } int lineIndexForCapitalAssetInfo = this.getLineToDelete(request); capitalAssetInformation.get(lineIndexForCapitalAssetInfo).getCapitalAssetInformationDetails().remove(0); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * get the capital asset information object currently associated with the document */ protected List<CapitalAssetInformation> getCurrentCapitalAssetInformationObject(KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase) { LOG.debug("getCurrentCapitalAssetInformationObject() - start"); CapitalAssetInformationDocumentBase capitalAssetInformationDocumentBase = (CapitalAssetInformationDocumentBase) kualiAccountingDocumentFormBase.getFinancialDocument(); if (!(capitalAssetInformationDocumentBase instanceof CapitalAssetEditable)) { return null; } List<CapitalAssetInformation> capitalAssetInformation = capitalAssetInformationDocumentBase.getCapitalAssetInformation(); return capitalAssetInformation; } /** * reset the nonkey fields of the given capital asset information * removes the corresponding capital asset information detail record from the list. * @param capitalAssetInformation the given capital asset information */ protected void resetCapitalAssetInfo(CapitalAssetInformation capitalAssetInformation) { if (capitalAssetInformation != null) { capitalAssetInformation.setCapitalAssetDescription(null); capitalAssetInformation.setCapitalAssetManufacturerModelNumber(null); capitalAssetInformation.setCapitalAssetManufacturerName(null); capitalAssetInformation.setCapitalAssetNumber(null); capitalAssetInformation.setCapitalAssetTypeCode(null); capitalAssetInformation.setCapitalAssetQuantity(null); capitalAssetInformation.setVendorDetailAssignedIdentifier(null); capitalAssetInformation.setVendorHeaderGeneratedIdentifier(null); // Set the BO to null cause it won't be updated automatically when vendorDetailAssetIdentifier and // VendorHeanderGeneratedIndentifier set to null. capitalAssetInformation.setVendorDetail(null); capitalAssetInformation.setVendorName(null); capitalAssetInformation.setCapitalAssetLineAmount(KualiDecimal.ZERO); capitalAssetInformation.getCapitalAssetInformationDetails().clear(); //zero out the amount distribute on the accounting lines... for (CapitalAssetAccountsGroupDetails groupAccountLine : capitalAssetInformation.getCapitalAssetAccountsGroupDetails()) { groupAccountLine.setAmount(KualiDecimal.ZERO); } } } /** * Overridden to guarantee that form of copied document is set to whatever the entry mode of the document is * @see org.kuali.rice.kns.web.struts.action.KualiTransactionalDocumentActionBase#copy(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) */ @Override public ActionForward copy(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { CapitalAccountingLinesFormBase capitalAccountingLinesFormBase = (CapitalAccountingLinesFormBase) form;; CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) capitalAccountingLinesFormBase.getFinancialDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); List<CapitalAccountingLines> copiedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { copiedCapitalAccountingLines.add(capitalAccountingLine); } capitalAccountingLines.clear(); ActionForward forward = super.copy(mapping, form, request, response); caldb.setCapitalAccountingLines(copiedCapitalAccountingLines); // if the copied document has capital asset collection, remove the collection KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; AccountingDocument document = kualiAccountingDocumentFormBase.getFinancialDocument(); if (document instanceof CapitalAssetEditable) { CapitalAssetEditable capitalAssetEditable = (CapitalAssetEditable) document; List<CapitalAssetInformation> capitalAssets = capitalAssetEditable.getCapitalAssetInformation(); for (CapitalAssetInformation capitalAsset : capitalAssets) { Long capitalAssetNumber = capitalAsset.getCapitalAssetNumber(); resetCapitalAssetInfo(capitalAsset); //set capital asset number to copied asset line if "modify" asset //because resetCapitalAssetInfo cleared the value. if (KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equalsIgnoreCase(capitalAsset.getCapitalAssetActionIndicator())) { capitalAsset.setCapitalAssetNumber(capitalAssetNumber); } capitalAsset.setCapitalAssetProcessedIndicator(false); } } //setup the initial next sequence number column.. KualiDocumentFormBase kualiDocumentFormBase = (KualiDocumentFormBase) form; setupIntialNextCapitalAssetLineNumber(kualiDocumentFormBase); checkCapitalAccountingLinesSelected(capitalAccountingLinesFormBase); return forward; } /** * setups the next capital asset line number * * @param kualiDocumentFormBase */ protected void setupIntialNextCapitalAssetLineNumber(KualiDocumentFormBase kualiDocumentFormBase) { KualiAccountingDocumentFormBase kadfb = (KualiAccountingDocumentFormBase) kualiDocumentFormBase; CapitalAssetInformationDocumentBase caidb = (CapitalAssetInformationDocumentBase) kadfb.getFinancialDocument(); List<CapitalAssetInformation> currentCapitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kadfb); for (CapitalAssetInformation capitalAsset : currentCapitalAssetInformation) { if (capitalAsset.getCapitalAssetLineNumber() > caidb.getNextCapitalAssetLineNumber()) { caidb.setNextCapitalAssetLineNumber(capitalAsset.getCapitalAssetLineNumber()); } } caidb.setNextCapitalAssetLineNumber(caidb.getNextCapitalAssetLineNumber()+1); } /** * calculates the percents for the selected capital accounting lines only * * @param calfb */ protected void calculatePercentsForSelectedCapitalAccountingLines(CapitalAccountingLinesFormBase calfb) { CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); KualiDecimal totalCapitalLinesSelectedAmount = (calculateTotalCapitalLinesSelectedAmount(capitalAccountingLines)).abs(); if (totalCapitalLinesSelectedAmount.isNonZero()) { for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { capitalAccountingLine.setAccountLinePercent(capitalAccountingLine.getAmount().abs().divide(totalCapitalLinesSelectedAmount).multiply(new KualiDecimal(100), true)); } } } } /** * * @param capitalAccountingLines * @return */ protected KualiDecimal calculateTotalCapitalLinesSelectedAmount(List<CapitalAccountingLines> capitalAccountingLines) { KualiDecimal totalLineAmount = KualiDecimal.ZERO; for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { totalLineAmount = totalLineAmount.add(capitalAccountingLine.getAmount()); } } return totalLineAmount; } /** * Populates capital asset information collection with capital accounting lines. * Based on actionType, capitalassetactionindicator attribute is filled with 'C' for create * and 'M' for modify assets, which will be used to differentiate to pull the records in * create asset screen or modify asset screen. * * @param calfb * @param actionType * @param distributionAmountCode */ protected void createCapitalAssetForGroupAccountingLines(CapitalAccountingLinesFormBase calfb, String actionType, String distributionAmountCode) { CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); List<CapitalAssetInformation> capitalAssetInformation = new ArrayList<CapitalAssetInformation>(); KualiAccountingDocumentFormBase kadfb = calfb; List<CapitalAssetInformation> currentCapitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kadfb); String documentNumber = calfb.getDocument().getDocumentNumber(); calfb.setSystemControlAmount(KualiDecimal.ZERO); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { capitalAccountingLine.setDistributionAmountCode(distributionAmountCode); selectedCapitalAccountingLines.add(capitalAccountingLine); } } CapitalAssetInformation existingCapitalAsset = capitalAssetCreated(selectedCapitalAccountingLines, currentCapitalAssetInformation); if (ObjectUtils.isNotNull(existingCapitalAsset)) { if (!accountingLinesAmountDistributed(selectedCapitalAccountingLines, existingCapitalAsset)) { //accounting line amount not completely distributed yet so we need to create more assets //add the capital information record to the list of asset information createNewCapitalAsset(selectedCapitalAccountingLines, currentCapitalAssetInformation, documentNumber, actionType, getNextCapitalAssetLineNumber(kadfb)); } } else { //add the capital information record to the list of asset information createNewCapitalAsset(selectedCapitalAccountingLines, currentCapitalAssetInformation, documentNumber, actionType, getNextCapitalAssetLineNumber(kadfb)); } } /** * helper method to add accounting details for this new capital asset record * * @param capitalAccountingLines * @param currentCapitalAssetInformation * @param documentNumber * @param actionType * @param nextCapitalAssetLineNumnber */ protected void createNewCapitalAsset(List<CapitalAccountingLines> capitalAccountingLines, List<CapitalAssetInformation> currentCapitalAssetInformation, String documentNumber, String actionType, Integer nextCapitalAssetLineNumber) { CapitalAssetInformation capitalAsset = new CapitalAssetInformation(); capitalAsset.setCapitalAssetLineAmount(KualiDecimal.ZERO); capitalAsset.setDocumentNumber(documentNumber); capitalAsset.setCapitalAssetLineNumber(nextCapitalAssetLineNumber); capitalAsset.setCapitalAssetActionIndicator(actionType); capitalAsset.setCapitalAssetProcessedIndicator(false); //now setup the account line information associated with this capital asset for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { capitalAsset.setDistributionAmountCode(capitalAccountingLine.getDistributionAmountCode()); createCapitalAssetAccountingLinesDetails(capitalAccountingLine, capitalAsset); } currentCapitalAssetInformation.add(capitalAsset); } /** * helper method to add accounting details for this new modify capital asset record * * @param capitalAccountingLines * @param currentCapitalAssetInformation * @param documentNumber * @param actionType * @param nextCapitalAssetLineNumnber * @param capitalAssetNumber */ protected void createNewModifyCapitalAsset(List<CapitalAccountingLines> capitalAccountingLines, List<CapitalAssetInformation> currentCapitalAssetInformation, String documentNumber, String actionType, Integer nextCapitalAssetLineNumber, long capitalAssetNumber) { CapitalAssetInformation capitalAsset = new CapitalAssetInformation(); capitalAsset.setCapitalAssetNumber(capitalAssetNumber); capitalAsset.setCapitalAssetLineAmount(KualiDecimal.ZERO); capitalAsset.setDocumentNumber(documentNumber); capitalAsset.setCapitalAssetLineNumber(nextCapitalAssetLineNumber); capitalAsset.setCapitalAssetActionIndicator(actionType); capitalAsset.setCapitalAssetProcessedIndicator(false); //now setup the account line information associated with this capital asset for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { capitalAsset.setDistributionAmountCode(capitalAccountingLine.getDistributionAmountCode()); createCapitalAssetAccountingLinesDetails(capitalAccountingLine, capitalAsset); } currentCapitalAssetInformation.add(capitalAsset); } /** * * * @param capitalAccountingLine * @param capitalAsset */ protected void createCapitalAssetAccountingLinesDetails(CapitalAccountingLines capitalAccountingLine, CapitalAssetInformation capitalAsset) { //now setup the account line information associated with this capital asset CapitalAssetAccountsGroupDetails capitalAssetAccountLine = new CapitalAssetAccountsGroupDetails(); capitalAssetAccountLine.setDocumentNumber(capitalAsset.getDocumentNumber()); capitalAssetAccountLine.setChartOfAccountsCode(capitalAccountingLine.getChartOfAccountsCode()); capitalAssetAccountLine.setAccountNumber(capitalAccountingLine.getAccountNumber()); capitalAssetAccountLine.setSubAccountNumber(capitalAccountingLine.getSubAccountNumber()); capitalAssetAccountLine.setFinancialDocumentLineTypeCode(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE); capitalAssetAccountLine.setCapitalAssetAccountLineNumber(getNextAccountingLineNumber(capitalAccountingLine, capitalAsset)); capitalAssetAccountLine.setCapitalAssetLineNumber(capitalAsset.getCapitalAssetLineNumber()); capitalAssetAccountLine.setFinancialObjectCode(capitalAccountingLine.getFinancialObjectCode()); capitalAssetAccountLine.setFinancialSubObjectCode(capitalAccountingLine.getFinancialSubObjectCode()); capitalAssetAccountLine.setProjectCode(capitalAccountingLine.getProjectCode()); capitalAssetAccountLine.setOrganizationReferenceId(capitalAccountingLine.getOrganizationReferenceId()); capitalAssetAccountLine.setSequenceNumber(capitalAccountingLine.getSequenceNumber()); capitalAssetAccountLine.setAmount(KualiDecimal.ZERO); capitalAsset.getCapitalAssetAccountsGroupDetails().add(capitalAssetAccountLine); } /** * calculates the next accounting line number for accounts details for each capital asset. * Goes through the current records and gets the last accounting line number. * * @param capitalAsset * @return nextAccountingLineNumber */ protected Integer getNextAccountingLineNumber(CapitalAccountingLines capitalAccountingLine, CapitalAssetInformation capitalAsset) { Integer nextAccountingLineNumber = 0; List<CapitalAssetAccountsGroupDetails> capitalAssetAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails capitalAssetAccountLine : capitalAssetAccountLines) { nextAccountingLineNumber = capitalAssetAccountLine.getCapitalAssetAccountLineNumber(); } return ++nextAccountingLineNumber; } /** * * Finds a Capital Asset Information that matches the given capitalAccountingLine. * * @param capitalAccountingLine * @param capitalAssetInformation * @return return existingCapitalAsset */ protected CapitalAssetInformation getCapitalAssetCreated(CapitalAccountingLines capitalAccountingLine, List<CapitalAssetInformation> capitalAssetInformation) { CapitalAssetInformation existingCapitalAsset = null; if (ObjectUtils.isNull(capitalAssetInformation) ||capitalAssetInformation.size() <= 0) { return existingCapitalAsset; } for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { return capitalAsset; } } } return existingCapitalAsset; } /** * * @param capitalAccountingLine * @param capitalAssetInformation * @return capitalAsset */ protected CapitalAssetInformation capitalAssetCreated(List<CapitalAccountingLines> capitalAccountingLines, List<CapitalAssetInformation> capitalAssetInformation) { CapitalAssetInformation existingCapitalAsset = null; if (ObjectUtils.isNull(capitalAssetInformation) && capitalAssetInformation.size() <= 0) { return existingCapitalAsset; } for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { existingCapitalAsset = getCapitalAssetCreated(capitalAccountingLine, capitalAssetInformation); if (ObjectUtils.isNotNull(existingCapitalAsset)) { return existingCapitalAsset; } } return existingCapitalAsset; } /** * * @param capitalAccountingLine * @param capitalAssetInformation * @return modify capital asset */ protected CapitalAssetInformation modifyCapitalAssetCreated(CapitalAccountingLines capitalAccountingLine, List<CapitalAssetInformation> capitalAssetInformation) { CapitalAssetInformation existingCapitalAsset = null; if (ObjectUtils.isNull(capitalAssetInformation) && capitalAssetInformation.size() <= 0) { return existingCapitalAsset; } for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator()) && ObjectUtils.isNull(capitalAsset.getCapitalAssetNumber())) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { return capitalAsset; } } } } return existingCapitalAsset; } /** * * @param capitalAssetInformation * @param existingCapitalAssetInformation * @return */ protected Integer getNextCapitalAssetLineNumber(KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase) { int nextCapitalAssetLineNumber = 1; CapitalAssetInformationDocumentBase caidb = (CapitalAssetInformationDocumentBase) kualiAccountingDocumentFormBase.getFinancialDocument(); nextCapitalAssetLineNumber = caidb.getNextCapitalAssetLineNumber(); caidb.setNextCapitalAssetLineNumber(nextCapitalAssetLineNumber+1); return nextCapitalAssetLineNumber; } /** * * @param kadfb * @param existingCapitalAsset * @return true if accounting line amount equals to capital asset amount, else false. */ protected boolean accountingLinesAmountDistributed(List<CapitalAccountingLines> capitalAccountingLines, CapitalAssetInformation existingCapitalAsset) { KualiDecimal accountingLineAmount = KualiDecimal.ZERO; for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { accountingLineAmount = accountingLineAmount.add(capitalAccountingLine.getAmount().abs()); } KualiDecimal capitalAssetsAmount = existingCapitalAsset.getCapitalAssetLineAmount(); return accountingLineAmount.equals(capitalAssetsAmount); } /** * * Checks to see if all the capital assets' distributed amount is the same as * the capital accounting lines (there is only one lines, of course). * @param kadfb * @param capitalAssetsInformation * @return true if accounting line amount equals to capital asset amount, else false. */ protected boolean capitalAccountingLineAmountDistributed(CapitalAccountingLines capitalAccountingLine, List<CapitalAssetInformation> capitalAssetsInformation) { KualiDecimal amountDistributed = KualiDecimal.ZERO; for (CapitalAssetInformation capitalAsset : capitalAssetsInformation) { amountDistributed = amountDistributed.add(getAccountingLineAmount(capitalAsset, capitalAccountingLine)); } KualiDecimal capitalAccountingLineAmount = capitalAccountingLine.getAmount(); return amountDistributed.equals(capitalAccountingLineAmount); } /** * * Returns the amount of the group accounting line from the capital asset information that * matches the capital accounting lines (only one lines, of course). If none exists, zero is returned. * * @param capitalAsset * @param capitalAccountingLine * @return accountLineAmount */ protected KualiDecimal getAccountingLineAmount(CapitalAssetInformation capitalAsset, CapitalAccountingLines capitalAccountingLine) { KualiDecimal accountLineAmount = KualiDecimal.ZERO; List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { return groupAccountLine.getAmount(); } } return accountLineAmount; } /** * adds any missing capital accounting line details as an accounting line into the collection of * accounting lines for this capital asset based on the action type. * * @param capitalAccountingLines * @param existingCapitalAsset */ protected void addMissingAccountingLinesToCapitalAsset(List<CapitalAccountingLines> capitalAccountingLines, CapitalAssetInformation existingCapitalAsset) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = existingCapitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLineMissing(capitalAccountingLine, groupAccountLines, existingCapitalAsset.getCapitalAssetLineNumber())) { createCapitalAssetAccountingLinesDetails(capitalAccountingLine, existingCapitalAsset); } } } /** * creates a new tag/location details record and adds to the collection for capital asset * @param capitalAsset */ protected void createCapitalAssetInformationDetail(CapitalAssetInformation capitalAsset) { CapitalAssetInformationDetail assetDetail = new CapitalAssetInformationDetail(); assetDetail.setDocumentNumber(capitalAsset.getDocumentNumber()); assetDetail.setCapitalAssetLineNumber(capitalAsset.getCapitalAssetLineNumber()); assetDetail.setItemLineNumber(getNextLineItemNumber(capitalAsset)); capitalAsset.getCapitalAssetInformationDetails().add(0,assetDetail); } /** * calculates the next line item number for tag/location details for each capital asset. * Goes through the current records and gets the last number. * * @param capitalAsset * @return nextLineNumber */ protected Integer getNextLineItemNumber(CapitalAssetInformation capitalAsset) { Integer nextLineNumber = 0; List<CapitalAssetInformationDetail> capitalAssetDetails = capitalAsset.getCapitalAssetInformationDetails(); for (CapitalAssetInformationDetail capitalAssetDetail : capitalAssetDetails) { nextLineNumber = capitalAssetDetail.getItemLineNumber(); } return ++nextLineNumber; } protected void calculateRemainingDistributedAmount(CapitalAccountingLinesFormBase calfb, List<CapitalAssetInformation> capitalAssetInformation) { calfb.setCreatedAssetsControlAmount(calfb.getSystemControlAmount()); //get amount allocated so far....or the system control remainder amount field. for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { calfb.setCreatedAssetsControlAmount(calfb.getCreatedAssetsControlAmount().subtract(capitalAsset.getCapitalAssetLineAmount())); } } /** * checks the current list of accounting lines created for the capital asset against the given * capital accounting line and returns true or false * * @param capitalAccountingLine * @param groupAccountLines * @param capitalAssetLineNumber * @return true if line exists else return false */ protected boolean capitalAccountingLineMissing(CapitalAccountingLines capitalAccountingLine, List<CapitalAssetAccountsGroupDetails> groupAccountLines, Integer capitalAssetLineNumber) { boolean missing = true; for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(capitalAssetLineNumber) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { return false; } } return missing; } /** * sets the capital accounting lines select and amount distributed values to true if * there are capital asset records for a given capital accounting line. The system control * amount and system control remaining amounts are calculated here. * * @param calfb */ protected void checkCapitalAccountingLinesSelected(CapitalAccountingLinesFormBase calfb) { CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); KualiAccountingDocumentFormBase kadfb = calfb; List<CapitalAssetInformation> currentCapitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kadfb); SpringContext.getBean(CapitalAssetBuilderModuleService.class).filterNonCapitalAssets(currentCapitalAssetInformation); calfb.setCreatedAssetsControlAmount(KualiDecimal.ZERO); calfb.setSystemControlAmount(KualiDecimal.ZERO); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine()) { calfb.setSystemControlAmount(calfb.getSystemControlAmount().add(capitalAccountingLine.getAmount())); } if (currentCapitalAssetInformation.size() <= 0) { capitalAccountingLine.setAccountLinePercent(null); capitalAccountingLine.setAmountDistributed(false); capitalAccountingLine.setSelectLine(false); } else { CapitalAssetInformation existingCapitalAsset = getCapitalAssetCreated(capitalAccountingLine, currentCapitalAssetInformation); if (ObjectUtils.isNotNull(existingCapitalAsset)) { // There is a CapitalAssetInformation matching the current accounting line. capitalAccountingLine.setSelectLine(true); } else { capitalAccountingLine.setAccountLinePercent(null); capitalAccountingLine.setSelectLine(false); } } if (capitalAccountingLineAmountDistributed(capitalAccountingLine, currentCapitalAssetInformation)) { // all the money from this accounting line is distributed among the assets capitalAccountingLine.setAmountDistributed(true); } else { capitalAccountingLine.setAmountDistributed(false); } } KualiDecimal capitalAssetsTotal = KualiDecimal.ZERO; //get amount allocated so far....or the system control remainder amount field. for (CapitalAssetInformation capitalAsset : currentCapitalAssetInformation) { capitalAssetsTotal= capitalAssetsTotal.add(capitalAsset.getCapitalAssetLineAmount()); } calfb.setCreatedAssetsControlAmount(calfb.getSystemControlAmount().subtract(capitalAssetsTotal)); } /** * sets the capital assets screens for create and modify and accounting lines * for capitalization screen as open. If accounting lines for capitalizataion list is * not empty then set "Accounting Lines for Capitalization" tab to open else set to close. * If capital asset with capital asset action indicator = 'C' then set "Create Capital Asset" * tab to open else set to close * If capital asset with capital asset action indicator = 'M' then set "Modify Capital Asset" * tab to open else set to close * * @param form */ protected void setTabStatesForCapitalAssets(ActionForm form) { KualiForm kualiForm = (KualiForm) form; CapitalAccountingLinesFormBase capitalAccountingLinesFormBase = (CapitalAccountingLinesFormBase) form; Map<String, String> tabStates = kualiForm.getTabStates(); Map<String, String> newTabStates = new HashMap<String, String>(); CapitalAssetInformationFormBase capitalAssetInformationFormBase = (CapitalAssetInformationFormBase) form; CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) capitalAssetInformationFormBase.getFinancialDocument(); //generated tab key for the three tabs String tabIdForAccountingLinesForCapitalization = WebUtils.generateTabKey(KFSConstants.CapitalAssets.ACCOUNTING_LINES_FOR_CAPITALIZATION_TAB_TITLE); String tabIdForCreateCapitalAsset = WebUtils.generateTabKey(KFSConstants.CapitalAssets.CREATE_CAPITAL_ASSETS_TAB_TITLE); String tabIdForModifyCapitalAsset = WebUtils.generateTabKey(KFSConstants.CapitalAssets.MODIFY_CAPITAL_ASSETS_TAB_TITLE); tabStates.remove(tabIdForAccountingLinesForCapitalization); tabStates.remove(tabIdForCreateCapitalAsset); tabStates.remove(tabIdForModifyCapitalAsset); //if there are any capital accounting lines for capitalization exists then if (caldb.getCapitalAccountingLines().size() > 0 || caldb.isCapitalAccountingLinesExist()) { tabStates.put(tabIdForAccountingLinesForCapitalization, KFSConstants.CapitalAssets.CAPITAL_ASSET_TAB_STATE_OPEN); } else { tabStates.put(tabIdForAccountingLinesForCapitalization, KFSConstants.CapitalAssets.CAPITAL_ASSET_TAB_STATE_CLOSE); } if (checkCreateAssetsExist(capitalAccountingLinesFormBase)) { tabStates.put(tabIdForCreateCapitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_TAB_STATE_OPEN); } else { tabStates.put(tabIdForCreateCapitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_TAB_STATE_CLOSE); } if (checkModifyAssetsExist(capitalAccountingLinesFormBase)) { tabStates.put(tabIdForModifyCapitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_TAB_STATE_OPEN); } else { tabStates.put(tabIdForModifyCapitalAsset, KFSConstants.CapitalAssets.CAPITAL_ASSET_TAB_STATE_CLOSE); } kualiForm.setTabStates(tabStates); } /** * * @param capitalAccountingLinesFormBase * @return true if a capital asset with capital asset action indicator = 'C' else false; */ protected boolean checkCreateAssetsExist(CapitalAccountingLinesFormBase capitalAccountingLinesFormBase) { boolean exists = false; CapitalAssetInformationDocumentBase capitalAssetInformationDocumentBase = (CapitalAssetInformationDocumentBase) capitalAccountingLinesFormBase.getFinancialDocument(); List<CapitalAssetInformation> capitalAssets = capitalAssetInformationDocumentBase.getCapitalAssetInformation(); for (CapitalAssetInformation capitalAsset : capitalAssets) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_CREATE_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator())) { return true; } } return exists; } /** * * @param capitalAccountingLinesFormBase * @return true if a capital asset with capital asset action indicator = 'C' else false; */ protected boolean checkModifyAssetsExist(CapitalAccountingLinesFormBase capitalAccountingLinesFormBase) { boolean exists = false; CapitalAssetInformationDocumentBase capitalAssetInformationDocumentBase = (CapitalAssetInformationDocumentBase) capitalAccountingLinesFormBase.getFinancialDocument(); List<CapitalAssetInformation> capitalAssets = capitalAssetInformationDocumentBase.getCapitalAssetInformation(); for (CapitalAssetInformation capitalAsset : capitalAssets) { if (KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR.equals(capitalAsset.getCapitalAssetActionIndicator())) { return true; } } return exists; } /** * * @param mapping * @param form * @param request * @param response * @return actionForward * @throws Exception */ public ActionForward redistributeCreateCapitalAssetAmount(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("redistributeCreateCapitalAssetAmount() - start"); KualiDecimal remainingAmountToDistribute = KualiDecimal.ZERO; CapitalAccountingLinesFormBase calfb = (CapitalAccountingLinesFormBase) form; CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); String distributionCode = calfb.getCapitalAccountingLine().getDistributionCode(); remainingAmountToDistribute = getRemainingAmounToDistribute(selectedCapitalAccountingLines, form); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); //run the process to redistribute the accounting line amount to the capital assets. redistributeEqualAmountsForAccountingLineForCreateAssets(selectedCapitalAccountingLines, capitalAssetInformation, remainingAmountToDistribute); redistributeIndividualAmountsForAccountingLinesForCreateAssets(selectedCapitalAccountingLines, capitalAssetInformation); //adjust any variance from capital accounting lines to the distributed accounting lines amounts.... adjustCapitalAssetsAccountingLinesAmounts(selectedCapitalAccountingLines, capitalAssetInformation); //now perform calculations of adjusting variance when asset amounts are odd ///// adjustVarianceOnCapitalAssets(capitalAssetInformation); checkCapitalAccountingLinesSelected(calfb); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * redistributes the capital asset amount for the modify capital asset lines. * @param mapping * @param form * @param request * @param response * @return ActionForward * @throws Exception */ public ActionForward redistributeModifyCapitalAssetAmount(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { LOG.debug("redistributeModifyCapitalAssetAmount() - start"); KualiDecimal remainingAmountToDistribute = KualiDecimal.ZERO; CapitalAccountingLinesFormBase calfb = (CapitalAccountingLinesFormBase) form; CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); String distributionCode = calfb.getCapitalAccountingLine().getDistributionCode(); remainingAmountToDistribute = getRemainingAmounToDistribute(selectedCapitalAccountingLines, form); KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase = (KualiAccountingDocumentFormBase) form; List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); //run the process to redistribute the accounting line amount to the capital assets. redistributeAmountsForAccountingsLineForModifyAssets(selectedCapitalAccountingLines, capitalAssetInformation, remainingAmountToDistribute); redistributeIndividualAmountsForAccountingLinesForModifyAssets(selectedCapitalAccountingLines, capitalAssetInformation); //now process any capital assets that has distribution set to "by amount" redistributeAmountsForAccountingsLineForModifyAssetsByAmounts(selectedCapitalAccountingLines, capitalAssetInformation, remainingAmountToDistribute); //adjust any variance from capital accounting lines to the distributed accounting lines amounts.... adjustCapitalAssetsAccountingLinesAmounts(selectedCapitalAccountingLines, capitalAssetInformation); processRemainingCapitalAssetInfo(form, capitalAssetInformation); //redistribute capital asset amount to its group accounting lines on refresh DistributeCapitalAssetAmountToGroupAccountingLines((KualiAccountingDocumentFormBase) form); checkCapitalAccountingLinesSelected(calfb); return mapping.findForward(KFSConstants.MAPPING_BASIC); } /** * Calculates the remaining amount to distribute by taking selecte capital accounting lines * and subtracting the allocated capital asset accounting lines amounts totals. * * @param selectedCapitalAccountingLines * @param form * @return remainingAmountToDistribute */ protected KualiDecimal getRemainingAmounToDistribute(List<CapitalAccountingLines> selectedCapitalAccountingLines, ActionForm form) { KualiDecimal remainingAmountToDistribute = KualiDecimal.ZERO; KualiDecimal capitalAccountsAmountToDistribute = KualiDecimal.ZERO; KualiDecimal capitalAssetsAllocatedAmount = KualiDecimal.ZERO; CapitalAccountingLinesFormBase calfb = (CapitalAccountingLinesFormBase) form; CapitalAssetInformationDocumentBase capitalAssetInformationDocumentBase = (CapitalAssetInformationDocumentBase) calfb.getFinancialDocument(); List<CapitalAssetInformation> capitalAssets = capitalAssetInformationDocumentBase.getCapitalAssetInformation(); CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { selectedCapitalAccountingLines.add(capitalAccountingLine); capitalAccountsAmountToDistribute = capitalAccountsAmountToDistribute.add(capitalAccountingLine.getAmount()); capitalAssetsAllocatedAmount = capitalAssetsAllocatedAmount.add(getCapitalAssetsAmountAllocated(capitalAssets, capitalAccountingLine)); } } remainingAmountToDistribute = capitalAccountsAmountToDistribute.subtract(capitalAssetsAllocatedAmount); return remainingAmountToDistribute; } /** * Removes any matching accounting line in capital asset records * whenever an accounting line is removed. * @param financialDocumentForm * @param line */ protected void deleteCapitalAssetLines(KualiAccountingDocumentFormBase financialDocumentForm, AccountingLine accountingLine) { CapitalAssetInformationDocumentBase capitalAssetInformationDocumentBase = (CapitalAssetInformationDocumentBase) financialDocumentForm.getFinancialDocument(); List<CapitalAssetInformation> removalCaiList = new ArrayList<CapitalAssetInformation>(); List<CapitalAssetInformation> capitalAssets = capitalAssetInformationDocumentBase.getCapitalAssetInformation(); for (CapitalAssetInformation capitalAsset : capitalAssets) { removeDistributedAccountingLine(capitalAsset, accountingLine); if (capitalAsset.getCapitalAssetAccountsGroupDetails().size() == 0) { capitalAsset.getCapitalAssetInformationDetails().clear(); removalCaiList.add(capitalAsset); } } //if the removal list is not empty, remove these bunch of capital asset records //for that accounting line. if (ObjectUtils.isNotNull(removalCaiList)) { capitalAssets.removeAll(removalCaiList); } } /** * Removes the matching accounting line that has been distributed to the capital asset * * @param capitalAsset * @param accountingLine */ protected void removeDistributedAccountingLine(CapitalAssetInformation capitalAsset, AccountingLine accountingLine) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); CapitalAssetAccountsGroupDetails accountLineToDelete = null; for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getSequenceNumber().compareTo(accountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(groupAccountLine.getFinancialDocumentLineTypeCode()) && groupAccountLine.getChartOfAccountsCode().equals(accountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(accountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(accountingLine.getFinancialObjectCode())) { accountLineToDelete = groupAccountLine; break; } } if (ObjectUtils.isNotNull(accountLineToDelete)) { capitalAsset.setCapitalAssetLineAmount(capitalAsset.getCapitalAssetLineAmount().subtract(accountLineToDelete.getAmount())); groupAccountLines.remove(accountLineToDelete); } } /** * add detail lines into the given capital asset information * * @param capitalAssetInformation the given capital asset information */ protected void addCapitalAssetInfoDetailLines(CapitalAssetInformation capitalAssetInformation) { LOG.debug("addCapitalAssetInfoDetailLines() - start"); if (ObjectUtils.isNull(capitalAssetInformation)) { return; } Integer quantity = capitalAssetInformation.getCapitalAssetQuantity(); if (quantity == null || quantity <= 0) { String errorPath = KFSPropertyConstants.DOCUMENT + "." + KFSPropertyConstants.CAPITAL_ASSET_INFORMATION; GlobalVariables.getMessageMap().putError(errorPath, KFSKeyConstants.ERROR_INVALID_CAPITAL_ASSET_QUANTITY); return; } List<CapitalAssetInformationDetail> detailLines = capitalAssetInformation.getCapitalAssetInformationDetails(); Integer nextItemLineNumber = 0; if (ObjectUtils.isNotNull(detailLines) || detailLines.size() > 0) { for (CapitalAssetInformationDetail detailLine : detailLines) { nextItemLineNumber = detailLine.getItemLineNumber().intValue(); } } // If details collection has old lines, this loop will add new lines to make the total equal to the quantity. for (int index = 1; detailLines.size() < quantity; index++) { CapitalAssetInformationDetail detailLine = new CapitalAssetInformationDetail(); detailLine.setDocumentNumber(capitalAssetInformation.getDocumentNumber()); detailLine.setCapitalAssetLineNumber(capitalAssetInformation.getCapitalAssetLineNumber()); detailLine.setItemLineNumber(++nextItemLineNumber); detailLines.add(detailLine); } } /** * unchecks the capital accounting lines select when there are no capital assets created yet. * * @param calfb */ protected void uncheckCapitalAccountingLinesSelected(CapitalAccountingLinesFormBase calfb) { CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); KualiAccountingDocumentFormBase kadfb = calfb; List<CapitalAssetInformation> currentCapitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kadfb); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { calfb.setSystemControlAmount(calfb.getSystemControlAmount().add(capitalAccountingLine.getAmount())); selectedCapitalAccountingLines.add(capitalAccountingLine); } } CapitalAssetInformation existingCapitalAsset = capitalAssetCreated(selectedCapitalAccountingLines, currentCapitalAssetInformation); for (CapitalAccountingLines capitalAccountingLine : selectedCapitalAccountingLines) { if (ObjectUtils.isNull(existingCapitalAsset)) { capitalAccountingLine.setSelectLine(false); } } } /** * checks "select" check box on capital accounting lines if there are * corresponding capital asset records. * * @param calfb */ protected void checkSelectForCapitalAccountingLines(CapitalAccountingLinesFormBase calfb) { CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) calfb.getFinancialDocument(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); KualiAccountingDocumentFormBase kadfb = calfb; List<CapitalAssetInformation> currentCapitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kadfb); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (currentCapitalAssetInformation.size() <= 0) { capitalAccountingLine.setSelectLine(false); } else { CapitalAssetInformation existingCapitalAsset = getCapitalAssetCreated(capitalAccountingLine, currentCapitalAssetInformation); if (ObjectUtils.isNotNull(existingCapitalAsset)) { capitalAccountingLine.setSelectLine(true); } else { capitalAccountingLine.setSelectLine(false); } } } } /** * gets the total of all accounting lines from that capital asset. * * @param capitalAssetInformation * @return accountingLinesTotalAmount */ protected KualiDecimal getAccountingLinesTotalAmount(CapitalAssetInformation capitalAssetInformation) { KualiDecimal accountingLinesTotalAmount = KualiDecimal.ZERO; List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAssetInformation.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { accountingLinesTotalAmount = accountingLinesTotalAmount.add(groupAccountLine.getAmount()); } return accountingLinesTotalAmount; } /** * * * @param capitalAccountingLine * @param capitalAssetInformation * @param actionTypeCode * @return accountingLinesTotalAmount */ protected KualiDecimal getAccountingLinesDistributedAmount(CapitalAccountingLines capitalAccountingLine, List<CapitalAssetInformation> capitalAssetInformation, String actionTypeCode) { KualiDecimal accountingLinesTotalAmount = KualiDecimal.ZERO; for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { if (capitalAsset.getCapitalAssetActionIndicator().equalsIgnoreCase(actionTypeCode)) { accountingLinesTotalAmount = accountingLinesTotalAmount.add(getAccountingLineAmount(capitalAsset, capitalAccountingLine)); } } return accountingLinesTotalAmount; } /** * * @param capitalAccountingLine * @param lastCapitalAsset * @param difference */ protected void adjustAccountingLineAmountOnLastCapitalAsset(CapitalAccountingLines capitalAccountingLine, CapitalAssetInformation lastCapitalAsset, KualiDecimal difference) { List<CapitalAssetAccountsGroupDetails> groupAccountLines = lastCapitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { if (groupAccountLine.getCapitalAssetLineNumber().compareTo(lastCapitalAsset.getCapitalAssetLineNumber()) == 0 && groupAccountLine.getSequenceNumber().compareTo(capitalAccountingLine.getSequenceNumber()) == 0 && groupAccountLine.getFinancialDocumentLineTypeCode().equals(KFSConstants.SOURCE.equals(capitalAccountingLine.getLineType()) ? KFSConstants.SOURCE_ACCT_LINE_TYPE_CODE : KFSConstants.TARGET_ACCT_LINE_TYPE_CODE) && groupAccountLine.getChartOfAccountsCode().equals(capitalAccountingLine.getChartOfAccountsCode()) && groupAccountLine.getAccountNumber().equals(capitalAccountingLine.getAccountNumber()) && groupAccountLine.getFinancialObjectCode().equals(capitalAccountingLine.getFinancialObjectCode())) { groupAccountLine.setAmount(groupAccountLine.getAmount().add(difference)); } } } /** * when the user user hits refresh button, takes the amount in the amount field and * distributes to the group capital accounting lines for that asset only. * @param capitalAssetInformation * @param selectedCapitalAccountingLines */ protected void redistributeToGroupAccountingLinesFromAssetsByAmounts(List<CapitalAccountingLines> selectedCapitalAccountingLines, CapitalAssetInformation capitalAsset) { KualiDecimal amountToDistribute = capitalAsset.getCapitalAssetLineAmount(); KualiDecimal amountDistributed = KualiDecimal.ZERO; KualiDecimal totalCapitalAccountsAmount = getTotalCapitalAccountsAmounts(selectedCapitalAccountingLines); //to capture the last group accounting line to update its amount with any variance. CapitalAssetAccountsGroupDetails lastGroupAccountLine = new CapitalAssetAccountsGroupDetails(); List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { BigDecimal linePercent = getCapitalAccountingLinePercent(selectedCapitalAccountingLines, groupAccountLine, totalCapitalAccountsAmount); //found the accounting line lastGroupAccountLine = groupAccountLine; KualiDecimal groupAccountLineAmount = capitalAsset.getCapitalAssetLineAmount().multiply(new KualiDecimal(linePercent)); groupAccountLine.setAmount(groupAccountLineAmount); //keep track of amoutn distributed so far. amountDistributed = amountDistributed.add(groupAccountLineAmount); } //add any variance in the amounts to the last group accounting line. lastGroupAccountLine.setAmount(lastGroupAccountLine.getAmount().add(amountToDistribute.subtract(amountDistributed))); } /** * calculates the total amount of the selected capital accounting lines * * @param capitalAccountingLines * @return total amount of the selected capital accounting lines. */ protected KualiDecimal getTotalCapitalAccountsAmounts(List<CapitalAccountingLines> capitalAccountingLines) { KualiDecimal totalCapitalAccountsAmount = KualiDecimal.ZERO; for (CapitalAccountingLines capitalLine : capitalAccountingLines) { totalCapitalAccountsAmount = totalCapitalAccountsAmount.add(capitalLine.getAmount()); } return totalCapitalAccountsAmount; } /** * This method redistributes the capital asset amount to its group accounting lines * based on the accounting line's percent. Takes each capital assets amount and * distributes to the capital asset group accounting lines. * * @param kualiAccountingDocumentFormBase */ protected void DistributeCapitalAssetAmountToGroupAccountingLines(KualiAccountingDocumentFormBase kualiAccountingDocumentFormBase) { CapitalAccountingLinesFormBase capitalAccountingLinesFormBase = (CapitalAccountingLinesFormBase) kualiAccountingDocumentFormBase; checkSelectForCapitalAccountingLines(capitalAccountingLinesFormBase); checkCapitalAccountingLinesSelected(capitalAccountingLinesFormBase); calculatePercentsForSelectedCapitalAccountingLines(capitalAccountingLinesFormBase); CapitalAccountingLinesDocumentBase caldb = (CapitalAccountingLinesDocumentBase) capitalAccountingLinesFormBase.getFinancialDocument(); String distributionAmountCode = capitalAccountingLinesFormBase.getCapitalAccountingLine().getDistributionCode(); List<CapitalAccountingLines> capitalAccountingLines = caldb.getCapitalAccountingLines(); List<CapitalAccountingLines> selectedCapitalAccountingLines = new ArrayList<CapitalAccountingLines>(); for (CapitalAccountingLines capitalAccountingLine : capitalAccountingLines) { if (capitalAccountingLine.isSelectLine() && !capitalAccountingLine.isAmountDistributed()) { capitalAccountingLine.setDistributionAmountCode(KFSConstants.CapitalAssets.CAPITAL_ASSET_MODIFY_ACTION_INDICATOR); selectedCapitalAccountingLines.add(capitalAccountingLine); } } List<CapitalAssetInformation> capitalAssetInformation = this.getCurrentCapitalAssetInformationObject(kualiAccountingDocumentFormBase); for (CapitalAssetInformation capitalAsset : capitalAssetInformation) { //redistribute the capital asset modify amount to the group accounting lines //based on amount. if (!capitalAssetAmountAlreadyDistributedToGroupAccountingLines(capitalAsset)) { redistributeToGroupAccountingLinesFromAssetsByAmounts(selectedCapitalAccountingLines, capitalAsset); } } } /** * checks if the capital asset amount already distributed to its group accounting lines * * @param capitalAsset * @return true if amount already distributed else return false. */ protected boolean capitalAssetAmountAlreadyDistributedToGroupAccountingLines(CapitalAssetInformation capitalAsset) { boolean amountDistributed = true; KualiDecimal capitalAssetAmount = capitalAsset.getCapitalAssetLineAmount(); KualiDecimal totalAmountDistributed = KualiDecimal.ZERO; List<CapitalAssetAccountsGroupDetails> groupAccountLines = capitalAsset.getCapitalAssetAccountsGroupDetails(); for (CapitalAssetAccountsGroupDetails groupAccountLine : groupAccountLines) { //keep track of amount distributed so far. totalAmountDistributed = totalAmountDistributed.add(groupAccountLine.getAmount()); } return (capitalAssetAmount.compareTo(totalAmountDistributed) == 0); } }