/*
 * The Kuali Financial System, a comprehensive financial management system for higher education.
 *
 * Copyright 2005-2016 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.tem.batch.service.impl;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.log4j.Logger;
import org.kuali.kfs.coa.businessobject.ObjectCode;
import org.kuali.kfs.coa.service.ObjectCodeService;
import org.kuali.kfs.coreservice.framework.parameter.ParameterService;
import org.kuali.kfs.krad.service.DataDictionaryService;
import org.kuali.kfs.krad.util.ObjectUtils;
import org.kuali.kfs.module.tem.TemConstants;
import org.kuali.kfs.module.tem.TemConstants.AgencyMatchProcessParameter;
import org.kuali.kfs.module.tem.TemParameterConstants;
import org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService;
import org.kuali.kfs.module.tem.businessobject.AgencyServiceFee;
import org.kuali.kfs.module.tem.businessobject.AgencyStagingData;
import org.kuali.kfs.module.tem.businessobject.ImportedExpense;
import org.kuali.kfs.module.tem.businessobject.TemSourceAccountingLine;
import org.kuali.kfs.module.tem.businessobject.TripAccountingInformation;
import org.kuali.kfs.module.tem.document.TravelDocument;
import org.kuali.kfs.module.tem.document.service.TravelDocumentService;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntry;
import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper;
import org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail;
import org.kuali.kfs.sys.document.validation.impl.AccountingDocumentRuleBaseConstants.GENERAL_LEDGER_PENDING_ENTRY_CODE;
import org.kuali.kfs.sys.service.GeneralLedgerPendingEntryService;
import org.kuali.kfs.sys.service.UniversityDateService;
import org.kuali.rice.core.api.datetime.DateTimeService;
import org.kuali.rice.core.api.util.type.KualiDecimal;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("deprecation")
public class ImportedExpensePendingEntryServiceImpl implements ImportedExpensePendingEntryService {

    private static Logger LOG = org.apache.log4j.Logger.getLogger(ImportedExpensePendingEntryServiceImpl.class);

    DateTimeService dateTimeService;
    UniversityDateService universityDateService;
    ParameterService parameterService;
    GeneralLedgerPendingEntryService generalLedgerPendingEntryService;
    TravelDocumentService travelDocumentService;
    ObjectCodeService objectCodeService;
    DataDictionaryService dataDictionaryService;


    /**
     * @see org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService#checkAndAddPendingEntriesToList(java.util.List, org.kuali.kfs.module.tem.businessobject.AgencyStagingData, boolean, boolean)
     */
    @Override
    public boolean checkAndAddPendingEntriesToList(List<GeneralLedgerPendingEntry> pendingEntries, List<GeneralLedgerPendingEntry> entryList, AgencyStagingData agencyData, boolean isCredit, boolean generateOffset) {
        boolean result = true;
        //if offset is expected, there should be two entries, otherwise only one
        int expectedEntrySize = generateOffset ? 2 : 1;

        if (pendingEntries.size() != expectedEntrySize) {
            LOG.error("Failed to create a " + (isCredit ? " CREDIT" : "DEBIT") + " GLPE for agency: " + agencyData.getId() + " tripId: " + agencyData.getTripId());
            result = false;
        } else {
            //validated, add to list
            entryList.addAll(pendingEntries);
        }

        return result;
    }

    /**
     * @see org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService#buildGeneralLedgerPendingEntry(org.kuali.kfs.module.tem.businessobject.AgencyStagingData, org.kuali.kfs.module.tem.businessobject.TripAccountingInformation, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, java.lang.String, java.lang.String, org.kuali.rice.kns.util.KualiDecimal, java.lang.String)
     */
    @Override
    public GeneralLedgerPendingEntry buildGeneralLedgerPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper,
                                                                    String chartCode, String objectCode, KualiDecimal amount, String glCredtiDebitCode) {

        ObjectCode objectCd = getObjectCodeService().getByPrimaryIdForCurrentYear(chartCode, objectCode);
        if (ObjectUtils.isNull(objectCd)) {
            LOG.error("ERROR: Could not get an ObjectCode for chart code: " + chartCode + " object code: " + objectCode);
            return null;
        }

        GeneralLedgerPendingEntry glpe = buildBasicDistributionPendingEntry(sequenceHelper);
        //setup document number by agency data
        glpe.setDocumentNumber(getImportExpenseDocumentNumber(agencyData));
        // customizations for glpe
        glpe.setChartOfAccountsCode(chartCode);
        glpe.setFinancialObjectCode(objectCode);
        glpe.setFinancialSubObjectCode(StringUtils.defaultIfEmpty(info.getSubObjectCode(), GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankFinancialSubObjectCode()));
        glpe.setFinancialObjectTypeCode(objectCd.getFinancialObjectTypeCode());
        glpe.setProjectCode(StringUtils.defaultIfEmpty(info.getProjectCode(), GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankProjectCode()));
        glpe.setTransactionLedgerEntryAmount(amount);
        glpe.setTransactionDebitCreditCode(glCredtiDebitCode);
        glpe.setTransactionDate(agencyData.getTransactionPostingDate());
        glpe.setOrganizationDocumentNumber(StringUtils.isNotEmpty(agencyData.getTravelerId()) ? agencyData.getTravelerId() : agencyData.getTripId());
        glpe.setFinancialDocumentApprovedCode(KFSConstants.PENDING_ENTRY_APPROVED_STATUS_CODE.APPROVED);

        return glpe;
    }

    /**
     * Builds a really basic distribution pending entry from a sequence helper; this can be used as the basis for other customizations by different methods
     *
     * @param sequenceHelper the sequence helper to help us set a sequence number on the GLPE
     * @return the beginnings of a GLPE
     */
    protected GeneralLedgerPendingEntry buildBasicDistributionPendingEntry(GeneralLedgerPendingEntrySequenceHelper sequenceHelper) {
        GeneralLedgerPendingEntry glpe = new GeneralLedgerPendingEntry();
        final String DIST_INCOME_DOC_TYPE = KFSConstants.FinancialDocumentTypeCodes.DISTRIBUTION_OF_INCOME_AND_EXPENSE;


        glpe.setVersionNumber(new Long(1));
        glpe.setUniversityFiscalYear(universityDateService.getCurrentFiscalYear());
        glpe.setFinancialBalanceTypeCode(KFSConstants.BALANCE_TYPE_ACTUAL);
        glpe.setFinancialDocumentTypeCode(DIST_INCOME_DOC_TYPE);
        glpe.setFinancialSystemOriginationCode(TemConstants.TEM_IMPORTED_SYS_ORIG_CD);
        glpe.setTransactionLedgerEntryDescription(TemConstants.TEM_IMPORTED_GLPE_DESC);
        glpe.setTransactionLedgerEntrySequenceNumber(new Integer(sequenceHelper.getSequenceCounter()));
        glpe.setOrganizationReferenceId(DIST_INCOME_DOC_TYPE + TemConstants.IMPORTED_FLAG);

        sequenceHelper.increment();

        return glpe;
    }

    /**
     * @see org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService#buildDebitPendingEntry(org.kuali.kfs.module.tem.businessobject.AgencyStagingData, org.kuali.kfs.module.tem.businessobject.TripAccountingInformation, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, java.lang.String, org.kuali.rice.kns.util.KualiDecimal, boolean)
     */
    @Override
    public List<GeneralLedgerPendingEntry> buildDebitPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String objectCode, KualiDecimal amount, boolean generateOffset) {

        List<GeneralLedgerPendingEntry> entryList = new ArrayList<GeneralLedgerPendingEntry>();

        GeneralLedgerPendingEntry pendingEntry = buildGeneralLedgerPendingEntry(agencyData, info, sequenceHelper, info.getTripChartCode(), objectCode, amount, KFSConstants.GL_DEBIT_CODE);
        if (ObjectUtils.isNotNull(pendingEntry)) {
            pendingEntry.setAccountNumber(info.getTripAccountNumber());
            pendingEntry.setSubAccountNumber(StringUtils.defaultIfEmpty(info.getTripSubAccountNumber(), GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankSubAccountNumber()));

            LOG.info("Created DEBIT GLPE: " + pendingEntry.getDocumentNumber() + " for AGENCY Import Expense: " + agencyData.getId() + " TripId: " + agencyData.getTripId()
                + "\n\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));

            //add to list if entry was created successfully
            entryList.add(pendingEntry);
            //handling offset
            if (generateOffset) {
                generateOffsetPendingEntry(entryList, sequenceHelper, pendingEntry);
            }
        }
        return entryList;
    }

    /**
     * @see org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService#buildCreditPendingEntry(org.kuali.kfs.module.tem.businessobject.AgencyStagingData, org.kuali.kfs.module.tem.businessobject.TripAccountingInformation, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, java.lang.String, org.kuali.rice.kns.util.KualiDecimal, boolean)
     */
    @Override
    public List<GeneralLedgerPendingEntry> buildCreditPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String objectCode, KualiDecimal amount, boolean generateOffset) {
        List<GeneralLedgerPendingEntry> entryList = new ArrayList<GeneralLedgerPendingEntry>();

        //get chart code from parameter
        String chartCode = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_CHART);

        GeneralLedgerPendingEntry pendingEntry = buildGeneralLedgerPendingEntry(agencyData, info, sequenceHelper, chartCode, objectCode, amount, KFSConstants.GL_CREDIT_CODE);
        if (ObjectUtils.isNotNull(pendingEntry)) {
            pendingEntry.setAccountNumber(parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_ACCOUNT));
            pendingEntry.setSubAccountNumber(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankSubAccountNumber());
        }

        LOG.info("Created CREDIT GLPE: " + pendingEntry.getDocumentNumber() + " for AGENCY Import Expense: " + agencyData.getId() + " TripId: " + agencyData.getTripId()
            + "\n\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));

        //add to list if entry was created successfully
        if (ObjectUtils.isNotNull(pendingEntry)) {
            entryList.add(pendingEntry);
            //handling offset
            if (generateOffset) {
                generateOffsetPendingEntry(entryList, sequenceHelper, pendingEntry);
            }
        }
        return entryList;
    }

    /**
     * @see org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService#buildCreditPendingEntryForImportedExpense(org.kuali.kfs.module.tem.businessobject.HistoricalTravelExpense, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, java.lang.String)
     */
    @Override
    public List<GeneralLedgerPendingEntry> buildDistributionEntriesForCTSExpense(ImportedExpense expense, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, String travelDocumentIdentifier) {
        List<GeneralLedgerPendingEntry> entries = new ArrayList<GeneralLedgerPendingEntry>();

        final String chartCode = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_CHART);
        final String accountNumber = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_ACCOUNT);
        final String creditObjectCode = parameterService.getParameterValueAsString(TemParameterConstants.TEM_ALL.class, AgencyMatchProcessParameter.TRAVEL_CREDIT_CARD_CLEARING_OBJECT_CODE);

        ObjectCode objectCd = getObjectCodeService().getByPrimaryIdForCurrentYear(chartCode, creditObjectCode);
        if (ObjectUtils.isNull(objectCd)) {
            LOG.error("ERROR: Could not get an ObjectCode for chart code: " + chartCode + " object code: " + creditObjectCode);
            return null;
        }

        GeneralLedgerPendingEntry explicitEntry = buildBasicDistributionPendingEntry(sequenceHelper);
        //setup document number by agency data
        explicitEntry.setDocumentNumber(expense.getDocumentNumber());
        // customizations for glpe
        explicitEntry.setChartOfAccountsCode(chartCode);
        explicitEntry.setAccountNumber(accountNumber);
        explicitEntry.setFinancialObjectCode(creditObjectCode);
        explicitEntry.setFinancialObjectTypeCode(objectCd.getFinancialObjectTypeCode());
        explicitEntry.setTransactionLedgerEntryAmount(expense.getConvertedAmount());
        explicitEntry.setTransactionDebitCreditCode(KFSConstants.GL_CREDIT_CODE);
        explicitEntry.setTransactionDate(dateTimeService.getCurrentSqlDate());
        explicitEntry.setOrganizationDocumentNumber(travelDocumentIdentifier);

        entries.add(explicitEntry);

        generateOffsetPendingEntry(entries, sequenceHelper, explicitEntry);

        return entries;
    }


    /**
     * @see org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService#buildCreditPendingEntry(org.kuali.kfs.module.tem.businessobject.AgencyStagingData, org.kuali.kfs.module.tem.businessobject.TripAccountingInformation, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, java.lang.String, org.kuali.rice.kns.util.KualiDecimal, boolean)
     */
    @Override
    public List<GeneralLedgerPendingEntry> buildServiceFeeCreditPendingEntry(AgencyStagingData agencyData, TripAccountingInformation info, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, AgencyServiceFee serviceFee, KualiDecimal amount, boolean generateOffset) {
        List<GeneralLedgerPendingEntry> entryList = new ArrayList<GeneralLedgerPendingEntry>();

        GeneralLedgerPendingEntry pendingEntry = buildGeneralLedgerPendingEntry(agencyData, info, sequenceHelper, serviceFee.getCreditChartCode(), serviceFee.getCreditObjectCode(), amount, KFSConstants.GL_CREDIT_CODE);
        if (ObjectUtils.isNotNull(pendingEntry)) {
            pendingEntry.setAccountNumber(serviceFee.getCreditAccountNumber());
            pendingEntry.setSubAccountNumber(GENERAL_LEDGER_PENDING_ENTRY_CODE.getBlankSubAccountNumber());
        }

        LOG.info("Created ServiceFee CREDIT GLPE: " + pendingEntry.getDocumentNumber() + " for AGENCY Import Expense: " + agencyData.getId() + " TripId: " + agencyData.getTripId()
            + "\n\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));

        //add to list if entry was created successfully
        if (ObjectUtils.isNotNull(pendingEntry)) {
            entryList.add(pendingEntry);
            //handling offset
            if (generateOffset) {
                generateOffsetPendingEntry(entryList, sequenceHelper, pendingEntry);
            }
        }
        return entryList;
    }

    /**
     * Generate the offset entry from the given pending entry.  If entry is created successfully, add to the entry list
     *
     * @param entryList
     * @param sequenceHelper
     * @param pendingEntry
     */
    private void generateOffsetPendingEntry(List<GeneralLedgerPendingEntry> entryList, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntry pendingEntry) {
        GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(pendingEntry);
        boolean success = generalLedgerPendingEntryService.populateOffsetGeneralLedgerPendingEntry(universityDateService.getCurrentFiscalYear(), pendingEntry, sequenceHelper, offsetEntry);
        sequenceHelper.increment();
        if (success) {
            LOG.info("Created OFFSET GLPE: " + pendingEntry.getDocumentNumber() + "\n" + ReflectionToStringBuilder.reflectionToString(pendingEntry, ToStringStyle.MULTI_LINE_STYLE));
            entryList.add(offsetEntry);
        }
    }

    /**
     * @see org.kuali.kfs.module.tem.batch.service.ImportedExpensePendingEntryService#generateDocumentImportedExpenseGeneralLedgerPendingEntries(org.kuali.kfs.module.tem.document.TravelDocument, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySourceDetail, org.kuali.kfs.sys.businessobject.GeneralLedgerPendingEntrySequenceHelper, boolean, java.lang.String)
     */
    @Override
    public boolean generateDocumentImportedExpenseGeneralLedgerPendingEntries(TravelDocument travelDocument, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, boolean isCredit, String docType) {
        LOG.debug("processGenerateGeneralLedgerPendingEntries(TravelDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper, boolean) - start");

        glpeSourceDetail.getObjectCode().setChartOfAccountsCode(glpeSourceDetail.getChartOfAccountsCode());
        glpeSourceDetail.getObjectCode().setFinancialObjectCode(glpeSourceDetail.getFinancialObjectCode());
        glpeSourceDetail.getObjectCode().setUniversityFiscalYear(glpeSourceDetail.getPostingYear());

        ((TemSourceAccountingLine) glpeSourceDetail).getObjectTypeCode();

        // handle the explicit entry
        // create a reference to the explicitEntry to be populated, so we can pass to the offset method later
        GeneralLedgerPendingEntry explicitEntry = new GeneralLedgerPendingEntry();
        processExplicitGeneralLedgerPendingEntry(travelDocument, sequenceHelper, glpeSourceDetail, explicitEntry);

        explicitEntry.setFinancialDocumentTypeCode(docType);
        explicitEntry.setTransactionLedgerEntryDescription(TemConstants.TEM_IMPORTED_GLPE_DESC);
        explicitEntry.setOrganizationDocumentNumber(travelDocument.getTravelDocumentIdentifier());
        explicitEntry.setDocumentNumber(getImportExpenseDocumentNumber(travelDocument));
        explicitEntry.setOrganizationReferenceId(travelDocument.getFinancialDocumentTypeCode() + TemConstants.IMPORTED_FLAG);
        final String transactionCode = isCredit ? KFSConstants.GL_CREDIT_CODE : KFSConstants.GL_DEBIT_CODE;
        explicitEntry.setTransactionDebitCreditCode(transactionCode);

        // increment the sequence counter
        sequenceHelper.increment();

        // handle the offset entry
        GeneralLedgerPendingEntry offsetEntry = new GeneralLedgerPendingEntry(explicitEntry);
        explicitEntry.setOrganizationReferenceId(travelDocument.getFinancialDocumentTypeCode() + TemConstants.IMPORTED_FLAG);
        boolean success = processOffsetGeneralLedgerPendingEntry(travelDocument, sequenceHelper, glpeSourceDetail, explicitEntry, offsetEntry);
        sequenceHelper.increment();

        LOG.debug("processGenerateGeneralLedgerPendingEntries(TravelDocument, AccountingLine, GeneralLedgerPendingEntrySequenceHelper, boolean) - end");
        return success;
    }

    /**
     * @param travelDocument
     * @param sequenceHelper
     * @param glpeSourceDetail
     * @param explicitEntry
     */
    private void processExplicitGeneralLedgerPendingEntry(TravelDocument travelDocument, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail glpeSourceDetail, GeneralLedgerPendingEntry explicitEntry) {
        LOG.debug("processExplicitGeneralLedgerPendingEntry(TravelDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry) ");

        generalLedgerPendingEntryService.populateExplicitGeneralLedgerPendingEntry(travelDocument, glpeSourceDetail, sequenceHelper, explicitEntry);
        travelDocument.addPendingEntry(explicitEntry);
    }

    /**
     * @param travelDocument
     * @param sequenceHelper
     * @param postable
     * @param explicitEntry
     * @param offsetEntry
     * @return
     */
    private boolean processOffsetGeneralLedgerPendingEntry(TravelDocument travelDocument, GeneralLedgerPendingEntrySequenceHelper sequenceHelper, GeneralLedgerPendingEntrySourceDetail postable, GeneralLedgerPendingEntry explicitEntry, GeneralLedgerPendingEntry offsetEntry) {
        LOG.debug("processOffsetGeneralLedgerPendingEntry(TravelDocument, GeneralLedgerPendingEntrySequenceHelper, AccountingLine, GeneralLedgerPendingEntry, GeneralLedgerPendingEntry) ");

        // populate the offset entry
        boolean success = generalLedgerPendingEntryService.populateOffsetGeneralLedgerPendingEntry(travelDocument.getPostingYear(), explicitEntry, sequenceHelper, offsetEntry);
        travelDocument.addPendingEntry(offsetEntry);
        return success;
    }

    /**
     * Returns the Document Number to set on the GLPE
     *
     * @param travelDocument
     * @return
     */
    protected String getImportExpenseDocumentNumber(TravelDocument travelDocument) {
        if (ObjectUtils.isNotNull(travelDocument)) {
            return travelDocument.getDocumentNumber();
        } else {
            return null;
        }
    }

    /**
     * Returns the Document Number to set on the GLPE
     *
     * @param agencyData
     * @return
     */
    protected String getImportExpenseDocumentNumber(AgencyStagingData agencyData) {
        TravelDocument travelDocument = getTravelDocumentService().getParentTravelDocument(agencyData.getTripId());
        return getImportExpenseDocumentNumber(travelDocument);
    }

    public void setDateTimeService(DateTimeService dateTimeService) {
        this.dateTimeService = dateTimeService;
    }

    public void setUniversityDateService(UniversityDateService universityDateService) {
        this.universityDateService = universityDateService;
    }

    public void setParameterService(ParameterService parameterService) {
        this.parameterService = parameterService;
    }

    public void setGeneralLedgerPendingEntryService(GeneralLedgerPendingEntryService generalLedgerPendingEntryService) {
        this.generalLedgerPendingEntryService = generalLedgerPendingEntryService;
    }

    public TravelDocumentService getTravelDocumentService() {
        return travelDocumentService;
    }

    public void setTravelDocumentService(TravelDocumentService travelDocumentService) {
        this.travelDocumentService = travelDocumentService;
    }

    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;
    }
}
