001/* 002 * Copyright 2005-2006 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 */ 016package org.kuali.ole.fp.document.web.struts; 017 018import static org.kuali.ole.sys.OLEConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE; 019import static org.kuali.ole.sys.OLEConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE; 020import static org.kuali.ole.sys.OLEConstants.AuxiliaryVoucher.RECODE_DOC_TYPE; 021 022import java.sql.Date; 023import java.util.ArrayList; 024import java.util.Calendar; 025import java.util.List; 026 027import javax.servlet.http.HttpServletRequest; 028 029import org.apache.commons.collections.CollectionUtils; 030import org.apache.commons.collections.Predicate; 031import org.joda.time.DateTime; 032import org.kuali.ole.coa.businessobject.AccountingPeriod; 033import org.kuali.ole.coa.service.AccountingPeriodService; 034import org.kuali.ole.fp.document.AuxiliaryVoucherDocument; 035import org.kuali.ole.fp.document.validation.impl.AuxiliaryVoucherDocumentRuleConstants; 036import org.kuali.ole.sys.OLEConstants; 037import org.kuali.ole.sys.context.SpringContext; 038import org.kuali.ole.sys.service.UniversityDateService; 039import org.kuali.rice.core.api.datetime.DateTimeService; 040import org.kuali.rice.core.api.parameter.ParameterEvaluatorService; 041import org.kuali.rice.coreservice.framework.parameter.ParameterService; 042import org.kuali.rice.krad.document.Document; 043import org.kuali.rice.krad.util.ObjectUtils; 044 045/** 046 * Struts form so <code>{@link AuxiliaryVoucherDocument}</code> can be accessed and modified through UI. 047 */ 048public class AuxiliaryVoucherForm extends VoucherForm { 049 private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AuxiliaryVoucherForm.class); 050 051 protected String originalVoucherType = OLEConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE; // keep this in sync with the default 052 053 // value set in the document business 054 // object 055 056 public AuxiliaryVoucherForm() { 057 super(); 058 } 059 060 @Override 061 protected String getDefaultDocumentTypeName() { 062 return "OLE_AV"; 063 } 064 065 /** 066 * Overrides the parent to call super.populate and then to call the two methods that are specific to loading the two select 067 * lists on the page. In addition, this also makes sure that the credit and debit amounts are filled in for situations where 068 * validation errors occur and the page reposts. 069 * 070 * @see org.kuali.rice.kns.web.struts.pojo.PojoForm#populate(javax.servlet.http.HttpServletRequest) 071 */ 072 @Override 073 public void populate(HttpServletRequest request) { 074 // populate the drop downs 075 super.populate(request); 076 populateReversalDateForRendering(); 077 } 078 079 /** 080 * @return Returns the serviceBillingDocument. 081 */ 082 public AuxiliaryVoucherDocument getAuxiliaryVoucherDocument() { 083 return (AuxiliaryVoucherDocument) getDocument(); 084 } 085 086 /** 087 * @param serviceBillingDocument The serviceBillingDocument to set. 088 */ 089 public void setAuxiliaryVoucherDocument(AuxiliaryVoucherDocument auxiliaryVoucherDocument) { 090 setDocument(auxiliaryVoucherDocument); 091 } 092 093 /** 094 * Gets today's date and then sets the day of the month as 15th, irrespective of the current day of the month 095 * @return the modified reversal date 096 */ 097 protected Date getAvReversalDate() { 098 Date documentReveralDate = getAuxiliaryVoucherDocument().getReversalDate(); 099 if (ObjectUtils.isNotNull(documentReveralDate)) { 100 return documentReveralDate; 101 } 102 103 java.sql.Date avReversalDate = SpringContext.getBean(DateTimeService.class).getCurrentSqlDateMidnight(); 104 105 Calendar cal = Calendar.getInstance(); 106 cal.setTime(avReversalDate); 107 108 int thisMonth; 109 110 if (getAuxiliaryVoucherDocument().getAccountingPeriod().getUniversityFiscalPeriodCode().equals(OLEConstants.MONTH13)) { 111 thisMonth = cal.JULY; 112 } 113 else { 114 thisMonth = getAuxiliaryVoucherDocument().getAccountingPeriod().getMonth(); 115 } 116 117 cal.set(Calendar.MONTH, (thisMonth)); 118 119 //if today's day > 15 then set the month to next month. 120 // if (cal.get(Calendar.DAY_OF_MONTH) > OLEConstants.AuxiliaryVoucher.ACCRUAL_DOC_DAY_OF_MONTH) { 121 // cal.add(Calendar.MONTH, 1); 122 // } 123 124 int reversalDateDefaultDayOfMonth = this.getReversalDateDefaultDayOfMonth(); 125 126 cal.set(Calendar.DAY_OF_MONTH, reversalDateDefaultDayOfMonth); 127 128 long timeInMillis = cal.getTimeInMillis(); 129 avReversalDate.setTime(timeInMillis); 130 131 return avReversalDate; 132 } 133 134 /** 135 * Handles special case display rules for displaying Reversal Date at UI layer 136 */ 137 public void populateReversalDateForRendering() { 138 java.sql.Date today = getAvReversalDate(); 139 140 if (getAuxiliaryVoucherDocument().getTypeCode().equals(ACCRUAL_DOC_TYPE)) { 141 getAuxiliaryVoucherDocument().setReversalDate(today); 142 } 143 else if (getAuxiliaryVoucherDocument().getTypeCode().equals(ADJUSTMENT_DOC_TYPE)) { 144 getAuxiliaryVoucherDocument().setReversalDate(null); 145 } 146 else if (getAuxiliaryVoucherDocument().getTypeCode().equals(RECODE_DOC_TYPE)) { 147 DateTime ts = new DateTime(getAuxiliaryVoucherDocument().getDocumentHeader().getWorkflowDocument().getDateCreated()); 148 Date newts = new Date(ts.getMillis()); 149 150 getAuxiliaryVoucherDocument().setReversalDate(newts); 151 } 152 } 153 154 /** 155 * This method returns the reversal date in the format MMM d, yyyy. 156 * 157 * @return String 158 */ 159 @Override 160 public String getFormattedReversalDate() { 161 return formatReversalDate(getAuxiliaryVoucherDocument().getReversalDate()); 162 } 163 164 /** 165 * @return String 166 */ 167 public String getOriginalVoucherType() { 168 return originalVoucherType; 169 } 170 171 /** 172 * @param originalVoucherType 173 */ 174 public void setOriginalVoucherType(String originalVoucherType) { 175 this.originalVoucherType = originalVoucherType; 176 } 177 178 /** 179 * Returns a formatted auxiliary voucher type: <Voucher Type Name> (<Voucher Type Code>) 180 * 181 * @return 182 */ 183 public String getFormattedAuxiliaryVoucherType() { 184 String voucherTypeCode = getAuxiliaryVoucherDocument().getTypeCode(); 185 String formattedVoucherType = new String(); 186 187 if (OLEConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE.equals(voucherTypeCode)) { 188 formattedVoucherType = OLEConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE_NAME; 189 } 190 else if (OLEConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE.equals(voucherTypeCode)) { 191 formattedVoucherType = OLEConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE_NAME; 192 } 193 else if (OLEConstants.AuxiliaryVoucher.RECODE_DOC_TYPE.equals(voucherTypeCode)) { 194 formattedVoucherType = OLEConstants.AuxiliaryVoucher.RECODE_DOC_TYPE_NAME; 195 } 196 else { 197 throw new IllegalStateException("Invalid auxiliary voucher type code: " + voucherTypeCode); 198 } 199 200 return formattedVoucherType + " (" + voucherTypeCode + ")"; 201 } 202 203 /** 204 * This method generates a proper list of valid accounting periods that the user can select from. 205 * 206 * @see org.kuali.ole.fp.document.web.struts.VoucherForm#populateAccountingPeriodListForRendering() 207 */ 208 @Override 209 public void populateAccountingPeriodListForRendering() { 210 // grab the list of valid accounting periods 211 ArrayList accountingPeriods = new ArrayList(SpringContext.getBean(AccountingPeriodService.class).getOpenAccountingPeriods()); 212 // now, validate further, based on the rules from AuxiliaryVoucherDocumentRule 213 ArrayList filteredAccountingPeriods = new ArrayList(); 214 filteredAccountingPeriods.addAll(CollectionUtils.select(accountingPeriods, new OpenAuxiliaryVoucherPredicate(this.getDocument()))); 215 // if our auxiliary voucher doc contains an accounting period already, make sure the collection has it too! 216 if (this.getDocument() instanceof AuxiliaryVoucherDocument) { 217 AuxiliaryVoucherDocument avDoc = (AuxiliaryVoucherDocument) this.getDocument(); 218 if (avDoc != null && avDoc.getAccountingPeriod() != null && !filteredAccountingPeriods.contains(avDoc.getAccountingPeriod())) { 219 // this is most likely going to happen because the approver is trying 220 // to approve a document after the grace period of an accounting period 221 // or a fiscal year has switched over when the document was first created; 222 // as such, it's probably a good bet that the doc's accounting period 223 // belongs at the top of the list 224 filteredAccountingPeriods.add(0, avDoc.getAccountingPeriod()); 225 } 226 } 227 // set into the form for rendering 228 setAccountingPeriods(filteredAccountingPeriods); 229 // set the chosen accounting period into the form 230 populateSelectedVoucherAccountingPeriod(); 231 } 232 233 protected class OpenAuxiliaryVoucherPredicate implements Predicate { 234 protected ParameterService parameterService; 235 protected UniversityDateService dateService; 236 protected AccountingPeriodService acctPeriodService; 237 protected Document auxiliaryVoucherDocument; 238 protected AccountingPeriod currPeriod; 239 protected java.sql.Date currentDate; 240 protected Integer currentFiscalYear; 241 242 public OpenAuxiliaryVoucherPredicate(Document doc) { 243 this.parameterService = SpringContext.getBean(ParameterService.class); 244 this.dateService = SpringContext.getBean(UniversityDateService.class); 245 this.acctPeriodService = SpringContext.getBean(AccountingPeriodService.class); 246 this.auxiliaryVoucherDocument = doc; 247 this.currPeriod = acctPeriodService.getByDate(new java.sql.Date(new java.util.GregorianCalendar().getTimeInMillis())); 248 this.currentDate = new java.sql.Date(new java.util.Date().getTime()); 249 this.currentFiscalYear = dateService.getCurrentFiscalYear(); 250 } 251 252 @Override 253 public boolean evaluate(Object o) { 254 boolean result = false; 255 if (o instanceof AccountingPeriod) { 256 AccountingPeriod period = (AccountingPeriod) o; 257 result = /*REFACTORME*/SpringContext.getBean(ParameterEvaluatorService.class).getParameterEvaluator(AuxiliaryVoucherDocument.class, AuxiliaryVoucherDocumentRuleConstants.RESTRICTED_PERIOD_CODES, period.getUniversityFiscalPeriodCode()).evaluationSucceeds(); 258 if (result) { 259 result = (period.getUniversityFiscalYear().equals( currentFiscalYear )); 260 if (result) { 261 // did this accounting period end before now? 262 result = acctPeriodService.compareAccountingPeriodsByDate(period, currPeriod) >= 0; 263 if (!result) { 264 // if yes, are we still in the grace period? 265 result = getAuxiliaryVoucherDocument().calculateIfWithinGracePeriod(currentDate, period); 266 } 267 } 268 else { 269 // are we in current in the grace period of an ending accounting period of the previous fiscal year? 270 result = getAuxiliaryVoucherDocument().calculateIfWithinGracePeriod(currentDate, period) && getAuxiliaryVoucherDocument().isEndOfPreviousFiscalYear(period); 271 } 272 } 273 } 274 return result; 275 } 276 } 277 278 public List<String> getAccountingPeriodCompositeValueList() { 279 List<String> accountingPeriodCompositeValueList = new ArrayList<String>(); 280 for (int i = 0; i < this.getAccountingPeriods().size(); i++) { 281 AccountingPeriod temp = (AccountingPeriod) this.getAccountingPeriods().get(i); 282 accountingPeriodCompositeValueList.add(temp.getUniversityFiscalPeriodCode() + temp.getUniversityFiscalYear()); 283 } 284 285 return accountingPeriodCompositeValueList; 286 } 287 288 public List<String> getAccountingPeriodLabelList() { 289 List<String> accountingPeriodLabelList = new ArrayList<String>(); 290 for (int i = 0; i < this.getAccountingPeriods().size(); i++) { 291 AccountingPeriod temp = (AccountingPeriod) this.getAccountingPeriods().get(i); 292 accountingPeriodLabelList.add(temp.getUniversityFiscalPeriodName()); 293 } 294 295 return accountingPeriodLabelList; 296 } 297 298 public static final String REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH_PARM_NAME = "REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH"; 299 300 /** 301 * get the reversal date default day of month defined as an application parameter 302 */ 303 protected int getReversalDateDefaultDayOfMonth() { 304 ParameterService parameterService = SpringContext.getBean(ParameterService.class); 305 String defaultDayOfMonth = parameterService.getParameterValueAsString(AuxiliaryVoucherDocument.class, REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH_PARM_NAME); 306 307 try { 308 Integer reversalDateDefaultDayOfMonth = Integer.parseInt(defaultDayOfMonth); 309 310 return reversalDateDefaultDayOfMonth; 311 } 312 catch(Exception e){ 313 LOG.info("Invalid value was assigned to the paremeter: " + REVERSAL_DATE_DEFAULT_DAY_OF_THE_MONTH_PARM_NAME + ". The default value " + OLEConstants.AuxiliaryVoucher.ACCRUAL_DOC_DAY_OF_MONTH + " is applied."); 314 } 315 316 return OLEConstants.AuxiliaryVoucher.ACCRUAL_DOC_DAY_OF_MONTH; 317 } 318}