1 /*
2 * Copyright 2006 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.ole.coa.document.validation.impl;
17
18 import java.util.List;
19
20 import org.apache.commons.lang.StringUtils;
21 import org.kuali.ole.coa.businessobject.AccountGlobalDetail;
22 import org.kuali.ole.sys.OLEKeyConstants;
23 import org.kuali.ole.sys.document.validation.impl.KfsMaintenanceDocumentRuleBase;
24 import org.kuali.rice.krad.util.GlobalVariables;
25
26 /**
27 * This class contains common Business Rule functionality for Global Documents.
28 */
29 public class GlobalDocumentRuleBase extends KfsMaintenanceDocumentRuleBase {
30
31 /**
32 * Constructs a GlobalDocumentRuleBase.java.
33 */
34 public GlobalDocumentRuleBase() {
35 super();
36 }
37
38 /**
39 * This method checks whether the set of Account Change Detail records on this document all are under the same Chart of
40 * Accounts. It will set the appropriate field error if it did fail, and return the result.
41 *
42 * @param accountGlobalDetails
43 * @return True if the test passed with no errors, False if any errors occurred.
44 */
45 protected boolean checkOnlyOneChartErrorWrapper(List<AccountGlobalDetail> accountGlobalDetails) {
46 CheckOnlyOneChartResult result = checkOnlyOneChart(accountGlobalDetails);
47 if (!result.success) {
48 putFieldError("accountGlobalDetails[" + result.firstLineNumber + "].chartOfAccountsCode", OLEKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY);
49 putFieldError("accountGlobalDetails[" + result.failedLineNumber + "].chartOfAccountsCode", OLEKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY);
50 }
51 return result.success;
52 }
53
54 /**
55 * This method checks whether the set of Account Change Detail records on this document all are under the same Chart of
56 * Accounts. It will return a failed CheckOnlyOneChartResult if so. Note that this method doesnt actually set any errors, it
57 * just returns whether or not the test succeeded, and where it failed if it failed.
58 *
59 * @param accountGlobalDetails The popualted accountGlobalDocument to test.
60 * @return A populated CheckOnlyOneChartResult object. This will contain whether the test succeeded or failed, and if failed,
61 * what lines the failures occurred on.
62 */
63 protected CheckOnlyOneChartResult checkOnlyOneChart(List<AccountGlobalDetail> accountGlobalDetails) {
64 // if there is not enough information to do the test, then exit happily with no failure
65 if (accountGlobalDetails == null) {
66 return new CheckOnlyOneChartResult(true);
67 }
68 if (accountGlobalDetails.isEmpty()) {
69 return new CheckOnlyOneChartResult(true);
70 }
71
72 // test to see if there is more than one chart listed, ignores blank chartcodes
73 int compareLineNumber = 0;
74 int firstChartLineNumber = 0;
75 String firstChart = "";
76 for (AccountGlobalDetail account : accountGlobalDetails) {
77 if (StringUtils.isBlank(firstChart)) {
78 if (StringUtils.isNotBlank(account.getChartOfAccountsCode())) {
79 firstChart = account.getChartOfAccountsCode();
80 firstChartLineNumber = compareLineNumber;
81 }
82 }
83 else {
84 if (StringUtils.isNotBlank(account.getChartOfAccountsCode())) {
85 if (!firstChart.equalsIgnoreCase(account.getChartOfAccountsCode())) {
86 return new CheckOnlyOneChartResult(false, firstChartLineNumber, compareLineNumber);
87 }
88 }
89 }
90 compareLineNumber++;
91 }
92 return new CheckOnlyOneChartResult(true);
93 }
94
95 /**
96 * This class is used internally to represent the result of the CheckOnlyOneChart method.
97 */
98 protected class CheckOnlyOneChartResult {
99
100 public int firstLineNumber;
101 public int failedLineNumber;
102 public boolean success;
103
104 /**
105 * Constructs a CheckOnlyOneChartResult
106 */
107 public CheckOnlyOneChartResult() {
108 firstLineNumber = -1;
109 failedLineNumber = -1;
110 success = true;
111 }
112
113 /**
114 * Constructs a CheckOnlyOneChartResult
115 *
116 * @param success
117 */
118 public CheckOnlyOneChartResult(boolean success) {
119 this();
120 this.success = success;
121 }
122
123 /**
124 * Constructs a CheckOnlyOneChartResult
125 *
126 * @param success
127 * @param firstLineNumber
128 * @param failedLineNumber
129 */
130 public CheckOnlyOneChartResult(boolean success, int firstLineNumber, int failedLineNumber) {
131 this.success = success;
132 this.firstLineNumber = firstLineNumber;
133 this.failedLineNumber = failedLineNumber;
134 }
135
136 }
137
138 /**
139 * This method tests whether the line being added has a different Chart of Accounts Code from any of the existing lines. It will
140 * set an Error and return false if this is the case.
141 *
142 * @param newAccountLine
143 * @param accountGlobalDetails
144 * @return True if the line being added has the exact same chart as all the existing lines, False if not.
145 */
146 protected boolean checkOnlyOneChartAddLineErrorWrapper(AccountGlobalDetail newAccountLine, List<AccountGlobalDetail> accountGlobalDetails) {
147 boolean success = checkOnlyOneChartAddLine(newAccountLine, accountGlobalDetails);
148 if (!success) {
149 // putGlobalError(OLEKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY_ADDNEW);
150 // TODO: KULCOA-1091 Need to add this error to the add line, but this doesn't work right, as the
151 // error message comes out at the bottom, and the field doesn't get highlighted.
152 // putFieldError("newAccountGlobalDetail.chartOfAccountsCode",
153 // OLEKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY);
154
155 // added to prevent error from showing at the top of the document, but rather in the Account Detail Edit section
156 GlobalVariables.getMessageMap().putError("chartOfAccountsCode", OLEKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_ONE_CHART_ONLY_ADDNEW);
157 }
158 return success;
159 }
160
161 /**
162 * 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
163 * same chart. If the line being added differs from any existing line's Chart code, it will return false. Note that this
164 * document does not actually set any errors, it just reports success or failure.
165 *
166 * @param newAccountLine
167 * @param accountGlobalDetails
168 * @return True if no errors are found, False if the line being added has a different Chart code than any of the existing lines.
169 */
170 protected boolean checkOnlyOneChartAddLine(AccountGlobalDetail newAccountLine, List<AccountGlobalDetail> accountGlobalDetails) {
171 if (newAccountLine == null || accountGlobalDetails == null) {
172 return true;
173 }
174 if (accountGlobalDetails.isEmpty()) {
175 return true;
176 }
177 String newChart = newAccountLine.getChartOfAccountsCode();
178 if (StringUtils.isBlank(newChart)) {
179 return true;
180 }
181 for (AccountGlobalDetail account : accountGlobalDetails) {
182 if (StringUtils.isNotBlank(account.getChartOfAccountsCode())) {
183 if (!newChart.equalsIgnoreCase(account.getChartOfAccountsCode())) {
184 return false;
185 }
186 }
187 }
188 return true;
189 }
190
191 }