001/* 002 * The Kuali Financial System, a comprehensive financial management system for higher education. 003 * 004 * Copyright 2005-2014 The Kuali Foundation 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU Affero General Public License as 008 * published by the Free Software Foundation, either version 3 of the 009 * License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU Affero General Public License for more details. 015 * 016 * You should have received a copy of the GNU Affero General Public License 017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package org.kuali.kfs.gl.batch.service.impl; 020 021import java.util.Collection; 022import java.util.Date; 023import java.util.Iterator; 024 025import org.kuali.kfs.gl.batch.service.AccountingCycleCachingService; 026import org.kuali.kfs.gl.batch.service.BalanceCalculator; 027import org.kuali.kfs.gl.batch.service.PostTransaction; 028import org.kuali.kfs.gl.businessobject.Balance; 029import org.kuali.kfs.gl.businessobject.Transaction; 030import org.kuali.kfs.sys.businessobject.UniversityDate; 031import org.kuali.kfs.sys.context.SpringContext; 032import org.kuali.kfs.sys.service.ReportWriterService; 033import org.kuali.kfs.sys.service.UniversityDateService; 034import org.kuali.rice.core.api.util.type.KualiDecimal; 035import org.springframework.transaction.annotation.Transactional; 036 037/** 038 * This implementation of PostTransaction updates the appropriate Balance 039 */ 040@Transactional 041public class PostBalance implements PostTransaction, BalanceCalculator { 042 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PostBalance.class); 043 044 private AccountingCycleCachingService accountingCycleCachingService; 045 private static final KualiDecimal NEGATIVE_ONE = new KualiDecimal(-1); 046 /** 047 * Constructs a PostBalance instance 048 */ 049 public PostBalance() { 050 super(); 051 } 052 053 /** 054 * This posts the effect of the transaction upon the appropriate balance record. 055 * 056 * @param t the transaction which is being posted 057 * @param mode the mode the poster is currently running in 058 * @param postDate the date this transaction should post to 059 * @param posterReportWriterService the writer service where the poster is writing its report 060 * @return the accomplished post type 061 * @see org.kuali.kfs.gl.batch.service.PostTransaction#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date) 062 */ 063 public String post(Transaction t, int mode, Date postDate, ReportWriterService posterReportWriterService) { 064 LOG.debug("post() started"); 065 066 String postType = "U"; 067 068 KualiDecimal amount = t.getTransactionLedgerEntryAmount(); 069 070 // Subtract the amount if offset generation indicator & the debit/credit code isn't the same 071 // as the one in the object type code table 072 if (t.getBalanceType().isFinancialOffsetGenerationIndicator()) { 073 if (!t.getTransactionDebitCreditCode().equals(t.getObjectType().getFinObjectTypeDebitcreditCd())) { 074 amount = amount.multiply(NEGATIVE_ONE); 075 } 076 } 077 078 Balance b = accountingCycleCachingService.getBalance(t); 079 if (b == null) { 080 postType = "I"; 081 b = new Balance(t); 082 } 083 String period = t.getUniversityFiscalPeriodCode(); 084 b.addAmount(period, amount); 085 086 if (postType.equals("I")) { 087 accountingCycleCachingService.insertBalance(b); 088 } else { 089 accountingCycleCachingService.updateBalance(b); 090 } 091 092 return postType; 093 } 094 095 /** 096 * Given a list of balances, determines which one the given trsnaction should post to 097 * 098 * @param balanceList a Collection of balances 099 * @param t the transaction that is being posted 100 * @return the balance, either found from the list, or, if not present in the list, newly created 101 * @see org.kuali.kfs.gl.batch.service.BalanceCalculator#findBalance(java.util.Collection, org.kuali.kfs.gl.businessobject.Transaction) 102 */ 103 public Balance findBalance(Collection balanceList, Transaction t) { 104 // Try to find one that already exists 105 for (Iterator iter = balanceList.iterator(); iter.hasNext();) { 106 Balance b = (Balance) iter.next(); 107 108 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())) { 109 return b; 110 } 111 } 112 113 // If we couldn't find one that exists, create a new one 114 Balance b = new Balance(t); 115 balanceList.add(b); 116 117 return b; 118 } 119 120 /** 121 * @param t 122 * @param enc 123 */ 124 public void updateBalance(Transaction t, Balance b) { 125 126 // The pending entries haven't been scrubbed so there could be 127 // bad data. This won't update a balance if the data it needs 128 // is invalid 129 KualiDecimal amount = t.getTransactionLedgerEntryAmount(); 130 if (amount == null) { 131 amount = KualiDecimal.ZERO; 132 } 133 134 if (t.getObjectType() == null) { 135 LOG.error("updateBalance() Invalid object type (" + t.getFinancialObjectTypeCode() + ") in pending table"); 136 return; 137 } 138 139 if (t.getBalanceType() == null) { 140 LOG.error("updateBalance() Invalid balance type (" + t.getFinancialBalanceTypeCode() + ") in pending table"); 141 return; 142 } 143 144 // Subtract the amount if offset generation indicator & the debit/credit code isn't the same 145 // as the one in the object type code table 146 if (t.getBalanceType().isFinancialOffsetGenerationIndicator()) { 147 if (!t.getTransactionDebitCreditCode().equals(t.getObjectType().getFinObjectTypeDebitcreditCd())) { 148 amount = amount.multiply(new KualiDecimal(-1)); 149 } 150 } 151 152 // update the balance amount of the cooresponding period 153 String period = t.getUniversityFiscalPeriodCode(); 154 if (period == null) { 155 UniversityDate currentUniversityDate = SpringContext.getBean(UniversityDateService.class).getCurrentUniversityDate(); 156 period = currentUniversityDate.getUniversityFiscalAccountingPeriod(); 157 } 158 159 b.addAmount(period, amount); 160 } 161 162 /** 163 * @see org.kuali.kfs.gl.batch.service.PostTransaction#getDestinationName() 164 */ 165 public String getDestinationName() { 166 return "GL_BALANCE_T"; 167 } 168 169 public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) { 170 this.accountingCycleCachingService = accountingCycleCachingService; 171 } 172}