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.FileNotFoundException;
019: import java.io.IOException;
020: import java.util.ArrayList;
021:
022: import javax.servlet.http.HttpServletRequest;
023: import javax.servlet.http.HttpServletResponse;
024:
025: import org.apache.commons.lang.StringUtils;
026: import org.apache.struts.action.ActionForm;
027: import org.apache.struts.action.ActionForward;
028: import org.apache.struts.action.ActionMapping;
029: import org.kuali.core.document.Document;
030: import org.kuali.core.document.authorization.DocumentAuthorizer;
031: import org.kuali.core.question.ConfirmationQuestion;
032: import org.kuali.core.service.DocumentAuthorizationService;
033: import org.kuali.core.service.KualiConfigurationService;
034: import org.kuali.core.util.GlobalVariables;
035: import org.kuali.core.util.KualiDecimal;
036: import org.kuali.core.web.format.CurrencyFormatter;
037: import org.kuali.core.web.struts.form.KualiDocumentFormBase;
038: import org.kuali.kfs.KFSConstants;
039: import org.kuali.kfs.KFSKeyConstants;
040: import org.kuali.kfs.KFSPropertyConstants;
041: import org.kuali.kfs.bo.SourceAccountingLine;
042: import org.kuali.kfs.context.SpringContext;
043: import org.kuali.module.chart.bo.codes.BalanceTyp;
044: import org.kuali.module.chart.service.BalanceTypService;
045: import org.kuali.module.financial.bo.VoucherAccountingLineHelper;
046: import org.kuali.module.financial.bo.VoucherAccountingLineHelperBase;
047: import org.kuali.module.financial.bo.VoucherSourceAccountingLine;
048: import org.kuali.module.financial.document.JournalVoucherDocument;
049: import org.kuali.module.financial.document.VoucherDocument;
050: import org.kuali.module.financial.web.struts.form.JournalVoucherForm;
051: import org.kuali.module.financial.web.struts.form.VoucherForm;
052:
053: import edu.iu.uis.eden.exception.WorkflowException;
054:
055: /**
056: * This class piggy backs on all of the functionality in the KualiTransactionalDocumentActionBase but is necessary for this document
057: * type. The Journal Voucher is unique in that it defines several fields that aren't typically used by the other financial
058: * transaction processing eDocs (i.e. external system fields, object type override, credit and debit amounts).
059: */
060: public class JournalVoucherAction extends VoucherAction {
061:
062: // used to determine which way the change balance type action is switching these are local constants only used within this
063: // action class these should not be used outside of this class
064: protected static final int CREDIT_DEBIT_TO_SINGLE_AMT_MODE = 0;
065: protected static final int SINGLE_AMT_TO_CREDIT_DEBIT_MODE = 1;
066: protected static final int EXT_ENCUMB_TO_NON_EXT_ENCUMB = 0;
067: protected static final int NON_EXT_ENCUMB_TO_EXT_ENCUMB = 1;
068: protected static final int NO_MODE_CHANGE = -1;
069:
070: /**
071: * Overrides the parent and then calls the super method after building the array lists for valid accounting periods and balance
072: * types.
073: *
074: * @see org.kuali.core.web.struts.action.KualiAction#execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
075: * HttpServletResponse response)
076: */
077: @Override
078: public ActionForward execute(ActionMapping mapping,
079: ActionForm form, HttpServletRequest request,
080: HttpServletResponse response) throws Exception {
081: JournalVoucherForm journalVoucherForm = (JournalVoucherForm) form;
082:
083: populateBalanceTypeOneDocument(journalVoucherForm);
084:
085: // now check to see if the balance type was changed and if so, we want to
086: // set the method to call so that the appropriate action can be invoked
087: // had to do it this way b/c the changing of the drop down causes the page to re-submit
088: // and couldn't use a hidden field called "methodToCall" b/c it screwed everything up
089: ActionForward returnForward;
090: if (StringUtils.isNotBlank(journalVoucherForm
091: .getOriginalBalanceType())
092: && !journalVoucherForm.getSelectedBalanceType()
093: .getCode().equals(
094: journalVoucherForm
095: .getOriginalBalanceType())) {
096: returnForward = super
097: .dispatchMethod(
098: mapping,
099: form,
100: request,
101: response,
102: KFSConstants.CHANGE_JOURNAL_VOUCHER_BALANCE_TYPE_METHOD);
103: // must call this here, because execute in the super method will never have control for this particular action
104: // this is called in the parent by super.execute()
105: Document document = journalVoucherForm.getDocument();
106: DocumentAuthorizer documentAuthorizer = SpringContext
107: .getBean(DocumentAuthorizationService.class)
108: .getDocumentAuthorizer(document);
109: journalVoucherForm
110: .populateAuthorizationFields(documentAuthorizer);
111: } else { // otherwise call the super
112: returnForward = super .execute(mapping, journalVoucherForm,
113: request, response);
114: }
115: return returnForward;
116: }
117:
118: /**
119: * Overrides the parent to first prompt the user appropriately to make sure that they want to submit and out of balance
120: * document, then calls super's route method.
121: *
122: * @see org.kuali.core.web.struts.action.KualiDocumentActionBase#route(org.apache.struts.action.ActionMapping,
123: * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
124: */
125: @Override
126: public ActionForward route(ActionMapping mapping, ActionForm form,
127: HttpServletRequest request, HttpServletResponse response)
128: throws Exception {
129: // process the question but we need to make sure there are lines and then check to see if it's not balanced
130: VoucherDocument vDoc = ((VoucherForm) form)
131: .getVoucherDocument();
132:
133: KualiDecimal balance = vDoc.getCreditTotal().subtract(
134: vDoc.getDebitTotal());
135: if (vDoc.getSourceAccountingLines().size() > 0
136: && balance.compareTo(KFSConstants.ZERO) != 0) {
137: // it's not in "balance"
138: ActionForward returnForward = processRouteOutOfBalanceDocumentConfirmationQuestion(
139: mapping, form, request, response);
140:
141: // if not null, then the question component either has control of the flow and needs to ask its questions
142: // or the person chose the "cancel" or "no" button
143: // otherwise we have control
144: if (returnForward != null) {
145: return returnForward;
146: }
147: }
148: // now call the route method
149: return super .route(mapping, form, request, response);
150: }
151:
152: /**
153: * This method handles grabbing the values from the form and pushing them into the document appropriately.
154: *
155: * @param journalVoucherForm
156: */
157: private void populateBalanceTypeOneDocument(
158: JournalVoucherForm journalVoucherForm) {
159: String selectedBalanceTypeCode = journalVoucherForm
160: .getSelectedBalanceType().getCode();
161: BalanceTyp selectedBalanceType = getPopulatedBalanceTypeInstance(selectedBalanceTypeCode);
162: journalVoucherForm.getJournalVoucherDocument()
163: .setBalanceTypeCode(selectedBalanceTypeCode);
164: journalVoucherForm.getJournalVoucherDocument().setBalanceType(
165: selectedBalanceType); // set the fully populated balance type
166: // object into the form's selected
167: // balance type
168: journalVoucherForm.setSelectedBalanceType(selectedBalanceType);
169: }
170:
171: /**
172: * Overrides to call super, and then to repopulate the credit/debit amounts b/c the credit/debit code might change during a JV
173: * error correction.
174: *
175: * @see org.kuali.core.web.struts.action.KualiTransactionalDocumentActionBase#correct(org.apache.struts.action.ActionMapping,
176: * org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
177: */
178: @Override
179: public ActionForward correct(ActionMapping mapping,
180: ActionForm form, HttpServletRequest request,
181: HttpServletResponse response) throws Exception {
182: ActionForward actionForward = super .correct(mapping, form,
183: request, response);
184:
185: JournalVoucherDocument jvDoc = (JournalVoucherDocument) ((JournalVoucherForm) form)
186: .getDocument();
187:
188: jvDoc.refreshReferenceObject(KFSPropertyConstants.BALANCE_TYPE);
189: // only repopulate if this is a JV that was entered in debit/credit mode
190: if (jvDoc.getBalanceType()
191: .isFinancialOffsetGenerationIndicator()) {
192: // now make sure to repopulate credit/debit amounts
193: populateAllVoucherAccountingLineHelpers((JournalVoucherForm) form);
194: }
195:
196: return actionForward;
197: }
198:
199: /**
200: * This method processes a change in the balance type for a Journal Voucher document - from either a offset generation balance
201: * type to a non-offset generation balance type or visa-versa.
202: *
203: * @param mapping
204: * @param form
205: * @param request
206: * @param response
207: * @return ActionForward
208: * @throws Exception
209: */
210: public ActionForward changeBalanceType(ActionMapping mapping,
211: ActionForm form, HttpServletRequest request,
212: HttpServletResponse response) throws Exception {
213: JournalVoucherForm journalVoucherForm = (JournalVoucherForm) form;
214:
215: // figure out which way the balance type is changing
216: int balanceTypeAmountChangeMode = determineBalanceTypeAmountChangeMode(journalVoucherForm);
217: int balanceTypeExternalEncumbranceChangeMode = determineBalanceTypeEncumbranceChangeMode(journalVoucherForm);
218:
219: // process the question
220: if (balanceTypeAmountChangeMode != NO_MODE_CHANGE
221: || balanceTypeExternalEncumbranceChangeMode != NO_MODE_CHANGE) {
222: ActionForward returnForward = processChangeBalanceTypeConfirmationQuestion(
223: mapping, form, request, response);
224:
225: // if not null, then the question component either has control of the flow and needs to ask its questions
226: // or the person choose the "cancel" or "no" button otherwise we have control
227: if (returnForward != null) {
228: return returnForward;
229: } else {
230: // deal with balance type changes first amount change
231: if (balanceTypeAmountChangeMode == CREDIT_DEBIT_TO_SINGLE_AMT_MODE) {
232: switchFromCreditDebitModeToSingleAmountMode(journalVoucherForm);
233: } else if (balanceTypeAmountChangeMode == SINGLE_AMT_TO_CREDIT_DEBIT_MODE) {
234: switchFromSingleAmountModeToCreditDebitMode(journalVoucherForm);
235: }
236:
237: // then look to see if the external encumbrance was involved
238: if (balanceTypeExternalEncumbranceChangeMode == EXT_ENCUMB_TO_NON_EXT_ENCUMB) {
239: switchFromExternalEncumbranceModeToNonExternalEncumbrance(journalVoucherForm);
240: }
241: }
242: }
243:
244: return mapping.findForward(KFSConstants.MAPPING_BASIC);
245: }
246:
247: /**
248: * This method will determine which balance type amount mode to switch to. A change in the balance type selection will
249: * eventually invoke this mechanism, which looks at the old balance type value, and the new balance type value to determine what
250: * the next mode is.
251: *
252: * @param journalVoucherForm
253: * @throws Exception
254: */
255: protected int determineBalanceTypeAmountChangeMode(
256: JournalVoucherForm journalVoucherForm) throws Exception {
257: int balanceTypeAmountChangeMode = NO_MODE_CHANGE;
258:
259: // retrieve fully populated balance type instances
260: BalanceTyp origBalType = getPopulatedBalanceTypeInstance(journalVoucherForm
261: .getOriginalBalanceType());
262: BalanceTyp newBalType = getPopulatedBalanceTypeInstance(journalVoucherForm
263: .getSelectedBalanceType().getCode());
264:
265: // figure out which ways we are switching the modes first deal with amount changes
266: if (origBalType.isFinancialOffsetGenerationIndicator()
267: && !newBalType.isFinancialOffsetGenerationIndicator()) { // credit/debit
268: balanceTypeAmountChangeMode = CREDIT_DEBIT_TO_SINGLE_AMT_MODE;
269: } else if (!origBalType.isFinancialOffsetGenerationIndicator()
270: && newBalType.isFinancialOffsetGenerationIndicator()) { // single
271: balanceTypeAmountChangeMode = SINGLE_AMT_TO_CREDIT_DEBIT_MODE;
272: }
273:
274: return balanceTypeAmountChangeMode;
275: }
276:
277: /**
278: * This method will determine which balance type encumbrance mode to switch to. A change in the balance type selection will
279: * eventually invoke this mechanism, which looks at the old balance type value, and the new balance type value to determine what
280: * the next mode is.
281: *
282: * @param journalVoucherForm
283: * @throws Exception
284: */
285: protected int determineBalanceTypeEncumbranceChangeMode(
286: JournalVoucherForm journalVoucherForm) throws Exception {
287: int balanceTypeExternalEncumbranceChangeMode = NO_MODE_CHANGE;
288:
289: // retrieve fully populated balance type instances
290: BalanceTyp origBalType = getPopulatedBalanceTypeInstance(journalVoucherForm
291: .getOriginalBalanceType());
292: BalanceTyp newBalType = getPopulatedBalanceTypeInstance(journalVoucherForm
293: .getSelectedBalanceType().getCode());
294:
295: // then deal with external encumbrance changes
296: if (origBalType.getCode().equals(
297: KFSConstants.BALANCE_TYPE_EXTERNAL_ENCUMBRANCE)
298: && !newBalType.getCode().equals(
299: KFSConstants.BALANCE_TYPE_EXTERNAL_ENCUMBRANCE)) {
300: balanceTypeExternalEncumbranceChangeMode = EXT_ENCUMB_TO_NON_EXT_ENCUMB;
301: } else if (!origBalType.getCode().equals(
302: KFSConstants.BALANCE_TYPE_EXTERNAL_ENCUMBRANCE)
303: && newBalType.getCode().equals(
304: KFSConstants.BALANCE_TYPE_EXTERNAL_ENCUMBRANCE)) {
305: balanceTypeExternalEncumbranceChangeMode = NON_EXT_ENCUMB_TO_EXT_ENCUMB;
306: }
307:
308: return balanceTypeExternalEncumbranceChangeMode;
309: }
310:
311: /**
312: * This method takes control from the changeBalanceType action method in order to present a question prompt to the user so that
313: * they can confirm the change in balance type.
314: *
315: * @param mapping
316: * @param form
317: * @param request
318: * @param response
319: * @return ActionForward
320: * @throws Exception
321: */
322: private ActionForward processChangeBalanceTypeConfirmationQuestion(
323: ActionMapping mapping, ActionForm form,
324: HttpServletRequest request, HttpServletResponse response)
325: throws Exception {
326: JournalVoucherForm jvForm = (JournalVoucherForm) form;
327: JournalVoucherDocument jvDoc = jvForm
328: .getJournalVoucherDocument();
329:
330: // only want to present the confirmation question to the user if there are any
331: // accouting lines, because that is the only impact
332: if (jvDoc.getSourceAccountingLines().size() != 0) {
333: String question = request
334: .getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
335: KualiConfigurationService kualiConfiguration = SpringContext
336: .getBean(KualiConfigurationService.class);
337:
338: if (question == null) { // question hasn't been asked
339: String message = buildBalanceTypeChangeConfirmationMessage(
340: jvForm, kualiConfiguration);
341:
342: // now transfer control over to the question component
343: return this
344: .performQuestionWithoutInput(
345: mapping,
346: form,
347: request,
348: response,
349: KFSConstants.JOURNAL_VOUCHER_CHANGE_BALANCE_TYPE_QUESTION,
350: message,
351: KFSConstants.CONFIRMATION_QUESTION,
352: KFSConstants.CHANGE_JOURNAL_VOUCHER_BALANCE_TYPE_METHOD,
353: "");
354: } else {
355: String buttonClicked = request
356: .getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
357: if ((KFSConstants.JOURNAL_VOUCHER_CHANGE_BALANCE_TYPE_QUESTION
358: .equals(question))
359: && ConfirmationQuestion.NO
360: .equals(buttonClicked)) {
361: // if no button clicked keep the old value and reload doc
362: BalanceTyp origBalType = getPopulatedBalanceTypeInstance(jvForm
363: .getOriginalBalanceType());
364: jvForm.setSelectedBalanceType(origBalType);
365: jvDoc.setBalanceType(origBalType);
366: jvDoc.setBalanceTypeCode(origBalType.getCode());
367: return mapping
368: .findForward(KFSConstants.MAPPING_BASIC);
369: }
370: }
371: }
372: return null;
373: }
374:
375: /**
376: * This method will setup the message that will get displayed to the user when they are asked to confirm the balance type
377: * change. The message is tuned to the particular context, the value chosen, and also the previous value. It also combines with
378: * the core part of the message which is part of the ApplicationResources.properties file.
379: *
380: * @param jvForm
381: * @param kualiConfiguration
382: * @return The message to display to the user in the question prompt window.
383: * @throws Exception
384: */
385: private String buildBalanceTypeChangeConfirmationMessage(
386: JournalVoucherForm jvForm,
387: KualiConfigurationService kualiConfiguration)
388: throws Exception {
389: String message = new String("");
390:
391: // figure out which way the balance type is changing
392: int balanceTypeAmountChangeMode = determineBalanceTypeAmountChangeMode(jvForm);
393: int balanceTypeExternalEncumbranceChangeMode = determineBalanceTypeEncumbranceChangeMode(jvForm);
394:
395: // grab the right message from the ApplicationResources.properties file depending upon the balance type switching mode
396: if (balanceTypeAmountChangeMode == SINGLE_AMT_TO_CREDIT_DEBIT_MODE) {
397: message = kualiConfiguration
398: .getPropertyString(KFSKeyConstants.QUESTION_CHANGE_JV_BAL_TYPE_FROM_SINGLE_AMT_TO_CREDIT_DEBIT_MODE);
399: // see if we need the extra bit about the external encumbrance
400: String newMessage = new String("");
401: if (balanceTypeExternalEncumbranceChangeMode == NON_EXT_ENCUMB_TO_EXT_ENCUMB) {
402: newMessage = StringUtils
403: .replace(
404: message,
405: "{3}",
406: kualiConfiguration
407: .getPropertyString(KFSKeyConstants.QUESTION_CHANGE_JV_BAL_TYPE_FROM_SINGLE_AMT_TO_EXT_ENCUMB_CREDIT_DEBIT_MODE));
408: } else {
409: newMessage = StringUtils.replace(message, "{3}", "");
410: }
411: message = new String(newMessage);
412: } else if (balanceTypeAmountChangeMode == CREDIT_DEBIT_TO_SINGLE_AMT_MODE) {
413: message = kualiConfiguration
414: .getPropertyString(KFSKeyConstants.QUESTION_CHANGE_JV_BAL_TYPE_FROM_CREDIT_DEBIT_TO_SINGLE_AMT_MODE);
415: // see if we need the extra bit about the external encumbrance
416: String newMessage = new String("");
417: if (balanceTypeExternalEncumbranceChangeMode == EXT_ENCUMB_TO_NON_EXT_ENCUMB) {
418: newMessage = StringUtils
419: .replace(
420: message,
421: "{3}",
422: kualiConfiguration
423: .getPropertyString(KFSKeyConstants.QUESTION_CHANGE_JV_BAL_TYPE_FROM_EXT_ENCUMB_CREDIT_DEBIT_TO_SINGLE_AMT_MODE));
424: } else {
425: newMessage = StringUtils.replace(message, "{3}", "");
426: }
427: message = new String(newMessage);
428: } else if (balanceTypeExternalEncumbranceChangeMode == EXT_ENCUMB_TO_NON_EXT_ENCUMB) {
429: message = kualiConfiguration
430: .getPropertyString(KFSKeyConstants.QUESTION_CHANGE_JV_BAL_TYPE_FROM_EXT_ENCUMB_TO_NON_EXT_ENCUMB);
431: } else if (balanceTypeExternalEncumbranceChangeMode == NON_EXT_ENCUMB_TO_EXT_ENCUMB) {
432: message = kualiConfiguration
433: .getPropertyString(KFSKeyConstants.QUESTION_CHANGE_JV_BAL_TYPE_FROM_NON_EXT_ENCUMB_TO_EXT_ENCUMB);
434: }
435:
436: // retrieve fully populated balance type instances
437: BalanceTyp origBalType = getPopulatedBalanceTypeInstance(jvForm
438: .getOriginalBalanceType());
439: BalanceTyp newBalType = getPopulatedBalanceTypeInstance(jvForm
440: .getSelectedBalanceType().getCode());
441:
442: // now complete building of the message
443: String replacement = "\"" + origBalType.getCode() + "-"
444: + origBalType.getName() + "\"";
445: String newMessage = StringUtils.replace(message, "{0}",
446: replacement);
447:
448: replacement = "\"" + newBalType.getCode() + "-"
449: + newBalType.getName() + "\"";
450: String finalMessage = StringUtils.replace(newMessage, "{1}",
451: replacement);
452:
453: return finalMessage;
454: }
455:
456: /**
457: * This method will fully populate a balance type given the passed in code, by calling the business object service that
458: * retrieves the rest of the instances' information.
459: *
460: * @param balanceTypeCode
461: * @return BalanceTyp
462: */
463: protected BalanceTyp getPopulatedBalanceTypeInstance(
464: String balanceTypeCode) {
465: // now we have to get the code and the name of the original and new balance types
466: return SpringContext.getBean(BalanceTypService.class)
467: .getBalanceTypByCode(balanceTypeCode);
468: }
469:
470: /**
471: * This method will clear out the source line values that aren't needed for the "Single Amount" mode.
472: *
473: * @param journalVoucherForm
474: */
475: private void switchFromSingleAmountModeToCreditDebitMode(
476: JournalVoucherForm journalVoucherForm) {
477: // going from single amount to credit/debit view so we want to blank out the amount and the extra "reference" fields
478: // that the single amount view uses
479: JournalVoucherDocument jvDoc = (JournalVoucherDocument) journalVoucherForm
480: .getTransactionalDocument();
481: ArrayList sourceLines = (ArrayList) jvDoc
482: .getSourceAccountingLines();
483: ArrayList helperLines = (ArrayList) journalVoucherForm
484: .getVoucherLineHelpers();
485: helperLines.clear(); // reset so we can add in fresh empty ones
486:
487: // make sure that there is enough space in the list
488: helperLines.ensureCapacity(sourceLines.size());
489:
490: KualiDecimal ZERO = new KualiDecimal("0.00");
491: for (int i = 0; i < sourceLines.size(); i++) {
492: VoucherSourceAccountingLine sourceLine = (VoucherSourceAccountingLine) sourceLines
493: .get(i);
494: sourceLine.setAmount(ZERO);
495: sourceLine.setDebitCreditCode(KFSConstants.GL_DEBIT_CODE); // default to debit
496:
497: helperLines.add(new VoucherAccountingLineHelperBase()); // populate with a fresh new empty object
498: }
499: }
500:
501: /**
502: * This method will clear out the extra "reference" fields that the external encumbrance balance type uses, but will leave the
503: * amounts since we aren't changing the offset generation code stuff.
504: *
505: * @param journalVoucherForm
506: */
507: private void switchFromExternalEncumbranceModeToNonExternalEncumbrance(
508: JournalVoucherForm journalVoucherForm) {
509: // going from external encumbrance view to non external encumbrance view, so we want to blank out the extra "reference"
510: // fields
511: JournalVoucherDocument jvDoc = (JournalVoucherDocument) journalVoucherForm
512: .getTransactionalDocument();
513: ArrayList sourceLines = (ArrayList) jvDoc
514: .getSourceAccountingLines();
515:
516: for (int i = 0; i < sourceLines.size(); i++) {
517: VoucherSourceAccountingLine sourceLine = (VoucherSourceAccountingLine) sourceLines
518: .get(i);
519: sourceLine.setReferenceOriginCode(null); // won't be needed in this mode
520: sourceLine.setReferenceNumber(null); // won't be needed in this mode
521: sourceLine.setReferenceTypeCode(null); // won't be needed in this mode
522: }
523: }
524:
525: /**
526: * This method will clear out the source line values that aren't needed for the "Credit/Debit" mode.
527: *
528: * @param journalVoucherForm
529: */
530: private void switchFromCreditDebitModeToSingleAmountMode(
531: JournalVoucherForm journalVoucherForm) {
532: // going from credit/debit view to single amount view so we don't need the debit and credit
533: // indicator set any more and we need to blank out the amount values to zero
534: JournalVoucherDocument jvDoc = journalVoucherForm
535: .getJournalVoucherDocument();
536: ArrayList sourceLines = (ArrayList) jvDoc
537: .getSourceAccountingLines();
538: ArrayList helperLines = (ArrayList) journalVoucherForm
539: .getVoucherLineHelpers();
540:
541: KualiDecimal ZERO = new KualiDecimal("0.00");
542: for (int i = 0; i < sourceLines.size(); i++) {
543: VoucherAccountingLineHelper helperLine = (VoucherAccountingLineHelper) helperLines
544: .get(i);
545: SourceAccountingLine sourceLine = (SourceAccountingLine) sourceLines
546: .get(i);
547: sourceLine.setAmount(ZERO);
548: sourceLine.setDebitCreditCode(KFSConstants.GL_DEBIT_CODE); // single sided is always debit
549:
550: helperLine.setCredit(null); // won't be needed in this mode
551: helperLine.setDebit(null); // won't be needed in this mode
552: }
553: }
554:
555: /**
556: * Overrides the parent to make sure that the JV specific accounting line helper forms are properly populated when the document
557: * is first loaded. This first calls super, then populates the helper objects.
558: *
559: * @see org.kuali.core.web.struts.action.KualiDocumentActionBase#loadDocument(org.kuali.core.web.struts.form.KualiDocumentFormBase)
560: */
561: @Override
562: protected void loadDocument(
563: KualiDocumentFormBase kualiDocumentFormBase)
564: throws WorkflowException {
565: super .loadDocument(kualiDocumentFormBase);
566: JournalVoucherForm journalVoucherForm = (JournalVoucherForm) kualiDocumentFormBase;
567:
568: // if the balance type is an offset generation balance type, then the user is able to enter the amount
569: // as either a debit or a credit, otherwise, they only need to deal with the amount field
570: JournalVoucherDocument journalVoucherDocument = (JournalVoucherDocument) journalVoucherForm
571: .getTransactionalDocument();
572: if (journalVoucherDocument.getBalanceType()
573: .isFinancialOffsetGenerationIndicator()) {
574: populateAllVoucherAccountingLineHelpers(journalVoucherForm);
575: KualiDecimal ZERO = new KualiDecimal("0.00");
576: journalVoucherForm.setNewSourceLineCredit(ZERO);
577: journalVoucherForm.setNewSourceLineDebit(ZERO);
578: }
579:
580: // always wipe out the new source line
581: journalVoucherForm.setNewSourceLine(null);
582:
583: // reload the balance type and accounting period selections since now we have data in the document bo
584: populateSelectedJournalBalanceType(journalVoucherDocument,
585: journalVoucherForm);
586: populateSelectedAccountingPeriod(journalVoucherDocument,
587: journalVoucherForm);
588: }
589:
590: /**
591: * This method grabs the value from the document bo and sets the selected balance type appropriately.
592: *
593: * @param journalVoucherDocument
594: * @param journalVoucherForm
595: */
596: private void populateSelectedJournalBalanceType(
597: JournalVoucherDocument journalVoucherDocument,
598: JournalVoucherForm journalVoucherForm) {
599: journalVoucherForm
600: .setSelectedBalanceType(journalVoucherDocument
601: .getBalanceType());
602: if (StringUtils.isNotBlank(journalVoucherDocument
603: .getBalanceTypeCode())) {
604: journalVoucherForm
605: .setOriginalBalanceType(journalVoucherDocument
606: .getBalanceTypeCode());
607: }
608: }
609:
610: /**
611: * This helper method determines from the request object instance whether or not the user has been prompted about the journal
612: * being out of balance. If they haven't, then the method will build the appropriate message given the state of the document and
613: * return control to the question component so that the user receives the "yes"/"no" prompt. If the question has been asked, the
614: * we evaluate the user's answer and direct the flow appropriately. If they answer with a "No", then we build out a message
615: * stating that they chose that value and return an ActionForward of a MAPPING_BASIC which keeps them at the same page that they
616: * were on. If they choose "Yes", then we return a null ActionForward, which the calling action method recognizes as a "Yes" and
617: * continues on processing the "Route."
618: *
619: * @param mapping
620: * @param form
621: * @param request
622: * @param response
623: * @return ActionForward
624: * @throws Exception
625: */
626: @Override
627: protected ActionForward processRouteOutOfBalanceDocumentConfirmationQuestion(
628: ActionMapping mapping, ActionForm form,
629: HttpServletRequest request, HttpServletResponse response)
630: throws Exception {
631: JournalVoucherForm jvForm = (JournalVoucherForm) form;
632: JournalVoucherDocument jvDoc = jvForm
633: .getJournalVoucherDocument();
634:
635: String question = request
636: .getParameter(KFSConstants.QUESTION_INST_ATTRIBUTE_NAME);
637: KualiConfigurationService kualiConfiguration = SpringContext
638: .getBean(KualiConfigurationService.class);
639:
640: if (question == null) { // question hasn't been asked
641: String currencyFormattedDebitTotal = (String) new CurrencyFormatter()
642: .format(jvDoc.getDebitTotal());
643: String currencyFormattedCreditTotal = (String) new CurrencyFormatter()
644: .format(jvDoc.getCreditTotal());
645: String currencyFormattedTotal = (String) new CurrencyFormatter()
646: .format(jvDoc.getTotalDollarAmount());
647: String message = "";
648: jvDoc
649: .refreshReferenceObject(KFSPropertyConstants.BALANCE_TYPE);
650: if (jvDoc.getBalanceType()
651: .isFinancialOffsetGenerationIndicator()) {
652: message = StringUtils
653: .replace(
654: kualiConfiguration
655: .getPropertyString(KFSKeyConstants.QUESTION_ROUTE_OUT_OF_BALANCE_JV_DOC),
656: "{0}", currencyFormattedDebitTotal);
657: message = StringUtils.replace(message, "{1}",
658: currencyFormattedCreditTotal);
659: } else {
660: message = StringUtils
661: .replace(
662: kualiConfiguration
663: .getPropertyString(KFSKeyConstants.QUESTION_ROUTE_OUT_OF_BALANCE_JV_DOC_SINGLE_AMT_MODE),
664: "{0}", currencyFormattedTotal);
665: }
666:
667: // now transfer control over to the question component
668: return this
669: .performQuestionWithoutInput(
670: mapping,
671: form,
672: request,
673: response,
674: KFSConstants.JOURNAL_VOUCHER_ROUTE_OUT_OF_BALANCE_DOCUMENT_QUESTION,
675: message,
676: KFSConstants.CONFIRMATION_QUESTION,
677: KFSConstants.ROUTE_METHOD, "");
678: } else {
679: String buttonClicked = request
680: .getParameter(KFSConstants.QUESTION_CLICKED_BUTTON);
681: if ((KFSConstants.JOURNAL_VOUCHER_ROUTE_OUT_OF_BALANCE_DOCUMENT_QUESTION
682: .equals(question))
683: && ConfirmationQuestion.NO.equals(buttonClicked)) {
684: GlobalVariables.getMessageList().add(
685: KFSKeyConstants.MESSAGE_JV_CANCELLED_ROUTE);
686: return mapping.findForward(KFSConstants.MAPPING_BASIC);
687: }
688: }
689: return null;
690: }
691:
692: /**
693: * This action executes a call to upload CSV accounting line values as SourceAccountingLines for a given transactional document.
694: * The "uploadAccountingLines()" method handles the multi-part request.
695: *
696: * @param mapping
697: * @param form
698: * @param request
699: * @param response
700: * @return ActionForward
701: * @throws FileNotFoundException
702: * @throws IOException
703: */
704: @Override
705: public ActionForward uploadSourceLines(ActionMapping mapping,
706: ActionForm form, HttpServletRequest request,
707: HttpServletResponse response) throws FileNotFoundException,
708: IOException {
709: // call method that sourceform and destination list
710: uploadAccountingLines(true, form);
711:
712: return mapping.findForward(KFSConstants.MAPPING_BASIC);
713: }
714:
715: /**
716: * This method determines whether we are uploading source or target lines, and then calls uploadAccountingLines directly on the
717: * document object. This method handles retrieving the actual upload file as an input stream into the document.
718: *
719: * @param isSource
720: * @param form
721: * @throws FileNotFoundException
722: * @throws IOException
723: */
724: @Override
725: protected void uploadAccountingLines(boolean isSource,
726: ActionForm form) throws FileNotFoundException, IOException {
727: JournalVoucherForm jvForm = (JournalVoucherForm) form;
728: // JournalVoucherAccountingLineParser needs a fresh BalanceType BO in the JournalVoucherDocument.
729: jvForm.getJournalVoucherDocument().refreshReferenceObject(
730: KFSPropertyConstants.BALANCE_TYPE);
731: super.uploadAccountingLines(isSource, jvForm);
732: }
733:
734: }
|