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.GeneralLedgerConstants;
023 import org.kuali.kfs.gl.batch.service.AccountBalanceCalculator;
024 import org.kuali.kfs.gl.batch.service.AccountingCycleCachingService;
025 import org.kuali.kfs.gl.batch.service.PostTransaction;
026 import org.kuali.kfs.gl.businessobject.AccountBalance;
027 import org.kuali.kfs.gl.businessobject.Transaction;
028 import org.kuali.kfs.sys.KFSConstants;
029 import org.kuali.kfs.sys.service.ReportWriterService;
030 import org.kuali.rice.kns.service.PersistenceStructureService;
031 import org.springframework.transaction.annotation.Transactional;
032
033 @Transactional
034 public class PostAccountBalance implements PostTransaction, AccountBalanceCalculator {
035 private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PostAccountBalance.class);
036
037 private AccountingCycleCachingService accountingCycleCachingService;
038 private PersistenceStructureService persistenceStructureService;
039
040 /**
041 * Constructs a PostAccountBalance instance
042 */
043 public PostAccountBalance() {
044 super();
045 }
046
047 /**
048 * Posts the transaction to the appropriate account balance record.
049 *
050 * @param t the transaction which is being posted
051 * @param mode the mode the poster is currently running in
052 * @param postDate the date this transaction should post to
053 * @param posterReportWriterService the writer service where the poster is writing its report
054 * @return the accomplished post type
055 * @see org.kuali.kfs.gl.batch.service.PostTransaction#post(org.kuali.kfs.gl.businessobject.Transaction, int, java.util.Date)
056 */
057 public String post(Transaction t, int mode, Date postDate, ReportWriterService posterReportWriterService) {
058 LOG.debug("post() started");
059
060 // Only post transactions where:
061 // balance type code is AC or CB
062 // or where object type isn't FB and balance type code is EX, IE, PE and CE
063 if ((t.getFinancialBalanceTypeCode().equals(t.getOption().getActualFinancialBalanceTypeCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getBudgetCheckingBalanceTypeCd())) || (t.getFinancialBalanceTypeCode().equals(t.getOption().getExtrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getIntrnlEncumFinBalanceTypCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getPreencumbranceFinBalTypeCd()) || t.getFinancialBalanceTypeCode().equals(t.getOption().getCostShareEncumbranceBalanceTypeCd())) && (!t.getFinancialObjectTypeCode().equals(t.getOption().getFinObjectTypeFundBalanceCd()))) {
064 // We are posting this transaction
065 String returnCode = GeneralLedgerConstants.UPDATE_CODE;
066
067 // Load it
068 AccountBalance ab = accountingCycleCachingService.getAccountBalance(t);
069
070 if (ab == null) {
071 returnCode = GeneralLedgerConstants.INSERT_CODE;
072 ab = new AccountBalance(t);
073 }
074
075 ab.setTimestamp(new java.sql.Date(postDate.getTime()));
076
077 if (!updateAccountBalanceReturn(t, ab)) {
078 return GeneralLedgerConstants.EMPTY_CODE;
079 }
080
081 if (returnCode.equals(GeneralLedgerConstants.INSERT_CODE)) {
082 accountingCycleCachingService.insertAccountBalance(ab);
083 } else {
084 accountingCycleCachingService.updateAccountBalance(ab);
085 }
086
087 return returnCode;
088 }
089 else {
090 return GeneralLedgerConstants.EMPTY_CODE;
091 }
092 }
093
094 public AccountBalance findAccountBalance(Collection balanceList, Transaction t) {
095
096 // Try to find one that already exists
097 for (Iterator iter = balanceList.iterator(); iter.hasNext();) {
098 AccountBalance b = (AccountBalance) iter.next();
099
100 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())) {
101 return b;
102 }
103 }
104
105 // If we couldn't find one that exists, create a new one
106 AccountBalance b = new AccountBalance(t);
107 balanceList.add(b);
108
109 return b;
110 }
111
112 protected boolean updateAccountBalanceReturn(Transaction t, AccountBalance ab) {
113 if (t.getFinancialBalanceTypeCode().equals(t.getOption().getBudgetCheckingBalanceTypeCd())) {
114 ab.setCurrentBudgetLineBalanceAmount(ab.getCurrentBudgetLineBalanceAmount().add(t.getTransactionLedgerEntryAmount()));
115 }
116 else if (t.getFinancialBalanceTypeCode().equals(t.getOption().getActualFinancialBalanceTypeCd())) {
117 if (t.getObjectType().getFinObjectTypeDebitcreditCd().equals(t.getTransactionDebitCreditCode()) || ((!t.getBalanceType().isFinancialOffsetGenerationIndicator()) && KFSConstants.GL_BUDGET_CODE.equals(t.getTransactionDebitCreditCode()))) {
118 ab.setAccountLineActualsBalanceAmount(ab.getAccountLineActualsBalanceAmount().add(t.getTransactionLedgerEntryAmount()));
119 }
120 else {
121 ab.setAccountLineActualsBalanceAmount(ab.getAccountLineActualsBalanceAmount().subtract(t.getTransactionLedgerEntryAmount()));
122 }
123 }
124 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())) {
125 if (t.getObjectType().getFinObjectTypeDebitcreditCd().equals(t.getTransactionDebitCreditCode()) || ((!t.getBalanceType().isFinancialOffsetGenerationIndicator()) && KFSConstants.GL_BUDGET_CODE.equals(t.getTransactionDebitCreditCode()))) {
126 ab.setAccountLineEncumbranceBalanceAmount(ab.getAccountLineEncumbranceBalanceAmount().add(t.getTransactionLedgerEntryAmount()));
127 }
128 else {
129 ab.setAccountLineEncumbranceBalanceAmount(ab.getAccountLineEncumbranceBalanceAmount().subtract(t.getTransactionLedgerEntryAmount()));
130 }
131 }
132 else {
133 return false;
134 }
135 return true;
136 }
137
138 /**
139 * @param t
140 * @param enc
141 */
142 public void updateAccountBalance(Transaction t, AccountBalance ab) {
143 updateAccountBalanceReturn(t, ab);
144 }
145
146 public String getDestinationName() {
147 return persistenceStructureService.getTableName(AccountBalance.class);
148 }
149
150 public void setAccountingCycleCachingService(AccountingCycleCachingService accountingCycleCachingService) {
151 this.accountingCycleCachingService = accountingCycleCachingService;
152 }
153
154 public void setPersistenceStructureService(PersistenceStructureService persistenceStructureService) {
155 this.persistenceStructureService = persistenceStructureService;
156 }
157 }