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.action;
017:
018: import java.io.ByteArrayOutputStream;
019: import java.util.Iterator;
020: import java.util.List;
021:
022: import javax.servlet.http.HttpServletRequest;
023: import javax.servlet.http.HttpServletResponse;
024:
025: import org.apache.struts.action.ActionForm;
026: import org.apache.struts.action.ActionForward;
027: import org.apache.struts.action.ActionMapping;
028: import org.kuali.core.service.DocumentService;
029: import org.kuali.core.service.KualiConfigurationService;
030: import org.kuali.core.service.KualiRuleService;
031: import org.kuali.core.util.GlobalVariables;
032: import org.kuali.core.util.Timer;
033: import org.kuali.core.util.WebUtils;
034: import org.kuali.core.web.struts.form.KualiDocumentFormBase;
035: import org.kuali.kfs.KFSConstants;
036: import org.kuali.kfs.KFSKeyConstants;
037: import org.kuali.kfs.KFSPropertyConstants;
038: import org.kuali.kfs.context.SpringContext;
039: import org.kuali.kfs.web.struts.action.KualiAccountingDocumentActionBase;
040: import org.kuali.module.financial.bo.CashReceiptHeader;
041: import org.kuali.module.financial.bo.Check;
042: import org.kuali.module.financial.bo.CoinDetail;
043: import org.kuali.module.financial.bo.CurrencyDetail;
044: import org.kuali.module.financial.document.CashReceiptDocument;
045: import org.kuali.module.financial.rule.event.AddCheckEvent;
046: import org.kuali.module.financial.rule.event.DeleteCheckEvent;
047: import org.kuali.module.financial.rule.event.UpdateCheckEvent;
048: import org.kuali.module.financial.rules.CashReceiptDocumentRuleUtil;
049: import org.kuali.module.financial.service.CashReceiptCoverSheetService;
050: import org.kuali.module.financial.service.CashReceiptService;
051: import org.kuali.module.financial.web.struts.form.CashReceiptForm;
052:
053: import edu.iu.uis.eden.exception.WorkflowException;
054:
055: /**
056: *
057: */
058: public class CashReceiptAction extends
059: KualiAccountingDocumentActionBase {
060: /**
061: * Adds handling for check updates
062: *
063: * @see org.apache.struts.action.Action#execute(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm,
064: * javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
065: */
066: @Override
067: public ActionForward execute(ActionMapping mapping,
068: ActionForm form, HttpServletRequest request,
069: HttpServletResponse response) throws Exception {
070: Timer t0 = new Timer("execute");
071: CashReceiptForm cform = (CashReceiptForm) form;
072:
073: if (cform.hasDocumentId()) {
074: CashReceiptDocument cdoc = cform.getCashReceiptDocument();
075:
076: // handle change of checkEntryMode
077: processCheckEntryMode(cform, cdoc);
078:
079: // handle changes to checks (but only if current checkEntryMode is 'detail')
080: if (CashReceiptDocument.CHECK_ENTRY_DETAIL.equals(cdoc
081: .getCheckEntryMode())) {
082: cdoc.setTotalCheckAmount(cdoc.calculateCheckTotal()); // recalc b/c changes to the amounts could have happened
083: processChecks(cdoc, cform);
084: }
085:
086: // generate errors for negative cash totals (especially for the recalculate button)
087: CashReceiptDocumentRuleUtil.areCashTotalsInvalid(cdoc);
088: }
089:
090: // proceed as usual
091: ActionForward result = super .execute(mapping, form, request,
092: response);
093: t0.log();
094: return result;
095:
096: }
097:
098: /**
099: * Prepares and streams CR PDF Cover Sheet
100: *
101: * @param mapping
102: * @param form
103: * @param request
104: * @param response
105: * @return ActionForward
106: * @throws Exception
107: */
108: public ActionForward printCoverSheet(ActionMapping mapping,
109: ActionForm form, HttpServletRequest request,
110: HttpServletResponse response) throws Exception {
111:
112: // get directory of tempate
113: String directory = SpringContext.getBean(
114: KualiConfigurationService.class).getPropertyString(
115: KFSConstants.EXTERNALIZABLE_HELP_URL_KEY);
116:
117: // retrieve document
118: String documentNumber = request
119: .getParameter(KFSPropertyConstants.DOCUMENT_NUMBER);
120:
121: CashReceiptDocument document = (CashReceiptDocument) SpringContext
122: .getBean(DocumentService.class).getByDocumentHeaderId(
123: documentNumber);
124:
125: // since this action isn't triggered by a post, we don't have the normal document data
126: // so we have to set the document into the form manually so that later authz processing
127: // has a document object instance to work with
128: CashReceiptForm crForm = (CashReceiptForm) form;
129: crForm.setDocument(document);
130:
131: ByteArrayOutputStream baos = new ByteArrayOutputStream();
132: CashReceiptCoverSheetService coverSheetService = SpringContext
133: .getBean(CashReceiptCoverSheetService.class);
134: coverSheetService.generateCoverSheet(document, directory, baos);
135: String fileName = documentNumber + "_cover_sheet.pdf";
136: WebUtils.saveMimeOutputStreamAsFile(response,
137: "application/pdf", baos, fileName);
138:
139: return null;
140: }
141:
142: /**
143: * This method processes the check entry mode to determine if the user is entering checks or if they are just entering the
144: * total.
145: *
146: * @param crForm
147: * @param crDoc
148: */
149: private void processCheckEntryMode(CashReceiptForm crForm,
150: CashReceiptDocument crDoc) {
151: String formMode = crForm.getCheckEntryMode();
152: String docMode = crDoc.getCheckEntryMode();
153:
154: if (CashReceiptDocument.CHECK_ENTRY_DETAIL.equals(formMode)
155: || CashReceiptDocument.CHECK_ENTRY_TOTAL
156: .equals(formMode)) {
157: if (!formMode.equals(docMode)) {
158: if (formMode
159: .equals(CashReceiptDocument.CHECK_ENTRY_DETAIL)) {
160: // save current checkTotal, for future restoration
161: crForm.setCheckTotal(crDoc.getTotalCheckAmount());
162:
163: // change mode
164: crDoc.setCheckEntryMode(formMode);
165: crDoc.setTotalCheckAmount(crDoc
166: .calculateCheckTotal());
167:
168: // notify user
169: GlobalVariables
170: .getMessageList()
171: .add(
172: KFSKeyConstants.CashReceipt.MSG_CHECK_ENTRY_INDIVIDUAL);
173: } else {
174: // restore saved checkTotal
175: crDoc.setTotalCheckAmount(crForm.getCheckTotal());
176:
177: // change mode
178: crDoc.setCheckEntryMode(formMode);
179:
180: // notify user
181: GlobalVariables
182: .getMessageList()
183: .add(
184: KFSKeyConstants.CashReceipt.MSG_CHECK_ENTRY_TOTAL);
185: }
186: }
187: }
188: }
189:
190: /**
191: * This method handles iterating over the check list and generating check events to apply rules to.
192: *
193: * @param cdoc
194: * @param cform
195: */
196: private void processChecks(CashReceiptDocument cdoc,
197: CashReceiptForm cform) {
198: List formChecks = cdoc.getChecks();
199:
200: int index = 0;
201: Iterator i = formChecks.iterator();
202: while (i.hasNext()) {
203: Check formCheck = (Check) i.next();
204:
205: // only generate update events for specific action methods
206: String methodToCall = cform.getMethodToCall();
207: if (UPDATE_EVENT_ACTIONS.contains(methodToCall)) {
208: SpringContext
209: .getBean(KualiRuleService.class)
210: .applyRules(
211: new UpdateCheckEvent(
212: KFSPropertyConstants.DOCUMENT
213: + "."
214: + KFSPropertyConstants.CHECK
215: + "[" + index + "]",
216: cdoc, formCheck));
217: }
218: index++;
219: }
220: }
221:
222: /**
223: * Adds Check instance created from the current "new check" line to the document
224: *
225: * @param mapping
226: * @param form
227: * @param request
228: * @param response
229: * @return ActionForward
230: * @throws Exception
231: */
232: public ActionForward addCheck(ActionMapping mapping,
233: ActionForm form, HttpServletRequest request,
234: HttpServletResponse response) throws Exception {
235: CashReceiptForm crForm = (CashReceiptForm) form;
236: CashReceiptDocument crDoc = crForm.getCashReceiptDocument();
237:
238: Check newCheck = crForm.getNewCheck();
239: newCheck.setDocumentNumber(crDoc.getDocumentNumber());
240:
241: // check business rules
242: boolean rulePassed = SpringContext.getBean(
243: KualiRuleService.class).applyRules(
244: new AddCheckEvent(KFSConstants.NEW_CHECK_PROPERTY_NAME,
245: crDoc, newCheck));
246: if (rulePassed) {
247: // add check
248: crDoc.addCheck(newCheck);
249:
250: // clear the used newCheck
251: crForm.setNewCheck(crDoc.createNewCheck());
252: }
253:
254: return mapping.findForward(KFSConstants.MAPPING_BASIC);
255: }
256:
257: /**
258: * Deletes the selected check (line) from the document
259: *
260: * @param mapping
261: * @param form
262: * @param request
263: * @param response
264: * @return ActionForward
265: * @throws Exception
266: */
267: public ActionForward deleteCheck(ActionMapping mapping,
268: ActionForm form, HttpServletRequest request,
269: HttpServletResponse response) throws Exception {
270: CashReceiptForm crForm = (CashReceiptForm) form;
271: CashReceiptDocument crDoc = crForm.getCashReceiptDocument();
272:
273: int deleteIndex = getLineToDelete(request);
274: Check oldCheck = crDoc.getCheck(deleteIndex);
275:
276: boolean rulePassed = SpringContext.getBean(
277: KualiRuleService.class).applyRules(
278: new DeleteCheckEvent(
279: KFSConstants.EXISTING_CHECK_PROPERTY_NAME,
280: crDoc, oldCheck));
281:
282: if (rulePassed) {
283: // delete check
284: crDoc.removeCheck(deleteIndex);
285:
286: // delete baseline check, if any
287: if (crForm.hasBaselineCheck(deleteIndex)) {
288: crForm.getBaselineChecks().remove(deleteIndex);
289: }
290: } else {
291: GlobalVariables.getErrorMap().putError(
292: "document.check[" + deleteIndex + "]",
293: KFSKeyConstants.Check.ERROR_CHECK_DELETERULE,
294: Integer.toString(deleteIndex));
295: }
296:
297: return mapping.findForward(KFSConstants.MAPPING_BASIC);
298: }
299:
300: /**
301: * Changes the current check-entry mode, if necessary
302: *
303: * @param mapping
304: * @param form
305: * @param request
306: * @param response
307: * @return ActionForward
308: * @throws Exception
309: */
310: public ActionForward changeCheckEntryMode(ActionMapping mapping,
311: ActionForm form, HttpServletRequest request,
312: HttpServletResponse response) throws Exception {
313:
314: CashReceiptForm crForm = (CashReceiptForm) form;
315: CashReceiptDocument crDoc = crForm.getCashReceiptDocument();
316:
317: String formMode = crForm.getCheckEntryMode();
318: String docMode = crDoc.getCheckEntryMode();
319:
320: if (CashReceiptDocument.CHECK_ENTRY_DETAIL.equals(formMode)
321: || CashReceiptDocument.CHECK_ENTRY_TOTAL
322: .equals(formMode)) {
323: if (!formMode.equals(docMode)) {
324:
325: if (formMode
326: .equals(CashReceiptDocument.CHECK_ENTRY_DETAIL)) {
327: // save current checkTotal, for future restoration
328: crForm.setCheckTotal(crDoc.getTotalCheckAmount());
329:
330: // change mode
331: crDoc.setCheckEntryMode(formMode);
332: crDoc.setTotalCheckAmount(crDoc
333: .calculateCheckTotal());
334:
335: // notify user
336: GlobalVariables
337: .getMessageList()
338: .add(
339: KFSKeyConstants.CashReceipt.MSG_CHECK_ENTRY_INDIVIDUAL);
340: } else {
341: // restore saved checkTotal
342: crDoc.setTotalCheckAmount(crForm.getCheckTotal());
343:
344: // change mode
345: crDoc.setCheckEntryMode(formMode);
346:
347: // notify user
348: GlobalVariables
349: .getMessageList()
350: .add(
351: KFSKeyConstants.CashReceipt.MSG_CHECK_ENTRY_TOTAL);
352: }
353: }
354: }
355:
356: return mapping.findForward(KFSConstants.MAPPING_BASIC);
357: }
358:
359: /**
360: * @see org.kuali.core.web.struts.action.KualiTransactionalDocumentActionBase#createDocument(org.kuali.core.web.struts.form.KualiDocumentFormBase)
361: */
362: @Override
363: protected void createDocument(
364: KualiDocumentFormBase kualiDocumentFormBase)
365: throws WorkflowException {
366: super .createDocument(kualiDocumentFormBase);
367:
368: CashReceiptForm crForm = (CashReceiptForm) kualiDocumentFormBase;
369: CashReceiptDocument crDoc = crForm.getCashReceiptDocument();
370:
371: CashReceiptService crs = SpringContext
372: .getBean(CashReceiptService.class);
373: String verificationUnit = crs
374: .getCashReceiptVerificationUnitForUser(GlobalVariables
375: .getUserSession().getUniversalUser());
376: String campusCode = crs
377: .getCampusCodeForCashReceiptVerificationUnit(verificationUnit);
378: crDoc.setCampusLocationCode(campusCode);
379:
380: crDoc.setCashReceiptHeader(new CashReceiptHeader());
381: crDoc.getCashReceiptHeader().setDocumentNumber(
382: crDoc.getDocumentNumber());
383: crDoc.getCashReceiptHeader().setWorkgroupName(verificationUnit);
384:
385: /* initialize currency and coin detail */
386: CurrencyDetail currencyDetail = new CurrencyDetail();
387: currencyDetail
388: .setCashieringRecordSource(KFSConstants.CurrencyCoinSources.CASH_RECEIPTS);
389: currencyDetail
390: .setFinancialDocumentTypeCode(CashReceiptDocument.DOCUMENT_TYPE);
391: currencyDetail.setDocumentNumber(crDoc.getDocumentNumber());
392: crDoc.setCurrencyDetail(currencyDetail);
393:
394: CoinDetail coinDetail = new CoinDetail();
395: coinDetail
396: .setCashieringRecordSource(KFSConstants.CurrencyCoinSources.CASH_RECEIPTS);
397: coinDetail
398: .setFinancialDocumentTypeCode(CashReceiptDocument.DOCUMENT_TYPE);
399: coinDetail.setDocumentNumber(crDoc.getDocumentNumber());
400: crDoc.setCoinDetail(coinDetail);
401:
402: initDerivedCheckValues(crForm);
403: }
404:
405: /**
406: * @see org.kuali.core.web.struts.action.KualiTransactionalDocumentActionBase#loadDocument(org.kuali.core.web.struts.form.KualiDocumentFormBase)
407: */
408: @Override
409: protected void loadDocument(
410: KualiDocumentFormBase kualiDocumentFormBase)
411: throws WorkflowException {
412: super .loadDocument(kualiDocumentFormBase);
413:
414: initDerivedCheckValues((CashReceiptForm) kualiDocumentFormBase);
415: }
416:
417: /**
418: * Initializes form values which must be derived form document contents (i.e. those which aren't directly available from the
419: * document)
420: *
421: * @param cform
422: */
423: private void initDerivedCheckValues(CashReceiptForm cform) {
424: CashReceiptDocument cdoc = cform.getCashReceiptDocument();
425:
426: cform.setCheckEntryMode(cdoc.getCheckEntryMode());
427: cform.setCheckTotal(cdoc.getTotalCheckAmount());
428:
429: cform.getBaselineChecks().clear();
430: cform.getBaselineChecks().addAll(
431: cform.getCashReceiptDocument().getChecks());
432: }
433: }
|