001: /*
002: * Copyright 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.bo.PersistableBusinessObject;
022: import org.kuali.core.bo.user.UniversalUser;
023: import org.kuali.core.document.MaintenanceDocument;
024: import org.kuali.core.util.GlobalVariables;
025: import org.kuali.core.util.KualiDecimal;
026: import org.kuali.core.util.ObjectUtils;
027: import org.kuali.kfs.KFSConstants;
028: import org.kuali.kfs.KFSKeyConstants;
029: import org.kuali.kfs.KFSPropertyConstants;
030: import org.kuali.kfs.context.SpringContext;
031: import org.kuali.kfs.service.ParameterService;
032: import org.kuali.module.chart.bo.AccountGlobalDetail;
033: import org.kuali.module.chart.bo.Delegate;
034: import org.kuali.module.chart.bo.DelegateGlobal;
035: import org.kuali.module.chart.bo.DelegateGlobalDetail;
036:
037: /**
038: * This class executes specific rules for the {@link DelegateGlobalMaintenanceDocument}
039: */
040: public class DelegateGlobalRule extends GlobalDocumentRuleBase {
041:
042: protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
043: .getLogger(DelegateGlobalRule.class);
044:
045: private static final KualiDecimal ZERO = new KualiDecimal(0);
046: private DelegateGlobal newDelegateGlobal;
047: private static final String DELEGATE_GLOBALS_PREFIX = "delegateGlobals";
048:
049: public DelegateGlobalRule() {
050: super ();
051: }
052:
053: /**
054: * This method sets the convenience objects like newAccount and oldAccount, so you have short and easy handles to the new and
055: * old objects contained in the maintenance document. It also calls the BusinessObjectBase.refresh(), which will attempt to load
056: * all sub-objects from the DB by their primary keys, if available.
057: */
058: @Override
059: public void setupConvenienceObjects() {
060:
061: // setup newDelegateGlobal convenience objects,
062: // make sure all possible sub-objects are populated
063: newDelegateGlobal = (DelegateGlobal) super .getNewBo();
064:
065: // forces refreshes on all the sub-objects in the lists
066: for (DelegateGlobalDetail delegateGlobal : newDelegateGlobal
067: .getDelegateGlobals()) {
068: delegateGlobal.refreshNonUpdateableReferences();
069: }
070: for (AccountGlobalDetail accountGlobalDetail : newDelegateGlobal
071: .getAccountGlobalDetails()) {
072: accountGlobalDetail.refreshNonUpdateableReferences();
073: }
074: }
075:
076: /**
077: * This checks some basic rules for document approval Specifically it calls the following:
078: * <ul>
079: * <li>{@link DelegateGlobalRule#checkSimpleRulesAllLines()}</li>
080: * <li>{@link DelegateGlobalRule#checkOnlyOneChartErrorWrapper(List)}</li>
081: * <li>{@link DelegateGlobalRule#checkForPrimaryDelegateAllLines()}</li>
082: * </ul>
083: * fails if any rules fail
084: *
085: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomApproveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
086: */
087: @Override
088: protected boolean processCustomApproveDocumentBusinessRules(
089: MaintenanceDocument document) {
090: boolean success = true;
091: setupConvenienceObjects();
092: // check simple rules
093: success &= checkSimpleRulesAllLines();
094:
095: success &= checkOnlyOneChartErrorWrapper(newDelegateGlobal
096: .getAccountGlobalDetails());
097:
098: // check for primary routing
099: success &= checkForPrimaryDelegateAllLines();
100: return success;
101: }
102:
103: /**
104: * This checks some basic rules for document routing Specifically it calls the following:
105: * <ul>
106: * <li>{@link DelegateGlobalRule#checkSimpleRulesAllLines()}</li>
107: * <li>{@link DelegateGlobalRule#checkAccountDetails(List)}</li>
108: * <li>{@link DelegateGlobalRule#checkForPrimaryDelegateAllLines()}</li>
109: * </ul>
110: * fails if any rules fail
111: *
112: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
113: */
114: @Override
115: protected boolean processCustomRouteDocumentBusinessRules(
116: MaintenanceDocument document) {
117: boolean success = true;
118: setupConvenienceObjects();
119: // check simple rules
120: success &= checkSimpleRulesAllLines();
121:
122: success &= checkAccountDetails(newDelegateGlobal
123: .getAccountGlobalDetails());
124:
125: // check for primary routing
126: success &= checkForPrimaryDelegateAllLines();
127: return success;
128: }
129:
130: /**
131: * This checks some basic rules for document saving Specifically it calls the following:
132: * <ul>
133: * <li>{@link DelegateGlobalRule#checkSimpleRulesAllLines()}</li>
134: * <li>{@link DelegateGlobalRule#checkOnlyOneChartErrorWrapper(List)}</li>
135: * <li>{@link DelegateGlobalRule#checkForPrimaryDelegateAllLines()}</li>
136: * </ul>
137: * fails if any rules fail
138: *
139: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.core.document.MaintenanceDocument)
140: */
141: @Override
142: protected boolean processCustomSaveDocumentBusinessRules(
143: MaintenanceDocument document) {
144: setupConvenienceObjects();
145: // check simple rules
146: checkSimpleRulesAllLines();
147:
148: checkOnlyOneChartErrorWrapper(newDelegateGlobal
149: .getAccountGlobalDetails());
150:
151: // check for primary routing
152: checkForPrimaryDelegateAllLines();
153: return true;
154: }
155:
156: /**
157: * This checks to see if there are any accounts in the details collection if there are then it calls
158: * {@link DelegateGlobalRule#checkAccountDetails(AccountGlobalDetail)}
159: *
160: * @param details - collection of {@link AccountGlobalDetail}s
161: * @return false if there are no objects in the collection or any one of the {@link AccountGlobalDetail} fail
162: */
163: public boolean checkAccountDetails(List<AccountGlobalDetail> details) {
164: boolean success = true;
165:
166: // check if there are any accounts
167: if (details.size() == 0) {
168: putFieldError(
169: KFSConstants.MAINTENANCE_ADD_PREFIX
170: + "accountGlobalDetails.accountNumber",
171: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_NO_ACCOUNTS);
172: success = false;
173: } else {
174: // check each account
175: int index = 0;
176: for (AccountGlobalDetail dtl : details) {
177: String errorPath = MAINTAINABLE_ERROR_PREFIX
178: + "accountGlobalDetails[" + index + "]";
179: GlobalVariables.getErrorMap().addToErrorPath(errorPath);
180: success &= checkAccountDetails(dtl);
181: GlobalVariables.getErrorMap().removeFromErrorPath(
182: errorPath);
183: index++;
184: }
185: success &= checkOnlyOneChartErrorWrapper(details);
186: }
187:
188: return success;
189: }
190:
191: /**
192: * This checks to make sure that each {@link AccountGlobalDetail} has a valid {@link Account}
193: *
194: * @param dtl - the {@link AccountGlobalDetail}
195: * @return false if it does not have a valid {@link Account}
196: */
197: public boolean checkAccountDetails(AccountGlobalDetail dtl) {
198: boolean success = true;
199: int originalErrorCount = GlobalVariables.getErrorMap()
200: .getErrorCount();
201: getDictionaryValidationService().validateBusinessObject(dtl);
202: if (StringUtils.isNotBlank(dtl.getAccountNumber())
203: && StringUtils.isNotBlank(dtl.getChartOfAccountsCode())) {
204: dtl.refreshReferenceObject("account");
205: if (dtl.getAccount() == null) {
206: GlobalVariables
207: .getErrorMap()
208: .putError(
209: "accountNumber",
210: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_ACCOUNT_INVALID_ACCOUNT,
211: new String[] {
212: dtl.getChartOfAccountsCode(),
213: dtl.getAccountNumber() });
214: }
215: }
216: success &= GlobalVariables.getErrorMap().getErrorCount() == originalErrorCount;
217:
218: return success;
219: }
220:
221: /**
222: * This method checks the simple rules for all lines at once and gets called on save, submit, etc. but not on add Specifically
223: * it calls the following:
224: * <ul>
225: * <li>{@link DelegateGlobalRule#checkDelegateUserRules(DelegateGlobalDetail, int, boolean)}</li>
226: * <li>{@link DelegateGlobalRule#checkDelegateForNullToAmount(KualiDecimal, KualiDecimal, int, boolean)}</li>
227: * <li>{@link DelegateGlobalRule#checkDelegateToAmtGreaterThanFromAmt(KualiDecimal, KualiDecimal, int, boolean)}</li>
228: * <li>{@link DelegateGlobalRule#checkDelegateFromAmtGreaterThanEqualZero(KualiDecimal, int, boolean)}</li>
229: * <li>{@link DelegateGlobalRule#checkPrimaryRouteRules(List, DelegateGlobalDetail, Integer, boolean)}</li>
230: * </ul>
231: *
232: * @return
233: */
234: protected boolean checkSimpleRulesAllLines() {
235:
236: boolean success = true;
237: // check if there are any accounts
238: if (newDelegateGlobal.getDelegateGlobals().size() == 0) {
239: putFieldError(
240: KFSConstants.MAINTENANCE_ADD_PREFIX
241: + KFSPropertyConstants.DELEGATE_GLOBALS
242: + "."
243: + KFSPropertyConstants.FINANCIAL_DOCUMENT_TYPE_CODE,
244: KFSKeyConstants.ERROR_DOCUMENT_DELEGATE_CHANGE_NO_DELEGATE);
245: success = false;
246: } else {
247: // check each delegate
248: int i = 0;
249: for (DelegateGlobalDetail newDelegateGlobalDetail : newDelegateGlobal
250: .getDelegateGlobals()) {
251: KualiDecimal fromAmount = newDelegateGlobalDetail
252: .getApprovalFromThisAmount();
253: KualiDecimal toAmount = newDelegateGlobalDetail
254: .getApprovalToThisAmount();
255:
256: success &= checkDelegateUserRules(
257: newDelegateGlobalDetail, i, false);
258:
259: // FROM amount must be >= 0 (may not be negative)
260: success &= checkDelegateFromAmtGreaterThanEqualZero(
261: fromAmount, i, false);
262:
263: // to amount cannot be null if from amount is valid
264: success &= checkDelegateForNullToAmount(fromAmount,
265: toAmount, i, false);
266:
267: // TO amount must be >= FROM amount or Zero
268: success &= checkDelegateToAmtGreaterThanFromAmt(
269: fromAmount, toAmount, i, false);
270:
271: // increment counter for delegate changes list
272: i++;
273: }
274: }
275: return success;
276: }
277:
278: /**
279: * This method will check through each delegate referenced in the DelegateGlobal to ensure that there is one and only primary
280: * for each account and doctype
281: *
282: * @return false if there is more than one primary delegate
283: */
284: protected boolean checkForPrimaryDelegateAllLines() {
285: boolean success = true;
286: int i = 0;
287: for (DelegateGlobalDetail newDelegateGlobalDetail : newDelegateGlobal
288: .getDelegateGlobals()) {
289: success &= checkPrimaryRouteRules(newDelegateGlobal
290: .getDelegateGlobals(), newDelegateGlobalDetail,
291: new Integer(i), false);
292: i++;
293: }
294: return success;
295: }
296:
297: /**
298: * This method checks to see if the from amount is greater than zero
299: *
300: * @param fromAmount
301: * @param lineNum
302: * @return false if from amount less than zero
303: */
304: protected boolean checkDelegateFromAmtGreaterThanEqualZero(
305: KualiDecimal fromAmount, int lineNum, boolean add) {
306: boolean success = true;
307: if (ObjectUtils.isNotNull(fromAmount)) {
308: if (fromAmount.isLessThan(ZERO)) {
309: String errorPath = KFSConstants.EMPTY_STRING;
310: if (add) {
311: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
312: + DELEGATE_GLOBALS_PREFIX + "."
313: + "approvalFromThisAmount";
314: putFieldError(
315: errorPath,
316: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_FROM_AMOUNT_NONNEGATIVE);
317: } else {
318: errorPath = DELEGATE_GLOBALS_PREFIX + "[" + lineNum
319: + "]." + "approvalFromThisAmount";
320: putFieldError(
321: errorPath,
322: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_FROM_AMOUNT_NONNEGATIVE);
323: }
324: success &= false;
325: }
326: }
327: return success;
328: }
329:
330: /**
331: * This method checks to see if the from amount is not null and the to amount is null
332: *
333: * @param fromAmount
334: * @param toAmount
335: * @param lineNum
336: * @return false if from amount valid and to amount are null
337: */
338: protected boolean checkDelegateForNullToAmount(
339: KualiDecimal fromAmount, KualiDecimal toAmount,
340: int lineNum, boolean add) {
341: boolean success = true;
342: if (ObjectUtils.isNotNull(fromAmount)
343: && ObjectUtils.isNull(toAmount)) {
344: String errorPath = KFSConstants.EMPTY_STRING;
345: if (add) {
346: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
347: + DELEGATE_GLOBALS_PREFIX + "."
348: + "approvalToThisAmount";
349: putFieldError(
350: errorPath,
351: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_TO_AMOUNT_MORE_THAN_FROM_OR_ZERO);
352: } else {
353: errorPath = DELEGATE_GLOBALS_PREFIX + "[" + lineNum
354: + "]." + "approvalToThisAmount";
355: putFieldError(
356: errorPath,
357: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_TO_AMOUNT_MORE_THAN_FROM_OR_ZERO);
358: }
359: success &= false;
360: }
361: return success;
362: }
363:
364: /**
365: * This method checks to see if the to Amount is greater than the from amount
366: *
367: * @param fromAmount
368: * @param toAmount
369: * @param lineNum
370: * @return false if to amount less than from amount
371: */
372: protected boolean checkDelegateToAmtGreaterThanFromAmt(
373: KualiDecimal fromAmount, KualiDecimal toAmount,
374: int lineNum, boolean add) {
375: boolean success = true;
376: if (ObjectUtils.isNotNull(toAmount)) {
377:
378: if (ObjectUtils.isNull(fromAmount)) {
379: // case if FROM amount is null and TO amount not null then TO amount must be zero
380: if (!toAmount.equals(ZERO)) {
381: String errorPath = KFSConstants.EMPTY_STRING;
382: if (add) {
383: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
384: + DELEGATE_GLOBALS_PREFIX + "."
385: + "approvalToThisAmount";
386: putFieldError(
387: errorPath,
388: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_TO_AMOUNT_MORE_THAN_FROM_OR_ZERO);
389: } else {
390: errorPath = DELEGATE_GLOBALS_PREFIX + "["
391: + lineNum + "]."
392: + "approvalToThisAmount";
393:
394: putFieldError(
395: errorPath,
396: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_TO_AMOUNT_MORE_THAN_FROM_OR_ZERO);
397: }
398: success &= false;
399: }
400: } else {
401: // case if FROM amount is non-null and positive, disallow TO amount being less if it is not ZERO (another indicator
402: // of infinity)
403: if (!toAmount.equals(ZERO)
404: && toAmount.isLessThan(fromAmount)) {
405: String errorPath = KFSConstants.EMPTY_STRING;
406: if (add) {
407: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
408: + DELEGATE_GLOBALS_PREFIX + "."
409: + "approvalToThisAmount";
410: putFieldError(
411: errorPath,
412: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_TO_AMOUNT_MORE_THAN_FROM_OR_ZERO);
413: } else {
414: errorPath = DELEGATE_GLOBALS_PREFIX + "["
415: + lineNum + "]."
416: + "approvalToThisAmount";
417: putFieldError(
418: errorPath,
419: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_TO_AMOUNT_MORE_THAN_FROM_OR_ZERO);
420: }
421: success &= false;
422: }
423: }
424: }
425: return success;
426: }
427:
428: /**
429: * This method validates the rule that says there can be only one PrimaryRoute delegate on a Global Delegate document if the
430: * docType is ALL. It checks the delegateGlobalToTest against the list, to determine whether adding this new
431: * delegateGlobalToTest would violate any PrimaryRoute business rule violations. If any of the incoming variables is null or
432: * empty, the method will do nothing, and return Null. It will only process the business rules if there is sufficient data to do
433: * so.
434: *
435: * @param delegateGlobalToTest A delegateGlobal line that you want to test agains the list.
436: * @param delegateGlobals A List of delegateGlobal items that is being tested against.
437: * @return Null if the business rule passes, or an Integer value greater than zero, representing the line that the new line is
438: * conflicting with
439: */
440: protected Integer checkPrimaryRouteOnlyAllowOneAllDocType(
441: DelegateGlobalDetail delegateGlobalToTest,
442: List<DelegateGlobalDetail> delegateGlobals,
443: Integer testLineNum) {
444:
445: // exit immediately if the adding line isnt both Primary and ALL docTypes
446: if (delegateGlobalToTest == null || delegateGlobals == null
447: || delegateGlobals.isEmpty()) {
448: return null;
449: }
450: if (!delegateGlobalToTest
451: .getAccountDelegatePrimaryRoutingIndicator()) {
452: return null;
453: }
454: if (!"ALL".equalsIgnoreCase(delegateGlobalToTest
455: .getFinancialDocumentTypeCode())) {
456: return null;
457: }
458:
459: // at this point, the delegateGlobal being added is a Primary for ALL docTypes, so we need to
460: // test whether any in the existing list are also Primary, regardless of docType
461: DelegateGlobalDetail delegateGlobal = null;
462: for (int lineNumber = 0; lineNumber < delegateGlobals.size(); lineNumber++) {
463: delegateGlobal = delegateGlobals.get(lineNumber);
464: if (delegateGlobal
465: .getAccountDelegatePrimaryRoutingIndicator()) {
466: if (testLineNum == null) {
467: return new Integer(lineNumber);
468: } else if (!(testLineNum.intValue() == lineNumber)) {
469: return new Integer(lineNumber);
470: }
471: }
472: }
473:
474: return null;
475: }
476:
477: /**
478: * This method validates the rule that says there can be only one PrimaryRoute delegate for each given docType. It checks the
479: * delegateGlobalToTest against the list, to determine whether adding this new delegateGlobalToTest would violate any
480: * PrimaryRoute business rule violations. If any of the incoming variables is null or empty, the method will do nothing, and
481: * return Null. It will only process the business rules if there is sufficient data to do so.
482: *
483: * @param delegateGlobalToTest A delegateGlobal line that you want to test against the list.
484: * @param delegateGlobals A List of delegateGlobal items that is being tested against.
485: * @return Null if the business rule passes, or an Integer value greater than zero, representing the line that the new line is
486: * conflicting with
487: */
488: protected Integer checkPrimaryRoutePerDocType(
489: DelegateGlobalDetail delegateGlobalToTest,
490: List<DelegateGlobalDetail> delegateGlobals,
491: Integer testLineNum) {
492:
493: // exit immediately if the adding line isnt a Primary routing
494: if (delegateGlobalToTest == null || delegateGlobals == null
495: || delegateGlobals.isEmpty()) {
496: return null;
497: }
498: if (!delegateGlobalToTest
499: .getAccountDelegatePrimaryRoutingIndicator()) {
500: return null;
501: }
502: if (StringUtils.isBlank(delegateGlobalToTest
503: .getFinancialDocumentTypeCode())) {
504: return null;
505: }
506:
507: // at this point, the delegateGlobal being added is a Primary for ALL docTypes, so we need to
508: // test whether any in the existing list are also Primary, regardless of docType
509: String docType = delegateGlobalToTest
510: .getFinancialDocumentTypeCode();
511: DelegateGlobalDetail delegateGlobal = null;
512: for (int lineNumber = 0; lineNumber < delegateGlobals.size(); lineNumber++) {
513: delegateGlobal = delegateGlobals.get(lineNumber);
514: if (delegateGlobal
515: .getAccountDelegatePrimaryRoutingIndicator()) {
516: if (docType.equalsIgnoreCase(delegateGlobal
517: .getFinancialDocumentTypeCode())) {
518: if (testLineNum == null) {
519: return new Integer(lineNumber);
520: } else if (!(testLineNum.intValue() == lineNumber)) {
521: return new Integer(lineNumber);
522: }
523: }
524: }
525: }
526:
527: return null;
528: }
529:
530: /**
531: * This checks that the primary routing for delegates is correct, specifically that - there is not already a primary route
532: * delegate setup for this {@link Account}
533: *
534: * @param delegateGlobals
535: * @param delegateGlobalToTest
536: * @param lineNum
537: * @param add
538: * @return
539: */
540: protected boolean checkPrimaryRouteRules(
541: List<DelegateGlobalDetail> delegateGlobals,
542: DelegateGlobalDetail delegateGlobalToTest, Integer lineNum,
543: boolean add) {
544: boolean success = true;
545:
546: String errorPath = "";
547: Integer result = null;
548: for (DelegateGlobalDetail delegateGlobal : delegateGlobals) {
549:
550: result = checkPrimaryRoutePerDocType(delegateGlobalToTest,
551: delegateGlobals, lineNum);
552: if (result != null) {
553: if (add) {
554: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
555: + DELEGATE_GLOBALS_PREFIX + "."
556: + "financialDocumentTypeCode";
557: putFieldError(
558: errorPath,
559: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_DELEGATEMAINT_PRIMARY_ROUTE_ALREADY_EXISTS_FOR_DOCTYPE);
560: } else {
561: errorPath = DELEGATE_GLOBALS_PREFIX + "["
562: + lineNum.toString() + "]."
563: + "financialDocumentTypeCode";
564: putFieldError(
565: errorPath,
566: KFSKeyConstants.ERROR_DOCUMENT_GLOBAL_DELEGATEMAINT_PRIMARY_ROUTE_ALREADY_EXISTS_FOR_DOCTYPE);
567: }
568: success &= false;
569: }
570: }
571: return success;
572: }
573:
574: /**
575: * This checks that the delegate for this {@link Account} exists and is valid (active and a professional)
576: *
577: * @param delegateGlobal
578: * @param lineNum
579: * @param add
580: * @return false if the delegate for the {@link Account} doesn't exist or isn't valid
581: */
582: protected boolean checkDelegateUserRules(
583: DelegateGlobalDetail delegateGlobal, int lineNum,
584: boolean add) {
585:
586: boolean success = true;
587:
588: String errorPath = KFSConstants.EMPTY_STRING;
589: // user must exist
590: if (delegateGlobal.getAccountDelegate() == null) {
591: if (add) {
592: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
593: + DELEGATE_GLOBALS_PREFIX + "."
594: + "accountDelegate.personUserIdentifier";
595: putFieldError(
596: errorPath,
597: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_USER_DOESNT_EXIST);
598: } else {
599: errorPath = DELEGATE_GLOBALS_PREFIX + "[" + lineNum
600: + "]." + "accountDelegate.personUserIdentifier";
601: putFieldError(
602: errorPath,
603: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_USER_DOESNT_EXIST);
604: }
605: success &= false;
606: return success;
607: }
608: UniversalUser user = delegateGlobal.getAccountDelegate();
609:
610: // user must be of the allowable statuses (A - Active)
611: if (!SpringContext
612: .getBean(ParameterService.class)
613: .getParameterEvaluator(
614: Delegate.class,
615: KFSConstants.ChartApcParms.DELEGATE_USER_EMP_STATUSES,
616: user.getEmployeeStatusCode())
617: .evaluationSucceeds()) {
618: if (add) {
619: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
620: + DELEGATE_GLOBALS_PREFIX + "."
621: + "accountDelegate.personUserIdentifier";
622: putFieldError(
623: errorPath,
624: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_USER_NOT_ACTIVE);
625: } else {
626: errorPath = DELEGATE_GLOBALS_PREFIX + "[" + lineNum
627: + "]." + "accountDelegate.personUserIdentifier";
628: putFieldError(
629: errorPath,
630: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_USER_NOT_ACTIVE);
631: }
632: success &= false;
633: }
634:
635: // user must be of the allowable types (P - Professional)
636: if (!SpringContext
637: .getBean(ParameterService.class)
638: .getParameterEvaluator(
639: Delegate.class,
640: KFSConstants.ChartApcParms.DELEGATE_USER_EMP_TYPES,
641: user.getEmployeeTypeCode())
642: .evaluationSucceeds()) {
643: if (add) {
644: errorPath = KFSConstants.MAINTENANCE_ADD_PREFIX
645: + DELEGATE_GLOBALS_PREFIX + "."
646: + "accountDelegate.personUserIdentifier";
647: putFieldError(
648: errorPath,
649: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_USER_NOT_PROFESSIONAL);
650: } else {
651: errorPath = DELEGATE_GLOBALS_PREFIX + "[" + lineNum
652: + "]." + "accountDelegate.personUserIdentifier";
653: putFieldError(
654: errorPath,
655: KFSKeyConstants.ERROR_DOCUMENT_ACCTDELEGATEMAINT_USER_NOT_PROFESSIONAL);
656: }
657: success &= false;
658: }
659:
660: return success;
661: }
662:
663: /**
664: * This checks that when a new line is added (either {@link AccountGlobalDetail} or {@link DelegateGlobalDetail}) that the
665: * appropriate rules are run on the new lines being added on {@link AccountGlobalDetail}: - make sure that the account number
666: * and chart are entered
667: * <ul>
668: * <li>{@link DelegateGlobalRule#checkAccountDetails(AccountGlobalDetail)}</li>
669: * </ul>
670: * on {@link DelegateGlobalDetail}
671: * <ul>
672: * <li>{@link DelegateGlobalRule#checkDelegateFromAmtGreaterThanEqualZero(KualiDecimal, int, boolean)}</li>
673: * <li>{@link DelegateGlobalRule#checkDelegateForNullToAmount(KualiDecimal, KualiDecimal, int, boolean)}</li>
674: * <li>{@link DelegateGlobalRule#checkDelegateToAmtGreaterThanFromAmt(KualiDecimal, KualiDecimal, int, boolean)}</li>
675: * <li>{@link DelegateGlobalRule#checkDelegateUserRules(DelegateGlobalDetail, int, boolean)}</li>
676: * <li>{@link DelegateGlobalRule#checkPrimaryRouteRules(List, DelegateGlobalDetail, Integer, boolean)}</li>
677: * </ul>
678: *
679: * @see org.kuali.core.maintenance.rules.MaintenanceDocumentRuleBase#processCustomAddCollectionLineBusinessRules(org.kuali.core.document.MaintenanceDocument,
680: * java.lang.String, org.kuali.core.bo.PersistableBusinessObject)
681: */
682: public boolean processCustomAddCollectionLineBusinessRules(
683: MaintenanceDocument document, String collectionName,
684: PersistableBusinessObject bo) {
685: boolean success = true;
686: if (bo instanceof AccountGlobalDetail) {
687: AccountGlobalDetail detail = (AccountGlobalDetail) bo;
688: // make sure that both primary keys are available for this object
689: if (!checkEmptyValue(detail.getAccountNumber())) {
690: // put an error about accountnumber
691: GlobalVariables.getErrorMap().putError("accountNumber",
692: KFSKeyConstants.ERROR_REQUIRED,
693: "Account Number");
694: success &= false;
695: }
696: if (!checkEmptyValue(detail.getChartOfAccountsCode())) {
697: // put an error about chart code
698: GlobalVariables.getErrorMap().putError(
699: "chartOfAccountsCode",
700: KFSKeyConstants.ERROR_REQUIRED,
701: "Chart of Accounts Code");
702: success &= false;
703: }
704: success &= checkAccountDetails(detail);
705: } else if (bo instanceof DelegateGlobalDetail) {
706: DelegateGlobalDetail detail = (DelegateGlobalDetail) bo;
707: detail.refreshNonUpdateableReferences();
708: KualiDecimal fromAmount = detail
709: .getApprovalFromThisAmount();
710: KualiDecimal toAmount = detail.getApprovalToThisAmount();
711:
712: // FROM amount must be >= 0 (may not be negative)
713: success &= checkDelegateFromAmtGreaterThanEqualZero(
714: fromAmount, 0, true);
715:
716: // from cannot be a valid value and toAmount cannot be null
717: success &= checkDelegateForNullToAmount(fromAmount,
718: toAmount, 0, true);
719:
720: // TO amount must be >= FROM amount or Zero
721: success &= checkDelegateToAmtGreaterThanFromAmt(fromAmount,
722: toAmount, 0, true);
723:
724: // check the user that is being added
725: // TODO: add back in once the user issues have been fixed
726: success &= checkDelegateUserRules(detail, 0, true);
727:
728: // check the routing
729: success &= checkPrimaryRouteRules(newDelegateGlobal
730: .getDelegateGlobals(), detail, null, true);
731:
732: }
733: return success;
734: }
735:
736: }
|