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 */ 016package org.kuali.ole.gl.batch.service.impl; 017 018import java.util.Date; 019 020import org.kuali.ole.gl.GeneralLedgerConstants; 021import org.kuali.ole.gl.batch.service.AccountingCycleCachingService; 022import org.kuali.ole.gl.batch.service.PostTransaction; 023import org.kuali.ole.gl.businessobject.SufficientFundBalances; 024import org.kuali.ole.gl.businessobject.Transaction; 025import org.kuali.ole.sys.OLEConstants; 026import org.kuali.ole.sys.service.ReportWriterService; 027import org.kuali.rice.core.api.util.type.KualiDecimal; 028import org.kuali.rice.krad.service.PersistenceStructureService; 029import org.kuali.rice.krad.util.ObjectUtils; 030import org.springframework.transaction.annotation.Transactional; 031 032/** 033 * An implementation of PostTransaction which posts a transaction to the appropriate sufficient funds record 034 */ 035@Transactional 036public class PostSufficientFundBalances implements PostTransaction { 037 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PostSufficientFundBalances.class); 038 039 private AccountingCycleCachingService accountingCycleCachingService; 040 private PersistenceStructureService persistenceStructureService; 041 042 /** 043 * Constructs a PostSufficientFundBalances instance 044 */ 045 public PostSufficientFundBalances() { 046 super(); 047 } 048 049 /** 050 * Posts the transaction to the appropriate sufficient funds records 051 * 052 * @param t the transaction which is being posted 053 * @param mode the mode the poster is currently running in 054 * @param postDate the date this transaction should post to 055 * @param posterReportWriterService the writer service where the poster is writing its report 056 * @return the accomplished post type 057 * @see org.kuali.ole.gl.batch.service.PostTransaction#post(org.kuali.ole.gl.businessobject.Transaction, int, java.util.Date) 058 */ 059 public String post(Transaction t, int mode, Date postDate, ReportWriterService posterReportWriterService) { 060 LOG.debug("post() started"); 061 062 String returnCode = GeneralLedgerConstants.UPDATE_CODE; 063 064 if (OLEConstants.SF_TYPE_NO_CHECKING.equals(t.getAccount().getAccountSufficientFundsCode())) { 065 // Don't need to post 066 return GeneralLedgerConstants.EMPTY_CODE; 067 } 068 069 // Get the Sufficient funds code 070 // Sufficient Funds Code 071 String sufficientFundsObjectCode = null; 072 if (OLEConstants.SF_TYPE_OBJECT.equals(t.getAccount().getAccountSufficientFundsCode())) { 073 sufficientFundsObjectCode = t.getFinancialObjectCode(); 074 } 075 else if (OLEConstants.SF_TYPE_LEVEL.equals(t.getAccount().getAccountSufficientFundsCode())) { 076 if (ObjectUtils.isNull(t.getFinancialObject())) { 077 return "E:Could not find sufficient funds object code for " + t.toString(); 078 } 079 sufficientFundsObjectCode = t.getFinancialObject().getFinancialObjectLevelCode(); 080 } 081 else if (OLEConstants.SF_TYPE_CONSOLIDATION.equals(t.getAccount().getAccountSufficientFundsCode())) { 082 //sufficientFundsObjectCode = t.getFinancialObject().getFinancialObjectLevel().getFinancialConsolidationObjectCode(); 083 if (ObjectUtils.isNull(t.getFinancialObject())) { 084 return "E:Could not find sufficient funds object code for " + t.toString(); 085 } 086 sufficientFundsObjectCode = accountingCycleCachingService.getObjectLevel(t.getFinancialObject().getChartOfAccountsCode(), t.getFinancialObject().getFinancialObjectLevelCode()).getFinancialConsolidationObjectCode(); 087 } 088 else if (OLEConstants.SF_TYPE_CASH_AT_ACCOUNT.equals(t.getAccount().getAccountSufficientFundsCode()) || OLEConstants.SF_TYPE_ACCOUNT.equals(t.getAccount().getAccountSufficientFundsCode())) { 089 sufficientFundsObjectCode = GeneralLedgerConstants.getSpaceFinancialObjectCode(); 090 } 091 else { 092 return "E:Invalid sufficient funds code (" + t.getAccount().getAccountSufficientFundsCode() + ")"; 093 } 094 095 // Look to see if there is a sufficient funds record for this 096 SufficientFundBalances sfBalance = accountingCycleCachingService.getSufficientFundBalances(t.getUniversityFiscalYear(), t.getChartOfAccountsCode(), t.getAccountNumber(), sufficientFundsObjectCode); 097 if (sfBalance == null) { 098 returnCode = GeneralLedgerConstants.INSERT_CODE; 099 sfBalance = new SufficientFundBalances(); 100 sfBalance.setUniversityFiscalYear(t.getUniversityFiscalYear()); 101 sfBalance.setChartOfAccountsCode(t.getChartOfAccountsCode()); 102 sfBalance.setAccountNumber(t.getAccountNumber()); 103 sfBalance.setFinancialObjectCode(sufficientFundsObjectCode); 104 sfBalance.setAccountActualExpenditureAmt(KualiDecimal.ZERO); 105 sfBalance.setAccountEncumbranceAmount(KualiDecimal.ZERO); 106 sfBalance.setCurrentBudgetBalanceAmount(KualiDecimal.ZERO); 107 sfBalance.setAccountSufficientFundsCode(t.getAccount().getAccountSufficientFundsCode()); 108 } 109 110 if (OLEConstants.SF_TYPE_CASH_AT_ACCOUNT.equals(t.getAccount().getAccountSufficientFundsCode())) { 111 // 2640-PROCESS-CASH 112 if (t.getFinancialBalanceTypeCode().equals(t.getOption().getActualFinancialBalanceTypeCd())) { 113 if (t.getFinancialObjectCode().equals(t.getChart().getFinancialCashObjectCode()) || t.getFinancialObjectCode().equals(t.getChart().getFinAccountsPayableObjectCode())) { 114 // 2641-PROCESS-CASH-ACTUAL 115 updateBudgetAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount()); 116 } 117 else { 118 // No need to post this 119 return GeneralLedgerConstants.EMPTY_CODE; 120 } 121 } 122 else if (t.getFinancialBalanceTypeCode().equals(t.getOption().getExtrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getIntrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getPreencumbranceFinBalTypeCd()) || t.getOption().getCostShareEncumbranceBalanceTypeCd().equals(t.getFinancialBalanceTypeCode())) { 123 if (t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpenditureexpCd()) || t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpendNotExpCode()) || t.getOption().getFinancialObjectTypeTransferExpenseCd().equals(t.getFinancialObjectTypeCode()) || t.getOption().getFinObjTypeExpNotExpendCode().equals(t.getFinancialObjectTypeCode())) { 124 // 2462-PROCESS-CASH-ENCUMBRANCE 125 updateEncumbranceAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount()); 126 } 127 else { 128 // No need to post this 129 return GeneralLedgerConstants.EMPTY_CODE; 130 } 131 } 132 else { 133 // No need to post this 134 return GeneralLedgerConstants.EMPTY_CODE; 135 } 136 } 137 else { 138 // 2630-PROCESS-OBJECT-OR-ACCOUNT 139 if (t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpenditureexpCd()) || t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjTypeExpendNotExpCode()) || t.getOption().getFinancialObjectTypeTransferExpenseCd().equals(t.getFinancialObjectTypeCode()) || t.getOption().getFinObjTypeExpNotExpendCode().equals(t.getFinancialObjectTypeCode())) { 140 if (t.getFinancialBalanceTypeCode().equals(t.getOption().getActualFinancialBalanceTypeCd())) { 141 // 2631-PROCESS-OBJTACCT-ACTUAL 142 updateExpendedAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount()); 143 } 144 else if (t.getFinancialBalanceTypeCode().equals(t.getOption().getExtrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getIntrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getPreencumbranceFinBalTypeCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getCostShareEncumbranceBalanceTypeCd())) { 145 // 2632-PROCESS-OBJTACCT-ENCMBRNC 146 updateEncumbranceAmount(t.getTransactionDebitCreditCode(), sfBalance, t.getTransactionLedgerEntryAmount()); 147 } 148 else if (t.getFinancialBalanceTypeCode().equals(t.getOption().getBudgetCheckingBalanceTypeCd())) { 149 sfBalance.setCurrentBudgetBalanceAmount(sfBalance.getCurrentBudgetBalanceAmount().add(t.getTransactionLedgerEntryAmount())); 150 } 151 else { 152 // No need to post this 153 return GeneralLedgerConstants.EMPTY_CODE; 154 } 155 } 156 else { 157 // No need to post this 158 return GeneralLedgerConstants.EMPTY_CODE; 159 } 160 } 161 162 // If we get here, we need to save the balance entry 163 if (returnCode.equals(GeneralLedgerConstants.INSERT_CODE)) { 164 accountingCycleCachingService.insertSufficientFundBalances(sfBalance); 165 } else { 166 accountingCycleCachingService.updateSufficientFundBalances(sfBalance); 167 } 168 169 170 return returnCode; 171 } 172 173 /** 174 * Updates the expenditure amount of a given sufficient funds balance record 175 * 176 * @param debitCreditCode whether the the amount should be debited or credited to the SF balance 177 * @param bal a sufficient funds balance to update 178 * @param amount the amount to debit or credit 179 */ 180 protected void updateExpendedAmount(String debitCreditCode, SufficientFundBalances bal, KualiDecimal amount) { 181 if (OLEConstants.GL_CREDIT_CODE.equals(debitCreditCode)) { 182 bal.setAccountActualExpenditureAmt(bal.getAccountActualExpenditureAmt().subtract(amount)); 183 } 184 else if (OLEConstants.GL_DEBIT_CODE.equals(debitCreditCode) || OLEConstants.GL_BUDGET_CODE.equals(debitCreditCode)) { 185 bal.setAccountActualExpenditureAmt(bal.getAccountActualExpenditureAmt().add(amount)); 186 } 187 } 188 189 /** 190 * Updates the encumbrance amount of a given sufficient funds balance record 191 * 192 * @param debitCreditCode whether the the amount should be debited or credited to the SF balance 193 * @param bal a sufficient funds balance to update 194 * @param amount the amount to debit or credit 195 */ 196 protected void updateEncumbranceAmount(String debitCreditCode, SufficientFundBalances bal, KualiDecimal amount) { 197 if (OLEConstants.GL_CREDIT_CODE.equals(debitCreditCode)) { 198 bal.setAccountEncumbranceAmount(bal.getAccountEncumbranceAmount().subtract(amount)); 199 } 200 else if (OLEConstants.GL_DEBIT_CODE.equals(debitCreditCode) || OLEConstants.GL_BUDGET_CODE.equals(debitCreditCode)) { 201 bal.setAccountEncumbranceAmount(bal.getAccountEncumbranceAmount().add(amount)); 202 } 203 } 204 205 /** 206 * Updates the budget amount of a given sufficient funds balance record 207 * 208 * @param debitCreditCode whether the the amount should be debited or credited to the SF balance 209 * @param bal a sufficient funds balance to update 210 * @param amount the amount to debit or credit 211 */ 212 protected void updateBudgetAmount(String debitCreditCode, SufficientFundBalances bal, KualiDecimal amount) { 213 if (OLEConstants.GL_CREDIT_CODE.equals(debitCreditCode)) { 214 bal.setCurrentBudgetBalanceAmount(bal.getCurrentBudgetBalanceAmount().subtract(amount)); 215 } 216 else if (OLEConstants.GL_DEBIT_CODE.equals(debitCreditCode) || OLEConstants.GL_BUDGET_CODE.equals(debitCreditCode)) { 217 bal.setCurrentBudgetBalanceAmount(bal.getCurrentBudgetBalanceAmount().add(amount)); 218 } 219 } 220 221 /** 222 * @see org.kuali.ole.gl.batch.service.PostTransaction#getDestinationName() 223 */ 224 public String getDestinationName() { 225 return persistenceStructureService.getTableName(SufficientFundBalances.class); 226 } 227 228 public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) { 229 this.accountingCycleCachingService = accountingCycleCachingService; 230 } 231 232 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) { 233 this.persistenceStructureService = persistenceStructureService; 234 } 235}