001/*
002 * Copyright 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 java.io.Serializable;
019import java.sql.Timestamp;
020import java.util.ArrayList;
021import java.util.HashMap;
022import java.util.Iterator;
023import java.util.List;
024import java.util.Map;
025
026import org.apache.log4j.Logger;
027import org.kuali.ole.fp.businessobject.CashDrawer;
028import org.kuali.ole.fp.businessobject.CashieringItemInProcess;
029import org.kuali.ole.fp.businessobject.Check;
030import org.kuali.ole.fp.businessobject.CheckBase;
031import org.kuali.ole.fp.businessobject.CoinDetail;
032import org.kuali.ole.fp.businessobject.CurrencyDetail;
033import org.kuali.ole.fp.businessobject.Deposit;
034import org.kuali.ole.fp.businessobject.format.CashDrawerStatusCodeFormatter;
035import org.kuali.ole.fp.businessobject.format.CashReceiptDepositTypeFormatter;
036import org.kuali.ole.fp.document.CashManagementDocument;
037import org.kuali.ole.fp.document.CashReceiptDocument;
038import org.kuali.ole.fp.document.authorization.CashManagementDocumentPresentationController;
039import org.kuali.ole.fp.document.service.CashManagementService;
040import org.kuali.ole.fp.document.service.CashReceiptService;
041import org.kuali.ole.fp.service.CashDrawerService;
042import org.kuali.ole.sys.OLEConstants.DepositConstants;
043import org.kuali.ole.sys.OLEConstants.DocumentStatusCodes.CashReceipt;
044import org.kuali.ole.sys.context.SpringContext;
045import org.kuali.ole.sys.document.datadictionary.FinancialSystemTransactionalDocumentEntry;
046import org.kuali.rice.core.api.datetime.DateTimeService;
047import org.kuali.rice.core.api.util.type.KualiDecimal;
048import org.kuali.rice.core.web.format.CurrencyFormatter;
049import org.kuali.rice.core.web.format.TimestampAMPMFormatter;
050import org.kuali.rice.kns.service.DataDictionaryService;
051import org.kuali.rice.kns.web.struts.form.KualiDocumentFormBase;
052
053/**
054 * This class is the action form for CashManagement
055 */
056public class CashManagementForm extends KualiDocumentFormBase {
057    protected static final long serialVersionUID = 1L;
058    protected static Logger LOG = Logger.getLogger(CashManagementForm.class);
059
060    protected static final String CAMPUS_CODE_PROPERTY = "document.campusCode";
061
062    protected transient List depositHelpers;
063    protected CashDrawerSummary cashDrawerSummary;
064    protected List<CashieringItemInProcess> recentlyClosedItemsInProcess;
065    protected transient CashManagementDocumentPresentationController cmDocPrezController;
066
067    /**
068     * Constructs a CashManagementForm.
069     */
070    public CashManagementForm() {
071        super();
072
073        depositHelpers = new ArrayList();
074
075        setFormatterType("document.cashDrawerStatus", CashDrawerStatusCodeFormatter.class);
076        setFormatterType("document.deposit.depositTypeCode", CashReceiptDepositTypeFormatter.class);
077
078        setFormatterType("cashDrawerSummary.timeOpened", TimestampAMPMFormatter.class);
079        setFormatterType("cashDrawerSummary.timeRefreshed", TimestampAMPMFormatter.class);
080        setFormatterType("cashDrawerSummary.*Total", CurrencyFormatter.class);
081
082        setFormatterType("document.currentTransaction.transactionStarted", TimestampAMPMFormatter.class);
083    }
084
085    @Override
086    protected String getDefaultDocumentTypeName() {
087        return "OLE_CMD";
088    }
089    
090    /**
091     * @return cashManagementDocument
092     */
093    public CashManagementDocument getCashManagementDocument() {
094        return (CashManagementDocument) getDocument();
095    }
096
097
098    /**
099     * Creates a DepositHelper foreach Deposit associated with this form's document
100     */
101    public void populateDepositHelpers() {
102        depositHelpers = new ArrayList();
103
104        List deposits = getCashManagementDocument().getDeposits();
105        for (Iterator i = deposits.iterator(); i.hasNext();) {
106            Deposit d = (Deposit) i.next();
107
108            DepositHelper dh = new DepositHelper(d);
109            depositHelpers.add(dh);
110        }
111    }
112
113    /**
114     * Creates and initializes a CashDrawerSummary for the related CashManagementDocument, if it is not currently closed
115     */
116    public void populateCashDrawerSummary() {
117        CashManagementDocument cmd = getCashManagementDocument();
118        if (cmd != null) {
119            CashDrawer cd = SpringContext.getBean(CashDrawerService.class).getByCampusCode(cmd.getCampusCode());
120            if (cd == null) {
121                throw new RuntimeException("No cash drawer exists for campus code "+cmd.getCampusCode()+"; please create on via the Cash Drawer Maintenance Document before attemping to create a CashManagementDocument for campus "+cmd.getCampusCode());
122            }
123            if (!cd.isClosed()) {
124                cashDrawerSummary = new CashDrawerSummary(cmd);
125            }
126        }
127    }
128
129    /**
130     * Tells any JSP page using this form whether an action can be taken to make the last interim deposit the final deposit
131     * 
132     * @return true if last interim deposit could be the final deposit, false if otherwise
133     */
134    public boolean isLastInterimDepositFinalizable() {
135        boolean result = true;
136        CashManagementDocument cmDoc = getCashManagementDocument();
137        result &= !cmDoc.hasFinalDeposit();
138        result &= (cmDoc.getDeposits().size() > 0);
139        if (result) {
140            result &= SpringContext.getBean(CashManagementService.class).allVerifiedCashReceiptsAreDeposited(cmDoc);
141        }
142        return result;
143    }
144
145    /**
146     * @return CashDrawerSummary instance associated with this form, if any
147     */
148    public CashDrawerSummary getCashDrawerSummary() {
149        return cashDrawerSummary;
150    }
151
152    /**
153     * Sets the CashDrawerSummary
154     */
155    public void setCashDrawerSummary(CashDrawerSummary cashDrawerSummary) {
156        this.cashDrawerSummary = cashDrawerSummary;
157    }
158
159    /**
160     * @return List
161     */
162    public List getDepositHelpers() {
163        return depositHelpers;
164    }
165
166    /**
167     * Gets the recentlyClosedItemsInProcess attribute.
168     * 
169     * @return Returns the recentlyClosedItemsInProcess.
170     */
171    public List<CashieringItemInProcess> getRecentlyClosedItemsInProcess() {
172        return recentlyClosedItemsInProcess;
173    }
174
175    /**
176     * Sets the recentlyClosedItemsInProcess attribute value.
177     * 
178     * @param recentlyClosedItemsInProcess The recentlyClosedItemsInProcess to set.
179     */
180    public void setRecentlyClosedItemsInProcess(List<CashieringItemInProcess> recentlyClosedItemsInProcess) {
181        this.recentlyClosedItemsInProcess = recentlyClosedItemsInProcess;
182    }
183    
184    /**
185     * @return true if the cash drawer can currently be opened, false otherwise
186     */
187    public boolean getAllowOpenCashDrawer() {
188        if (cmDocPrezController == null) {
189            cmDocPrezController = createCashManagementDocumentPresentationController();
190        }
191        return cmDocPrezController.canOpenCashDrawer(getDocument());
192    }
193    
194    /**
195     * Creates an instance of the appropriate implementation of CashManagementDocumentPresentationController to check the cash drawer opening logic
196     * @return an instance of the CashManagementDocumentPresentationController for the document
197     */
198    protected CashManagementDocumentPresentationController createCashManagementDocumentPresentationController() {
199        final DataDictionaryService dataDictionaryService = SpringContext.getBean(DataDictionaryService.class);
200        final FinancialSystemTransactionalDocumentEntry cmDocEntry = (FinancialSystemTransactionalDocumentEntry)dataDictionaryService.getDataDictionary().getDocumentEntry(dataDictionaryService.getDocumentTypeNameByClass(getDocument().getClass()));
201        
202        final CashManagementDocumentPresentationController cmDocPrezController;
203        try {
204            cmDocPrezController = (CashManagementDocumentPresentationController)cmDocEntry.getDocumentPresentationControllerClass().newInstance();
205        }
206        catch (InstantiationException ie) {
207            throw new RuntimeException("Cannot instantiate instance of document presentation controller with class "+cmDocEntry.getDocumentPresentationControllerClass().getName(), ie);
208        }
209        catch (IllegalAccessException iae) {
210            throw new RuntimeException("Illegal access occurred while instantiating instance of maintainable implementation "+cmDocEntry.getDocumentPresentationControllerClass().getName(), iae);
211        }
212        return cmDocPrezController;
213    }
214
215    /**
216     * @param i
217     * @return DepositHelper
218     */
219    public DepositHelper getDepositHelper(int i) {
220        while (depositHelpers.size() <= i) {
221            depositHelpers.add(new DepositHelper());
222        }
223        DepositHelper dh = (DepositHelper) depositHelpers.get(i);
224
225        return dh;
226    }
227
228    /**
229     * Removes and returns DepositHelper at the given index
230     * 
231     * @param i
232     * @return
233     */
234    public DepositHelper removeDepositHelper(int i) {
235        return (DepositHelper) depositHelpers.remove(i);
236    }
237
238    /**
239     * Inner helper class.
240     */
241    public static final class DepositHelper {
242        protected Integer depositLineNumber;
243        protected List<CashReceiptSummary> cashReceiptSummarys;
244        protected List<Check> cashieringChecks;
245
246        /**
247         * Constructs a DepositHelper - default constructor used by PojoProcessor.
248         */
249        public DepositHelper() {
250            cashReceiptSummarys = new ArrayList<CashReceiptSummary>();
251            cashieringChecks = new ArrayList<Check>();
252            depositLineNumber = new Integer(1);
253        }
254
255        /**
256         * Constructs a DepositHelper
257         * 
258         * @param deposit
259         */
260        public DepositHelper(Deposit deposit) {
261            depositLineNumber = deposit.getFinancialDocumentDepositLineNumber();
262
263            cashReceiptSummarys = new ArrayList<CashReceiptSummary>();
264
265            CashManagementService cmService = SpringContext.getBean(CashManagementService.class);
266            List<CashReceiptDocument> cashReceipts = cmService.retrieveCashReceipts(deposit);
267            for (CashReceiptDocument document : cashReceipts) {
268                cashReceiptSummarys.add(new CashReceiptSummary(document));
269            }
270
271            cashieringChecks = cmService.selectCashieringChecksForDeposit(deposit.getDocumentNumber(), depositLineNumber);
272        }
273
274        /**
275         * @return List
276         */
277        public List<CashReceiptSummary> getCashReceiptSummarys() {
278            return cashReceiptSummarys;
279        }
280
281        /**
282         * @param i
283         * @return CashReceiptSummary
284         */
285        public CashReceiptSummary getCashReceiptSummary(int index) {
286            extendCashReceiptSummarys(index + 1);
287
288            return cashReceiptSummarys.get(index);
289        }
290
291        /**
292         * Ensures that there are at least minSize entries in the cashReceiptSummarys list
293         * 
294         * @param minSize
295         */
296        protected void extendCashReceiptSummarys(int minSize) {
297            while (cashReceiptSummarys.size() < minSize) {
298                cashReceiptSummarys.add(new CashReceiptSummary());
299            }
300        }
301
302        /**
303         * Gets the cashieringChecks attribute.
304         * 
305         * @return Returns the cashieringChecks.
306         */
307        public List<Check> getCashieringChecks() {
308            return cashieringChecks;
309        }
310
311        /**
312         * Get a specific cashiering check in the list of cashiering checks
313         * 
314         * @param index the index of the check to retrieve
315         * @return a check
316         */
317        public Check getCashieringCheck(int index) {
318            extendCashieringChecks(index);
319            return cashieringChecks.get(index);
320        }
321
322        /**
323         * This method makes the cashiering checks list longer, to avoid Array Index out of bounds issues
324         * 
325         * @param minSize the minimum size to make the list
326         */
327        protected void extendCashieringChecks(int minSize) {
328            while (cashieringChecks.size() <= minSize) {
329                cashieringChecks.add(new CheckBase());
330            }
331        }
332
333        /**
334         * @return Integer
335         */
336        public Integer getDepositLineNumber() {
337            return depositLineNumber;
338        }
339
340        /**
341         * @see java.lang.Object#toString()
342         */
343        @Override
344        public String toString() {
345            return "deposit #" + depositLineNumber;
346        }
347    }
348
349    public static final class CashReceiptSummary {
350        protected String documentNumber;
351        protected String description;
352        protected Timestamp createDate;
353        protected KualiDecimal totalAmount;
354        protected KualiDecimal cashAmount;
355        protected KualiDecimal checkAmount;
356        protected String documentStatusCode;
357
358        /**
359         * Default constructor used by PojoProcessor.
360         */
361        public CashReceiptSummary() {
362        }
363
364        /**
365         * Constructs a CashReceiptSummary from the given CashReceiptDocument.
366         * 
367         * @param crd
368         */
369        public CashReceiptSummary(CashReceiptDocument crd) {
370            documentNumber = crd.getDocumentNumber();
371            description = crd.getDocumentHeader().getDocumentDescription();
372            createDate = new Timestamp(crd.getDocumentHeader().getWorkflowDocument().getDateCreated().getMillis());
373            checkAmount = crd.getTotalConfirmedCheckAmount();
374            cashAmount = crd.getTotalConfirmedCashAmount();
375            totalAmount = crd.getTotalConfirmedDollarAmount().subtract(crd.getTotalChangeAmount());
376            documentStatusCode = crd.getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode();
377        }
378
379        /**
380         * @return current value of createDate.
381         */
382        public Timestamp getCreateDate() {
383            return createDate;
384        }
385
386        /**
387         * Sets the createDate attribute value.
388         * 
389         * @param createDate The createDate to set.
390         */
391        public void setCreateDate(Timestamp createDate) {
392            this.createDate = createDate;
393        }
394
395        /**
396         * @return current value of description.
397         */
398        public String getDescription() {
399            return description;
400        }
401
402        /**
403         * Sets the description attribute value.
404         * 
405         * @param description The description to set.
406         */
407        public void setDescription(String description) {
408            this.description = description;
409        }
410
411        /**
412         * @return current value of documentNumber.
413         */
414        public String getDocumentNumber() {
415            return documentNumber;
416        }
417
418        /**
419         * Sets the documentNumber attribute value.
420         * 
421         * @param docNumber The documentNumber to set.
422         */
423        public void setDocumentNumber(String documentNumber) {
424            this.documentNumber = documentNumber;
425        }
426
427        /**
428         * @return current value of totalAmount.
429         */
430        public KualiDecimal getTotalAmount() {
431            return totalAmount;
432        }
433
434        /**
435         * Sets the totalAmount attribute value.
436         * 
437         * @param totalAmount The totalAmount to set.
438         */
439        public void setTotalAmount(KualiDecimal totalAmount) {
440            this.totalAmount = totalAmount;
441        }
442
443        /**
444         * Returns the total check amount for this CR
445         * 
446         * @return a total of checks
447         */
448        public KualiDecimal getCheckAmount() {
449            return this.checkAmount;
450        }
451
452        /**
453         * Sets the checkAmount attribute value.
454         */
455        public void setCheckAmount(KualiDecimal checkAmount) {
456            this.checkAmount = checkAmount;
457        }
458
459        /**
460         * @see java.lang.Object#toString()
461         */
462        @Override
463        public String toString() {
464            return "CRSummary " + getDocumentNumber();
465        }
466
467        /**
468         * @return the cashAmount
469         */
470        public KualiDecimal getCashAmount() {
471            return cashAmount;
472        }
473
474        /**
475         * @param cashAmount the cashAmount to set
476         */
477        public void setCashAmount(KualiDecimal cashAmount) {
478            this.cashAmount = cashAmount;
479        }
480
481        /**
482         * @return the documentStatusCode
483         */
484        public String getDocumentStatusCode() {
485            return documentStatusCode;
486        }
487
488        /**
489         * @param documentStatusCode the documentStatusCode to set
490         */
491        public void setDocumentStatusCode(String documentStatusCode) {
492            this.documentStatusCode = documentStatusCode;
493        }
494        
495    }
496
497    public static final class CashDrawerSummary implements Serializable {
498        protected Timestamp timeOpened;
499        protected Timestamp timeRefreshed;
500
501        // directly calculated
502        protected int overallReceiptCount;
503        protected int depositedReceiptCount;
504
505        protected CashReceiptStatistics verifiedReceiptStats = new CashReceiptStatistics();
506        protected CashReceiptStatistics interimReceiptStats = new CashReceiptStatistics();
507        protected CashReceiptStatistics finalReceiptStats = new CashReceiptStatistics();
508        protected CashReceiptStatistics overallReceiptStats = new CashReceiptStatistics();
509
510        // derived
511        protected KualiDecimal verifiedReceiptSumTotal;
512        protected KualiDecimal interimReceiptSumTotal;
513        protected KualiDecimal finalReceiptSumTotal;
514        protected KualiDecimal overallReceiptSumTotal;
515
516        protected KualiDecimal remainingCheckTotal;
517        protected KualiDecimal remainingCurrencyTotal;
518        protected KualiDecimal remainingCoinTotal;
519        protected KualiDecimal remainingSumTotal;
520
521        protected boolean isDepositsFinal = false;
522        protected KualiDecimal cashieringChecksTotal;
523        protected KualiDecimal depositedCashieringChecksTotal;
524        protected KualiDecimal undepositedCashieringChecksTotal;
525        protected KualiDecimal cashDrawerCurrencyTotal;
526        protected KualiDecimal cashDrawerCoinTotal;
527        protected KualiDecimal openItemsTotal;
528        protected KualiDecimal cashDrawerTotal;
529        protected KualiDecimal interimDepositedCashieringChecksTotal;
530        protected KualiDecimal finalDepositedCashieringChecksTotal;
531
532        public CashDrawerSummary(CashManagementDocument cmDoc) {
533            timeOpened = new Timestamp(cmDoc.getDocumentHeader().getWorkflowDocument().getDateCreated().getMillis());
534
535            resummarize(cmDoc);
536        }
537
538        public CashDrawerSummary() {
539        }
540
541
542        protected static final String[] INTERESTING_STATII = { CashReceipt.VERIFIED, CashReceipt.INTERIM, CashReceipt.FINAL };
543
544        public void resummarize(CashManagementDocument cmDoc) {
545            //
546            // get all interesting CRs
547            String campusCode = cmDoc.getCampusCode(); 
548            List<CashReceiptDocument> interestingReceipts = SpringContext.getBean(CashReceiptService.class).getCashReceipts(campusCode, INTERESTING_STATII);
549
550
551            //
552            // rather than separating into lists by status, gather statistics in one fell swoop
553            overallReceiptStats.clear();
554            verifiedReceiptStats.clear();
555            interimReceiptStats.clear();
556            finalReceiptStats.clear();
557
558            for (CashReceiptDocument receipt : interestingReceipts) {
559                String status = receipt.getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode();
560                overallReceiptStats.add(receipt);
561                if (status.equals(CashReceipt.VERIFIED)) {
562                    verifiedReceiptStats.add(receipt);
563                }
564                else if (status.equals(CashReceipt.INTERIM)) {
565                    interimReceiptStats.add(receipt);
566                }
567                else if (status.equals(CashReceipt.FINAL)) {
568                    finalReceiptStats.add(receipt);
569                }
570                else {
571                    throw new IllegalStateException("invalid (unknown) financialDocumentStatusCode '" + status + "'");
572                }
573            }
574
575            overallReceiptCount = overallReceiptStats.getReceiptCount();
576            depositedReceiptCount = interimReceiptStats.getReceiptCount() + finalReceiptStats.getReceiptCount();
577
578            // get cash drawer summary info
579            depositedCashieringChecksTotal = calculateDepositedCashieringChecksTotal(cmDoc);
580            undepositedCashieringChecksTotal = calculateUndepositedCashieringChecksTotal(cmDoc);
581            cashieringChecksTotal = depositedCashieringChecksTotal.add(undepositedCashieringChecksTotal);
582            openItemsTotal = calculateOpenItemsTotal(cmDoc);
583            cashDrawerCurrencyTotal = cmDoc.getCashDrawer().getCurrencyTotalAmount();
584            cashDrawerCoinTotal = cmDoc.getCashDrawer().getCoinTotalAmount();
585            cashDrawerTotal = undepositedCashieringChecksTotal.add(openItemsTotal.add(cashDrawerCurrencyTotal.add(cashDrawerCoinTotal)));
586            Map<String, KualiDecimal> results = calculateDepositedCashieringChecksTotalByDepositType(cmDoc);
587            interimDepositedCashieringChecksTotal = results.get(DepositConstants.DEPOSIT_TYPE_INTERIM);
588            KualiDecimal finalDepositCashTotal = KualiDecimal.ZERO;
589            Map<Class, Object> finalDepositCashDetails = SpringContext.getBean(CashManagementService.class).getCashDetailsForFinalDeposit(cmDoc.getDocumentNumber());
590            KualiDecimal currencyDepositAmount = KualiDecimal.ZERO;
591            if (finalDepositCashDetails.get(CurrencyDetail.class) != null) {
592                currencyDepositAmount = ((CurrencyDetail) finalDepositCashDetails.get(CurrencyDetail.class)).getTotalAmount();
593            }
594            KualiDecimal coinDepositAmount = KualiDecimal.ZERO;
595            if (finalDepositCashDetails.get(CoinDetail.class) != null) {
596                coinDepositAmount = ((CoinDetail) finalDepositCashDetails.get(CoinDetail.class)).getTotalAmount();
597            }
598            finalDepositCashTotal = finalDepositCashTotal.add(currencyDepositAmount).add(coinDepositAmount);
599            finalDepositedCashieringChecksTotal = results.get(DepositConstants.DEPOSIT_TYPE_FINAL).add(finalDepositCashTotal);
600
601
602            verifiedReceiptSumTotal = verifiedReceiptStats.getSumTotal();
603            interimReceiptSumTotal = interimReceiptStats.getCheckTotal().add(interimDepositedCashieringChecksTotal);
604            finalReceiptSumTotal = finalReceiptStats.getCheckTotal().add(finalDepositedCashieringChecksTotal);
605            overallReceiptSumTotal = overallReceiptStats.getSumTotal();
606
607            remainingCheckTotal = overallReceiptStats.getCheckTotal().subtract(interimReceiptStats.getCheckTotal()).subtract(finalReceiptStats.getCheckTotal());
608            remainingCurrencyTotal = overallReceiptStats.getCurrencyTotal().subtract(currencyDepositAmount).subtract(depositedCashieringChecksTotal);
609            remainingCoinTotal = overallReceiptStats.getCoinTotal().subtract(coinDepositAmount);
610            remainingSumTotal = remainingCheckTotal.add(remainingCurrencyTotal.add(remainingCoinTotal));
611
612            isDepositsFinal = cmDoc.hasFinalDeposit();
613
614            timeRefreshed = SpringContext.getBean(DateTimeService.class).getCurrentTimestamp();
615        }
616
617        protected KualiDecimal calculateDepositedCashieringChecksTotal(CashManagementDocument cmDoc) {
618            return SpringContext.getBean(CashManagementService.class).calculateDepositedCheckTotal(cmDoc.getDocumentNumber());
619        }
620
621        protected KualiDecimal calculateUndepositedCashieringChecksTotal(CashManagementDocument cmDoc) {
622            return SpringContext.getBean(CashManagementService.class).calculateUndepositedCheckTotal(cmDoc.getDocumentNumber());
623        }
624
625        protected KualiDecimal calculateOpenItemsTotal(CashManagementDocument cmDoc) {
626            KualiDecimal total = KualiDecimal.ZERO;
627            for (CashieringItemInProcess itemInProcess : SpringContext.getBean(CashManagementService.class).getOpenItemsInProcess(cmDoc)) {
628                if (itemInProcess.getItemRemainingAmount() != null) {
629                    total = total.add(itemInProcess.getItemRemainingAmount());
630                }
631            }
632            return total;
633        }
634
635        protected Map<String, KualiDecimal> calculateDepositedCashieringChecksTotalByDepositType(CashManagementDocument cmDoc) {
636            Map<String, KualiDecimal> result = new HashMap<String, KualiDecimal>();
637            result.put(DepositConstants.DEPOSIT_TYPE_INTERIM, KualiDecimal.ZERO);
638            result.put(DepositConstants.DEPOSIT_TYPE_FINAL, KualiDecimal.ZERO);
639            // 1. get all deposited cashiering checks
640            List<Check> checks = SpringContext.getBean(CashManagementService.class).selectDepositedCashieringChecks(cmDoc.getDocumentNumber());
641            // 2. get all deposits
642            List<Deposit> deposits = cmDoc.getDeposits();
643            Map<Integer, String> depositTypes = new HashMap<Integer, String>();
644            for (Deposit deposit : deposits) {
645                depositTypes.put(deposit.getFinancialDocumentDepositLineNumber(), deposit.getDepositTypeCode());
646            }
647            // 3. now, go through all cashiering checks, totalling them to the right deposit type
648            for (Check check : checks) {
649                KualiDecimal properTotal = result.get(depositTypes.get(check.getFinancialDocumentDepositLineNumber()));
650                properTotal = properTotal.add(check.getAmount());
651                result.put(depositTypes.get(check.getFinancialDocumentDepositLineNumber()), properTotal);
652            }
653            return result;
654        }
655
656        /**
657         * @return current value of depositedReceiptCount.
658         */
659        public int getDepositedReceiptCount() {
660            return depositedReceiptCount;
661        }
662
663        /**
664         * Sets the depositedReceiptCount attribute value.
665         * 
666         * @param depositedReceiptCount The depositedReceiptCount to set.
667         */
668        public void setDepositedReceiptCount(int depositedReceiptCount) {
669            this.depositedReceiptCount = depositedReceiptCount;
670        }
671
672
673        /**
674         * @return current value of finalReceiptSumTotal.
675         */
676        public KualiDecimal getFinalReceiptSumTotal() {
677            return finalReceiptSumTotal;
678        }
679
680        /**
681         * Sets the finalReceiptSumTotal attribute value.
682         * 
683         * @param finalReceiptSumTotal The finalReceiptSumTotal to set.
684         */
685        public void setFinalReceiptSumTotal(KualiDecimal finalSumTotal) {
686            this.finalReceiptSumTotal = finalSumTotal;
687        }
688
689
690        /**
691         * @return current value of interimReceiptSumTotal.
692         */
693        public KualiDecimal getInterimReceiptSumTotal() {
694            return interimReceiptSumTotal;
695        }
696
697        /**
698         * Sets the interimReceiptSumTotal attribute value.
699         * 
700         * @param interimReceiptSumTotal The interimReceiptSumTotal to set.
701         */
702        public void setInterimReceiptSumTotal(KualiDecimal interimSumTotal) {
703            this.interimReceiptSumTotal = interimSumTotal;
704        }
705
706
707        /**
708         * @return current value of overallReceiptCount.
709         */
710        public int getOverallReceiptCount() {
711            return overallReceiptCount;
712        }
713
714        /**
715         * Sets the overallReceiptCount attribute value.
716         * 
717         * @param overallReceiptCount The overallReceiptCount to set.
718         */
719        public void setOverallReceiptCount(int overallReceiptCount) {
720            this.overallReceiptCount = overallReceiptCount;
721        }
722
723
724        /**
725         * @return current value of remainingCheckTotal.
726         */
727        public KualiDecimal getRemainingCheckTotal() {
728            return remainingCheckTotal;
729        }
730
731        /**
732         * Sets the remainingCheckTotal attribute value.
733         * 
734         * @param remainingCheckTotal The remainingCheckTotal to set.
735         */
736        public void setRemainingCheckTotal(KualiDecimal remainingCheckTotal) {
737            this.remainingCheckTotal = remainingCheckTotal;
738        }
739
740
741        /**
742         * @return current value of remainingCoinTotal.
743         */
744        public KualiDecimal getRemainingCoinTotal() {
745            return remainingCoinTotal;
746        }
747
748        /**
749         * Sets the remainingCoinTotal attribute value.
750         * 
751         * @param remainingCoinTotal The remainingCoinTotal to set.
752         */
753        public void setRemainingCoinTotal(KualiDecimal remainingCoinTotal) {
754            this.remainingCoinTotal = remainingCoinTotal;
755        }
756
757        /**
758         * @return current value of remainingCurrencyTotal.
759         */
760        public KualiDecimal getRemainingCurrencyTotal() {
761            return remainingCurrencyTotal;
762        }
763
764        /**
765         * Sets the remainingCurrencyTotal attribute value.
766         * 
767         * @param remainingCurrencyTotal The remainingCurrencyTotal to set.
768         */
769        public void setRemainingCurrencyTotal(KualiDecimal remainingCurrencyTotal) {
770            this.remainingCurrencyTotal = remainingCurrencyTotal;
771        }
772
773
774        /**
775         * @return current value of remainingSumTotal.
776         */
777        public KualiDecimal getRemainingSumTotal() {
778            return remainingSumTotal;
779        }
780
781        /**
782         * Sets the remainingSumTotal attribute value.
783         * 
784         * @param remainingSumTotal The remainingSumTotal to set.
785         */
786        public void setRemainingSumTotal(KualiDecimal remainingSumTotal) {
787            this.remainingSumTotal = remainingSumTotal;
788        }
789
790
791        /**
792         * @return current value of timeOpened.
793         */
794        public Timestamp getTimeOpened() {
795            return timeOpened;
796        }
797
798        /**
799         * Sets the timeOpened attribute value.
800         * 
801         * @param timeOpened The timeOpened to set.
802         */
803        public void setTimeOpened(Timestamp timeOpened) {
804            this.timeOpened = timeOpened;
805        }
806
807
808        /**
809         * @return current value of timeRefreshed.
810         */
811        public Timestamp getTimeRefreshed() {
812            return timeRefreshed;
813        }
814
815        /**
816         * Sets the timeRefreshed attribute value.
817         * 
818         * @param timeRefreshed The timeRefreshed to set.
819         */
820        public void setTimeRefreshed(Timestamp timeRefreshed) {
821            this.timeRefreshed = timeRefreshed;
822        }
823
824
825        /**
826         * @return current value of verifiedReceiptSumTotal.
827         */
828        public KualiDecimal getVerifiedReceiptSumTotal() {
829            return verifiedReceiptSumTotal;
830        }
831
832        /**
833         * Sets the verifiedReceiptSumTotal attribute value.
834         * 
835         * @param verifiedReceiptSumTotal The verifiedReceiptSumTotal to set.
836         */
837        public void setVerifiedReceiptSumTotal(KualiDecimal verifiedSumTotal) {
838            this.verifiedReceiptSumTotal = verifiedSumTotal;
839        }
840
841
842        /**
843         * @return current value of overallReceiptSumTotal.
844         */
845        public KualiDecimal getOverallReceiptSumTotal() {
846            return overallReceiptSumTotal;
847        }
848
849        /**
850         * Sets the overallReceiptSumTotal attribute value.
851         * 
852         * @param overallReceiptSumTotal The overallReceiptSumTotal to set.
853         */
854        public void setOverallReceiptSumTotal(KualiDecimal overallSumTotal) {
855            this.overallReceiptSumTotal = overallSumTotal;
856        }
857
858
859        /**
860         * @return current value of finalReceiptStats.
861         */
862        public CashReceiptStatistics getFinalReceiptStats() {
863            return finalReceiptStats;
864        }
865
866        /**
867         * @return current value of interimReceiptStats.
868         */
869        public CashReceiptStatistics getInterimReceiptStats() {
870            return interimReceiptStats;
871        }
872
873        /**
874         * @return current value of verifiedReceiptStats.
875         */
876        public CashReceiptStatistics getVerifiedReceiptStats() {
877            return verifiedReceiptStats;
878        }
879
880        /**
881         * Gets the cashDrawerCoinTotal attribute.
882         * 
883         * @return Returns the cashDrawerCoinTotal.
884         */
885        public KualiDecimal getCashDrawerCoinTotal() {
886            return cashDrawerCoinTotal;
887        }
888
889        /**
890         * Gets the cashDrawerCurrencyTotal attribute.
891         * 
892         * @return Returns the cashDrawerCurrencyTotal.
893         */
894        public KualiDecimal getCashDrawerCurrencyTotal() {
895            return cashDrawerCurrencyTotal;
896        }
897
898        /**
899         * Gets the cashDrawerTotal attribute.
900         * 
901         * @return Returns the cashDrawerTotal.
902         */
903        public KualiDecimal getCashDrawerTotal() {
904            return cashDrawerTotal;
905        }
906
907        /**
908         * Gets the cashieringChecksTotal attribute.
909         * 
910         * @return Returns the cashieringChecksTotal.
911         */
912        public KualiDecimal getCashieringChecksTotal() {
913            return cashieringChecksTotal;
914        }
915
916        /**
917         * Sets the cashieringChecksTotal attribute value.
918         * 
919         * @param cashieringChecksTotal The cashieringChecksTotal to set.
920         */
921        public void setCashieringChecksTotal(KualiDecimal cashieringChecksTotal) {
922            this.cashieringChecksTotal = cashieringChecksTotal;
923        }
924
925        /**
926         * Sets the depositedCashieringChecksTotal attribute value.
927         * 
928         * @param depositedCashieringChecksTotal The depositedCashieringChecksTotal to set.
929         */
930        public void setDepositedCashieringChecksTotal(KualiDecimal depositedCashieringChecksTotal) {
931            this.depositedCashieringChecksTotal = depositedCashieringChecksTotal;
932        }
933
934        /**
935         * Gets the isDepositsFinal attribute.
936         * 
937         * @return Returns the isDepositsFinal.
938         */
939        public boolean isDepositsFinal() {
940            return isDepositsFinal;
941        }
942
943        /**
944         * Sets the cashDrawerCoinTotal attribute value.
945         * 
946         * @param cashDrawerCoinTotal The cashDrawerCoinTotal to set.
947         */
948        public void setCashDrawerCoinTotal(KualiDecimal cashDrawerCoinTotal) {
949            this.cashDrawerCoinTotal = cashDrawerCoinTotal;
950        }
951
952        /**
953         * Sets the cashDrawerCurrencyTotal attribute value.
954         * 
955         * @param cashDrawerCurrencyTotal The cashDrawerCurrencyTotal to set.
956         */
957        public void setCashDrawerCurrencyTotal(KualiDecimal cashDrawerCurrencyTotal) {
958            this.cashDrawerCurrencyTotal = cashDrawerCurrencyTotal;
959        }
960
961        /**
962         * Sets the cashDrawerTotal attribute value.
963         * 
964         * @param cashDrawerTotal The cashDrawerTotal to set.
965         */
966        public void setCashDrawerTotal(KualiDecimal cashDrawerTotal) {
967            this.cashDrawerTotal = cashDrawerTotal;
968        }
969
970        /**
971         * Sets the openItemsTotal attribute value.
972         * 
973         * @param openItemsTotal The openItemsTotal to set.
974         */
975        public void setOpenItemsTotal(KualiDecimal openItemsTotal) {
976            this.openItemsTotal = openItemsTotal;
977        }
978
979        /**
980         * Sets the undepositedCashieringChecksTotal attribute value.
981         * 
982         * @param undepositedCashieringChecksTotal The undepositedCashieringChecksTotal to set.
983         */
984        public void setUndepositedCashieringChecksTotal(KualiDecimal undepositedCashieringChecksTotal) {
985            this.undepositedCashieringChecksTotal = undepositedCashieringChecksTotal;
986        }
987
988        /**
989         * Gets the openItemsTotal attribute.
990         * 
991         * @return Returns the openItemsTotal.
992         */
993        public KualiDecimal getOpenItemsTotal() {
994            return openItemsTotal;
995        }
996
997        /**
998         * Gets the depositedCashieringChecksTotal attribute.
999         * 
1000         * @return Returns the depositedCashieringChecksTotal.
1001         */
1002        public KualiDecimal getDepositedCashieringChecksTotal() {
1003            return depositedCashieringChecksTotal;
1004        }
1005
1006        /**
1007         * Gets the undepositedCashieringChecksTotal attribute.
1008         * 
1009         * @return Returns the undepositedCashieringChecksTotal.
1010         */
1011        public KualiDecimal getUndepositedCashieringChecksTotal() {
1012            return undepositedCashieringChecksTotal;
1013        }
1014
1015        /**
1016         * @return current value of overalllStats.
1017         */
1018        public CashReceiptStatistics getOverallReceiptStats() {
1019            return overallReceiptStats;
1020        }
1021
1022        public static final class CashReceiptStatistics implements Serializable{
1023            protected int receiptCount;
1024            protected KualiDecimal checkTotal;
1025            protected KualiDecimal currencyTotal;
1026            protected KualiDecimal coinTotal;
1027
1028            /**
1029             * Constructs a SubSummary.
1030             */
1031            public CashReceiptStatistics() {
1032                clear();
1033            }
1034
1035            /**
1036             * Increments the counter by 1, and the various totals by the amounts in the given CashReceiptDocument
1037             * 
1038             * @param receipt
1039             */
1040            public void add(CashReceiptDocument receipt) {
1041                receipt.refreshCashDetails();
1042                receiptCount++;
1043                checkTotal = checkTotal.add(receipt.getTotalConfirmedCheckAmount());
1044                currencyTotal = currencyTotal.add(receipt.getTotalConfirmedCashAmount()).subtract(receipt.getTotalChangeCashAmount());
1045                coinTotal = coinTotal.add(receipt.getTotalConfirmedCoinAmount()).subtract(receipt.getTotalChangeCoinAmount());
1046            }
1047
1048            /**
1049             * Zeros counter and totals.
1050             */
1051            public void clear() {
1052                receiptCount = 0;
1053                checkTotal = KualiDecimal.ZERO;
1054                currencyTotal = KualiDecimal.ZERO;
1055                coinTotal = KualiDecimal.ZERO;
1056            }
1057
1058
1059            /**
1060             * Returns total of all check, coin, and currency totals
1061             */
1062            public KualiDecimal getSumTotal() {
1063                KualiDecimal sumTotal = getCheckTotal().add(getCoinTotal().add(getCurrencyTotal()));
1064
1065                return sumTotal;
1066            }
1067
1068            /**
1069             * This method doesn't do anything but appease the demands of POJO form population...I mean...er...this sets the sum
1070             * total, now doesn't it?
1071             * 
1072             * @param total total you want this method to ignore
1073             */
1074            public void setSumTotal(KualiDecimal total) {
1075                // don't do anything. just be very quiet and maybe the POJO loader will be satisfied
1076            }
1077
1078
1079            /**
1080             * @return current value of checkTotal.
1081             */
1082            public KualiDecimal getCheckTotal() {
1083                return checkTotal;
1084            }
1085
1086            /**
1087             * Sets the checkTotal attribute value.
1088             * 
1089             * @param checkTotal The checkTotal to set.
1090             */
1091            public void setCheckTotal(KualiDecimal checkTotal) {
1092                this.checkTotal = checkTotal;
1093            }
1094
1095
1096            /**
1097             * @return current value of coinTotal.
1098             */
1099            public KualiDecimal getCoinTotal() {
1100                return coinTotal;
1101            }
1102
1103            /**
1104             * Sets the coinTotal attribute value.
1105             * 
1106             * @param coinTotal The coinTotal to set.
1107             */
1108            public void setCoinTotal(KualiDecimal coinTotal) {
1109                this.coinTotal = coinTotal;
1110            }
1111
1112
1113            /**
1114             * @return current value of currencyTotal.
1115             */
1116            public KualiDecimal getCurrencyTotal() {
1117                return currencyTotal;
1118            }
1119
1120            /**
1121             * Sets the currencyTotal attribute value.
1122             * 
1123             * @param currencyTotal The currencyTotal to set.
1124             */
1125            public void setCurrencyTotal(KualiDecimal currencyTotal) {
1126                this.currencyTotal = currencyTotal;
1127            }
1128
1129
1130            /**
1131             * @return current value of receiptCount.
1132             */
1133            public int getReceiptCount() {
1134                return receiptCount;
1135            }
1136
1137            /**
1138             * Sets the receiptCount attribute value.
1139             * 
1140             * @param receiptCount The receiptCount to set.
1141             */
1142            public void setReceiptCount(int receiptCount) {
1143                this.receiptCount = receiptCount;
1144            }
1145
1146
1147            /**
1148             * @see java.lang.Object#toString()
1149             */
1150            @Override
1151            public String toString() {
1152                return "CashDrawerSummary(" + getSumTotal() + " = " + getCheckTotal() + " + " + getCurrencyTotal() + " + " + getCoinTotal() + ")";
1153            }
1154        }
1155    }
1156
1157    /**
1158     * @see org.kuali.rice.kns.web.struts.pojo.PojoFormBase#postprocessRequestParameters(java.util.Map)
1159     */
1160    @Override
1161    public void postprocessRequestParameters(Map requestParameters) {
1162        super.postprocessRequestParameters(requestParameters);
1163        // fish the campus code name out of the parameters
1164        String[] campusCodes = (String[]) requestParameters.get(CashManagementForm.CAMPUS_CODE_PROPERTY);
1165        String campusCode = null;
1166        if (campusCodes != null && campusCodes.length > 0) {
1167            campusCode = campusCodes[0];
1168        }
1169        if (campusCode != null && getCashManagementDocument() != null) {
1170            // use that to put the cash drawer back into the cash management document
1171            getCashManagementDocument().setCashDrawer(SpringContext.getBean(CashDrawerService.class).getByCampusCode(campusCode));
1172        }
1173    }
1174
1175
1176}