View Javadoc
1   /*
2    * Copyright 2006 The Kuali Foundation
3    * 
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    * http://www.opensource.org/licenses/ecl2.php
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.ole.fp.document.validation.impl;
17  
18  import java.util.Arrays;
19  import java.util.Calendar;
20  import java.util.Date;
21  import java.util.GregorianCalendar;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import org.apache.log4j.Logger;
26  import org.kuali.ole.fp.businessobject.CashDrawer;
27  import org.kuali.ole.fp.businessobject.CashieringItemInProcess;
28  import org.kuali.ole.fp.businessobject.CashieringTransaction;
29  import org.kuali.ole.fp.businessobject.Check;
30  import org.kuali.ole.fp.businessobject.CoinDetail;
31  import org.kuali.ole.fp.businessobject.CurrencyDetail;
32  import org.kuali.ole.fp.businessobject.Deposit;
33  import org.kuali.ole.fp.businessobject.DepositCashReceiptControl;
34  import org.kuali.ole.fp.document.CashManagementDocument;
35  import org.kuali.ole.fp.document.CashReceiptDocument;
36  import org.kuali.ole.fp.document.service.CashManagementService;
37  import org.kuali.ole.fp.document.service.CashReceiptService;
38  import org.kuali.ole.fp.document.validation.CashManagingRule;
39  import org.kuali.ole.fp.service.CashDrawerService;
40  import org.kuali.ole.sys.OLEConstants;
41  import org.kuali.ole.sys.OLEConstants.DocumentStatusCodes.CashReceipt;
42  import org.kuali.ole.sys.OLEKeyConstants;
43  import org.kuali.ole.sys.OLEPropertyConstants;
44  import org.kuali.ole.sys.context.SpringContext;
45  import org.kuali.ole.sys.document.validation.impl.BankCodeValidation;
46  import org.kuali.ole.sys.document.validation.impl.GeneralLedgerPostingDocumentRuleBase;
47  import org.kuali.rice.core.api.util.type.KualiDecimal;
48  import org.kuali.rice.kim.api.identity.Person;
49  import org.kuali.rice.kns.service.DictionaryValidationService;
50  import org.kuali.rice.krad.document.Document;
51  import org.kuali.rice.krad.util.GlobalVariables;
52  
53  /**
54   * Business rule(s) applicable to Cash Management Document.
55   */
56  public class CashManagementDocumentRule extends GeneralLedgerPostingDocumentRuleBase implements CashManagingRule {
57      private static final Logger LOG = Logger.getLogger(CashManagementDocumentRule.class);
58  
59      /**
60       * Overrides to validate that the person saving the document is the initiator, validates that the cash drawer is open for
61       * initial creation, validates that the cash drawer for the specific verification unit is closed for subsequent saves, and
62       * validates that the associate cash receipts are still verified.
63       * 
64       * @param document submitted cash management document
65       * @return true if there are no issues processing rules associated with saving a cash management document
66       * @see org.kuali.rice.krad.rule.DocumentRuleBase#processCustomSaveDocumentBusinessRules(org.kuali.rice.krad.document.Document)
67       */
68      @Override
69      protected boolean processCustomSaveDocumentBusinessRules(Document document) {
70          boolean isValid = super.processCustomSaveDocumentBusinessRules(document);
71  
72          CashManagementDocument cmd = (CashManagementDocument) document;
73  
74          // verify the cash drawer for the verification unit is closed for post-initialized saves
75          verifyCashDrawerForVerificationUnitIsOpenForPostInitiationSaves(cmd);
76  
77          // verify deposits
78          isValid &= validateDeposits(cmd);
79  
80          return isValid;
81      }
82  
83      /**
84       * Overrides to validate that all cash receipts are deposited when routing cash management document.
85       * 
86       * @param document submitted cash management document
87       * @return true if there are no issues processing rules associated with routing a cash management document
88       * @see org.kuali.rice.krad.rules.DocumentRuleBase#processCustomRouteDocumentBusinessRules(org.kuali.rice.krad.document.Document)
89       */
90      @Override
91      protected boolean processCustomRouteDocumentBusinessRules(Document document) {
92          boolean isValid = true;
93  
94          CashManagementDocument cmDoc = (CashManagementDocument) document;
95          isValid &= verifyAllVerifiedCashReceiptsDeposited(cmDoc);
96  
97          return isValid;
98      }
99  
100     /**
101      * This method checks to make sure that the current system user is the person that initiated this document in the first place.
102      * 
103      * @param cmd submitted cash management document
104      */
105     protected void verifyUserIsDocumentInitiator(CashManagementDocument cmd) {
106         Person currentUser = GlobalVariables.getUserSession().getPerson();
107         if (cmd.getDocumentHeader() != null && cmd.getDocumentHeader().getWorkflowDocument() != null) {
108             String cmdInitiatorNetworkId = cmd.getDocumentHeader().getWorkflowDocument().getInitiatorPrincipalId();
109             if (!cmdInitiatorNetworkId.equalsIgnoreCase(currentUser.getPrincipalName())) {
110                 throw new IllegalStateException("The current user (" + currentUser.getPrincipalName() + ") is not the individual (" + cmdInitiatorNetworkId + ") that initiated this document.");
111             }
112         }
113     }
114 
115     /**
116      * This method checks to make sure that the cash drawer is closed for the associated verification unit, for post initiation
117      * saves for CashManagementDocuments which don't have Final
118      * 
119      * @param cmd submitted cash management document
120      */
121     protected void verifyCashDrawerForVerificationUnitIsOpenForPostInitiationSaves(CashManagementDocument cmd) {
122         if (cmd.getDocumentHeader() != null && cmd.getDocumentHeader().getWorkflowDocument() != null && cmd.getDocumentHeader().getWorkflowDocument() != null) {
123             if (cmd.getDocumentHeader().getWorkflowDocument().isSaved()) {
124                 // now verify that the associated cash drawer is in the appropriate state
125                 CashDrawer cd = SpringContext.getBean(CashDrawerService.class).getByCampusCode(cmd.getCampusCode());
126                 if (cd == null) {
127                     // we got the rule without having a cash drawer?  freaky...
128                     throw new RuntimeException("No cash drawer exists for campus code "+cmd.getCampusCode()+"; please create on via the Cash Drawer Maintenance Document before attemping to create a CashManagementDocument for campus "+cmd.getCampusCode());
129                 }
130                 if (!cmd.hasFinalDeposit()) {
131                     if (!cd.isOpen()) {
132                         throw new IllegalStateException("The cash drawer for verification unit \"" + cd.getCampusCode() + "\" is closed.  It should be open when a cash management document for that verification unit is open and being saved.");
133                     }
134                 }
135                 else {
136                     if (!cd.isLocked()) {
137                         throw new IllegalStateException("The cash drawer for verification unit \"" + cd.getCampusCode() + "\" is closed.  It should be open when a cash management document for that verification unit is open and being saved.");
138                     }
139                 }
140             }
141         }
142     }
143 
144 
145     /**
146      * Validates all Deposits associated with the given CashManagementDocument
147      * 
148      * @param cmd submitted cash management document
149      * @return true if all deposits in a cash management are valid
150      */
151     protected boolean validateDeposits(CashManagementDocument cmd) {
152         boolean isValid = true;
153         boolean isInitiated = cmd.getDocumentHeader().getWorkflowDocument().isInitiated();
154 
155         GlobalVariables.getMessageMap().addToErrorPath(OLEPropertyConstants.DOCUMENT);
156 
157         int index = 0;
158         for (Iterator deposits = cmd.getDeposits().iterator(); deposits.hasNext(); index++) {
159             Deposit deposit = (Deposit) deposits.next();
160 
161             GlobalVariables.getMessageMap().addToErrorPath(OLEPropertyConstants.DEPOSIT + "[" + index + "]");
162             isValid &= validateDeposit(deposit, isInitiated);
163             GlobalVariables.getMessageMap().removeFromErrorPath(OLEPropertyConstants.DEPOSIT + "[" + index + "]");
164         }
165 
166         GlobalVariables.getMessageMap().removeFromErrorPath(OLEPropertyConstants.DOCUMENT);
167 
168         return isValid;
169     }
170 
171     /**
172      * If documentIsInitiated, performs complete dataDictionary-driven validation of the given Deposit. Unconditionally validates
173      * the CashReceipts associated with the given Deposit.
174      * 
175      * @param deposit individual deposit from cash management document
176      * @param documentIsInitiated if document is initiated
177      * @return true if deposit is valid
178      */
179     protected boolean validateDeposit(Deposit deposit, boolean documentIsInitiated) {
180         boolean isValid = true;
181 
182         verifyCashReceipts(deposit, documentIsInitiated);
183 
184         if (!documentIsInitiated) {
185             isValid = performDataDictionaryValidation(deposit);
186         }
187 
188         return isValid;
189     }
190 
191 
192     private static final List INITIATED_STATES = Arrays.asList(new String[] { CashReceipt.VERIFIED });
193     private static final List UNINITIATED_STATES = Arrays.asList(new String[] { CashReceipt.INTERIM, CashReceipt.FINAL });
194 
195     /**
196      * Verifies that all CashReceipts associated with the given document are of an appropriate status for the given
197      * CashManagementDocument state
198      * 
199      * @param deposit deposit from cash management document
200      * @param documentIsInitiated if document is initiated
201      */
202     protected void verifyCashReceipts(Deposit deposit, boolean documentIsInitiated) {
203         List desiredCRStates = null;
204         if (documentIsInitiated) {
205             desiredCRStates = INITIATED_STATES;
206         }
207         else {
208             desiredCRStates = UNINITIATED_STATES;
209         }
210 
211         for (Iterator depositCashReceiptControls = deposit.getDepositCashReceiptControl().iterator(); depositCashReceiptControls.hasNext();) {
212             DepositCashReceiptControl depositCashReceiptControl = (DepositCashReceiptControl) depositCashReceiptControls.next();
213             CashReceiptDocument cashReceipt = depositCashReceiptControl.getCashReceiptDocument();
214             String crState = cashReceipt.getFinancialSystemDocumentHeader().getFinancialDocumentStatusCode();
215             if (!desiredCRStates.contains(crState)) {
216                 throw new IllegalStateException("Cash receipt document number " + cashReceipt.getDocumentNumber() + " is not in an appropriate state for the associated CashManagementDocument to be submitted.");
217             }
218         }
219     }
220 
221     /**
222      * Verifies that all verified cash receipts have been deposited
223      * 
224      * @param cmDoc the cash management document that is about to be routed
225      * @return true if there are no outstanding verified cash receipts that are not part of a deposit, false if otherwise
226      */
227     protected boolean verifyAllVerifiedCashReceiptsDeposited(CashManagementDocument cmDoc) {
228         boolean allCRsDeposited = true;
229         CashManagementService cms = SpringContext.getBean(CashManagementService.class);
230         List verifiedReceipts = SpringContext.getBean(CashReceiptService.class).getCashReceipts(cmDoc.getCampusCode(), OLEConstants.DocumentStatusCodes.CashReceipt.VERIFIED);
231         for (Object o : verifiedReceipts) {
232             if (!cms.verifyCashReceiptIsDeposited(cmDoc, (CashReceiptDocument) o)) {
233                 allCRsDeposited = false;
234                 GlobalVariables.getMessageMap().putError(OLEConstants.CASH_MANAGEMENT_DEPOSIT_ERRORS, OLEKeyConstants.CashManagement.ERROR_NON_DEPOSITED_VERIFIED_CASH_RECEIPT, new String[] { ((CashReceiptDocument) o).getDocumentNumber() });
235             }
236         }
237         return allCRsDeposited;
238     }
239 
240     /**
241      * Performs complete, recursive dataDictionary-driven validation of the given Deposit.
242      * 
243      * @param deposit deposit from cash management document
244      * @return true if deposit is validated against data dictionary entry
245      */
246     protected boolean performDataDictionaryValidation(Deposit deposit) {
247         // check for required fields
248         SpringContext.getBean(DictionaryValidationService.class).validateBusinessObject(deposit);
249 
250         // validate foreign-key relationships
251         //KFSMI-798 - refresh() changed to refreshNonUpdateableReferences()
252         //Deposit has updatable references, but for validation we do not need to refresh the updatable references. 
253         //E.g. updatable collections - they might have been set by the user and we would not want to overwrite their changes.
254         deposit.refreshNonUpdateableReferences();
255         
256         // validate bank code
257         BankCodeValidation.validate(deposit.getDepositBankCode(), OLEPropertyConstants.DEPOSIT_BANK_CODE, true, false);
258 
259         return GlobalVariables.getMessageMap().hasNoErrors();
260     }
261 
262     /**
263      * Processes the checks to validate that the application of the given cashiering transaction will be valid
264      * @see org.kuali.ole.fp.document.validation.CashManagingRule#processCashieringTransactionApplication(org.kuali.ole.fp.businessobject.CashieringTransaction)
265      */
266     public boolean processCashieringTransactionApplication(CashDrawer cashDrawer, CashieringTransaction cashieringTransaction) {
267         boolean success = true;
268         success &= checkMoneyInNoNegatives(cashieringTransaction);
269         success &= checkMoneyOutNoNegatives(cashieringTransaction);
270         success &= checkAllPaidBackItemsInProcess(cashieringTransaction);
271         success &= checkNewItemInProcessDoesNotExceedCashDrawer(cashDrawer, cashieringTransaction);
272         success &= checkNewItemInProcessInPast(cashieringTransaction);
273         success &= checkTransactionCheckTotalDoesNotExceedCashDrawer(cashDrawer, cashieringTransaction);
274         success &= checkItemInProcessIsNotPayingOffItemInProcess(cashieringTransaction);
275         if (success) {
276             success = checkEnoughCashForMoneyOut(cashDrawer, cashieringTransaction);
277         }
278         if (success) {
279             success &= checkMoneyInMoneyOutBalance(cashieringTransaction);
280         }
281         return success;
282     }
283     
284     /**
285      * Returns true if none of the entered money-in amounts (cash and coin) are not negative in a cashiering transaction
286      * 
287      * @param trans represents cashiering transaction from document
288      * @return true if none of the amounts are negative
289      */
290     public boolean checkMoneyInNoNegatives(CashieringTransaction trans) {
291         boolean success = true;
292 
293         // money in currency
294         if (trans.getMoneyInCurrency().getFinancialDocumentHundredDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentHundredDollarAmount().isNegative()) {
295             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.hundredDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getHundredDollarCount().toString(), "hundred dollar count" });
296             success = false;
297         }
298         if (trans.getMoneyInCurrency().getFinancialDocumentFiftyDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentFiftyDollarAmount().isNegative()) {
299             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.fiftyDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getFiftyDollarCount().toString(), "fifty dollar count" });
300             success = false;
301         }
302         if (trans.getMoneyInCurrency().getFinancialDocumentTwentyDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentTwentyDollarAmount().isNegative()) {
303             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.twentyDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getTwentyDollarCount().toString(), "twenty dollar count" });
304             success = false;
305         }
306         if (trans.getMoneyInCurrency().getFinancialDocumentTenDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentTenDollarAmount().isNegative()) {
307             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.tenDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getTenDollarCount().toString(), "ten dollar count" });
308             success = false;
309         }
310         if (trans.getMoneyInCurrency().getFinancialDocumentFiveDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentFiveDollarAmount().isNegative()) {
311             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.fiveDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getFiveDollarCount().toString(), "five dollar count" });
312             success = false;
313         }
314         if (trans.getMoneyInCurrency().getFinancialDocumentTwoDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentTwoDollarAmount().isNegative()) {
315             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.twoDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getTwoDollarCount().toString(), "two dollar count" });
316             success = false;
317         }
318         if (trans.getMoneyInCurrency().getFinancialDocumentOneDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentOneDollarAmount().isNegative()) {
319             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.oneDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getOneDollarCount().toString(), "one dollar count" });
320             success = false;
321         }
322         if (trans.getMoneyInCurrency().getFinancialDocumentOtherDollarAmount() != null && trans.getMoneyInCurrency().getFinancialDocumentOtherDollarAmount().isNegative()) {
323             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.financialDocumentOtherDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getFinancialDocumentOtherDollarAmount().toString(), "other dollar amount" });
324             success = false;
325         }
326 
327         // money in coin
328         if (trans.getMoneyInCoin().getFinancialDocumentHundredCentAmount() != null && trans.getMoneyInCoin().getFinancialDocumentHundredCentAmount().isNegative()) {
329             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCoin.hundredCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getHundredCentCount().toString(), "hundred cent count" });
330             success = false;
331         }
332         if (trans.getMoneyInCoin().getFinancialDocumentFiftyCentAmount() != null && trans.getMoneyInCoin().getFinancialDocumentFiftyCentAmount().isNegative()) {
333             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCoin.fiftyCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getFiftyCentCount().toString(), "fifty cent count" });
334             success = false;
335         }
336         if (trans.getMoneyInCoin().getFinancialDocumentTenCentAmount() != null && trans.getMoneyInCoin().getFinancialDocumentTenCentAmount().isNegative()) {
337             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCoin.tenCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getTenCentCount().toString(), "ten cent count" });
338             success = false;
339         }
340         if (trans.getMoneyInCoin().getFinancialDocumentTwentyFiveCentAmount() != null && trans.getMoneyInCoin().getFinancialDocumentTwentyFiveCentAmount().isNegative()) {
341             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCoin.twentyFiveCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getTwentyFiveCentCount().toString(), "twenty five cent count" });
342             success = false;
343         }
344         if (trans.getMoneyInCoin().getFinancialDocumentFiveCentAmount() != null && trans.getMoneyInCoin().getFinancialDocumentFiveCentAmount().isNegative()) {
345             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCoin.fiveCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getFiveCentCount().toString(), "five cent count" });
346             success = false;
347         }
348         if (trans.getMoneyInCoin().getFinancialDocumentOneCentAmount() != null && trans.getMoneyInCoin().getFinancialDocumentOneCentAmount().isNegative()) {
349             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCoin.oneCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getOneCentCount().toString(), "one cent count" });
350             success = false;
351         }
352         if (trans.getMoneyInCoin().getFinancialDocumentOtherCentAmount() != null && trans.getMoneyInCoin().getFinancialDocumentOtherCentAmount().isNegative()) {
353             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCoin.financialDocumentOtherCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getFinancialDocumentOtherCentAmount().toString(), "other cent amount" });
354             success = false;
355         }
356 
357         // newItemInProcess amount
358         if (trans.getNewItemInProcess() != null && trans.getNewItemInProcess().isPopulated() && trans.getNewItemInProcess().getItemAmount().isNegative()) {
359             GlobalVariables.getMessageMap().putError("document.currentTransaction.newItemInProcess.itemAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_NEW_ITEM_IN_PROCESS_NOT_NEGATIVE, new String[0]);
360             success = false;
361         }
362 
363         // checks
364         int count = 0;
365         for (Check check : trans.getMoneyInChecks()) {
366             if (check.getAmount() != null && check.getAmount().isNegative()) {
367                 GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInChecks[" + count + "].amount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CHECK_AMOUNT_NOT_NEGATIVE, new String[] { check.getAmount().toString(), check.getDescription() });
368                 success = false;
369             }
370             count += 1;
371         }
372 
373         return success;
374     }
375 
376     /**
377      * Returns true if none of the entered money-out amounts (cash and coin) are not negative in a cashiering transaction
378      * 
379      * @param trans represents cashiering transaction from document
380      * @return true if none of the amounts are negative
381      */
382     public boolean checkMoneyOutNoNegatives(CashieringTransaction trans) {
383         boolean success = true;
384 
385         // money out currency
386         if (trans.getMoneyOutCurrency().getFinancialDocumentHundredDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentHundredDollarAmount().isNegative()) {
387             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.hundredDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyOutCurrency().getHundredDollarCount().toString(), "hundred dollar count" });
388             success = false;
389         }
390         if (trans.getMoneyOutCurrency().getFinancialDocumentFiftyDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentFiftyDollarAmount().isNegative()) {
391             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.fiftyDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyOutCurrency().getFiftyDollarCount().toString(), "fifty dollar count" });
392             success = false;
393         }
394         if (trans.getMoneyOutCurrency().getFinancialDocumentTwentyDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentTwentyDollarAmount().isNegative()) {
395             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.twentyDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyOutCurrency().getTwentyDollarCount().toString(), "twenty dollar count" });
396             success = false;
397         }
398         if (trans.getMoneyOutCurrency().getFinancialDocumentTenDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentTenDollarAmount().isNegative()) {
399             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.tenDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getTenDollarCount().toString(), "ten dollar count" });
400             success = false;
401         }
402         if (trans.getMoneyOutCurrency().getFinancialDocumentFiveDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentFiveDollarAmount().isNegative()) {
403             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.fiveDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyOutCurrency().getFiveDollarCount().toString(), "five dollar count" });
404             success = false;
405         }
406         if (trans.getMoneyOutCurrency().getFinancialDocumentTwoDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentTwoDollarAmount().isNegative()) {
407             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.twoDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyOutCurrency().getTwoDollarCount().toString(), "two dollar count" });
408             success = false;
409         }
410         if (trans.getMoneyOutCurrency().getFinancialDocumentOneDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentOneDollarAmount().isNegative()) {
411             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.oneDollarCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getOneDollarCount().toString(), "one dollar count" });
412             success = false;
413         }
414         if (trans.getMoneyOutCurrency().getFinancialDocumentOtherDollarAmount() != null && trans.getMoneyOutCurrency().getFinancialDocumentOtherDollarAmount().isNegative()) {
415             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentOtherDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCurrency().getFinancialDocumentOtherDollarAmount().toString(), "other dollar amount" });
416             success = false;
417         }
418 
419         // money out coin
420         if (trans.getMoneyOutCoin().getFinancialDocumentHundredCentAmount() != null && trans.getMoneyOutCoin().getFinancialDocumentHundredCentAmount().isNegative()) {
421             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.hundredCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getHundredCentCount().toString(), "hundred cent count" });
422             success = false;
423         }
424         if (trans.getMoneyOutCoin().getFinancialDocumentFiftyCentAmount() != null && trans.getMoneyOutCoin().getFinancialDocumentFiftyCentAmount().isNegative()) {
425             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.fiftyCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getFiftyCentCount().toString(), "fifty cent count" });
426             success = false;
427         }
428         if (trans.getMoneyOutCoin().getFinancialDocumentTenCentAmount() != null && trans.getMoneyOutCoin().getFinancialDocumentTenCentAmount().isNegative()) {
429             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.tenCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getTenCentCount().toString(), "ten cent count" });
430             success = false;
431         }
432         if (trans.getMoneyOutCoin().getFinancialDocumentTwentyFiveCentAmount() != null && trans.getMoneyOutCoin().getFinancialDocumentTwentyFiveCentAmount().isNegative()) {
433             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.twentyFiveCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getTwentyFiveCentCount().toString(), "twenty five cent count" });
434             success = false;
435         }
436         if (trans.getMoneyOutCoin().getFinancialDocumentFiveCentAmount() != null && trans.getMoneyOutCoin().getFinancialDocumentFiveCentAmount().isNegative()) {
437             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.fiveCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getFiveCentCount().toString(), "five cent count" });
438             success = false;
439         }
440         if (trans.getMoneyOutCoin().getFinancialDocumentOneCentAmount() != null && trans.getMoneyOutCoin().getFinancialDocumentOneCentAmount().isNegative()) {
441             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.oneCentCount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyInCoin().getOneCentCount().toString(), "one cent count" });
442             success = false;
443         }
444         if (trans.getMoneyOutCoin().getFinancialDocumentOtherCentAmount() != null && trans.getMoneyOutCoin().getFinancialDocumentOtherCentAmount().isNegative()) {
445             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentOtherCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_NOT_NEGATIVE, new String[] { trans.getMoneyOutCoin().getFinancialDocumentOtherCentAmount().toString(), "other cent amount" });
446             success = false;
447         }
448 
449         // open items in process amounts
450         int count = 0;
451         if (trans.getOpenItemsInProcess() != null) {
452             for (CashieringItemInProcess itemInProc : trans.getOpenItemsInProcess()) {
453                 if (itemInProc.getCurrentPayment() != null && itemInProc.getCurrentPayment().isNegative()) {
454                     GlobalVariables.getMessageMap().putError("document.currentTransaction.openItemsInProcess[" + count + "].currentPayment", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_REDUCED_ITEM_IN_PROCESS_NOT_NEGATIVE, new String[] { itemInProc.getItemIdentifier().toString() });
455                     success = false;
456                 }
457                 count += 1;
458             }
459         }
460 
461         return success;
462     }
463 
464     /**
465      * Returns true if money-in and money-out are in balance with each other
466      * 
467      * @param trans represents cashiering transaction from cash management document
468      * @return true if money-in and money-out are balanced
469      */
470     public boolean checkMoneyInMoneyOutBalance(CashieringTransaction trans) {
471         boolean success = true;
472         if (!trans.getMoneyInTotal().equals(trans.getMoneyOutTotal())) {
473             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyInCurrency.financialDocumentHundredDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_IN_OUT_DO_NOT_BALANCE, new String[0]);
474             success = false;
475         }
476         return success;
477     }
478 
479     /**
480      * This method returns true if none of the coin (1 cent, 5 cents, etc) and cash increments (1 dollar, 2 dollars, 5 dollars etc. )
481      * from ( money-in + cash drawer ) exceed the amount for that increment from the money-out.
482      * 
483      * @param cmDoc represents cash management document
484      * @param trans represents cash transaction from cash management document
485      * @return true if none of the coin and cash increments from money-in + cash drawer excreed amount for increments in money-out 
486      */
487     public boolean checkEnoughCashForMoneyOut(CashDrawer cashDrawer, CashieringTransaction trans) {
488         boolean success = true;
489 
490         // money out currency
491         CurrencyDetail moneyInCurrency = trans.getMoneyInCurrency();
492         CurrencyDetail moneyOutCurrency = trans.getMoneyOutCurrency();
493 
494         KualiDecimal existingHundredDollarAmount = KualiDecimal.ZERO;
495         if (cashDrawer.getFinancialDocumentHundredDollarAmount() != null) {
496             existingHundredDollarAmount = existingHundredDollarAmount.add(cashDrawer.getFinancialDocumentHundredDollarAmount());
497         }
498         if (moneyInCurrency.getFinancialDocumentHundredDollarAmount() != null) {
499             existingHundredDollarAmount = existingHundredDollarAmount.add(moneyInCurrency.getFinancialDocumentHundredDollarAmount());
500         }
501         if (moneyOutCurrency.getFinancialDocumentHundredDollarAmount() != null && existingHundredDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentHundredDollarAmount())) {
502             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentHundredDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "hundred dollar", moneyOutCurrency.getFinancialDocumentHundredDollarAmount().toString(), cashDrawer.getFinancialDocumentHundredDollarAmount().toString() });
503             success = false;
504         }
505 
506         KualiDecimal existingOtherDollarAmount = KualiDecimal.ZERO;
507         if (cashDrawer.getFinancialDocumentOtherDollarAmount() != null) {
508             existingOtherDollarAmount = existingOtherDollarAmount.add(cashDrawer.getFinancialDocumentOtherDollarAmount());
509         }
510         if (moneyInCurrency.getFinancialDocumentOtherDollarAmount() != null) {
511             existingOtherDollarAmount = existingOtherDollarAmount.add(moneyInCurrency.getFinancialDocumentOtherDollarAmount());
512         }
513         if (moneyOutCurrency.getFinancialDocumentOtherDollarAmount() != null && existingOtherDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentOtherDollarAmount())) {
514             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentOtherDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "other dollar", moneyOutCurrency.getFinancialDocumentOtherDollarAmount().toString(), cashDrawer.getFinancialDocumentOtherDollarAmount().toString() });
515             success = false;
516         }
517 
518         KualiDecimal existingTwoDollarAmount = KualiDecimal.ZERO;
519         if (cashDrawer.getFinancialDocumentTwoDollarAmount() != null) {
520             existingTwoDollarAmount = existingTwoDollarAmount.add(cashDrawer.getFinancialDocumentTwoDollarAmount());
521         }
522         if (moneyInCurrency.getFinancialDocumentTwoDollarAmount() != null) {
523             existingTwoDollarAmount = existingTwoDollarAmount.add(moneyInCurrency.getFinancialDocumentTwoDollarAmount());
524         }
525         if (moneyOutCurrency.getFinancialDocumentTwoDollarAmount() != null && existingTwoDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentTwoDollarAmount())) {
526             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentTwoDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "two dollar", moneyOutCurrency.getFinancialDocumentTwoDollarAmount().toString(), cashDrawer.getFinancialDocumentTwoDollarAmount().toString() });
527             success = false;
528         }
529 
530         KualiDecimal existingFiftyDollarAmount = KualiDecimal.ZERO;
531         if (cashDrawer.getFinancialDocumentFiftyDollarAmount() != null) {
532             existingFiftyDollarAmount = existingFiftyDollarAmount.add(cashDrawer.getFinancialDocumentFiftyDollarAmount());
533         }
534         if (moneyInCurrency.getFinancialDocumentFiftyDollarAmount() != null) {
535             existingFiftyDollarAmount = existingFiftyDollarAmount.add(moneyInCurrency.getFinancialDocumentFiftyDollarAmount());
536         }
537         if (moneyOutCurrency.getFinancialDocumentFiftyDollarAmount() != null && existingFiftyDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentFiftyDollarAmount())) {
538             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentFiftyDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "fifty dollar", moneyOutCurrency.getFinancialDocumentFiftyDollarAmount().toString(), cashDrawer.getFinancialDocumentFiftyDollarAmount().toString() });
539             success = false;
540         }
541 
542         KualiDecimal existingTwentyDollarAmount = KualiDecimal.ZERO;
543         if (cashDrawer.getFinancialDocumentTwentyDollarAmount() != null) {
544             existingTwentyDollarAmount = existingTwentyDollarAmount.add(cashDrawer.getFinancialDocumentTwentyDollarAmount());
545         }
546         if (moneyInCurrency.getFinancialDocumentTwentyDollarAmount() != null) {
547             existingTwentyDollarAmount = existingTwentyDollarAmount.add(moneyInCurrency.getFinancialDocumentTwentyDollarAmount());
548         }
549         if (moneyOutCurrency.getFinancialDocumentTwentyDollarAmount() != null && existingTwentyDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentTwentyDollarAmount())) {
550             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentTwentyDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "twenty dollar", moneyOutCurrency.getFinancialDocumentTwentyDollarAmount().toString(), cashDrawer.getFinancialDocumentTwentyDollarAmount().toString() });
551             success = false;
552         }
553 
554         KualiDecimal existingTenDollarAmount = KualiDecimal.ZERO;
555         if (cashDrawer.getFinancialDocumentTenDollarAmount() != null) {
556             existingTenDollarAmount = existingTenDollarAmount.add(cashDrawer.getFinancialDocumentTenDollarAmount());
557         }
558         if (moneyInCurrency.getFinancialDocumentTenDollarAmount() != null) {
559             existingTenDollarAmount = existingTenDollarAmount.add(moneyInCurrency.getFinancialDocumentTenDollarAmount());
560         }
561         if (moneyOutCurrency.getFinancialDocumentTenDollarAmount() != null && existingTenDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentTenDollarAmount())) {
562             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentTenDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "ten dollar", moneyOutCurrency.getFinancialDocumentTenDollarAmount().toString(), cashDrawer.getFinancialDocumentTenDollarAmount().toString() });
563             success = false;
564         }
565 
566         KualiDecimal existingFiveDollarAmount = KualiDecimal.ZERO;
567         if (cashDrawer.getFinancialDocumentFiveDollarAmount() != null) {
568             existingFiveDollarAmount = existingFiveDollarAmount.add(cashDrawer.getFinancialDocumentFiveDollarAmount());
569         }
570         if (moneyInCurrency.getFinancialDocumentFiveDollarAmount() != null) {
571             existingFiveDollarAmount = existingFiveDollarAmount.add(moneyInCurrency.getFinancialDocumentFiveDollarAmount());
572         }
573         if (moneyOutCurrency.getFinancialDocumentFiveDollarAmount() != null && existingFiveDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentFiveDollarAmount())) {
574             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentFiveDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "five dollar", moneyOutCurrency.getFinancialDocumentFiveDollarAmount().toString(), cashDrawer.getFinancialDocumentFiveDollarAmount().toString() });
575             success = false;
576         }
577 
578         KualiDecimal existingOneDollarAmount = KualiDecimal.ZERO;
579         if (cashDrawer.getFinancialDocumentOneDollarAmount() != null) {
580             existingOneDollarAmount = existingOneDollarAmount.add(cashDrawer.getFinancialDocumentOneDollarAmount());
581         }
582         if (moneyInCurrency.getFinancialDocumentOneDollarAmount() != null) {
583             existingOneDollarAmount = existingOneDollarAmount.add(moneyInCurrency.getFinancialDocumentOneDollarAmount());
584         }
585         if (moneyOutCurrency.getFinancialDocumentOneDollarAmount() != null && existingOneDollarAmount.isLessThan(moneyOutCurrency.getFinancialDocumentOneDollarAmount())) {
586             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCurrency.financialDocumentOneDollarAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "one dollar", moneyOutCurrency.getFinancialDocumentOneDollarAmount().toString(), cashDrawer.getFinancialDocumentOneDollarAmount().toString() });
587             success = false;
588         }
589 
590         // money out coin
591         CoinDetail moneyOutCoin = trans.getMoneyOutCoin();
592         CoinDetail moneyInCoin = trans.getMoneyInCoin();
593         KualiDecimal existingHundredCentAmount = KualiDecimal.ZERO;
594         if (cashDrawer.getFinancialDocumentHundredCentAmount() != null) {
595             existingHundredCentAmount = existingHundredCentAmount.add(cashDrawer.getFinancialDocumentHundredCentAmount());
596         }
597         if (moneyInCoin.getFinancialDocumentHundredCentAmount() != null) {
598             existingHundredCentAmount = existingHundredCentAmount.add(moneyInCoin.getFinancialDocumentHundredCentAmount());
599         }
600         if (moneyOutCoin.getFinancialDocumentHundredCentAmount() != null && existingHundredCentAmount.isLessThan(moneyOutCoin.getFinancialDocumentHundredCentAmount())) {
601             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentHundredCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "hundred cent", moneyOutCoin.getFinancialDocumentHundredCentAmount().toString(), cashDrawer.getFinancialDocumentHundredCentAmount().toString() });
602             success = false;
603         }
604 
605         KualiDecimal existingOtherCentAmount = KualiDecimal.ZERO;
606         if (cashDrawer.getFinancialDocumentOtherCentAmount() != null) {
607             existingOtherCentAmount = existingOtherCentAmount.add(cashDrawer.getFinancialDocumentOtherCentAmount());
608         }
609         if (moneyInCoin.getFinancialDocumentOtherCentAmount() != null) {
610             existingOtherCentAmount = existingOtherCentAmount.add(moneyInCoin.getFinancialDocumentOtherCentAmount());
611         }
612         if (moneyOutCoin.getFinancialDocumentOtherCentAmount() != null && existingOtherCentAmount.isLessThan(moneyOutCoin.getFinancialDocumentOtherCentAmount())) {
613             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentOtherCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "other cent", moneyOutCoin.getFinancialDocumentOtherCentAmount().toString(), cashDrawer.getFinancialDocumentOtherCentAmount().toString() });
614             success = false;
615         }
616 
617         KualiDecimal existingFiftyCentAmount = KualiDecimal.ZERO;
618         if (cashDrawer.getFinancialDocumentFiftyCentAmount() != null) {
619             existingFiftyCentAmount = existingFiftyCentAmount.add(cashDrawer.getFinancialDocumentFiftyCentAmount());
620         }
621         if (moneyInCoin.getFinancialDocumentFiftyCentAmount() != null) {
622             existingFiftyCentAmount = existingFiftyCentAmount.add(moneyInCoin.getFinancialDocumentFiftyCentAmount());
623         }
624         if (moneyOutCoin.getFinancialDocumentFiftyCentAmount() != null && existingFiftyCentAmount.isLessThan(moneyOutCoin.getFinancialDocumentFiftyCentAmount())) {
625             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentFiftyCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "fifty cent", moneyOutCoin.getFinancialDocumentFiftyCentAmount().toString(), cashDrawer.getFinancialDocumentFiftyCentAmount().toString() });
626             success = false;
627         }
628 
629         KualiDecimal existingTwentyFiveCentAmount = KualiDecimal.ZERO;
630         if (cashDrawer.getFinancialDocumentTwentyFiveCentAmount() != null) {
631             existingTwentyFiveCentAmount = existingTwentyFiveCentAmount.add(cashDrawer.getFinancialDocumentTwentyFiveCentAmount());
632         }
633         if (moneyInCoin.getFinancialDocumentTwentyFiveCentAmount() != null) {
634             existingTwentyFiveCentAmount = existingTwentyFiveCentAmount.add(moneyInCoin.getFinancialDocumentTwentyFiveCentAmount());
635         }
636         if (moneyOutCoin.getFinancialDocumentTwentyFiveCentAmount() != null && existingTwentyFiveCentAmount.isLessThan(moneyOutCoin.getFinancialDocumentTwentyFiveCentAmount())) {
637             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentTwentyFiveCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "twenty five cent", moneyOutCoin.getFinancialDocumentTwentyFiveCentAmount().toString(), cashDrawer.getFinancialDocumentTwentyFiveCentAmount().toString() });
638             success = false;
639         }
640 
641         KualiDecimal existingTenCentAmount = KualiDecimal.ZERO;
642         if (cashDrawer.getFinancialDocumentTenCentAmount() != null) {
643             existingTenCentAmount = existingTenCentAmount.add(cashDrawer.getFinancialDocumentTenCentAmount());
644         }
645         if (moneyInCoin.getFinancialDocumentTenCentAmount() != null) {
646             existingTenCentAmount = existingTenCentAmount.add(moneyInCoin.getFinancialDocumentTenCentAmount());
647         }
648         if (moneyOutCoin.getFinancialDocumentTenCentAmount() != null && existingTenCentAmount.isLessThan(moneyOutCoin.getFinancialDocumentTenCentAmount())) {
649             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentTenCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "ten cent", moneyOutCoin.getFinancialDocumentTenCentAmount().toString(), cashDrawer.getFinancialDocumentTenCentAmount().toString() });
650             success = false;
651         }
652 
653         KualiDecimal existingFiveCentAmount = KualiDecimal.ZERO;
654         if (cashDrawer.getFinancialDocumentFiveCentAmount() != null) {
655             existingFiveCentAmount = existingFiveCentAmount.add(cashDrawer.getFinancialDocumentFiveCentAmount());
656         }
657         if (moneyInCoin.getFinancialDocumentFiveCentAmount() != null) {
658             existingFiveCentAmount = existingFiveCentAmount.add(moneyInCoin.getFinancialDocumentFiveCentAmount());
659         }
660         if (moneyOutCoin.getFinancialDocumentFiveCentAmount() != null && existingFiveCentAmount.isLessThan(moneyOutCoin.getFinancialDocumentFiveCentAmount())) {
661             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentFiveCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "five cent", moneyOutCoin.getFinancialDocumentFiveCentAmount().toString(), cashDrawer.getFinancialDocumentFiveCentAmount().toString() });
662             success = false;
663         }
664 
665         KualiDecimal existingOneCentAmount = KualiDecimal.ZERO;
666         if (cashDrawer.getFinancialDocumentOneCentAmount() != null) {
667             existingOneCentAmount = existingOneCentAmount.add(cashDrawer.getFinancialDocumentOneCentAmount());
668         }
669         if (moneyInCoin.getFinancialDocumentOneCentAmount() != null) {
670             existingOneCentAmount = existingOneCentAmount.add(moneyInCoin.getFinancialDocumentOneCentAmount());
671         }
672         if (moneyOutCoin.getFinancialDocumentOneCentAmount() != null && existingOneCentAmount.isLessThan(moneyOutCoin.getFinancialDocumentOneCentAmount())) {
673             GlobalVariables.getMessageMap().putError("document.currentTransaction.moneyOutCoin.financialDocumentOneCentAmount", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CASH_COUNT_EXCEEDS_DRAWER, new String[] { "one cent", moneyOutCoin.getFinancialDocumentOneCentAmount().toString(), cashDrawer.getFinancialDocumentOneCentAmount().toString() });
674             success = false;
675         }
676 
677         return success;
678     }
679 
680     /**
681      * This method returns true if the new item in process does not exceed the current amount in the cash drawer reserves
682      * 
683      * @param cmDoc submitted cash management document
684      * @param trans transaction from cash management document
685      * @return true if the new item in process does not exceed the current amount in the cash drawer reserves
686      */
687     public boolean checkNewItemInProcessDoesNotExceedCashDrawer(CashDrawer cashDrawer, CashieringTransaction trans) {
688         boolean success = true;
689 
690         if (trans.getNewItemInProcess().getItemAmount() != null && trans.getNewItemInProcess().getItemAmount().isGreaterThan(calculateTotalCashDrawerReserves(cashDrawer, trans))) {
691             GlobalVariables.getMessageMap().putError("document.currentTransaction.newItemInProcess", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_AMOUNT_EXCEEDS_DRAWER, new String[] { "new Item In Process", trans.getNewItemInProcess().getItemAmount().toString(), calculateTotalCashDrawerReserves(cashDrawer, trans).toString() });
692             success = false;
693         }
694 
695         return success;
696     }
697 
698     /**
699      * This method returns true if check total from transaction does not exceed the current amount in the cash drawer reserves 
700      * 
701      * @param cmDoc submitted cash management document
702      * @param trans transaction from cash management document
703      * @return true if check total from transaction does not exceed the current amount in the cash drawer reserves
704      */
705     public boolean checkTransactionCheckTotalDoesNotExceedCashDrawer(CashDrawer cashDrawer, CashieringTransaction trans) {
706         boolean success = true;
707 
708         if (trans.getTotalCheckAmount().isGreaterThan(calculateTotalCashDrawerReserves(cashDrawer, trans))) {
709             GlobalVariables.getMessageMap().putError("document.currentTransaction.newCheck", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_AMOUNT_EXCEEDS_DRAWER, new String[] { "given checks", trans.getTotalCheckAmount().toString(), calculateTotalCashDrawerReserves(cashDrawer, trans).toString() });
710             success = false;
711         }
712 
713         return success;
714     }
715  
716     /**
717      * This method returns true if the current payment amount for the cashiering item in process does not exceed
718      * the actual item amount for the item in process
719      * 
720      * @param itemInProc cashiering item in process
721      * @param cashieringItemNumber cashiering item number
722      * @return true if the current payment amount for the cashiering item in process does not exceed
723      *          the actual item amount for the item in process
724      */
725     public boolean checkPaidBackItemInProcessDoesNotExceedTotal(CashieringItemInProcess itemInProc, int cashieringItemNumber) {
726         boolean success = true;
727         if (itemInProc.getCurrentPayment() != null && itemInProc.getCurrentPayment().isGreaterThan(itemInProc.getItemAmount())) {
728             GlobalVariables.getMessageMap().putError(OLEConstants.CASHIERING_TRANSACTION_OPEN_ITEM_IN_PROCESS_PROPERTY + "[" + cashieringItemNumber + "]", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_AMOUNT_PAID_BACK_EXCEEDS_AMOUNT_LEFT, new String[] { itemInProc.getItemIdentifier().toString() });
729             success = false;
730         }
731         return success;
732     }
733 
734     /**
735      * This method returns true if a new item in process is populated and none of the open item in process' amounts are greater than zero.
736      * 
737      * @param cmDoc submitted cash management document
738      * @param trans transaction from cash management document
739      * @return true if a new item in process is populated and none of the open item in process' amounts are greater than zero.
740      */
741     public boolean checkItemInProcessIsNotPayingOffItemInProcess(CashieringTransaction trans) {
742         boolean success = true;
743         if (trans.getNewItemInProcess().isPopulated()) {
744             int count = 0;
745             for (CashieringItemInProcess advance : trans.getOpenItemsInProcess()) {
746                 if (advance.getCurrentPayment() != null && advance.getCurrentPayment().isGreaterThan(KualiDecimal.ZERO)) {
747                     GlobalVariables.getMessageMap().putError(OLEConstants.CASHIERING_TRANSACTION_OPEN_ITEM_IN_PROCESS_PROPERTY + "[" + count + "]", OLEKeyConstants.CashManagement.ERROR_DOCUMENT_CASHIERING_TRANSACTION_CANNOT_PAY_OFF_ADVANCE_WITH_ADVANCE, new String[] { advance.getItemIdentifier().toString() });
748                     success = false;
749                 }
750                 count += 1;
751             }
752         }
753         return success;
754     }
755 
756     /**
757      * This method returns true if all open items in process amounts do not exceed the total for each specific item's amount total
758      * 
759      * @param trans transaction from cash management document
760      * @return true if all open items in process amounts do not exceed the total for each specific item's amount total
761      */
762     public boolean checkAllPaidBackItemsInProcess(CashieringTransaction trans) {
763         boolean success = true;
764         int count = 0;
765         if (trans.getOpenItemsInProcess() != null) {
766             for (CashieringItemInProcess itemInProc : trans.getOpenItemsInProcess()) {
767                 success &= checkPaidBackItemInProcessDoesNotExceedTotal(itemInProc, count);
768                 count += 1;
769             }
770         }
771         return success;
772     }
773 
774     /**
775      * This method returns true if the current date is after all new items in process' open dates
776      * 
777      * @param trans transaction from cash management document
778      * @return true if the current date is after all new items in process' open dates
779      */
780     public boolean checkNewItemInProcessInPast(CashieringTransaction trans) {
781         boolean success = true;
782         if (trans.getNewItemInProcess().isPopulated()) {
783             if (trans.getNewItemInProcess().getItemOpenDate() != null && convertDateToDayYear(trans.getNewItemInProcess().getItemOpenDate()) > convertDateToDayYear(new Date())) {
784                 GlobalVariables.getMessageMap().putError("document.currentTransaction.newItemInProcess.itemOpenDate", OLEKeyConstants.CashManagement.ERROR_NEW_ITEM_IN_PROCESS_IN_FUTURE, new String[] {});
785                 success = false;
786             }
787         }
788         return success;
789     }
790 
791     /**
792      * This method calculates the total cash drawer reserves amount
793      * 
794      * @param cmDoc
795      * @param trans
796      * @return KualiDecimal as total from cash drawer reserves
797      */
798     protected KualiDecimal calculateTotalCashDrawerReserves(CashDrawer cashDrawer, CashieringTransaction trans) {
799         KualiDecimal reserves = new KualiDecimal(cashDrawer.getTotalAmount().bigDecimalValue());
800         reserves = reserves.add(trans.getMoneyInCurrency().getTotalAmount());
801         reserves = reserves.add(trans.getMoneyInCoin().getTotalAmount());
802         return reserves;
803     }
804 
805     /**
806      * This method returns the current day of year as an int for a specific date.
807      * 
808      * @param d date
809      * @return int as day of year
810      */
811     protected int convertDateToDayYear(Date d) {
812         Calendar cal = new GregorianCalendar();
813         cal.setTime(d);
814         return cal.get(Calendar.YEAR) * 366 + cal.get(Calendar.DAY_OF_YEAR);
815     }
816     
817 }
818