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.Iterator;
020    import java.util.List;
021    
022    import org.kuali.kfs.fp.businessobject.CapitalAssetInformation;
023    import org.kuali.kfs.fp.businessobject.InternalBillingItem;
024    import org.kuali.kfs.integration.cam.CapitalAssetManagementModuleService;
025    import org.kuali.kfs.sys.KFSConstants;
026    import org.kuali.kfs.sys.businessobject.AccountingLine;
027    import org.kuali.kfs.sys.businessobject.AccountingLineParser;
028    import org.kuali.kfs.sys.businessobject.AccountingLineParserBase;
029    import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
030    import org.kuali.kfs.sys.context.SpringContext;
031    import org.kuali.kfs.sys.document.AccountingDocumentBase;
032    import org.kuali.kfs.sys.document.AmountTotaling;
033    import org.kuali.kfs.sys.document.Correctable;
034    import org.kuali.kfs.sys.document.service.DebitDeterminerService;
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.KualiDecimal;
041    import org.kuali.rice.kns.util.ObjectUtils;
042    
043    
044    /**
045     * This is the business object that represents the InternalBillingDocument in Kuali. This is a transactional document that will
046     * eventually post transactions to the G/L. It integrates with workflow and also contains two groupings of accounting lines: Expense
047     * and Income.
048     */
049    public class InternalBillingDocument extends AccountingDocumentBase implements Copyable, Correctable, AmountTotaling, CapitalAssetEditable {
050    
051        protected List items;
052        protected Integer nextItemLineNumber;
053    
054        protected transient CapitalAssetInformation capitalAssetInformation;
055        protected transient CapitalAssetManagementModuleService capitalAssetManagementModuleService;
056    
057        /**
058         * Initializes the array lists and some basic info.
059         */
060        public InternalBillingDocument() {
061            super();
062            setItems(new ArrayList());
063            this.nextItemLineNumber = new Integer(1);
064        }
065    
066        /**
067         * Adds a new item to the item list.
068         * 
069         * @param item
070         */
071        public void addItem(InternalBillingItem item) {
072            item.setItemSequenceId(this.nextItemLineNumber);
073            this.items.add(item);
074            this.nextItemLineNumber = new Integer(this.nextItemLineNumber.intValue() + 1);
075        }
076    
077        /**
078         * Retrieve a particular item at a given index in the list of items. For Struts, the requested item and any intervening ones are
079         * initialized if necessary.
080         * 
081         * @param index
082         * @return the item
083         */
084        public InternalBillingItem getItem(int index) {
085            while (getItems().size() <= index) {
086                getItems().add(new InternalBillingItem());
087            }
088            return (InternalBillingItem) getItems().get(index);
089        }
090    
091        /**
092         * @return Returns the items.
093         */
094        public List getItems() {
095            return items;
096        }
097    
098        /**
099         * Allows items (in addition to accounting lines) to be deleted from the database after being saved there.
100         * 
101         * @see org.kuali.rice.kns.document.TransactionalDocumentBase#buildListOfDeletionAwareLists()
102         */
103        @Override
104        public List buildListOfDeletionAwareLists() {
105            List managedLists = super.buildListOfDeletionAwareLists();
106            managedLists.add(getItems());
107            if (ObjectUtils.isNotNull(capitalAssetInformation) && ObjectUtils.isNotNull(capitalAssetInformation.getCapitalAssetInformationDetails())) {
108                managedLists.add(capitalAssetInformation.getCapitalAssetInformationDetails());
109            }
110            return managedLists;
111        }
112    
113        /**
114         * Iterates through the list of items and sums up their totals.
115         * 
116         * @return the total
117         */
118        public KualiDecimal getItemTotal() {
119            KualiDecimal total = KualiDecimal.ZERO;
120            for (Iterator iterator = items.iterator(); iterator.hasNext();) {
121                total = total.add(((InternalBillingItem) iterator.next()).getTotal());
122            }
123            return total;
124        }
125    
126        /**
127         * Retrieves the next item line number.
128         * 
129         * @return The next available item line number
130         */
131        public Integer getNextItemLineNumber() {
132            return this.nextItemLineNumber;
133        }
134    
135        /**
136         * @param items
137         */
138        public void setItems(List items) {
139            this.items = items;
140        }
141    
142        /**
143         * Setter for OJB to get from database and JSP to maintain state in hidden fields. This property is also incremented by the
144         * <code>addItem</code> method.
145         * 
146         * @param nextItemLineNumber
147         */
148        public void setNextItemLineNumber(Integer nextItemLineNumber) {
149            this.nextItemLineNumber = nextItemLineNumber;
150        }
151    
152        /**
153         * @return "Income"
154         */
155        @Override
156        public String getSourceAccountingLinesSectionTitle() {
157            return KFSConstants.INCOME;
158        }
159    
160        /**
161         * @return "Expense"
162         */
163        @Override
164        public String getTargetAccountingLinesSectionTitle() {
165            return KFSConstants.EXPENSE;
166        }
167    
168        /**
169         * This method determines if an accounting line is a debit accounting line by calling IsDebitUtils.isDebitConsideringSection().
170         * 
171         * @param transactionalDocument The document containing the accounting line being analyzed.
172         * @param accountingLine The accounting line being reviewed to determine if it is a debit line or not.
173         * @return True if the accounting line is a debit accounting line, false otherwise.
174         * @see IsDebitUtils#isDebitConsideringSection(FinancialDocumentRuleBase, FinancialDocument, AccountingLine)
175         * @see org.kuali.rice.kns.rule.AccountingLineRule#isDebit(org.kuali.rice.kns.document.FinancialDocument,
176         *      org.kuali.rice.kns.bo.AccountingLine)
177         */
178        public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) {
179            DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class);
180            return isDebitUtils.isDebitConsideringSection(this, (AccountingLine) postable);
181        }
182    
183        /**
184         * Gets the capitalAssetInformation attribute.
185         * 
186         * @return Returns the capitalAssetInformation.
187         */
188        public CapitalAssetInformation getCapitalAssetInformation() {
189            return ObjectUtils.isNull(capitalAssetInformation) ? null : capitalAssetInformation;
190        }
191    
192        /**
193         * Sets the capitalAssetInformation attribute value.
194         * 
195         * @param capitalAssetInformation The capitalAssetInformation to set.
196         */
197        @Deprecated
198        public void setCapitalAssetInformation(CapitalAssetInformation capitalAssetInformation) {
199            this.capitalAssetInformation = capitalAssetInformation;
200        }
201    
202    
203        /**
204         * @see org.kuali.kfs.sys.document.GeneralLedgerPostingDocumentBase#doRouteStatusChange()
205         */
206        @Override
207        public void doRouteStatusChange(DocumentRouteStatusChangeDTO statusChangeEvent) {
208            super.doRouteStatusChange(statusChangeEvent);
209            this.getCapitalAssetManagementModuleService().deleteDocumentAssetLocks(this);
210        }
211    
212    
213        /**
214         * @see org.kuali.rice.kns.document.DocumentBase#postProcessSave(org.kuali.rice.kns.rule.event.KualiDocumentEvent)
215         */
216        @Override
217        public void postProcessSave(KualiDocumentEvent event) {
218            super.postProcessSave(event);
219            if (!(event instanceof SaveDocumentEvent)) { // don't lock until they route
220                String documentTypeName = SpringContext.getBean(DataDictionaryService.class).getDocumentTypeNameByClass(this.getClass());
221                this.getCapitalAssetManagementModuleService().generateCapitalAssetLock(this, documentTypeName);
222            }
223        }
224    
225    
226        /**
227         * @return CapitalAssetManagementModuleService
228         */
229        CapitalAssetManagementModuleService getCapitalAssetManagementModuleService() {
230            if (capitalAssetManagementModuleService == null) {
231                capitalAssetManagementModuleService = SpringContext.getBean(CapitalAssetManagementModuleService.class);
232            }
233            return capitalAssetManagementModuleService;
234        }
235    }