1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  package org.kuali.ole.fp.document;
18  
19  import java.util.ArrayList;
20  import java.util.HashMap;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.Map;
24  
25  import org.apache.commons.lang.StringUtils;
26  import org.apache.log4j.Logger;
27  import org.kuali.ole.fp.businessobject.CashDrawer;
28  import org.kuali.ole.fp.businessobject.CashieringItemInProcess;
29  import org.kuali.ole.fp.businessobject.CashieringTransaction;
30  import org.kuali.ole.fp.businessobject.Check;
31  import org.kuali.ole.fp.businessobject.Deposit;
32  import org.kuali.ole.fp.document.service.CashManagementService;
33  import org.kuali.ole.fp.service.CashDrawerService;
34  import org.kuali.ole.sys.OLEConstants;
35  import org.kuali.ole.sys.OLEConstants.DepositConstants;
36  import org.kuali.ole.sys.OLEKeyConstants;
37  import org.kuali.ole.sys.OLEPropertyConstants;
38  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
39  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
40  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
41  import org.kuali.ole.sys.context.SpringContext;
42  import org.kuali.ole.sys.document.GeneralLedgerPendingEntrySource;
43  import org.kuali.ole.sys.document.GeneralLedgerPostingDocumentBase;
44  import org.kuali.ole.sys.document.service.AccountingDocumentRuleHelperService;
45  import org.kuali.ole.sys.service.BankService;
46  import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
47  import org.kuali.ole.sys.service.UniversityDateService;
48  import org.kuali.rice.core.api.datetime.DateTimeService;
49  import org.kuali.rice.core.api.util.type.KualiDecimal;
50  import org.kuali.rice.kew.api.WorkflowDocument;
51  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
52  import org.kuali.rice.krad.exception.ValidationException;
53  import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
54  import org.kuali.rice.krad.util.KRADPropertyConstants;
55  import org.kuali.rice.krad.util.ObjectUtils;
56  import org.kuali.rice.location.api.campus.Campus;
57  import org.kuali.rice.location.api.campus.CampusService;
58  
59  
60  
61  
62  public class CashManagementDocument extends GeneralLedgerPostingDocumentBase implements GeneralLedgerPendingEntrySource {
63      protected static final long serialVersionUID = 7475843770851900297L;
64      protected static Logger LOG = Logger.getLogger(CashManagementDocument.class);
65  
66      protected String campusCode;
67  
68      protected List<Deposit> deposits;
69  
70      protected List<Check> checks;
71  
72      protected CashieringTransaction currentTransaction;
73      protected CashDrawer cashDrawer;
74      protected Campus campus;
75      
76      private KualiDecimal financialDocumentHundredDollarAmount;
77      private KualiDecimal financialDocumentFiftyDollarAmount;
78      private KualiDecimal financialDocumentTwentyDollarAmount;
79      private KualiDecimal financialDocumentTenDollarAmount;
80      private KualiDecimal financialDocumentFiveDollarAmount;
81      private KualiDecimal financialDocumentTwoDollarAmount;
82      private KualiDecimal financialDocumentOneDollarAmount;
83      private KualiDecimal financialDocumentOtherDollarAmount;
84      private KualiDecimal financialDocumentHundredCentAmount;
85      private KualiDecimal financialDocumentFiftyCentAmount;
86      private KualiDecimal financialDocumentTwentyFiveCentAmount;
87      private KualiDecimal financialDocumentTenCentAmount;
88      private KualiDecimal financialDocumentFiveCentAmount;
89      private KualiDecimal financialDocumentOneCentAmount;
90      private KualiDecimal financialDocumentOtherCentAmount;
91      
92  
93      
94  
95  
96      public CashManagementDocument() {
97          super();
98          deposits = new ArrayList<Deposit>();
99          checks = new ArrayList<Check>();
100         this.resetCurrentTransaction();
101     }
102 
103 
104     
105 
106 
107     public String getCampusCode() {
108         return campusCode;
109     }
110 
111     
112 
113 
114 
115 
116     public void setCampusCode(String campusCode) {
117         this.campusCode = campusCode;
118     }
119 
120     
121 
122 
123     public String getCashDrawerStatus() {
124         return getCashDrawer().getStatusCode();
125     }
126 
127     
128 
129 
130     public void setCashDrawerStatus(String cashDrawerStatus) {
131         
132         
133     }
134 
135     
136 
137 
138     public String getRawCashDrawerStatus() {
139         return getCashDrawerStatus();
140     }
141 
142     
143     
144 
145 
146     public List<Deposit> getDeposits() {
147         return deposits;
148     }
149 
150     
151 
152 
153 
154 
155     public void setDeposits(List<Deposit> deposits) {
156         this.deposits = deposits;
157     }
158 
159     
160 
161 
162 
163 
164 
165     public Deposit getDeposit(int index) {
166         extendDeposits(index + 1);
167 
168         return (Deposit) deposits.get(index);
169     }
170 
171     
172 
173 
174 
175 
176 
177     public Deposit removeDeposit(int index) {
178         extendDeposits(index + 1);
179 
180         return (Deposit) deposits.remove(index);
181     }
182 
183 
184     
185 
186 
187     public boolean hasFinalDeposit() {
188         boolean hasFinal = false;
189 
190         for (Iterator i = deposits.iterator(); !hasFinal && i.hasNext();) {
191             Deposit d = (Deposit) i.next();
192 
193             hasFinal = StringUtils.equals(DepositConstants.DEPOSIT_TYPE_FINAL, d.getDepositTypeCode());
194         }
195 
196         return hasFinal;
197     }
198 
199     
200 
201 
202     public Integer getNextDepositLineNumber() {
203         int maxLineNumber = -1;
204 
205         for (Iterator i = deposits.iterator(); i.hasNext();) {
206             Deposit d = (Deposit) i.next();
207 
208             Integer depositLineNumber = d.getFinancialDocumentDepositLineNumber();
209             if ((depositLineNumber != null) && (depositLineNumber.intValue() > maxLineNumber)) {
210                 maxLineNumber = depositLineNumber.intValue();
211             }
212         }
213 
214         return new Integer(maxLineNumber + 1);
215     }
216 
217     
218 
219 
220 
221 
222     protected void extendDeposits(int minSize) {
223         while (deposits.size() < minSize) {
224             deposits.add(new Deposit());
225         }
226     }
227 
228     
229 
230 
231 
232     @Override
233     public List buildListOfDeletionAwareLists() {
234         List managedLists = super.buildListOfDeletionAwareLists();
235 
236         managedLists.add(getDeposits());
237 
238         return managedLists;
239     }
240 
241 
242     
243 
244 
245 
246 
247     public CashDrawer getCashDrawer() {
248         return cashDrawer;
249     }
250 
251     
252 
253 
254 
255 
256     public void setCashDrawer(CashDrawer cd) {
257         cashDrawer = cd;
258     }
259 
260     
261 
262 
263 
264 
265     public CashieringTransaction getCurrentTransaction() {
266         return currentTransaction;
267     }
268 
269 
270     
271 
272 
273 
274 
275     public void setCurrentTransaction(CashieringTransaction currentTransaction) {
276         this.currentTransaction = currentTransaction;
277     }
278 
279     
280 
281 
282 
283 
284     public List<Check> getChecks() {
285         return checks;
286     }
287 
288     
289 
290 
291 
292 
293     public void setChecks(List<Check> checks) {
294         this.checks = checks;
295     }
296 
297     
298 
299 
300 
301 
302     public void addCheck(Check check) {
303         this.checks.add(check);
304     }
305 
306     
307 
308 
309     @Override
310     public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
311         super.doRouteStatusChange(statusChangeEvent);
312 
313         WorkflowDocument kwd = getDocumentHeader().getWorkflowDocument();
314 
315         if (LOG.isDebugEnabled()) {
316             logState();
317         }
318 
319         if (kwd.isProcessed()) {
320             
321             SpringContext.getBean(CashManagementService.class).finalizeCashManagementDocument(this);
322         }
323         else if (kwd.isCanceled() || kwd.isDisapproved()) {
324             
325             SpringContext.getBean(CashManagementService.class).cancelCashManagementDocument(this);
326         }
327     }
328 
329     protected void logState() {
330         WorkflowDocument kwd = getDocumentHeader().getWorkflowDocument();
331 
332         if (kwd.isInitiated()) {
333             LOG.debug("CMD isInitiated");
334         }
335         if (kwd.isProcessed()) {
336             LOG.debug("CMD isProcessed");
337         }
338         if (kwd.isCanceled()) {
339             LOG.debug("CMD isCanceled");
340         }
341         if (kwd.isDisapproved()) {
342             LOG.debug("CMD isDisapproved");
343         }
344     }
345 
346     
347 
348 
349     @Override
350     public void processAfterRetrieve() {
351         super.processAfterRetrieve();
352         
353         if (this.getCampusCode() != null) {
354             this.cashDrawer = SpringContext.getBean(CashDrawerService.class).getByCampusCode(this.getCampusCode());
355             this.resetCurrentTransaction();
356         }
357         SpringContext.getBean(CashManagementService.class).populateCashDetailsForDeposit(this);
358     }
359 
360     
361 
362 
363     public void resetCurrentTransaction() {
364         if (this.currentTransaction != null) {
365             this.currentTransaction.setTransactionEnded(SpringContext.getBean(DateTimeService.class).getCurrentDate());
366         }
367         currentTransaction = new CashieringTransaction(campusCode, documentNumber);
368         if (this.getCampusCode() != null) {
369             List<CashieringItemInProcess> openItemsInProcess = SpringContext.getBean(CashManagementService.class).getOpenItemsInProcess(this);
370             if (openItemsInProcess != null) {
371                 currentTransaction.setOpenItemsInProcess(openItemsInProcess);
372             }
373             currentTransaction.setNextCheckSequenceId(SpringContext.getBean(CashManagementService.class).selectNextAvailableCheckLineNumber(this.documentNumber));
374         }
375     }
376 
377 
378     
379 
380 
381 
382     public void customizeExplicitGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry) {}
383 
384 
385     
386 
387 
388 
389     public boolean customizeOffsetGeneralLedgerPendingEntry(GeneralLedgerPendingEntrySourceDetail accountingLine, GeneralLedgerPendingEntry explicitEntry, GeneralLedgerPendingEntry offsetEntry) {
390         return true;
391     }
392 
393 
394     
395 
396 
397 
398     @Override
399     public List<GeneralLedgerPendingEntrySourceDetail> getGeneralLedgerPendingEntrySourceDetails() {
400         return new ArrayList<GeneralLedgerPendingEntrySourceDetail>();
401     }
402 
403 
404     
405 
406 
407 
408     @Override
409     public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) {
410         return true;
411     }
412 
413 
414     
415 
416 
417 
418 
419 
420 
421     @Override
422     public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
423         boolean success = true;
424         
425         GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class);
426         
427         if (SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) {
428             Integer universityFiscalYear = getUniversityFiscalYear();
429             int interimDepositNumber = 1;
430             for (Deposit deposit: getDeposits()) {
431                 deposit.refreshReferenceObject(OLEPropertyConstants.BANK);
432 
433                 GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry();
434                 if (!glpeService.populateBankOffsetGeneralLedgerPendingEntry(deposit.getBank(), deposit.getDepositAmount(), this, universityFiscalYear, sequenceHelper, bankOffsetEntry, OLEConstants.CASH_MANAGEMENT_DEPOSIT_ERRORS)) {
435                     success = false;
436                     LOG.warn("Skipping ledger entries for deposit " + deposit.getDepositTicketNumber() + ".");
437                     continue; 
438                 }
439                 
440                 bankOffsetEntry.setTransactionLedgerEntryDescription(createDescription(deposit, interimDepositNumber++));
441                 getGeneralLedgerPendingEntries().add(bankOffsetEntry);
442                 sequenceHelper.increment();
443 
444                 GeneralLedgerPendingEntry offsetEntry = (GeneralLedgerPendingEntry) ObjectUtils.deepCopy(bankOffsetEntry);
445                 success &= glpeService.populateOffsetGeneralLedgerPendingEntry(universityFiscalYear, bankOffsetEntry, sequenceHelper, offsetEntry);
446                 getGeneralLedgerPendingEntries().add(offsetEntry);
447                 sequenceHelper.increment();
448             }
449         }
450         
451         return success;
452     }
453     
454     
455 
456 
457 
458 
459 
460 
461     protected static String createDescription(Deposit deposit, int interimDepositNumber) {
462         String descriptionKey;
463         if (OLEConstants.DepositConstants.DEPOSIT_TYPE_FINAL.equals(deposit.getDepositTypeCode())) {
464             descriptionKey = OLEKeyConstants.CashManagement.DESCRIPTION_GLPE_BANK_OFFSET_FINAL;
465         }
466         else {
467            
468             descriptionKey = OLEKeyConstants.CashManagement.DESCRIPTION_GLPE_BANK_OFFSET_INTERIM;
469         }
470         AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class);
471         return accountingDocumentRuleUtil.formatProperty(descriptionKey, interimDepositNumber);
472     }
473 
474     
475 
476 
477 
478 
479 
480 
481 
482 
483 
484     protected Integer getUniversityFiscalYear() {
485         return SpringContext.getBean(UniversityDateService.class).getCurrentFiscalYear();
486     }
487 
488     
489 
490 
491 
492     @Override
493     public boolean generateGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
494         return true;
495     }
496 
497 
498     
499 
500 
501     @Override
502     public KualiDecimal getGeneralLedgerPendingEntryAmountForDetail(GeneralLedgerPendingEntrySourceDetail postable) {
503         return postable.getAmount().abs();
504     }
505     
506     
507 
508 
509 
510 
511     public boolean getBankCashOffsetEnabled() {
512         return SpringContext.getBean(BankService.class).isBankSpecificationEnabled();
513     }
514 
515     
516 
517 
518     @Override
519     public void prepareForSave(KualiDocumentEvent event) {
520         if (getBankCashOffsetEnabled()) { 
521             if (!SpringContext.getBean(GeneralLedgerPendingEntryService.class).generateGeneralLedgerPendingEntries(this)) {
522                 logErrors();
523                 throw new ValidationException("general ledger GLPE generation failed");
524             }
525         }
526         
527         super.prepareForSave(event);
528     }
529     
530     
531 
532 
533     public Campus getCampus() {
534         if (campusCode != null && (campus == null || !campus.getCode().equals(campusCode))) {
535             campus = retrieveCampus();
536         }
537         return campus;
538     }
539     
540     protected Campus retrieveCampus() {
541         Map<String, Object> criteria = new HashMap<String, Object>();
542         criteria.put(KRADPropertyConstants.CAMPUS_CODE, campusCode);
543         return campus = SpringContext.getBean(CampusService.class).getCampus(campusCode);
544     }
545 
546 
547     
548 
549 
550 
551     public KualiDecimal getFinancialDocumentHundredDollarAmount() {
552         return financialDocumentHundredDollarAmount;
553     }
554 
555 
556     
557 
558 
559 
560     public void setFinancialDocumentHundredDollarAmount(KualiDecimal financialDocumentHundredDollarAmount) {
561         this.financialDocumentHundredDollarAmount = financialDocumentHundredDollarAmount;
562     }
563 
564 
565     
566 
567 
568 
569     public KualiDecimal getFinancialDocumentFiftyDollarAmount() {
570         return financialDocumentFiftyDollarAmount;
571     }
572 
573 
574     
575 
576 
577 
578     public void setFinancialDocumentFiftyDollarAmount(KualiDecimal financialDocumentFiftyDollarAmount) {
579         this.financialDocumentFiftyDollarAmount = financialDocumentFiftyDollarAmount;
580     }
581 
582 
583     
584 
585 
586 
587     public KualiDecimal getFinancialDocumentTwentyDollarAmount() {
588         return financialDocumentTwentyDollarAmount;
589     }
590 
591 
592     
593 
594 
595 
596     public void setFinancialDocumentTwentyDollarAmount(KualiDecimal financialDocumentTwentyDollarAmount) {
597         this.financialDocumentTwentyDollarAmount = financialDocumentTwentyDollarAmount;
598     }
599 
600 
601     
602 
603 
604 
605     public KualiDecimal getFinancialDocumentTenDollarAmount() {
606         return financialDocumentTenDollarAmount;
607     }
608 
609 
610     
611 
612 
613 
614     public void setFinancialDocumentTenDollarAmount(KualiDecimal financialDocumentTenDollarAmount) {
615         this.financialDocumentTenDollarAmount = financialDocumentTenDollarAmount;
616     }
617 
618 
619     
620 
621 
622 
623     public KualiDecimal getFinancialDocumentFiveDollarAmount() {
624         return financialDocumentFiveDollarAmount;
625     }
626 
627 
628     
629 
630 
631 
632     public void setFinancialDocumentFiveDollarAmount(KualiDecimal financialDocumentFiveDollarAmount) {
633         this.financialDocumentFiveDollarAmount = financialDocumentFiveDollarAmount;
634     }
635 
636 
637     
638 
639 
640 
641     public KualiDecimal getFinancialDocumentTwoDollarAmount() {
642         return financialDocumentTwoDollarAmount;
643     }
644 
645 
646     
647 
648 
649 
650     public void setFinancialDocumentTwoDollarAmount(KualiDecimal financialDocumentTwoDollarAmount) {
651         this.financialDocumentTwoDollarAmount = financialDocumentTwoDollarAmount;
652     }
653 
654 
655     
656 
657 
658 
659     public KualiDecimal getFinancialDocumentOneDollarAmount() {
660         return financialDocumentOneDollarAmount;
661     }
662 
663 
664     
665 
666 
667 
668     public void setFinancialDocumentOneDollarAmount(KualiDecimal financialDocumentOneDollarAmount) {
669         this.financialDocumentOneDollarAmount = financialDocumentOneDollarAmount;
670     }
671 
672 
673     
674 
675 
676 
677     public KualiDecimal getFinancialDocumentOtherDollarAmount() {
678         return financialDocumentOtherDollarAmount;
679     }
680 
681 
682     
683 
684 
685 
686     public void setFinancialDocumentOtherDollarAmount(KualiDecimal financialDocumentOtherDollarAmount) {
687         this.financialDocumentOtherDollarAmount = financialDocumentOtherDollarAmount;
688     }
689 
690 
691     
692 
693 
694 
695     public KualiDecimal getFinancialDocumentHundredCentAmount() {
696         return financialDocumentHundredCentAmount;
697     }
698 
699 
700     
701 
702 
703 
704     public void setFinancialDocumentHundredCentAmount(KualiDecimal financialDocumentHundredCentAmount) {
705         this.financialDocumentHundredCentAmount = financialDocumentHundredCentAmount;
706     }
707 
708 
709     
710 
711 
712 
713     public KualiDecimal getFinancialDocumentFiftyCentAmount() {
714         return financialDocumentFiftyCentAmount;
715     }
716 
717 
718     
719 
720 
721 
722     public void setFinancialDocumentFiftyCentAmount(KualiDecimal financialDocumentFiftyCentAmount) {
723         this.financialDocumentFiftyCentAmount = financialDocumentFiftyCentAmount;
724     }
725 
726 
727     
728 
729 
730 
731     public KualiDecimal getFinancialDocumentTwentyFiveCentAmount() {
732         return financialDocumentTwentyFiveCentAmount;
733     }
734 
735 
736     
737 
738 
739 
740     public void setFinancialDocumentTwentyFiveCentAmount(KualiDecimal financialDocumentTwentyFiveCentAmount) {
741         this.financialDocumentTwentyFiveCentAmount = financialDocumentTwentyFiveCentAmount;
742     }
743 
744 
745     
746 
747 
748 
749     public KualiDecimal getFinancialDocumentTenCentAmount() {
750         return financialDocumentTenCentAmount;
751     }
752 
753 
754     
755 
756 
757 
758     public void setFinancialDocumentTenCentAmount(KualiDecimal financialDocumentTenCentAmount) {
759         this.financialDocumentTenCentAmount = financialDocumentTenCentAmount;
760     }
761 
762 
763     
764 
765 
766 
767     public KualiDecimal getFinancialDocumentFiveCentAmount() {
768         return financialDocumentFiveCentAmount;
769     }
770 
771 
772     
773 
774 
775 
776     public void setFinancialDocumentFiveCentAmount(KualiDecimal financialDocumentFiveCentAmount) {
777         this.financialDocumentFiveCentAmount = financialDocumentFiveCentAmount;
778     }
779 
780 
781     
782 
783 
784 
785     public KualiDecimal getFinancialDocumentOneCentAmount() {
786         return financialDocumentOneCentAmount;
787     }
788 
789 
790     
791 
792 
793 
794     public void setFinancialDocumentOneCentAmount(KualiDecimal financialDocumentOneCentAmount) {
795         this.financialDocumentOneCentAmount = financialDocumentOneCentAmount;
796     }
797 
798 
799     
800 
801 
802 
803     public KualiDecimal getFinancialDocumentOtherCentAmount() {
804         return financialDocumentOtherCentAmount;
805     }
806 
807 
808     
809 
810 
811 
812     public void setFinancialDocumentOtherCentAmount(KualiDecimal financialDocumentOtherCentAmount) {
813         this.financialDocumentOtherCentAmount = financialDocumentOtherCentAmount;
814     }
815 }