/* * 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.coa.batch.dataaccess.impl; import java.sql.Date; import java.util.Collection; import java.util.Collections; import java.util.GregorianCalendar; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.coa.businessobject.AccountingPeriod; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.batch.dataaccess.impl.FiscalYearMakerImpl; import org.kuali.kfs.sys.businessobject.FiscalYearBasedBusinessObject; /** * Performs custom population of accounting periods records for a new year being created in the fiscal year maker process */ public class AccountingPeriodFiscalYearMakerImpl extends FiscalYearMakerImpl { public AccountingPeriodFiscalYearMakerImpl() { super(); super.setAllowOverrideTargetYear(false); } /** * Updates the year on the fiscal period name and sets status to open for next year records * * @see org.kuali.kfs.coa.batch.dataaccess.impl.FiscalYearMakerHelperImpl#changeForNewYear(java.lang.Integer, * org.kuali.rice.krad.bo.PersistableBusinessObject) */ @Override public void changeForNewYear(Integer baseFiscalYear, FiscalYearBasedBusinessObject currentRecord) { super.changeForNewYear(baseFiscalYear, currentRecord); AccountingPeriod accountingPeriod = (AccountingPeriod) currentRecord; // update fiscal period name which contains the fiscal year String fiscalPeriodName = accountingPeriod.getUniversityFiscalPeriodName(); String oldCalendarStartYear = new Integer(accountingPeriod.getUniversityFiscalYear() - 2).toString(); String oldCalendarEndYear = new Integer(accountingPeriod.getUniversityFiscalYear() - 1).toString(); String newCalendarStartYear = new Integer(accountingPeriod.getUniversityFiscalYear() - 1).toString(); String newCalendarEndYear = new Integer(accountingPeriod.getUniversityFiscalYear()).toString(); // replace 4 digit year in name if found, else replace 2 digit if (StringUtils.contains(fiscalPeriodName, oldCalendarEndYear)) { fiscalPeriodName = StringUtils.replace(fiscalPeriodName, oldCalendarEndYear, newCalendarEndYear); } else if (StringUtils.contains(fiscalPeriodName, oldCalendarStartYear)) { fiscalPeriodName = StringUtils.replace(fiscalPeriodName, oldCalendarStartYear, newCalendarStartYear); } else { fiscalPeriodName = updateTwoDigitYear(newCalendarEndYear.substring(2, 4), oldCalendarEndYear.substring(2, 4), fiscalPeriodName); fiscalPeriodName = updateTwoDigitYear(newCalendarStartYear.substring(2, 4), oldCalendarStartYear.substring(2, 4), fiscalPeriodName); } accountingPeriod.setUniversityFiscalPeriodName(fiscalPeriodName); // increment period end date by one year accountingPeriod.setUniversityFiscalPeriodEndDate(addYearToDate(accountingPeriod.getUniversityFiscalPeriodEndDate())); // set status to closed accountingPeriod.setActive(false); } /** * Retrieves all Accounting Period records for the first copied fiscal year and make active * * @see org.kuali.kfs.coa.batch.dataaccess.impl.FiscalYearMakerHelperImpl#performCustomProcessing(java.lang.Integer) */ @Override public void performCustomProcessing(Integer baseFiscalYear, boolean firstCopyYear) { if (!firstCopyYear) { return; } Collection<AccountingPeriod> accountingPeriods = businessObjectService.findMatching(AccountingPeriod.class,Collections.singletonMap(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, baseFiscalYear + 1)); for (AccountingPeriod accountingPeriod : accountingPeriods) { accountingPeriod.setActive(true); businessObjectService.save(accountingPeriod); } } /** * Adds one year to the given date * * @param inDate date to increment * @return Date incoming date plus one year */ protected java.sql.Date addYearToDate(Date inDate) { GregorianCalendar currentCalendarDate = new GregorianCalendar(); currentCalendarDate.clear(); currentCalendarDate.setTimeInMillis(inDate.getTime()); currentCalendarDate.add(GregorianCalendar.YEAR, 1); return new Date(currentCalendarDate.getTimeInMillis()); } /** * this routine is provided to update string fields which contain two-digit years that need to be updated for display. it is * very specific, but it's necessary. "two-digit year" means the two numeric characters preceded by a non-numeric character. * * @param newYear * @param oldYear * @param currentString * @return the updated string for a two digit year */ protected String updateTwoDigitYear(String newYear, String oldYear, String currentString) { // group 1 is the bounded by the outermost set of parentheses // group 2 is the first inner set // group 3 is the second inner set--a two-digit year at the beginning of the line String regExpString = "(([^0-9]{1}" + oldYear + ")|^(" + oldYear + "))"; Pattern pattern = Pattern.compile(regExpString); Matcher matcher = pattern.matcher(currentString); // start looking for a match boolean matched = matcher.find(); if (!matched) { // just return if nothing is found return currentString; } // we found something // we have to process it String returnString = currentString; StringBuffer outString = new StringBuffer(); // is there a match at the beginning of the line (a match with group 3)? if (matcher.group(3) != null) { // there is a two-digit-year string at the beginning of the line // we want to replace it matcher.appendReplacement(outString, newYear); // find the next match if there is one matched = matcher.find(); } while (matched) { // the new string will no longer match with group 3 // if there is still a match, it will be with group 2 // now we have to prefix the new year string with the same // non-numeric character as the next match (hyphen, space, whatever) String newYearString = matcher.group(2).substring(0, 1) + newYear; matcher.appendReplacement(outString, newYearString); matched = matcher.find(); } // dump whatever detritus is left into the new string matcher.appendTail(outString); return outString.toString(); } }