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    }