/* * 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.web.struts; import static org.kuali.kfs.sys.KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE; import static org.kuali.kfs.sys.KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE; import static org.kuali.kfs.sys.KFSConstants.AuxiliaryVoucher.RECODE_DOC_TYPE; import java.sql.Date; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import javax.servlet.http.HttpServletRequest; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.Predicate; import org.apache.commons.lang.StringUtils; import org.joda.time.DateTime; import org.kuali.kfs.coa.businessobject.AccountingPeriod; import org.kuali.kfs.coa.service.AccountingPeriodService; import org.kuali.kfs.fp.document.AuxiliaryVoucherDocument; import org.kuali.kfs.fp.document.validation.impl.AuxiliaryVoucherDocumentRuleConstants; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.kfs.sys.service.UniversityDateService; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.core.api.parameter.ParameterEvaluatorService; import org.kuali.rice.coreservice.framework.parameter.ParameterService; import org.kuali.rice.krad.document.Document; import org.kuali.rice.krad.util.ObjectUtils; /** * Struts form so <code>{@link AuxiliaryVoucherDocument}</code> can be accessed and modified through UI. */ public class AuxiliaryVoucherForm extends VoucherForm { protected String originalVoucherType = KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE; // keep this in sync with the default // value set in the document business // object public AuxiliaryVoucherForm() { super(); } @Override protected String getDefaultDocumentTypeName() { return "AV"; } /** * Overrides the parent to call super.populate and then to call the two methods that are specific to loading the two select * lists on the page. In addition, this also makes sure that the credit and debit amounts are filled in for situations where * validation errors occur and the page reposts. * * @see org.kuali.rice.kns.web.struts.pojo.PojoForm#populate(javax.servlet.http.HttpServletRequest) */ @Override public void populate(HttpServletRequest request) { // populate the drop downs super.populate(request); populateReversalDateForRendering(); } /** * @return Returns the serviceBillingDocument. */ public AuxiliaryVoucherDocument getAuxiliaryVoucherDocument() { return (AuxiliaryVoucherDocument) getDocument(); } /** * @param serviceBillingDocument The serviceBillingDocument to set. */ public void setAuxiliaryVoucherDocument(AuxiliaryVoucherDocument auxiliaryVoucherDocument) { setDocument(auxiliaryVoucherDocument); } /** * Gets today's date and then sets the day of the month as 15th, irrespective of the current day of the month * @return the modified reversal date */ protected Date getAvReversalDate() { Date documentReveralDate = getAuxiliaryVoucherDocument().getReversalDate(); if (ObjectUtils.isNotNull(documentReveralDate)) { return documentReveralDate; } java.sql.Date avReversalDate = SpringContext.getBean(DateTimeService.class).getCurrentSqlDateMidnight(); Calendar cal = Calendar.getInstance(); cal.setTime(avReversalDate); int thisMonth; if (getAuxiliaryVoucherDocument().getAccountingPeriod().getUniversityFiscalPeriodCode().equals(KFSConstants.MONTH13)) { thisMonth = cal.JULY; } else { thisMonth = getAuxiliaryVoucherDocument().getAccountingPeriod().getMonth(); } cal.set(Calendar.MONTH, (thisMonth)); //if today's day > 15 then set the month to next month. // if (cal.get(Calendar.DAY_OF_MONTH) > KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_DAY_OF_MONTH) { // cal.add(Calendar.MONTH, 1); // } int reversalDateDefaultDayOfMonth = this.getReversalDateDefaultDayOfMonth(); cal.set(Calendar.DAY_OF_MONTH, reversalDateDefaultDayOfMonth); long timeInMillis = cal.getTimeInMillis(); avReversalDate.setTime(timeInMillis); return avReversalDate; } /** * Handles special case display rules for displaying Reversal Date at UI layer */ public void populateReversalDateForRendering() { java.sql.Date today = getAvReversalDate(); if (getAuxiliaryVoucherDocument().getTypeCode().equals(ACCRUAL_DOC_TYPE)) { getAuxiliaryVoucherDocument().setReversalDate(today); } else if (getAuxiliaryVoucherDocument().getTypeCode().equals(ADJUSTMENT_DOC_TYPE)) { getAuxiliaryVoucherDocument().setReversalDate(null); } else if (getAuxiliaryVoucherDocument().getTypeCode().equals(RECODE_DOC_TYPE)) { DateTime ts = new DateTime(getAuxiliaryVoucherDocument().getDocumentHeader().getWorkflowDocument().getDateCreated()); Date newts = new Date(ts.getMillis()); getAuxiliaryVoucherDocument().setReversalDate(newts); } } /** * This method returns the reversal date in the format MMM d, yyyy. * * @return String */ @Override public String getFormattedReversalDate() { return formatReversalDate(getAuxiliaryVoucherDocument().getReversalDate()); } /** * @return String */ public String getOriginalVoucherType() { return originalVoucherType; } /** * @param originalVoucherType */ public void setOriginalVoucherType(String originalVoucherType) { this.originalVoucherType = originalVoucherType; } /** * Returns a formatted auxiliary voucher type: <Voucher Type Name> (<Voucher Type Code>) * * @return */ public String getFormattedAuxiliaryVoucherType() { String voucherTypeCode = getAuxiliaryVoucherDocument().getTypeCode(); String formattedVoucherType = new String(); if (KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE.equals(voucherTypeCode)) { formattedVoucherType = KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE_NAME; } else if (KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE.equals(voucherTypeCode)) { formattedVoucherType = KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE_NAME; } else if (KFSConstants.AuxiliaryVoucher.RECODE_DOC_TYPE.equals(voucherTypeCode)) { formattedVoucherType = KFSConstants.AuxiliaryVoucher.RECODE_DOC_TYPE_NAME; } else { throw new IllegalStateException("Invalid auxiliary voucher type code: " + voucherTypeCode); } return formattedVoucherType + " (" + voucherTypeCode + ")"; } /** * This method generates a proper list of valid accounting periods that the user can select from. * * @see org.kuali.kfs.fp.document.web.struts.VoucherForm#populateAccountingPeriodListForRendering() */ @Override public void populateAccountingPeriodListForRendering() { // grab the list of valid accounting periods ArrayList accountingPeriods = new ArrayList(SpringContext.getBean(AccountingPeriodService.class).getOpenAccountingPeriods()); // now, validate further, based on the rules from AuxiliaryVoucherDocumentRule ArrayList filteredAccountingPeriods = new ArrayList(); filteredAccountingPeriods.addAll(CollectionUtils.select(accountingPeriods, new OpenAuxiliaryVoucherPredicate(this.getDocument()))); // if our auxiliary voucher doc contains an accounting period already, make sure the collection has it too! if (this.getDocument() instanceof AuxiliaryVoucherDocument) { AuxiliaryVoucherDocument avDoc = (AuxiliaryVoucherDocument) this.getDocument(); if (avDoc != null && avDoc.getAccountingPeriod() != null && !filteredAccountingPeriods.contains(avDoc.getAccountingPeriod())) { // this is most likely going to happen because the approver is trying // to approve a document after the grace period of an accounting period // or a fiscal year has switched over when the document was first created; // as such, it's probably a good bet that the doc's accounting period // belongs at the top of the list filteredAccountingPeriods.add(0, avDoc.getAccountingPeriod()); } } // set into the form for rendering setAccountingPeriods(filteredAccountingPeriods); // set the chosen accounting period into the form populateSelectedVoucherAccountingPeriod(); } public boolean getAccountingPeriodReadOnly(){ AuxiliaryVoucherDocument doc = (AuxiliaryVoucherDocument)this.getDocument(); return !StringUtils.equals(doc.getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode(), "?"); } protected class OpenAuxiliaryVoucherPredicate implements Predicate { protected ParameterService parameterService; protected UniversityDateService dateService; protected AccountingPeriodService acctPeriodService; protected Document auxiliaryVoucherDocument; protected AccountingPeriod currPeriod; protected java.sql.Date currentDate; protected Integer currentFiscalYear; public OpenAuxiliaryVoucherPredicate(Document doc) { this.parameterService = SpringContext.getBean(ParameterService.class); this.dateService = SpringContext.getBean(UniversityDateService.class); this.acctPeriodService = SpringContext.getBean(AccountingPeriodService.class); this.auxiliaryVoucherDocument = doc; this.currPeriod = acctPeriodService.getByDate(new java.sql.Date(new java.util.GregorianCalendar().getTimeInMillis())); this.currentDate = new java.sql.Date(new java.util.Date().getTime()); this.currentFiscalYear = dateService.getCurrentFiscalYear(); } @Override public boolean evaluate(Object o) { boolean result = false; if (o instanceof AccountingPeriod) { AccountingPeriod period = (AccountingPeriod) o; result = /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AuxiliaryVoucherDocument.class, AuxiliaryVoucherDocumentRuleConstants.RESTRICTED_PERIOD_CODES, period.getUniversityFiscalPeriodCode()).evaluationSucceeds(); if (result) { result = (period.getUniversityFiscalYear().equals( currentFiscalYear )); if (result) { // did this accounting period end before now? result = acctPeriodService.compareAccountingPeriodsByDate(period, currPeriod) >= 0; if (!result) { // if yes, are we still in the grace period? result = getAuxiliaryVoucherDocument().calculateIfWithinGracePeriod(currentDate, period); } } else { // are we in current in the grace period of an ending accounting period of the previous fiscal year? result = getAuxiliaryVoucherDocument().calculateIfWithinGracePeriod(currentDate, period); } } } return result; } } public List<String> getAccountingPeriodCompositeValueList() { List<String> accountingPeriodCompositeValueList = new ArrayList<String>(); for (int i = 0; i < this.getAccountingPeriods().size(); i++) { AccountingPeriod temp = (AccountingPeriod) this.getAccountingPeriods().get(i); accountingPeriodCompositeValueList.add(temp.getUniversityFiscalPeriodCode() + temp.getUniversityFiscalYear()); } return accountingPeriodCompositeValueList; } public List<String> getAccountingPeriodLabelList() { List<String> accountingPeriodLabelList = new ArrayList<String>(); for (int i = 0; i < this.getAccountingPeriods().size(); i++) { AccountingPeriod temp = (AccountingPeriod) this.getAccountingPeriods().get(i); accountingPeriodLabelList.add(temp.getUniversityFiscalPeriodName()); } return accountingPeriodLabelList; } public static final String REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH_PARM_NAME = "REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH"; /** * get the reversal date default day of month defined as an application parameter */ protected int getReversalDateDefaultDayOfMonth() { ParameterService parameterService = SpringContext.getBean(ParameterService.class); String defaultDayOfMonth = parameterService.getParameterValueAsString(AuxiliaryVoucherDocument.class, REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH_PARM_NAME); try { Integer reversalDateDefaultDayOfMonth = Integer.parseInt(defaultDayOfMonth); return reversalDateDefaultDayOfMonth; } catch(Exception e){ LOG.info("Invalid value was assigned to the paremeter: " + REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH_PARM_NAME + ". The default value " + KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_DAY_OF_MONTH + " is applied."); } return KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_DAY_OF_MONTH; } }