001: /*
002: * Copyright 2006-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.closing.year.util;
017:
018: import java.sql.Date;
019:
020: import org.kuali.core.service.DataDictionaryService;
021: import org.kuali.core.util.KualiDecimal;
022: import org.kuali.kfs.KFSConstants;
023: import org.kuali.kfs.KFSPropertyConstants;
024: import org.kuali.kfs.context.SpringContext;
025: import org.kuali.kfs.service.OptionsService;
026: import org.kuali.kfs.service.ParameterService;
027: import org.kuali.kfs.service.impl.ParameterConstants;
028: import org.kuali.module.chart.bo.A21SubAccount;
029: import org.kuali.module.chart.bo.ObjectCode;
030: import org.kuali.module.chart.bo.OffsetDefinition;
031: import org.kuali.module.chart.bo.SubObjCd;
032: import org.kuali.module.chart.service.A21SubAccountService;
033: import org.kuali.module.chart.service.ObjectCodeService;
034: import org.kuali.module.chart.service.OffsetDefinitionService;
035: import org.kuali.module.chart.service.SubObjectCodeService;
036: import org.kuali.module.gl.GLConstants;
037: import org.kuali.module.gl.batch.EncumbranceForwardStep;
038: import org.kuali.module.gl.bo.Encumbrance;
039: import org.kuali.module.gl.bo.OriginEntryFull;
040: import org.kuali.module.gl.util.OriginEntryOffsetPair;
041:
042: /**
043: * A helper to create origin entries to carry forward different types of encumbrances.
044: */
045:
046: public class EncumbranceClosingOriginEntryFactory {
047:
048: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
049: .getLogger(EncumbranceClosingOriginEntryFactory.class);
050:
051: /**
052: * Create a pair of cost share entries, one explicit and one offset to carry forward an encumbrance after validating the
053: * encumbrance.
054: *
055: * @param encumbrance the encumbrance to create origin entry and offset for
056: * @param transactionDate the date all origin entries should have as their transaction date
057: * @return a cost share entry/offset pair to carry forward the given encumbrance.
058: */
059: static final public OriginEntryOffsetPair createCostShareBeginningBalanceEntryOffsetPair(
060: Encumbrance encumbrance, Date transactionDate) {
061:
062: ParameterService parameterService = SpringContext
063: .getBean(ParameterService.class);
064: OffsetDefinitionService offsetDefinitionService = SpringContext
065: .getBean(OffsetDefinitionService.class);
066: ObjectCodeService objectCodeService = SpringContext
067: .getBean(ObjectCodeService.class);
068:
069: final String GL_ACLO = parameterService
070: .getParameterValue(
071: ParameterConstants.GENERAL_LEDGER_BATCH.class,
072: KFSConstants.SystemGroupParameterNames.GL_ANNUAL_CLOSING_DOC_TYPE);
073: final String GL_ORIGINATION_CODE = parameterService
074: .getParameterValue(
075: ParameterConstants.GENERAL_LEDGER_BATCH.class,
076: KFSConstants.SystemGroupParameterNames.GL_ORIGINATION_CODE);
077:
078: OriginEntryOffsetPair pair = new OriginEntryOffsetPair();
079:
080: // Generate the entry ...
081:
082: OriginEntryFull entry = new OriginEntryFull(encumbrance
083: .getDocumentTypeCode(), encumbrance.getOriginCode());
084:
085: String description = encumbrance
086: .getTransactionEncumbranceDescription();
087: String fromDesc = "FR-" + encumbrance.getChartOfAccountsCode()
088: + encumbrance.getAccountNumber();
089: int descLength = SpringContext.getBean(
090: DataDictionaryService.class).getAttributeMaxLength(
091: OriginEntryFull.class,
092: KFSPropertyConstants.TRANSACTION_LEDGER_ENTRY_DESC);
093: if ((description.length() + fromDesc.length()) < descLength) {
094: int padLength = descLength
095: - (description.length() + fromDesc.length());
096: StringBuilder sb = new StringBuilder();
097: for (int i = 0; i < padLength; i++) {
098: sb.append(' ');
099: }
100: sb.append(fromDesc);
101: fromDesc = sb.toString();
102: description += fromDesc;
103: } else if ((description.length() + fromDesc.length()) > descLength) {
104: description = description.substring(0,
105: (descLength - fromDesc.length()))
106: + fromDesc;
107: } else {
108: description += fromDesc;
109: }
110: entry.setTransactionLedgerEntryDescription(description);
111:
112: // SpringContext is used because this method is static.
113: A21SubAccountService a21SubAccountService = SpringContext
114: .getBean(A21SubAccountService.class);
115: A21SubAccount a21SubAccount = a21SubAccountService
116: .getByPrimaryKey(encumbrance.getChartOfAccountsCode(),
117: encumbrance.getAccountNumber(), encumbrance
118: .getSubAccountNumber());
119:
120: entry.setUniversityFiscalYear(new Integer(encumbrance
121: .getUniversityFiscalYear().intValue() + 1));
122: entry.setChartOfAccountsCode(a21SubAccount
123: .getCostShareChartOfAccountCode());
124: entry.setAccountNumber(a21SubAccount
125: .getCostShareSourceAccountNumber());
126: entry.setSubAccountNumber(a21SubAccount
127: .getCostShareSourceSubAccountNumber());
128:
129: // The subAccountNumber is set to dashes in the OriginEntryFull constructor.
130: if (entry.getSubAccountNumber() == null
131: || KFSConstants.EMPTY_STRING.equals(entry
132: .getSubAccountNumber().trim())) {
133: entry.setSubAccountNumber(KFSConstants
134: .getDashSubAccountNumber());
135: }
136:
137: entry.setFinancialObjectCode(encumbrance.getObjectCode());
138: entry.setFinancialSubObjectCode(KFSConstants
139: .getDashFinancialSubObjectCode());
140: entry
141: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_COST_SHARE_ENCUMBRANCE);
142:
143: ObjectCode finObjCode = objectCodeService.getByPrimaryId(
144: encumbrance.getUniversityFiscalYear(), entry
145: .getChartOfAccountsCode(), entry
146: .getFinancialObjectCode());
147: entry.setFinancialObjectTypeCode(finObjCode
148: .getFinancialObjectTypeCode());
149:
150: entry
151: .setUniversityFiscalPeriodCode(KFSConstants.PERIOD_CODE_BEGINNING_BALANCE);
152: entry.setTransactionLedgerEntrySequenceNumber(new Integer(0));
153: entry.setDocumentNumber(encumbrance.getDocumentNumber());
154: entry
155: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_COST_SHARE_ENCUMBRANCE);
156:
157: KualiDecimal delta = encumbrance
158: .getAccountLineEncumbranceAmount()
159: .subtract(
160: encumbrance
161: .getAccountLineEncumbranceClosedAmount());
162: if (delta.isPositive()) {
163: entry
164: .setTransactionDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
165: entry.setTransactionLedgerEntryAmount(delta);
166: } else {
167: entry
168: .setTransactionDebitCreditCode(KFSConstants.GL_CREDIT_CODE);
169: entry.setTransactionLedgerEntryAmount(delta.negated());
170: }
171: entry
172: .setTransactionEncumbranceUpdateCode(KFSConstants.ENCUMB_UPDT_DOCUMENT_CD);
173: entry.setTransactionDate(transactionDate);
174:
175: pair.setEntry(entry);
176:
177: // And now the offset ...
178:
179: OriginEntryFull offset = new OriginEntryFull(encumbrance
180: .getDocumentTypeCode(), encumbrance.getOriginCode());
181: final String GENERATED_TRANSACTION_LEDGER_ENTRY_DESCRIPTION = parameterService
182: .getParameterValue(
183: EncumbranceForwardStep.class,
184: GLConstants.EncumbranceClosingOriginEntry.GENERATED_TRANSACTION_LEDGER_ENTRY_DESCRIPTION);
185: offset
186: .setTransactionLedgerEntryDescription(GENERATED_TRANSACTION_LEDGER_ENTRY_DESCRIPTION);
187:
188: offset.setUniversityFiscalYear(new Integer(encumbrance
189: .getUniversityFiscalYear().intValue() + 1));
190: offset.setChartOfAccountsCode(a21SubAccount
191: .getCostShareChartOfAccountCode());
192: offset.setAccountNumber(a21SubAccount
193: .getCostShareSourceAccountNumber());
194: offset.setSubAccountNumber(a21SubAccount
195: .getCostShareSourceSubAccountNumber());
196: if (offset.getSubAccountNumber() == null
197: || KFSConstants.EMPTY_STRING.equals(offset
198: .getSubAccountNumber().trim())) {
199: offset.setSubAccountNumber(KFSConstants
200: .getDashSubAccountNumber());
201: }
202: // Lookup the offset definition for the explicit entry we just created.
203: OffsetDefinition offsetDefinition = offsetDefinitionService
204: .getByPrimaryId(entry.getUniversityFiscalYear(), entry
205: .getChartOfAccountsCode(), entry
206: .getFinancialDocumentTypeCode(), entry
207: .getFinancialBalanceTypeCode());
208: // Set values from the offset definition if it was found.
209: if (null != offsetDefinition) {
210:
211: offset.setFinancialObjectCode(offsetDefinition
212: .getFinancialObjectCode());
213: offset.setFinancialSubObjectCode(KFSConstants
214: .getDashFinancialSubObjectCode());
215: } else { // Log an exception if the offset definition was not found.
216:
217: LOG
218: .info("FATAL ERROR: One of the following errors occurred (no way to know exactly which):\n\t"
219: + "- OFFSET DEFINITION NOT FOUND\n\t"
220: + "- ERROR ACCESSING OFSD TABLE");
221: pair.setFatalErrorFlag(true);
222: return pair;
223:
224: }
225: offset
226: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_COST_SHARE_ENCUMBRANCE);
227: // Validate the object code for the explicit entry.
228: ObjectCode objectCode = objectCodeService.getByPrimaryId(offset
229: .getUniversityFiscalYear(), offset
230: .getChartOfAccountsCode(), offset
231: .getFinancialObjectCode());
232: if (null != objectCode) {
233: offset.setFinancialObjectTypeCode(objectCode
234: .getFinancialObjectTypeCode());
235: } else {
236: LOG
237: .info("FATAL ERROR: One of the following errors occurred (no way to know exactly which):\n\t"
238: + "- NO OBJECT FOR OBJECT ON OFSD\n\t"
239: + "- ERROR ACCESSING OBJECT TABLE");
240: pair.setFatalErrorFlag(true);
241: return pair;
242: }
243: offset
244: .setUniversityFiscalPeriodCode(KFSConstants.PERIOD_CODE_BEGINNING_BALANCE);
245: offset.setDocumentNumber(encumbrance.getDocumentNumber());
246: offset.setTransactionLedgerEntrySequenceNumber(new Integer(0));
247: if (delta.isPositive()) {
248: offset
249: .setTransactionDebitCreditCode(KFSConstants.GL_CREDIT_CODE);
250: offset.setTransactionLedgerEntryAmount(delta);
251: } else {
252: offset
253: .setTransactionDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
254: offset.setTransactionLedgerEntryAmount(delta.negated());
255: }
256:
257: offset.setTransactionEncumbranceUpdateCode(null);
258: offset.setOrganizationDocumentNumber(null);
259: offset.setProjectCode(KFSConstants.getDashProjectCode());
260: offset.setTransactionDate(transactionDate);
261: offset.setOrganizationReferenceId(null);
262: offset.setReferenceFinancialDocumentTypeCode(null);
263: offset.setReferenceFinancialSystemOriginationCode(null);
264: offset.setReferenceFinancialDocumentNumber(null);
265: offset.setReversalDate(null);
266:
267: pair.setOffset(offset);
268:
269: return pair;
270:
271: }
272:
273: /**
274: * Create a pair of OriginEntries, one explicit and one offset to carry forward an encumbrance.
275: *
276: * @param encumbrance the encumbrance to create origin entries for
277: * @param closingFiscalYear the fiscal year that's closing
278: * @param transactionDate the transaction date these entries should have
279: * @return a entry/offset pair for the given encumbrance
280: */
281: static final public OriginEntryOffsetPair createBeginningBalanceEntryOffsetPair(
282: Encumbrance encumbrance, Integer closingFiscalYear,
283: Date transactionDate) {
284:
285: ParameterService parameterService = SpringContext
286: .getBean(ParameterService.class);
287: OriginEntryOffsetPair pair = new OriginEntryOffsetPair();
288:
289: // Build the entry ...
290: OriginEntryFull entry = new OriginEntryFull(encumbrance
291: .getDocumentTypeCode(), encumbrance.getOriginCode());
292:
293: Integer this FiscalYear = new Integer(closingFiscalYear
294: .intValue() + 1);
295: entry.setUniversityFiscalYear(this FiscalYear);
296: entry.setChartOfAccountsCode(encumbrance
297: .getChartOfAccountsCode());
298: entry.setAccountNumber(encumbrance.getAccountNumber());
299: entry.setSubAccountNumber(encumbrance.getSubAccountNumber());
300:
301: // SpringContext is used because this method is static.
302: ObjectCodeService objectCodeService = SpringContext
303: .getBean(ObjectCodeService.class);
304: ObjectCode objectCode = objectCodeService.getByPrimaryId(
305: encumbrance.getUniversityFiscalYear(), encumbrance
306: .getChartOfAccountsCode(), encumbrance
307: .getObjectCode());
308:
309: if (null != objectCode) {
310:
311: entry.setFinancialObjectTypeCode(objectCode
312: .getFinancialObjectTypeCode());
313:
314: if (null != objectCode.getNextYearFinancialObjectCode()
315: && !KFSConstants.EMPTY_STRING.equals(objectCode
316: .getNextYearFinancialObjectCode().trim())) {
317:
318: entry.setFinancialObjectCode(objectCode
319: .getNextYearFinancialObjectCode());
320:
321: } else {
322:
323: entry.setFinancialObjectCode(encumbrance
324: .getObjectCode());
325:
326: }
327:
328: } else {
329:
330: LOG
331: .info("FATAL ERROR: ERROR ACCESSING OBJECT TABLE FOR CAOBJT-FIN-OBJECT-CD");
332: pair.setFatalErrorFlag(true);
333: return pair;
334:
335: }
336:
337: // SpringContext is used because this method is static.
338: SubObjectCodeService subObjectCodeService = SpringContext
339: .getBean(SubObjectCodeService.class);
340: SubObjCd subObjectCode = subObjectCodeService.getByPrimaryId(
341: encumbrance.getUniversityFiscalYear(), encumbrance
342: .getChartOfAccountsCode(), encumbrance
343: .getAccountNumber(), encumbrance
344: .getObjectCode(), encumbrance
345: .getSubObjectCode());
346:
347: if (null != subObjectCode) {
348:
349: entry.setFinancialSubObjectCode(subObjectCode
350: .getFinancialSubObjectCode());
351:
352: } else {
353:
354: entry.setFinancialSubObjectCode(KFSConstants
355: .getDashFinancialSubObjectCode());
356:
357: }
358:
359: entry.setFinancialBalanceTypeCode(encumbrance
360: .getBalanceTypeCode());
361: entry
362: .setUniversityFiscalPeriodCode(KFSConstants.PERIOD_CODE_BEGINNING_BALANCE);
363: entry.setDocumentNumber(encumbrance.getDocumentNumber());
364: entry.setTransactionLedgerEntrySequenceNumber(new Integer(1));
365: entry.setTransactionLedgerEntryDescription(encumbrance
366: .getTransactionEncumbranceDescription());
367: entry
368: .setTransactionLedgerEntryAmount(encumbrance
369: .getAccountLineEncumbranceAmount()
370: .subtract(
371: encumbrance
372: .getAccountLineEncumbranceClosedAmount()));
373:
374: if (entry.getTransactionLedgerEntryAmount().isNegative()) {
375:
376: entry.setTransactionLedgerEntryAmount(entry
377: .getTransactionLedgerEntryAmount().negated());
378: entry
379: .setTransactionDebitCreditCode(KFSConstants.GL_CREDIT_CODE);
380:
381: } else {
382:
383: entry
384: .setTransactionDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
385:
386: }
387:
388: entry.setTransactionDate(transactionDate);
389: entry.setOrganizationDocumentNumber(null);
390: entry.setProjectCode(KFSConstants.getDashProjectCode());
391: entry.setOrganizationReferenceId(null);
392: entry.setReferenceFinancialDocumentTypeCode(null);
393: entry.setReferenceFinancialSystemOriginationCode(null);
394: entry.setReferenceFinancialDocumentNumber(null);
395: entry.setReversalDate(null);
396: entry
397: .setTransactionEncumbranceUpdateCode(KFSConstants.ENCUMB_UPDT_DOCUMENT_CD);
398:
399: pair.setEntry(entry);
400:
401: final String OBJECT_CODE_FOR_BALANCE_TYPE_INTERNAL_ENCUMBRANCE = parameterService
402: .getParameterValue(
403: EncumbranceForwardStep.class,
404: GLConstants.EncumbranceClosingOriginEntry.OFFSET_OBJECT_CODE_FOR_INTERNAL_ENCUMBRANCE);
405: final String OBJECT_CODE_FOR_BALANCE_TYPE_PRE_ENCUMBRANCE = parameterService
406: .getParameterValue(
407: EncumbranceForwardStep.class,
408: GLConstants.EncumbranceClosingOriginEntry.OFFSET_OBJECT_CODE_FOR_PRE_ENCUMBRANCE);
409: final String OBJECT_CODE_FOR_BALANCE_TYPE_EXTERNAL_ENCUMBRANCE = parameterService
410: .getParameterValue(
411: EncumbranceForwardStep.class,
412: GLConstants.EncumbranceClosingOriginEntry.OFFSET_OBJECT_CODE_FOR_EXTERNAL_ENCUMBRANCE);
413: final String BEGINNING_FUND_TRANSACTION_LEDGER_ENTRY_DESCRIPTION = parameterService
414: .getParameterValue(
415: EncumbranceForwardStep.class,
416: GLConstants.EncumbranceClosingOriginEntry.BEGINNING_FUND_BALANCE_TRANSACTION_LEDGER_ENTRY_DESCRIPTION);
417:
418: // And now build the offset.
419: OriginEntryFull offset = new OriginEntryFull(entry);
420: offset.setTransactionLedgerEntryAmount(entry
421: .getTransactionLedgerEntryAmount());
422: // KFSConstants.BALANCE_TYPE_INTERNAL_ENCUMBRANCE case...
423: offset
424: .setFinancialObjectCode(OBJECT_CODE_FOR_BALANCE_TYPE_INTERNAL_ENCUMBRANCE);
425:
426: if (KFSConstants.BALANCE_TYPE_PRE_ENCUMBRANCE.equals(entry
427: .getFinancialBalanceTypeCode())) {
428:
429: offset
430: .setFinancialObjectCode(OBJECT_CODE_FOR_BALANCE_TYPE_PRE_ENCUMBRANCE);
431:
432: } else if (KFSConstants.BALANCE_TYPE_EXTERNAL_ENCUMBRANCE
433: .equals(entry.getFinancialBalanceTypeCode())) {
434:
435: offset
436: .setFinancialObjectCode(OBJECT_CODE_FOR_BALANCE_TYPE_EXTERNAL_ENCUMBRANCE);
437:
438: }
439:
440: offset.setFinancialObjectTypeCode(SpringContext.getBean(
441: OptionsService.class).getCurrentYearOptions()
442: .getFinObjectTypeFundBalanceCd());
443: offset
444: .setTransactionLedgerEntryDescription(BEGINNING_FUND_TRANSACTION_LEDGER_ENTRY_DESCRIPTION);
445:
446: if (KFSConstants.GL_DEBIT_CODE.equals(entry
447: .getTransactionDebitCreditCode())) {
448:
449: offset
450: .setTransactionDebitCreditCode(KFSConstants.GL_CREDIT_CODE);
451:
452: } else {
453:
454: offset
455: .setTransactionDebitCreditCode(KFSConstants.GL_DEBIT_CODE);
456:
457: }
458:
459: pair.setOffset(offset);
460:
461: return pair;
462:
463: }
464:
465: }
|