001/* 002 * Copyright 2007 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 */ 016package org.kuali.ole.sys.document; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import org.apache.commons.lang.StringUtils; 022import org.kuali.ole.gl.service.SufficientFundsService; 023import org.kuali.ole.sys.OLEConstants; 024import org.kuali.ole.sys.OLEKeyConstants; 025import org.kuali.ole.sys.businessobject.GeneralLedgerPendingEntry; 026import org.kuali.ole.sys.businessobject.SufficientFundsItem; 027import org.kuali.ole.sys.context.SpringContext; 028import org.kuali.ole.sys.service.GeneralLedgerPendingEntryService; 029import org.kuali.rice.kew.api.exception.WorkflowException; 030import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange; 031import org.kuali.rice.krad.exception.ValidationException; 032import org.kuali.rice.krad.rules.rule.event.ApproveDocumentEvent; 033import org.kuali.rice.krad.rules.rule.event.KualiDocumentEvent; 034import org.kuali.rice.krad.rules.rule.event.RouteDocumentEvent; 035import org.kuali.rice.krad.util.GlobalVariables; 036 037/** 038 * Base implementation for a general ledger posting document. 039 */ 040public class GeneralLedgerPostingDocumentBase extends LedgerPostingDocumentBase implements GeneralLedgerPostingDocument { 041 protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(GeneralLedgerPostingDocumentBase.class); 042 043 protected List<GeneralLedgerPendingEntry> generalLedgerPendingEntries; 044 045 /** 046 * Default constructor. 047 */ 048 public GeneralLedgerPostingDocumentBase() { 049 super(); 050 setGeneralLedgerPendingEntries(new ArrayList<GeneralLedgerPendingEntry>()); 051 } 052 053 /** 054 * @see org.kuali.ole.sys.document.GeneralLedgerPostingDocument#getGeneralLedgerPendingEntries() 055 */ 056 public List<GeneralLedgerPendingEntry> getGeneralLedgerPendingEntries() { 057 return generalLedgerPendingEntries; 058 } 059 060 /** 061 * @see org.kuali.ole.sys.document.GeneralLedgerPostingDocument#getGeneralLedgerPendingEntry(int) 062 */ 063 public GeneralLedgerPendingEntry getGeneralLedgerPendingEntry(int index) { 064 while (generalLedgerPendingEntries.size() <= index) { 065 generalLedgerPendingEntries.add(new GeneralLedgerPendingEntry()); 066 } 067 return generalLedgerPendingEntries.get(index); 068 } 069 070 /** 071 * @see org.kuali.ole.sys.document.GeneralLedgerPostingDocument#setGeneralLedgerPendingEntries(java.util.List) 072 */ 073 public void setGeneralLedgerPendingEntries(List<GeneralLedgerPendingEntry> generalLedgerPendingEntries) { 074 this.generalLedgerPendingEntries = generalLedgerPendingEntries; 075 } 076 077 /** 078 * @see org.kuali.ole.sys.document.GeneralLedgerPostingDocument#checkSufficientFunds() 079 */ 080 public List<SufficientFundsItem> checkSufficientFunds() { 081 LOG.debug("checkSufficientFunds() started"); 082 083 if (documentPerformsSufficientFundsCheck()) { 084 SufficientFundsService sufficientFundsService = SpringContext.getBean(SufficientFundsService.class); 085 return sufficientFundsService.checkSufficientFunds(this); 086 } 087 else { 088 return new ArrayList<SufficientFundsItem>(); 089 } 090 } 091 092 /** 093 * This method checks to see if SF checking should be done for this document. This was originally part of 094 * SufficientFundsService.checkSufficientFunds() but was externalized so documents that need to override any of the SF methods 095 * can still explicitly check this 096 * 097 * @return 098 */ 099 public boolean documentPerformsSufficientFundsCheck() { 100 // check for reversing entries generated by an error correction. 101 return StringUtils.isBlank(this.getFinancialSystemDocumentHeader().getFinancialDocumentInErrorNumber()); 102 } 103 104 /** 105 * @see org.kuali.ole.sys.document.GeneralLedgerPostingDocument#getPendingLedgerEntriesForSufficientFundsChecking() 106 */ 107 public List<GeneralLedgerPendingEntry> getPendingLedgerEntriesForSufficientFundsChecking() { 108 return getGeneralLedgerPendingEntries(); 109 } 110 111 /** 112 * Override to call super and then iterate over all GLPEs and update the approved code appropriately. 113 * 114 * @see Document#doRouteStatusChange() 115 */ 116 @Override 117 public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) { 118 super.doRouteStatusChange(statusChangeEvent); 119 if (getDocumentHeader().getWorkflowDocument().isProcessed()) { 120 changeGeneralLedgerPendingEntriesApprovedStatusCode(); // update all glpes for doc and set their status to approved 121 } 122 else if (getDocumentHeader().getWorkflowDocument().isCanceled() || getDocumentHeader().getWorkflowDocument().isDisapproved()) { 123 removeGeneralLedgerPendingEntries(); 124 if (this instanceof ElectronicPaymentClaiming) { 125 ((ElectronicPaymentClaiming)this).declaimElectronicPaymentClaims(); 126 } 127 } 128 } 129 130 /** 131 * This method iterates over all of the GLPEs for a document and sets their approved status code to APPROVED "A". 132 */ 133 protected void changeGeneralLedgerPendingEntriesApprovedStatusCode() { 134 for (GeneralLedgerPendingEntry glpe : getGeneralLedgerPendingEntries()) { 135 glpe.setFinancialDocumentApprovedCode(OLEConstants.DocumentStatusCodes.APPROVED); 136 } 137 } 138 139 /** 140 * This method calls the service to remove all of the GLPE's associated with this document 141 */ 142 protected void removeGeneralLedgerPendingEntries() { 143 GeneralLedgerPendingEntryService glpeService = SpringContext.getBean(GeneralLedgerPendingEntryService.class); 144 glpeService.delete(getDocumentHeader().getDocumentNumber()); 145 } 146 147 /** 148 * @see org.kuali.rice.krad.document.DocumentBase#toCopy() 149 */ 150 @Override 151 public void toCopy() throws WorkflowException { 152 super.toCopy(); 153 getGeneralLedgerPendingEntries().clear(); 154 } 155 156 /** 157 * @see org.kuali.rice.krad.document.TransactionalDocumentBase#toErrorCorrection() 158 */ 159 @Override 160 public void toErrorCorrection() throws WorkflowException { 161 super.toErrorCorrection(); 162 getGeneralLedgerPendingEntries().clear(); 163 } 164 165 @Override 166 public void prepareForSave(KualiDocumentEvent event) { 167 super.prepareForSave(event); 168 // TODO - add OLE wrappers of Rice Events to list 169 if (event instanceof RouteDocumentEvent || event instanceof ApproveDocumentEvent) { 170 // generate general ledger pending entries should be called prior to sufficient funds checking 171 List<SufficientFundsItem> sfItems = checkSufficientFunds(); 172 if (!sfItems.isEmpty()) { 173 for (SufficientFundsItem sfItem : sfItems) { 174 GlobalVariables.getMessageMap().putError(OLEConstants.ACCOUNTING_LINE_ERRORS, OLEKeyConstants.SufficientFunds.ERROR_INSUFFICIENT_FUNDS, new String[] { sfItem.getAccount().getChartOfAccountsCode(), sfItem.getAccount().getAccountNumber(), StringUtils.isNotBlank(sfItem.getSufficientFundsObjectCode()) ? sfItem.getSufficientFundsObjectCode() : OLEConstants.NOT_AVAILABLE_STRING, sfItem.getAccountSufficientFundsCode() }); 175 } 176 throw new ValidationException("Insufficient Funds on this Document:"); 177 } 178 } 179 } 180 181 /** 182 * Adds a GeneralLedgerPendingEntry to this document's list of pending entries 183 * @param pendingEntry a pending entry to add 184 */ 185 public void addPendingEntry(GeneralLedgerPendingEntry pendingEntry) { 186 pendingEntry.refreshReferenceObject("financialObject"); 187 generalLedgerPendingEntries.add(pendingEntry); 188 } 189 190 /** 191 * This resets this document's list of general ledger pending etnries, though it does not delete those entries (however, the GeneralLedgerPendingEntryService will in most cases when this method is called). 192 */ 193 public void clearAnyGeneralLedgerPendingEntries() { 194 generalLedgerPendingEntries = new ArrayList<GeneralLedgerPendingEntry>(); 195 } 196}