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.kuali.kfs.gl.batch.service.AccountingCycleCachingService; 023 import org.kuali.kfs.gl.batch.service.BalanceCalculator; 024 import org.kuali.kfs.gl.batch.service.PostTransaction; 025 import org.kuali.kfs.gl.businessobject.Balance; 026 import org.kuali.kfs.gl.businessobject.Transaction; 027 import org.kuali.kfs.gl.dataaccess.BalanceDao; 028 import org.kuali.kfs.sys.businessobject.UniversityDate; 029 import org.kuali.kfs.sys.context.SpringContext; 030 import org.kuali.kfs.sys.service.ReportWriterService; 031 import org.kuali.kfs.sys.service.UniversityDateService; 032 import org.kuali.rice.kns.util.KualiDecimal; 033 import org.springframework.transaction.annotation.Transactional; 034 035 /** 036 * This implementation of PostTransaction updates the appropriate Balance 037 */ 038 @Transactional 039 public class PostBalance implements PostTransaction, BalanceCalculator { 040 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PostBalance.class); 041 042 private AccountingCycleCachingService accountingCycleCachingService; 043 private static final KualiDecimal NEGATIVE_ONE = new KualiDecimal(-1); 044 /** 045 * Constructs a PostBalance instance 046 */ 047 public PostBalance() { 048 super(); 049 } 050 051 /** 052 * This posts the effect of the transaction upon the appropriate balance record. 053 * 054 * @param t the transaction which is being posted 055 * @param mode the mode the poster is currently running in 056 * @param postDate the date this transaction should post to 057 * @param posterReportWriterService the writer service where the poster is writing its report 058 * @return the accomplished post type 059 * @see org.kuali.kfs.gl.batch.service.PostTransaction#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) 060 */ 061 public String post(Transaction t, int mode, Date postDate, ReportWriterService posterReportWriterService) { 062 LOG.debug("post() started"); 063 064 String postType = "U"; 065 066 KualiDecimal amount = t.getTransactionLedgerEntryAmount(); 067 068 // Subtract the amount if offset generation indicator & the debit/credit code isn't the same 069 // as the one in the object type code table 070 if (t.getBalanceType().isFinancialOffsetGenerationIndicator()) { 071 if (!t.getTransactionDebitCreditCode().equals(t.getObjectType().getFinObjectTypeDebitcreditCd())) { 072 amount = amount.multiply(NEGATIVE_ONE); 073 } 074 } 075 076 Balance b = accountingCycleCachingService.getBalance(t); 077 if (b == null) { 078 postType = "I"; 079 b = new Balance(t); 080 } 081 String period = t.getUniversityFiscalPeriodCode(); 082 b.addAmount(period, amount); 083 084 if (postType.equals("I")) { 085 accountingCycleCachingService.insertBalance(b); 086 } else { 087 accountingCycleCachingService.updateBalance(b); 088 } 089 090 return postType; 091 } 092 093 /** 094 * Given a list of balances, determines which one the given trsnaction should post to 095 * 096 * @param balanceList a Collection of balances 097 * @param t the transaction that is being posted 098 * @return the balance, either found from the list, or, if not present in the list, newly created 099 * @see org.kuali.kfs.gl.batch.service.BalanceCalculator#findBalance(java.util.Collection, org.kuali.kfs.gl.businessobject.Transaction) 100 */ 101 public Balance findBalance(Collection balanceList, Transaction t) { 102 // Try to find one that already exists 103 for (Iterator iter = balanceList.iterator(); iter.hasNext();) { 104 Balance b = (Balance) iter.next(); 105 106 if (b.getUniversityFiscalYear().equals(t.getUniversityFiscalYear()) && b.getChartOfAccountsCode().equals(t.getChartOfAccountsCode()) && b.getAccountNumber().equals(t.getAccountNumber()) && b.getSubAccountNumber().equals(t.getSubAccountNumber()) && b.getObjectCode().equals(t.getFinancialObjectCode()) && b.getSubObjectCode().equals(t.getFinancialSubObjectCode()) && b.getBalanceTypeCode().equals(t.getFinancialBalanceTypeCode()) && b.getObjectTypeCode().equals(t.getFinancialObjectTypeCode())) { 107 return b; 108 } 109 } 110 111 // If we couldn't find one that exists, create a new one 112 Balance b = new Balance(t); 113 balanceList.add(b); 114 115 return b; 116 } 117 118 /** 119 * @param t 120 * @param enc 121 */ 122 public void updateBalance(Transaction t, Balance b) { 123 124 // The pending entries haven't been scrubbed so there could be 125 // bad data. This won't update a balance if the data it needs 126 // is invalid 127 KualiDecimal amount = t.getTransactionLedgerEntryAmount(); 128 if (amount == null) { 129 amount = KualiDecimal.ZERO; 130 } 131 132 if (t.getObjectType() == null) { 133 LOG.error("updateBalance() Invalid object type (" + t.getFinancialObjectTypeCode() + ") in pending table"); 134 return; 135 } 136 137 if (t.getBalanceType() == null) { 138 LOG.error("updateBalance() Invalid balance type (" + t.getFinancialBalanceTypeCode() + ") in pending table"); 139 return; 140 } 141 142 // Subtract the amount if offset generation indicator & the debit/credit code isn't the same 143 // as the one in the object type code table 144 if (t.getBalanceType().isFinancialOffsetGenerationIndicator()) { 145 if (!t.getTransactionDebitCreditCode().equals(t.getObjectType().getFinObjectTypeDebitcreditCd())) { 146 amount = amount.multiply(new KualiDecimal(-1)); 147 } 148 } 149 150 // update the balance amount of the cooresponding period 151 String period = t.getUniversityFiscalPeriodCode(); 152 if (period == null) { 153 UniversityDate currentUniversityDate = SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate(); 154 period = currentUniversityDate.getUniversityFiscalAccountingPeriod(); 155 } 156 157 b.addAmount(period, amount); 158 } 159 160 /** 161 * @see org.kuali.kfs.gl.batch.service.PostTransaction#getDestinationName() 162 */ 163 public String getDestinationName() { 164 return "GL_BALANCE_T"; 165 } 166 167 public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) { 168 this.accountingCycleCachingService = accountingCycleCachingService; 169 } 170 }