View Javadoc
1   /*
2    * The Kuali Financial System, a comprehensive financial management system for higher education.
3    * 
4    * Copyright 2005-2014 The Kuali Foundation
5    * 
6    * This program is free software: you can redistribute it and/or modify
7    * it under the terms of the GNU Affero General Public License as
8    * published by the Free Software Foundation, either version 3 of the
9    * License, or (at your option) any later version.
10   * 
11   * This program is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   * GNU Affero General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Affero General Public License
17   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18   */
19  package org.kuali.kfs.coa.document.validation.impl;
20  
21  import static org.kuali.kfs.sys.KualiTestAssertionUtils.assertGlobalMessageMapEmpty;
22  import static org.kuali.kfs.sys.KualiTestAssertionUtils.assertGlobalMessageMapSize;
23  import static org.kuali.kfs.sys.fixture.UserNameFixture.khuntley;
24  
25  import java.sql.Date;
26  import java.util.ArrayList;
27  import java.util.Calendar;
28  import java.util.Iterator;
29  import java.util.List;
30  
31  import org.apache.commons.lang.time.DateUtils;
32  import org.kuali.kfs.coa.businessobject.Account;
33  import org.kuali.kfs.coa.businessobject.AccountGuideline;
34  import org.kuali.kfs.coa.businessobject.IndirectCostRecoveryAccount;
35  import org.kuali.kfs.coa.businessobject.SubFundGroup;
36  import org.kuali.kfs.coa.service.AccountService;
37  import org.kuali.kfs.sys.ConfigureContext;
38  import org.kuali.kfs.sys.KFSConstants;
39  import org.kuali.kfs.sys.KFSConstants.SystemGroupParameterNames;
40  import org.kuali.kfs.sys.KFSKeyConstants;
41  import org.kuali.kfs.sys.KFSPropertyConstants;
42  import org.kuali.kfs.sys.businessobject.SystemOptions;
43  import org.kuali.kfs.sys.context.SpringContext;
44  import org.kuali.kfs.sys.context.TestUtils;
45  import org.kuali.kfs.sys.service.OptionsService;
46  import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
47  import org.kuali.rice.core.api.datetime.DateTimeService;
48  import org.kuali.rice.kim.api.identity.Person;
49  import org.kuali.rice.kim.api.identity.PersonService;
50  import org.kuali.rice.kns.document.MaintenanceDocument;
51  import org.kuali.rice.krad.service.BusinessObjectService;
52  import org.kuali.rice.krad.util.GlobalVariables;
53  
54  @ConfigureContext(session = khuntley)
55  public class AccountRuleTest extends ChartRuleTestBase {
56  
57      private class Accounts {
58          private class ChartCode {
59              private static final String GOOD1 = "BL";
60              private static final String CLOSED1 = "BL";
61              private static final String EXPIRED1 = "BL";
62              private static final String GOOD2 = "UA";
63              private static final String BAD1 = "ZZ";
64          }
65  
66          private class AccountNumber {
67              private static final String GOOD1 = "1031400";
68              private static final String CLOSED1 = "2231414";
69              private static final String EXPIRED1 = "2231404";
70              private static final String BAD1 = "9999999";
71          }
72  
73          private class Org {
74              private static final String GOOD1 = "ACAD";
75              private static final String BAD1 = "1234";
76          }
77  
78          private class Campus {
79              private static final String GOOD1 = "BL";
80              private static final String BAD1 = "99";
81          }
82  
83          private class State {
84              private static final String GOOD1 = "IN";
85              private static final String BAD1 = "ZZ";
86          }
87  
88          private class Zip {
89              private static final String GOOD1 = "47405-3085";
90              private static final String BAD1 = "12345-6789";
91          }
92  
93          private class AccountType {
94              private static final String GOOD1 = "NA";
95              private static final String BAD1 = "ZZ";
96          }
97  
98          private class SubFund {
99              private class Code {
100                 private static final String CG1 = "HIEDUA";
101                 private static final String GF1 = "GENFND";
102                 private static final String GF_MPRACT = "MPRACT";
103                 private static final String EN1 = "ENDOW";
104             }
105 
106             private class FundGroupCode {
107                 private static final String CG1 = "CG";
108                 private static final String GF1 = "GF";
109                 private static final String EN1 = "EN";
110             }
111 
112             private static final String GOOD1 = "GENFND";
113         }
114 
115         private class HigherEdFunction {
116             private static final String GOOD1 = "AC";
117         }
118 
119         private class RestrictedCode {
120             private static final String GOOD1 = "U";
121         }
122 
123         private class BudgetRecordingLevel {
124             private static final String GOOD1 = "A";
125         }
126 
127         private class User {
128             private class McafeeAlan {
129                 private static final String UNIVERSAL_ID = "1509103107";
130                 private static final String USER_ID = "AEMCAFEE";
131                 private static final String EMP_ID = "0000000013";
132                 private static final String NAME = "Mcafee,Alan";
133                 private static final String EMP_STATUS = "A";
134                 private static final String EMP_TYPE = "P";
135             }
136 
137             private class PhamAnibal {
138                 private static final String UNIVERSAL_ID = "1195901455";
139                 private static final String USER_ID = "AAPHAM";
140                 private static final String EMP_ID = "0000004686";
141                 private static final String NAME = "Pham,Anibal";
142                 private static final String EMP_STATUS = "A";
143                 private static final String EMP_TYPE = "P";
144             }
145 
146             private class AhlersEsteban {
147                 private static final String UNIVERSAL_ID = "1959008511";
148                 private static final String USER_ID = "AHLERS";
149                 private static final String EMP_ID = "0000002820";
150                 private static final String NAME = "Ahlers,Esteban";
151                 private static final String EMP_STATUS = "A";
152                 private static final String EMP_TYPE = "P";
153             }
154         }
155 
156         private class FiscalOfficer {
157             private static final String GOOD1 = "4318506633";
158         }
159 
160         private class Supervisor {
161             private static final String GOOD1 = "4052406505";
162         }
163 
164         private class Manager {
165             private static final String GOOD1 = "4318506633";
166         }
167 
168         private class UserIds {
169             private static final String SUPER1 = "HEAGLE";
170             private static final String GOOD1 = "kcopley";
171             private static final String GOOD2 = "khuntley";
172         }
173 
174         private class IndirectCostRecoveryTypeCode {
175             private static final String GOOD1 = "";
176         }
177     }
178 
179     private static Person FO;
180     private static Person SUPERVISOR;
181     private static Person MANAGER;
182     Account newAccount;
183 
184     /**
185      * @see org.kuali.kfs.coa.document.validation.impl.ChartRuleTestBase#setUp()
186      */
187     @Override
188     protected void setUp() throws Exception {
189         super.setUp();
190         newAccount = new Account();
191         newAccount.setAccountFiscalOfficerSystemIdentifier(Accounts.FiscalOfficer.GOOD1);
192         newAccount.setAccountsSupervisorySystemsIdentifier(Accounts.Supervisor.GOOD1);
193         newAccount.setAccountManagerSystemIdentifier(Accounts.Manager.GOOD1);
194     }
195 
196     public void testDefaultExistenceChecks_Org_KnownGood() {
197 
198         // create new account to test
199         newAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
200         newAccount.setOrganizationCode(Accounts.Org.GOOD1);
201 
202         // run the test
203         testDefaultExistenceCheck(newAccount, "organizationCode", false);
204         assertGlobalMessageMapEmpty();
205 
206     }
207 
208     public void testDefaultExistenceChecks_Org_KnownBad() {
209 
210         // create new account to test
211 
212         newAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
213         newAccount.setOrganizationCode(Accounts.Org.BAD1);
214 
215         // run the test
216         testDefaultExistenceCheck(newAccount, "organizationCode", true);
217         assertGlobalMessageMapSize(1);
218 
219     }
220 
221     public void testDefaultExistenceChecks_AccountPhysicalCampus_KnownGood() {
222 
223         // create new account to test
224 
225         newAccount.setAccountPhysicalCampusCode(Accounts.Campus.GOOD1);
226 
227         // run the test
228         testDefaultExistenceCheck(newAccount, "accountPhysicalCampusCode", false);
229         assertGlobalMessageMapEmpty();
230 
231     }
232 
233     public void testDefaultExistenceChecks_AccountPhysicalCampus_KnownBad() {
234 
235         // create new account to test
236 
237         newAccount.setAccountPhysicalCampusCode(Accounts.Campus.BAD1);
238 
239         // run the test
240         testDefaultExistenceCheck(newAccount, "accountPhysicalCampusCode", true);
241         assertGlobalMessageMapSize(1);
242 
243     }
244 
245     public void testDefaultExistenceChecks_AccountState_KnownGood() {
246 
247         // create new account to test
248 
249         newAccount.setAccountStateCode(Accounts.State.GOOD1);
250 
251         // run the test
252         testDefaultExistenceCheck(newAccount, "accountStateCode", false);
253         assertGlobalMessageMapEmpty();
254 
255     }
256 
257     public void testDefaultExistenceChecks_AccountState_KnownBad() {
258 
259         // create new account to test
260 
261         newAccount.setAccountStateCode(Accounts.State.BAD1);
262 
263         // run the test
264         testDefaultExistenceCheck(newAccount, "accountStateCode", true);
265         assertGlobalMessageMapSize(1);
266 
267     }
268 
269     public void testDefaultExistenceChecks_PostalZipCode_KnownGood() {
270 
271         // create new account to test
272 
273         newAccount.setAccountZipCode(Accounts.Zip.GOOD1);
274 
275         // run the test
276         testDefaultExistenceCheck(newAccount, "accountZipCode", false);
277         assertGlobalMessageMapEmpty();
278 
279     }
280 
281     public void testDefaultExistenceChecks_PostalZipCode_KnownBad() {
282 
283         // create new account to test
284 
285         newAccount.setAccountZipCode(Accounts.Zip.BAD1);
286 
287         // run the test
288         testDefaultExistenceCheck(newAccount, "accountZipCode", true);
289         assertGlobalMessageMapSize(1);
290 
291     }
292 
293     public void testDefaultExistenceChecks_AccountType_KnownGood() {
294 
295         // create new account to test
296 
297         newAccount.setAccountTypeCode(Accounts.AccountType.GOOD1);
298 
299         // run the test
300         testDefaultExistenceCheck(newAccount, "accountTypeCode", false);
301         assertGlobalMessageMapEmpty();
302 
303     }
304 
305     public void testDefaultExistenceChecks_AccountType_KnownBad() {
306 
307         // create new account to test
308 
309         newAccount.setAccountTypeCode(Accounts.AccountType.BAD1);
310 
311         // run the test
312         testDefaultExistenceCheck(newAccount, "accountTypeCode", true);
313         assertGlobalMessageMapSize(1);
314 
315     }
316 
317     // TODO: finish explicitly testing all the defaultExistenceChecks ... though this isnt hugely valuable
318 
319     public void testGuidelinesConditionallyRequired_NullExpirationDate() {
320 
321         boolean result;
322         Account account = new Account();
323         MaintenanceDocument maintDoc = newMaintDoc(account);
324         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
325 
326         account.setAccountExpirationDate(null);
327         result = rule.areGuidelinesRequired(account);
328         assertEquals("Guidelines should be required for Account with no ExpirationDate.", true, result);
329 
330     }
331 
332     public void testGuidelinesConditionallyRequired_FarPastDate() {
333 
334         boolean result;
335         Account account = new Account();
336         MaintenanceDocument maintDoc = newMaintDoc(account);
337         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
338 
339         // get an arbitrarily early date
340         Calendar testDate = Calendar.getInstance();
341         testDate.clear();
342         testDate.set(1900, 1, 1);
343         account.setAccountExpirationDate(new Date(testDate.getTimeInMillis()));
344         result = rule.areGuidelinesRequired(account);
345         assertEquals("Guidelines should not be required for Account with prior ExpirationDate", false, result);
346     }
347 
348     public void testGuidelinesConditionallyRequired_TodaysDate() {
349 
350         boolean result;
351         Account account = new Account();
352         MaintenanceDocument maintDoc = newMaintDoc(account);
353         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
354 
355         // setup a var with today's date
356         Date today = new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime());
357         today.setTime(DateUtils.truncate(today, Calendar.DAY_OF_MONTH).getTime());
358         account.setAccountExpirationDate(today);
359         result = rule.areGuidelinesRequired(account);
360         assertEquals("Guidelines should be required for Account expiring today.", true, result);
361 
362     }
363 
364     public void testGuidelinesConditionallyRequired_FarFutureDate() {
365 
366         boolean result;
367         Account account = new Account();
368         MaintenanceDocument maintDoc = newMaintDoc(account);
369         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
370 
371         // get an arbitrarily future date
372         Calendar testDate = Calendar.getInstance();
373         testDate.clear();
374         testDate.set(2100, 1, 1);
375         account.setAccountExpirationDate(new Date(testDate.getTimeInMillis()));
376         result = rule.areGuidelinesRequired(account);
377         assertEquals("Guidelines should be required for Account with future ExpirationDate", true, result);
378 
379     }
380 
381     public void testAccountNumberStartsWithAllowedPrefix() {
382 
383         Account account = new Account();
384         MaintenanceDocument maintDoc = newMaintDoc(account);
385         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
386 
387         boolean result;
388         List<String> illegalValues = new ArrayList();
389         String accountNumber;
390 
391         accountNumber = "0100000";
392         illegalValues.add("0");
393         result = rule.accountNumberStartsWithAllowedPrefix(accountNumber, illegalValues);
394         assertEquals(false, result);
395 
396         accountNumber = "9999990";
397         illegalValues.clear();
398         illegalValues.add("999999");
399         result = rule.accountNumberStartsWithAllowedPrefix(accountNumber, illegalValues);
400         assertEquals(false, result);
401 
402         accountNumber = "1031400";
403         illegalValues.clear();
404         illegalValues.add("0");
405         result = rule.accountNumberStartsWithAllowedPrefix(accountNumber, illegalValues);
406         assertEquals(true, result);
407 
408         accountNumber = "1031400";
409         illegalValues.clear();
410         illegalValues.add("0");
411         illegalValues.add("9");
412         illegalValues.add("Z");
413         result = rule.accountNumberStartsWithAllowedPrefix(accountNumber, illegalValues);
414         assertEquals(true, result);
415 
416     }
417 
418     private Person getKualiUserByUserName(String userName) {
419         return SpringContext.getBean(PersonService.class).getPersonByPrincipalName(userName);
420     }
421 
422     public void testNonSystemSupervisorReopeningClosedAccount_NotBeingReopened() {
423         Account oldAccount = new Account();
424 
425         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
426         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
427 
428         // setup common information
429         oldAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
430         oldAccount.setAccountNumber(Accounts.AccountNumber.GOOD1);
431         newAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
432         newAccount.setAccountNumber(Accounts.AccountNumber.GOOD1);
433 
434         // document not being closed
435         oldAccount.setClosed(false);
436         newAccount.setClosed(false);
437         Person user = getKualiUserByUserName(Accounts.UserIds.GOOD1);
438         boolean result = rule.isNonSystemSupervisorEditingAClosedAccount(maintDoc, user);
439 
440         assertEquals("Account is not closed, and is not being reopened.", false, result);
441     }
442 
443     public void testNonSystemSupervisorReopeningClosedAccount_BeingReopenedNotSupervisor() {
444         Account oldAccount = new Account();
445 
446         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
447         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
448 
449         // setup common information
450         oldAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
451         oldAccount.setAccountNumber(Accounts.AccountNumber.GOOD1);
452         newAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
453         newAccount.setAccountNumber(Accounts.AccountNumber.GOOD1);
454 
455         // document being closed, non-supervisor user
456         oldAccount.setClosed(true);
457         newAccount.setClosed(false);
458         Person user = getKualiUserByUserName(Accounts.UserIds.GOOD1);
459         boolean result = rule.isNonSystemSupervisorEditingAClosedAccount(maintDoc, user);
460 
461         assertEquals("Account is being reopened by a non-System-Supervisor.", false, result);
462     }
463 
464     public void testNonSystemSupervisorReopeningClosedAccount_BeingReopenedBySupervisor() {
465         Account oldAccount = new Account();
466 
467         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
468         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
469 
470         // setup common information
471         oldAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
472         oldAccount.setAccountNumber(Accounts.AccountNumber.GOOD1);
473         newAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
474         newAccount.setAccountNumber(Accounts.AccountNumber.GOOD1);
475 
476         // document being closed, supervisor user
477         oldAccount.setClosed(true);
478         newAccount.setClosed(false);
479         Person user = getKualiUserByUserName(Accounts.UserIds.SUPER1);
480         boolean result = rule.isNonSystemSupervisorEditingAClosedAccount(maintDoc, user);
481 
482         assertEquals("Account is being reopened by a System-Supervisor.", false, result);
483     }
484 
485     public void testHasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate_BothNull() {
486         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
487         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
488 
489         // restricted status code blank, date not set
490         newAccount.setAccountRestrictedStatusCode(null);
491         newAccount.setAccountRestrictedStatusDate(null);
492         boolean result = rule.hasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate(newAccount);
493 
494         assertEquals("No error should be thrown if code is blank.", false, result);
495 
496     }
497 
498     public void testHasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate_NonTCodeAndNullDate() {
499 
500 
501         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
502         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
503         boolean result;
504 
505         // restricted status code != T, date not set
506         newAccount.setAccountRestrictedStatusCode("U");
507         newAccount.setAccountRestrictedStatusDate(null);
508         result = rule.hasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate(newAccount);
509         assertEquals("No error should be thrown if code is not T.", false, result);
510 
511     }
512 
513     public void testHasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate_TCodeAndNullDate() {
514 
515 
516         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
517         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
518         boolean result;
519 
520         // restricted status code == T, date not set
521         newAccount.setAccountRestrictedStatusCode("T");
522         newAccount.setAccountRestrictedStatusDate(null);
523         result = rule.hasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate(newAccount);
524         assertEquals("An error should be thrown if code is not T, but date is not set.", true, result);
525 
526     }
527 
528     public void testHasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate_TCodeAndRealDate() {
529 
530 
531         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
532         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
533         boolean result;
534 
535         // restricted status code == T, date set
536         newAccount.setAccountRestrictedStatusCode("T");
537         newAccount.setAccountRestrictedStatusDate(SpringContext.getBean(DateTimeService.class).getCurrentSqlDate());
538         result = rule.hasTemporaryRestrictedStatusCodeButNoRestrictedStatusDate(newAccount);
539         assertEquals("No error should be thrown if code is T but date is null.", false, result);
540 
541     }
542 
543     public void testCheckFringeBenefitAccountRule_FringeBenefitFlagTrue() {
544 
545 
546         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
547         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
548         boolean result;
549 
550         // fringe benefit flag is checked TRUE
551         newAccount.setAccountsFringesBnftIndicator(true);
552         result = rule.checkFringeBenefitAccountRule(newAccount);
553         assertEquals("If FringeBenefit is checked, then rule always returns true.", true, result);
554 
555     }
556 
557     public void testCheckFringeBenefitAccountRule_FringeBenefitChartCodeMissing() {
558 
559 
560         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
561         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
562         boolean result;
563 
564         // fringe benefit chartCode missing
565         newAccount.setAccountsFringesBnftIndicator(false);
566         newAccount.setReportsToChartOfAccountsCode(null);
567         newAccount.setReportsToAccountNumber(Accounts.AccountNumber.GOOD1);
568         result = rule.checkFringeBenefitAccountRule(newAccount);
569         assertEquals("FringeBenefit ChartCode missing causes error.", false, result);
570         assertFieldErrorExists("reportsToChartOfAccountsCode", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_RPTS_TO_ACCT_REQUIRED_IF_FRINGEBENEFIT_FALSE);
571         assertGlobalMessageMapSize(1);
572 
573     }
574 
575     public void testCheckFringeBenefitAccountRule_FringeBenefitAccountNumberMissing() {
576 
577 
578         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
579         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
580         boolean result;
581 
582         // fringe benefit accountNumber missing
583         newAccount.setAccountsFringesBnftIndicator(false);
584         newAccount.setReportsToChartOfAccountsCode(Accounts.ChartCode.GOOD1);
585         newAccount.setReportsToAccountNumber(null);
586         result = rule.checkFringeBenefitAccountRule(newAccount);
587         assertEquals("FringeBenefit AccountNumber missing causes error.", false, result);
588         assertFieldErrorExists("reportsToAccountNumber", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_RPTS_TO_ACCT_REQUIRED_IF_FRINGEBENEFIT_FALSE);
589         assertGlobalMessageMapSize(1);
590 
591     }
592 
593     public void testCheckFringeBenefitAccountRule_FringeBenefitAccountDoesntExist() {
594 
595 
596         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
597         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
598         boolean result;
599 
600         // fringe benefit accountNumber missing
601         newAccount.setAccountsFringesBnftIndicator(false);
602         newAccount.setReportsToChartOfAccountsCode(Accounts.ChartCode.GOOD2);
603         newAccount.setReportsToAccountNumber(Accounts.AccountNumber.GOOD1);
604         result = rule.checkFringeBenefitAccountRule(newAccount);
605         assertEquals("FringeBenefit doesnt exist causes error.", false, result);
606         assertFieldErrorExists("reportsToAccountNumber", KFSKeyConstants.ERROR_EXISTENCE);
607         assertGlobalMessageMapSize(1);
608 
609     }
610 
611     public void testCheckFringeBenefitAccountRule_FringeBenefitAccountClosed() {
612 
613 
614         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
615         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
616         boolean result;
617 
618         // fringe benefit accountNumber missing
619         newAccount.setAccountsFringesBnftIndicator(false);
620         newAccount.setReportsToChartOfAccountsCode(Accounts.ChartCode.CLOSED1);
621         newAccount.setReportsToAccountNumber(Accounts.AccountNumber.CLOSED1);
622         result = rule.checkFringeBenefitAccountRule(newAccount);
623         assertEquals("FringeBenefit Closed causes error.", false, result);
624         assertFieldErrorExists("reportsToAccountNumber", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_RPTS_TO_ACCT_MUST_BE_FLAGGED_FRINGEBENEFIT);
625         assertGlobalMessageMapSize(1);
626 
627     }
628 
629     public void testCheckFringeBenefitAccountRule_FringeBenefitGood() {
630 
631 
632         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
633         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
634         boolean result;
635 
636         // fringe benefit accountNumber missing
637         newAccount.setAccountsFringesBnftIndicator(false);
638         newAccount.setReportsToChartOfAccountsCode(Accounts.ChartCode.GOOD1);
639         newAccount.setReportsToAccountNumber(Accounts.AccountNumber.GOOD1);
640         result = rule.checkFringeBenefitAccountRule(newAccount);
641         assertEquals("Good FringeBenefit Account should not fail.", true, result);
642         assertGlobalMessageMapEmpty();
643 
644     }
645 
646     public void testIsContinuationAccountExpired_MissingChartCode() {
647 
648 
649         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
650         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
651         boolean result;
652 
653         // continuation chartCode is missing
654         newAccount.setContinuationFinChrtOfAcctCd(null);
655         newAccount.setContinuationAccountNumber(Accounts.AccountNumber.GOOD1);
656         result = rule.isContinuationAccountExpired(newAccount);
657         assertEquals("Missing continuation chartCode should return false.", false, result);
658 
659     }
660 
661     public void testIsContinuationAccountExpired_MissingAccountNumber() {
662 
663 
664         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
665         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
666         boolean result;
667 
668         // continuation accountNumber is missing
669         newAccount.setContinuationFinChrtOfAcctCd(Accounts.ChartCode.GOOD1);
670         newAccount.setContinuationAccountNumber(null);
671         result = rule.isContinuationAccountExpired(newAccount);
672         assertEquals("Missing continuation accountNumber should return false.", false, result);
673 
674     }
675 
676     public void testIsContinuationAccountExpired_InvalidContinuationAccount() {
677 
678 
679         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
680         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
681         boolean result;
682 
683         // bad continuation chart/account
684         newAccount.setContinuationFinChrtOfAcctCd(Accounts.ChartCode.BAD1);
685         newAccount.setContinuationAccountNumber(Accounts.AccountNumber.GOOD1);
686         result = rule.isContinuationAccountExpired(newAccount);
687         assertEquals("Bad continuation chartCode/Account should return false.", false, result);
688 
689     }
690 
691     public void testIsContinuationAccountExpired_ValidNonExpiredContinuationAccount() {
692 
693 
694         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
695         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
696         boolean result;
697 
698         // non-expired continuation account
699         newAccount.setContinuationFinChrtOfAcctCd(Accounts.ChartCode.GOOD1);
700         newAccount.setContinuationAccountNumber(Accounts.AccountNumber.GOOD1);
701         result = rule.isContinuationAccountExpired(newAccount);
702         assertEquals("Good and non-expired continuation account should return false.", false, result);
703 
704     }
705 
706     public void testIsContinuationAccountExpired_ValidExpiredContinuationAccount() {
707 
708 
709         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
710         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
711         boolean result;
712 
713         // EXPIRED continuation account
714         newAccount.setContinuationFinChrtOfAcctCd(Accounts.ChartCode.EXPIRED1);
715         newAccount.setContinuationAccountNumber(Accounts.AccountNumber.EXPIRED1);
716         result = rule.isContinuationAccountExpired(newAccount);
717         assertEquals("A valid, expired account should return true.", true, result);
718 
719     }
720 
721     public void testCheckAccountExpirationDateTodayOrEarlier_NullDate() {
722 
723 
724         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
725         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
726         boolean result;
727 
728         // empty expiration date - fail
729         newAccount.setAccountExpirationDate(null);
730         result = rule.checkAccountExpirationDateValidTodayOrEarlier(newAccount);
731         assertEquals("Null expiration date should fail.", false, result);
732         assertFieldErrorExists("accountExpirationDate", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_ACCT_CANNOT_BE_CLOSED_EXP_DATE_INVALID);
733         assertGlobalMessageMapSize(1);
734 
735     }
736 
737     public void testCheckAccountExpirationDateTodayOrEarlier_PastDate() {
738 
739 
740         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
741         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
742         boolean result;
743         Calendar testCalendar;
744         Date testTimestamp;
745 
746         // get an arbitrarily early date
747         testCalendar = Calendar.getInstance();
748         testCalendar.clear();
749         testCalendar.set(1900, 1, 1);
750         testTimestamp = new Date(testCalendar.getTimeInMillis());
751 
752         // past expiration date - pass
753         newAccount.setAccountExpirationDate(testTimestamp);
754         result = rule.checkAccountExpirationDateValidTodayOrEarlier(newAccount);
755         assertEquals("Arbitrarily early date should fail.", true, result);
756         assertGlobalMessageMapEmpty();
757 
758     }
759 
760     public void testCheckAccountExpirationDateTodayOrEarlier_TodaysDate() {
761 
762 
763         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
764         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
765         boolean result;
766         Calendar testCalendar;
767         Date testTimestamp;
768 
769         // get today's date (or whatever's provided by the DateTimeService)
770         testCalendar = Calendar.getInstance();
771         testCalendar.setTime(SpringContext.getBean(DateTimeService.class).getCurrentDate());
772         testCalendar = DateUtils.truncate(testCalendar, Calendar.DAY_OF_MONTH);
773         testTimestamp = new Date(testCalendar.getTimeInMillis());
774 
775         // current date - pass
776         newAccount.setAccountExpirationDate(testTimestamp);
777         result = rule.checkAccountExpirationDateValidTodayOrEarlier(newAccount);
778         assertEquals("Today's date should pass.", true, result);
779         assertGlobalMessageMapEmpty();
780 
781     }
782 
783     public void testCheckAccountExpirationDateTodayOrEarlier_FutureDate() {
784 
785 
786         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
787         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
788         boolean result;
789         Calendar testCalendar;
790         Date testTimestamp;
791 
792         // get an arbitrarily late date - fail
793         testCalendar = Calendar.getInstance();
794         testCalendar.clear();
795         testCalendar.set(2100, 1, 1);
796         testTimestamp = new Date(testCalendar.getTimeInMillis());
797 
798         // past or today expiration date - pass
799         newAccount.setAccountExpirationDate(testTimestamp);
800         result = rule.checkAccountExpirationDateValidTodayOrEarlier(newAccount);
801         assertEquals("Arbitrarily late date should pass.", false, result);
802         assertFieldErrorExists("accountExpirationDate", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_ACCT_CANNOT_BE_CLOSED_EXP_DATE_INVALID);
803         assertGlobalMessageMapSize(1);
804 
805     }
806 
807     private void disableBeginBalanceLoadInd() {
808         SystemOptions options = SpringContext.getBean(OptionsService.class).getCurrentYearOptions();
809         options.setFinancialBeginBalanceLoadInd(true);
810         SpringContext.getBean(BusinessObjectService.class).save(options);
811     }
812 
813     public void testCheckCloseAccountContinuation_NullContinuationCoaCode() {
814 
815         // set preconditions
816         disableBeginBalanceLoadInd();
817         Account oldAccount = new Account();
818 
819         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
820         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
821         boolean result;
822 
823         // account must be being closed
824         oldAccount.setActive(true);
825         newAccount.setActive(false);
826         newAccount.setAccountExpirationDate(new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime()));
827 
828         // continuation coa code null
829         newAccount.setContinuationFinChrtOfAcctCd(null);
830         newAccount.setContinuationAccountNumber(Accounts.AccountNumber.GOOD1);
831         result = rule.checkCloseAccount(maintDoc);
832         assertEquals("Null continuation coa code should fail with one error.", false, result);
833         assertFieldErrorExists("continuationFinChrtOfAcctCd", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_ACCT_CLOSE_CONTINUATION_CHART_CODE_REQD);
834         assertGlobalMessageMapSize(1);
835 
836     }
837 
838     public void testCheckCloseAccountContinuation_NullContinuationAccountNumber() {
839 
840         // set preconditions
841         disableBeginBalanceLoadInd();
842         Account oldAccount = new Account();
843 
844         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
845         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
846         boolean result;
847 
848         // account must be being closed
849         oldAccount.setActive(true);
850         newAccount.setActive(false);
851         newAccount.setAccountExpirationDate(new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime()));
852 
853         // continuation coa code null
854         newAccount.setContinuationFinChrtOfAcctCd(Accounts.ChartCode.GOOD1);
855         newAccount.setContinuationAccountNumber(null);
856         result = rule.checkCloseAccount(maintDoc);
857         assertEquals("Null continuation account number should fail with one error.", false, result);
858         assertFieldErrorExists("continuationAccountNumber", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_ACCT_CLOSE_CONTINUATION_ACCT_REQD);
859         assertGlobalMessageMapSize(1);
860 
861     }
862 
863     public void testCheckCloseAccountContinuation_ValidContinuationAccount() {
864 
865         Account oldAccount = new Account();
866 
867         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
868         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
869         boolean result;
870 
871         // account must be being closed
872         oldAccount.setActive(false);
873         newAccount.setActive(false);
874         newAccount.setAccountExpirationDate(new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime()));
875 
876         // continuation coa code null
877         newAccount.setContinuationFinChrtOfAcctCd(Accounts.ChartCode.GOOD1);
878         newAccount.setContinuationAccountNumber(Accounts.AccountNumber.GOOD1);
879         result = rule.checkCloseAccount(maintDoc);
880         assertEquals("Valid continuation account info should not fail.", true, result);
881         assertGlobalMessageMapEmpty();
882 
883     }
884 
885     /**
886      * Note that we are not testing any of the other elements in the AccountRule.checkCloseAccount(). This is because there is no
887      * logic to them. They simple exercise GL service methods, and if those GL service methods return false, they add an error.
888      */
889     @SuppressWarnings("deprecation")
890     public void testCGFields_RequiredCGFields_Missing() {
891 
892 
893         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
894         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
895         boolean result;
896 
897         // create the populated CG subfundgroup
898         SubFundGroup subFundGroup = new SubFundGroup();
899         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
900         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.CG1);
901         subFundGroup.setActive(true);
902 
903         // add the subFundGroup info to Account
904         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
905         newAccount.setSubFundGroup(subFundGroup);
906 
907         // make sure all the required fields are missing
908         newAccount.setContractControlFinCoaCode(null);
909         newAccount.setContractControlAccountNumber(null);
910         newAccount.setAcctIndirectCostRcvyTypeCd(null);
911         newAccount.setFinancialIcrSeriesIdentifier(null);
912         newAccount.setAccountCfdaNumber(null);
913 
914         // run the rule
915         result = rule.checkCgRequiredFields(newAccount);
916         assertEquals("Rule should return false with missing fields.", false, result);
917         assertGlobalMessageMapSize(3);
918         assertFieldErrorExists("acctIndirectCostRcvyTypeCd", KFSKeyConstants.ERROR_REQUIRED);
919         assertFieldErrorExists("financialIcrSeriesIdentifier", KFSKeyConstants.ERROR_REQUIRED);
920         assertFieldErrorExists(KFSPropertyConstants.INDIRECT_COST_RECOVERY_ACCOUNTS, KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_ICR_CHART_CODE_CANNOT_BE_EMPTY);
921     }
922 
923     @SuppressWarnings("deprecation")
924     public void testCGFields_RequiredCGFields_AllPresent() {
925 
926 
927         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
928         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
929         boolean result;
930 
931         // create the populated CG subfundgroup
932         SubFundGroup subFundGroup = new SubFundGroup();
933         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
934         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.CG1);
935         subFundGroup.setActive(true);
936 
937         // add the subFundGroup info to Account
938         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
939         newAccount.setSubFundGroup(subFundGroup);
940 
941         // make sure all the required fields are missing
942         newAccount.setContractControlFinCoaCode(Accounts.ChartCode.GOOD1);
943         newAccount.setContractControlAccountNumber(Accounts.AccountNumber.GOOD1);
944         newAccount.setAcctIndirectCostRcvyTypeCd("10");
945         newAccount.setFinancialIcrSeriesIdentifier("001");
946         addIndirectCostRecoveryAccount(newAccount);
947         newAccount.setAccountCfdaNumber("001");
948 
949         // run the rule
950         rule.setActiveIndirectCostRecoveryAccountList(newAccount.getIndirectCostRecoveryAccounts());
951         result = rule.checkCgRequiredFields(newAccount);
952 
953         assertGlobalMessageMapEmpty();
954         assertEquals("Rule should return true with no missing fields.", true, result);
955     }
956 
957     /**
958      * Set IndirectCostRecovery Account
959      *
960      * @param newAccount
961      */
962     private void addIndirectCostRecoveryAccount(Account newAccount) {
963         IndirectCostRecoveryAccount icr = new IndirectCostRecoveryAccount();
964         icr.setIndirectCostRecoveryAccountNumber(Accounts.AccountNumber.GOOD1);
965         icr.setIndirectCostRecoveryFinCoaCode(Accounts.ChartCode.GOOD1);
966         newAccount.getIndirectCostRecoveryAccounts().add(icr);
967     }
968 
969     /**
970      * @RelatesTo KULRNE-4662 This test makes sure that if the account has a non-CG subfund group, no fields are allowed to be
971      *            filled in. (The contrary test--that if we have an account with a CG fund group, all fields are now required--
972      *            should be tested by testCGFields_RequiredCGFields_AllPresent()).
973      */
974     @SuppressWarnings("deprecation")
975     public void testCGFields_NotCGSubFund_NoFieldsPresent() {
976         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
977         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
978         boolean result;
979 
980         // create the populated CG subfundgroup
981         SubFundGroup subFundGroup = new SubFundGroup();
982         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.EN1);
983         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.EN1);
984         subFundGroup.setActive(true);
985 
986         // add the subFundGroup info to Account
987         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.EN1);
988         newAccount.setSubFundGroup(subFundGroup);
989 
990         // make sure all the required fields are present, so the rule creates validation errors for all of them
991         newAccount.setContractControlFinCoaCode(Accounts.ChartCode.GOOD1);
992         newAccount.setContractControlAccountNumber(Accounts.AccountNumber.GOOD1);
993         newAccount.setAcctIndirectCostRcvyTypeCd("10");
994         newAccount.setFinancialIcrSeriesIdentifier("001");
995         addIndirectCostRecoveryAccount(newAccount);
996         newAccount.setAccountCfdaNumber("001");
997 
998         // run the rule
999         rule.setActiveIndirectCostRecoveryAccountList(newAccount.getIndirectCostRecoveryAccounts());
1000         result = rule.checkCgRequiredFields(newAccount);
1001 
1002         System.out.println(GlobalVariables.getMessageMap());
1003 
1004         assertFieldErrorExists("acctIndirectCostRcvyTypeCd", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_CG_FIELDS_FILLED_FOR_NON_CG_ACCOUNT);
1005         assertFieldErrorExists("financialIcrSeriesIdentifier", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_CG_FIELDS_FILLED_FOR_NON_CG_ACCOUNT);
1006         assertFieldErrorExists(KFSPropertyConstants.INDIRECT_COST_RECOVERY_ACCOUNTS, KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_CG_ICR_FIELDS_FILLED_FOR_NON_CG_ACCOUNT);
1007         assertFalse("We do not have a C&G sub fund group, but we have all the fields filled; the rule run result should be false", result);
1008     }
1009 
1010     /**
1011      * @RelatesTo KULRNE-4662
1012      * @RelatesTo KULCG-111 This method makes sure that the new account can act as its own contract control account.
1013      */
1014     @SuppressWarnings("deprecation")
1015     public void testCGFields_AccountCanBeCGAccount() {
1016         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1017         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1018         boolean result;
1019 
1020         // create the populated CG subfundgroup
1021         SubFundGroup subFundGroup = new SubFundGroup();
1022         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1023         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.CG1);
1024         subFundGroup.setActive(true);
1025 
1026         // add the subFundGroup info to Account
1027         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1028         newAccount.setSubFundGroup(subFundGroup);
1029 
1030         // set chart of accounts and account #, just for this test run
1031         String oldNewAccountChart = newAccount.getChartOfAccountsCode();
1032         String oldNewAccountsAcctNum = newAccount.getAccountNumber();
1033         newAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
1034         newAccount.setAccountNumber(Accounts.AccountNumber.BAD1);
1035 
1036         // make sure all the required fields are present
1037         newAccount.setContractControlFinCoaCode(newAccount.getChartOfAccountsCode());
1038         newAccount.setContractControlAccountNumber(newAccount.getAccountNumber());
1039         newAccount.setAcctIndirectCostRcvyTypeCd("10");
1040         newAccount.setFinancialIcrSeriesIdentifier("001");
1041         addIndirectCostRecoveryAccount(newAccount);
1042         newAccount.setAccountCfdaNumber("001");
1043 
1044         // run the rule
1045         rule.setActiveIndirectCostRecoveryAccountList(newAccount.getIndirectCostRecoveryAccounts());
1046         result = rule.checkCgRequiredFields(newAccount);
1047         assertGlobalMessageMapEmpty();
1048         assertTrue("Rule should allow new account to be the contract control account.", result);
1049 
1050         newAccount.setChartOfAccountsCode(oldNewAccountChart);
1051         newAccount.setAccountNumber(oldNewAccountsAcctNum);
1052     }
1053 
1054     /**
1055      * @RelatesTo KULCG-111 This method makes sure that any account specified as the contract control account must actually exist.
1056      */
1057     @SuppressWarnings("deprecation")
1058     public void testCGFields_AccountMustBeReal() {
1059         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1060         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1061         boolean result;
1062 
1063         // create the populated CG subfundgroup
1064         SubFundGroup subFundGroup = new SubFundGroup();
1065         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1066         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.CG1);
1067         subFundGroup.setActive(true);
1068 
1069         // add the subFundGroup info to Account
1070         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1071         newAccount.setSubFundGroup(subFundGroup);
1072 
1073         // make sure all the required fields exist...we don't really want to test for that
1074         newAccount.setContractControlFinCoaCode(Accounts.ChartCode.BAD1);
1075         newAccount.setContractControlAccountNumber(Accounts.AccountNumber.BAD1);
1076         newAccount.setAcctIndirectCostRcvyTypeCd("10");
1077         newAccount.setFinancialIcrSeriesIdentifier("001");
1078         addIndirectCostRecoveryAccount(newAccount);
1079         newAccount.setAccountCfdaNumber("001");
1080 
1081         // run the rule
1082         rule.setActiveIndirectCostRecoveryAccountList(newAccount.getIndirectCostRecoveryAccounts());
1083         result = rule.checkCgRequiredFields(newAccount);
1084         assertFieldErrorExists("contractControlAccountNumber", KFSKeyConstants.ERROR_EXISTENCE);
1085         assertFalse("Rule should require contract account to be real.", result);
1086     }
1087 
1088     @SuppressWarnings("deprecation")
1089     public void testCheckIncomeStreamRequired_NotApplicableAccount() {
1090         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1091         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1092         boolean result;
1093 
1094         // create the populated CG subfundgroup
1095         SubFundGroup subFundGroup = new SubFundGroup();
1096         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.EN1);
1097         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.EN1);
1098         subFundGroup.setActive(true);
1099 
1100         // add the subFundGroup info to Account
1101         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.EN1);
1102         newAccount.setSubFundGroup(subFundGroup);
1103 
1104         // make sure the income stream fields are blank
1105         newAccount.setIncomeStreamFinancialCoaCode(null);
1106         newAccount.setIncomeStreamAccountNumber(null);
1107         newAccount.setIncomeStreamAccount(null);
1108 
1109         // run the rule
1110         result = rule.checkIncomeStreamValid(newAccount);
1111         assertEquals("Non-applicable accounts should not fail.", true, result);
1112         assertGlobalMessageMapEmpty();
1113 
1114     }
1115 
1116     @SuppressWarnings("deprecation")
1117     public void testCheckIncomeStreamRequired_GFMPRACTException() {
1118         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_FUND_GROUPS, "GF;CG");
1119         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_SUB_FUND_GROUPS, "MPRACT");
1120 
1121         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1122         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1123         boolean result;
1124 
1125         // create the populated CG subfundgroup
1126         SubFundGroup subFundGroup = new SubFundGroup();
1127         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.GF_MPRACT);
1128         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.GF1);
1129         subFundGroup.setActive(true);
1130 
1131         // add the subFundGroup info to Account
1132         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.GF_MPRACT);
1133         newAccount.setSubFundGroup(subFundGroup);
1134 
1135         // make sure the income stream fields are blank
1136         newAccount.setIncomeStreamFinancialCoaCode(null);
1137         newAccount.setIncomeStreamAccountNumber(null);
1138         newAccount.setIncomeStreamAccount(null);
1139 
1140         // run the rule
1141         result = rule.checkIncomeStreamValid(newAccount);
1142         assertEquals("GF MPRACT account should not fail.", true, result);
1143         assertGlobalMessageMapEmpty();
1144 
1145     }
1146 
1147     @SuppressWarnings("deprecation")
1148     public void testCheckIncomeStreamRequired_CGAcctNoIncomeStreamFields() {
1149         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_FUND_GROUPS, "GF;CG");
1150         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_SUB_FUND_GROUPS, "MPRACT");
1151 
1152         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1153         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1154         boolean result;
1155 
1156         // create the populated CG subfundgroup
1157         SubFundGroup subFundGroup = new SubFundGroup();
1158         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1159         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.CG1);
1160         subFundGroup.setActive(true);
1161 
1162         // add the subFundGroup info to Account
1163         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1164         newAccount.setSubFundGroup(subFundGroup);
1165 
1166         // make sure the income stream fields are blank
1167         newAccount.setIncomeStreamFinancialCoaCode(null);
1168         newAccount.setIncomeStreamAccountNumber(null);
1169         newAccount.setIncomeStreamAccount(null);
1170 
1171         // run the rule
1172         result = rule.checkIncomeStreamValid(newAccount);
1173         assertEquals("CG Account with no Income Stream data should fail.", false, result);
1174         assertFieldErrorExists("incomeStreamFinancialCoaCode", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_INCOME_STREAM_ACCT_COA_CANNOT_BE_EMPTY);
1175         assertFieldErrorExists("incomeStreamAccountNumber", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_INCOME_STREAM_ACCT_NBR_CANNOT_BE_EMPTY);
1176         assertGlobalMessageMapSize(2);
1177 
1178     }
1179 
1180     @SuppressWarnings("deprecation")
1181     public void testCheckIncomeStreamRequired_CGAcctInvalidIncomeStreamAccount() {
1182         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_FUND_GROUPS, "GF;CG");
1183         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_SUB_FUND_GROUPS, "MPRACT");
1184 
1185         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1186         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1187         boolean result;
1188 
1189         // create the populated CG subfundgroup
1190         SubFundGroup subFundGroup = new SubFundGroup();
1191         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1192         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.CG1);
1193         subFundGroup.setActive(true);
1194 
1195         // add the subFundGroup info to Account
1196         newAccount.setChartOfAccountsCode(Accounts.ChartCode.GOOD1);
1197         newAccount.setAccountNumber(Accounts.AccountNumber.GOOD1);
1198         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1199         newAccount.setSubFundGroup(subFundGroup);
1200 
1201         // make sure the income stream fields are blank
1202         newAccount.setIncomeStreamFinancialCoaCode(Accounts.ChartCode.BAD1);
1203         newAccount.setIncomeStreamAccountNumber(Accounts.AccountNumber.GOOD1);
1204         newAccount.setIncomeStreamAccount(null);
1205 
1206         // run the rule
1207         result = rule.checkIncomeStreamValid(newAccount);
1208         assertEquals("CG Account with invalid Income Stream data should fail.", false, result);
1209         assertFieldErrorExists("incomeStreamAccountNumber", KFSKeyConstants.ERROR_EXISTENCE);
1210         assertGlobalMessageMapSize(1);
1211 
1212     }
1213 
1214     @SuppressWarnings("deprecation")
1215     public void testCheckIncomeStreamRequired_GFAcctNoIncomeStreamFields() {
1216         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_FUND_GROUPS, "GF;CG");
1217         TestUtils.setSystemParameter(Account.class, KFSConstants.ChartApcParms.INCOME_STREAM_ACCOUNT_REQUIRING_SUB_FUND_GROUPS, "MPRACT");
1218 
1219         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1220         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1221         boolean result;
1222 
1223         // create the populated CG subfundgroup
1224         SubFundGroup subFundGroup = new SubFundGroup();
1225         subFundGroup.setSubFundGroupCode(Accounts.SubFund.Code.GF1);
1226         subFundGroup.setFundGroupCode(Accounts.SubFund.FundGroupCode.GF1);
1227         subFundGroup.setActive(true);
1228 
1229         // add the subFundGroup info to Account
1230         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.GF1);
1231         newAccount.setSubFundGroup(subFundGroup);
1232 
1233         // make sure the income stream fields are blank
1234         newAccount.setIncomeStreamFinancialCoaCode(null);
1235         newAccount.setIncomeStreamAccountNumber(null);
1236         newAccount.setIncomeStreamAccount(null);
1237 
1238         // run the rule
1239         result = rule.checkIncomeStreamValid(newAccount);
1240         assertEquals("GF Account with no Income Stream data should fail.", false, result);
1241         assertFieldErrorExists("incomeStreamFinancialCoaCode", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_INCOME_STREAM_ACCT_COA_CANNOT_BE_EMPTY);
1242         assertFieldErrorExists("incomeStreamAccountNumber", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_INCOME_STREAM_ACCT_NBR_CANNOT_BE_EMPTY);
1243         assertGlobalMessageMapSize(2);
1244 
1245     }
1246 
1247     @SuppressWarnings("deprecation")
1248     public void testCheckUniqueAccountNumber_AccountsCanCrossCharts() {
1249         TestUtils.setSystemParameter(KfsParameterConstants.FINANCIAL_SYSTEM_ALL.class, SystemGroupParameterNames.ACCOUNTS_CAN_CROSS_CHARTS_IND, "Y");
1250 
1251         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1252         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1253         boolean result;
1254 
1255         // find an existing account
1256         Iterator accountList = SpringContext.getBean(AccountService.class).getAllAccounts();
1257         Account account = accountList.hasNext() ? (Account)accountList.next() : null;
1258         if (account == null)
1259          {
1260             return; // shouldn't happen: there shall always be some accounts in the system
1261         }
1262 
1263         // set new COA code different from the existing account
1264         String chartCode = account.getChartOfAccountsCode().equals("BL") ? "BA" : "BL";
1265         newAccount.setChartOfAccountsCode(chartCode);
1266 
1267         // set new account number same as the existing account
1268         String accountNumber = account.getAccountNumber();
1269         newAccount.setAccountNumber(accountNumber);
1270 
1271         // run the rule
1272         result = rule.checkUniqueAccountNumber(maintDoc);
1273         assertEquals("Accounts should be allowed to cross charts with current settings", true, result);
1274         this.assertFieldErrorDoesNotExist("accountNumber", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_ACCT_NMBR_NOT_UNIQUE);
1275         assertGlobalMessageMapSize(0);
1276     }
1277 
1278     @SuppressWarnings("deprecation")
1279     public void testCheckUniqueAccountNumber_AccountsCantCrossCharts() {
1280         TestUtils.setSystemParameter(KfsParameterConstants.FINANCIAL_SYSTEM_ALL.class, SystemGroupParameterNames.ACCOUNTS_CAN_CROSS_CHARTS_IND, "N");
1281 
1282         MaintenanceDocument maintDoc = newMaintDoc(newAccount);
1283         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1284         boolean result;
1285 
1286         // find an existing account
1287         Iterator accountList = SpringContext.getBean(AccountService.class).getAllAccounts();
1288         Account account = accountList.hasNext() ? (Account)accountList.next() : null;
1289         if (account == null)
1290          {
1291             return; // shouldn't happen: there shall always be some accounts in the system
1292         }
1293 
1294         // set new COA code different from the existing account
1295         String chartCode = account.getChartOfAccountsCode().equals("BL") ? "BA" : "BL";
1296         newAccount.setChartOfAccountsCode(chartCode);
1297 
1298         // set new account number same as the existing account
1299         String accountNumber = account.getAccountNumber();
1300         newAccount.setAccountNumber(accountNumber);
1301 
1302         // run the rule
1303         result = rule.checkUniqueAccountNumber(maintDoc);
1304         assertEquals("Accounts shouldn't be allowed to cross charts with current settings", false, result);
1305         assertFieldErrorExists("accountNumber", KFSKeyConstants.ERROR_DOCUMENT_ACCMAINT_ACCT_NMBR_NOT_UNIQUE);
1306         assertGlobalMessageMapSize(1);
1307     }
1308 
1309     public void testIsUpdateExpirationDateInvalid_BothExpirationDatesNull() {
1310 
1311         Account oldAccount = new Account();
1312 
1313         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1314         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1315         boolean result;
1316 
1317         // set both expiration dates to null
1318         oldAccount.setAccountExpirationDate(null);
1319         newAccount.setAccountExpirationDate(null);
1320 
1321         result = rule.isUpdatedExpirationDateInvalid(maintDoc);
1322         assertEquals("Doc with no expiration dates should return false.", false, result);
1323 
1324     }
1325 
1326     public void testIsUpdateExpirationDateInvalid_ExpirationDatesSame() {
1327 
1328         Account oldAccount = new Account();
1329 
1330         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1331         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1332         boolean result;
1333 
1334         // get today's date
1335         Date todaysDate = new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime());
1336 
1337         // set both expiration dates to null
1338         oldAccount.setAccountExpirationDate(todaysDate);
1339         newAccount.setAccountExpirationDate(todaysDate);
1340 
1341         result = rule.isUpdatedExpirationDateInvalid(maintDoc);
1342         assertEquals("Doc with same expiration dates should return false.", false, result);
1343 
1344     }
1345 
1346     public void testIsUpdateExpirationDateInvalid_NewExpDateNull() {
1347 
1348         Account oldAccount = new Account();
1349 
1350         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1351         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1352         boolean result;
1353 
1354         // get today's date
1355         Date todaysDate = new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime());
1356 
1357         // set both expiration dates to null
1358         oldAccount.setAccountExpirationDate(todaysDate);
1359         newAccount.setAccountExpirationDate(null);
1360 
1361         result = rule.isUpdatedExpirationDateInvalid(maintDoc);
1362         assertEquals("Doc with null new expiration dates should return false.", false, result);
1363 
1364     }
1365 
1366     @SuppressWarnings("deprecation")
1367     public void testIsUpdateExpirationDateInvalid_SubFundGroupNull() {
1368 
1369         Account oldAccount = new Account();
1370 
1371         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1372         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1373         boolean result;
1374 
1375         // get today's date
1376         Calendar calendar;
1377         Date todaysDate = new Date(SpringContext.getBean(DateTimeService.class).getCurrentTimestamp().getTime());
1378 
1379         // old exp date
1380         calendar = Calendar.getInstance();
1381         calendar.set(1900, 1, 1);
1382         Date oldDate = new Date(calendar.getTimeInMillis());
1383 
1384         // new exp date
1385         Date newDate = todaysDate;
1386 
1387         // set both expiration dates to null
1388         oldAccount.setAccountExpirationDate(oldDate);
1389         newAccount.setAccountExpirationDate(newDate);
1390 
1391         // set subfund group to null
1392         newAccount.setSubFundGroupCode(null);
1393         newAccount.setSubFundGroup(null);
1394 
1395         // run the rule
1396         result = rule.isUpdatedExpirationDateInvalid(maintDoc);
1397         assertEquals("Doc with changed exp dates, but no subfund group should false.", false, result);
1398 
1399     }
1400 
1401     @SuppressWarnings("deprecation")
1402     public void testIsUpdateExpirationDateInvalid_ChangedNewInPast_CGSubFund() {
1403 
1404         Account oldAccount = new Account();
1405 
1406         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1407         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1408         boolean result;
1409 
1410         // get today's date
1411         Calendar calendar;
1412         Date todaysDate = new Date(SpringContext.getBean(DateTimeService.class).getCurrentTimestamp().getTime());
1413 
1414         // old exp date
1415         calendar = Calendar.getInstance();
1416         calendar.set(1900, 1, 1);
1417         Date oldDate = new Date(calendar.getTimeInMillis());
1418 
1419         // new exp date
1420         calendar = Calendar.getInstance();
1421         calendar.set(2000, 1, 1);
1422         Date newDate = new Date(calendar.getTimeInMillis());
1423 
1424         // set both expiration dates to null
1425         oldAccount.setAccountExpirationDate(oldDate);
1426         newAccount.setAccountExpirationDate(newDate);
1427 
1428         // setup new subfund
1429         SubFundGroup subFundGroup = new SubFundGroup();
1430         subFundGroup.setFundGroupCode(Accounts.SubFund.Code.CG1);
1431         subFundGroup.setSubFundGroupCode(Accounts.SubFund.FundGroupCode.CG1);
1432 
1433         // set subfund group to null
1434         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.CG1);
1435         newAccount.setSubFundGroup(subFundGroup);
1436 
1437         // run the rule
1438         result = rule.isUpdatedExpirationDateInvalid(maintDoc);
1439         assertEquals("Doc with changed exp dates, CG fundgroup should be false.", false, result);
1440 
1441     }
1442 
1443     @SuppressWarnings("deprecation")
1444     public void testIsUpdateExpirationDateInvalid_ChangedNewInPast_NonCGSubFund() {
1445 
1446         Account oldAccount = new Account();
1447 
1448         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1449         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1450         boolean result;
1451 
1452         // get today's date
1453         Calendar calendar;
1454         Date todaysDate = new Date(SpringContext.getBean(DateTimeService.class).getCurrentDate().getTime());
1455 
1456         // old exp date
1457         calendar = Calendar.getInstance();
1458         calendar.set(1900, 1, 1);
1459         Date oldDate = new Date(calendar.getTimeInMillis());
1460 
1461         // new exp date
1462         calendar = Calendar.getInstance();
1463         calendar.set(2000, 1, 1);
1464         Date newDate = new Date(calendar.getTimeInMillis());
1465 
1466         // set both expiration dates to null
1467         oldAccount.setAccountExpirationDate(oldDate);
1468         newAccount.setAccountExpirationDate(newDate);
1469 
1470         // setup new subfund
1471         SubFundGroup subFundGroup = new SubFundGroup();
1472         subFundGroup.setFundGroupCode(Accounts.SubFund.Code.GF1);
1473         subFundGroup.setSubFundGroupCode(Accounts.SubFund.FundGroupCode.GF1);
1474 
1475         // set subfund group to null
1476         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.GF1);
1477         newAccount.setSubFundGroup(subFundGroup);
1478 
1479         // run the rule
1480         result = rule.isUpdatedExpirationDateInvalid(maintDoc);
1481         assertEquals("Doc with changed exp dates, exp in past should be false.", false, result);
1482 
1483     }
1484 
1485     @SuppressWarnings("deprecation")
1486     public void testDataDictionaryValidation_AccountPurpose_TooLong() {
1487         Account oldAccount = new Account();
1488         newAccount.setAccountGuideline(new AccountGuideline());
1489         newAccount.getAccountGuideline().setAccountPurposeText("01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "01324567890123456789012345678901324567890132456789012345678901234567890132456789");
1490         assertTrue("Purpose text should be more than 400 characters.  (was: " + newAccount.getAccountGuideline().getAccountPurposeText().length() + ")", newAccount.getAccountGuideline().getAccountPurposeText().length() > 400);
1491 
1492         // setup new subfund
1493         SubFundGroup subFundGroup = new SubFundGroup();
1494         subFundGroup.setFundGroupCode(Accounts.SubFund.Code.GF1);
1495         subFundGroup.setSubFundGroupCode(Accounts.SubFund.FundGroupCode.GF1);
1496 
1497         // set subfund group to null
1498         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.GF1);
1499         newAccount.setSubFundGroup(subFundGroup);
1500 
1501         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1502         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1503         rule.processCustomRouteDocumentBusinessRules(maintDoc);
1504         // System.out.println( GlobalVariables.getMessageMap().entrySet() );
1505         assertFieldErrorExists("accountGuideline.accountPurposeText", KFSKeyConstants.ERROR_MAX_LENGTH);
1506     }
1507 
1508     @SuppressWarnings("deprecation")
1509     public void testDataDictionaryValidation_AccountPurpose_GoodLength() {
1510         Account oldAccount = new Account();
1511         newAccount.setAccountGuideline(new AccountGuideline());
1512         newAccount.getAccountGuideline().setAccountPurposeText("01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "01324567890123456789012345678901324567890132456789012345678901234567890132456789\r" + "013245678901234567890123456789013245678901324567890123456789012345678901324");
1513         System.out.println(newAccount.getAccountGuideline().getAccountPurposeText().length());
1514         assertTrue("Purpose text should be <= 400 characters.  (was: " + newAccount.getAccountGuideline().getAccountPurposeText().length() + ")", newAccount.getAccountGuideline().getAccountPurposeText().length() <= 400);
1515         // setup new subfund
1516         SubFundGroup subFundGroup = new SubFundGroup();
1517         subFundGroup.setFundGroupCode(Accounts.SubFund.Code.GF1);
1518         subFundGroup.setSubFundGroupCode(Accounts.SubFund.FundGroupCode.GF1);
1519 
1520         // set subfund group to null
1521         newAccount.setSubFundGroupCode(Accounts.SubFund.Code.GF1);
1522         newAccount.setSubFundGroup(subFundGroup);
1523 
1524         MaintenanceDocument maintDoc = newMaintDoc(oldAccount, newAccount);
1525         AccountRule rule = (AccountRule) setupMaintDocRule(maintDoc, AccountRule.class);
1526         rule.processCustomRouteDocumentBusinessRules(maintDoc);
1527         System.out.println(GlobalVariables.getMessageMap().getAllPropertiesAndErrors());
1528         assertFieldErrorDoesNotExist("accountGuideline.accountPurposeText", KFSKeyConstants.ERROR_MAX_LENGTH);
1529     }
1530 }