001: /*
002: * Copyright 2005-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 org.apache.commons.lang.StringUtils;
019: import org.kuali.core.util.GlobalVariables;
020: import org.kuali.core.workflow.service.KualiWorkflowDocument;
021: import org.kuali.kfs.KFSPropertyConstants;
022: import org.kuali.kfs.bo.AccountingLine;
023: import org.kuali.kfs.bo.GeneralLedgerPendingEntry;
024: import org.kuali.kfs.document.AccountingDocument;
025:
026: /**
027: * Business rule(s) applicable to Service Billing documents. They differ from {@link InternalBillingDocumentRule} by not routing for
028: * fiscal officer approval. Instead, they route straight to final, by a formal pre-agreement between the service provider and the
029: * department being billed, based on the service provider's ability to provide documentation for all transactions. These agreements
030: * are configured in the Service Billing Control table by workgroup and income account number. This class enforces those agreements.
031: */
032: public class ServiceBillingDocumentRule extends
033: InternalBillingDocumentRule {
034:
035: /**
036: * This method determines if an account is still accessible. This is performed by one of two methods:
037: * <ul>
038: * <li> If the document is in 'initiated' or 'saved' status, then if the accounting line is a target line and the
039: * account associated with that line is accessible based on ServiceBillingDocumentRuleUtils.serviceBillingIncomeAccountIsAccessible()</li>
040: * <li> If the document is not in 'initiated' or 'saved' status, then call the super method to determine accessibility.</li>
041: * </ul>
042: *
043: * @param financialDocument The document used to retrieve the route status from. The route status will impact how
044: * accessibility of the account is determined.
045: * @param accountingLine The accounting line the account is retrieved from.
046: * @return True if the account is accessible, false otherwise.
047: *
048: * @see AccountingDocumentRuleBase#accountIsAccessible(FinancialDocument, AccountingLine)
049: * @see ServiceBillingDocumentRuleUtil#serviceBillingIncomeAccountIsAccessible(AccountingLine, org.kuali.kfs.rules.AccountingDocumentRuleBase.AccountingLineAction)
050: */
051: @Override
052: protected boolean accountIsAccessible(
053: AccountingDocument financialDocument,
054: AccountingLine accountingLine) {
055: KualiWorkflowDocument workflowDocument = financialDocument
056: .getDocumentHeader().getWorkflowDocument();
057:
058: if (workflowDocument.stateIsInitiated()
059: || workflowDocument.stateIsSaved()) {
060: // The use from hasAccessibleAccountingLines() is not important for SB, which routes straight to final.
061: return accountingLine.isTargetAccountingLine()
062: || ServiceBillingDocumentRuleUtil
063: .serviceBillingIncomeAccountIsAccessible(
064: accountingLine, null);
065: }
066: return super .accountIsAccessible(financialDocument,
067: accountingLine);
068: }
069:
070: /**
071: * This method determines if an account is still accessible. This is performed by one of two methods:
072: * <ul>
073: * <li> If the document is in 'initiated' or 'saved' status, then if the accounting line is a target line and the
074: * account associated with that line is accessible based on ServiceBillingDocumentRuleUtils.serviceBillingIncomeAccountIsAccessible()</li>
075: * <li> If the document is not in 'initiated' or 'saved' status, then call the super method to determine accessibility.</li>
076: * </ul>
077: *
078: * @param financialDocument The document used to retrieve the route status from. The route status will impact how
079: * accessibility of the account is determined.
080: * @param accountingLine The accounting line the account is retrieved from.
081: * @param action The constant used to identify which error key to use when reporting errors.
082: * @return True if the account is accessible, false otherwise.
083: *
084: * @see FinancialDocumentRuleBase#checkAccountingLineAccountAccessibility(org.kuali.core.document.FinancialDocument,
085: * org.kuali.core.bo.AccountingLine, org.kuali.module.financial.rules.FinancialDocumentRuleBase.AccountingLineAction)
086: * @see AccountingDocumentRuleBase.AccountingLineAction
087: */
088: @Override
089: protected boolean checkAccountingLineAccountAccessibility(
090: AccountingDocument financialDocument,
091: AccountingLine accountingLine, AccountingLineAction action) {
092: // Duplicate code from accountIsAccessible() to avoid unnecessary calls to SB control and Workgroup services.
093: KualiWorkflowDocument workflowDocument = financialDocument
094: .getDocumentHeader().getWorkflowDocument();
095:
096: if (workflowDocument.stateIsInitiated()
097: || workflowDocument.stateIsSaved()) {
098: return accountingLine.isTargetAccountingLine()
099: || ServiceBillingDocumentRuleUtil
100: .serviceBillingIncomeAccountIsAccessible(
101: accountingLine, action);
102: }
103: if (!super .accountIsAccessible(financialDocument,
104: accountingLine)) {
105: GlobalVariables.getErrorMap().putError(
106: KFSPropertyConstants.ACCOUNT_NUMBER,
107: action.accessibilityErrorKey,
108: accountingLine.getAccountNumber(),
109: GlobalVariables.getUserSession().getUniversalUser()
110: .getPersonUserIdentifier());
111: return false;
112: }
113: return true;
114: }
115:
116: /**
117: * This method sets extra accounting line fields in explicit general ledger pending entries. Internal billing transactions
118: * don't have this field.
119: *
120: * @param financialDocument The accounting document containing the general ledger pending entries being customized.
121: * @param accountingLine The accounting line the explicit general ledger pending entry was generated from.
122: * @param explicitEntry The explicit general ledger pending entry to be customized.
123: *
124: * @see FinancialDocumentRuleBase#customizeExplicitGeneralLedgerPendingEntry(FinancialDocument, AccountingLine,
125: * GeneralLedgerPendingEntry)
126: */
127: protected void customizeExplicitGeneralLedgerPendingEntry(
128: AccountingDocument financialDocument,
129: AccountingLine accountingLine,
130: GeneralLedgerPendingEntry explicitEntry) {
131: String description = accountingLine
132: .getFinancialDocumentLineDescription();
133: if (StringUtils.isNotBlank(description)) {
134: explicitEntry
135: .setTransactionLedgerEntryDescription(description);
136: }
137: }
138:
139: /**
140: * This method further restricts the valid accounting line types exclusively to those with income or expense
141: * object type codes only. This is done by calling isIncome() and isExpense() passing the accounting line.
142: *
143: * @param financialDocument The document used to determine if the accounting line is a debit line.
144: * @param accountingLine The accounting line to be analyzed.
145: * @return True if the accounting line passed in is an expense or income accounting line and meets the rules defined
146: * by super.isDebit() method.
147: *
148: * @see org.kuali.module.financial.rules.InternalBillingDocumentRule#isDebit(org.kuali.core.document.FinancialDocument,
149: * org.kuali.core.bo.AccountingLine)
150: */
151: @Override
152: public boolean isDebit(AccountingDocument financialDocument,
153: AccountingLine accountingLine) {
154: if (!isIncome(accountingLine) && !isExpense(accountingLine)) {
155: throw new IllegalStateException(
156: IsDebitUtils.isDebitCalculationIllegalStateExceptionMessage);
157: }
158:
159: return super.isDebit(financialDocument, accountingLine);
160: }
161: }
|