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