001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.kfs.coa.batch.dataaccess.impl; 017 018 import java.sql.Date; 019 import java.util.Collection; 020 import java.util.GregorianCalendar; 021 import java.util.regex.Matcher; 022 import java.util.regex.Pattern; 023 024 import org.apache.commons.lang.StringUtils; 025 import org.apache.ojb.broker.query.Criteria; 026 import org.apache.ojb.broker.query.QueryByCriteria; 027 import org.kuali.kfs.coa.businessobject.AccountingPeriod; 028 import org.kuali.kfs.sys.KFSPropertyConstants; 029 import org.kuali.kfs.sys.batch.dataaccess.impl.FiscalYearMakerImpl; 030 import org.kuali.rice.kns.bo.PersistableBusinessObject; 031 032 /** 033 * Performs custom population of accounting periods records for a new year being created in the fiscal year maker process 034 */ 035 public class AccountingPeriodFiscalYearMakerImpl extends FiscalYearMakerImpl { 036 037 public AccountingPeriodFiscalYearMakerImpl() { 038 super(); 039 040 super.setAllowOverrideTargetYear(false); 041 } 042 043 /** 044 * Updates the year on the fiscal period name and sets status to open for next year records 045 * 046 * @see org.kuali.kfs.coa.batch.dataaccess.impl.FiscalYearMakerHelperImpl#changeForNewYear(java.lang.Integer, 047 * org.kuali.rice.kns.bo.PersistableBusinessObject) 048 */ 049 @Override 050 public void changeForNewYear(Integer baseFiscalYear, PersistableBusinessObject currentRecord) { 051 super.changeForNewYear(baseFiscalYear, currentRecord); 052 053 AccountingPeriod accountingPeriod = (AccountingPeriod) currentRecord; 054 055 // update fiscal period name which contains the fiscal year 056 String fiscalPeriodName = accountingPeriod.getUniversityFiscalPeriodName(); 057 058 String oldCalendarStartYear = new Integer(accountingPeriod.getUniversityFiscalYear() - 2).toString(); 059 String oldCalendarEndYear = new Integer(accountingPeriod.getUniversityFiscalYear() - 1).toString(); 060 061 String newCalendarStartYear = new Integer(accountingPeriod.getUniversityFiscalYear() - 1).toString(); 062 String newCalendarEndYear = new Integer(accountingPeriod.getUniversityFiscalYear()).toString(); 063 064 // replace 4 digit year in name if found, else replace 2 digit 065 if (StringUtils.contains(fiscalPeriodName, oldCalendarEndYear)) { 066 fiscalPeriodName = StringUtils.replace(fiscalPeriodName, oldCalendarEndYear, newCalendarEndYear); 067 } 068 else if (StringUtils.contains(fiscalPeriodName, oldCalendarStartYear)) { 069 fiscalPeriodName = StringUtils.replace(fiscalPeriodName, oldCalendarStartYear, newCalendarStartYear); 070 } 071 else { 072 fiscalPeriodName = updateTwoDigitYear(newCalendarEndYear.substring(2, 4), oldCalendarEndYear.substring(2, 4), fiscalPeriodName); 073 fiscalPeriodName = updateTwoDigitYear(newCalendarStartYear.substring(2, 4), oldCalendarStartYear.substring(2, 4), fiscalPeriodName); 074 } 075 076 accountingPeriod.setUniversityFiscalPeriodName(fiscalPeriodName); 077 078 // increment period end date by one year 079 accountingPeriod.setUniversityFiscalPeriodEndDate(addYearToDate(accountingPeriod.getUniversityFiscalPeriodEndDate())); 080 081 // set status to closed 082 accountingPeriod.setActive(false); 083 } 084 085 /** 086 * Retrieves all Accounting Period records for the first copied fiscal year and make active 087 * 088 * @see org.kuali.kfs.coa.batch.dataaccess.impl.FiscalYearMakerHelperImpl#performCustomProcessing(java.lang.Integer) 089 */ 090 @Override 091 public void performCustomProcessing(Integer baseFiscalYear, boolean firstCopyYear) { 092 if (!firstCopyYear) { 093 return; 094 } 095 096 Criteria criteriaId = new Criteria(); 097 criteriaId.addEqualTo(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, baseFiscalYear + 1); 098 099 QueryByCriteria queryId = new QueryByCriteria(AccountingPeriod.class, criteriaId); 100 101 Collection<AccountingPeriod> accountingPeriods = getPersistenceBrokerTemplate().getCollectionByQuery(queryId); 102 for (AccountingPeriod accountingPeriod : accountingPeriods) { 103 accountingPeriod.setActive(true); 104 getPersistenceBrokerTemplate().store(accountingPeriod); 105 } 106 } 107 108 /** 109 * Adds one year to the given date 110 * 111 * @param inDate date to increment 112 * @return Date incoming date plus one year 113 */ 114 protected java.sql.Date addYearToDate(Date inDate) { 115 GregorianCalendar currentCalendarDate = new GregorianCalendar(); 116 currentCalendarDate.clear(); 117 118 currentCalendarDate.setTimeInMillis(inDate.getTime()); 119 currentCalendarDate.add(GregorianCalendar.YEAR, 1); 120 121 return new Date(currentCalendarDate.getTimeInMillis()); 122 } 123 124 /** 125 * this routine is provided to update string fields which contain two-digit years that need to be updated for display. it is 126 * very specific, but it's necessary. "two-digit year" means the two numeric characters preceded by a non-numeric character. 127 * 128 * @param newYear 129 * @param oldYear 130 * @param currentString 131 * @return the updated string for a two digit year 132 */ 133 protected String updateTwoDigitYear(String newYear, String oldYear, String currentString) { 134 // group 1 is the bounded by the outermost set of parentheses 135 // group 2 is the first inner set 136 // group 3 is the second inner set--a two-digit year at the beginning of the line 137 String regExpString = "(([^0-9]{1}" + oldYear + ")|^(" + oldYear + "))"; 138 Pattern pattern = Pattern.compile(regExpString); 139 Matcher matcher = pattern.matcher(currentString); 140 141 // start looking for a match 142 boolean matched = matcher.find(); 143 if (!matched) { 144 // just return if nothing is found 145 return currentString; 146 } 147 148 // we found something 149 // we have to process it 150 String returnString = currentString; 151 StringBuffer outString = new StringBuffer(); 152 // is there a match at the beginning of the line (a match with group 3)? 153 if (matcher.group(3) != null) { 154 // there is a two-digit-year string at the beginning of the line 155 // we want to replace it 156 matcher.appendReplacement(outString, newYear); 157 // find the next match if there is one 158 matched = matcher.find(); 159 } 160 161 while (matched) { 162 // the new string will no longer match with group 3 163 // if there is still a match, it will be with group 2 164 // now we have to prefix the new year string with the same 165 // non-numeric character as the next match (hyphen, space, whatever) 166 String newYearString = matcher.group(2).substring(0, 1) + newYear; 167 matcher.appendReplacement(outString, newYearString); 168 matched = matcher.find(); 169 } 170 171 // dump whatever detritus is left into the new string 172 matcher.appendTail(outString); 173 174 return outString.toString(); 175 } 176 177 }