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.gl.batch.service.impl; 017 018 import java.util.Collection; 019 import java.util.Date; 020 import java.util.Iterator; 021 022 import org.apache.commons.lang.ArrayUtils; 023 import org.apache.commons.lang.StringUtils; 024 import org.kuali.kfs.gl.GeneralLedgerConstants; 025 import org.kuali.kfs.gl.batch.PosterEntriesStep; 026 import org.kuali.kfs.gl.batch.ScrubberStep; 027 import org.kuali.kfs.gl.batch.service.AccountingCycleCachingService; 028 import org.kuali.kfs.gl.batch.service.EncumbranceCalculator; 029 import org.kuali.kfs.gl.batch.service.PostTransaction; 030 import org.kuali.kfs.gl.businessobject.Encumbrance; 031 import org.kuali.kfs.gl.businessobject.Entry; 032 import org.kuali.kfs.gl.businessobject.Transaction; 033 import org.kuali.kfs.sys.KFSConstants; 034 import org.kuali.kfs.sys.service.ReportWriterService; 035 import org.kuali.rice.kns.service.DateTimeService; 036 import org.kuali.rice.kns.service.ParameterService; 037 import org.kuali.rice.kns.service.PersistenceStructureService; 038 import org.springframework.transaction.annotation.Transactional; 039 040 /** 041 * This implementation of PostTransaction posts a transaction that could be an encumbrance 042 */ 043 @Transactional 044 public class PostEncumbrance implements PostTransaction, EncumbranceCalculator { 045 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PostEncumbrance.class); 046 047 private AccountingCycleCachingService accountingCycleCachingService; 048 private DateTimeService dateTimeService; 049 private PersistenceStructureService persistenceStructureService; 050 private ParameterService parameterService; 051 052 /** 053 * Constructs a PostEncumbrance instance 054 */ 055 public PostEncumbrance() { 056 super(); 057 } 058 059 /** 060 * Called by the poster to post a transaction. The transaction might or might not be an encumbrance transaction. 061 * 062 * @param t the transaction which is being posted 063 * @param mode the mode the poster is currently running in 064 * @param postDate the date this transaction should post to 065 * @param posterReportWriterService the writer service where the poster is writing its report 066 * @return the accomplished post type 067 */ 068 public String post(Transaction t, int mode, Date postDate, ReportWriterService posterReportWriterService) { 069 LOG.debug("post() started"); 070 071 String returnCode = GeneralLedgerConstants.UPDATE_CODE; 072 073 // If the encumbrance update code is space or N, or the object type code is FB 074 // we don't need to post an encumbrance 075 if ((StringUtils.isBlank(t.getTransactionEncumbranceUpdateCode())) || " ".equals(t.getTransactionEncumbranceUpdateCode()) || KFSConstants.ENCUMB_UPDT_NO_ENCUMBRANCE_CD.equals(t.getTransactionEncumbranceUpdateCode()) || t.getOption().getFinObjectTypeFundBalanceCd().equals(t.getFinancialObjectTypeCode())) { 076 LOG.debug("post() not posting non-encumbrance transaction"); 077 return ""; 078 } 079 080 // Get the current encumbrance record if there is one 081 Entry e = new Entry(t, null); 082 if (KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD.equals(t.getTransactionEncumbranceUpdateCode())) { 083 e.setDocumentNumber(t.getReferenceFinancialDocumentNumber()); 084 e.setFinancialSystemOriginationCode(t.getReferenceFinancialSystemOriginationCode()); 085 e.setFinancialDocumentTypeCode(t.getReferenceFinancialDocumentTypeCode()); 086 } 087 088 Encumbrance enc = accountingCycleCachingService.getEncumbrance(e); 089 if (enc == null) { 090 // Build a new encumbrance record 091 enc = new Encumbrance(e); 092 093 returnCode = GeneralLedgerConstants.INSERT_CODE; 094 } 095 else { 096 // Use the one retrieved 097 if (enc.getTransactionEncumbranceDate() == null) { 098 enc.setTransactionEncumbranceDate(t.getTransactionDate()); 099 } 100 101 returnCode = GeneralLedgerConstants.UPDATE_CODE; 102 } 103 104 updateEncumbrance(t, enc); 105 106 if (returnCode.equals(GeneralLedgerConstants.INSERT_CODE)) { 107 accountingCycleCachingService.insertEncumbrance(enc); 108 } else { 109 accountingCycleCachingService.updateEncumbrance(enc); 110 } 111 112 return returnCode; 113 } 114 115 /** 116 * Given a Collection of encumbrances, returns the encumbrance that would affected by the given transaction 117 * 118 * @param encumbranceList a Collection of encumbrances 119 * @param t the transaction to find the appropriate encumbrance for 120 * @return the encumbrance found from the list, or, if not found, a newly created encumbrance 121 * @see org.kuali.kfs.gl.batch.service.EncumbranceCalculator#findEncumbrance(java.util.Collection, org.kuali.kfs.gl.businessobject.Transaction) 122 */ 123 public Encumbrance findEncumbrance(Collection encumbranceList, Transaction t) { 124 125 // If it isn't an encumbrance transaction, skip it 126 if ((!KFSConstants.ENCUMB_UPDT_DOCUMENT_CD.equals(t.getTransactionEncumbranceUpdateCode())) && (!KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD.equals(t.getTransactionEncumbranceUpdateCode()))) { 127 return null; 128 } 129 130 // Try to find one that already exists 131 for (Iterator iter = encumbranceList.iterator(); iter.hasNext();) { 132 Encumbrance e = (Encumbrance) iter.next(); 133 134 if (KFSConstants.ENCUMB_UPDT_DOCUMENT_CD.equals(t.getTransactionEncumbranceUpdateCode()) && e.getUniversityFiscalYear().equals(t.getUniversityFiscalYear()) && e.getChartOfAccountsCode().equals(t.getChartOfAccountsCode()) && e.getAccountNumber().equals(t.getAccountNumber()) && e.getSubAccountNumber().equals(t.getSubAccountNumber()) && e.getObjectCode().equals(t.getFinancialObjectCode()) && e.getSubObjectCode().equals(t.getFinancialSubObjectCode()) && e.getBalanceTypeCode().equals(t.getFinancialBalanceTypeCode()) && e.getDocumentTypeCode().equals(t.getFinancialDocumentTypeCode()) && e.getOriginCode().equals(t.getFinancialSystemOriginationCode()) && e.getDocumentNumber().equals(t.getDocumentNumber())) { 135 return e; 136 } 137 138 if (KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD.equals(t.getTransactionEncumbranceUpdateCode()) && e.getUniversityFiscalYear().equals(t.getUniversityFiscalYear()) && e.getChartOfAccountsCode().equals(t.getChartOfAccountsCode()) && e.getAccountNumber().equals(t.getAccountNumber()) && e.getSubAccountNumber().equals(t.getSubAccountNumber()) && e.getObjectCode().equals(t.getFinancialObjectCode()) && e.getSubObjectCode().equals(t.getFinancialSubObjectCode()) && e.getBalanceTypeCode().equals(t.getFinancialBalanceTypeCode()) && e.getDocumentTypeCode().equals(t.getReferenceFinancialDocumentTypeCode()) && e.getOriginCode().equals(t.getReferenceFinancialSystemOriginationCode()) && e.getDocumentNumber().equals(t.getReferenceFinancialDocumentNumber())) { 139 return e; 140 } 141 } 142 143 // If we couldn't find one that exists, create a new one 144 145 // NOTE: the date doesn't matter so there is no need to call the date service 146 // Changed to use the datetime service because of KULRNE-4183 147 Entry e = new Entry(t, dateTimeService.getCurrentDate()); 148 if (KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD.equals(t.getTransactionEncumbranceUpdateCode())) { 149 e.setDocumentNumber(t.getReferenceFinancialDocumentNumber()); 150 e.setFinancialSystemOriginationCode(t.getReferenceFinancialSystemOriginationCode()); 151 e.setFinancialDocumentTypeCode(t.getReferenceFinancialDocumentTypeCode()); 152 } 153 154 Encumbrance enc = new Encumbrance(e); 155 encumbranceList.add(enc); 156 return enc; 157 } 158 159 /** 160 * @param t 161 * @param enc 162 */ 163 public void updateEncumbrance(Transaction t, Encumbrance enc) { 164 //KFSMI-1571 - check parameter encumbranceOpenAmountOeverridingDocTypes 165 String[] encumbranceOpenAmountOeverridingDocTypes = parameterService.getParameterValues(PosterEntriesStep.class, GeneralLedgerConstants.PosterService.ENCUMBRANCE_OPEN_AMOUNT_OVERRIDING_DOCUMENT_TYPES).toArray(new String[] {}); 166 167 if (KFSConstants.ENCUMB_UPDT_REFERENCE_DOCUMENT_CD.equals(t.getTransactionEncumbranceUpdateCode()) && !ArrayUtils.contains(encumbranceOpenAmountOeverridingDocTypes, t.getFinancialDocumentTypeCode())) { 168 // If using referring doc number, add or subtract transaction amount from 169 // encumbrance closed amount 170 if (KFSConstants.GL_DEBIT_CODE.equals(t.getTransactionDebitCreditCode())) { 171 enc.setAccountLineEncumbranceClosedAmount(enc.getAccountLineEncumbranceClosedAmount().subtract(t.getTransactionLedgerEntryAmount())); 172 } 173 else { 174 enc.setAccountLineEncumbranceClosedAmount(enc.getAccountLineEncumbranceClosedAmount().add(t.getTransactionLedgerEntryAmount())); 175 } 176 } 177 else { 178 // If not using referring doc number, add or subtract transaction amount from 179 // encumbrance amount 180 if (KFSConstants.GL_DEBIT_CODE.equals(t.getTransactionDebitCreditCode()) || KFSConstants.GL_BUDGET_CODE.equals(t.getTransactionDebitCreditCode())) { 181 enc.setAccountLineEncumbranceAmount(enc.getAccountLineEncumbranceAmount().add(t.getTransactionLedgerEntryAmount())); 182 } 183 else { 184 enc.setAccountLineEncumbranceAmount(enc.getAccountLineEncumbranceAmount().subtract(t.getTransactionLedgerEntryAmount())); 185 } 186 } 187 } 188 189 /** 190 * @see org.kuali.kfs.gl.batch.service.PostTransaction#getDestinationName() 191 */ 192 public String getDestinationName() { 193 return persistenceStructureService.getTableName(Encumbrance.class); 194 } 195 196 197 public void setDateTimeService(DateTimeService dateTimeService) { 198 this.dateTimeService = dateTimeService; 199 } 200 201 public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) { 202 this.accountingCycleCachingService = accountingCycleCachingService; 203 } 204 205 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) { 206 this.persistenceStructureService = persistenceStructureService; 207 } 208 209 public void setParameterService(ParameterService parameterService) { 210 this.parameterService = parameterService; 211 } 212 }