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}