001: /*
002: * Copyright 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.bo;
017:
018: import java.util.ArrayList;
019: import java.util.HashMap;
020: import java.util.Iterator;
021: import java.util.LinkedHashMap;
022: import java.util.List;
023: import java.util.Map;
024:
025: import org.kuali.core.bo.TransientBusinessObjectBase;
026: import org.kuali.core.service.DateTimeService;
027: import org.kuali.core.util.KualiDecimal;
028: import org.kuali.kfs.KFSConstants;
029: import org.kuali.kfs.context.SpringContext;
030:
031: /**
032: * This class represents a cashiering-related transaction used in the cash management document
033: */
034: public class CashieringTransaction extends TransientBusinessObjectBase {
035: public static final String DETAIL_DOCUMENT_TYPE = "CM";
036:
037: private String workgroupName;
038: private String referenceFinancialDocumentNumber;
039:
040: // money in properties
041: private List<Check> moneyInChecks;
042: private CoinDetail moneyInCoin;
043: private CurrencyDetail moneyInCurrency;
044: private CashieringItemInProcess newItemInProcess;
045: private List<Check> baselineChecks;
046: private Check newCheck;
047: private KualiDecimal checkTotal;
048:
049: // money out properties
050: private CoinDetail moneyOutCoin;
051: private CurrencyDetail moneyOutCurrency;
052: private List<CashieringItemInProcess> openItemsInProcess;
053:
054: private java.util.Date transactionStarted;
055: private java.util.Date transactionEnded;
056:
057: // incrementers for detail lines
058: private Integer nextCheckSequenceId;
059:
060: /**
061: * Constructs a CashieringTransaction
062: */
063: public CashieringTransaction(String workgroupName,
064: String referenceFinancialDocumentNumber) {
065: super ();
066: this .workgroupName = workgroupName;
067: this .referenceFinancialDocumentNumber = referenceFinancialDocumentNumber;
068: this .transactionStarted = SpringContext.getBean(
069: DateTimeService.class).getCurrentDate();
070:
071: moneyInCoin = new CoinDetail();
072: moneyInCurrency = new CurrencyDetail();
073:
074: moneyOutCoin = new CoinDetail();
075: moneyOutCurrency = new CurrencyDetail();
076:
077: newItemInProcess = new CashieringItemInProcess();
078: moneyInChecks = new ArrayList<Check>();
079: newCheck = new CheckBase();
080: baselineChecks = new ArrayList<Check>();
081: openItemsInProcess = new ArrayList<CashieringItemInProcess>();
082: nextCheckSequenceId = new Integer(1);
083: }
084:
085: /**
086: * Gets the moneyInChecks attribute.
087: *
088: * @return Returns the moneyInChecks.
089: */
090: public List<Check> getMoneyInChecks() {
091: return moneyInChecks;
092: }
093:
094: /**
095: * Sets the moneyInChecks attribute value.
096: *
097: * @param moneyInChecks The moneyInChecks to set.
098: */
099: public void setMoneyInChecks(List<Check> moneyInChecks) {
100: this .moneyInChecks = moneyInChecks;
101: }
102:
103: /**
104: * Retrieves a specific check from the list, by array index
105: *
106: * @param index the index of the checks array to retrieve the check from
107: * @return a Check
108: */
109: public Check getMoneyInCheck(int index) {
110: if (index >= moneyInChecks.size()) {
111: for (int i = moneyInChecks.size(); i <= index; i++) {
112: moneyInChecks.add(createNewCheck());
113: }
114: }
115: return moneyInChecks.get(index);
116: }
117:
118: /**
119: * Gets the moneyInCoin attribute.
120: *
121: * @return Returns the moneyInCoin.
122: */
123: public CoinDetail getMoneyInCoin() {
124: return moneyInCoin;
125: }
126:
127: /**
128: * Sets the moneyInCoin attribute value.
129: *
130: * @param moneyInCoin The moneyInCoin to set.
131: */
132: public void setMoneyInCoin(CoinDetail moneyInCoin) {
133: this .moneyInCoin = moneyInCoin;
134: }
135:
136: /**
137: * Gets the moneyInCurrency attribute.
138: *
139: * @return Returns the moneyInCurrency.
140: */
141: public CurrencyDetail getMoneyInCurrency() {
142: return moneyInCurrency;
143: }
144:
145: /**
146: * Sets the moneyInCurrency attribute value.
147: *
148: * @param moneyInCurrency The moneyInCurrency to set.
149: */
150: public void setMoneyInCurrency(CurrencyDetail moneyInCurrency) {
151: this .moneyInCurrency = moneyInCurrency;
152: }
153:
154: /**
155: * Gets the moneyOutCoin attribute.
156: *
157: * @return Returns the moneyOutCoin.
158: */
159: public CoinDetail getMoneyOutCoin() {
160: return moneyOutCoin;
161: }
162:
163: /**
164: * Sets the moneyOutCoin attribute value.
165: *
166: * @param moneyOutCoin The moneyOutCoin to set.
167: */
168: public void setMoneyOutCoin(CoinDetail moneyOutCoin) {
169: this .moneyOutCoin = moneyOutCoin;
170: }
171:
172: /**
173: * Gets the transactionEnded attribute.
174: *
175: * @return Returns the transactionEnded.
176: */
177: public java.util.Date getTransactionEnded() {
178: return transactionEnded;
179: }
180:
181: /**
182: * Sets the transactionEnded attribute value.
183: *
184: * @param transactionEnded The transactionEnded to set.
185: */
186: public void setTransactionEnded(java.util.Date transactionEnded) {
187: this .transactionEnded = transactionEnded;
188: }
189:
190: /**
191: * Gets the transactionStarted attribute.
192: *
193: * @return Returns the transactionStarted.
194: */
195: public java.util.Date getTransactionStarted() {
196: return transactionStarted;
197: }
198:
199: /**
200: * Sets the transactionStarted attribute value.
201: *
202: * @param transactionStarted The transactionStarted to set.
203: */
204: public void setTransactionStarted(java.util.Date transactionStarted) {
205: this .transactionStarted = transactionStarted;
206: }
207:
208: /**
209: * Gets the workgroupName attribute.
210: *
211: * @return Returns the workgroupName.
212: */
213: public String getWorkgroupName() {
214: return workgroupName;
215: }
216:
217: /**
218: * Sets the workgroupName attribute value.
219: *
220: * @param workgroupName The workgroupName to set.
221: */
222: public void setWorkgroupName(String workgroupName) {
223: this .workgroupName = workgroupName;
224: }
225:
226: /**
227: * Sets the moneyOutCurrency attribute value.
228: *
229: * @param moneyOutCurrency The moneyOutCurrency to set.
230: */
231: public void setMoneyOutCurrency(CurrencyDetail moneyOutCurrency) {
232: this .moneyOutCurrency = moneyOutCurrency;
233: }
234:
235: /**
236: * Gets the referenceFinancialDocumentNumber attribute.
237: *
238: * @return Returns the referenceFinancialDocumentNumber.
239: */
240: public String getReferenceFinancialDocumentNumber() {
241: return referenceFinancialDocumentNumber;
242: }
243:
244: /**
245: * Sets the referenceFinancialDocumentNumber attribute value.
246: *
247: * @param referenceFinancialDocumentNumber The referenceFinancialDocumentNumber to set.
248: */
249: public void setReferenceFinancialDocumentNumber(
250: String referenceFinancialDocumentNumber) {
251: this .referenceFinancialDocumentNumber = referenceFinancialDocumentNumber;
252: }
253:
254: /**
255: * Gets the moneyOutCurrency attribute.
256: *
257: * @return Returns the moneyOutCurrency.
258: */
259: public CurrencyDetail getMoneyOutCurrency() {
260: return moneyOutCurrency;
261: }
262:
263: /**
264: * Gets the newItemInProcess attribute.
265: *
266: * @return Returns the newItemInProcess.
267: */
268: public CashieringItemInProcess getNewItemInProcess() {
269: return newItemInProcess;
270: }
271:
272: /**
273: * Sets the newItemInProcess attribute value.
274: *
275: * @param newItemInProcess The newItemInProcess to set.
276: */
277: public void setNewItemInProcess(
278: CashieringItemInProcess newItemInProcess) {
279: this .newItemInProcess = newItemInProcess;
280: }
281:
282: /**
283: * Gets the openItemsInProcess attribute.
284: *
285: * @return Returns the openItemsInProcess.
286: */
287: public List<CashieringItemInProcess> getOpenItemsInProcess() {
288: return openItemsInProcess;
289: }
290:
291: /**
292: * Sets the openItemsInProcess attribute value.
293: *
294: * @param openItemsInProcess The openItemsInProcess to set.
295: */
296: public void setOpenItemsInProcess(
297: List<CashieringItemInProcess> openItemsInProcess) {
298: this .openItemsInProcess = openItemsInProcess;
299: }
300:
301: /**
302: * This method returns a single open item in process
303: *
304: * @return a cashiering item in process
305: */
306: public CashieringItemInProcess getOpenItemInProcess(int index) {
307: extendOpenItemsList(index);
308: return this .openItemsInProcess.get(index);
309: }
310:
311: /**
312: * make the open items in process list bigger, so it doesn't return a null value
313: *
314: * @param minSize the minsize to make the list
315: */
316: private void extendOpenItemsList(int minSize) {
317: while (this .openItemsInProcess.size() <= minSize) {
318: this .openItemsInProcess.add(new CashieringItemInProcess());
319: }
320: }
321:
322: /**
323: * Gets the newCheck attribute.
324: *
325: * @return Returns the newCheck.
326: */
327: public Check getNewCheck() {
328: return newCheck;
329: }
330:
331: /**
332: * Sets the newCheck attribute value.
333: *
334: * @param newCheck The newCheck to set.
335: */
336: public void setNewCheck(Check newCheck) {
337: this .newCheck = newCheck;
338: }
339:
340: /**
341: * This method will make sure that all of the various currency, coin, check, and item in process detail records are populated
342: * with the correct info.
343: */
344: public void prepareForSave() {
345: moneyInCoin
346: .setDocumentNumber(this .referenceFinancialDocumentNumber);
347: moneyInCoin.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE);
348: moneyInCoin
349: .setCashieringRecordSource(KFSConstants.CurrencyCoinSources.CASH_MANAGEMENT_IN);
350:
351: moneyInCurrency
352: .setDocumentNumber(this .referenceFinancialDocumentNumber);
353: moneyInCurrency
354: .setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE);
355: moneyInCurrency
356: .setCashieringRecordSource(KFSConstants.CurrencyCoinSources.CASH_MANAGEMENT_IN);
357:
358: moneyOutCoin
359: .setDocumentNumber(this .referenceFinancialDocumentNumber);
360: moneyOutCoin.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE);
361: moneyOutCoin
362: .setCashieringRecordSource(KFSConstants.CurrencyCoinSources.CASH_MANAGEMENT_OUT);
363:
364: moneyOutCurrency
365: .setDocumentNumber(this .referenceFinancialDocumentNumber);
366: moneyOutCurrency
367: .setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE);
368: moneyOutCurrency
369: .setCashieringRecordSource(KFSConstants.CurrencyCoinSources.CASH_MANAGEMENT_OUT);
370:
371: newItemInProcess.setWorkgroupName(this .workgroupName);
372: }
373:
374: /**
375: * @see org.kuali.core.bo.BusinessObjectBase#toStringMapper()
376: */
377: @Override
378: protected LinkedHashMap toStringMapper() {
379: LinkedHashMap pkMap = new LinkedHashMap();
380: pkMap.put("workgroupName", this .workgroupName);
381: pkMap.put("referenceFinancialDocumentNumber",
382: this .referenceFinancialDocumentNumber);
383: pkMap.put("transactionStarted", this .transactionStarted);
384: return pkMap;
385: }
386:
387: /**
388: * Gets the checks attribute.
389: *
390: * @return Returns the checks.
391: */
392: public List getChecks() {
393: return getMoneyInChecks();
394: }
395:
396: /**
397: * Sets the checks attribute value.
398: *
399: * @param checks The checks to set.
400: */
401: public void setChecks(List checks) {
402: moneyInChecks = new ArrayList<Check>();
403: for (Object o : checks) {
404: moneyInChecks.add((Check) o);
405: }
406: }
407:
408: /**
409: * Gets the number of checks, since Sun doesn't have a direct getter for collection size
410: *
411: * @return the number of checks
412: */
413: public int getCheckCount() {
414: int count = 0;
415: if (moneyInChecks != null) {
416: count = moneyInChecks.size();
417: }
418: return count;
419: }
420:
421: /**
422: * Adds a new check to the list.
423: *
424: * @param check
425: */
426: public void addCheck(Check check) {
427: check.setSequenceId(this .nextCheckSequenceId);
428:
429: this .moneyInChecks.add(check);
430:
431: this .nextCheckSequenceId = new Integer(this .nextCheckSequenceId
432: .intValue() + 1);
433: }
434:
435: /**
436: * Retrieve a particular check at a given index in the list of checks.
437: *
438: * @param index
439: * @return Check
440: */
441: public Check getCheck(int index) {
442: while (this .moneyInChecks.size() <= index) {
443: moneyInChecks.add(createNewCheck());
444: }
445: return (Check) moneyInChecks.get(index);
446: }
447:
448: /**
449: * @param checks
450: * @return Map containing Checks from the given List, indexed by their sequenceId
451: */
452: private Map buildCheckMap(List checks) {
453: Map checkMap = new HashMap();
454:
455: for (Iterator i = checks.iterator(); i.hasNext();) {
456: Check check = (Check) i.next();
457: Integer sequenceId = check.getSequenceId();
458:
459: Object oldCheck = checkMap.put(sequenceId, check);
460:
461: // verify that sequence numbers are unique...
462: if (oldCheck != null) {
463: throw new IllegalStateException(
464: "sequence id collision detected for sequence id "
465: + sequenceId);
466: }
467: }
468:
469: return checkMap;
470: }
471:
472: /**
473: * This method removes a check from the list and updates the total appropriately.
474: *
475: * @param index
476: */
477: public void removeCheck(int index) {
478: Check check = (Check) moneyInChecks.remove(index);
479: KualiDecimal newTotalCheckAmount = getTotalCheckAmount()
480: .subtract(check.getAmount());
481: // if the totalCheckAmount goes negative, bring back to zero.
482: if (newTotalCheckAmount.isNegative()) {
483: newTotalCheckAmount = KualiDecimal.ZERO;
484: }
485: }
486:
487: public KualiDecimal getTotalCheckAmount() {
488: KualiDecimal result = new KualiDecimal(0);
489: for (Check c : moneyInChecks) {
490: if (c != null && c.getAmount() != null) {
491: result = result.add(c.getAmount());
492: }
493: }
494: return result;
495: }
496:
497: /**
498: * Gets the nextCheckSequenceId attribute.
499: *
500: * @return Returns the nextCheckSequenceId.
501: */
502: public Integer getNextCheckSequenceId() {
503: return nextCheckSequenceId;
504: }
505:
506: /**
507: * Sets the nextCheckSequenceId attribute value.
508: *
509: * @param nextCheckSequenceId The nextCheckSequenceId to set.
510: */
511: public void setNextCheckSequenceId(Integer nextCheckSequenceId) {
512: this .nextCheckSequenceId = nextCheckSequenceId;
513: }
514:
515: public Check createNewCheck() {
516: Check newCheck = new CheckBase();
517: newCheck.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE);
518: newCheck
519: .setCashieringRecordSource(KFSConstants.CheckSources.CASH_MANAGEMENT);
520: return newCheck;
521: }
522:
523: /**
524: * This method calculates how much money has been paid back in all items in process
525: *
526: * @return the calculated amount
527: */
528: public KualiDecimal getPaidBackItemsInProcessAmount() {
529: KualiDecimal amount = new KualiDecimal(0);
530: if (this .openItemsInProcess != null) {
531: for (CashieringItemInProcess itemInProcess : this .openItemsInProcess) {
532: if (itemInProcess.getCurrentPayment() != null
533: && itemInProcess.getCurrentPayment()
534: .isGreaterThan(KualiDecimal.ZERO)) {
535: amount = amount.add(itemInProcess
536: .getCurrentPayment());
537: }
538: }
539: }
540: return amount;
541: }
542:
543: /**
544: * @return current List of baseline checks for use in update detection
545: */
546: public List getBaselineChecks() {
547: return baselineChecks;
548: }
549:
550: /**
551: * Sets the current List of baseline checks to the given List
552: *
553: * @param baselineChecks
554: */
555: public void setBaselineChecks(List baselineChecks) {
556: this .baselineChecks = baselineChecks;
557: }
558:
559: /**
560: * @param index
561: * @return true if a baselineCheck with the given index exists
562: */
563: public boolean hasBaselineCheck(int index) {
564: boolean has = false;
565:
566: if ((index >= 0) && (index <= baselineChecks.size())) {
567: has = true;
568: }
569:
570: return has;
571: }
572:
573: /**
574: * Implementation creates empty Checks as a side-effect, so that Struts' efforts to set fields of lines which haven't been
575: * created will succeed rather than causing a NullPointerException.
576: *
577: * @param index
578: * @return baseline Check at the given index
579: */
580: public Check getBaselineCheck(int index) {
581: while (baselineChecks.size() <= index) {
582: baselineChecks.add(this .createNewCheck());
583: }
584: return (Check) baselineChecks.get(index);
585: }
586:
587: /**
588: * This method calcuates how much money has come in to the "Money In" side of the transaction
589: *
590: * @return the amount calculated
591: */
592: public KualiDecimal getMoneyInTotal() {
593: KualiDecimal result = new KualiDecimal(0);
594: result = result.add(this .moneyInCurrency.getTotalAmount());
595: result = result.add(this .moneyInCoin.getTotalAmount());
596: result = result.add(this .getTotalCheckAmount());
597: if (this .newItemInProcess.isPopulated()) {
598: result = result.add(this .newItemInProcess.getItemAmount());
599: }
600: return result;
601: }
602:
603: /**
604: * This method calculates how much money has gone out through the "Money Out" side of the transaction
605: *
606: * @return the amount calculated
607: */
608: public KualiDecimal getMoneyOutTotal() {
609: KualiDecimal result = new KualiDecimal(0);
610: result = result.add(this .moneyOutCurrency.getTotalAmount());
611: result = result.add(this .moneyOutCoin.getTotalAmount());
612: result = result.add(this .getPaidBackItemsInProcessAmount());
613: return result;
614: }
615:
616: /**
617: * @param checkTotal
618: * @deprecated
619: */
620: public void setCheckTotal(KualiDecimal checkTotal) {
621: this.checkTotal = checkTotal;
622: }
623:
624: }
|