001 /* 002 * Copyright 2011 The Kuali Foundation. 003 * 004 * Licensed under the Educational Community License, Version 2.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/ecl2.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.kfs.fp.document; 017 018 import java.util.ArrayList; 019 import java.util.List; 020 021 import org.kuali.kfs.fp.businessobject.BasicFormatWithLineDescriptionAccountingLineParser; 022 import org.kuali.kfs.fp.businessobject.CreditCardDetail; 023 import org.kuali.kfs.sys.KFSConstants; 024 import org.kuali.kfs.sys.KFSKeyConstants; 025 import org.kuali.kfs.sys.KFSParameterKeyConstants; 026 import org.kuali.kfs.sys.businessobject.AccountingLineParser; 027 import org.kuali.kfs.sys.businessobject.Bank; 028 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry; 029 import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; 030 import org.kuali.kfs.sys.context.SpringContext; 031 import org.kuali.kfs.sys.document.AmountTotaling; 032 import org.kuali.kfs.sys.document.service.AccountingDocumentRuleHelperService; 033 import org.kuali.kfs.sys.service.BankService; 034 import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService; 035 import org.kuali.rice.kew.dto.DocumentRouteStatusChangeDTO; 036 import org.kuali.rice.kns.document.Copyable; 037 import org.kuali.rice.kns.rule.event.KualiDocumentEvent; 038 import org.kuali.rice.kns.rule.event.SaveDocumentEvent; 039 import org.kuali.rice.kns.service.DataDictionaryService; 040 import org.kuali.rice.kns.util.GlobalVariables; 041 import org.kuali.rice.kns.util.KualiDecimal; 042 import org.kuali.rice.kns.util.ObjectUtils; 043 import org.kuali.rice.kns.web.format.CurrencyFormatter; 044 045 /** 046 * This is the business object that represents the CreditCardReceipt document in Kuali. This is a transactional document that will 047 * eventually post transactions to the G/L. It integrates with workflow. Since a Credit Card Receipt is a one sided transactional 048 * document, only accepting funds into the university, the accounting line data will be held in the source accounting line data 049 * structure only. 050 */ 051 public class CreditCardReceiptDocument extends CashReceiptFamilyBase implements Copyable, AmountTotaling { 052 // holds details about each credit card receipt 053 protected List<CreditCardDetail> creditCardReceipts = new ArrayList<CreditCardDetail>(); 054 055 // incrementers for detail lines 056 protected Integer nextCcCrLineNumber = new Integer(1); 057 058 // monetary attributes 059 protected KualiDecimal totalCreditCardAmount = KualiDecimal.ZERO; 060 061 /** 062 * Default constructor that calls super. 063 */ 064 public CreditCardReceiptDocument() { 065 super(); 066 } 067 068 069 @Override 070 public boolean documentPerformsSufficientFundsCheck() { 071 return false; 072 } 073 074 /** 075 * Gets the total credit card amount. 076 * 077 * @return KualiDecimal 078 */ 079 public KualiDecimal getTotalCreditCardAmount() { 080 return totalCreditCardAmount; 081 } 082 083 /** 084 * This method returns the credit card total amount as a currency formatted string. 085 * 086 * @return String 087 */ 088 public String getCurrencyFormattedTotalCreditCardAmount() { 089 return (String) new CurrencyFormatter().format(totalCreditCardAmount); 090 } 091 092 /** 093 * Sets the total credit card amount which is the sum of all credit card receipts on this document. 094 * 095 * @param creditCardAmount 096 */ 097 public void setTotalCreditCardAmount(KualiDecimal creditCardAmount) { 098 this.totalCreditCardAmount = creditCardAmount; 099 } 100 101 /** 102 * Gets the list of credit card receipts which is a list of CreditCardDetail business objects. 103 * 104 * @return List 105 */ 106 public List<CreditCardDetail> getCreditCardReceipts() { 107 return creditCardReceipts; 108 } 109 110 /** 111 * Sets the credit card receipts list. 112 * 113 * @param creditCardReceipts 114 */ 115 public void setCreditCardReceipts(List<CreditCardDetail> creditCardReceipts) { 116 this.creditCardReceipts = creditCardReceipts; 117 } 118 119 /** 120 * Adds a new credit card receipt to the list. 121 * 122 * @param creditCardReceiptDetail 123 */ 124 public void addCreditCardReceipt(CreditCardDetail creditCardReceiptDetail) { 125 // these three make up the primary key for a credit card detail record 126 prepareNewCreditCardReceipt(creditCardReceiptDetail); 127 128 // add the new detail record to the list 129 this.creditCardReceipts.add(creditCardReceiptDetail); 130 131 // increment line number 132 this.nextCcCrLineNumber = new Integer(this.nextCcCrLineNumber.intValue() + 1); 133 134 // update the overall amount 135 this.totalCreditCardAmount = this.totalCreditCardAmount.add(creditCardReceiptDetail.getCreditCardAdvanceDepositAmount()); 136 } 137 138 /** 139 * This is a helper method that automatically populates document specfic information into the credit card receipt 140 * (CreditCardDetail) instance. 141 * 142 * @param creditCardReceiptDetail 143 */ 144 public final void prepareNewCreditCardReceipt(CreditCardDetail creditCardReceiptDetail) { 145 creditCardReceiptDetail.setFinancialDocumentLineNumber(this.nextCcCrLineNumber); 146 creditCardReceiptDetail.setFinancialDocumentColumnTypeCode(KFSConstants.CreditCardReceiptConstants.CASH_RECEIPT_CREDIT_CARD_RECEIPT_COLUMN_TYPE_CODE); 147 creditCardReceiptDetail.setDocumentNumber(this.getDocumentNumber()); 148 creditCardReceiptDetail.setFinancialDocumentTypeCode(SpringContext.getBean(DataDictionaryService.class).getDocumentTypeNameByClass(this.getClass())); 149 } 150 151 /** 152 * Retrieve a particular credit card receipt at a given index in the list of credit card receipts. 153 * 154 * @param index 155 * @return CreditCardReceiptDetail 156 */ 157 public CreditCardDetail getCreditCardReceipt(int index) { 158 while (this.creditCardReceipts.size() <= index) { 159 creditCardReceipts.add(new CreditCardDetail()); 160 } 161 return creditCardReceipts.get(index); 162 } 163 164 /** 165 * This method removes a credit card receipt from the list and updates the total appropriately. 166 * 167 * @param index 168 */ 169 public void removeCreditCardReceipt(int index) { 170 CreditCardDetail creditCardReceiptDetail = creditCardReceipts.remove(index); 171 this.totalCreditCardAmount = this.totalCreditCardAmount.subtract(creditCardReceiptDetail.getCreditCardAdvanceDepositAmount()); 172 } 173 174 /** 175 * @return Integer 176 */ 177 public Integer getNextCcCrLineNumber() { 178 return nextCcCrLineNumber; 179 } 180 181 /** 182 * @param nextCcCrLineNumber 183 */ 184 public void setNextCcCrLineNumber(Integer nextCcCrLineNumber) { 185 this.nextCcCrLineNumber = nextCcCrLineNumber; 186 } 187 188 /** 189 * This method returns the overall total of the document - the credit card total. 190 * 191 * @see org.kuali.kfs.sys.document.AccountingDocumentBase#getTotalDollarAmount() 192 * @return KualiDecimal 193 */ 194 @Override 195 public KualiDecimal getTotalDollarAmount() { 196 return this.totalCreditCardAmount; 197 } 198 199 /** 200 * This method returns the sum of all of the credit card receipts for this document. 201 * 202 * @return KualiDecimal 203 */ 204 public KualiDecimal calculateCreditCardReceiptTotal() { 205 KualiDecimal total = KualiDecimal.ZERO; 206 for (CreditCardDetail detail : getCreditCardReceipts()) { 207 if (null != detail.getCreditCardAdvanceDepositAmount()) { 208 total = total.add(detail.getCreditCardAdvanceDepositAmount()); 209 } 210 } 211 return total; 212 } 213 214 215 /** 216 * Overrides super to call super and then also add in the new list of credit card receipts that have to be managed. 217 * 218 * @see org.kuali.rice.kns.document.TransactionalDocumentBase#buildListOfDeletionAwareLists() 219 */ 220 @Override 221 public List buildListOfDeletionAwareLists() { 222 List managedLists = super.buildListOfDeletionAwareLists(); 223 managedLists.add(getCreditCardReceipts()); 224 225 return managedLists; 226 } 227 228 /** 229 * Generates bank offset GLPEs for deposits, if enabled. 230 * 231 * @param financialDocument submitted accounting document 232 * @param sequenceHelper helper class for keep track of sequence for GLPEs 233 * @return true if generation of GLPE's is successful for credit card receipt document 234 * 235 * @see org.kuali.rice.kns.rule.GenerateGeneralLedgerDocumentPendingEntriesRule#processGenerateDocumentGeneralLedgerPendingEntries(org.kuali.rice.kns.document.FinancialDocument,org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) 236 */ 237 @Override 238 public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { 239 boolean success = true; 240 241 GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class); 242 243 if (SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) { 244 final KualiDecimal bankOffsetAmount = glpeService.getOffsetToCashAmount(this).negated(); 245 GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry(); 246 247 Bank offsetBank = getOffsetBank(); 248 if (ObjectUtils.isNull(offsetBank)) { 249 success = false; 250 GlobalVariables.getMessageMap().putError("newCreditCardReceipt.financialDocumentCreditCardTypeCode", KFSKeyConstants.CreditCardReceipt.ERROR_DOCUMENT_CREDIT_CARD_BANK_MUST_EXIST_WHEN_BANK_ENHANCEMENT_ENABLED, new String[] { KFSParameterKeyConstants.ENABLE_BANK_SPECIFICATION_IND, KFSParameterKeyConstants.DEFAULT_BANK_BY_DOCUMENT_TYPE }); 251 } 252 else { 253 success &= glpeService.populateBankOffsetGeneralLedgerPendingEntry(offsetBank, bankOffsetAmount, this, getPostingYear(), sequenceHelper, bankOffsetEntry, KFSConstants.CREDIT_CARD_RECEIPTS_LINE_ERRORS); 254 255 // An unsuccessfully populated bank offset entry may contain invalid relations, so don't add it 256 if (success) { 257 AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class); 258 bankOffsetEntry.setTransactionLedgerEntryDescription(accountingDocumentRuleUtil.formatProperty(KFSKeyConstants.Bank.DESCRIPTION_GLPE_BANK_OFFSET)); 259 getGeneralLedgerPendingEntries().add(bankOffsetEntry); 260 sequenceHelper.increment(); 261 262 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(bankOffsetEntry); 263 success &= glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), bankOffsetEntry, sequenceHelper, offsetEntry); 264 getGeneralLedgerPendingEntries().add(offsetEntry); 265 sequenceHelper.increment(); 266 } 267 } 268 } 269 270 return success; 271 } 272 273 /** 274 * Returns the default bank code for Credit Card Receipt documents. 275 */ 276 protected Bank getOffsetBank() { 277 return SpringContext.getBean(BankService.class).getDefaultBankByDocType(this.getClass()); 278 } 279 280 @Override 281 public void postProcessSave(KualiDocumentEvent event) { 282 super.postProcessSave(event); 283 if (!(event instanceof SaveDocumentEvent)) { // don't lock until they route 284 String documentTypeName = SpringContext.getBean(DataDictionaryService.class).getDocumentTypeNameByClass(this.getClass()); 285 this.getCapitalAssetManagementModuleService().generateCapitalAssetLock(this,documentTypeName); 286 } 287 } 288 289 @Override 290 public void doRouteStatusChange(DocumentRouteStatusChangeDTO statusChangeEvent) { 291 super.doRouteStatusChange(statusChangeEvent); 292 this.getCapitalAssetManagementModuleService().deleteDocumentAssetLocks(this); 293 } 294 }