/* * 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.fp.document; import java.util.HashSet; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.kuali.kfs.coa.businessobject.ObjectCode; import org.kuali.kfs.coa.businessobject.OffsetDefinition; import org.kuali.kfs.coa.service.ObjectCodeService; import org.kuali.kfs.coa.service.OffsetDefinitionService; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.businessobject.AccountingLine; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.document.AccountingDocument; import org.kuali.kfs.sys.service.UniversityDateService; import org.kuali.rice.krad.service.BusinessObjectService; /** * Utilities to help with the persistence of previous year object codes for year end tests */ public class YearEndObjectCodePersistenceUtils { /** * Saves the object code for a fiscal year * @param accountingLine the accounting line which has the object code to save, but for the previous year */ protected static void persistPreviousYearObjectCode(AccountingLine accountingLine, Set<String> storedObjectCodes) { ObjectCode objectCode = new ObjectCode(); final Integer postingYear = new Integer(SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear().intValue() - 1); final ObjectCodeService objectCodeService = SpringContext.getBean(ObjectCodeService.class); final ObjectCode existingObjectCode = objectCodeService.getByPrimaryId(postingYear, accountingLine.getChartOfAccountsCode(), accountingLine.getFinancialObjectCode()); if (existingObjectCode == null) { objectCode.setUniversityFiscalYear(postingYear); objectCode.setChartOfAccountsCode(accountingLine.getChartOfAccountsCode()); objectCode.setFinancialObjectCode(accountingLine.getFinancialObjectCode()); if (!storedObjectCodes.contains(buildObjectCodeString(objectCode))) { final ObjectCode alObjectCode = accountingLine.getObjectCode(); copyObjectCodeNonPKProperties(objectCode, alObjectCode); SpringContext.getBean(BusinessObjectService.class).save(objectCode); storedObjectCodes.add(buildObjectCodeString(objectCode)); } } // now, find the offset object code and add that if needed final OffsetDefinitionService offsetDefinitionService = SpringContext.getBean(OffsetDefinitionService.class); final OffsetDefinition offsetDefinition = offsetDefinitionService.getByPrimaryId(accountingLine.getPostingYear(), accountingLine.getChartOfAccountsCode(), "YEGE", KFSConstants.BALANCE_TYPE_ACTUAL); if (offsetDefinition != null) { final ObjectCode offsetObjectCode = objectCodeService.getByPrimaryId(offsetDefinition.getUniversityFiscalYear(), offsetDefinition.getChartOfAccountsCode(), offsetDefinition.getFinancialObjectCode()); if (offsetObjectCode != null) { final ObjectCode existingOffsetObjectCode = objectCodeService.getByPrimaryId(postingYear, offsetDefinition.getChartOfAccountsCode(), offsetDefinition.getFinancialObjectCode()); if (existingOffsetObjectCode == null) { ObjectCode newOffsetObjectCode = new ObjectCode(); newOffsetObjectCode.setUniversityFiscalYear(postingYear); newOffsetObjectCode.setChartOfAccountsCode(offsetObjectCode.getChartOfAccountsCode()); newOffsetObjectCode.setFinancialObjectCode(offsetObjectCode.getFinancialObjectCode()); if (!storedObjectCodes.contains(buildObjectCodeString(newOffsetObjectCode))) { copyObjectCodeNonPKProperties(newOffsetObjectCode, offsetObjectCode); SpringContext.getBean(BusinessObjectService.class).save(newOffsetObjectCode); storedObjectCodes.add(buildObjectCodeString(newOffsetObjectCode)); } } } } } /** * Copies the non primary key properties on an object code from the source to the target * @param target the object code to copy to * @param source the object code to copy from */ protected static void copyObjectCodeNonPKProperties(ObjectCode target, ObjectCode source) { target.setName(source.getName()); target.setActive(true); target.setFinancialObjectLevelCode(source.getFinancialObjectLevelCode()); target.setReportsToChartOfAccountsCode(source.getReportsToChartOfAccountsCode()); target.setReportsToFinancialObjectCode(source.getReportsToFinancialObjectCode()); target.setFinancialObjectTypeCode(source.getFinancialObjectTypeCode()); target.setFinancialObjectSubTypeCode(source.getFinancialObjectSubTypeCode()); target.setFinancialBudgetAggregationCd(source.getFinancialBudgetAggregationCd()); target.setNextYearFinancialObjectCode(source.getNextYearFinancialObjectCode()); target.setFinObjMandatoryTrnfrelimCd(source.getFinObjMandatoryTrnfrelimCd()); target.setFinancialFederalFundedCode(source.getFinancialFederalFundedCode()); } /** * Persists all object codes used on a document in the previous year * @param document the document with object codes to persist to the previous year */ public static Set<String> persistPreviousYearObjectCodesForDocument(AccountingDocument document) { Set<String> storedObjectCodes = new HashSet<String>(); for (Object accountingLineAsObject : document.getSourceAccountingLines()) { final AccountingLine accountingLine = (AccountingLine)accountingLineAsObject; persistPreviousYearObjectCode(accountingLine, storedObjectCodes); } for (Object accountingLineAsObject : document.getTargetAccountingLines()) { final AccountingLine accountingLine = (AccountingLine)accountingLineAsObject; persistPreviousYearObjectCode(accountingLine, storedObjectCodes); } return storedObjectCodes; } /** * Deletes all of the object codes saved to make this test work * @param objectCodesToDelete the object codes to remove */ public static void removePreviousYearObjectCodes(Set<String> objectCodesToDelete) { final BusinessObjectService boService = SpringContext.getBean(BusinessObjectService.class); for (String objectCodeRepresenation : objectCodesToDelete) { final ObjectCode objectCode = retrieveObjectCodeFromRepresentation(objectCodeRepresenation); boService.delete(objectCode); } } /** * Builds a unique and complete String representation of the PK of an object code * @param objectCode the object code to build a represenation of * @return a unique and complete representation of the PK of an object code */ protected static String buildObjectCodeString(ObjectCode objectCode) { return objectCode.getUniversityFiscalYear()+"::"+objectCode.getChartOfAccountsCode()+"::"+objectCode.getFinancialObjectCode(); } /** * From the given representation, builds an object code with all the primary key fields filled in, so it can be deleted * @return an object code with PK fields filled in */ protected static ObjectCode retrieveObjectCodeFromRepresentation(String objectCodeRepresenation) { Pattern pat = Pattern.compile("(\\d+)\\:\\:([^\\:]+)\\:\\:(.+)"); Matcher mat = pat.matcher(objectCodeRepresenation); if (mat.matches()) { ObjectCode objectCode = new ObjectCode(); objectCode.setUniversityFiscalYear(new Integer(mat.group(1))); objectCode.setChartOfAccountsCode(mat.group(2)); objectCode.setFinancialObjectCode(mat.group(3)); objectCode.setVersionNumber(1L); return objectCode; } return null; } }