001: /*
002: * Copyright 2005-2007 The Kuali Foundation.
003: *
004: * Licensed under the Educational Community License, Version 1.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/ecl1.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.module.gl.batch.poster.impl;
017:
018: import java.util.Date;
019:
020: import org.apache.ojb.broker.metadata.MetadataManager;
021: import org.kuali.kfs.KFSConstants;
022: import org.kuali.module.chart.bo.A21SubAccount;
023: import org.kuali.module.chart.bo.Account;
024: import org.kuali.module.chart.bo.IndirectCostRecoveryExclusionAccount;
025: import org.kuali.module.chart.bo.IndirectCostRecoveryExclusionType;
026: import org.kuali.module.chart.bo.ObjectCode;
027: import org.kuali.module.chart.bo.ObjectType;
028: import org.kuali.module.chart.dao.A21SubAccountDao;
029: import org.kuali.module.chart.dao.IndirectCostRecoveryExclusionAccountDao;
030: import org.kuali.module.chart.dao.IndirectCostRecoveryExclusionTypeDao;
031: import org.kuali.module.gl.GLConstants;
032: import org.kuali.module.gl.batch.poster.PostTransaction;
033: import org.kuali.module.gl.bo.ExpenditureTransaction;
034: import org.kuali.module.gl.bo.Transaction;
035: import org.kuali.module.gl.dao.ExpenditureTransactionDao;
036: import org.kuali.module.gl.service.IcrTransaction;
037: import org.springframework.transaction.annotation.Transactional;
038: import org.springframework.util.StringUtils;
039:
040: /**
041: * This implementation of PostTransaction creates ExpenditureTransactions, temporary records used
042: * for ICR generation
043: */
044: @Transactional
045: public class PostExpenditureTransaction implements IcrTransaction,
046: PostTransaction {
047: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
048: .getLogger(PostExpenditureTransaction.class);
049:
050: private A21SubAccountDao a21SubAccountDao;
051: private IndirectCostRecoveryExclusionAccountDao indirectCostRecoveryExclusionAccountDao;
052: private IndirectCostRecoveryExclusionTypeDao indirectCostRecoveryExclusionTypeDao;
053: private ExpenditureTransactionDao expenditureTransactionDao;
054:
055: public void setA21SubAccountDao(A21SubAccountDao asad) {
056: a21SubAccountDao = asad;
057: }
058:
059: public void setIndirectCostRecoveryExclusionAccountDao(
060: IndirectCostRecoveryExclusionAccountDao icrea) {
061: indirectCostRecoveryExclusionAccountDao = icrea;
062: }
063:
064: public void setIndirectCostRecoveryExclusionTypeDao(
065: IndirectCostRecoveryExclusionTypeDao icrea) {
066: indirectCostRecoveryExclusionTypeDao = icrea;
067: }
068:
069: public void setExpenditureTransactionDao(
070: ExpenditureTransactionDao etd) {
071: expenditureTransactionDao = etd;
072: }
073:
074: /**
075: * Creates a PostExpenditureTransaction instance
076: */
077: public PostExpenditureTransaction() {
078: super ();
079: }
080:
081: /**
082: * This will determine if this transaction is an ICR eligible transaction
083: *
084: * @param objectType the object type of the transaction
085: * @param account the account of the transaction
086: * @param subAccountNumber the subAccountNumber of the transaction
087: * @param objectCode the object code of the transaction
088: * @param universityFiscalPeriodCode the accounting period code of the transactoin
089: * @return true if the transaction is an ICR transaction and therefore should have an expenditure transaction created for it; false if otherwise
090: */
091: public boolean isIcrTransaction(ObjectType objectType,
092: Account account, String subAccountNumber,
093: ObjectCode objectCode, String universityFiscalPeriodCode) {
094: LOG.debug("isIcrTransaction() started");
095:
096: // Is the ICR indicator set and the ICR Series identifier set?
097: // Is the period code a non-balance period? If so, continue, if not, we aren't posting this transaction
098: if (objectType.isFinObjectTypeIcrSelectionIndicator()
099: && StringUtils.hasText(account
100: .getFinancialIcrSeriesIdentifier())
101: && (!KFSConstants.PERIOD_CODE_ANNUAL_BALANCE
102: .equals(universityFiscalPeriodCode))
103: && (!KFSConstants.PERIOD_CODE_BEGINNING_BALANCE
104: .equals(universityFiscalPeriodCode))
105: && (!KFSConstants.PERIOD_CODE_CG_BEGINNING_BALANCE
106: .equals(universityFiscalPeriodCode))) {
107: // Continue on the posting process
108:
109: // Check the sub account type code. A21 subaccounts with the type of CS don't get posted
110: A21SubAccount a21SubAccount = a21SubAccountDao
111: .getByPrimaryKey(account.getChartOfAccountsCode(),
112: account.getAccountNumber(),
113: subAccountNumber);
114: if ((a21SubAccount != null)
115: && KFSConstants.COST_SHARE.equals(a21SubAccount
116: .getSubAccountTypeCode())) {
117: // No need to post this
118: LOG
119: .debug("isIcrTransaction() A21 subaccounts with type of CS - not posted");
120: return false;
121: }
122:
123: // Do we exclude this account from ICR because account/object is in the table?
124: IndirectCostRecoveryExclusionAccount excAccount = indirectCostRecoveryExclusionAccountDao
125: .getByPrimaryKey(account.getChartOfAccountsCode(),
126: account.getAccountNumber(), objectCode
127: .getChartOfAccountsCode(),
128: objectCode.getFinancialObjectCode());
129: if (excAccount != null) {
130: // No need to post this
131: LOG
132: .debug("isIcrTransaction() ICR Excluded account - not posted");
133: return false;
134: }
135:
136: // How about if we just look based on account?
137: if (indirectCostRecoveryExclusionAccountDao.existByAccount(
138: account.getChartOfAccountsCode(), account
139: .getAccountNumber())) {
140: return true;
141: } else {
142: // If the ICR type code is empty or 10, don't post
143:
144: // TODO: use type 10 constant
145: if ((!StringUtils.hasText(account
146: .getAcctIndirectCostRcvyTypeCd()))
147: || KFSConstants.MONTH10.equals(account
148: .getAcctIndirectCostRcvyTypeCd())) {
149: // No need to post this
150: LOG
151: .debug("isIcrTransaction() ICR type is null or 10 - not posted");
152: return false;
153: }
154:
155: // If the type is excluded, don't post. First step finds the top level object code...
156: ObjectCode currentObjectCode = objectCode;
157: boolean foundIt = false;
158: while (!foundIt) {
159: if (currentObjectCode
160: .getChartOfAccountsCode()
161: .equals(
162: currentObjectCode
163: .getReportsToChartOfAccountsCode())
164: && currentObjectCode
165: .getFinancialObjectCode()
166: .equals(
167: currentObjectCode
168: .getReportsToFinancialObjectCode())) {
169: foundIt = true;
170: } else {
171: if (currentObjectCode
172: .getReportsToFinancialObject() == null) {
173: foundIt = true;
174: } else {
175: currentObjectCode = currentObjectCode
176: .getReportsToFinancialObject();
177: }
178: }
179: }
180: // second step checks if the top level object code is to be excluded...
181: IndirectCostRecoveryExclusionType excType = indirectCostRecoveryExclusionTypeDao
182: .getByPrimaryKey(account
183: .getAcctIndirectCostRcvyTypeCd(),
184: currentObjectCode
185: .getChartOfAccountsCode(),
186: currentObjectCode
187: .getFinancialObjectCode());
188: if (excType != null) {
189: // No need to post this
190: LOG
191: .debug("isIcrTransaction() ICR Excluded type - not posted");
192: return false;
193: }
194: return true;
195: }
196: } else {
197: // Don't need to post anything
198: LOG
199: .debug("isIcrTransaction() Not ICR account or invalid period code - not posted");
200: return false;
201: }
202: }
203:
204: /**
205: * If the transaction is a valid ICR transaction, posts an expenditure transaction record for the transaction
206: *
207: * @param t the transaction which is being posted
208: * @param mode the mode the poster is currently running in
209: * @param postDate the date this transaction should post to
210: * @return the accomplished post type
211: * @see org.kuali.module.gl.batch.poster.PostTransaction#post(org.kuali.module.gl.bo.Transaction, int, java.util.Date)
212: */
213: public String post(Transaction t, int mode, Date postDate) {
214: LOG.debug("post() started");
215:
216: if (isIcrTransaction(t.getObjectType(), t.getAccount(), t
217: .getSubAccountNumber(), t.getFinancialObject(), t
218: .getUniversityFiscalPeriodCode())) {
219: return postTransaction(t, mode);
220: }
221: return GLConstants.EMPTY_CODE;
222: }
223:
224: /**
225: * Actually posts the transaction to the appropriate expenditure transaction record
226: *
227: * @param t the transaction to post
228: * @param mode the mode of the poster as it is currently running
229: * @return the accomplished post type
230: */
231: private String postTransaction(Transaction t, int mode) {
232: LOG.debug("postTransaction() started");
233:
234: String returnCode = GLConstants.UPDATE_CODE;
235:
236: ExpenditureTransaction et = expenditureTransactionDao
237: .getByTransaction(t);
238: if (et == null) {
239: LOG.warn("Posting expenditure transation");
240: et = new ExpenditureTransaction(t);
241: returnCode = GLConstants.INSERT_CODE;
242: }
243:
244: if (org.apache.commons.lang.StringUtils.isBlank(t
245: .getOrganizationReferenceId())) {
246: et.setOrganizationReferenceId(GLConstants
247: .getDashOrganizationReferenceId());
248: }
249:
250: if (KFSConstants.GL_DEBIT_CODE.equals(t
251: .getTransactionDebitCreditCode())
252: || KFSConstants.GL_BUDGET_CODE.equals(t
253: .getTransactionDebitCreditCode())) {
254: et.setAccountObjectDirectCostAmount(et
255: .getAccountObjectDirectCostAmount().add(
256: t.getTransactionLedgerEntryAmount()));
257: } else {
258: et.setAccountObjectDirectCostAmount(et
259: .getAccountObjectDirectCostAmount().subtract(
260: t.getTransactionLedgerEntryAmount()));
261: }
262:
263: expenditureTransactionDao.save(et);
264:
265: return returnCode;
266: }
267:
268: /**
269: * @see org.kuali.module.gl.batch.poster.PostTransaction#getDestinationName()
270: */
271: public String getDestinationName() {
272: return MetadataManager.getInstance().getGlobalRepository()
273: .getDescriptorFor(ExpenditureTransaction.class)
274: .getFullTableName();
275: }
276: }
|