001: /*
002: * Copyright 2006-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.financial.rules;
017:
018: import static org.kuali.kfs.rules.AccountingDocumentRuleBaseConstants.ERROR_PATH.DOCUMENT_ERROR_PREFIX;
019:
020: import org.kuali.core.document.Document;
021: import org.kuali.core.util.GeneralLedgerPendingEntrySequenceHelper;
022: import org.kuali.core.util.GlobalVariables;
023: import org.kuali.core.util.ObjectUtils;
024: import org.kuali.kfs.KFSConstants;
025: import org.kuali.kfs.KFSKeyConstants;
026: import org.kuali.kfs.KFSPropertyConstants;
027: import org.kuali.kfs.KFSKeyConstants.CashReceipt;
028: import org.kuali.kfs.bo.GeneralLedgerPendingEntry;
029: import org.kuali.kfs.document.AccountingDocument;
030: import org.kuali.kfs.rule.GenerateGeneralLedgerDocumentPendingEntriesRule;
031: import org.kuali.kfs.rules.AccountingDocumentRuleUtil;
032: import org.kuali.module.financial.bo.AdvanceDepositDetail;
033: import org.kuali.module.financial.document.AdvanceDepositDocument;
034: import org.kuali.module.financial.document.CashReceiptFamilyBase;
035:
036: /**
037: * Business rules applicable to Advance Deposit documents.
038: */
039: public class AdvanceDepositDocumentRule extends CashReceiptFamilyRule
040: implements
041: GenerateGeneralLedgerDocumentPendingEntriesRule<AccountingDocument> {
042: /**
043: * For Advance Deposit documents, the document is balanced if the sum total of advance deposits equals the sum total of the
044: * accounting lines.
045: *
046: * @param financialDocument submitted financial document
047: * @return true if document is balanced (i.e. sum of advance deposits equals the sum total of accounting lines)
048: * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#isDocumentBalanceValid(org.kuali.core.document.FinancialDocument)
049: */
050: @Override
051: protected boolean isDocumentBalanceValid(
052: AccountingDocument financialDocument) {
053: AdvanceDepositDocument ad = (AdvanceDepositDocument) financialDocument;
054:
055: // make sure the document is in balance
056: boolean isValid = ad.getSourceTotal().equals(
057: ad.getTotalDollarAmount());
058:
059: if (!isValid) {
060: GlobalVariables
061: .getErrorMap()
062: .putError(
063: KFSPropertyConstants.NEW_ADVANCE_DEPOSIT,
064: KFSKeyConstants.AdvanceDeposit.ERROR_DOCUMENT_ADVANCE_DEPOSIT_OUT_OF_BALANCE);
065: }
066:
067: return isValid;
068: }
069:
070: /**
071: * Overrides to call super and then make sure the minimum number of deposit lines exist on this document.
072: *
073: * @param document submitted document
074: * @return true if associated rules are all valid
075: * @see org.kuali.core.rule.DocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.core.document.Document)
076: */
077: @Override
078: protected boolean processCustomRouteDocumentBusinessRules(
079: Document document) {
080: boolean isValid = super
081: .processCustomRouteDocumentBusinessRules(document);
082:
083: if (isValid) {
084: isValid = isMinimumNumberOfAdvanceDepositsMet(document);
085: }
086:
087: return isValid;
088: }
089:
090: /**
091: * This method is a helper that checks to make sure that at least one deposit line exists for the document.
092: *
093: * @param document submitted document
094: * @return boolean true if the there is a least one deposit line for document
095: */
096: private boolean isMinimumNumberOfAdvanceDepositsMet(
097: Document document) {
098: AdvanceDepositDocument ad = (AdvanceDepositDocument) document;
099:
100: if (ad.getAdvanceDeposits().size() == 0) {
101: GlobalVariables
102: .getErrorMap()
103: .putError(
104: DOCUMENT_ERROR_PREFIX,
105: KFSKeyConstants.AdvanceDeposit.ERROR_DOCUMENT_ADVANCE_DEPOSIT_REQ_NUMBER_DEPOSITS_NOT_MET);
106: return false;
107: } else {
108: return true;
109: }
110: }
111:
112: /**
113: * Overrides to validate all of the deposits associated with this document.
114: *
115: * @param document submitted document
116: * @return true if associated rules are all valid
117: * @see org.kuali.core.rule.DocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.core.document.Document)
118: */
119: @Override
120: protected boolean processCustomSaveDocumentBusinessRules(
121: Document document) {
122: boolean isValid = super
123: .processCustomSaveDocumentBusinessRules(document);
124:
125: if (isValid) {
126: isValid &= validateAccountingLineTotal((CashReceiptFamilyBase) document);
127: isValid &= validateAdvanceDeposits((AdvanceDepositDocument) document);
128: }
129:
130: return isValid;
131: }
132:
133: /**
134: * Validates all of the Advance Deposits in the given Document, adding global errors for invalid items. It just uses the
135: * DataDictionary validation.
136: *
137: * @param advanceDepositDocument submitted Advance Deposit Document
138: * @return boolean true if all advance deposits are valid (i.e. advance deposit amount is not 0, bank and bank account number
139: * are not blank)
140: */
141: private boolean validateAdvanceDeposits(
142: AdvanceDepositDocument advanceDepositDocument) {
143: GlobalVariables.getErrorMap().addToErrorPath(
144: KFSConstants.DOCUMENT_PROPERTY_NAME);
145: boolean isValid = true;
146: for (int i = 0; i < advanceDepositDocument.getAdvanceDeposits()
147: .size(); i++) {
148: String propertyName = KFSPropertyConstants.ADVANCE_DEPOSIT_DETAIL
149: + "[" + i + "]";
150: GlobalVariables.getErrorMap().addToErrorPath(propertyName);
151: isValid &= AdvanceDepositDocumentRuleUtil
152: .validateAdvanceDeposit(advanceDepositDocument
153: .getAdvanceDepositDetail(i));
154: GlobalVariables.getErrorMap().removeFromErrorPath(
155: propertyName);
156: }
157:
158: // don't bother checking the total if some deposits are broken
159: if (isValid
160: && advanceDepositDocument
161: .getTotalAdvanceDepositAmount().isZero()) {
162: isValid = false;
163: GlobalVariables.getErrorMap().putError(
164: KFSPropertyConstants.ADVANCE_DEPOSIT_DETAIL,
165: CashReceipt.ERROR_ZERO_TOTAL,
166: "Advance Deposit Total");
167: }
168:
169: GlobalVariables.getErrorMap().removeFromErrorPath(
170: KFSConstants.DOCUMENT_PROPERTY_NAME);
171: return isValid;
172: }
173:
174: /**
175: * Generates bank offset GLPEs for deposits, if enabled.
176: *
177: * @param financialDocument submitted financial document
178: * @param sequenceHelper helper class which will allows us to increment a reference without using an Integer
179: * @return true if there are no issues creating GLPE's
180: * @see org.kuali.core.rule.GenerateGeneralLedgerDocumentPendingEntriesRule#processGenerateDocumentGeneralLedgerPendingEntries(org.kuali.core.document.FinancialDocument,org.kuali.core.util.GeneralLedgerPendingEntrySequenceHelper)
181: */
182: public boolean processGenerateDocumentGeneralLedgerPendingEntries(
183: AccountingDocument financialDocument,
184: GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
185: boolean success = true;
186: final AdvanceDepositDocument advanceDepositDocument = ((AdvanceDepositDocument) financialDocument);
187: if (advanceDepositDocument.isBankCashOffsetEnabled()) {
188: int displayedDepositNumber = 1;
189: for (AdvanceDepositDetail detail : advanceDepositDocument
190: .getAdvanceDeposits()) {
191: detail
192: .refreshReferenceObject(KFSPropertyConstants.FINANCIAL_DOCUMENT_BANK_ACCOUNT);
193:
194: GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry();
195: if (!AccountingDocumentRuleUtil
196: .populateBankOffsetGeneralLedgerPendingEntry(
197: detail
198: .getFinancialDocumentBankAccount(),
199: detail
200: .getFinancialDocumentAdvanceDepositAmount(),
201: advanceDepositDocument,
202: advanceDepositDocument.getPostingYear(),
203: sequenceHelper,
204: bankOffsetEntry,
205: KFSConstants.ADVANCE_DEPOSITS_LINE_ERRORS)) {
206: success = false;
207: continue; // An unsuccessfully populated bank offset entry may contain invalid relations, so don't add it at
208: // all.
209: }
210: bankOffsetEntry
211: .setTransactionLedgerEntryDescription(AccountingDocumentRuleUtil
212: .formatProperty(
213: KFSKeyConstants.AdvanceDeposit.DESCRIPTION_GLPE_BANK_OFFSET,
214: displayedDepositNumber++));
215: advanceDepositDocument.getGeneralLedgerPendingEntries()
216: .add(bankOffsetEntry);
217: sequenceHelper.increment();
218:
219: GeneralLedgerPendingEntry offsetEntry = (GeneralLedgerPendingEntry) ObjectUtils
220: .deepCopy(bankOffsetEntry);
221: success &= populateOffsetGeneralLedgerPendingEntry(
222: advanceDepositDocument.getPostingYear(),
223: bankOffsetEntry, sequenceHelper, offsetEntry);
224: advanceDepositDocument.getGeneralLedgerPendingEntries()
225: .add(offsetEntry);
226: sequenceHelper.increment();
227: }
228: }
229: return success;
230: }
231: }
|