/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.fp.businessobject; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.context.SpringContext; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.krad.bo.TransientBusinessObjectBase; /** * This class represents a cashiering-related transaction used in the cash management document */ public class CashieringTransaction extends TransientBusinessObjectBase { public static final String DETAIL_DOCUMENT_TYPE = "CMD"; private String campusCode; private String referenceFinancialDocumentNumber; // money in properties private List<Check> moneyInChecks; private CoinDetail moneyInCoin; private CurrencyDetail moneyInCurrency; private CashieringItemInProcess newItemInProcess; private List<Check> baselineChecks; private Check newCheck; private KualiDecimal checkTotal; // money out properties private CoinDetail moneyOutCoin; private CurrencyDetail moneyOutCurrency; private List<CashieringItemInProcess> openItemsInProcess; private java.util.Date transactionStarted; private java.util.Date transactionEnded; // incrementers for detail lines private Integer nextCheckSequenceId; /** * Constructs a CashieringTransaction */ public CashieringTransaction(String campusCode, String referenceFinancialDocumentNumber) { super(); this.campusCode = campusCode; this.referenceFinancialDocumentNumber = referenceFinancialDocumentNumber; this.transactionStarted = SpringContext.getBean(DateTimeService.class).getCurrentDate(); moneyInCoin = new CoinDetail(); moneyInCurrency = new CurrencyDetail(); moneyOutCoin = new CoinDetail(); moneyOutCurrency = new CurrencyDetail(); newItemInProcess = new CashieringItemInProcess(); moneyInChecks = new ArrayList<Check>(); newCheck = new CheckBase(); baselineChecks = new ArrayList<Check>(); openItemsInProcess = new ArrayList<CashieringItemInProcess>(); nextCheckSequenceId = new Integer(1); } /** * Gets the moneyInChecks attribute. * * @return Returns the moneyInChecks. */ public List<Check> getMoneyInChecks() { return moneyInChecks; } /** * Sets the moneyInChecks attribute value. * * @param moneyInChecks The moneyInChecks to set. */ public void setMoneyInChecks(List<Check> moneyInChecks) { this.moneyInChecks = moneyInChecks; } /** * Retrieves a specific check from the list, by array index * * @param index the index of the checks array to retrieve the check from * @return a Check */ public Check getMoneyInCheck(int index) { if (index >= moneyInChecks.size()) { for (int i = moneyInChecks.size(); i <= index; i++) { moneyInChecks.add(createNewCheck()); } } return moneyInChecks.get(index); } /** * Gets the moneyInCoin attribute. * * @return Returns the moneyInCoin. */ public CoinDetail getMoneyInCoin() { return moneyInCoin; } /** * Sets the moneyInCoin attribute value. * * @param moneyInCoin The moneyInCoin to set. */ public void setMoneyInCoin(CoinDetail moneyInCoin) { this.moneyInCoin = moneyInCoin; } /** * Gets the moneyInCurrency attribute. * * @return Returns the moneyInCurrency. */ public CurrencyDetail getMoneyInCurrency() { return moneyInCurrency; } /** * Sets the moneyInCurrency attribute value. * * @param moneyInCurrency The moneyInCurrency to set. */ public void setMoneyInCurrency(CurrencyDetail moneyInCurrency) { this.moneyInCurrency = moneyInCurrency; } /** * Gets the moneyOutCoin attribute. * * @return Returns the moneyOutCoin. */ public CoinDetail getMoneyOutCoin() { return moneyOutCoin; } /** * Sets the moneyOutCoin attribute value. * * @param moneyOutCoin The moneyOutCoin to set. */ public void setMoneyOutCoin(CoinDetail moneyOutCoin) { this.moneyOutCoin = moneyOutCoin; } /** * Gets the transactionEnded attribute. * * @return Returns the transactionEnded. */ public java.util.Date getTransactionEnded() { return transactionEnded; } /** * Sets the transactionEnded attribute value. * * @param transactionEnded The transactionEnded to set. */ public void setTransactionEnded(java.util.Date transactionEnded) { this.transactionEnded = transactionEnded; } /** * Gets the transactionStarted attribute. * * @return Returns the transactionStarted. */ public java.util.Date getTransactionStarted() { return transactionStarted; } /** * Sets the transactionStarted attribute value. * * @param transactionStarted The transactionStarted to set. */ public void setTransactionStarted(java.util.Date transactionStarted) { this.transactionStarted = transactionStarted; } /** * Gets the campusCode attribute. * * @return Returns the campusCode. */ public String getCampusCode() { return campusCode; } /** * Sets the campusCode attribute value. * * @param campusCode The campusCode to set. */ public void setCampusCode(String campusCode) { this.campusCode = campusCode; } /** * Sets the moneyOutCurrency attribute value. * * @param moneyOutCurrency The moneyOutCurrency to set. */ public void setMoneyOutCurrency(CurrencyDetail moneyOutCurrency) { this.moneyOutCurrency = moneyOutCurrency; } /** * Gets the referenceFinancialDocumentNumber attribute. * * @return Returns the referenceFinancialDocumentNumber. */ public String getReferenceFinancialDocumentNumber() { return referenceFinancialDocumentNumber; } /** * Sets the referenceFinancialDocumentNumber attribute value. * * @param referenceFinancialDocumentNumber The referenceFinancialDocumentNumber to set. */ public void setReferenceFinancialDocumentNumber(String referenceFinancialDocumentNumber) { this.referenceFinancialDocumentNumber = referenceFinancialDocumentNumber; } /** * Gets the moneyOutCurrency attribute. * * @return Returns the moneyOutCurrency. */ public CurrencyDetail getMoneyOutCurrency() { return moneyOutCurrency; } /** * Gets the newItemInProcess attribute. * * @return Returns the newItemInProcess. */ public CashieringItemInProcess getNewItemInProcess() { return newItemInProcess; } /** * Sets the newItemInProcess attribute value. * * @param newItemInProcess The newItemInProcess to set. */ public void setNewItemInProcess(CashieringItemInProcess newItemInProcess) { this.newItemInProcess = newItemInProcess; } /** * Gets the openItemsInProcess attribute. * * @return Returns the openItemsInProcess. */ public List<CashieringItemInProcess> getOpenItemsInProcess() { return openItemsInProcess; } /** * Sets the openItemsInProcess attribute value. * * @param openItemsInProcess The openItemsInProcess to set. */ public void setOpenItemsInProcess(List<CashieringItemInProcess> openItemsInProcess) { this.openItemsInProcess = openItemsInProcess; } /** * This method returns a single open item in process * * @return a cashiering item in process */ public CashieringItemInProcess getOpenItemInProcess(int index) { extendOpenItemsList(index); return this.openItemsInProcess.get(index); } /** * make the open items in process list bigger, so it doesn't return a null value * * @param minSize the minsize to make the list */ private void extendOpenItemsList(int minSize) { while (this.openItemsInProcess.size() <= minSize) { this.openItemsInProcess.add(new CashieringItemInProcess()); } } /** * Gets the newCheck attribute. * * @return Returns the newCheck. */ public Check getNewCheck() { return newCheck; } /** * Sets the newCheck attribute value. * * @param newCheck The newCheck to set. */ public void setNewCheck(Check newCheck) { this.newCheck = newCheck; } /** * This method will make sure that all of the various currency, coin, check, and item in process detail records are populated * with the correct info. */ public void prepareForSave() { moneyInCoin.setDocumentNumber(this.referenceFinancialDocumentNumber); moneyInCoin.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE); moneyInCoin.setCashieringStatus(KFSConstants.CurrencyCoinSources.CASH_MANAGEMENT_IN); moneyInCurrency.setDocumentNumber(this.referenceFinancialDocumentNumber); moneyInCurrency.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE); moneyInCurrency.setCashieringStatus(KFSConstants.CurrencyCoinSources.CASH_MANAGEMENT_IN); moneyOutCoin.setDocumentNumber(this.referenceFinancialDocumentNumber); moneyOutCoin.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE); moneyOutCoin.setCashieringStatus(KFSConstants.CurrencyCoinSources.DEPOSITS); moneyOutCurrency.setDocumentNumber(this.referenceFinancialDocumentNumber); moneyOutCurrency.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE); moneyOutCurrency.setCashieringStatus(KFSConstants.CurrencyCoinSources.DEPOSITS); newItemInProcess.setCampusCode(this.campusCode); } /** * @see org.kuali.rice.krad.bo.BusinessObjectBase#toStringMapper() */ protected LinkedHashMap toStringMapper_RICE20_REFACTORME() { LinkedHashMap pkMap = new LinkedHashMap(); pkMap.put("campusCode", this.campusCode); pkMap.put("referenceFinancialDocumentNumber", this.referenceFinancialDocumentNumber); pkMap.put("transactionStarted", this.transactionStarted); return pkMap; } /** * Gets the checks attribute. * * @return Returns the checks. */ public List getChecks() { return getMoneyInChecks(); } /** * Sets the checks attribute value. * * @param checks The checks to set. */ public void setChecks(List checks) { moneyInChecks = new ArrayList<Check>(); for (Object o : checks) { moneyInChecks.add((Check) o); } } /** * Gets the number of checks, since Sun doesn't have a direct getter for collection size * * @return the number of checks */ public int getCheckCount() { int count = 0; if (moneyInChecks != null) { count = moneyInChecks.size(); } return count; } /** * Adds a new check to the list. * * @param check */ public void addCheck(Check check) { check.setSequenceId(this.nextCheckSequenceId); this.moneyInChecks.add(check); this.nextCheckSequenceId = new Integer(this.nextCheckSequenceId.intValue() + 1); } /** * Retrieve a particular check at a given index in the list of checks. * * @param index * @return Check */ public Check getCheck(int index) { while (this.moneyInChecks.size() <= index) { moneyInChecks.add(createNewCheck()); } return (Check) moneyInChecks.get(index); } /** * @param checks * @return Map containing Checks from the given List, indexed by their sequenceId */ private Map buildCheckMap(List checks) { Map checkMap = new HashMap(); for (Iterator i = checks.iterator(); i.hasNext();) { Check check = (Check) i.next(); Integer sequenceId = check.getSequenceId(); Object oldCheck = checkMap.put(sequenceId, check); // verify that sequence numbers are unique... if (oldCheck != null) { throw new IllegalStateException("sequence id collision detected for sequence id " + sequenceId); } } return checkMap; } /** * This method removes a check from the list and updates the total appropriately. * * @param index */ public void removeCheck(int index) { Check check = (Check) moneyInChecks.remove(index); KualiDecimal newTotalCheckAmount = getTotalCheckAmount().subtract(check.getAmount()); // if the totalCheckAmount goes negative, bring back to zero. if (newTotalCheckAmount.isNegative()) { newTotalCheckAmount = KualiDecimal.ZERO; } } public KualiDecimal getTotalCheckAmount() { KualiDecimal result = KualiDecimal.ZERO; for (Check c : moneyInChecks) { if (c != null && c.getAmount() != null) { result = result.add(c.getAmount()); } } return result; } /** * Gets the nextCheckSequenceId attribute. * * @return Returns the nextCheckSequenceId. */ public Integer getNextCheckSequenceId() { return nextCheckSequenceId; } /** * Sets the nextCheckSequenceId attribute value. * * @param nextCheckSequenceId The nextCheckSequenceId to set. */ public void setNextCheckSequenceId(Integer nextCheckSequenceId) { this.nextCheckSequenceId = nextCheckSequenceId; } public Check createNewCheck() { Check newCheck = new CheckBase(); newCheck.setFinancialDocumentTypeCode(DETAIL_DOCUMENT_TYPE); newCheck.setCashieringStatus(KFSConstants.CheckSources.CASH_MANAGEMENT); return newCheck; } /** * This method calculates how much money has been paid back in all items in process * * @return the calculated amount */ public KualiDecimal getPaidBackItemsInProcessAmount() { KualiDecimal amount = KualiDecimal.ZERO; if (this.openItemsInProcess != null) { for (CashieringItemInProcess itemInProcess : this.openItemsInProcess) { if (itemInProcess.getCurrentPayment() != null && itemInProcess.getCurrentPayment().isGreaterThan(KualiDecimal.ZERO)) { amount = amount.add(itemInProcess.getCurrentPayment()); } } } return amount; } /** * @return current List of baseline checks for use in update detection */ public List getBaselineChecks() { return baselineChecks; } /** * Sets the current List of baseline checks to the given List * * @param baselineChecks */ public void setBaselineChecks(List baselineChecks) { this.baselineChecks = baselineChecks; } /** * @param index * @return true if a baselineCheck with the given index exists */ public boolean hasBaselineCheck(int index) { boolean has = false; if ((index >= 0) && (index <= baselineChecks.size())) { has = true; } return has; } /** * Implementation creates empty Checks as a side-effect, so that Struts' efforts to set fields of lines which haven't been * created will succeed rather than causing a NullPointerException. * * @param index * @return baseline Check at the given index */ public Check getBaselineCheck(int index) { while (baselineChecks.size() <= index) { baselineChecks.add(this.createNewCheck()); } return (Check) baselineChecks.get(index); } /** * This method calcuates how much money has come in to the "Money In" side of the transaction * * @return the amount calculated */ public KualiDecimal getMoneyInTotal() { KualiDecimal result = KualiDecimal.ZERO; result = result.add(this.moneyInCurrency.getTotalAmount()); result = result.add(this.moneyInCoin.getTotalAmount()); result = result.add(this.getTotalCheckAmount()); if (this.newItemInProcess.isPopulated()) { result = result.add(this.newItemInProcess.getItemAmount()); } return result; } /** * This method calculates how much money has gone out through the "Money Out" side of the transaction * * @return the amount calculated */ public KualiDecimal getMoneyOutTotal() { KualiDecimal result = KualiDecimal.ZERO; result = result.add(this.moneyOutCurrency.getTotalAmount()); result = result.add(this.moneyOutCoin.getTotalAmount()); result = result.add(this.getPaidBackItemsInProcessAmount()); return result; } /** * @param checkTotal * @deprecated */ public void setCheckTotal(KualiDecimal checkTotal) { this.checkTotal = checkTotal; } }