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.math.BigDecimal;
019: import java.util.HashMap;
020: import java.util.Map;
021:
022: import org.apache.commons.lang.StringUtils;
023: import org.kuali.core.document.MaintenanceDocument;
024: import org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase;
025: import org.kuali.core.service.DataDictionaryService;
026: import org.kuali.core.util.GlobalVariables;
027: import org.kuali.kfs.KFSConstants;
028: import org.kuali.kfs.KFSKeyConstants;
029: import org.kuali.kfs.context.SpringContext;
030: import org.kuali.module.chart.bo.Account;
031: import org.kuali.module.chart.bo.Chart;
032: import org.kuali.module.chart.bo.IcrAutomatedEntry;
033: import org.kuali.module.chart.bo.ObjectCode;
034: import org.kuali.module.chart.bo.SubAccount;
035: import org.kuali.module.chart.bo.SubObjCd;
036:
037: /**
038: * Business rule(s) applicable to IcrAutomatedEntryMaintenance documents.
039: */
040: public class IcrAutomatedEntryRule extends MaintenanceDocumentRuleBase {
041: protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
042: .getLogger(IcrAutomatedEntryRule.class);
043: private IcrAutomatedEntry oldIcrAutomatedEntry;
044: private IcrAutomatedEntry newIcrAutomatedEntry;
045:
046: public IcrAutomatedEntryRule() {
047: super ();
048:
049: }
050:
051: /**
052: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomApproveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
053: */
054: protected boolean processCustomApproveDocumentBusinessRules(
055: MaintenanceDocument document) {
056: boolean success = true;
057:
058: LOG
059: .info("Entering processCustomApproveDocumentBusinessRules()");
060:
061: return success;
062: }
063:
064: /**
065: * Calls custom rules prior to routing document
066: * <ul>
067: * <li>{@link IcrAutomatedEntryRule#checkCorrectWildcards(IcrAutomatedEntry)} </li>
068: * <li>if no wildcards then it verifies that the fields exist in the database</li>
069: * <li>Award Indirect Cost Recovery Rate Percent validation</li>
070: * </ul>
071: *
072: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
073: */
074: protected boolean processCustomRouteDocumentBusinessRules(
075: MaintenanceDocument document) {
076:
077: boolean success = true;
078:
079: LOG.info("Entering processCustomRouteDocumentBusinessRules()");
080:
081: setupConvenienceObjects(document);
082: Integer universityFiscalYear = newIcrAutomatedEntry
083: .getUniversityFiscalYear();
084: String chartOfAccountsCode = newIcrAutomatedEntry
085: .getChartOfAccountsCode();
086: String accountNumber = newIcrAutomatedEntry.getAccountNumber();
087: String subAccountNumber = newIcrAutomatedEntry
088: .getSubAccountNumber();
089: String financialObjectCode = newIcrAutomatedEntry
090: .getFinancialObjectCode();
091: String financialSubObjectCode = newIcrAutomatedEntry
092: .getFinancialSubObjectCode();
093: String offsetBalanceSheetObjectCodeNumber = newIcrAutomatedEntry
094: .getOffsetBalanceSheetObjectCodeNumber();
095: String transactionDebitIndicator = newIcrAutomatedEntry
096: .getTransactionDebitIndicator();
097: BigDecimal awardIndrCostRcvyRatePct = newIcrAutomatedEntry
098: .getAwardIndrCostRcvyRatePct();
099:
100: success &= checkCorrectWildcards(newIcrAutomatedEntry);
101:
102: if (success) {
103: // because of check above, we know that:
104: // if any of these are wildcards: chart, account, or subaccount, then they are all wildcards (except for subaccount,
105: // which may be 3 dashes i.e. KFSConstants.getDashSubAccountNumber()())
106:
107: Class icrClazz = newIcrAutomatedEntry.getClass();
108:
109: // Chart Code Rule
110: if (chartOfAccountsCode != null) {
111: if (isWildcard(chartOfAccountsCode)) {
112:
113: } else {
114: // there should be no wildcards if the code gets in there, so we should not have to worry about removing
115: // wildcards from pkMap
116: Map pkMap = new HashMap();
117: pkMap
118: .put(
119: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
120: chartOfAccountsCode);
121: success &= checkExistenceFromTable(
122: Chart.class,
123: pkMap,
124: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
125: SpringContext
126: .getBean(
127: DataDictionaryService.class)
128: .getAttributeLabel(
129: icrClazz,
130: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME));
131: }
132: }
133:
134: // Account Number Rule
135: if (accountNumber != null) {
136: if (isWildcard(accountNumber)) {
137:
138: } else {
139: // there should be no wildcards if the code gets in there, so we should not have to worry about removing
140: // wildcards from pkMap
141: Map pkMap = new HashMap();
142: pkMap.put(
143: KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME,
144: accountNumber);
145: pkMap
146: .put(
147: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
148: chartOfAccountsCode);
149: success &= checkExistenceFromTable(
150: Account.class,
151: pkMap,
152: KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME,
153: SpringContext
154: .getBean(
155: DataDictionaryService.class)
156: .getAttributeLabel(
157: icrClazz,
158: KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME));
159: }
160: }
161:
162: // Sub-Account Number Rule
163: if (subAccountNumber != null) {
164: // checkCorrectWildcards makes sure that the wildcard is appropriate for the sub account number
165: // we allow any string of only dashes to be a valid value for the sub acct, but to bypass validation, it must be
166: // equal to KFSConstants.getDashSubAccountNumber()()
167: if (isWildcard(subAccountNumber)
168: || StringUtils.equals(subAccountNumber,
169: KFSConstants.getDashSubAccountNumber())) {
170:
171: } else {
172: // there should be no wildcards if the code gets in there, so we should not have to worry about removing
173: // wildcards from pkMap
174: Map pkMap = new HashMap();
175: pkMap
176: .put(
177: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
178: chartOfAccountsCode);
179: pkMap.put(
180: KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME,
181: accountNumber);
182: pkMap
183: .put(
184: KFSConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME,
185: subAccountNumber);
186: success &= checkExistenceFromTable(
187: SubAccount.class,
188: pkMap,
189: KFSConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME,
190: SpringContext
191: .getBean(
192: DataDictionaryService.class)
193: .getAttributeLabel(
194: icrClazz,
195: KFSConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME));
196: }
197: }
198:
199: // Financial ObjectCode Rule
200: if (financialObjectCode != null) {
201: if (isWildcard(financialObjectCode)) {
202:
203: } else {
204: // COA code could be a wildcard so, we have to check if its a wildcard or not before we add it to the map.
205: Map pkMap = new HashMap();
206: pkMap
207: .put(
208: KFSConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME,
209: universityFiscalYear);
210: if (!isWildcard(chartOfAccountsCode)) {
211: pkMap
212: .put(
213: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
214: chartOfAccountsCode);
215: }
216: pkMap
217: .put(
218: KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME,
219: financialObjectCode);
220: success &= checkExistenceFromTable(
221: ObjectCode.class,
222: pkMap,
223: KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME,
224: SpringContext
225: .getBean(
226: DataDictionaryService.class)
227: .getAttributeLabel(
228: icrClazz,
229: KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME));
230: }
231: }
232:
233: // Financial SubObjectCode Rule
234: if (financialSubObjectCode != null) {
235: // we allow any string of only dashes to be a valid value for the sub object, but to bypass validation, it must be
236: // equal to KFSConstants.getDashFinancialSubObjectCode()
237: if (isWildcard(financialSubObjectCode)
238: || StringUtils
239: .equals(
240: financialSubObjectCode,
241: KFSConstants
242: .getDashFinancialSubObjectCode())) {
243:
244: } else {
245: // COA code and account number could be wildcards so, we have to check if its a wildcard or not before we add it
246: // to the map.
247: Map pkMap = new HashMap();
248: pkMap
249: .put(
250: KFSConstants.UNIVERSITY_FISCAL_YEAR_PROPERTY_NAME,
251: universityFiscalYear);
252: if (!isWildcard(chartOfAccountsCode)) {
253: pkMap
254: .put(
255: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
256: chartOfAccountsCode);
257: }
258: if (!isWildcard(accountNumber)) {
259: pkMap
260: .put(
261: KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME,
262: accountNumber);
263: }
264: pkMap
265: .put(
266: KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME,
267: financialObjectCode);
268: pkMap
269: .put(
270: KFSConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME,
271: financialSubObjectCode);
272: success = checkExistenceFromTable(
273: SubObjCd.class,
274: pkMap,
275: KFSConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME,
276: SpringContext
277: .getBean(
278: DataDictionaryService.class)
279: .getAttributeLabel(
280: icrClazz,
281: KFSConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME));
282: }
283: }
284: }
285:
286: // TODO Offset Balance Sheet Object Code Rule
287: // It should exist in the Object Code table.
288: // Note: There are currently records in the test database where ( Chart Code = "@" or "#")
289: // and Offset Balance Sheet Object Code is a number like "8000".
290: // It is not clear how we validate the Offset Balance Sheet Object Code in this case
291: // since we don't have a real Chart Code.
292:
293: // Transaction Debit Indicator Rule: It was checked in some place.
294: if (transactionDebitIndicator != null) {
295: if (StringUtils.contains(transactionDebitIndicator, "D")
296: || StringUtils.contains(transactionDebitIndicator,
297: "C")) {
298:
299: }
300:
301: }
302:
303: // Award Indirect Cost Recovery Rate Percent
304: if (awardIndrCostRcvyRatePct != null) {
305: if (awardIndrCostRcvyRatePct.doubleValue() < 0.00) {
306: putFieldError("awardIndrCostRcvyRatePct",
307: KFSKeyConstants.ERROR_INVALIDNEGATIVEAMOUNT,
308: "ICR Percent");
309: success = false;
310: } else if (awardIndrCostRcvyRatePct.scale() > 3) {
311: putFieldError("awardIndrCostRcvyRatePct",
312: KFSKeyConstants.ERROR_INVALID_FORMAT,
313: new String[] { "ICR Percent",
314: awardIndrCostRcvyRatePct.toString() });
315: success = false;
316: }
317: }
318:
319: return success;
320: }
321:
322: /**
323: * Normally this method calls any custom save rules, but this does not (right now)
324: *
325: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
326: */
327: protected boolean processCustomSaveDocumentBusinessRules(
328: MaintenanceDocument document) {
329:
330: boolean success = true;
331:
332: LOG.info("Entering processCustomSaveDocumentBusinessRules()");
333:
334: return success;
335: }
336:
337: /**
338: * This method sets the convenience objects like newIcrAutomatedEntry and oldIcrAutomatedEntry, so you have short and easy
339: * handles to the new and old objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(),
340: * which will attempt to load all sub-objects from the DB by their primary keys, if available.
341: */
342: public void setupConvenienceObjects(MaintenanceDocument document) {
343:
344: // setup oldICRAutomatedEntry convenience objects, make sure all possible sub-objects are populated
345: oldIcrAutomatedEntry = (IcrAutomatedEntry) super .getOldBo();
346:
347: // setup newICRAutomatedEntry convenience objects, make sure all possible sub-objects are populated
348: newIcrAutomatedEntry = (IcrAutomatedEntry) super .getNewBo();
349: }
350:
351: /**
352: * This checks the existence of each field from table.
353: *
354: * @param clazz
355: * @param fieldValues
356: * @param errorField
357: * @param errorMessage
358: * @return true if there exists more than one record that matches
359: */
360: private boolean checkExistenceFromTable(Class clazz,
361: Map fieldValues, String errorField, String errorMessage) {
362: boolean success = true;
363: success = getBoService().countMatching(clazz, fieldValues) != 0;
364: if (!success) {
365: GlobalVariables.getErrorMap().putErrorWithoutFullErrorPath(
366: KFSConstants.MAINTENANCE_NEW_MAINTAINABLE
367: + errorField,
368: KFSKeyConstants.ERROR_EXISTENCE, errorMessage);
369: }
370: return success;
371: }
372:
373: /**
374: * This checks to see if the correct wildcards are being used
375: * <ul>
376: * <li>"@" should be valid for chart, account, sub account.</li>
377: * <li>"#" should be valid for chart, account, sub account. </li>
378: * </ul>
379: *
380: * @param newIcrAutomatedEntry
381: * @return true if they are valid wildcards
382: */
383: protected boolean checkCorrectWildcards(
384: IcrAutomatedEntry newIcrAutomatedEntry) {
385: String chartOfAccountsCode = newIcrAutomatedEntry
386: .getChartOfAccountsCode();
387: String accountNumber = newIcrAutomatedEntry.getAccountNumber();
388: String subAccountNumber = newIcrAutomatedEntry
389: .getSubAccountNumber();
390: String financialObjectCode = newIcrAutomatedEntry
391: .getFinancialObjectCode();
392: String financialSubObjectCode = newIcrAutomatedEntry
393: .getFinancialSubObjectCode();
394:
395: boolean success = true;
396:
397: // first check that each of the above fields has an appropriate wildcard/field value
398: // @ should be valid for chart, account, sub account.
399: // # should be valid for chart, account, sub account.
400:
401: // TODO: make these into app parameters?
402: success &= isValidWildcard(newIcrAutomatedEntry,
403: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
404: chartOfAccountsCode, "@", "#");
405: success &= isValidWildcard(newIcrAutomatedEntry,
406: KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME,
407: accountNumber, "@", "#");
408: if (!StringUtils.containsOnly(subAccountNumber, "-")) {
409: success &= isValidWildcard(newIcrAutomatedEntry,
410: KFSConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME,
411: subAccountNumber, "@", "#");
412: }
413:
414: // second, check that object code and sub object code do not have wildcards
415: if (isWildcard(financialObjectCode)) {
416: putFieldError(
417: KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME,
418: KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_FIELD_MUST_NOT_BE_WILDCARD,
419: new String[] { SpringContext
420: .getBean(DataDictionaryService.class)
421: .getAttributeLabel(
422: newIcrAutomatedEntry.getClass(),
423: KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME) });
424: success &= false;
425: }
426:
427: if (isWildcard(financialSubObjectCode)) {
428: putFieldError(
429: KFSConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME,
430: KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_FIELD_MUST_NOT_BE_WILDCARD,
431: new String[] { SpringContext
432: .getBean(DataDictionaryService.class)
433: .getAttributeLabel(
434: newIcrAutomatedEntry.getClass(),
435: KFSConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME) });
436: success &= false;
437: }
438:
439: if (!success) {
440: // invalid wildcards, don't bother validating the rest
441: return false;
442: }
443:
444: success &= checkWildcardsForChartAccountSubAccount(newIcrAutomatedEntry);
445:
446: return success;
447:
448: }
449:
450: /**
451: * This checks to see if this is a valid wildcard character the user is attempting to use
452: *
453: * @param newIcrAutomatedEntry
454: * @param fieldName
455: * @param fieldValue
456: * @param allowedWildcards
457: * @return true if it is an allowed wildcard and generates an appropriate error message for the user otherwise
458: */
459: private boolean isValidWildcard(
460: IcrAutomatedEntry newIcrAutomatedEntry, String fieldName,
461: String fieldValue, String... allowedWildcards) {
462: if (!StringUtils.isBlank(fieldValue)) {
463: if (!StringUtils.isAlphanumeric(fieldValue)) {
464: for (String wildcard : allowedWildcards) {
465: if (wildcard.equals(fieldValue)) {
466: // wildcard validation passed
467: return true;
468: }
469: }
470: if (StringUtils.containsOnly(fieldValue, "-")
471: && (StringUtils
472: .equals(
473: KFSConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME,
474: fieldName) || StringUtils
475: .equals(
476: KFSConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME,
477: fieldName))) {
478: return true;
479: }
480: // validation didn't pass against allowed list of wildcards
481: putInvalidWildcardError(newIcrAutomatedEntry,
482: fieldName, allowedWildcards);
483: return false;
484: }
485: }
486: return true;
487: }
488:
489: /**
490: * This builds up a string of allowed wildcards and sticks in the error message
491: *
492: * @param instance
493: * @param fieldName
494: * @param allowedWildcards
495: */
496: private void putInvalidWildcardError(IcrAutomatedEntry instance,
497: String fieldName, String... allowedWildcards) {
498: StringBuilder sb = new StringBuilder();
499: // build a human readable string listing all the possible values for the allowed values string.
500: for (int i = 0; i < allowedWildcards.length; i++) {
501: if (i == 0) {
502: sb.append(allowedWildcards[i]);
503: } else if (i == allowedWildcards.length - 1) {
504: // last element
505: // if there are 2 elements, then no comma (e.g. A or B), but if there are more than 2, than we need a comma (e.g. A,
506: // B, or C)
507: sb.append(i == 1 ? "" : ",").append(" or ").append(
508: allowedWildcards[i]);
509: } else {
510: sb.append(", ").append(allowedWildcards[i]);
511: }
512: }
513: putFieldError(
514: fieldName,
515: KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_INVALID_WILDCARD,
516: new String[] {
517: SpringContext.getBean(
518: DataDictionaryService.class)
519: .getAttributeLabel(instance.getClass(),
520: fieldName), sb.toString() });
521: }
522:
523: /**
524: * Checks whether if at least one of these attributes has a wildcard, that they all have a wildcard: chart, account, and
525: * subaccount
526: *
527: * @param chartOfAccountsCode
528: * @param accountNumber
529: * @param subAccountNumber
530: * @return
531: */
532: protected boolean checkWildcardsForChartAccountSubAccount(
533: IcrAutomatedEntry icrAutomatedEntry) {
534: String chartOfAccountsCode = icrAutomatedEntry
535: .getChartOfAccountsCode();
536: String accountNumber = icrAutomatedEntry.getAccountNumber();
537: String subAccountNumber = icrAutomatedEntry
538: .getSubAccountNumber();
539:
540: if (isWildcard(chartOfAccountsCode)
541: || isWildcard(accountNumber)
542: || isWildcard(subAccountNumber)) {
543: // these should never be null
544: // chart needs same wildcard as account, and if chart is wildcard, then then subaccount must be the same wildcard or
545: // dashes
546: boolean success = chartOfAccountsCode.equals(accountNumber)
547: && (chartOfAccountsCode.equals(subAccountNumber) || StringUtils
548: .containsOnly(subAccountNumber, "-"));
549: if (!success) {
550: String chartDesc = SpringContext
551: .getBean(DataDictionaryService.class)
552: .getAttributeLabel(
553: icrAutomatedEntry.getClass(),
554: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME);
555: String accountDesc = SpringContext.getBean(
556: DataDictionaryService.class).getAttributeLabel(
557: icrAutomatedEntry.getClass(),
558: KFSConstants.ACCOUNT_NUMBER_PROPERTY_NAME);
559: String subAccountDesc = SpringContext.getBean(
560: DataDictionaryService.class).getAttributeLabel(
561: icrAutomatedEntry.getClass(),
562: KFSConstants.SUB_ACCOUNT_NUMBER_PROPERTY_NAME);
563:
564: String groupDesc = chartDesc + ", " + accountDesc
565: + ", and " + subAccountDesc;
566: GlobalVariables
567: .getErrorMap()
568: .putErrorWithoutFullErrorPath(
569: KFSConstants.MAINTENANCE_NEW_MAINTAINABLE
570: + KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
571: KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
572: new String[] { groupDesc,
573: subAccountDesc });
574: }
575: return success;
576: }
577: // if no wildcards in this group, then this check is fine
578: return true;
579: }
580:
581: /**
582: * Checks whether if at least one of these attributes has a wildcard, that they all have a wildcard: chart, object, and
583: * subobject
584: *
585: * @param chartOfAccountsCode
586: * @param financialObjectCode
587: * @param financialSubObjectCode
588: * @return
589: */
590: protected boolean checkWildcardsForChartObjectSubObject(
591: IcrAutomatedEntry icrAutomatedEntry) {
592: String chartOfAccountsCode = icrAutomatedEntry
593: .getChartOfAccountsCode();
594: String financialObjectCode = icrAutomatedEntry
595: .getFinancialObjectCode();
596: String financialSubObjectCode = icrAutomatedEntry
597: .getFinancialSubObjectCode();
598:
599: if (isWildcard(chartOfAccountsCode)
600: || isWildcard(financialObjectCode)
601: || isWildcard(financialSubObjectCode)) {
602: // these should never be null
603: boolean success = chartOfAccountsCode
604: .equals(financialObjectCode)
605: && (chartOfAccountsCode
606: .equals(financialSubObjectCode) || StringUtils
607: .containsOnly(financialSubObjectCode, "-"));
608: if (!success) {
609: String chartDesc = SpringContext
610: .getBean(DataDictionaryService.class)
611: .getAttributeLabel(
612: icrAutomatedEntry.getClass(),
613: KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME);
614: String objectDesc = SpringContext
615: .getBean(DataDictionaryService.class)
616: .getAttributeLabel(
617: icrAutomatedEntry.getClass(),
618: KFSConstants.FINANCIAL_OBJECT_CODE_PROPERTY_NAME);
619: String subObjectDesc = SpringContext
620: .getBean(DataDictionaryService.class)
621: .getAttributeLabel(
622: icrAutomatedEntry.getClass(),
623: KFSConstants.FINANCIAL_SUB_OBJECT_CODE_PROPERTY_NAME);
624:
625: String groupDesc = chartDesc + ", " + objectDesc
626: + ", and " + subObjectDesc;
627: GlobalVariables
628: .getErrorMap()
629: .putErrorWithoutFullErrorPath(
630: KFSConstants.MAINTENANCE_NEW_MAINTAINABLE
631: + KFSConstants.CHART_OF_ACCOUNTS_CODE_PROPERTY_NAME,
632: KFSKeyConstants.IndirectCostRecovery.ERROR_DOCUMENT_ICR_WILDCARDS_MUST_MATCH,
633: new String[] { groupDesc, subObjectDesc });
634: }
635: return success;
636: }
637: // if no wildcards in this group, then this check is fine
638: return true;
639: }
640:
641: protected boolean isWildcard(String fieldValue) {
642: return StringUtils.equals(fieldValue, "@")
643: || StringUtils.equals(fieldValue, "#");
644: }
645: }
|