/* * The Kuali Financial System, a comprehensive financial management system for higher education. * * Copyright 2005-2014 The Kuali Foundation * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.kuali.kfs.module.ld.document.service.impl; import java.sql.Date; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.coa.businessobject.ObjectCode; import org.kuali.kfs.coa.service.ObjectCodeService; import org.kuali.kfs.fp.document.YearEndDocument; import org.kuali.kfs.fp.document.service.YearEndPendingEntryService; import org.kuali.kfs.module.ld.LaborConstants; import org.kuali.kfs.module.ld.businessobject.BenefitsCalculation; import org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine; import org.kuali.kfs.module.ld.businessobject.LaborLedgerPendingEntry; import org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument; import org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService; import org.kuali.kfs.module.ld.service.LaborBenefitsCalculationService; import org.kuali.kfs.module.ld.util.DebitCreditUtil; import org.kuali.kfs.sys.KFSConstants; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper; import org.kuali.kfs.sys.service.HomeOriginationService; import org.kuali.kfs.sys.service.OptionsService; import org.kuali.rice.core.api.datetime.DateTimeService; import org.kuali.rice.core.api.util.type.KualiDecimal; import org.kuali.rice.kns.service.DataDictionaryService; import org.kuali.rice.krad.bo.DocumentHeader; /** * Default implementation of the LaborPendingEntryConverterService */ public class LaborPendingEntryConverterServiceImpl implements LaborPendingEntryConverterService { protected HomeOriginationService homeOriginationService; protected LaborBenefitsCalculationService laborBenefitsCalculationService; protected OptionsService optionsService; protected ObjectCodeService objectCodeService; protected DataDictionaryService dataDictionaryService; protected DateTimeService dateTimeService; protected YearEndPendingEntryService yearEndPendingEntryService; /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitA21PendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, org.kuali.rice.core.api.util.type.KualiDecimal, java.lang.String) */ public LaborLedgerPendingEntry getBenefitA21PendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, KualiDecimal benefitAmount, String fringeBenefitObjectCode) { LaborLedgerPendingEntry pendingEntry = getBenefitPendingEntry(document, accountingLine, sequenceHelper, benefitAmount, fringeBenefitObjectCode); pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_A21); String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode()); pendingEntry.setTransactionDebitCreditCode(debitCreditCode); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitA21ReversalPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, org.kuali.rice.core.api.util.type.KualiDecimal, java.lang.String) */ public LaborLedgerPendingEntry getBenefitA21ReversalPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, KualiDecimal benefitAmount, String fringeBenefitObjectCode) { LaborLedgerPendingEntry pendingEntry = getBenefitA21PendingEntry(document, accountingLine, sequenceHelper, benefitAmount, fringeBenefitObjectCode); pendingEntry.setUniversityFiscalYear(accountingLine.getPayrollEndDateFiscalYear()); pendingEntry.setUniversityFiscalPeriodCode(accountingLine.getPayrollEndDateFiscalPeriodCode()); String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode()); pendingEntry.setTransactionDebitCreditCode(debitCreditCode); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitClearingPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, java.lang.String, java.lang.String, java.lang.String, org.kuali.rice.core.api.util.type.KualiDecimal) */ public LaborLedgerPendingEntry getBenefitClearingPendingEntry(LaborLedgerPostingDocument document, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String accountNumber, String chartOfAccountsCode, String benefitTypeCode, KualiDecimal clearingAmount) { LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document); pendingEntry.setChartOfAccountsCode(chartOfAccountsCode); pendingEntry.setAccountNumber(accountNumber); pendingEntry.setSubAccountNumber(KFSConstants.getDashSubAccountNumber()); pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL); Integer fiscalYear = getOptionsService().getCurrentYearOptions().getUniversityFiscalYear(); BenefitsCalculation benefitsCalculation = getLaborBenefitsCalculationService().getBenefitsCalculation(fiscalYear, chartOfAccountsCode, benefitTypeCode); String objectCode = benefitsCalculation.getPositionFringeBenefitObjectCode(); pendingEntry.setFinancialObjectCode(objectCode); ObjectCode oc = getObjectCodeService().getByPrimaryId(fiscalYear, chartOfAccountsCode, objectCode); pendingEntry.setFinancialObjectTypeCode(oc.getFinancialObjectTypeCode()); pendingEntry.setFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode()); pendingEntry.setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper)); String debitCreditCode = DebitCreditUtil.getDebitCreditCode(clearingAmount, false); pendingEntry.setTransactionDebitCreditCode(debitCreditCode); pendingEntry.setTransactionLedgerEntryAmount(clearingAmount.abs()); pendingEntry.setProjectCode(KFSConstants.getDashProjectCode()); pendingEntry.setPositionNumber(LaborConstants.getDashPositionNumber()); pendingEntry.setEmplid(LaborConstants.getDashEmplId()); pendingEntry.setTransactionTotalHours(null); overrideEntryForYearEndIfNecessary(document, pendingEntry); return pendingEntry; } /** * Updates the given LLPE for year end documents * @param document the document to check if it is YearEnd * @param pendingEntry the pending entry to update */ protected void overrideEntryForYearEndIfNecessary(LaborLedgerPostingDocument document, LaborLedgerPendingEntry pendingEntry) { // year end document should post to previous fiscal year and final period if (document instanceof YearEndDocument) { pendingEntry.setUniversityFiscalYear(getYearEndPendingEntryService().getPreviousFiscalYear()); pendingEntry.setUniversityFiscalPeriodCode(getYearEndPendingEntryService().getFinalAccountingPeriod()); } } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getBenefitPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, org.kuali.rice.core.api.util.type.KualiDecimal, java.lang.String) */ public LaborLedgerPendingEntry getBenefitPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, KualiDecimal benefitAmount, String fringeBenefitObjectCode) { LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document, accountingLine); // if account doesn't accept fringe charges, use reports to account if (!accountingLine.getAccount().isAccountsFringesBnftIndicator()) { pendingEntry.setChartOfAccountsCode(accountingLine.getAccount().getReportsToChartOfAccountsCode()); pendingEntry.setAccountNumber(accountingLine.getAccount().getReportsToAccountNumber()); } pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL); pendingEntry.setFinancialObjectCode(pickValue(fringeBenefitObjectCode, KFSConstants.getDashFinancialObjectCode())); ObjectCode fringeObjectCode = getObjectCodeService().getByPrimaryId(accountingLine.getPayrollEndDateFiscalYear(), accountingLine.getChartOfAccountsCode(), fringeBenefitObjectCode); pendingEntry.setFinancialObjectTypeCode(fringeObjectCode.getFinancialObjectTypeCode()); pendingEntry.setFinancialSubObjectCode(KFSConstants.getDashFinancialSubObjectCode()); pendingEntry.setTransactionLedgerEntryAmount(benefitAmount.abs()); pendingEntry.setPositionNumber(LaborConstants.getDashPositionNumber()); pendingEntry.setEmplid(LaborConstants.getDashEmplId()); pendingEntry.setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper)); // year end document should post to previous fiscal year and final period overrideEntryForYearEndIfNecessary(document, pendingEntry); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getDefaultPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine) */ public LaborLedgerPendingEntry getDefaultPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine) { LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document); pendingEntry.setUniversityFiscalYear(accountingLine.getPostingYear()); pendingEntry.setChartOfAccountsCode(accountingLine.getChartOfAccountsCode()); pendingEntry.setAccountNumber(accountingLine.getAccountNumber()); pendingEntry.setFinancialObjectCode(accountingLine.getFinancialObjectCode()); String subAccountNumber = pickValue(accountingLine.getSubAccountNumber(), KFSConstants.getDashSubAccountNumber()); pendingEntry.setSubAccountNumber(subAccountNumber); String subObjectCode = pickValue(accountingLine.getFinancialSubObjectCode(), KFSConstants.getDashFinancialSubObjectCode()); pendingEntry.setFinancialSubObjectCode(subObjectCode); String projectCode = pickValue(accountingLine.getProjectCode(), KFSConstants.getDashProjectCode()); pendingEntry.setProjectCode(projectCode); accountingLine.refreshReferenceObject(KFSPropertyConstants.OBJECT_CODE); String objectTypeCode = accountingLine.getObjectCode().getFinancialObjectTypeCode(); pendingEntry.setFinancialObjectTypeCode(objectTypeCode); KualiDecimal transactionAmount = accountingLine.getAmount(); String debitCreditCode = DebitCreditUtil.getDebitCreditCodeForExpenseDocument(accountingLine); pendingEntry.setTransactionDebitCreditCode(debitCreditCode); pendingEntry.setTransactionLedgerEntryAmount(transactionAmount.abs()); pendingEntry.setPositionNumber(accountingLine.getPositionNumber()); pendingEntry.setEmplid(accountingLine.getEmplid()); pendingEntry.setPayrollEndDateFiscalYear(accountingLine.getPayrollEndDateFiscalYear()); pendingEntry.setPayrollEndDateFiscalPeriodCode(accountingLine.getPayrollEndDateFiscalPeriodCode()); pendingEntry.setTransactionTotalHours(accountingLine.getPayrollTotalHours()); pendingEntry.setOrganizationReferenceId(accountingLine.getOrganizationReferenceId()); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getDefaultPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument) */ public LaborLedgerPendingEntry getDefaultPendingEntry(LaborLedgerPostingDocument document) { LaborLedgerPendingEntry pendingEntry = getSimpleDefaultPendingEntry(); DocumentHeader documentHeader = document.getDocumentHeader(); String documentTypeCode = getDataDictionaryService().getDocumentTypeNameByClass(document.getClass()); pendingEntry.setFinancialDocumentTypeCode(documentTypeCode); pendingEntry.setDocumentNumber(documentHeader.getDocumentNumber()); pendingEntry.setTransactionLedgerEntryDescription(documentHeader.getDocumentDescription()); pendingEntry.setOrganizationDocumentNumber(documentHeader.getOrganizationDocumentNumber()); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getExpenseA21PendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) */ public LaborLedgerPendingEntry getExpenseA21PendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { LaborLedgerPendingEntry pendingEntry = getExpensePendingEntry(document, accountingLine, sequenceHelper); pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_A21); String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode()); pendingEntry.setTransactionDebitCreditCode(debitCreditCode); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getExpenseA21ReversalPendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) */ public LaborLedgerPendingEntry getExpenseA21ReversalPendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { LaborLedgerPendingEntry pendingEntry = getExpenseA21PendingEntry(document, accountingLine, sequenceHelper); pendingEntry.setUniversityFiscalYear(accountingLine.getPayrollEndDateFiscalYear()); pendingEntry.setUniversityFiscalPeriodCode(accountingLine.getPayrollEndDateFiscalPeriodCode()); String debitCreditCode = DebitCreditUtil.getReverseDebitCreditCode(pendingEntry.getTransactionDebitCreditCode()); pendingEntry.setTransactionDebitCreditCode(debitCreditCode); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getExpensePendingEntry(org.kuali.kfs.module.ld.document.LaborLedgerPostingDocument, org.kuali.kfs.module.ld.businessobject.ExpenseTransferAccountingLine, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper) */ public LaborLedgerPendingEntry getExpensePendingEntry(LaborLedgerPostingDocument document, ExpenseTransferAccountingLine accountingLine, GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { LaborLedgerPendingEntry pendingEntry = getDefaultPendingEntry(document, accountingLine); pendingEntry.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL); pendingEntry.setTransactionLedgerEntrySequenceNumber(getNextSequenceNumber(sequenceHelper)); // year end document should post to previous fiscal year and final period overrideEntryForYearEndIfNecessary(document, pendingEntry); return pendingEntry; } /** * @see org.kuali.kfs.module.ld.document.service.LaborPendingEntryConverterService#getSimpleDefaultPendingEntry() */ public LaborLedgerPendingEntry getSimpleDefaultPendingEntry() { LaborLedgerPendingEntry pendingEntry = new LaborLedgerPendingEntry(); pendingEntry.setUniversityFiscalYear(null); pendingEntry.setUniversityFiscalPeriodCode(null); String originationCode = getHomeOriginationService().getHomeOrigination().getFinSystemHomeOriginationCode(); pendingEntry.setFinancialSystemOriginationCode(originationCode); Date transactionDate = getDateTimeService().getCurrentSqlDate(); pendingEntry.setTransactionDate(transactionDate); pendingEntry.setFinancialDocumentReversalDate(null); pendingEntry.setReferenceFinancialSystemOriginationCode(null); pendingEntry.setReferenceFinancialDocumentNumber(null); pendingEntry.setReferenceFinancialDocumentTypeCode(null); return pendingEntry; } /** * Pick one from target and backup values based on the availability of target value * * @param targetValue the given target value * @param backupValue the backup value of the target value * @return target value if it is not null; otherwise, return its backup */ protected String pickValue(String targetValue, String backupValue) { return StringUtils.isNotBlank(targetValue) ? targetValue : backupValue; } /** * This method gets the next sequence number and increments. * * @param sequenceHelper the given sequence helper * @return the next sequence number and increments */ protected Integer getNextSequenceNumber(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) { Integer nextSequenceNumber = sequenceHelper.getSequenceCounter(); sequenceHelper.increment(); return nextSequenceNumber; } public HomeOriginationService getHomeOriginationService() { return homeOriginationService; } public void setHomeOriginationService(HomeOriginationService homeOriginationService) { this.homeOriginationService = homeOriginationService; } public LaborBenefitsCalculationService getLaborBenefitsCalculationService() { return laborBenefitsCalculationService; } public void setLaborBenefitsCalculationService(LaborBenefitsCalculationService laborBenefitsCalculationService) { this.laborBenefitsCalculationService = laborBenefitsCalculationService; } public OptionsService getOptionsService() { return optionsService; } public void setOptionsService(OptionsService optionsService) { this.optionsService = optionsService; } public ObjectCodeService getObjectCodeService() { return objectCodeService; } public void setObjectCodeService(ObjectCodeService objectCodeService) { this.objectCodeService = objectCodeService; } public DataDictionaryService getDataDictionaryService() { return dataDictionaryService; } public void setDataDictionaryService(DataDictionaryService dataDictionaryService) { this.dataDictionaryService = dataDictionaryService; } public DateTimeService getDateTimeService() { return dateTimeService; } public void setDateTimeService(DateTimeService dateTimeService) { this.dateTimeService = dateTimeService; } public YearEndPendingEntryService getYearEndPendingEntryService() { return yearEndPendingEntryService; } public void setYearEndPendingEntryService(YearEndPendingEntryService yearEndPendingEntryService) { this.yearEndPendingEntryService = yearEndPendingEntryService; } }