001: /*
002: * Copyright 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.labor.util;
017:
018: import static org.kuali.kfs.bo.AccountingLineOverride.CODE.EXPIRED_ACCOUNT_AND_NON_FRINGE_ACCOUNT_USED;
019: import static org.kuali.kfs.bo.AccountingLineOverride.CODE.NON_FRINGE_ACCOUNT_USED;
020:
021: import java.sql.Date;
022:
023: import org.apache.commons.lang.StringUtils;
024: import org.kuali.core.bo.DocumentHeader;
025: import org.kuali.core.service.DateTimeService;
026: import org.kuali.core.service.DocumentTypeService;
027: import org.kuali.core.util.GeneralLedgerPendingEntrySequenceHelper;
028: import org.kuali.core.util.KualiDecimal;
029: import org.kuali.kfs.KFSConstants;
030: import org.kuali.kfs.KFSPropertyConstants;
031: import org.kuali.kfs.context.SpringContext;
032: import org.kuali.kfs.service.HomeOriginationService;
033: import org.kuali.kfs.service.OptionsService;
034: import org.kuali.module.chart.bo.ObjectCode;
035: import org.kuali.module.chart.service.ObjectCodeService;
036: import org.kuali.module.financial.document.YearEndDocument;
037: import org.kuali.module.financial.document.YearEndDocumentUtil;
038: import org.kuali.module.labor.bo.BenefitsCalculation;
039: import org.kuali.module.labor.bo.ExpenseTransferAccountingLine;
040: import org.kuali.module.labor.bo.LaborLedgerPendingEntry;
041: import org.kuali.module.labor.document.LaborLedgerPostingDocument;
042: import org.kuali.module.labor.service.LaborBenefitsCalculationService;
043:
044: /**
045: * This class provides a set of facilities that can conver the accounting document and its accounting lines into labor pending
046: * entries
047: */
048: public class LaborPendingEntryConverter {
049: private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger
050: .getLogger(LaborPendingEntryConverter.class);
051:
052: /**
053: * convert the given document and accounting line into the expense pending entries
054: *
055: * @param document the given accounting document
056: * @param accountingLine the given accounting line
057: * @param sequenceHelper the given squence helper
058: * @return a set of expense pending entries
059: */
060: public static LaborLedgerPendingEntry getExpensePendingEntry(
061: LaborLedgerPostingDocument document,
062: ExpenseTransferAccountingLine accountingLine,
063: GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
064: LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(
065: document, accountingLine);
066:
067: pendingEntry
068: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
069: pendingEntry
070: .setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper));
071:
072: // year end document should post to previous fiscal year and final period
073: if (document instanceof YearEndDocument) {
074: pendingEntry.setUniversityFiscalYear(YearEndDocumentUtil
075: .getPreviousFiscalYear());
076: pendingEntry
077: .setUniversityFiscalPeriodCode(YearEndDocumentUtil
078: .getFINAL_ACCOUNTING_PERIOD());
079: }
080:
081: return pendingEntry;
082: }
083:
084: /**
085: * convert the given document and accounting line into the expense pending entries for effort reporting
086: *
087: * @param document the given accounting document
088: * @param accountingLine the given accounting line
089: * @param sequenceHelper the given squence helper
090: * @return a set of expense pending entries for effort reporting
091: */
092: public static LaborLedgerPendingEntry getExpenseA21PendingEntry(
093: LaborLedgerPostingDocument document,
094: ExpenseTransferAccountingLine accountingLine,
095: GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
096: LaborLedgerPendingEntry pendingEntry = getExpensePendingEntry(
097: document, accountingLine, sequenceHelper);
098:
099: pendingEntry
100: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_A21);
101: String debitCreditCode = DebitCreditUtil
102: .getReverseDebitCreditCode(pendingEntry
103: .getTransactionDebitCreditCode());
104: pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
105:
106: return pendingEntry;
107: }
108:
109: /**
110: * convert the given document and accounting line into the expense reversal pending entries for effort reporting
111: *
112: * @param document the given accounting document
113: * @param accountingLine the given accounting line
114: * @param sequenceHelper the given squence helper
115: * @return a set of expense reversal pending entries for effort reporting
116: */
117: public static LaborLedgerPendingEntry getExpenseA21ReversalPendingEntry(
118: LaborLedgerPostingDocument document,
119: ExpenseTransferAccountingLine accountingLine,
120: GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
121: LaborLedgerPendingEntry pendingEntry = getExpenseA21PendingEntry(
122: document, accountingLine, sequenceHelper);
123:
124: pendingEntry.setUniversityFiscalYear(accountingLine
125: .getPayrollEndDateFiscalYear());
126: pendingEntry.setUniversityFiscalPeriodCode(accountingLine
127: .getPayrollEndDateFiscalPeriodCode());
128:
129: String debitCreditCode = DebitCreditUtil
130: .getReverseDebitCreditCode(pendingEntry
131: .getTransactionDebitCreditCode());
132: pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
133:
134: return pendingEntry;
135: }
136:
137: /**
138: * convert the given document and accounting line into the benefit pending entries
139: *
140: * @param document the given accounting document
141: * @param accountingLine the given accounting line
142: * @param sequenceHelper the given squence helper
143: * @param benefitAmount the given benefit amount
144: * @param fringeBenefitObjectCode the given finge benefit object code
145: * @return a set of benefit pending entries
146: */
147: public static LaborLedgerPendingEntry getBenefitPendingEntry(
148: LaborLedgerPostingDocument document,
149: ExpenseTransferAccountingLine accountingLine,
150: GeneralLedgerPendingEntrySequenceHelper sequenceHelper,
151: KualiDecimal benefitAmount, String fringeBenefitObjectCode) {
152: LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(
153: document, accountingLine);
154:
155: // if account doesn't accept fringe charges and override not selected, use reports to account
156: if (!accountingLine.getAccount()
157: .isAccountsFringesBnftIndicator()) {
158: String overrideCode = accountingLine.getOverrideCode();
159: boolean canNonFringeAccountUsed = NON_FRINGE_ACCOUNT_USED
160: .equals(overrideCode);
161: canNonFringeAccountUsed = canNonFringeAccountUsed
162: || EXPIRED_ACCOUNT_AND_NON_FRINGE_ACCOUNT_USED
163: .equals(overrideCode);
164:
165: if (!canNonFringeAccountUsed) {
166: pendingEntry
167: .setChartOfAccountsCode(accountingLine
168: .getAccount()
169: .getReportsToChartOfAccountsCode());
170: pendingEntry.setAccountNumber(accountingLine
171: .getAccount().getReportsToAccountNumber());
172: }
173: }
174:
175: pendingEntry
176: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
177: pendingEntry.setFinancialObjectCode(pickValue(
178: fringeBenefitObjectCode, KFSConstants
179: .getDashFinancialObjectCode()));
180:
181: ObjectCode fringeObjectCode = SpringContext.getBean(
182: ObjectCodeService.class).getByPrimaryId(
183: accountingLine.getPayrollEndDateFiscalYear(),
184: accountingLine.getChartOfAccountsCode(),
185: fringeBenefitObjectCode);
186: pendingEntry.setFinancialObjectTypeCode(fringeObjectCode
187: .getFinancialObjectTypeCode());
188:
189: pendingEntry.setFinancialSubObjectCode(KFSConstants
190: .getDashFinancialSubObjectCode());
191: pendingEntry.setTransactionLedgerEntryAmount(benefitAmount
192: .abs());
193: pendingEntry.setPositionNumber(KFSConstants
194: .getDashPositionNumber());
195: pendingEntry.setEmplid(KFSConstants.getDashEmplId());
196: pendingEntry
197: .setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper));
198:
199: // year end document should post to previous fiscal year and final period
200: if (document instanceof YearEndDocument) {
201: pendingEntry.setUniversityFiscalYear(YearEndDocumentUtil
202: .getPreviousFiscalYear());
203: pendingEntry
204: .setUniversityFiscalPeriodCode(YearEndDocumentUtil
205: .getFINAL_ACCOUNTING_PERIOD());
206: }
207:
208: return pendingEntry;
209: }
210:
211: /**
212: * convert the given document and accounting line into the benefit pending entry for effort reporting
213: *
214: * @param document the given accounting document
215: * @param accountingLine the given accounting line
216: * @param sequenceHelper the given squence helper
217: * @param benefitAmount the given benefit amount
218: * @param fringeBenefitObjectCode the given finge benefit object code
219: * @return a set of benefit pending entries for effort reporting
220: */
221: public static LaborLedgerPendingEntry getBenefitA21PendingEntry(
222: LaborLedgerPostingDocument document,
223: ExpenseTransferAccountingLine accountingLine,
224: GeneralLedgerPendingEntrySequenceHelper sequenceHelper,
225: KualiDecimal benefitAmount, String fringeBenefitObjectCode) {
226: LaborLedgerPendingEntry pendingEntry = getBenefitPendingEntry(
227: document, accountingLine, sequenceHelper,
228: benefitAmount, fringeBenefitObjectCode);
229:
230: pendingEntry
231: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_A21);
232: String debitCreditCode = DebitCreditUtil
233: .getReverseDebitCreditCode(pendingEntry
234: .getTransactionDebitCreditCode());
235: pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
236:
237: return pendingEntry;
238: }
239:
240: /**
241: * convert the given document and accounting line into the benefit reversal pending entries for effort reporting
242: *
243: * @param document the given accounting document
244: * @param accountingLine the given accounting line
245: * @param sequenceHelper the given squence helper
246: * @param benefitAmount the given benefit amount
247: * @param fringeBenefitObjectCode the given finge benefit object code
248: * @return a set of benefit reversal pending entries for effort reporting
249: */
250: public static LaborLedgerPendingEntry getBenefitA21ReversalPendingEntry(
251: LaborLedgerPostingDocument document,
252: ExpenseTransferAccountingLine accountingLine,
253: GeneralLedgerPendingEntrySequenceHelper sequenceHelper,
254: KualiDecimal benefitAmount, String fringeBenefitObjectCode) {
255: LaborLedgerPendingEntry pendingEntry = getBenefitA21PendingEntry(
256: document, accountingLine, sequenceHelper,
257: benefitAmount, fringeBenefitObjectCode);
258:
259: pendingEntry.setUniversityFiscalYear(accountingLine
260: .getPayrollEndDateFiscalYear());
261: pendingEntry.setUniversityFiscalPeriodCode(accountingLine
262: .getPayrollEndDateFiscalPeriodCode());
263:
264: String debitCreditCode = DebitCreditUtil
265: .getReverseDebitCreditCode(pendingEntry
266: .getTransactionDebitCreditCode());
267: pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
268:
269: return pendingEntry;
270: }
271:
272: /**
273: * convert the given document into benefit clearing pending entries with the given account, chart, amount and benefit type
274: *
275: * @param document the given accounting document
276: * @param sequenceHelper the given squence helper
277: * @param accountNumber the given account number that the benefit clearing amount can be charged
278: * @param chartOfAccountsCode the given chart of accounts code that the benefit clearing amount can be charged
279: * @param benefitTypeCode the given benefit type code
280: * @param clearingAmount the benefit clearing amount
281: * @return a set of benefit clearing pending entries
282: */
283: public static LaborLedgerPendingEntry getBenefitClearingPendingEntry(
284: LaborLedgerPostingDocument document,
285: GeneralLedgerPendingEntrySequenceHelper sequenceHelper,
286: String accountNumber, String chartOfAccountsCode,
287: String benefitTypeCode, KualiDecimal clearingAmount) {
288: LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document);
289:
290: pendingEntry.setChartOfAccountsCode(chartOfAccountsCode);
291: pendingEntry.setAccountNumber(accountNumber);
292: pendingEntry.setSubAccountNumber(KFSConstants
293: .getDashSubAccountNumber());
294: pendingEntry
295: .setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
296:
297: Integer fiscalYear = SpringContext
298: .getBean(OptionsService.class).getCurrentYearOptions()
299: .getUniversityFiscalYear();
300: BenefitsCalculation benefitsCalculation = SpringContext
301: .getBean(LaborBenefitsCalculationService.class)
302: .getBenefitsCalculation(fiscalYear,
303: chartOfAccountsCode, benefitTypeCode);
304: String objectCode = benefitsCalculation
305: .getPositionFringeBenefitObjectCode();
306: pendingEntry.setFinancialObjectCode(objectCode);
307:
308: ObjectCode oc = SpringContext.getBean(ObjectCodeService.class)
309: .getByPrimaryId(fiscalYear, chartOfAccountsCode,
310: objectCode);
311: pendingEntry.setFinancialObjectTypeCode(oc
312: .getFinancialObjectTypeCode());
313:
314: pendingEntry.setFinancialSubObjectCode(KFSConstants
315: .getDashFinancialSubObjectCode());
316: pendingEntry
317: .setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper));
318:
319: String debitCreditCode = DebitCreditUtil.getDebitCreditCode(
320: clearingAmount, false);
321: pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
322: pendingEntry.setTransactionLedgerEntryAmount(clearingAmount
323: .abs());
324:
325: pendingEntry.setProjectCode(KFSConstants.getDashProjectCode());
326: pendingEntry.setPositionNumber(KFSConstants
327: .getDashPositionNumber());
328: pendingEntry.setEmplid(KFSConstants.getDashEmplId());
329: pendingEntry.setTransactionTotalHours(null);
330:
331: // year end document should post to previous fiscal year and final period
332: if (document instanceof YearEndDocument) {
333: pendingEntry.setUniversityFiscalYear(YearEndDocumentUtil
334: .getPreviousFiscalYear());
335: pendingEntry
336: .setUniversityFiscalPeriodCode(YearEndDocumentUtil
337: .getFINAL_ACCOUNTING_PERIOD());
338: }
339:
340: return pendingEntry;
341: }
342:
343: /**
344: * contruct a LaborLedgerPendingEntry object based on the information in the given document and accounting line. The object can
345: * be used as a template
346: *
347: * @param document the given document
348: * @param accountingLine the given accounting line
349: * @return a LaborLedgerPendingEntry object based on the information in the given document and accounting line
350: */
351: public static LaborLedgerPendingEntry getDefaultPendingEntry(
352: LaborLedgerPostingDocument document,
353: ExpenseTransferAccountingLine accountingLine) {
354: LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document);
355:
356: pendingEntry.setChartOfAccountsCode(accountingLine
357: .getChartOfAccountsCode());
358: pendingEntry
359: .setAccountNumber(accountingLine.getAccountNumber());
360: pendingEntry.setFinancialObjectCode(accountingLine
361: .getFinancialObjectCode());
362:
363: String subAccountNumber = pickValue(accountingLine
364: .getSubAccountNumber(), KFSConstants
365: .getDashSubAccountNumber());
366: pendingEntry.setSubAccountNumber(subAccountNumber);
367:
368: String subObjectCode = pickValue(accountingLine
369: .getFinancialSubObjectCode(), KFSConstants
370: .getDashFinancialSubObjectCode());
371: pendingEntry.setFinancialSubObjectCode(subObjectCode);
372:
373: String projectCode = pickValue(accountingLine.getProjectCode(),
374: KFSConstants.getDashProjectCode());
375: pendingEntry.setProjectCode(projectCode);
376:
377: accountingLine
378: .refreshReferenceObject(KFSPropertyConstants.OBJECT_CODE);
379: String objectTypeCode = accountingLine.getObjectCode()
380: .getFinancialObjectTypeCode();
381: pendingEntry.setFinancialObjectTypeCode(objectTypeCode);
382:
383: KualiDecimal transactionAmount = accountingLine.getAmount();
384: String debitCreditCode = DebitCreditUtil
385: .getDebitCreditCodeForExpenseDocument(accountingLine);
386: pendingEntry.setTransactionDebitCreditCode(debitCreditCode);
387: pendingEntry.setTransactionLedgerEntryAmount(transactionAmount
388: .abs());
389:
390: pendingEntry.setPositionNumber(accountingLine
391: .getPositionNumber());
392: pendingEntry.setEmplid(accountingLine.getEmplid());
393: pendingEntry.setPayrollEndDateFiscalYear(accountingLine
394: .getPayrollEndDateFiscalYear());
395: pendingEntry.setPayrollEndDateFiscalPeriodCode(accountingLine
396: .getPayrollEndDateFiscalPeriodCode());
397: pendingEntry.setTransactionTotalHours(accountingLine
398: .getPayrollTotalHours());
399: pendingEntry.setOrganizationReferenceId(accountingLine
400: .getOrganizationReferenceId());
401:
402: return pendingEntry;
403: }
404:
405: /**
406: * contruct a LaborLedgerPendingEntry object based on the information in the given document. The object can be used as a
407: * template
408: *
409: * @param document the given document
410: * @return a LaborLedgerPendingEntry object based on the information in the given document
411: */
412: public static LaborLedgerPendingEntry getDefaultPendingEntry(
413: LaborLedgerPostingDocument document) {
414: LaborLedgerPendingEntry pendingEntry = getSimpleDefaultPendingEntry();
415: DocumentHeader documentHeader = document.getDocumentHeader();
416:
417: String documentTypeCode = SpringContext.getBean(
418: DocumentTypeService.class).getDocumentTypeCodeByClass(
419: document.getClass());
420: pendingEntry.setFinancialDocumentTypeCode(documentTypeCode);
421:
422: pendingEntry.setDocumentNumber(documentHeader
423: .getDocumentNumber());
424: pendingEntry
425: .setTransactionLedgerEntryDescription(documentHeader
426: .getFinancialDocumentDescription());
427: pendingEntry.setOrganizationDocumentNumber(documentHeader
428: .getOrganizationDocumentNumber());
429:
430: return pendingEntry;
431: }
432:
433: /**
434: * contruct a LaborLedgerPendingEntry object based on the information in the given document and accounting line. The object can
435: * be used as a template
436: *
437: * @param document the given document
438: * @param accountingLine the given accounting line
439: * @return a LaborLedgerPendingEntry object based on the information in the given document and accounting line
440: */
441: public static LaborLedgerPendingEntry getSimpleDefaultPendingEntry() {
442: LaborLedgerPendingEntry pendingEntry = new LaborLedgerPendingEntry();
443:
444: pendingEntry.setUniversityFiscalYear(null);
445: pendingEntry.setUniversityFiscalPeriodCode(null);
446:
447: String originationCode = SpringContext.getBean(
448: HomeOriginationService.class).getHomeOrigination()
449: .getFinSystemHomeOriginationCode();
450: pendingEntry.setFinancialSystemOriginationCode(originationCode);
451:
452: Date transactionDate = SpringContext.getBean(
453: DateTimeService.class).getCurrentSqlDate();
454: pendingEntry.setTransactionDate(transactionDate);
455:
456: pendingEntry.setFinancialDocumentReversalDate(null);
457: pendingEntry.setReferenceFinancialSystemOriginationCode(null);
458: pendingEntry.setReferenceFinancialDocumentNumber(null);
459: pendingEntry.setReferenceFinancialDocumentTypeCode(null);
460:
461: return pendingEntry;
462: }
463:
464: /**
465: * Pick one from target and backup values based on the availabilty of target value
466: *
467: * @param targetValue the given target value
468: * @param backupValue the backup value of the target value
469: * @return target value if it is not null; otherwise, return its backup
470: */
471: private static String pickValue(String targetValue,
472: String backupValue) {
473: return StringUtils.isNotBlank(targetValue) ? targetValue
474: : backupValue;
475: }
476:
477: /**
478: * This method gets the next sequence number and increments.
479: *
480: * @param sequenceHelper the given squence helper
481: * @return the next sequence number and increments
482: */
483: private static Integer getNextSequenceNumber(
484: GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
485: Integer nextSequenceNumber = sequenceHelper
486: .getSequenceCounter();
487: sequenceHelper.increment();
488:
489: return nextSequenceNumber;
490: }
491: }
|