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.coa.document.validation.impl;
017
018 import java.math.BigDecimal;
019 import java.util.HashMap;
020 import java.util.HashSet;
021 import java.util.List;
022 import java.util.Map;
023 import java.util.Set;
024
025 import org.apache.commons.lang.StringUtils;
026 import org.kuali.kfs.coa.businessobject.Account;
027 import org.kuali.kfs.coa.businessobject.Chart;
028 import org.kuali.kfs.coa.businessobject.IndirectCostRecoveryRate;
029 import org.kuali.kfs.coa.businessobject.IndirectCostRecoveryRateDetail;
030 import org.kuali.kfs.coa.businessobject.ObjectCode;
031 import org.kuali.kfs.coa.businessobject.SubAccount;
032 import org.kuali.kfs.coa.businessobject.SubObjectCode;
033 import org.kuali.kfs.gl.GeneralLedgerConstants;
034 import org.kuali.kfs.sys.KFSConstants;
035 import org.kuali.kfs.sys.KFSKeyConstants;
036 import org.kuali.kfs.sys.KFSPropertyConstants;
037 import org.kuali.kfs.sys.businessobject.SystemOptions;
038 import org.kuali.kfs.sys.context.SpringContext;
039 import org.kuali.rice.kns.bo.PersistableBusinessObject;
040 import org.kuali.rice.kns.document.MaintenanceDocument;
041 import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
042 import org.kuali.rice.kns.service.DataDictionaryService;
043 import org.kuali.rice.kns.util.GlobalVariables;
044 import org.kuali.rice.kns.util.KNSConstants;
045 import org.kuali.rice.kns.util.RiceKeyConstants;
046
047
048 public class IndirectCostRecoveryRateRule extends MaintenanceDocumentRuleBase {
049
050 protected static final String MAINTAINABLE_DETAIL_ERROR_PATH = KNSConstants.MAINTENANCE_NEW_MAINTAINABLE + "indirectCostRecoveryRateDetails";
051 protected static final String MAINTAINABLE_DETAIL_ADDLINE_ERROR_PATH = "add.indirectCostRecoveryRateDetails";
052
053 protected IndirectCostRecoveryRate indirectCostRecoveryRate;
054 protected IndirectCostRecoveryRateDetail indirectCostRecoveryRateDetail;
055 protected List<IndirectCostRecoveryRateDetail> indirectCostRecoveryRateDetails;
056
057 public void setupConvenienceObjects() {
058 indirectCostRecoveryRate = (IndirectCostRecoveryRate) super.getNewBo();
059 indirectCostRecoveryRateDetails = indirectCostRecoveryRate.getIndirectCostRecoveryRateDetails();
060 }
061
062 @Override
063 protected boolean processCustomRouteDocumentBusinessRules(MaintenanceDocument document) {
064 boolean success = true;
065
066 BigDecimal awardIndrCostRcvyRatePctCredits = new BigDecimal(0);
067 BigDecimal awardIndrCostRcvyRatePctDebits = new BigDecimal(0);
068
069 if (!processYear()) {
070 success = false;
071 }
072 else {
073 for(int i = 0;i<indirectCostRecoveryRateDetails.size();i++) {
074 if(indirectCostRecoveryRateDetails.get(i).isActive()) {
075 GlobalVariables.getMessageMap().addToErrorPath(MAINTAINABLE_DETAIL_ERROR_PATH + "[" + i + "]");
076 success &= processCollectionLine(indirectCostRecoveryRateDetails.get(i));
077 GlobalVariables.getMessageMap().removeFromErrorPath(MAINTAINABLE_DETAIL_ERROR_PATH + "[" + i + "]");
078
079 if(indirectCostRecoveryRateDetails.get(i).isActive()) {
080 if(KFSConstants.GL_CREDIT_CODE.equals(indirectCostRecoveryRateDetails.get(i).getTransactionDebitIndicator())) {
081 awardIndrCostRcvyRatePctCredits = awardIndrCostRcvyRatePctCredits.add(indirectCostRecoveryRateDetails.get(i).getAwardIndrCostRcvyRatePct());
082 }
083 if(KFSConstants.GL_DEBIT_CODE.equals(indirectCostRecoveryRateDetails.get(i).getTransactionDebitIndicator())) {
084 awardIndrCostRcvyRatePctDebits = awardIndrCostRcvyRatePctDebits.add(indirectCostRecoveryRateDetails.get(i).getAwardIndrCostRcvyRatePct());
085 }
086 }
087 }
088 }
089 }
090 success &= checkCreditsAndDebits(awardIndrCostRcvyRatePctCredits, awardIndrCostRcvyRatePctDebits);
091
092 return success;
093 }
094
095 public boolean checkCreditsAndDebits(BigDecimal credits, BigDecimal debits) {
096 boolean success = true;
097
098 // global errors, in KeyConstants or KFSconstants or something, use one for the top of the page (mark doc once)
099 // include the key word active (informing that only active records are considered)
100 if(!(credits.compareTo(debits) == 0)) {
101 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KNSConstants.GLOBAL_ERRORS, KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_RATE_PERCENTS_NOT_EQUAL,
102 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.AWARD_INDR_COST_RCVY_RATE_PCT));
103 success = false;
104 }
105
106 return success;
107 }
108
109 @Override
110 public boolean processCustomAddCollectionLineBusinessRules(MaintenanceDocument document, String collectionName, PersistableBusinessObject line) {
111 boolean success = true;
112 IndirectCostRecoveryRateDetail item = (IndirectCostRecoveryRateDetail) line;
113 success &= processCollectionLine(item);
114 return success;
115 }
116
117 public boolean processCollectionLine(IndirectCostRecoveryRateDetail item) {
118 boolean success = true;
119
120 success &= validateWildcards(item);
121 if(success) {
122 success &= checkExistence(item) && checkRateFormat(item);
123 }
124
125 return success;
126 }
127
128 public boolean checkExistence(IndirectCostRecoveryRateDetail item) {
129 boolean success =
130 processYear() &&
131 processChart(item) &&
132 processAccount(item) &&
133 processSubAccount(item) &&
134 processObjectCode(item) &&
135 processSubObjectCode(item);
136 return success;
137 }
138
139 public boolean processYear() {
140 boolean success = true;
141 Map pkMap = new HashMap();
142 Integer year = indirectCostRecoveryRate.getUniversityFiscalYear();
143 pkMap.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
144 if(!checkExistenceFromTable(SystemOptions.class, pkMap)) {
145 GlobalVariables.getMessageMap().putErrorWithoutFullErrorPath(KNSConstants.MAINTENANCE_NEW_MAINTAINABLE + KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR,
146 RiceKeyConstants.ERROR_EXISTENCE,
147 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRate.class, KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR));
148 success = false;
149 }
150 return success;
151 }
152
153 protected boolean processChart(IndirectCostRecoveryRateDetail item) {
154 boolean success = true;
155 Map pkMap = new HashMap();
156 String chart = item.getChartOfAccountsCode();
157 if(StringUtils.isNotBlank(chart)) {
158 if(!propertyIsWildcard(chart)) {
159 pkMap.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
160 if(!checkExistenceFromTable(Chart.class, pkMap)) {
161 logErrorUtility(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, RiceKeyConstants.ERROR_EXISTENCE);
162 success = false;
163 }
164 }
165 }
166 return success;
167 }
168
169 protected boolean processAccount(IndirectCostRecoveryRateDetail item) {
170 boolean success = true;
171 Map pkMap = new HashMap();
172 String chart = item.getChartOfAccountsCode();
173 String acct = item.getAccountNumber();
174 if(StringUtils.isNotBlank(acct)) {
175 if(!propertyIsWildcard(chart)) {
176 pkMap.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
177 }
178 if(!propertyIsWildcard(acct)) {
179 pkMap.put(KFSPropertyConstants.ACCOUNT_NUMBER, acct);
180 if(!checkExistenceFromTable(Account.class, pkMap)) {
181 logErrorUtility(KFSPropertyConstants.ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE);
182 success = false;
183 }
184 }
185 }
186 return success;
187 }
188
189 protected boolean processSubAccount(IndirectCostRecoveryRateDetail item) {
190 boolean success = true;
191 Map pkMap = new HashMap();
192 String chart = item.getChartOfAccountsCode();
193 String acct = item.getAccountNumber();
194 String subAcct = item.getSubAccountNumber();
195 if(StringUtils.isNotBlank(subAcct) && !StringUtils.containsOnly(subAcct, "-")) { // if doesn't contain only dashes
196 if(!propertyIsWildcard(chart)) {
197 pkMap.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
198 }
199 if(!propertyIsWildcard(acct)) {
200 pkMap.put(KFSPropertyConstants.ACCOUNT_NUMBER, acct);
201 }
202 if(!propertyIsWildcard(subAcct) && StringUtils.isNotBlank(subAcct) && !StringUtils.containsOnly(subAcct, "-")) {
203 pkMap.put(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, subAcct);
204 if(!checkExistenceFromTable(SubAccount.class, pkMap)) {
205 logErrorUtility(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, RiceKeyConstants.ERROR_EXISTENCE);
206 success = false;
207 }
208 }
209 }
210 return success;
211 }
212
213 protected boolean processObjectCode(IndirectCostRecoveryRateDetail item) {
214 boolean success = true;
215 Map pkMap = new HashMap();
216 Integer year = indirectCostRecoveryRate.getUniversityFiscalYear();
217 String chart = item.getChartOfAccountsCode();
218 String objCd = item.getFinancialObjectCode();
219 pkMap.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
220 if(StringUtils.isNotBlank(objCd)) {
221 if(!propertyIsWildcard(chart)) {
222 pkMap.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
223 }
224 if(!propertyIsWildcard(objCd)) {
225 pkMap.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, objCd);
226 if(!checkExistenceFromTable(ObjectCode.class, pkMap)) {
227 logErrorUtility(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE);
228 success = false;
229 }
230 }
231 }
232 return success;
233 }
234
235 protected boolean processSubObjectCode(IndirectCostRecoveryRateDetail item) { // chart being a wildcard implies account number being a wildcard, redundant checking?
236 boolean success = true;
237 Map pkMap = new HashMap();
238 Integer year = indirectCostRecoveryRate.getUniversityFiscalYear();
239 String chart = item.getChartOfAccountsCode();
240 String acct = item.getAccountNumber();
241 String objCd = item.getFinancialObjectCode();
242 String subObjCd = item.getFinancialSubObjectCode();
243 if(StringUtils.isNotBlank(subObjCd) && !propertyIsWildcard(subObjCd) && !StringUtils.containsOnly(subObjCd, "-")) {
244 pkMap.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, year);
245 if(!propertyIsWildcard(chart)) {
246 pkMap.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chart);
247 }
248 if(!propertyIsWildcard(acct)) {
249 pkMap.put(KFSPropertyConstants.ACCOUNT_NUMBER, acct);
250 }
251 if(!propertyIsWildcard(objCd)) {
252 pkMap.put(KFSPropertyConstants.FINANCIAL_OBJECT_CODE, objCd);
253 }
254 pkMap.put(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, subObjCd);
255 if(!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(subObjCd) && !checkExistenceFromTable(SubObjectCode.class, pkMap)) {
256 logErrorUtility(KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE, RiceKeyConstants.ERROR_EXISTENCE);
257 success = false;
258 }
259 }
260 return success;
261 }
262
263 public boolean checkExistenceFromTable(Class clazz, Map fieldValues) {
264 return getBoService().countMatching(clazz, fieldValues) != 0;
265 }
266
267 public boolean validateWildcards(IndirectCostRecoveryRateDetail item) {
268 boolean success = false;
269 if(!itemUsesWildcard(item) || (itemUsesWildcard(item) && itemPassesWildcardRules(item))) {
270 success = true;
271 }
272 return success;
273 }
274
275 public boolean itemPassesWildcardRules(IndirectCostRecoveryRateDetail item) {
276 boolean success = false;
277 String[] wildcards = {GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY, GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT};
278
279 success = !itemUsesWildcard(item) || checkWildcardRules(item);
280
281 return success;
282 }
283
284 public boolean itemUsesWildcard(IndirectCostRecoveryRateDetail item) {
285 boolean success = false;
286 String chart = item.getChartOfAccountsCode();
287 String acct = item.getAccountNumber();
288 String subAcct = item.getSubAccountNumber();
289 String objCd = item.getFinancialObjectCode();
290 String subObjCd = item.getFinancialSubObjectCode();
291 String[] fields = {chart,acct,subAcct,objCd,subObjCd};
292
293 for(int i=0;i<fields.length;i++) {
294 success |= propertyIsWildcard(fields[i]);
295 }
296
297 return success;
298 }
299
300 public boolean propertyIsWildcard(String property) {
301 return GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(property) || GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(property);
302 }
303
304 protected boolean checkAccountNumberWildcardRules(IndirectCostRecoveryRateDetail item) {
305 String accountNumber = item.getAccountNumber();
306 boolean success = true;
307 if (!accountNumber.equals(item.getChartOfAccountsCode())) {
308 GlobalVariables.getMessageMap().putError(
309 KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE,
310 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
311 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER),
312 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE)
313 );
314 success = false;
315 }
316
317 String subAccountNumber = item.getSubAccountNumber();
318
319 // If # is entered on account, then # "must" be entered for chart and sub account "must" be dashes.
320 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(accountNumber)) {
321 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(item.getChartOfAccountsCode()) && !StringUtils.containsOnly(subAccountNumber, KFSConstants.DASH)) {
322 GlobalVariables.getMessageMap().putError(
323 KFSPropertyConstants.SUB_ACCOUNT_NUMBER,
324 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_FIELD_MUST_BE_DASHES,
325 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER),
326 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT,
327 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.SUB_ACCOUNT_NUMBER));
328 success = false;
329 }
330 }
331
332 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(accountNumber)) {
333 if (!(StringUtils.equals(GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY, subAccountNumber) || !StringUtils.containsOnly(subAccountNumber, KFSConstants.DASH))) {
334 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.SUB_ACCOUNT_NUMBER,
335 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_ACCOUNT_USE_EXPENDITURE_ENTRY_WILDCARD_RESTRICTION_ON_SUB_ACCOUNT);
336 success = false;
337 }
338 }
339 return success;
340 }
341
342 protected boolean checkAccountNumberNotWildcardRules(IndirectCostRecoveryRateDetail item) {
343 boolean success = true;
344 if (propertyIsWildcard(item.getSubAccountNumber())) {
345 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(item.getSubAccountNumber())) {
346 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.SUB_ACCOUNT_NUMBER, KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_CANNOT_BE_WILDCARD,
347 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.SUB_ACCOUNT_NUMBER),
348 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER));
349 success = false;
350 }
351 }
352 return success;
353 }
354
355 protected boolean checkObjectCodeWildcardRules(IndirectCostRecoveryRateDetail item) {
356 String financialObjectCode = item.getFinancialObjectCode();
357 boolean success = true;
358 if (propertyIsWildcard(financialObjectCode)) {
359 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(financialObjectCode)) {
360 GlobalVariables.getMessageMap().putError(
361 KFSPropertyConstants.FINANCIAL_OBJECT_CODE,
362 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARD_NOT_VALID,
363 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT,
364 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_OBJECT_CODE),
365 GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY
366 );
367 success = false;
368 }
369 else {
370 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getChartOfAccountsCode())) {
371 GlobalVariables.getMessageMap().putError(
372 KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE,
373 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
374 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_OBJECT_CODE),
375 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE)
376 );
377 success = false;
378 }
379 }
380 }
381 return success;
382 }
383
384 protected boolean checkSubObjectWildcardRules(IndirectCostRecoveryRateDetail item) {
385 String financialSubObjectCode = item.getFinancialSubObjectCode();
386 boolean success = true;
387 if (propertyIsWildcard(financialSubObjectCode)) {
388 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(financialSubObjectCode)) {
389 GlobalVariables.getMessageMap().putError(
390 KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE,
391 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARD_NOT_VALID,
392 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT,
393 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE),
394 GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY
395 );
396 success = false;
397 }
398 else {
399 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getChartOfAccountsCode())) {
400 GlobalVariables.getMessageMap().putError(
401 KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE,
402 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
403 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE),
404 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE)
405 );
406 success = false;
407 }
408 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getAccountNumber())) {
409 GlobalVariables.getMessageMap().putError(
410 KFSPropertyConstants.ACCOUNT_NUMBER,
411 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
412 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE),
413 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER)
414 );
415 success = false;
416 }
417 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getFinancialObjectCode())) {
418 GlobalVariables.getMessageMap().putError(
419 KFSPropertyConstants.FINANCIAL_OBJECT_CODE,
420 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
421 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE),
422 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_OBJECT_CODE)
423 );
424 success = false;
425 }
426 }
427 }
428 return success;
429 }
430
431 protected boolean checkSubAccountWildcardRules(IndirectCostRecoveryRateDetail item) {
432 boolean success = true;
433 String subAccountNumber = item.getSubAccountNumber();
434 if (GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT.equals(subAccountNumber)) {
435 GlobalVariables.getMessageMap().putError(
436 KFSPropertyConstants.SUB_ACCOUNT_NUMBER,
437 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARD_NOT_VALID,
438 GeneralLedgerConstants.PosterService.SYMBOL_USE_ICR_FROM_ACCOUNT,
439 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.SUB_ACCOUNT_NUMBER),
440 GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY
441 );
442 success = false;
443 }
444 else {
445 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getChartOfAccountsCode())) {
446 GlobalVariables.getMessageMap().putError(
447 KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE,
448 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
449 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.SUB_ACCOUNT_NUMBER),
450 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE)
451 );
452 success = false;
453 }
454 if (!GeneralLedgerConstants.PosterService.SYMBOL_USE_EXPENDITURE_ENTRY.equals(item.getAccountNumber())) {
455 GlobalVariables.getMessageMap().putError(
456 KFSPropertyConstants.ACCOUNT_NUMBER,
457 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
458 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.SUB_ACCOUNT_NUMBER),
459 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER)
460 );
461 success = false;
462 }
463
464 }
465 return success;
466 }
467
468 /*
469 ** If @ is entered on chart, then @ "must" be entered for account and the sub account "must" be either @ or dashes.
470 ** If @ is entered on account, then @ "must" be entered for chart and "may" be entered for sub account.
471 ** If @ is entered on sub account, then @ "must" be entered for chart and account.
472 ** If @ is entered on object code, then @ "must" be entered for chart and "may" be entered for account, sub account and sub object.
473 * (This rule is the murkiest as enter @ in account, sub account, and sub object kicks of some of the other rules in this section).
474 ** If @ is entered on sub object code, then @ "must" be entered for chart, account, and object code and "may" be entered for sub account.
475
476 ** If # is entered on chart, then # "must" be entered for account and sub account "must" be dashes.
477 ** If # is entered on account, then # "must" be entered for chart and sub account "must" be dashes.
478 ** # can not be entered on the sub account.
479 ** # can not be entered on the object code.
480 ** # can not be entered on the sub object code.
481 *
482 */
483
484 public boolean checkWildcardRules(IndirectCostRecoveryRateDetail item) {
485 boolean success = checkAtMostOneWildcardUsed(item);
486 if (success) {
487 if (propertyIsWildcard(item.getFinancialObjectCode())) {
488 success &= checkObjectCodeWildcardRules(item); // verified
489 }
490 else {
491 }
492 if (propertyIsWildcard(item.getAccountNumber())) {
493 success &= checkAccountNumberWildcardRules(item); // verified
494 }
495 else {
496 success &= checkAccountNumberNotWildcardRules(item);
497 }
498 if (propertyIsWildcard(item.getFinancialSubObjectCode())) {
499 success &= checkSubObjectWildcardRules(item); // verified
500 }
501
502 if (propertyIsWildcard(item.getSubAccountNumber())) {
503 success &= checkSubAccountWildcardRules(item); // verified
504 }
505
506 if (!(propertyIsWildcard(item.getFinancialObjectCode()) || propertyIsWildcard(item.getAccountNumber()))) {
507 // chart code can't be the only wildcard on the item
508 if (success && propertyIsWildcard(item.getChartOfAccountsCode())) {
509 success = false;
510 GlobalVariables.getMessageMap().putError(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_CHART_CODE_NOT_ONLY_WILDCARD,
511 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE),
512 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.ACCOUNT_NUMBER),
513 SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, KFSPropertyConstants.FINANCIAL_OBJECT_CODE));
514 }
515 }
516 }
517 return success;
518 }
519
520 protected boolean checkAtMostOneWildcardUsed(IndirectCostRecoveryRateDetail item) {
521 String chart = item.getChartOfAccountsCode();
522 String acct = item.getAccountNumber();
523 String subAcct = item.getSubAccountNumber();
524 String objCd = item.getFinancialObjectCode();
525 String subObjCd = item.getFinancialSubObjectCode();
526
527 boolean success = true;
528 String errorPropertyName = null;
529
530 Set<String> wildcards = new HashSet<String>();
531 if (propertyIsWildcard(chart)) {
532 wildcards.add(chart);
533 errorPropertyName = KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE;
534 }
535 if (success && propertyIsWildcard(acct)) {
536 wildcards.add(acct);
537 if (wildcards.size() > 1) {
538 success = false;
539 errorPropertyName = KFSPropertyConstants.ACCOUNT_NUMBER;
540 }
541 }
542 if (success && propertyIsWildcard(subAcct)) {
543 wildcards.add(subAcct);
544 if (wildcards.size() > 1) {
545 success = false;
546 errorPropertyName = KFSPropertyConstants.SUB_ACCOUNT_NUMBER;
547 }
548 }
549 if (success && propertyIsWildcard(objCd)) {
550 wildcards.add(objCd);
551 if (wildcards.size() > 1) {
552 success = false;
553 errorPropertyName = KFSPropertyConstants.FINANCIAL_OBJECT_CODE;
554 }
555 }
556 if (success && propertyIsWildcard(subObjCd)) {
557 wildcards.add(subObjCd);
558 if (wildcards.size() > 1) {
559 success = false;
560 errorPropertyName = KFSPropertyConstants.FINANCIAL_SUB_OBJECT_CODE;
561 }
562 }
563
564 if (!success) {
565 GlobalVariables.getMessageMap().putError(
566 errorPropertyName,
567 KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_MULTIPLE_WILDCARDS_ON_ITEM);
568 }
569 return success;
570 }
571
572 public boolean checkRateFormat(IndirectCostRecoveryRateDetail item) {
573 boolean success = true;
574 BigDecimal zero = new BigDecimal(0.00);
575 if(!(item.getAwardIndrCostRcvyRatePct() == null)) {
576 if(item.getAwardIndrCostRcvyRatePct().scale() > 3) {
577 logErrorUtility(KFSPropertyConstants.AWARD_INDR_COST_RCVY_RATE_PCT, KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_RATE_PERCENT_INVALID_FORMAT_SCALE);
578 success = false;
579 }
580 if(item.getAwardIndrCostRcvyRatePct().compareTo(zero) < 0) {
581 logErrorUtility(KFSPropertyConstants.AWARD_INDR_COST_RCVY_RATE_PCT, KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_RATE_PERCENT_INVALID_FORMAT_ZERO);
582 success = false;
583 }
584 } else {
585
586 }
587 return success;
588 }
589
590 public void logErrorUtility(String propertyName, String errorKey) {
591 GlobalVariables.getMessageMap().putError(propertyName, errorKey, SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(IndirectCostRecoveryRateDetail.class, propertyName));
592 }
593
594 }