/*
* The Kuali Financial System, a comprehensive financial management system for higher education.
*
* Copyright 2005-2014 The Kuali Foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.kuali.kfs.module.ld.batch.service.impl;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.kuali.kfs.gl.GeneralLedgerConstants;
import org.kuali.kfs.gl.batch.service.impl.BalancingServiceBaseImpl;
import org.kuali.kfs.gl.batch.service.impl.BalancingServiceImplTestBase;
import org.kuali.kfs.gl.businessobject.Balance;
import org.kuali.kfs.gl.businessobject.Entry;
import org.kuali.kfs.gl.dataaccess.LedgerBalancingDao;
import org.kuali.kfs.gl.dataaccess.LedgerEntryHistoryBalancingDao;
import org.kuali.kfs.module.ld.LaborConstants;
import org.kuali.kfs.module.ld.batch.LaborBalancingStep;
import org.kuali.kfs.module.ld.businessobject.LaborBalanceHistory;
import org.kuali.kfs.module.ld.businessobject.LaborEntryHistory;
import org.kuali.kfs.module.ld.businessobject.LedgerBalance;
import org.kuali.kfs.module.ld.businessobject.LedgerEntry;
import org.kuali.kfs.sys.ConfigureContext;
import org.kuali.kfs.sys.batch.BatchSpringContext;
import org.kuali.kfs.sys.batch.Step;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.context.TestUtils;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.krad.service.BusinessObjectService;
/**
* LD LaborBalancingServiceImpl test cases
*/
@ConfigureContext
public class LaborBalancingServiceImplTest extends BalancingServiceImplTestBase {
private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LaborBalancingServiceImplTest.class);
private boolean batchFileDirectoryCreated = false;
@Override
protected void setUp() throws Exception {
balancingService = (BalancingServiceBaseImpl<Entry, Balance>) TestUtils.getUnproxiedService("laborBalancingService");
ledgerEntryHistoryBalancingDao = (LedgerEntryHistoryBalancingDao) SpringContext.getService("laborLedgerEntryHistoryDao");
ledgerBalancingDao = (LedgerBalancingDao) SpringContext.getService("laborBalancingDao");
businessObjectService = SpringContext.getBean(BusinessObjectService.class);
// Delete all data so that balancing has an empty table set to work with
Map<String, Object> fieldValues = new HashMap<String, Object>();
businessObjectService.deleteMatching(LedgerEntry.class, fieldValues);
businessObjectService.deleteMatching(LedgerBalance.class, fieldValues);
businessObjectService.deleteMatching(LaborEntryHistory.class, fieldValues);
businessObjectService.deleteMatching(LaborBalanceHistory.class, fieldValues);
// Because KULDBA doesn't support FYs more then 1 year back we need to limit our range in order to properly test boundary cases
TestUtils.setSystemParameter(LaborBalancingStep.class, LaborConstants.Balancing.NUMBER_OF_PAST_FISCAL_YEARS_TO_INCLUDE, "0");
File batchFileDirectory = new File(this.getBatchFileDirectoryName());
if (!batchFileDirectory.exists()) {
batchFileDirectory.mkdir();
batchFileDirectoryCreated = true;
}
// careful: super.setUp needs to happen at the end because of service initialization and NUMBER_OF_PAST_FISCAL_YEARS_TO_INCLUDE
super.setUp();
}
/**
* @see junit.framework.TestCase#tearDown()
*/
@Override
protected void tearDown() throws Exception {
if (batchFileDirectoryCreated) {
File batchFileDirectory = new File(this.getBatchFileDirectoryName());
for (File f : batchFileDirectory.listFiles()) {
f.delete();
}
batchFileDirectory.delete();
batchFileDirectoryCreated = false;
}
super.tearDown();
}
@Override
public void testRunBalancingPopulateData() {
LOG.debug("No data present scenario, hence process should populate data");
// First confirm tables are empty. If this fails then the test scenario is incorrectly set up
assertEquals(0, getLedgerEntryBalancingDao().findCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
assertEquals(0, getLedgerBalanceBalancingDao().findCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
assertEquals(0, this.getHistoryCount(null, LaborEntryHistory.class));
assertEquals(0, this.getHistoryCount(null, LaborBalanceHistory.class));
// Generate some data and check that poster operated as expected. If this fails then the test scenario is incorrectly set up
this.postTestCaseEntries(INPUT_TRANSACTIONS);
assertEquals(12, getLedgerEntryBalancingDao().findCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
assertEquals(3, getLedgerBalanceBalancingDao().findCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
// Balancing should succeed successfully since this is an expected use case where it does an initial population of history tables
assertTrue(balancingService.runBalancing());
// Once it ran, we expect data in balancing tables. This data is per INPUT_TRANSACTIONS data structure
assertEquals(12, ledgerEntryHistoryBalancingDao.findSumRowCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
assertEquals(10, this.getHistoryCount(null, LaborEntryHistory.class));
assertEquals(3, this.getHistoryCount(null, LaborBalanceHistory.class));
// Finally make sure there isn't any comparison failure. Since we just populated the history tables this should hold true
this.assertCompareHistorySuccess();
}
@Override
public void testRunBalancingDeleteObsoleteUniversityFiscalYearData() {
// Run the poster to pick up the last two entries which are out of range
this.postTestCaseEntries(INPUT_TRANSACTIONS);
// Manually populate our history tables and force entries to be picked up. This essentially does the same as testRunBalancingPopulateData
assertTrue("Populate should have copied some data", 0 != ledgerBalancingDao.populateLedgerEntryHistory(obsoleteUniversityFiscalYear));
assertTrue("Populate should have copied some data", 0 != ledgerBalancingDao.populateLedgerBalanceHistory(obsoleteUniversityFiscalYear));
// Pretty silly at this point, but lets double check that it copied the entries
assertTrue("Found no LaborEntryHistory", 0 != this.getHistoryCount(obsoleteUniversityFiscalYear, LaborEntryHistory.class));
assertTrue("Found no LaborBalanceHistory", 0 != this.getHistoryCount(obsoleteUniversityFiscalYear, LaborBalanceHistory.class));
// Run Balancing, it should hit the case that deletes the obsolete entries. Coincidentally: This will also ignore the two out of range entries in
// INPUT_TRANSACTIONS (the last two) but we're not actively testing for that here
assertTrue(balancingService.runBalancing());
// Verify that it deleted the entries
assertEquals(0, this.getHistoryCount(obsoleteUniversityFiscalYear, LaborEntryHistory.class));
assertEquals(0, this.getHistoryCount(obsoleteUniversityFiscalYear, LaborBalanceHistory.class));
}
@Override
public void testRunBalancingHistoryUpdate() {
// First pass is exactly the same as testRunBalancingPopulateData. This serves to populate the tables
this.postTestCaseEntries(INPUT_TRANSACTIONS);
assertTrue("Populate should have copied some data", 0 != ledgerBalancingDao.populateLedgerEntryHistory(obsoleteUniversityFiscalYear));
assertTrue("Populate should have copied some data", 0 != ledgerBalancingDao.populateLedgerBalanceHistory(obsoleteUniversityFiscalYear));
try {
// Briefly sleep to ensure that we get unique timestamps on the rename step. This is obsolete since the input files will
// be the same but done to avoid future bugs if there are changes to the test setup
Thread.sleep(1000);
} catch (InterruptedException e) {
assertTrue("No reason that this job should have gotten interrupted.", false);
}
// Next we post exactly the same entries and verify data exists. Note, now we have more entries
this.postTestCaseEntries(INPUT_TRANSACTIONS);
assertEquals(24, getLedgerEntryBalancingDao().findCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
assertEquals(3, getLedgerBalanceBalancingDao().findCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
// And run balancing again. Again, this should succeed
assertTrue(balancingService.runBalancing());
// Once it ran, we expect data in balancing tables, but different this time since the balancing job ran updates
assertEquals(24, ledgerEntryHistoryBalancingDao.findSumRowCountGreaterOrEqualThan(startUniversityFiscalYear).intValue());
assertEquals(10, this.getHistoryCount(null, LaborEntryHistory.class));
assertEquals(3, this.getHistoryCount(null, LaborBalanceHistory.class));
// Finally make sure there wasn't any comparison failure. We do this by running comparison methods directly (again)
this.assertCompareHistorySuccess();
}
/**
* @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceImplTestBase#postTestCaseEntries(java.lang.String[])
*/
@Override
protected void postTestCaseEntries(String[] inputTransactions) {
// Write test file
TestUtils.writeFile(this.getBatchFileDirectoryName() + File.separator + LaborConstants.BatchFileSystem.POSTER_INPUT_FILE + GeneralLedgerConstants.BatchFileSystem.EXTENSION, inputTransactions);
try {
// Run the poster
Step laborPosterStep = BatchSpringContext.getStep("laborPosterStep");
assertTrue("laborPosterStep should have succeeded", laborPosterStep.execute(getClass().getName(), dateTimeService.getCurrentDate()));
// Rename the file because that's what happens before the balancing job runs
Step laborFileRenameStep = BatchSpringContext.getStep("laborFileRenameStep");
assertTrue("laborFileRenameStep should have succeeded", laborFileRenameStep.execute(getClass().getName(), dateTimeService.getCurrentDate()));
}
catch (InterruptedException e) {
assertTrue("laborPosterStep or laborFileRenameStep failed: " + e.getMessage(), true);
}
}
/**
* @see org.kuali.kfs.gl.batch.service.impl.BalancingServiceImplTest#getInputTransactions()
*/
@Override
protected String[] getInputTransactions() {
// These inputTransactions are missing an initial 4 character FY string. It is added in setUp to test Balancing skipping old entries. Also, first 4
// of the following array are in error intentionally.
return new String[] {
"BL1031400----- ---A2EX05BT 01LP2837509 88888------------------TEST DESCRIPTION 619.90D2009-02-05 0.00 200905000000000010 ",
"BL1031400----- ---A2EX05BT 01LP2837509 88888------------------TEST DESCRIPTION 276.47D2009-02-05 0.00 200905000000000010 ",
"BL1031400----- ---A2EX05BT 01LP2837509 88888------------------TEST DESCRIPTION 448.77D2009-02-05 0.00 200905000000000010 ",
"BL1031400----- ---A2EX05BT 01LP2837509 88888------------------TEST DESCRIPTION 619.90C2009-02-05 0.00 200905000000000010 ",
"BL1031400-----5760---A2EX05BT 01LP2837509 88888------------------TEST DESCRIPTION 276.47C2009-02-05 0.00 200905000000000010 ",
"BL1031400-----5772---A2EX05BT 01LP2837509 88888------------------TEST DESCRIPTION 448.77C2009-02-05 0.00 200905000000000010 ",
"BL1031400-----5625---A2EX06BT 01LP2837509 88888------------------TEST DESCRIPTION 619.90D2009-02-05 0.00 200906000000000010 ",
"BL1031400-----5760---A2EX06BT 01LP2837509 88888------------------TEST DESCRIPTION 276.47D2009-02-05 0.00 200906000000000010 ",
"BL1031400-----5772---A2EX06BT 01LP2837509 88888------------------TEST DESCRIPTION 448.77D2009-02-05 0.00 200906000000000010 ",
"BL1031400-----5625---A2EX06BT 01LP2837509 88888------------------TEST DESCRIPTION 619.90C2009-02-05 0.00 200906000000000010 ",
"BL1031400-----5760---A2EX06BT 01LP2837509 88888------------------TEST DESCRIPTION 276.47C2009-02-05 0.00 200906000000000010 ",
"BL1031400-----5772---A2EX06BT 01LP2837509 88888------------------TEST DESCRIPTION 448.77C2009-02-05 0.00 200906000000000010 ",
"BL1031400-----5625---A2EX08BT 01LP2837509 88888------------------TEST DESCRIPTION 619.90C2009-02-05 0.00 200905000000000010 ",
"BL1031400-----5625---A2EX08BT 01LP2837509 88888------------------TEST DESCRIPTION 619.90C2009-02-05 0.00 200906000000000010 ",
"BL1031400-----5760---A2EX08BT 01LP2837509 88888------------------TEST DESCRIPTION 276.47C2009-02-05 0.00 200905000000000010 ",
"BL1031400-----5760---A2EX08BT 01LP2837509 88888------------------TEST DESCRIPTION 276.47C2009-02-05 0.00 200906000000000010 ",
CHART_OF_ACCOUNTS_CODE + "1031400-----" + FINANCIAL_OBJECT_CODE + "---A2EX08BT 01LP2837509 88888------------------TEST DESCRIPTION 448.77C2009-02-05 0.00 200905000000000010 ",
CHART_OF_ACCOUNTS_CODE + "1031400-----" + FINANCIAL_OBJECT_CODE + "---A2EX08BT 01LP2837509 88888------------------TEST DESCRIPTION 448.77C2009-02-05 0.00 200906000000000010 ",
};
}
}