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 java.util.HashMap;
019 import java.util.Map;
020
021 import org.apache.commons.lang.StringUtils;
022 import org.kuali.kfs.coa.businessobject.Account;
023 import org.kuali.kfs.coa.businessobject.SubAccount;
024 import org.kuali.kfs.coa.businessobject.SubObjectCode;
025 import org.kuali.kfs.fp.businessobject.CreditCardVendor;
026 import org.kuali.kfs.sys.KFSKeyConstants;
027 import org.kuali.rice.kns.document.MaintenanceDocument;
028 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
029 import org.kuali.rice.kns.util.ObjectUtils;
030
031 /**
032 * This class represents business rules for the credit card vendor maintenance document
033 */
034 public class CreditCardVendorRule extends MaintenanceDocumentRuleBase {
035
036 protected CreditCardVendor newCreditCardVendor;
037
038 /**
039 * Sets up a CreditCardVendor convenience objects to make sure all possible sub-objects are populated
040 *
041 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#setupConvenienceObjects()
042 */
043 public void setupConvenienceObjects() {
044
045 newCreditCardVendor = (CreditCardVendor) super.getNewBo();
046 }
047
048 /**
049 * Return true if rules for processing a save for the credit card maintenance document are are valid.
050 *
051 * @param document maintenance document
052 * @return true credit card vendor number is valid
053 *
054 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
055 */
056 protected boolean processCustomSaveDocumentBusinessRules(MaintenanceDocument document) {
057 // default to success
058 boolean success = true;
059 setupConvenienceObjects();
060
061 // check valid Credit Card Vendor Number (numeric, minimum length)
062 success &= checkCreditCardVendorNumber();
063
064 return success;
065 }
066
067 /**
068 * Returns value from processCustomRouteDocumentBusinessRules(document)
069 *
070 * @param document maintenance document
071 * @return value from processCustomRouteDocumentBusinessRules(document)
072 *
073 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomApproveDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
074 */
075 protected boolean processCustomApproveDocumentBusinessRules(MaintenanceDocument document) {
076
077 return processCustomRouteDocumentBusinessRules(document);
078 }
079
080 /**
081 * Returns true credit card vendor maintenance document is routed successfully
082 *
083 * @param document submitted credit card maintenance document
084 * @return true if credit card vendor number, income/expense account numbers, income/expense sub-account numbers, and income/expense sub-object codes are valid
085 *
086 * @see org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.kns.document.MaintenanceDocument)
087 */
088 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
089 // default to success
090 boolean success = true;
091
092 setupConvenienceObjects();
093
094 // check valid Credit Card Vendor Number (numeric, minimum length)
095 success &= checkCreditCardVendorNumber();
096
097 // check Income Account Number business rule
098 if (newCreditCardVendor.getIncomeAccountNumber() != null) {
099 success &= checkExistingActiveAccount(newCreditCardVendor.getIncomeAccountNumber(), "incomeAccountNumber", "Income Account Number");
100 }
101
102 // check Expense Account Number business rule
103 if (newCreditCardVendor.getExpenseAccountNumber() != null) {
104 success &= checkExistingActiveAccount(newCreditCardVendor.getExpenseAccountNumber(), "expenseAccountNumber", "Expense Account Number");
105 }
106
107 // check Income Sub-Account business rule
108 if (newCreditCardVendor.getIncomeSubAccountNumber() != null) {
109
110 // check required fields to validate Sub-Account
111 if (checkRequiredSubAccount("Income")) {
112 SubAccount existenceSubAccount = checkExistenceSubAccount("Income");
113
114 // check existence of Sub-Account
115 if (existenceSubAccount == null) {
116 putFieldError("incomeSubAccountNumber", KFSKeyConstants.ERROR_CCV_INVALIDSUBACCOUNT, "Income Sub-Account Number, " + newCreditCardVendor.getIncomeSubAccountNumber());
117 }
118 else
119
120 // check the Sub-Account is active
121 if (!existenceSubAccount.isActive()) {
122 putFieldError("incomeSubAccountNumber", KFSKeyConstants.ERROR_INACTIVE, "Income Sub-Account");
123 }
124 }
125 }
126
127 // check Expense Sub-Account business rule
128 if (newCreditCardVendor.getExpenseSubAccountNumber() != null) {
129 if (checkRequiredSubAccount("Expense")) {
130
131 // check existence of Sub-Account
132 SubAccount existenceSubAccount = checkExistenceSubAccount("Expense");
133 if (existenceSubAccount == null) {
134 putFieldError("expenseSubAccountNumber", KFSKeyConstants.ERROR_CCV_INVALIDSUBACCOUNT, "Expense Sub-Account Number, " + newCreditCardVendor.getExpenseSubAccountNumber());
135
136 }
137 else
138
139 // check the Sub-Account is active
140 if (!existenceSubAccount.isActive()) {
141 putFieldError("expenseSubAccountNumber", KFSKeyConstants.ERROR_INACTIVE, "Expense Sub-Account");
142 }
143 }
144 }
145
146 // check Income Sub-Object Code business rule
147 if (newCreditCardVendor.getIncomeFinancialSubObjectCode() != null) {
148 if (checkRequiredSubObjectCode("Income")) {
149
150 // check existence of Sub-Object
151 SubObjectCode existenceSubObj = checkExistenceSubObj("Income");
152 if (existenceSubObj == null) {
153 putFieldError("incomeFinancialSubObjectCode", KFSKeyConstants.ERROR_CCV_INVALIDSUBOBJECT, "Income Sub-Object Code, " + newCreditCardVendor.getIncomeFinancialSubObjectCode());
154 }
155 else
156 // check the Sub-Object is active
157 if (!existenceSubObj.isActive()) {
158 putFieldError("incomeFinancialSubObjectCode", KFSKeyConstants.ERROR_INACTIVE, "Income Sub-Object");
159 }
160
161 }
162 }
163
164 // check Expense Sub-Object Code business rule
165 if (newCreditCardVendor.getExpenseFinancialSubObjectCode() != null) {
166 if (checkRequiredSubObjectCode("Expense")) {
167
168 // check existence of Sub-Object
169 SubObjectCode existenceSubObj = checkExistenceSubObj("Expense");
170 if (existenceSubObj == null) {
171 putFieldError("expenseFinancialSubObjectCode", KFSKeyConstants.ERROR_CCV_INVALIDSUBOBJECT, "Expense Sub-Object Code, " + newCreditCardVendor.getExpenseFinancialSubObjectCode());
172 }
173 else
174 // check the Sub-Object is active
175 if (!existenceSubObj.isActive()) {
176 putFieldError("expenseFinancialSubObjectCode", KFSKeyConstants.ERROR_INACTIVE, "Expense Sub-Object");
177 }
178 }
179 }
180
181
182 return success;
183 }
184
185
186 /**
187 * Returns true if credit card vendor number is valid (i.e. numeric and at least 5 digits)
188 *
189 * @return true if credit card vendor number is valid (i.e. numeric and at least 5 digits)
190 */
191 protected boolean checkCreditCardVendorNumber() {
192 String ccvNumber = newCreditCardVendor.getFinancialDocumentCreditCardVendorNumber();
193
194 if (ccvNumber == null) {
195 return false;
196 }
197 else if (!StringUtils.isNumeric(ccvNumber)) {
198 putFieldError("financialDocumentCreditCardVendorNumber", KFSKeyConstants.ERROR_NUMERIC, "Vendor Credit Card Number");
199 return false;
200 }
201 else if (ccvNumber.length() < 5) {
202 String errorMessage[] = null;
203 errorMessage = new String[] { "Vendor Credit Card Number", "5" };
204 putFieldError("financialDocumentCreditCardVendorNumber", KFSKeyConstants.ERROR_MIN_LENGTH, errorMessage);
205 return false;
206 }
207
208 return true;
209 }
210
211
212 /**
213 * Returns true if account is active (i.e. exists and is not expired or closed)
214 *
215 * @param accountNumber account number
216 * @param fieldName field name to place error for
217 * @param errorMessage error message to display
218 * @return true if account is active (i.e. exists and is not expired or closed)
219 */
220 protected boolean checkExistingActiveAccount(String accountNumber, String fieldName, String errorMessage) {
221 boolean result = false;
222 Account account;
223 Map pkMap = new HashMap();
224 pkMap.put("accountNumber", accountNumber);
225 account = (Account) super.getBoService().findByPrimaryKey(Account.class, pkMap);
226
227 // if the object doesnt exist, then we cant continue, so exit
228 if (ObjectUtils.isNull(account)) {
229 putFieldError(fieldName, KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
230 return result;
231 }
232
233 // check whether expired or not
234 if (account.isExpired()) {
235 putFieldError(fieldName, KFSKeyConstants.ERROR_EXPIRED, errorMessage);
236 return result;
237 }
238
239 // check whether closed or not
240 if (!account.isActive()) {
241 putFieldError(fieldName, KFSKeyConstants.ERROR_CLOSED, errorMessage);
242 return result;
243 }
244
245
246 return true;
247 }
248
249 /**
250 * Returns true if income/expense financial chart of accounts code and account number exist. Income or expense is determined by
251 * the "Income" value or the "Expense" value passed in to the method as a string
252 *
253 * @param string determines whether or not to check income or expense sub account information (valid values include "Income" or "Expense")
254 * @return true if corresponding sub account values exist
255 */
256 protected boolean checkRequiredSubAccount(String string) {
257 boolean returnVal = true;
258 if (string.equals("Income")) {
259 if (newCreditCardVendor.getIncomeFinancialChartOfAccountsCode() == null) {
260 putFieldError("incomeFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_INCOME_SUBACCOUNT_REQUIRED, "Income Chart");
261 returnVal = false;
262 }
263
264 if (newCreditCardVendor.getIncomeAccountNumber() == null) {
265 putFieldError("incomeAccountNumber", KFSKeyConstants.ERROR_CCV_INCOME_SUBACCOUNT_REQUIRED, "Income Account Number");
266 returnVal = false;
267 }
268 }
269
270
271 if (string.equals("Expense")) {
272 if (newCreditCardVendor.getExpenseFinancialChartOfAccountsCode() == null) {
273 putFieldError("expenseFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBACCOUNT_REQUIRED, "Expense Chart");
274 returnVal = false;
275 }
276
277 if (newCreditCardVendor.getExpenseAccountNumber() == null) {
278 putFieldError("expenseAccountNumber", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBACCOUNT_REQUIRED, "Expense Account Number");
279 returnVal = false;
280 }
281 }
282
283
284 return returnVal;
285 }
286
287
288 /**
289 * Returns a SubAccount object if SubAccount object exists for "Income" or "Expense"
290 *
291 * @param string determines whether or not to retrieve a income or expense sub account (valid values include "Income" or "Expense")
292 * @return SubAccount Income/Expense SubAccount object
293 */
294 protected SubAccount checkExistenceSubAccount(String string) {
295
296 SubAccount subAccount = null;
297
298 if (string.equals("Income")) {
299 Map pkMap = new HashMap();
300 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getIncomeFinancialChartOfAccountsCode());
301 pkMap.put("accountNumber", newCreditCardVendor.getIncomeAccountNumber());
302 pkMap.put("subAccountNumber", newCreditCardVendor.getIncomeSubAccountNumber());
303 subAccount = (SubAccount) super.getBoService().findByPrimaryKey(SubAccount.class, pkMap);
304 }
305
306 if (string.equals("Expense")) {
307 Map pkMap = new HashMap();
308 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getExpenseFinancialChartOfAccountsCode());
309 pkMap.put("accountNumber", newCreditCardVendor.getExpenseAccountNumber());
310 pkMap.put("subAccountNumber", newCreditCardVendor.getExpenseSubAccountNumber());
311 subAccount = (SubAccount) super.getBoService().findByPrimaryKey(SubAccount.class, pkMap);
312 }
313
314 return subAccount;
315 }
316
317
318 /**
319 * Returns a true sub-object code exists for "Income" or "Expense"
320 *
321 * @param string determines whether or not to check for an income or expense sub-object code (valid values include "Income" or "Expense")
322 * @return true if income/expense chart of account code, account number, and financial object code exist
323 */
324 protected boolean checkRequiredSubObjectCode(String string) {
325
326 boolean returnVal = true;
327 if (string.equals("Income")) {
328 if (newCreditCardVendor.getIncomeFinancialChartOfAccountsCode() == null) {
329 putFieldError("incomeFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_INCOME_SUBOBJ_REQUIRED, "Income Chart");
330 returnVal = false;
331 }
332
333 if (newCreditCardVendor.getIncomeAccountNumber() == null) {
334 putFieldError("incomeAccountNumber", KFSKeyConstants.ERROR_CCV_INCOME_SUBOBJ_REQUIRED, "Income Account Number");
335 returnVal = false;
336 }
337
338 if (newCreditCardVendor.getIncomeFinancialObjectCode() == null) {
339 putFieldError("incomeFinancialObjectCode", KFSKeyConstants.ERROR_CCV_INCOME_SUBOBJ_REQUIRED, "Income Object Code");
340 returnVal = false;
341 }
342
343 }
344
345
346 if (string.equals("Expense")) {
347 if (newCreditCardVendor.getExpenseFinancialChartOfAccountsCode() == null) {
348 putFieldError("expenseFinancialChartOfAccountsCode", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBOBJ_REQUIRED, "Expense Chart");
349 returnVal = false;
350 }
351
352 if (newCreditCardVendor.getExpenseAccountNumber() == null) {
353 putFieldError("expenseAccountNumber", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBOBJ_REQUIRED, "Expense Account Number");
354 returnVal = false;
355 }
356
357 if (newCreditCardVendor.getExpenseFinancialObjectCode() == null) {
358 putFieldError("expenseFinancialObjectCode", KFSKeyConstants.ERROR_CCV_EXPENSE_SUBOBJ_REQUIRED, "Expense Object Code");
359 returnVal = false;
360 }
361
362 }
363
364
365 return returnVal;
366 }
367
368
369 /**
370 * Returns a SubObjCd object if SubObjCd object exists for "Income" or "Expense"
371 *
372 * @param string determines whether or not to retrieve a income or expense sub object (valid values include "Income" or "Expense")
373 * @return SubAccount Income/Expense SubObjCd object
374 */
375 protected SubObjectCode checkExistenceSubObj(String string) {
376
377 SubObjectCode subObjCd = null;
378
379 if (string.equals("Income")) {
380 Map pkMap = new HashMap();
381 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getIncomeFinancialChartOfAccountsCode());
382 pkMap.put("accountNumber", newCreditCardVendor.getIncomeAccountNumber());
383 pkMap.put("financialObjectCode", newCreditCardVendor.getIncomeFinancialObjectCode());
384 pkMap.put("financialSubObjectCode", newCreditCardVendor.getIncomeFinancialSubObjectCode());
385 subObjCd = (SubObjectCode) super.getBoService().findByPrimaryKey(SubObjectCode.class, pkMap);
386 }
387
388 if (string.equals("Expense")) {
389 Map pkMap = new HashMap();
390 pkMap.put("chartOfAccountsCode", newCreditCardVendor.getExpenseFinancialChartOfAccountsCode());
391 pkMap.put("accountNumber", newCreditCardVendor.getExpenseAccountNumber());
392 pkMap.put("financialObjectCode", newCreditCardVendor.getExpenseFinancialObjectCode());
393 pkMap.put("financialSubObjectCode", newCreditCardVendor.getExpenseFinancialSubObjectCode());
394 subObjCd = (SubObjectCode) super.getBoService().findByPrimaryKey(SubObjectCode.class, pkMap);
395 }
396
397 return subObjCd;
398 }
399
400 }