001 /*
002 * Copyright 2011 The Kuali Foundation.
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.kfs.fp.document.validation.impl;
017
018 import static org.kuali.kfs.sys.KFSKeyConstants.ERROR_DOCUMENT_FUND_GROUP_SET_DOES_NOT_BALANCE;
019
020 import java.util.ArrayList;
021 import java.util.Iterator;
022 import java.util.List;
023
024 import org.kuali.kfs.fp.document.TransferOfFundsDocument;
025 import org.kuali.kfs.sys.businessobject.AccountingLine;
026 import org.kuali.kfs.sys.document.AccountingDocument;
027 import org.kuali.kfs.sys.document.validation.GenericValidation;
028 import org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent;
029 import org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBaseConstants;
030 import org.kuali.rice.kns.service.ParameterEvaluator;
031 import org.kuali.rice.kns.service.ParameterService;
032 import org.kuali.rice.kns.util.GlobalVariables;
033 import org.kuali.rice.kns.util.KualiDecimal;
034
035 /**
036 * Validation for Transfer of Funds document that tests if the fund groups represented by a given document are in balance.
037 */
038 public class TransferOfFundsFundGroupsBalancedValidation extends GenericValidation {
039 private AccountingDocument accountingDocumentForValidation;
040 private ParameterService parameterService;
041
042 /**
043 * This is a helper method that wraps the fund group balancing check. This check can be configured by updating the
044 * application parameter table that is associated with this check. See the document's specification for details.
045 * @see org.kuali.kfs.sys.document.validation.Validation#validate(org.kuali.kfs.sys.document.validation.event.AttributedDocumentEvent)
046 */
047 public boolean validate(AttributedDocumentEvent event) {
048 return isFundGroupSetBalanceValid(accountingDocumentForValidation, TransferOfFundsDocument.class, AccountingDocumentRuleBaseConstants.APPLICATION_PARAMETER.FUND_GROUP_BALANCING_SET);
049 }
050
051 /**
052 * This method will make sure that totals for a specified set of fund groups is valid across the two different accounting line
053 * sections.
054 *
055 * @param tranDoc
056 * @param fundGroupCodes An array of the fund group codes that will be considered for balancing.
057 * @return True if they balance; false otherwise.
058 */
059 protected boolean isFundGroupSetBalanceValid(AccountingDocument tranDoc, Class componentClass, String parameterName) {
060 // don't need to do any of this if there's no parameter
061 if (!getParameterService().parameterExists(componentClass, parameterName)) {
062 return true;
063 }
064
065 List lines = new ArrayList();
066
067 lines.addAll(tranDoc.getSourceAccountingLines());
068 lines.addAll(tranDoc.getTargetAccountingLines());
069
070 KualiDecimal sourceLinesTotal = KualiDecimal.ZERO;
071 KualiDecimal targetLinesTotal = KualiDecimal.ZERO;
072
073 // iterate over each accounting line and if it has an account with a
074 // fund group that should be balanced, then add that lines amount to the bucket
075 for (Iterator i = lines.iterator(); i.hasNext();) {
076 AccountingLine line = (AccountingLine) i.next();
077 String fundGroupCode = line.getAccount().getSubFundGroup().getFundGroupCode();
078
079 ParameterEvaluator evaluator = getParameterService().getParameterEvaluator(componentClass, parameterName, fundGroupCode);
080 if (evaluator.evaluationSucceeds()) {
081 KualiDecimal glpeLineAmount = tranDoc.getGeneralLedgerPendingEntryAmountForDetail(line);
082 if (line.isSourceAccountingLine()) {
083 sourceLinesTotal = sourceLinesTotal.add(glpeLineAmount);
084 }
085 else {
086 targetLinesTotal = targetLinesTotal.add(glpeLineAmount);
087 }
088 }
089 }
090
091 // check that the amounts balance across sections
092 boolean isValid = true;
093
094 if (sourceLinesTotal.compareTo(targetLinesTotal) != 0) {
095 isValid = false;
096
097 // creating an evaluator to just format the fund codes into a nice string
098 ParameterEvaluator evaluator = getParameterService().getParameterEvaluator(componentClass, parameterName, "");
099 GlobalVariables.getMessageMap().putError("document.sourceAccountingLines", ERROR_DOCUMENT_FUND_GROUP_SET_DOES_NOT_BALANCE, new String[] { tranDoc.getSourceAccountingLinesSectionTitle(), tranDoc.getTargetAccountingLinesSectionTitle(), evaluator.getParameterValuesForMessage() });
100 }
101
102 return isValid;
103 }
104
105 /**
106 * Gets the accountingDocumentForValidation attribute.
107 * @return Returns the accountingDocumentForValidation.
108 */
109 public AccountingDocument getAccountingDocumentForValidation() {
110 return accountingDocumentForValidation;
111 }
112
113 /**
114 * Sets the accountingDocumentForValidation attribute value.
115 * @param accountingDocumentForValidation The accountingDocumentForValidation to set.
116 */
117 public void setAccountingDocumentForValidation(AccountingDocument accountingDocumentForValidation) {
118 this.accountingDocumentForValidation = accountingDocumentForValidation;
119 }
120
121 /**
122 * Gets the parameterService attribute.
123 * @return Returns the parameterService.
124 */
125 public ParameterService getParameterService() {
126 return parameterService;
127 }
128
129 /**
130 * Sets the parameterService attribute value.
131 * @param parameterService The parameterService to set.
132 */
133 public void setParameterService(ParameterService parameterService) {
134 this.parameterService = parameterService;
135 }
136 }