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;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  
21  import org.kuali.ole.fp.businessobject.AdvanceDepositDetail;
22  import org.kuali.ole.sys.OLEConstants;
23  import org.kuali.ole.sys.OLEKeyConstants;
24  import org.kuali.ole.sys.OLEPropertyConstants;
25  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry;
26  import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
27  import org.kuali.ole.sys.context.SpringContext;
28  import org.kuali.ole.sys.document.AmountTotaling;
29  import org.kuali.ole.sys.document.service.AccountingDocumentRuleHelperService;
30  import org.kuali.ole.sys.service.BankService;
31  import org.kuali.ole.sys.service.ElectronicPaymentClaimingService;
32  import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService;
33  import org.kuali.rice.core.api.util.type.KualiDecimal;
34  import org.kuali.rice.core.web.format.CurrencyFormatter;
35  import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
36  import org.kuali.rice.kns.service.DataDictionaryService;
37  import org.kuali.rice.krad.document.Copyable;
38  import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent;
39  import org.kuali.rice.krad.rules.rule.event.SaveDocumentEvent;
40  
41  /**
42   * This is the business object that represents the AdvanceDeposit document in Kuali. This is a transactional document that will
43   * eventually post transactions to the G/L. It integrates with workflow. Since an Advance Deposit document is a one sided
44   * transactional document, only accepting funds into the university, the accounting line data will be held in the source accounting
45   * line data structure only.
46   */
47  public class AdvanceDepositDocument extends CashReceiptFamilyBase implements Copyable, AmountTotaling {
48      public static final String ADVANCE_DEPOSIT_DOCUMENT_TYPE_CODE = "OLE_AD";
49      
50      // holds details about each advance deposit
51      protected List<AdvanceDepositDetail> advanceDeposits = new ArrayList<AdvanceDepositDetail>();
52  
53      // incrementers for detail lines
54      protected Integer nextAdvanceDepositLineNumber = 1;
55  
56      // monetary attributes
57      protected KualiDecimal totalAdvanceDepositAmount = KualiDecimal.ZERO;
58  
59      /**
60       * Default constructor that calls super.
61       */
62      public AdvanceDepositDocument() {
63          super();
64      }
65  
66      /**
67       * Gets the total advance deposit amount.
68       * 
69       * @return KualiDecimal
70       */
71      public KualiDecimal getTotalAdvanceDepositAmount() {
72          return totalAdvanceDepositAmount;
73      }
74  
75      /**
76       * This method returns the advance deposit total amount as a currency formatted string.
77       * 
78       * @return String
79       */
80      public String getCurrencyFormattedTotalAdvanceDepositAmount() {
81          return (String) new CurrencyFormatter().format(totalAdvanceDepositAmount);
82      }
83  
84      /**
85       * Sets the total advance deposit amount which is the sum of all advance deposits on this document.
86       * 
87       * @param advanceDepositAmount
88       */
89      public void setTotalAdvanceDepositAmount(KualiDecimal advanceDepositAmount) {
90          this.totalAdvanceDepositAmount = advanceDepositAmount;
91      }
92  
93      /**
94       * Gets the list of advance deposits which is a list of AdvanceDepositDetail business objects.
95       * 
96       * @return List
97       */
98      public List<AdvanceDepositDetail> getAdvanceDeposits() {
99          return advanceDeposits;
100     }
101 
102     /**
103      * Sets the advance deposits list.
104      * 
105      * @param advanceDeposits
106      */
107     public void setAdvanceDeposits(List<AdvanceDepositDetail> advanceDeposits) {
108         this.advanceDeposits = advanceDeposits;
109     }
110 
111     /**
112      * Adds a new advance deposit to the list.
113      * 
114      * @param advanceDepositDetail
115      */
116     public void addAdvanceDeposit(AdvanceDepositDetail advanceDepositDetail) {
117         // these three make up the primary key for an advance deposit detail record
118         prepareNewAdvanceDeposit(advanceDepositDetail);
119 
120         // add the new detail record to the list
121         this.advanceDeposits.add(advanceDepositDetail);
122 
123         // increment line number
124         this.nextAdvanceDepositLineNumber++;
125 
126         // update the overall amount
127         this.totalAdvanceDepositAmount = this.totalAdvanceDepositAmount.add(advanceDepositDetail.getFinancialDocumentAdvanceDepositAmount());
128     }
129 
130     /**
131      * This is a helper method that automatically populates document specfic information into the advance deposit
132      * (AdvanceDepositDetail) instance.
133      * 
134      * @param advanceDepositDetail
135      */
136     public final void prepareNewAdvanceDeposit(AdvanceDepositDetail advanceDepositDetail) {
137         advanceDepositDetail.setFinancialDocumentLineNumber(this.nextAdvanceDepositLineNumber);
138         advanceDepositDetail.setDocumentNumber(this.getDocumentNumber());
139         advanceDepositDetail.setFinancialDocumentTypeCode(SpringContext.getBean(DataDictionaryService.class).getDocumentTypeNameByClass(this.getClass()));
140     }
141 
142     /**
143      * Retrieve a particular advance deposit at a given index in the list of advance deposits.
144      * 
145      * @param index
146      * @return AdvanceDepositDetail
147      */
148     public AdvanceDepositDetail getAdvanceDepositDetail(int index) {
149         while (this.advanceDeposits.size() <= index) {
150             advanceDeposits.add(new AdvanceDepositDetail());
151         }
152         return advanceDeposits.get(index);
153     }
154 
155     /**
156      * This method removes an advance deposit from the list and updates the total appropriately.
157      * 
158      * @param index
159      */
160     public void removeAdvanceDeposit(int index) {
161         AdvanceDepositDetail advanceDepositDetail = advanceDeposits.remove(index);
162         this.totalAdvanceDepositAmount = this.totalAdvanceDepositAmount.subtract(advanceDepositDetail.getFinancialDocumentAdvanceDepositAmount());
163     }
164 
165     /**
166      * @return Integer
167      */
168     public Integer getNextAdvanceDepositLineNumber() {
169         return nextAdvanceDepositLineNumber;
170     }
171 
172     /**
173      * @param nextAdvanceDepositLineNumber
174      */
175     public void setNextAdvanceDepositLineNumber(Integer nextAdvanceDepositLineNumber) {
176         this.nextAdvanceDepositLineNumber = nextAdvanceDepositLineNumber;
177     }
178 
179     /**
180      * This method returns the overall total of the document - the advance deposit total.
181      * 
182      * @see org.kuali.ole.sys.document.AccountingDocumentBase#getTotalDollarAmount()
183      * @return KualiDecimal
184      */
185     @Override
186     public KualiDecimal getTotalDollarAmount() {
187         return this.totalAdvanceDepositAmount;
188     }
189 
190     /**
191      * This method defers to its parent's version of handleRouteStatusChange, but then, if the document is processed, it creates
192      * ElectronicPaymentClaim records for any qualifying accountings lines in the document.
193      * 
194      * @see org.kuali.ole.sys.document.GeneralLedgerPostingDocumentBase#doRouteStatusChange()
195      */
196     @Override
197     public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
198         super.doRouteStatusChange(statusChangeEvent);
199         if (getDocumentHeader().getWorkflowDocument().isProcessed()) {
200             SpringContext.getBean(ElectronicPaymentClaimingService.class).generateElectronicPaymentClaimRecords(this);
201         }
202         this.getCapitalAssetManagementModuleService().deleteDocumentAssetLocks(this); 
203     }
204 
205 
206     /**
207      * Overrides super to call super and then also add in the new list of advance deposits that have to be managed.
208      * 
209      * @see org.kuali.rice.krad.document.TransactionalDocumentBase#buildListOfDeletionAwareLists()
210      */
211     @Override
212     public List buildListOfDeletionAwareLists() {
213         List managedLists = super.buildListOfDeletionAwareLists();
214         managedLists.add(getAdvanceDeposits());
215 
216         return managedLists;
217     }
218 
219     /**
220      * Generates bank offset GLPEs for deposits, if enabled.
221      * 
222      * @param financialDocument submitted financial document
223      * @param sequenceHelper helper class which will allows us to increment a reference without using an Integer
224      * @return true if there are no issues creating GLPE's
225      * @see org.kuali.rice.krad.rule.GenerateGeneralLedgerDocumentPendingEntriesRule#processGenerateDocumentGeneralLedgerPendingEntries(org.kuali.rice.krad.document.FinancialDocument,org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper)
226      */
227     @Override
228     public boolean generateDocumentGeneralLedgerPendingEntries(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
229         boolean success = true;
230 
231         GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class);
232 
233         if (SpringContext.getBean(BankService.class).isBankSpecificationEnabled()) {
234             int displayedDepositNumber = 1;
235             for (AdvanceDepositDetail detail : getAdvanceDeposits()) {
236                 detail.refreshReferenceObject(OLEPropertyConstants.BANK);
237 
238                 GeneralLedgerPendingEntry bankOffsetEntry = new GeneralLedgerPendingEntry();
239                 if (!glpeService.populateBankOffsetGeneralLedgerPendingEntry(detail.getBank(), detail.getFinancialDocumentAdvanceDepositAmount(), this, getPostingYear(), sequenceHelper, bankOffsetEntry, OLEConstants.ADVANCE_DEPOSITS_LINE_ERRORS)) {
240                     success = false;
241                     continue; // An unsuccessfully populated bank offset entry may contain invalid relations, so don't add it
242                 }
243 
244                 AccountingDocumentRuleHelperService accountingDocumentRuleUtil = SpringContext.getBean(AccountingDocumentRuleHelperService.class);
245                 bankOffsetEntry.setTransactionLedgerEntryDescription(accountingDocumentRuleUtil.formatProperty(OLEKeyConstants.AdvanceDeposit.DESCRIPTION_GLPE_BANK_OFFSET, displayedDepositNumber++));
246                 addPendingEntry(bankOffsetEntry);
247                 sequenceHelper.increment();
248 
249                 GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(bankOffsetEntry);
250                 success &= glpeService.populateOffsetGeneralLedgerPendingEntry(getPostingYear(), bankOffsetEntry, sequenceHelper, offsetEntry);
251                 addPendingEntry(offsetEntry);
252                 sequenceHelper.increment();
253             }
254         }
255 
256         return success;
257     }
258 
259     @Override
260     public void postProcessSave(KualiDocumentEvent event) {
261         super.postProcessSave(event);
262         if (!(event instanceof SaveDocumentEvent)) { // don't lock until they route
263             String documentTypeName = SpringContext.getBean(DataDictionaryService.class).getDocumentTypeNameByClass(this.getClass());
264             this.getCapitalAssetManagementModuleService().generateCapitalAssetLock(this,documentTypeName);
265         }        
266     }
267 }