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 }