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.chart.rules;
017:
018: import java.util.List;
019:
020: import org.apache.commons.lang.StringUtils;
021: import org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase;
022: import org.kuali.core.util.GlobalVariables;
023: import org.kuali.kfs.KFSKeyConstants;
024: import org.kuali.module.chart.bo.AccountGlobalDetail;
025:
026: /**
027: * This class contains common Business Rule functionality for Global Documents.
028: */
029: public class GlobalDocumentRuleBase extends MaintenanceDocumentRuleBase {
030:
031: /**
032: * Constructs a GlobalDocumentRuleBase.java.
033: */
034: public GlobalDocumentRuleBase() {
035: super ();
036: }
037:
038: /**
039: * This method checks whether the set of Account Change Detail records on this document all are under the same Chart of
040: * Accounts. It will set the appropriate field error if it did fail, and return the result.
041: *
042: * @param accountGlobalDetails
043: * @return True if the test passed with no errors, False if any errors occurred.
044: */
045: protected boolean checkOnlyOneChartErrorWrapper(
046: List<AccountGlobalDetail> accountGlobalDetails) {
047: CheckOnlyOneChartResult result = checkOnlyOneChart(accountGlobalDetails);
048: if (!result.success) {
049: putFieldError(
050: "accountGlobalDetails[" + result.firstLineNumber
051: + "].chartOfAccountsCode",
052: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY);
053: putFieldError(
054: "accountGlobalDetails[" + result.failedLineNumber
055: + "].chartOfAccountsCode",
056: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY);
057: }
058: return result.success;
059: }
060:
061: /**
062: * This method checks whether the set of Account Change Detail records on this document all are under the same Chart of
063: * Accounts. It will return a failed CheckOnlyOneChartResult if so. Note that this method doesnt actually set any errors, it
064: * just returns whether or not the test succeeded, and where it failed if it failed.
065: *
066: * @param accountGlobalDetails The popualted accountGlobalDocument to test.
067: * @return A populated CheckOnlyOneChartResult object. This will contain whether the test succeeded or failed, and if failed,
068: * what lines the failures occurred on.
069: */
070: protected CheckOnlyOneChartResult checkOnlyOneChart(
071: List<AccountGlobalDetail> accountGlobalDetails) {
072: // if there is not enough information to do the test, then exit happily with no failure
073: if (accountGlobalDetails == null) {
074: return new CheckOnlyOneChartResult(true);
075: }
076: if (accountGlobalDetails.isEmpty()) {
077: return new CheckOnlyOneChartResult(true);
078: }
079:
080: // test to see if there is more than one chart listed, ignores blank chartcodes
081: int compareLineNumber = 0;
082: int firstChartLineNumber = 0;
083: String firstChart = "";
084: for (AccountGlobalDetail account : accountGlobalDetails) {
085: if (StringUtils.isBlank(firstChart)) {
086: if (StringUtils.isNotBlank(account
087: .getChartOfAccountsCode())) {
088: firstChart = account.getChartOfAccountsCode();
089: firstChartLineNumber = compareLineNumber;
090: }
091: } else {
092: if (StringUtils.isNotBlank(account
093: .getChartOfAccountsCode())) {
094: if (!firstChart.equalsIgnoreCase(account
095: .getChartOfAccountsCode())) {
096: return new CheckOnlyOneChartResult(false,
097: firstChartLineNumber, compareLineNumber);
098: }
099: }
100: }
101: compareLineNumber++;
102: }
103: return new CheckOnlyOneChartResult(true);
104: }
105:
106: /**
107: * This class is used internally to represent the result of the CheckOnlyOneChart method.
108: */
109: protected class CheckOnlyOneChartResult {
110:
111: public int firstLineNumber;
112: public int failedLineNumber;
113: public boolean success;
114:
115: /**
116: * Constructs a CheckOnlyOneChartResult
117: */
118: public CheckOnlyOneChartResult() {
119: firstLineNumber = -1;
120: failedLineNumber = -1;
121: success = true;
122: }
123:
124: /**
125: * Constructs a CheckOnlyOneChartResult
126: *
127: * @param success
128: */
129: public CheckOnlyOneChartResult(boolean success) {
130: this ();
131: this .success = success;
132: }
133:
134: /**
135: * Constructs a CheckOnlyOneChartResult
136: *
137: * @param success
138: * @param firstLineNumber
139: * @param failedLineNumber
140: */
141: public CheckOnlyOneChartResult(boolean success,
142: int firstLineNumber, int failedLineNumber) {
143: this .success = success;
144: this .firstLineNumber = firstLineNumber;
145: this .failedLineNumber = failedLineNumber;
146: }
147:
148: }
149:
150: /**
151: * This method tests whether the line being added has a different Chart of Accounts Code from any of the existing lines. It will
152: * set an Error and return false if this is the case.
153: *
154: * @param newAccountLine
155: * @param accountGlobalDetails
156: * @return True if the line being added has the exact same chart as all the existing lines, False if not.
157: */
158: protected boolean checkOnlyOneChartAddLineErrorWrapper(
159: AccountGlobalDetail newAccountLine,
160: List<AccountGlobalDetail> accountGlobalDetails) {
161: boolean success = checkOnlyOneChartAddLine(newAccountLine,
162: accountGlobalDetails);
163: if (!success) {
164: // putGlobalError(KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY_ADDNEW);
165: // TODO: KULCOA-1091 Need to add this error to the add line, but this doesn't work right, as the
166: // error message comes out at the bottom, and the field doesn't get highlighted.
167: // putFieldError("newAccountGlobalDetail.chartOfAccountsCode",
168: // KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY);
169:
170: // added to prevent error from showing at the top of the document, but rather in the Account Detail Edit section
171: GlobalVariables
172: .getErrorMap()
173: .putError(
174: "chartOfAccountsCode",
175: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY_ADDNEW);
176: }
177: return success;
178: }
179:
180: /**
181: * This method tests whether a new line can be added, based on the rule that says all the accounts being used must belong to the
182: * same chart. If the line being added differs from any existing line's Chart code, it will return false. Note that this
183: * document does not actually set any errors, it just reports success or failure.
184: *
185: * @param newAccountLine
186: * @param accountGlobalDetails
187: * @return True if no errors are found, False if the line being added has a different Chart code than any of the existing lines.
188: */
189: protected boolean checkOnlyOneChartAddLine(
190: AccountGlobalDetail newAccountLine,
191: List<AccountGlobalDetail> accountGlobalDetails) {
192: if (newAccountLine == null || accountGlobalDetails == null) {
193: return true;
194: }
195: if (accountGlobalDetails.isEmpty()) {
196: return true;
197: }
198: String newChart = newAccountLine.getChartOfAccountsCode();
199: if (StringUtils.isBlank(newChart)) {
200: return true;
201: }
202: for (AccountGlobalDetail account : accountGlobalDetails) {
203: if (StringUtils
204: .isNotBlank(account.getChartOfAccountsCode())) {
205: if (!newChart.equalsIgnoreCase(account
206: .getChartOfAccountsCode())) {
207: return false;
208: }
209: }
210: }
211: return true;
212: }
213:
214: }
|