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.gl.batch;
20  
21  import java.sql.Date;
22  import java.sql.Timestamp;
23  import java.text.ParseException;
24  import java.text.SimpleDateFormat;
25  import java.util.Calendar;
26  import java.util.GregorianCalendar;
27  import java.util.HashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  import org.kuali.kfs.coa.businessobject.A21SubAccount;
32  import org.kuali.kfs.coa.businessobject.OffsetDefinition;
33  import org.kuali.kfs.coa.service.A21SubAccountService;
34  import org.kuali.kfs.coa.service.ObjectTypeService;
35  import org.kuali.kfs.coa.service.OrganizationReversionService;
36  import org.kuali.kfs.coa.service.PriorYearAccountService;
37  import org.kuali.kfs.fp.businessobject.OffsetAccount;
38  import org.kuali.kfs.gl.GeneralLedgerConstants;
39  import org.kuali.kfs.gl.batch.service.EncumbranceClosingOriginEntryGenerationService;
40  import org.kuali.kfs.gl.batch.service.OrganizationReversionProcess;
41  import org.kuali.kfs.gl.batch.service.OrganizationReversionProcessService;
42  import org.kuali.kfs.gl.batch.service.OrganizationReversionUnitOfWorkService;
43  import org.kuali.kfs.gl.batch.service.impl.CashOrganizationReversionCategoryLogic;
44  import org.kuali.kfs.gl.batch.service.impl.OrganizationReversionMockServiceImpl;
45  import org.kuali.kfs.gl.batch.service.impl.OriginEntryOffsetPair;
46  import org.kuali.kfs.gl.batch.service.impl.exception.FatalErrorException;
47  import org.kuali.kfs.gl.businessobject.Balance;
48  import org.kuali.kfs.gl.businessobject.Encumbrance;
49  import org.kuali.kfs.gl.businessobject.OriginEntryFull;
50  import org.kuali.kfs.gl.businessobject.OriginEntryInformation;
51  import org.kuali.kfs.gl.businessobject.OriginEntryTestBase;
52  import org.kuali.kfs.gl.service.BalanceService;
53  import org.kuali.kfs.sys.ConfigureContext;
54  import org.kuali.kfs.sys.KFSConstants;
55  import org.kuali.kfs.sys.businessobject.SystemOptions;
56  import org.kuali.kfs.sys.context.SpringContext;
57  import org.kuali.kfs.sys.context.TestUtils;
58  import org.kuali.kfs.sys.service.OptionsService;
59  import org.kuali.kfs.sys.service.UniversityDateService;
60  import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
61  import org.kuali.rice.core.api.datetime.DateTimeService;
62  import org.kuali.rice.core.api.util.type.KualiDecimal;
63  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
64  import org.kuali.rice.krad.service.BusinessObjectService;
65  
66  /*
67   * Unit tests to verify that flexible offsets are being added to year end origin entries correctly
68   */
69  @ConfigureContext
70  public class YearEndFlexibleOffsetTest extends OriginEntryTestBase {
71      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(YearEndFlexibleOffsetTest.class);
72  
73      public static final String DEFAULT_FLEXIBLE_BALANCE_CHART = "BL";
74      public static final String DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR = "1031400";
75      public static final String DEFAULT_NO_FLEXIBLE_BALANCE_CHART = "BL";
76      public static final String DEFAULT_NO_FLEXIBLE_BALANCE_ACCOUNT_NBR = "1031420";
77      public static final String DEFAULT_FLEXIBLE_ENCUMBRANCE_CHART = "BL";
78      public static final String DEFAULT_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR = "4531402";
79      public static String DEFAULT_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR;
80      public static final String DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_CHART = "BL";
81      public static final String DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR = "4531403";
82      public static String DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR;
83      public static final String CS_FLEXIBLE_ENCUMBRANCE_CHART = "BL";
84      public static final String CS_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR = "4031418";
85      public static final String CS_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR = "CS001";
86      public static final String CS_NO_FLEXIBLE_ENCUMBRANCE_CHART = "BL";
87      public static final String CS_NO_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR = "4431423";
88      public static final String CS_NO_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR = "CS001";
89      public static final KualiDecimal DEFAULT_FIXTURE_AMOUNT = new KualiDecimal(3000);
90      public static final String DEFAULT_EXPENSE_OBJECT_CODE = "4680";
91      public static final String DEFAULT_NOMINAL_ACTIVITY_OFFSET_OBJECT_CODE = "9899";
92      public static final String DEFAULT_ENCUMBRANCE_OFFSET_OBJECT_CODE = "9892";
93      public static final String DEFAULT_COST_SHARE_ENCUMBRANCE_OFFSET_OBJECT_CODE = "9893";
94      public static final String DEFAULT_ENCUMBRANCE_BALANCE_TYPE_CODE = "EX";
95      public static final String DEFAULT_OFFSET_CHART = "BL";
96      public static final String DEFAULT_OFFSET_ACCOUNT_NBR = "0211201";
97      public static final String ORG_REVERSION_CASH_OBJECT_CODE = "8000";
98  
99      private BusinessObjectService boService;
100     private ParameterService parameterService;
101     private ObjectTypeService objectTypeService;
102     private Integer fiscalYear;
103     private Date transactionDate;
104 
105     enum NOMINAL_ACTIVITY_BALANCE_FIXTURE {
106         FLEXIBLE_NOMINAL_ACTIVITY_BALANCE(DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR),
107         INFLEXIBLE_NOMINAL_ACTIVITY_BALANCE(DEFAULT_NO_FLEXIBLE_BALANCE_CHART, DEFAULT_NO_FLEXIBLE_BALANCE_ACCOUNT_NBR);
108 
109         private String chartCode;
110         private String accountNumber;
111         private KualiDecimal amount;
112         private Date timestamp;
113         private static final String DATE_FORMAT = "yyyy-MM-dd";
114         private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(NOMINAL_ACTIVITY_BALANCE_FIXTURE.class);
115         private SystemOptions fsOptions = SpringContext.getBean(OptionsService.class).getCurrentYearOptions();
116 
117         private NOMINAL_ACTIVITY_BALANCE_FIXTURE(String chartCode, String accountNumber) {
118             this.chartCode = chartCode;
119             this.accountNumber = accountNumber;
120         }
121 
122         /**
123          * Converts the fixture into a balance to test
124          *
125          * @return a balance represented by this fixture
126          */
127         public Balance convertToBalance() {
128             Balance balance = new Balance();
129             balance.setUniversityFiscalYear(TestUtils.getFiscalYearForTesting().intValue());
130             balance.setChartOfAccountsCode(chartCode);
131             balance.setAccountNumber(accountNumber);
132             balance.setSubAccountNumber(KFSConstants.getDashSubAccountNumber());
133             balance.setObjectCode(DEFAULT_EXPENSE_OBJECT_CODE);
134             balance.setSubObjectCode(KFSConstants.getDashFinancialSubObjectCode());
135             balance.setBalanceTypeCode(fsOptions.getActualFinancialBalanceTypeCd());
136             balance.setObjectTypeCode(fsOptions.getFinObjTypeCshNotIncomeCd());
137             balance.setAccountLineAnnualBalanceAmount(DEFAULT_FIXTURE_AMOUNT);
138             balance.setBeginningBalanceLineAmount(KualiDecimal.ZERO);
139             balance.setContractsGrantsBeginningBalanceAmount(KualiDecimal.ZERO);
140             balance.setMonth1Amount(amount);
141             balance.setMonth2Amount(KualiDecimal.ZERO);
142             balance.setMonth3Amount(KualiDecimal.ZERO);
143             balance.setMonth4Amount(KualiDecimal.ZERO);
144             balance.setMonth5Amount(KualiDecimal.ZERO);
145             balance.setMonth6Amount(KualiDecimal.ZERO);
146             balance.setMonth7Amount(KualiDecimal.ZERO);
147             balance.setMonth8Amount(KualiDecimal.ZERO);
148             balance.setMonth9Amount(KualiDecimal.ZERO);
149             balance.setMonth10Amount(KualiDecimal.ZERO);
150             balance.setMonth11Amount(KualiDecimal.ZERO);
151             balance.setMonth12Amount(KualiDecimal.ZERO);
152             balance.setMonth13Amount(KualiDecimal.ZERO);
153             try {
154                 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
155                 java.util.Date jud = sdf.parse(SpringContext.getBean(ParameterService.class).getParameterValueAsString(KfsParameterConstants.GENERAL_LEDGER_BATCH.class, GeneralLedgerConstants.ANNUAL_CLOSING_TRANSACTION_DATE_PARM));
156                 balance.setTimestamp(new java.sql.Date(jud.getTime()));
157             }
158             catch (ParseException e) {
159                 LOG.debug("Parse date exception while parsing transaction date");
160             }
161             balance.refresh();
162             return balance;
163         }
164     };
165 
166     enum ENCUMBRANCE_FORWARD_FIXTURE {
167         FLEXIBLE_ENCUMBRANCE(DEFAULT_FLEXIBLE_ENCUMBRANCE_CHART, DEFAULT_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, DEFAULT_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR),
168         INFLEXIBLE_ENCUMBRANCE(DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_CHART, DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR),
169         FLEXIBLE_COST_SHARE_ENCUMBRANCE(CS_FLEXIBLE_ENCUMBRANCE_CHART, CS_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, CS_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR),
170         INFLEXIBLE_COST_SHARE_ENCUMBRANCE(CS_NO_FLEXIBLE_ENCUMBRANCE_CHART, CS_NO_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, CS_NO_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR);
171 
172         private ENCUMBRANCE_FORWARD_FIXTURE(String chart, String account, String subAccount) {
173             this.chartOfAccountsCode = chart;
174             this.accountNumber = account;
175             this.subAccountNumber = subAccount;
176         }
177 
178         private String chartOfAccountsCode;
179         private String accountNumber;
180         private String subAccountNumber;
181 
182         public Encumbrance convertToEncumbrance() {
183             Encumbrance encumbrance = new Encumbrance();
184             encumbrance.setUniversityFiscalYear(TestUtils.getFiscalYearForTesting().intValue() - 1);
185             encumbrance.setChartOfAccountsCode(this.chartOfAccountsCode);
186             encumbrance.setAccountNumber(this.accountNumber);
187             encumbrance.setSubAccountNumber(this.subAccountNumber);
188             encumbrance.setObjectCode(DEFAULT_EXPENSE_OBJECT_CODE);
189             encumbrance.setSubObjectCode(subAccountNumber);
190             encumbrance.setBalanceTypeCode(DEFAULT_ENCUMBRANCE_BALANCE_TYPE_CODE);
191             encumbrance.setDocumentTypeCode("EXEN");
192             encumbrance.setOriginCode("02");
193             encumbrance.setDocumentNumber("200200");
194             encumbrance.setTransactionEncumbranceDescription("Test Encumbrance");
195             encumbrance.setTransactionEncumbranceDate(getEncumbranceDate());
196             encumbrance.setAccountLineEncumbranceAmount(DEFAULT_FIXTURE_AMOUNT);
197             encumbrance.setAccountLineEncumbranceClosedAmount(KualiDecimal.ZERO);
198             encumbrance.setAccountLineEncumbrancePurgeCode(" ");
199             encumbrance.setTimestamp(new Timestamp(getEncumbranceDate().getTime()));
200             return encumbrance;
201         }
202 
203         private Date getEncumbranceDate() {
204             Calendar cal = new GregorianCalendar();
205             cal.set(Calendar.MONTH, Calendar.JANUARY);
206             cal.set(Calendar.DAY_OF_MONTH, 1);
207             cal.set(Calendar.YEAR, ((SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()).intValue() - 1));
208             return new Date(cal.getTimeInMillis());
209         }
210     }
211 
212     enum ORG_REVERSION_BALANCE_FIXTURE {
213         FLEXIBLE_ORG_REVERSION_BALANCE(DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR),
214         INFLEXIBLE_ORG_REVERSION_BALANCE(DEFAULT_NO_FLEXIBLE_BALANCE_CHART, DEFAULT_NO_FLEXIBLE_BALANCE_ACCOUNT_NBR);
215 
216         private String chartCode;
217         private String accountNumber;
218         private KualiDecimal amount;
219         private Date timestamp;
220         private static final String DATE_FORMAT = "yyyy-MM-dd";
221         private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(NOMINAL_ACTIVITY_BALANCE_FIXTURE.class);
222         private SystemOptions fsOptions = SpringContext.getBean(OptionsService.class).getCurrentYearOptions();
223 
224         private ORG_REVERSION_BALANCE_FIXTURE(String chartCode, String accountNumber) {
225             this.chartCode = chartCode;
226             this.accountNumber = accountNumber;
227         }
228 
229         /**
230          * Converts the fixture into a balance to test
231          *
232          * @return a balance represented by this fixture
233          */
234         public Balance convertToBalance() {
235             Balance balance = new Balance();
236             balance.setChartOfAccountsCode(chartCode);
237             balance.setAccountNumber(accountNumber);
238             balance.setSubAccountNumber(KFSConstants.getDashSubAccountNumber());
239             balance.setObjectCode(ORG_REVERSION_CASH_OBJECT_CODE);
240             balance.setSubObjectCode(KFSConstants.getDashFinancialSubObjectCode());
241             balance.setBalanceTypeCode(fsOptions.getActualFinancialBalanceTypeCd());
242             balance.setObjectTypeCode(fsOptions.getFinObjTypeCshNotIncomeCd());
243             balance.setAccountLineAnnualBalanceAmount(DEFAULT_FIXTURE_AMOUNT);
244             balance.setBeginningBalanceLineAmount(KualiDecimal.ZERO);
245             balance.setContractsGrantsBeginningBalanceAmount(KualiDecimal.ZERO);
246             balance.setMonth1Amount(amount);
247             balance.setMonth2Amount(KualiDecimal.ZERO);
248             balance.setMonth3Amount(KualiDecimal.ZERO);
249             balance.setMonth4Amount(KualiDecimal.ZERO);
250             balance.setMonth5Amount(KualiDecimal.ZERO);
251             balance.setMonth6Amount(KualiDecimal.ZERO);
252             balance.setMonth7Amount(KualiDecimal.ZERO);
253             balance.setMonth8Amount(KualiDecimal.ZERO);
254             balance.setMonth9Amount(KualiDecimal.ZERO);
255             balance.setMonth10Amount(KualiDecimal.ZERO);
256             balance.setMonth11Amount(KualiDecimal.ZERO);
257             balance.setMonth12Amount(KualiDecimal.ZERO);
258             balance.setMonth13Amount(KualiDecimal.ZERO);
259             try {
260                 SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
261                 java.util.Date jud = sdf.parse(SpringContext.getBean(ParameterService.class).getParameterValueAsString(KfsParameterConstants.GENERAL_LEDGER_BATCH.class, GeneralLedgerConstants.ANNUAL_CLOSING_TRANSACTION_DATE_PARM));
262                 balance.setTimestamp(new java.sql.Date(jud.getTime()));
263             }
264             catch (ParseException e) {
265                 LOG.debug("Parse date exception while parsing transaction date");
266             }
267             balance.refresh();
268             return balance;
269         }
270     };
271 
272     public enum FLEXIBLE_OFFSET_ACCOUNT_FIXTURE {
273         FLEXIBLE_ACTIVITY_CLOSING_OFFSET_ACCOUNT(DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR, DEFAULT_NOMINAL_ACTIVITY_OFFSET_OBJECT_CODE),
274         FLEXIBLE_ENCUMBRANCE_FORWARD_OFFSET_ACCOUNT(DEFAULT_FLEXIBLE_ENCUMBRANCE_CHART, DEFAULT_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, DEFAULT_ENCUMBRANCE_OFFSET_OBJECT_CODE),
275         FLEXIBLE_CS_ENCUMBRANCE_FORWARD_OFFSET_ACCOUNT(DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR, DEFAULT_COST_SHARE_ENCUMBRANCE_OFFSET_OBJECT_CODE),
276         CASH_REVERSION_FORWARD_OFFSET_ACCOUNT(OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_CHART, OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_ACCOUNT, DEFAULT_NOMINAL_ACTIVITY_OFFSET_OBJECT_CODE);
277 
278         private String chartCode;
279         private String accountNumber;
280         private String objectCode;
281 
282         private FLEXIBLE_OFFSET_ACCOUNT_FIXTURE(String chartCode, String accountNumber, String objectCode) {
283             this.chartCode = chartCode;
284             this.accountNumber = accountNumber;
285             this.objectCode = objectCode;
286         }
287 
288         public OffsetAccount convertToOffsetAccount() {
289             OffsetAccount offset = new OffsetAccount();
290             offset.setChartOfAccountsCode(this.chartCode);
291             offset.setAccountNumber(this.accountNumber);
292             offset.setFinancialOffsetObjectCode(this.objectCode);
293             offset.setFinancialOffsetChartOfAccountCode(DEFAULT_OFFSET_CHART);
294             offset.setFinancialOffsetAccountNumber(DEFAULT_OFFSET_ACCOUNT_NBR);
295             return offset;
296         }
297     }
298 
299     /**
300      * Initialize defaults for each test.
301      * @see org.kuali.kfs.gl.businessobject.OriginEntryTestBase#setUp()
302      */
303     @Override
304     public void setUp() throws Exception {
305         super.setUp();
306 
307         this.boService = SpringContext.getBean(BusinessObjectService.class);
308         this.fiscalYear = new Integer((SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear()).intValue() - 1);
309         this.transactionDate = new java.sql.Date(new java.util.Date().getTime());
310         this.parameterService = SpringContext.getBean(ParameterService.class);
311         this.objectTypeService = SpringContext.getBean(ObjectTypeService.class);
312 
313         DEFAULT_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR = KFSConstants.getDashSubAccountNumber();
314         DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR = KFSConstants.getDashSubAccountNumber();
315 
316         createFlexibleOffsetAccounts();
317     }
318 
319     /**
320      * Test that:
321      * <ol>
322      *  <li>when flexible offsets are turned on, nominal activity offsets that should get flexible offsets get them</li>
323      *  <li>when flexible offsets are turned on, nominal activity offsets that should not get flexible offsets don't get them</li>
324      *  <li>when flexible offsets are turned on, nominal activity entries do not get flexible offsets</li>
325      * </ol>
326      */
327     public void testNominalActivityFlexibleOffsetsWhenOffsetsOn() {
328         try {
329             NominalActivityClosingHelper closingHelper = new NominalActivityClosingHelper(fiscalYear, transactionDate, parameterService, kualiConfigurationService, objectTypeService);
330             OriginEntryInformation entry;
331 
332             // 1. flexible offsets on, flexible offset should be updated
333             toggleFlexibleOffsets(true);
334             entry = closingHelper.generateOffset(NOMINAL_ACTIVITY_BALANCE_FIXTURE.FLEXIBLE_NOMINAL_ACTIVITY_BALANCE.convertToBalance(), 1);
335             assertChartAndAccount(entry, DEFAULT_OFFSET_CHART, DEFAULT_OFFSET_ACCOUNT_NBR);
336 
337             // 2. flexible offsets on, but balances without matching offsets should not be updated
338             entry = closingHelper.generateOffset(NOMINAL_ACTIVITY_BALANCE_FIXTURE.INFLEXIBLE_NOMINAL_ACTIVITY_BALANCE.convertToBalance(), 1);
339             assertChartAndAccount(entry, DEFAULT_NO_FLEXIBLE_BALANCE_CHART, DEFAULT_NO_FLEXIBLE_BALANCE_ACCOUNT_NBR);
340 
341             // 3. flexible offsets on, but activity offsets stay the same!
342             entry = closingHelper.generateActivityEntry(NOMINAL_ACTIVITY_BALANCE_FIXTURE.FLEXIBLE_NOMINAL_ACTIVITY_BALANCE.convertToBalance(), 1);
343             assertChartAndAccount(entry, DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR);
344 
345         } catch (FatalErrorException fee) {
346             throw new RuntimeException(fee);
347         }
348     }
349 
350     /**
351      * Test that:
352      * <ol>
353      *  <li>when flexible offsets are turned off, nominal activity offsets that should get flexible offsets don't get them</li>
354      * </ol>
355      */
356     public void testNominalActivityFlexibleOffsetsWhenOffsetsOff() {
357         try {
358             NominalActivityClosingHelper closingHelper = new NominalActivityClosingHelper(fiscalYear, transactionDate, parameterService, kualiConfigurationService, objectTypeService);
359             OriginEntryInformation entry;
360 
361             // 1. flexible offsets off, flexible offset should not be updated
362             toggleFlexibleOffsets(false);
363             entry = closingHelper.generateOffset(NOMINAL_ACTIVITY_BALANCE_FIXTURE.FLEXIBLE_NOMINAL_ACTIVITY_BALANCE.convertToBalance(), 1);
364             assertChartAndAccount(entry, DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR);
365 
366         } catch (FatalErrorException fee) {
367             throw new RuntimeException(fee);
368         }
369     }
370 
371     /**
372      * Test that:
373      * <ol>
374      *  <li>when flexible offsets are turned on, encumbrance forward offsets that should get flexible offsets get them</li>
375      *  <li>when flexible offsets are turned on, encumbrance forward offsets that should not get flexible offsets don't get them</li>
376      *  <li>when flexible offsets are turned on, encumbrance forward entries do not get flexible offsets</li>
377      * </ol>
378      */
379     public void testEncumbranceForwardFlexibleOffsetsWhenFlexibleOffsetsOn() {
380         OriginEntryOffsetPair entryPair;
381         toggleFlexibleOffsets(true);
382 
383         final EncumbranceClosingOriginEntryGenerationService encumbranceClosingOriginEntryGenerationSerivce = SpringContext.getBean(EncumbranceClosingOriginEntryGenerationService.class);
384 
385         // 1. when flexible offsets are turned on, encumbrance forward offsets that should get flexible offsets get them
386         entryPair = encumbranceClosingOriginEntryGenerationSerivce.createBeginningBalanceEntryOffsetPair(ENCUMBRANCE_FORWARD_FIXTURE.FLEXIBLE_ENCUMBRANCE.convertToEncumbrance(), fiscalYear, transactionDate);
387         assertChartAndAccount(entryPair.getOffset(), DEFAULT_OFFSET_CHART, DEFAULT_OFFSET_ACCOUNT_NBR);
388         // 2. when flexible offsets are turned on, encumbrance forward entries do not get flexible offsets
389         assertChartAndAccount(entryPair.getEntry(), DEFAULT_FLEXIBLE_ENCUMBRANCE_CHART, DEFAULT_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR);
390 
391         // 3. when flexible offsets are turned on, encumbrance forward offsets that should not get flexible offsets don't get them
392         entryPair = encumbranceClosingOriginEntryGenerationSerivce.createBeginningBalanceEntryOffsetPair(ENCUMBRANCE_FORWARD_FIXTURE.INFLEXIBLE_ENCUMBRANCE.convertToEncumbrance(), fiscalYear, transactionDate);
393         assertChartAndAccount(entryPair.getOffset(), DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_CHART, DEFAULT_NO_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR);
394     }
395 
396     /**
397      * Test that:
398      * <ol>
399      *  <li>when flexible offsets are turned off, encumbrance forward offsets that should get flexible offsets don't get them</li>
400      * </ol>
401      */
402     public void testEncumbranceForwardFlexibleOffsetsWhenFlexibleOffsetsOff() {
403         OriginEntryOffsetPair entryPair;
404         toggleFlexibleOffsets(false);
405 
406         final EncumbranceClosingOriginEntryGenerationService encumbranceClosingOriginEntryGenerationSerivce = SpringContext.getBean(EncumbranceClosingOriginEntryGenerationService.class);
407 
408         // 1. when flexible offsets are turned off, encumbrance forward offsets that should get flexible offsets do not get them
409         entryPair = encumbranceClosingOriginEntryGenerationSerivce.createBeginningBalanceEntryOffsetPair(ENCUMBRANCE_FORWARD_FIXTURE.FLEXIBLE_ENCUMBRANCE.convertToEncumbrance(), fiscalYear, transactionDate);
410         assertChartAndAccount(entryPair.getEntry(), DEFAULT_FLEXIBLE_ENCUMBRANCE_CHART, DEFAULT_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR);
411     }
412 
413     /**
414      * Test that:
415      * <ul>
416      *  <li>when flexible offsets are turned on, encumbrance forward cost share offsets that should get flexible offsets get them</li>
417      *  <li>when flexible offsets are turned on, encumbrance forward cost share offsets that should not get flexible offsets don't get them</li>
418      *  <li>when flexible offsets are turned on, encumbrance forward cost share entries do not get flexible offsets</li>
419      * </ul>
420      */
421     public void testEncumbranceForwardCostShareFlexibleOffsetsWhenFlexibleOffsetsOn() {
422         OriginEntryOffsetPair entryPair;
423         A21SubAccount a21SubAccount;
424         toggleFlexibleOffsets(true);
425 
426         final EncumbranceClosingOriginEntryGenerationService encumbranceClosingOriginEntryGenerationSerivce = SpringContext.getBean(EncumbranceClosingOriginEntryGenerationService.class);
427 
428         // 1. when flexible offsets are turned on, encumbrance forward cost share offsets that should get flexible offsets get them
429         a21SubAccount = SpringContext.getBean(A21SubAccountService.class).getByPrimaryKey(CS_FLEXIBLE_ENCUMBRANCE_CHART, CS_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, CS_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR);
430         entryPair = encumbranceClosingOriginEntryGenerationSerivce.createCostShareBeginningBalanceEntryOffsetPair(ENCUMBRANCE_FORWARD_FIXTURE.FLEXIBLE_COST_SHARE_ENCUMBRANCE.convertToEncumbrance(), transactionDate);
431         assertChartAndAccount(entryPair.getOffset(), DEFAULT_OFFSET_CHART, DEFAULT_OFFSET_ACCOUNT_NBR);
432         // 2. when flexible offsets are turned on, encumbrance forward cost share entries do not get flexible offsets
433         assertChartAndAccount(entryPair.getEntry(), a21SubAccount.getCostShareChartOfAccountCode(), a21SubAccount.getCostShareSourceAccountNumber());
434 
435         // 3. when flexible offsets are turned on, encumbrance forward cost share offsets that should not get flexible offsets don't get them
436         a21SubAccount = SpringContext.getBean(A21SubAccountService.class).getByPrimaryKey(CS_NO_FLEXIBLE_ENCUMBRANCE_CHART, CS_NO_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, CS_NO_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR);
437         entryPair = encumbranceClosingOriginEntryGenerationSerivce.createCostShareBeginningBalanceEntryOffsetPair(ENCUMBRANCE_FORWARD_FIXTURE.INFLEXIBLE_COST_SHARE_ENCUMBRANCE.convertToEncumbrance(), transactionDate);
438         assertChartAndAccount(entryPair.getOffset(), a21SubAccount.getCostShareChartOfAccountCode(), a21SubAccount.getCostShareSourceAccountNumber());
439     }
440 
441     /**
442      * Test that:
443      * <ul>
444      *  <li>when flexible offsets are turned off, encumbrance forward cost share offsets that should get flexible offsets don't get them</li>
445      * </ul>
446      */
447     public void testEncumbranceForwardCostShareFlexibleOffsetsWhenFlexibleOffsetsOff() {
448         OriginEntryOffsetPair entryPair;
449         A21SubAccount a21SubAccount;
450         toggleFlexibleOffsets(false);
451 
452         final EncumbranceClosingOriginEntryGenerationService encumbranceClosingOriginEntryGenerationSerivce = SpringContext.getBean(EncumbranceClosingOriginEntryGenerationService.class);
453 
454         // 1. when flexible offsets are turned off, encumbrance forward cost share offsets that should get flexible offsets don't get them
455         a21SubAccount = SpringContext.getBean(A21SubAccountService.class).getByPrimaryKey(CS_FLEXIBLE_ENCUMBRANCE_CHART, CS_FLEXIBLE_ENCUMBRANCE_ACCOUNT_NBR, CS_FLEXIBLE_ENCUMBRANCE_SUB_ACCT_NBR);
456         entryPair = encumbranceClosingOriginEntryGenerationSerivce.createCostShareBeginningBalanceEntryOffsetPair(ENCUMBRANCE_FORWARD_FIXTURE.FLEXIBLE_COST_SHARE_ENCUMBRANCE.convertToEncumbrance(), transactionDate);
457         assertChartAndAccount(entryPair.getEntry(), a21SubAccount.getCostShareChartOfAccountCode(), a21SubAccount.getCostShareSourceAccountNumber());
458     }
459 
460     /**
461      * Test that:
462      * <ul>
463      *  <li>when flexible offsets are turned on, cash reversion offsets that should get flexible offsets get them</li>
464      *  <li>when flexible offsets are turned on, cash reversion activity offsets that should not get flexible offsets don't get them</li>
465      *  <li>when flexible offsets are turned on, cash reversion activity entries do not get flexible offsets</li>
466      * </ul>
467      */
468     public void testOrganizationReversionCashFlexibleOffsetsWhenFlexibleOffsetsOn() {
469 //        toggleFlexibleOffsets(true);
470 //        List<Balance> flexibleBalances = new ArrayList<Balance>();
471 //        flexibleBalances.add(ORG_REVERSION_BALANCE_FIXTURE.FLEXIBLE_ORG_REVERSION_BALANCE.convertToBalance());
472 //        flexibleBalances.add(ORG_REVERSION_BALANCE_FIXTURE.INFLEXIBLE_ORG_REVERSION_BALANCE.convertToBalance());
473 //
474 //        List<OriginEntryFull> resultingEntries = runOrganizationReversion(flexibleBalances);
475 //        assertEquals("Number of generated OriginEntries ", new Integer(8), new Integer(resultingEntries.size()));
476 //        // 1. when flexible offsets are turned on, cash reversion activity entries do not get flexible offsets
477 //        assertChartAndAccount(resultingEntries.get(0), DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR);
478 //        assertChartAndAccount(resultingEntries.get(2), OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_CHART, OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_ACCOUNT);
479 //        assertChartAndAccount(resultingEntries.get(4), DEFAULT_NO_FLEXIBLE_BALANCE_CHART, DEFAULT_NO_FLEXIBLE_BALANCE_ACCOUNT_NBR);
480 //        assertChartAndAccount(resultingEntries.get(6), OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_CHART, OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_ACCOUNT);
481 //        // 2. when flexible offsets are turned on, cash reversion offsets that should get flexible offsets get them
482 //        assertChartAndAccount(resultingEntries.get(1), DEFAULT_OFFSET_CHART, DEFAULT_OFFSET_ACCOUNT_NBR);
483 //        assertChartAndAccount(resultingEntries.get(3), DEFAULT_OFFSET_CHART, DEFAULT_OFFSET_ACCOUNT_NBR);
484 //        assertChartAndAccount(resultingEntries.get(7), DEFAULT_OFFSET_CHART, DEFAULT_OFFSET_ACCOUNT_NBR);
485 //        // 3. when flexible offsets are turned on, cash reversion offsets that should not get flexible offsets don't get them
486 //        assertChartAndAccount(resultingEntries.get(5), DEFAULT_NO_FLEXIBLE_BALANCE_CHART, DEFAULT_NO_FLEXIBLE_BALANCE_ACCOUNT_NBR);
487     }
488 
489     /**
490      * Test that:
491      * <ul>
492      *  <li>when flexible offsets are turned off, cash reversion activity offsets that should get flexible offsets don't get them</li>
493      * </ul>
494      */
495     public void testOrganizationReversionCashFlexibleOffsetsWhenFlexibleOffsetsOff() {
496 //        toggleFlexibleOffsets(false);
497 //        List<Balance> flexibleBalances = new ArrayList<Balance>();
498 //        flexibleBalances.add(ORG_REVERSION_BALANCE_FIXTURE.FLEXIBLE_ORG_REVERSION_BALANCE.convertToBalance());
499 //
500 //        List<OriginEntryFull> resultingEntries = runOrganizationReversion(flexibleBalances);
501 //        assertEquals("Number of generated OriginEntries ", new Integer(4), new Integer(resultingEntries.size()));
502 //        assertChartAndAccount(resultingEntries.get(1), DEFAULT_FLEXIBLE_BALANCE_CHART, DEFAULT_FLEXIBLE_BALANCE_ACCOUNT_NBR);
503 //        assertChartAndAccount(resultingEntries.get(3), OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_CHART, OrganizationReversionMockServiceImpl.DEFAULT_CASH_REVERSION_ACCOUNT);
504     }
505 
506     /**
507      * Runs the organization service against a given set of balances.
508      * @param balancesToTest a List of balances to test the organization reversion process against
509      * @return the list of origin entries generated by the organization reversion process
510      */
511     private List<OriginEntryFull> runOrganizationReversion(List<Balance> balancesToTest) {
512         OrganizationReversionService organizationReversionService = SpringContext.getBean(OrganizationReversionService.class,"glOrganizationReversionMockService");
513         DateTimeService dtService = SpringContext.getBean(DateTimeService.class);
514         BalanceService balanceService = SpringContext.getBean(BalanceService.class);
515         CashOrganizationReversionCategoryLogic cashOrganizationReversionCategoryLogic = SpringContext.getBean(CashOrganizationReversionCategoryLogic.class);
516         PriorYearAccountService priorYearAccountService = SpringContext.getBean(PriorYearAccountService.class);
517         OrganizationReversionUnitOfWorkService orgReversionUnitOfWorkService = SpringContext.getBean(OrganizationReversionUnitOfWorkService.class);
518         OrganizationReversionProcessService organizationReversionProcessService = SpringContext.getBean(OrganizationReversionProcessService.class);
519 
520         Map jobParameters = organizationReversionProcessService.getJobParameters();
521         Integer currentFiscalYear = new Integer(((Number)jobParameters.get(KFSConstants.UNIV_FISCAL_YR)).intValue() + 1);
522         Integer previousFiscalYear = new Integer(((Number)jobParameters.get(KFSConstants.UNIV_FISCAL_YR)).intValue());
523         Map<String, Integer> organizationReversionCounts = new HashMap<String, Integer>();
524 
525         OrganizationReversionProcess orgRevProcess = SpringContext.getBean(OrganizationReversionProcess.class,"glOrganizationReversionTestProcess");
526 
527         clearGlBalanceTable();
528         clearBatchFiles();
529         //we do not need to call clearCache() since no dao and jdbc calls mixted in this method.
530         //refer to KFSMI-7637
531       //  persistenceService.clearCache();
532         for (Balance bal : balancesToTest) {
533             bal.setUniversityFiscalYear(previousFiscalYear);
534             SpringContext.getBean(BusinessObjectService.class).save(bal);
535         }
536         //TODO:- commented out
537         //OriginEntryGroup outputGroup = organizationReversionProcessService.createOrganizationReversionProcessOriginEntryGroup();
538 
539         //TODO:- fix
540         //orgRevProcess.setOutputGroup(outputGroup);
541         orgRevProcess.setHoldGeneratedOriginEntries(true);
542         orgRevProcess.organizationReversionProcess(jobParameters, organizationReversionCounts);
543 
544         // ye olde sanity check
545         assertEquals("Balances Read", new Integer(balancesToTest.size()), new Integer(orgRevProcess.getBalancesRead()));
546 
547         // make sure this resulted in one Org Rev origin entry group
548         //TODO:- commented out
549 //        Collection groups = originEntryGroupService.getAllOriginEntryGroup();
550 //        assertEquals("Origin Entries Group Size", new Integer(1), new Integer(groups.size()));
551 //
552 //        OriginEntryGroup group = (OriginEntryGroup) groups.iterator().next();
553 //        assertEquals("Origin Entry Group Source Code", OriginEntrySource.YEAR_END_ORG_REVERSION, group.getSourceCode());
554         return orgRevProcess.getGeneratedOriginEntries();
555     }
556 
557     /**
558      * Asserts that certain fields in the given origin entry equal given parameters
559      * @param originEntry the actual origin entry
560      * @param fiscalYear the expected fiscal year
561      * @param periodCode the expected period code
562      * @param chart the expected chart
563      * @param account the expected account
564      * @param objectCode the expected object code
565      * @param balanceType the expected balance type
566      * @param objectType the expected object type
567      * @param amount the expected amount
568      */
569     private void assertChartAndAccount(OriginEntryInformation originEntry, String chart, String account) {
570         assertEquals("Origin Entry " + originEntry.toString() + " Chart of Accounts", chart, originEntry.getChartOfAccountsCode());
571         assertEquals("Origin Entry " + originEntry.toString() + " Account Number", account, originEntry.getAccountNumber());
572     }
573 
574     /**
575      * Turns the flexible offset option on or off
576      * @param flexibleOffsetsOn whether we should turn the flexible offsets on or off
577      */
578     private void toggleFlexibleOffsets(boolean flexibleOffsetsOn) {
579         try {
580             TestUtils.setSystemParameter(OffsetDefinition.class, KFSConstants.SystemGroupParameterNames.FLEXIBLE_OFFSET_ENABLED_FLAG, (flexibleOffsetsOn ? "Y" : "N"));
581         }
582         catch (Exception e) {
583             throw new RuntimeException(e);
584         }
585     }
586 
587     private void createFlexibleOffsetAccounts() {
588         // clear the flexible offsets table
589         unitTestSqlDao.sqlCommand("delete from FP_OFST_ACCT_T");
590         // save our offsets
591         boService.save(FLEXIBLE_OFFSET_ACCOUNT_FIXTURE.FLEXIBLE_ACTIVITY_CLOSING_OFFSET_ACCOUNT.convertToOffsetAccount());
592         boService.save(FLEXIBLE_OFFSET_ACCOUNT_FIXTURE.FLEXIBLE_ENCUMBRANCE_FORWARD_OFFSET_ACCOUNT.convertToOffsetAccount());
593         boService.save(FLEXIBLE_OFFSET_ACCOUNT_FIXTURE.FLEXIBLE_CS_ENCUMBRANCE_FORWARD_OFFSET_ACCOUNT.convertToOffsetAccount());
594         boService.save(FLEXIBLE_OFFSET_ACCOUNT_FIXTURE.CASH_REVERSION_FORWARD_OFFSET_ACCOUNT.convertToOffsetAccount());
595     }
596 }