001: /*
002: * Copyright 2006-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:
017: package org.kuali.module.financial.document;
018:
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.LinkedHashMap;
022: import java.util.List;
023:
024: import org.apache.commons.lang.StringUtils;
025: import org.apache.log4j.Logger;
026: import org.kuali.core.service.DateTimeService;
027: import org.kuali.core.workflow.service.KualiWorkflowDocument;
028: import org.kuali.kfs.KFSPropertyConstants;
029: import org.kuali.kfs.KFSConstants.DepositConstants;
030: import org.kuali.kfs.context.SpringContext;
031: import org.kuali.kfs.document.AccountingDocumentBase;
032: import org.kuali.module.financial.bo.CashDrawer;
033: import org.kuali.module.financial.bo.CashieringItemInProcess;
034: import org.kuali.module.financial.bo.CashieringTransaction;
035: import org.kuali.module.financial.bo.Check;
036: import org.kuali.module.financial.bo.Deposit;
037: import org.kuali.module.financial.service.CashDrawerService;
038: import org.kuali.module.financial.service.CashManagementService;
039:
040: /**
041: * This class represents the CashManagementDocument.
042: */
043: public class CashManagementDocument extends AccountingDocumentBase {
044: private static final long serialVersionUID = 7475843770851900297L;
045: private static Logger LOG = Logger
046: .getLogger(CashManagementDocument.class);
047:
048: private String workgroupName;
049: private String referenceFinancialDocumentNumber;
050:
051: private List<Deposit> deposits;
052:
053: private List<Check> checks;
054:
055: private transient CashieringTransaction currentTransaction;
056: private CashDrawer cashDrawer;
057:
058: /**
059: * Default constructor.
060: */
061: public CashManagementDocument() {
062: super ();
063: deposits = new ArrayList<Deposit>();
064: checks = new ArrayList<Check>();
065: this .resetCurrentTransaction();
066: }
067:
068: /**
069: * @return current value of referenceFinancialDocumentNumber.
070: */
071: public String getReferenceFinancialDocumentNumber() {
072: return referenceFinancialDocumentNumber;
073: }
074:
075: /**
076: * Sets the referenceFinancialDocumentNumber attribute value.
077: *
078: * @param referenceFinancialDocumentNumber The referenceFinancialDocumentNumber to set.
079: */
080: public void setReferenceFinancialDocumentNumber(
081: String referenceFinancialDocumentNumber) {
082: this .referenceFinancialDocumentNumber = referenceFinancialDocumentNumber;
083: }
084:
085: /**
086: * @return current value of workgroupName.
087: */
088: public String getWorkgroupName() {
089: return workgroupName;
090: }
091:
092: /**
093: * Sets the workgroupName attribute value.
094: *
095: * @param workgroupName The workgroupName to set.
096: */
097: public void setWorkgroupName(String workgroupName) {
098: this .workgroupName = workgroupName;
099: }
100:
101: /**
102: * Derives and returns the cash drawer status for the document's workgroup
103: */
104: public String getCashDrawerStatus() {
105: return getCashDrawer().getStatusCode();
106: }
107:
108: /**
109: * @param cashDrawerStatus
110: */
111: public void setCashDrawerStatus(String cashDrawerStatus) {
112: // ignored, because that value is dynamically retrieved from the service
113: // required, because POJO pitches a fit if this method doesn't exist
114: }
115:
116: /**
117: * Alias for getCashDrawerStatus which avoids the automagic formatting
118: */
119: public String getRawCashDrawerStatus() {
120: return getCashDrawerStatus();
121: }
122:
123: /* Deposit-list maintenance */
124: /**
125: * @return current List of Deposits
126: */
127: public List<Deposit> getDeposits() {
128: return deposits;
129: }
130:
131: /**
132: * Sets the current List of Deposits
133: *
134: * @param deposits
135: */
136: public void setDeposits(List<Deposit> deposits) {
137: this .deposits = deposits;
138: }
139:
140: /**
141: * Implementation creates empty Deposits as a side-effect, so that Struts' efforts to set fields of lines which haven't been
142: * created will succeed rather than causing a NullPointerException.
143: *
144: * @return Deposit at the given index
145: */
146: public Deposit getDeposit(int index) {
147: extendDeposits(index + 1);
148:
149: return (Deposit) deposits.get(index);
150: }
151:
152: /**
153: * Removes and returns the Deposit at the given index.
154: *
155: * @param index
156: * @return Deposit at the given index
157: */
158: public Deposit removeDeposit(int index) {
159: extendDeposits(index + 1);
160:
161: return (Deposit) deposits.remove(index);
162: }
163:
164: /**
165: * @return true if one of the Deposits contained in this document has a type of "final"
166: */
167: public boolean hasFinalDeposit() {
168: boolean hasFinal = false;
169:
170: for (Iterator i = deposits.iterator(); !hasFinal && i.hasNext();) {
171: Deposit d = (Deposit) i.next();
172:
173: hasFinal = StringUtils.equals(
174: DepositConstants.DEPOSIT_TYPE_FINAL, d
175: .getDepositTypeCode());
176: }
177:
178: return hasFinal;
179: }
180:
181: /**
182: * @return lowest unused deposit-line-number, to simplify adding and canceling deposits out-of-order
183: */
184: public Integer getNextDepositLineNumber() {
185: int maxLineNumber = -1;
186:
187: for (Iterator i = deposits.iterator(); i.hasNext();) {
188: Deposit d = (Deposit) i.next();
189:
190: Integer depositLineNumber = d
191: .getFinancialDocumentDepositLineNumber();
192: if ((depositLineNumber != null)
193: && (depositLineNumber.intValue() > maxLineNumber)) {
194: maxLineNumber = depositLineNumber.intValue();
195: }
196: }
197:
198: return new Integer(maxLineNumber + 1);
199: }
200:
201: /**
202: * Adds default AccountingLineDecorators to sourceAccountingLineDecorators until it contains at least minSize elements
203: *
204: * @param minSize
205: */
206: private void extendDeposits(int minSize) {
207: while (deposits.size() < minSize) {
208: deposits.add(new Deposit());
209: }
210: }
211:
212: /**
213: * @see org.kuali.core.document.DocumentBase#buildListOfDeletionAwareLists()
214: */
215: @Override
216: public List buildListOfDeletionAwareLists() {
217: List managedLists = super .buildListOfDeletionAwareLists();
218:
219: managedLists.add(getDeposits());
220:
221: return managedLists;
222: }
223:
224: /**
225: * Gets the cashDrawer attribute.
226: *
227: * @return Returns the cashDrawer.
228: */
229: public CashDrawer getCashDrawer() {
230: return cashDrawer;
231: // return cashDrawerService.getByWorkgroupName(this.workgroupName, false);
232: }
233:
234: /**
235: * Sets the cashDrawer attribute
236: *
237: * @param cd the cash drawer to set
238: */
239: public void setCashDrawer(CashDrawer cd) {
240: cashDrawer = cd;
241: }
242:
243: /**
244: * Gets the currentTransaction attribute.
245: *
246: * @return Returns the currentTransaction.
247: */
248: public CashieringTransaction getCurrentTransaction() {
249: return currentTransaction;
250: }
251:
252: /**
253: * Sets the currentTransaction attribute value.
254: *
255: * @param currentTransaction The currentTransaction to set.
256: */
257: public void setCurrentTransaction(
258: CashieringTransaction currentTransaction) {
259: this .currentTransaction = currentTransaction;
260: }
261:
262: /**
263: * Gets the checks attribute.
264: *
265: * @return Returns the checks.
266: */
267: public List<Check> getChecks() {
268: return checks;
269: }
270:
271: /**
272: * Sets the checks attribute value.
273: *
274: * @param checks The checks to set.
275: */
276: public void setChecks(List<Check> checks) {
277: this .checks = checks;
278: }
279:
280: /**
281: * Add a check to the cash management document
282: *
283: * @param check
284: */
285: public void addCheck(Check check) {
286: this .checks.add(check);
287: }
288:
289: /**
290: * @see org.kuali.core.document.DocumentBase#handleRouteStatusChange()
291: */
292: @Override
293: public void handleRouteStatusChange() {
294: super .handleRouteStatusChange();
295:
296: KualiWorkflowDocument kwd = getDocumentHeader()
297: .getWorkflowDocument();
298:
299: if (LOG.isDebugEnabled()) {
300: logState();
301: }
302:
303: if (kwd.stateIsProcessed()) {
304: // all approvals have been processed, finalize everything
305: SpringContext.getBean(CashManagementService.class)
306: .finalizeCashManagementDocument(this );
307: } else if (kwd.stateIsCanceled() || kwd.stateIsDisapproved()) {
308: // document has been canceled or disapproved
309: SpringContext.getBean(CashManagementService.class)
310: .cancelCashManagementDocument(this );
311: }
312: }
313:
314: private void logState() {
315: KualiWorkflowDocument kwd = getDocumentHeader()
316: .getWorkflowDocument();
317:
318: if (kwd.stateIsInitiated()) {
319: LOG.debug("CMD stateIsInitiated");
320: }
321: if (kwd.stateIsProcessed()) {
322: LOG.debug("CMD stateIsProcessed");
323: }
324: if (kwd.stateIsCanceled()) {
325: LOG.debug("CMD stateIsCanceled");
326: }
327: if (kwd.stateIsDisapproved()) {
328: LOG.debug("CMD stateIsDisapproved");
329: }
330: }
331:
332: /**
333: * @see org.kuali.core.document.DocumentBase#processAfterRetrieve()
334: */
335: @Override
336: public void processAfterRetrieve() {
337: super .processAfterRetrieve();
338: // grab the cash drawer
339: if (this .getWorkgroupName() != null) {
340: this .cashDrawer = SpringContext.getBean(
341: CashDrawerService.class).getByWorkgroupName(
342: this .getWorkgroupName(), false);
343: this .resetCurrentTransaction();
344: }
345: SpringContext.getBean(CashManagementService.class)
346: .populateCashDetailsForDeposit(this );
347: }
348:
349: /* utility methods */
350: /**
351: * @see org.kuali.core.bo.BusinessObjectBase#toStringMapper()
352: */
353: @Override
354: protected LinkedHashMap toStringMapper() {
355: LinkedHashMap m = new LinkedHashMap();
356: m
357: .put(KFSPropertyConstants.DOCUMENT_NUMBER,
358: getDocumentNumber());
359: m.put("workgroupName", getWorkgroupName());
360: return m;
361: }
362:
363: /**
364: * This method creates a clean current transaction to be the new current transaction on this document
365: */
366: public void resetCurrentTransaction() {
367: if (this .currentTransaction != null) {
368: this .currentTransaction.setTransactionEnded(SpringContext
369: .getBean(DateTimeService.class).getCurrentDate());
370: }
371: currentTransaction = new CashieringTransaction(workgroupName,
372: referenceFinancialDocumentNumber);
373: if (this .getWorkgroupName() != null) {
374: List<CashieringItemInProcess> openItemsInProcess = SpringContext
375: .getBean(CashManagementService.class)
376: .getOpenItemsInProcess(this );
377: if (openItemsInProcess != null) {
378: currentTransaction
379: .setOpenItemsInProcess(openItemsInProcess);
380: }
381: currentTransaction.setNextCheckSequenceId(SpringContext
382: .getBean(CashManagementService.class)
383: .selectNextAvailableCheckLineNumber(
384: this.documentNumber));
385: }
386: }
387:
388: }
|