View Javadoc
1   /*
2    * Copyright 2005-2006 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.fp.document.web.struts;
17  
18  import static org.kuali.ole.sys.OLEConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE;
19  import static org.kuali.ole.sys.OLEConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE;
20  import static org.kuali.ole.sys.OLEConstants.AuxiliaryVoucher.RECODE_DOC_TYPE;
21  
22  import java.sql.Date;
23  import java.util.ArrayList;
24  import java.util.Calendar;
25  import java.util.List;
26  
27  import javax.servlet.http.HttpServletRequest;
28  
29  import org.apache.commons.collections.CollectionUtils;
30  import org.apache.commons.collections.Predicate;
31  import org.joda.time.DateTime;
32  import org.kuali.ole.coa.businessobject.AccountingPeriod;
33  import org.kuali.ole.coa.service.AccountingPeriodService;
34  import org.kuali.ole.fp.document.AuxiliaryVoucherDocument;
35  import org.kuali.ole.fp.document.validation.impl.AuxiliaryVoucherDocumentRuleConstants;
36  import org.kuali.ole.sys.OLEConstants;
37  import org.kuali.ole.sys.context.SpringContext;
38  import org.kuali.ole.sys.service.UniversityDateService;
39  import org.kuali.rice.core.api.datetime.DateTimeService;
40  import org.kuali.rice.core.api.parameter.ParameterEvaluatorService;
41  import org.kuali.rice.coreservice.framework.parameter.ParameterService;
42  import org.kuali.rice.krad.document.Document;
43  import org.kuali.rice.krad.util.ObjectUtils;
44  
45  /**
46   * Struts form so <code>{@link AuxiliaryVoucherDocument}</code> can be accessed and modified through UI.
47   */
48  public class AuxiliaryVoucherForm extends VoucherForm {
49      private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(AuxiliaryVoucherForm.class);
50  
51      protected String originalVoucherType = OLEConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE; // keep this in sync with the default
52  
53      // value set in the document business
54      // object
55  
56      public AuxiliaryVoucherForm() {
57          super();
58      }
59  
60      @Override
61      protected String getDefaultDocumentTypeName() {
62          return "OLE_AV";
63      }
64  
65      /**
66       * Overrides the parent to call super.populate and then to call the two methods that are specific to loading the two select
67       * lists on the page. In addition, this also makes sure that the credit and debit amounts are filled in for situations where
68       * validation errors occur and the page reposts.
69       *
70       * @see org.kuali.rice.kns.web.struts.pojo.PojoForm#populate(javax.servlet.http.HttpServletRequest)
71       */
72      @Override
73      public void populate(HttpServletRequest request) {
74          // populate the drop downs
75          super.populate(request);
76          populateReversalDateForRendering();
77      }
78  
79      /**
80       * @return Returns the serviceBillingDocument.
81       */
82      public AuxiliaryVoucherDocument getAuxiliaryVoucherDocument() {
83          return (AuxiliaryVoucherDocument) getDocument();
84      }
85  
86      /**
87       * @param serviceBillingDocument The serviceBillingDocument to set.
88       */
89      public void setAuxiliaryVoucherDocument(AuxiliaryVoucherDocument auxiliaryVoucherDocument) {
90          setDocument(auxiliaryVoucherDocument);
91      }
92  
93      /**
94       * Gets today's date and then sets the day of the month as 15th, irrespective of the current day of the month
95       * @return the modified reversal date
96       */
97      protected Date getAvReversalDate() {
98          Date documentReveralDate = getAuxiliaryVoucherDocument().getReversalDate();
99          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 }