001/* 002 * Copyright 2006 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 017package org.kuali.ole.fp.document; 018 019import java.util.ArrayList; 020import java.util.Iterator; 021import java.util.List; 022 023import org.kuali.ole.fp.businessobject.ProcurementCardHolder; 024import org.kuali.ole.fp.businessobject.ProcurementCardSourceAccountingLine; 025import org.kuali.ole.fp.businessobject.ProcurementCardTargetAccountingLine; 026import org.kuali.ole.fp.businessobject.ProcurementCardTransactionDetail; 027import org.kuali.ole.integration.cam.CapitalAssetManagementModuleService; 028import org.kuali.ole.sys.businessobject.AccountingLine; 029import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntrySourceDetail; 030import org.kuali.ole.sys.businessobject.SourceAccountingLine; 031import org.kuali.ole.sys.businessobject.TargetAccountingLine; 032import org.kuali.ole.sys.context.SpringContext; 033import org.kuali.ole.sys.document.AmountTotaling; 034import org.kuali.ole.sys.document.service.DebitDeterminerService; 035import org.kuali.rice.kew.api.KewApiConstants; 036import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange; 037import org.kuali.rice.kns.service.DataDictionaryService; 038import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent; 039import org.kuali.rice.krad.rules.rule.event.SaveDocumentEvent; 040 041/** 042 * This is the Procurement Card Document Class. The procurement cards distributes expenses from clearing accounts. It is a two-sided 043 * document, but only target lines are displayed because source lines cannot be changed. Transaction, Card, and Vendor information 044 * are associated with the document to help better distribute the expense. 045 */ 046public class ProcurementCardDocument extends CapitalAccountingLinesDocumentBase implements AmountTotaling, CapitalAssetEditable { 047 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(ProcurementCardDocument.class); 048 049 protected ProcurementCardHolder procurementCardHolder; 050 051 protected List transactionEntries; 052 protected ProcurementCardTargetAccountingLine newTargetLine; 053 protected transient CapitalAssetManagementModuleService capitalAssetManagementModuleService; 054 055 /** 056 * Default constructor. 057 */ 058 public ProcurementCardDocument() { 059 super(); 060 transactionEntries = new ArrayList<ProcurementCardTransactionDetail>(); 061 } 062 063 /** 064 * @return Returns the transactionEntries. 065 */ 066 public List getTransactionEntries() { 067 return transactionEntries; 068 } 069 070 /** 071 * @param transactionEntries The transactionEntries to set. 072 */ 073 public void setTransactionEntries(List transactionEntries) { 074 this.transactionEntries = transactionEntries; 075 } 076 077 /** 078 * Gets the procurementCardHolder attribute. 079 * 080 * @return Returns the procurementCardHolder. 081 */ 082 public ProcurementCardHolder getProcurementCardHolder() { 083 return procurementCardHolder; 084 } 085 086 /** 087 * Sets the procurementCardHolder attribute value. 088 * 089 * @param procurementCardHolder The procurementCardHolder to set. 090 */ 091 public void setProcurementCardHolder(ProcurementCardHolder procurementCardHolder) { 092 this.procurementCardHolder = procurementCardHolder; 093 } 094 095 /** 096 * Removes the target accounting line at the given index from the transaction detail entry. 097 * 098 * @param index 099 */ 100 public void removeTargetAccountingLine(int index) { 101 ProcurementCardTargetAccountingLine line = (ProcurementCardTargetAccountingLine) getTargetAccountingLines().get(index); 102 103 for (Iterator iter = transactionEntries.iterator(); iter.hasNext();) { 104 ProcurementCardTransactionDetail transactionEntry = (ProcurementCardTransactionDetail) iter.next(); 105 if (transactionEntry.getFinancialDocumentTransactionLineNumber().equals(line.getFinancialDocumentTransactionLineNumber())) { 106 transactionEntry.getTargetAccountingLines().remove(line); 107 } 108 } 109 } 110 111 /** 112 * Override to set the accounting line in the transaction detail object. 113 * 114 * @see org.kuali.ole.sys.document.AccountingDocument#addSourceAccountingLine(SourceAccountingLine) 115 */ 116 117 public void addSourceAccountingLine(SourceAccountingLine sourceLine) { 118 ProcurementCardSourceAccountingLine line = (ProcurementCardSourceAccountingLine) sourceLine; 119 120 line.setSequenceNumber(this.getNextSourceLineNumber()); 121 122 for (Iterator iter = transactionEntries.iterator(); iter.hasNext();) { 123 ProcurementCardTransactionDetail transactionEntry = (ProcurementCardTransactionDetail) iter.next(); 124 if (transactionEntry.getFinancialDocumentTransactionLineNumber().equals(line.getFinancialDocumentTransactionLineNumber())) { 125 transactionEntry.getSourceAccountingLines().add(line); 126 } 127 } 128 129 this.nextSourceLineNumber = new Integer(this.getNextSourceLineNumber().intValue() + 1); 130 } 131 132 /** 133 * Override to set the accounting line in the transaction detail object. 134 * 135 * @see org.kuali.ole.sys.document.AccountingDocument#addTargetAccountingLine(TargetAccountingLine) 136 */ 137 @Override 138 public void addTargetAccountingLine(TargetAccountingLine targetLine) { 139 ProcurementCardTargetAccountingLine line = (ProcurementCardTargetAccountingLine) targetLine; 140 141 line.setSequenceNumber(this.getNextTargetLineNumber()); 142 143 for (Iterator iter = transactionEntries.iterator(); iter.hasNext();) { 144 ProcurementCardTransactionDetail transactionEntry = (ProcurementCardTransactionDetail) iter.next(); 145 if (transactionEntry.getFinancialDocumentTransactionLineNumber().equals(line.getFinancialDocumentTransactionLineNumber())) { 146 transactionEntry.getTargetAccountingLines().add(line); 147 } 148 } 149 150 this.nextTargetLineNumber = new Integer(this.getNextTargetLineNumber().intValue() + 1); 151 } 152 153 /** 154 * Override to get source accounting lines out of transactions 155 * 156 * @see org.kuali.ole.sys.document.AccountingDocument#getSourceAccountingLines() 157 */ 158 @Override 159 public List getSourceAccountingLines() { 160 List sourceAccountingLines = new ArrayList(); 161 162 for (Iterator iter = transactionEntries.iterator(); iter.hasNext();) { 163 ProcurementCardTransactionDetail transactionEntry = (ProcurementCardTransactionDetail) iter.next(); 164 for (Iterator iterator = transactionEntry.getSourceAccountingLines().iterator(); iterator.hasNext();) { 165 SourceAccountingLine sourceLine = (SourceAccountingLine) iterator.next(); 166 sourceAccountingLines.add(sourceLine); 167 } 168 } 169 170 return sourceAccountingLines; 171 } 172 173 /** 174 * Override to get target accounting lines out of transactions 175 * 176 * @see org.kuali.ole.sys.document.AccountingDocument#getTargetAccountingLines() 177 */ 178 @Override 179 public List getTargetAccountingLines() { 180 List targetAccountingLines = new ArrayList(); 181 182 for (Iterator iter = transactionEntries.iterator(); iter.hasNext();) { 183 ProcurementCardTransactionDetail transactionEntry = (ProcurementCardTransactionDetail) iter.next(); 184 for (Iterator iterator = transactionEntry.getTargetAccountingLines().iterator(); iterator.hasNext();) { 185 TargetAccountingLine targetLine = (TargetAccountingLine) iterator.next(); 186 targetAccountingLines.add(targetLine); 187 } 188 } 189 190 return targetAccountingLines; 191 } 192 193 /** 194 * @see org.kuali.ole.sys.document.AccountingDocumentBase#getSourceAccountingLineClass() 195 */ 196 @Override 197 public Class getSourceAccountingLineClass() { 198 return ProcurementCardSourceAccountingLine.class; 199 } 200 201 /** 202 * @see org.kuali.ole.sys.document.AccountingDocumentBase#getTargetAccountingLineClass() 203 */ 204 @Override 205 public Class getTargetAccountingLineClass() { 206 return ProcurementCardTargetAccountingLine.class; 207 } 208 209 @Override 210 public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) { 211 super.doRouteStatusChange(statusChangeEvent); 212 213 // Updating for rice-1.0.0 api changes. doRouteStatusChange() went away, so 214 // that functionality needs to be a part of doRouteStatusChange now. 215 // handleRouteStatusChange did not happen on a save 216 if (!KewApiConstants.ACTION_TAKEN_SAVED_CD.equals(statusChangeEvent.getDocumentEventCode())) { 217 this.getCapitalAssetManagementModuleService().deleteDocumentAssetLocks(this); 218 } 219 } 220 221 /** 222 * On procurement card documents, positive source amounts are credits, negative source amounts are debits. 223 * 224 * @param transactionalDocument The document the accounting line being checked is located in. 225 * @param accountingLine The accounting line being analyzed. 226 * @return True if the accounting line given is a debit accounting line, false otherwise. 227 * @throws Throws an IllegalStateException if one of the following rules are violated: the accounting line amount is zero or the 228 * accounting line is not an expense or income accounting line. 229 * @see org.kuali.module.financial.rules.FinancialDocumentRuleBase#isDebit(FinancialDocument, 230 * org.kuali.rice.krad.bo.AccountingLine) 231 * @see org.kuali.ole.sys.document.validation.impl.AccountingDocumentRuleBase.IsDebitUtils#isDebitConsideringSection(AccountingDocumentRuleBase, 232 * AccountingDocument, AccountingLine) 233 */ 234 public boolean isDebit(GeneralLedgerPendingEntrySourceDetail postable) throws IllegalStateException { 235 // disallow error correction 236 DebitDeterminerService isDebitUtils = SpringContext.getBean(DebitDeterminerService.class); 237 isDebitUtils.disallowErrorCorrectionDocumentCheck(this); 238 return isDebitUtils.isDebitConsideringSection(this, (AccountingLine) postable); 239 } 240 241 /** 242 * @see org.kuali.rice.krad.document.DocumentBase#postProcessSave(org.kuali.rice.krad.rule.event.KualiDocumentEvent) 243 */ 244 @Override 245 public void postProcessSave(KualiDocumentEvent event) { 246 super.postProcessSave(event); 247 if (!(event instanceof SaveDocumentEvent)) { // don't lock until they route 248 String documentTypeName = SpringContext.getBean(DataDictionaryService.class).getDocumentTypeNameByClass(this.getClass()); 249 this.getCapitalAssetManagementModuleService().generateCapitalAssetLock(this, documentTypeName); 250 } 251 } 252 253 /** 254 * @return CapitalAssetManagementModuleService 255 */ 256 protected CapitalAssetManagementModuleService getCapitalAssetManagementModuleService() { 257 if (capitalAssetManagementModuleService == null) { 258 capitalAssetManagementModuleService = SpringContext.getBean(CapitalAssetManagementModuleService.class); 259 } 260 return capitalAssetManagementModuleService; 261 } 262 263}