001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.financial.web.struts.form;
017:
018: import static org.kuali.kfs.KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE;
019: import static org.kuali.kfs.KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE;
020: import static org.kuali.kfs.KFSConstants.AuxiliaryVoucher.RECODE_DOC_TYPE;
021:
022: import java.util.ArrayList;
023:
024: import javax.servlet.http.HttpServletRequest;
025:
026: import org.apache.commons.collections.CollectionUtils;
027: import org.apache.commons.collections.Predicate;
028: import org.kuali.core.document.Document;
029: import org.kuali.core.service.DateTimeService;
030: import org.kuali.kfs.KFSConstants;
031: import org.kuali.kfs.context.SpringContext;
032: import org.kuali.kfs.service.ParameterEvaluator;
033: import org.kuali.kfs.service.ParameterService;
034: import org.kuali.module.chart.bo.AccountingPeriod;
035: import org.kuali.module.chart.service.AccountingPeriodService;
036: import org.kuali.module.financial.document.AuxiliaryVoucherDocument;
037: import org.kuali.module.financial.rules.AuxiliaryVoucherDocumentRule;
038: import org.kuali.module.financial.rules.AuxiliaryVoucherDocumentRuleConstants;
039: import org.kuali.module.financial.service.UniversityDateService;
040:
041: /**
042: * Struts form so <code>{@link AuxiliaryVoucherDocument}</code> can be accessed and modified through UI.
043: */
044: public class AuxiliaryVoucherForm extends VoucherForm {
045: private String originalVoucherType = KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE; // keep this in sync with the default
046:
047: // value set in the document business
048: // object
049:
050: public AuxiliaryVoucherForm() {
051: super ();
052: setDocument(new AuxiliaryVoucherDocument());
053: }
054:
055: /**
056: * Overrides the parent to call super.populate and then to call the two methods that are specific to loading the two select
057: * lists on the page. In addition, this also makes sure that the credit and debit amounts are filled in for situations where
058: * validation errors occur and the page reposts.
059: *
060: * @see org.kuali.core.web.struts.pojo.PojoForm#populate(javax.servlet.http.HttpServletRequest)
061: */
062: public void populate(HttpServletRequest request) {
063: // populate the drop downs
064: super .populate(request);
065: populateReversalDateForRendering();
066: }
067:
068: /**
069: * @return Returns the serviceBillingDocument.
070: */
071: public AuxiliaryVoucherDocument getAuxiliaryVoucherDocument() {
072: return (AuxiliaryVoucherDocument) getDocument();
073: }
074:
075: /**
076: * @param serviceBillingDocument The serviceBillingDocument to set.
077: */
078: public void setAuxiliaryVoucherDocument(
079: AuxiliaryVoucherDocument auxiliaryVoucherDocument) {
080: setDocument(auxiliaryVoucherDocument);
081: }
082:
083: /**
084: * Handles special case display rules for displaying Reversal Date at UI layer
085: */
086: public void populateReversalDateForRendering() {
087: java.sql.Date today = SpringContext.getBean(
088: DateTimeService.class).getCurrentSqlDateMidnight();
089:
090: if (getAuxiliaryVoucherDocument().getTypeCode().equals(
091: ACCRUAL_DOC_TYPE)
092: && (getAuxiliaryVoucherDocument().getReversalDate() == null || getAuxiliaryVoucherDocument()
093: .getReversalDate().before(today))) {
094: getAuxiliaryVoucherDocument().setReversalDate(today);
095: } else if (getAuxiliaryVoucherDocument().getTypeCode().equals(
096: ADJUSTMENT_DOC_TYPE)) {
097: getAuxiliaryVoucherDocument().setReversalDate(null);
098: } else if (getAuxiliaryVoucherDocument().getTypeCode().equals(
099: RECODE_DOC_TYPE)) {
100: getAuxiliaryVoucherDocument().setReversalDate(
101: new java.sql.Date(getDocument().getDocumentHeader()
102: .getWorkflowDocument().getCreateDate()
103: .getTime()));
104: }
105: }
106:
107: /**
108: * This method returns the reversal date in the format MMM d, yyyy.
109: *
110: * @return String
111: */
112: public String getFormattedReversalDate() {
113: return formatReversalDate(getAuxiliaryVoucherDocument()
114: .getReversalDate());
115: }
116:
117: /**
118: * @return String
119: */
120: public String getOriginalVoucherType() {
121: return originalVoucherType;
122: }
123:
124: /**
125: * @param originalVoucherType
126: */
127: public void setOriginalVoucherType(String originalVoucherType) {
128: this .originalVoucherType = originalVoucherType;
129: }
130:
131: /**
132: * Returns a formatted auxiliary voucher type: <Voucher Type Name> (<Voucher Type Code>)
133: *
134: * @return
135: */
136: public String getFormattedAuxiliaryVoucherType() {
137: String voucherTypeCode = getAuxiliaryVoucherDocument()
138: .getTypeCode();
139: String formattedVoucherType = new String();
140:
141: if (KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE
142: .equals(voucherTypeCode)) {
143: formattedVoucherType = KFSConstants.AuxiliaryVoucher.ACCRUAL_DOC_TYPE_NAME;
144: } else if (KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE
145: .equals(voucherTypeCode)) {
146: formattedVoucherType = KFSConstants.AuxiliaryVoucher.ADJUSTMENT_DOC_TYPE_NAME;
147: } else if (KFSConstants.AuxiliaryVoucher.RECODE_DOC_TYPE
148: .equals(voucherTypeCode)) {
149: formattedVoucherType = KFSConstants.AuxiliaryVoucher.RECODE_DOC_TYPE_NAME;
150: } else {
151: throw new IllegalStateException(
152: "Invalid auxiliary voucher type code: "
153: + voucherTypeCode);
154: }
155:
156: return formattedVoucherType + " (" + voucherTypeCode + ")";
157: }
158:
159: /**
160: * This method generates a proper list of valid accounting periods that the user can select from.
161: *
162: * @see org.kuali.module.financial.web.struts.form.VoucherForm#populateAccountingPeriodListForRendering()
163: */
164: @Override
165: protected void populateAccountingPeriodListForRendering() {
166: // grab the list of valid accounting periods
167: ArrayList accountingPeriods = new ArrayList(SpringContext
168: .getBean(AccountingPeriodService.class)
169: .getOpenAccountingPeriods());
170: // now, validate further, based on the rules from AuxiliaryVoucherDocumentRule
171: ArrayList filteredAccountingPeriods = new ArrayList();
172: filteredAccountingPeriods.addAll(CollectionUtils.select(
173: accountingPeriods, new OpenAuxiliaryVoucherPredicate(
174: this .getDocument())));
175: // if our auxiliary voucher doc contains an accounting period already, make sure the collection has it too!
176: if (this .getDocument() instanceof AuxiliaryVoucherDocument) {
177: AuxiliaryVoucherDocument avDoc = (AuxiliaryVoucherDocument) this
178: .getDocument();
179: if (avDoc != null
180: && avDoc.getAccountingPeriod() != null
181: && !filteredAccountingPeriods.contains(avDoc
182: .getAccountingPeriod())) {
183: // this is most likely going to happen because the approver is trying
184: // to approve a document after the grace period of an accounting period
185: // or a fiscal year has switched over when the document was first created;
186: // as such, it's probably a good bet that the doc's accounting period
187: // belongs at the top of the list
188: filteredAccountingPeriods.add(0, avDoc
189: .getAccountingPeriod());
190: }
191: }
192: // set into the form for rendering
193: setAccountingPeriods(filteredAccountingPeriods);
194: // set the chosen accounting period into the form
195: populateSelectedVoucherAccountingPeriod();
196: }
197:
198: private class OpenAuxiliaryVoucherPredicate implements Predicate {
199: private ParameterService parameterService;
200: private UniversityDateService dateService;
201: private AccountingPeriodService acctPeriodService;
202: private Document auxiliaryVoucherDocument;
203: private AccountingPeriod currPeriod;
204: private ParameterEvaluator evaluator;
205:
206: public OpenAuxiliaryVoucherPredicate(Document doc) {
207: this .parameterService = SpringContext
208: .getBean(ParameterService.class);
209: this .dateService = SpringContext
210: .getBean(UniversityDateService.class);
211: this .acctPeriodService = SpringContext
212: .getBean(AccountingPeriodService.class);
213: this .auxiliaryVoucherDocument = doc;
214: this .currPeriod = acctPeriodService
215: .getByDate(new java.sql.Date(
216: new java.util.GregorianCalendar()
217: .getTimeInMillis()));
218: }
219:
220: public boolean evaluate(Object o) {
221: boolean result = false;
222: if (o instanceof AccountingPeriod) {
223: AccountingPeriod period = (AccountingPeriod) o;
224:
225: java.sql.Date currentDate = new java.sql.Date(
226: new java.util.Date().getTime());
227:
228: if (evaluator == null) {
229: evaluator = SpringContext
230: .getBean(ParameterService.class)
231: .getParameterEvaluator(
232: AuxiliaryVoucherDocument.class,
233: AuxiliaryVoucherDocumentRuleConstants.RESTRICTED_PERIOD_CODES,
234: period
235: .getUniversityFiscalPeriodCode());
236: } else {
237: evaluator.setConstrainedValue(period
238: .getUniversityFiscalPeriodCode());
239: }
240: result = evaluator.evaluationSucceeds();
241: if (result) {
242: result = (period.getUniversityFiscalYear()
243: .equals(dateService.getCurrentFiscalYear()));
244: if (result) {
245: // did this accounting period end before now?
246: result = acctPeriodService
247: .compareAccountingPeriodsByDate(period,
248: currPeriod) >= 0;
249: if (!result) {
250: // if yes, are we still in the grace period?
251: result = AuxiliaryVoucherDocumentRule
252: .calculateIfWithinGracePeriod(
253: currentDate, period);
254: }
255: } else {
256: // are we in current in the grace period of an ending accounting period of the previous fiscal year?
257: result = AuxiliaryVoucherDocumentRule
258: .calculateIfWithinGracePeriod(
259: currentDate, period)
260: && AuxiliaryVoucherDocumentRule
261: .isEndOfPreviousFiscalYear(period);
262: }
263: }
264: }
265: return result;
266: }
267: }
268:
269: }
|