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 }