/*
 * 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.ec.document;

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

import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Organization;
import org.kuali.kfs.module.ec.businessobject.EffortCertificationDetail;
import org.kuali.kfs.module.ec.businessobject.EffortCertificationReportDefinition;
import org.kuali.kfs.module.ec.service.EffortCertificationDocumentService;
import org.kuali.kfs.module.ec.util.EffortCertificationParameterFinder;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.businessobject.SystemOptions;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase;
import org.kuali.kfs.sys.service.impl.KfsParameterConstants;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.coreservice.framework.parameter.ParameterConstants.COMPONENT;
import org.kuali.rice.coreservice.framework.parameter.ParameterService;
import org.kuali.rice.kew.api.WorkflowDocument;
import org.kuali.rice.kew.framework.postprocessor.DocumentRouteStatusChange;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.identity.PersonService;
import org.kuali.rice.krad.UserSession;
import org.kuali.rice.krad.util.GlobalVariables;
import org.kuali.rice.krad.util.ObjectUtils;

/**
 * Effort Certification Document Class.
 */
@COMPONENT(component="EffortCertification")
public class EffortCertificationDocument extends FinancialSystemTransactionalDocumentBase  {
    protected static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(EffortCertificationDocument.class);

    protected static final String DO_AWARD_SPLIT = "DoAwardSplit";
    protected static final String DO_RECREATE_SPLIT = "DoRecreateSplit";

    protected String effortCertificationReportNumber;
    protected boolean effortCertificationDocumentCode;
    protected Integer universityFiscalYear;
    protected String emplid;
    protected String organizationCode;
    protected KualiDecimal financialDocumentTotalAmount;

    protected Integer totalEffortPercent;
    protected Integer totalOriginalEffortPercent;
    protected KualiDecimal totalPayrollAmount;
    protected KualiDecimal totalOriginalPayrollAmount;

    protected EffortCertificationReportDefinition effortCertificationReportDefinition;
    protected Person employee;
    protected Organization organization;
    protected SystemOptions options;

    protected List<EffortCertificationDetail> effortCertificationDetailLines;
    protected List<EffortCertificationDetail> summarizedDetailLines;

    protected Person ledgerPerson;

    /**
     * Default constructor.
     */
    public EffortCertificationDocument() {
        super();

        effortCertificationDetailLines = new ArrayList<EffortCertificationDetail>();
        summarizedDetailLines = new ArrayList<EffortCertificationDetail>();
    }

    /**
     * Gets the effortCertificationReportNumber attribute.
     *
     * @return Returns the effortCertificationReportNumber.
     */
    public String getEffortCertificationReportNumber() {
        return effortCertificationReportNumber;
    }

    /**
     * Sets the effortCertificationReportNumber attribute value.
     *
     * @param effortCertificationReportNumber The effortCertificationReportNumber to set.
     */
    public void setEffortCertificationReportNumber(String effortCertificationReportNumber) {
        this.effortCertificationReportNumber = effortCertificationReportNumber;
    }

    /**
     * Gets the effortCertificationDocumentCode attribute.
     *
     * @return Returns the effortCertificationDocumentCode.
     */
    public boolean getEffortCertificationDocumentCode() {
        return effortCertificationDocumentCode;
    }

    /**
     * Sets the effortCertificationDocumentCode attribute value.
     *
     * @param effortCertificationDocumentCode The effortCertificationDocumentCode to set.
     */
    public void setEffortCertificationDocumentCode(boolean effortCertificationDocumentCode) {
        this.effortCertificationDocumentCode = effortCertificationDocumentCode;
    }

    /**
     * Gets the universityFiscalYear attribute.
     *
     * @return Returns the universityFiscalYear.
     */
    public Integer getUniversityFiscalYear() {
        return universityFiscalYear;
    }

    /**
     * Sets the universityFiscalYear attribute value.
     *
     * @param universityFiscalYear The universityFiscalYear to set.
     */
    public void setUniversityFiscalYear(Integer universityFiscalYear) {
        this.universityFiscalYear = universityFiscalYear;
    }

    /**
     * Gets the organizationCode attribute.
     *
     * @return Returns the organizationCode.
     */
    public String getOrganizationCode() {
        return organizationCode;
    }

    /**
     * Sets the organizationCode attribute value.
     *
     * @param organizationCode The organizationCode to set.
     */
    public void setOrganizationCode(String organizationCode) {
        this.organizationCode = organizationCode;
    }

    /**
     * Gets the organization attribute.
     *
     * @return Returns the organization.
     */
    public Organization getOrganization() {
        return organization;
    }

    /**
     * Sets the organization attribute value.
     *
     * @param organization The organization to set.
     */
    public void setOrganization(Organization organization) {
        this.organization = organization;
    }

    /**
     * Gets the emplid attribute.
     *
     * @return Returns the emplid.
     */
    public String getEmplid() {
        return emplid;
    }

    /**
     * Sets the emplid attribute value.
     *
     * @param emplid The emplid to set.
     */
    public void setEmplid(String emplid) {
        this.emplid = emplid;
    }

    /**
     * Gets the effortCertificationReportDefinition attribute.
     *
     * @return Returns the effortCertificationReportDefinition.
     */
    public EffortCertificationReportDefinition getEffortCertificationReportDefinition() {
        return effortCertificationReportDefinition;
    }

    /**
     * Sets the effortCertificationReportDefinition attribute value.
     *
     * @param effortCertificationReportDefinition The effortCertificationReportDefinition to set.
     */
    @Deprecated
    public void setEffortCertificationReportDefinition(EffortCertificationReportDefinition effortCertificationReportDefinition) {
        this.effortCertificationReportDefinition = effortCertificationReportDefinition;
    }

    /**
     * Gets the employee attribute.
     *
     * @return Returns the employee.
     */
    public Person getEmployee() {
        if ( StringUtils.isNotBlank( getEmplid() ) ) {
            return SpringContext.getBean(PersonService.class).getPersonByEmployeeId(getEmplid());
        } else {
            return null;
        }
    }

    /**
     * Sets the employee attribute value.
     *
     * @param employee The employee to set.
     */
    public void setEmployee(Person employee) {
        this.employee = employee;
    }

    /**
     * Gets the Person
     *
     * @return Returns the Person
     */
    public Person getLedgerPerson() {
        if( (ledgerPerson == null || !StringUtils.equals(ledgerPerson.getEmployeeId(), emplid)) && StringUtils.isNotBlank( emplid )) {
            ledgerPerson = SpringContext.getBean(PersonService.class).getPersonByEmployeeId(emplid);
        }

        return ledgerPerson;
    }

    /**
     * Sets the ledgerPerson
     *
     * @param ledgerPerson The ledgerPerson to set.
     */
    public void setLedgerPerson(Person ledgerPerson) {
        this.ledgerPerson = ledgerPerson;
    }

    /**
     * Gets the options attribute.
     *
     * @return Returns the options.
     */
    public SystemOptions getOptions() {
        return options;
    }

    /**
     * Sets the options attribute value.
     *
     * @param options The options to set.
     */
    public void setOptions(SystemOptions options) {
        this.options = options;
    }

    /**
     * Gets the effortCertificationDetailLines attribute.
     *
     * @return Returns the effortCertificationDetailLines.
     */
    public List<EffortCertificationDetail> getEffortCertificationDetailLines() {
        return effortCertificationDetailLines;
    }

    /**
     * Sets the effortCertificationDetailLines attribute value.
     *
     * @param effortCertificationDetailLines The effortCertificationDetailLines to set.
     */
    @Deprecated
    public void setEffortCertificationDetailLines(List<EffortCertificationDetail> effortCertificationDetailLines) {
        this.effortCertificationDetailLines = effortCertificationDetailLines;
    }

    /**
     * get the total amount of the given effort certification document
     *
     * @param effortCertificationDocument the given effort certification document
     * @return the total amount of the given effort certification document
     */
    public static KualiDecimal getDocumentTotalAmount(EffortCertificationDocument effortCertificationDocument) {
        List<EffortCertificationDetail> detailLines = effortCertificationDocument.getEffortCertificationDetailLines();
        return EffortCertificationDetail.getTotalPayrollAmount(detailLines);
    }

    /**
     * @see org.kuali.rice.krad.document.DocumentBase#doRouteStatusChange()
     */
    @Override
    public void doRouteStatusChange(DocumentRouteStatusChange statusChangeEvent) {
        LOG.debug("doRouteStatusChange() start...");

        super.doRouteStatusChange(statusChangeEvent);
        WorkflowDocument workflowDocument = this.getDocumentHeader().getWorkflowDocument();
        if (workflowDocument.isFinal()) {
            GlobalVariables.setUserSession(new UserSession(KFSConstants.SYSTEM_USER));
            SpringContext.getBean(EffortCertificationDocumentService.class).generateSalaryExpenseTransferDocument(this);
        }
        //           SpringContext.getBean(EffortCertificationDocumentService.class).processApprovedEffortCertificationDocument(this);
    }

    /**
     * Gets the totalEffortPercent attribute.
     *
     * @return Returns the totalEffortPercent.
     */
    public Integer getTotalEffortPercent() {
        return EffortCertificationDetail.getTotalEffortPercent(this.getEffortCertificationDetailLines());
    }

    /**
     * Gets the totalOriginalEffortPercent attribute.
     *
     * @return Returns the totalOriginalEffortPercent.
     */
    public Integer getTotalOriginalEffortPercent() {
        return EffortCertificationDetail.getTotalOriginalEffortPercent(this.getEffortCertificationDetailLines());
    }

    /**
     * Gets the totalPayrollAmount attribute.
     *
     * @return Returns the totalPayrollAmount.
     */
    public KualiDecimal getTotalPayrollAmount() {
        return EffortCertificationDetail.getTotalPayrollAmount(this.getEffortCertificationDetailLines());
    }

    /**
     * Gets the totalOriginalPayrollAmount attribute.
     *
     * @return Returns the totalOriginalPayrollAmount.
     */
    public KualiDecimal getTotalOriginalPayrollAmount() {
        return EffortCertificationDetail.getTotalOriginalPayrollAmount(this.getEffortCertificationDetailLines());
    }

    /**
     * find the detail lines that have max payroll amount
     *
     * @return the detail lines that have max payroll amount
     */
    public List<EffortCertificationDetail> getEffortCertificationDetailWithMaxPayrollAmount() {
        List<EffortCertificationDetail> detailLines = new ArrayList<EffortCertificationDetail>();

        KualiDecimal maxAmount = null;
        for (EffortCertificationDetail line : this.getEffortCertificationDetailLines()) {
            KualiDecimal currentAmount = line.getEffortCertificationPayrollAmount();

            if (maxAmount == null) {
                maxAmount = currentAmount;
                detailLines.add(line);
                continue;
            }

            if (maxAmount.isLessThan(currentAmount)) {
                detailLines.removeAll(detailLines);
                maxAmount = currentAmount;
                detailLines.add(line);
            }
            else if (maxAmount.equals(currentAmount)) {
                detailLines.add(line);
            }
        }

        return detailLines;
    }

    /**
     * Calculates the total updated effort for all federal detail lines
     *
     * @return effortFederalTotal
     */
    public Integer getFederalTotalEffortPercent() {
        Integer effortFederalTotal = 0;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (detailLine.isFederalOrFederalPassThroughIndicator()) {
                effortFederalTotal += detailLine.getEffortCertificationUpdatedOverallPercent();
            }
        }

        return effortFederalTotal;
    }

    /**
     * Calculates the total original effort for all federal detail lines
     *
     * @return original federal total
     */
    public Integer getFederalTotalOriginalEffortPercent() {
        Integer effortOrigFederalTotal = 0;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (detailLine.isFederalOrFederalPassThroughIndicator()) {
                effortOrigFederalTotal += detailLine.getEffortCertificationCalculatedOverallPercent();
            }
        }

        return effortOrigFederalTotal;
    }

    /**
     * Calculates the total original fringe benefit amount for federal pass through detail lines
     *
     * @return total federal benefit amount
     */
    public KualiDecimal getFederalTotalOriginalFringeBenefit() {
        KualiDecimal totalBenAmount = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (detailLine.isFederalOrFederalPassThroughIndicator()) {
                totalBenAmount = totalBenAmount.add(detailLine.getOriginalFringeBenefitAmount());
            }
        }

        return totalBenAmount;
    }

    /**
     * Calculates total original fringe benenfit amount for non federal pass through detail lines
     *
     * @return total non federal benefit amount
     */
    public KualiDecimal getOtherTotalOriginalFringeBenefit() {
        KualiDecimal totalBenAmount = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (!detailLine.isFederalOrFederalPassThroughIndicator()) {
                totalBenAmount = totalBenAmount.add(detailLine.getOriginalFringeBenefitAmount());
            }
        }

        return totalBenAmount;
    }

    /**
     * Calculates the total fringe benefit amount for federal pass through detail lines
     *
     * @return total federal benefit amount
     */
    public KualiDecimal getFederalTotalFringeBenefit() {
        KualiDecimal totalBenAmount = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (detailLine.isFederalOrFederalPassThroughIndicator()) {
                totalBenAmount = totalBenAmount.add(detailLine.getFringeBenefitAmount());
            }
        }

        return totalBenAmount;
    }

    /**
     * Calculates total fringe benenfit amount for non federal pass through detail lines
     *
     * @return total non federal benefit amount
     */
    public KualiDecimal getOtherTotalFringeBenefit() {
        KualiDecimal totalBenAmount = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (!detailLine.isFederalOrFederalPassThroughIndicator()) {
                totalBenAmount = totalBenAmount.add(detailLine.getFringeBenefitAmount());
            }
        }

        return totalBenAmount;
    }

    /**
     * Calculates the total original effor for non federal pass through detail lines
     *
     * @return original other total
     */
    public Integer getOtherTotalOriginalEffortPercent() {
        Integer effortOrigOtherTotal = 0;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (!detailLine.isFederalOrFederalPassThroughIndicator()) {
                effortOrigOtherTotal += detailLine.getEffortCertificationCalculatedOverallPercent();
            }
        }

        return effortOrigOtherTotal;
    }

    /**
     * Calculates the total updated effort for non federal pass through detail lines
     *
     * @return effort total for non federal pass through accounts
     */
    public Integer getOtherTotalEffortPercent() {
        Integer effortOtherTotal = 0;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (!detailLine.isFederalOrFederalPassThroughIndicator()) {
                effortOtherTotal += detailLine.getEffortCertificationUpdatedOverallPercent();
            }
        }

        return effortOtherTotal;
    }

    /**
     * Calculates the total salary for federal detail lines
     *
     * @return total salary
     */
    public KualiDecimal getFederalTotalPayrollAmount() {
        KualiDecimal salaryFederalTotal = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (detailLine.isFederalOrFederalPassThroughIndicator()) {
                salaryFederalTotal = salaryFederalTotal.add(detailLine.getEffortCertificationPayrollAmount());
            }
        }

        return salaryFederalTotal;
    }

    /**
     * Calculates the total original salary for federal pass through detail lines
     *
     * @return total salary
     */
    public KualiDecimal getFederalTotalOriginalPayrollAmount() {
        KualiDecimal salaryOrigFederalTotal = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (detailLine.isFederalOrFederalPassThroughIndicator()) {
                salaryOrigFederalTotal = salaryOrigFederalTotal.add(detailLine.getEffortCertificationOriginalPayrollAmount());
            }
        }

        return salaryOrigFederalTotal;
    }

    /**
     * Calculates the total original salary for non federal pass through detail lines
     *
     * @return total original salary
     */
    public KualiDecimal getOtherTotalOriginalPayrollAmount() {
        KualiDecimal salaryOrigOtherTotal = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (!detailLine.isFederalOrFederalPassThroughIndicator()) {
                salaryOrigOtherTotal = salaryOrigOtherTotal.add(detailLine.getEffortCertificationOriginalPayrollAmount());
            }
        }

        return salaryOrigOtherTotal;
    }

    /**
     * Calculates total updated salary for non federal pass through detail lines
     *
     * @return total salary
     */
    public KualiDecimal getOtherTotalPayrollAmount() {
        KualiDecimal salaryOtherTotal = KualiDecimal.ZERO;
        List<EffortCertificationDetail> detailLineList = this.getEffortCertificationDetailLines();

        for (EffortCertificationDetail detailLine : detailLineList) {
            if (!detailLine.isFederalOrFederalPassThroughIndicator()) {
                salaryOtherTotal = salaryOtherTotal.add(detailLine.getEffortCertificationPayrollAmount());
            }
        }

        return salaryOtherTotal;
    }

    /**
     * Gets the totalFringeBenefit attribute.
     *
     * @return Returns the totalFringeBenefit.
     */
    public KualiDecimal getTotalFringeBenefit() {
        return EffortCertificationDetail.getTotalFringeBenefit(effortCertificationDetailLines);
    }

    /**
     * Gets the totalOriginalFringeBenefit attribute.
     *
     * @return Returns the totalOriginalFringeBenefit.
     */
    public KualiDecimal getTotalOriginalFringeBenefit() {
        return EffortCertificationDetail.getTotalOriginalFringeBenefit(effortCertificationDetailLines);
    }

    /**
     * @see org.kuali.rice.krad.document.DocumentBase#processAfterRetrieve()
     */
    @Override
    public void processAfterRetrieve() {
        super.processAfterRetrieve();

        // capture each line's salary amount before route level modification for later rule validation
        for (EffortCertificationDetail detailLine : this.getEffortCertificationDetailLines()) {
            detailLine.setPersistedPayrollAmount(new KualiDecimal(detailLine.getEffortCertificationPayrollAmount().bigDecimalValue()));

            int effortPercent = detailLine.getEffortCertificationUpdatedOverallPercent();
            detailLine.setPersistedEffortPercent(new Integer(effortPercent));
        }

        // calculate original fringe benefits for each line
        for (EffortCertificationDetail detailLine : this.getEffortCertificationDetailLines()) {
            detailLine.recalculateOriginalFringeBenefit();
        }
    }

    /**
     * Checks if the effort has changed for any of the detail lines.
     *
     * @return true if effort has changed, false otherwise
     */
    public boolean isEffortDistributionChanged() {
        for (EffortCertificationDetail detail : this.getEffortCertificationDetailLines()) {
            if (!detail.getEffortCertificationCalculatedOverallPercent().equals(detail.getEffortCertificationUpdatedOverallPercent())) {
                return true;
            }
        }

        return false;
    }

    /**
     * Finds the default position number for display based on the detail line with the maximum effort
     *
     * @return default position number
     */
    public String getDefaultPositionNumber() {
        return this.getMaxEffortLine().getPositionNumber();
    }

    /**
     * Finds the default object code for display based on the value for the detail line with the maximum effort
     *
     * @return default object code
     */
    public String getDefaultObjectCode() {
        return this.getMaxEffortLine().getFinancialObjectCode();
    }

    /**
     * Finds the detail line with the maximum effort
     *
     * @return max effort line
     */
    protected EffortCertificationDetail getMaxEffortLine() {
        Integer maxEffort = 0;
        EffortCertificationDetail maxLine = null;
        List<EffortCertificationDetail> detailLines = this.getEffortCertificationDetailLines();
        for (EffortCertificationDetail detailLine : detailLines) {
            if (detailLine.getEffortCertificationUpdatedOverallPercent() > maxEffort) {
                maxEffort = detailLine.getEffortCertificationUpdatedOverallPercent();
                maxLine = detailLine;
            }
        }
        return maxLine;
    }

    /**
     * @see org.kuali.rice.krad.document.DocumentBase#populateDocumentForRouting()
     */
    @Override
    public void populateDocumentForRouting() {
        if (ObjectUtils.isNotNull(getTotalPayrollAmount())) {
            getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(getTotalPayrollAmount());
        }
        else {
            getFinancialSystemDocumentHeader().setFinancialDocumentTotalAmount(new KualiDecimal(0));
        }
        super.populateDocumentForRouting();
    }


    /**
     * Finds the list of unique object codes contained in this document
     *
     * @return list of unique object codes
     */
    public List<String> getObjectCodeList() {
        List<String> uniqueObjectCodeList = new ArrayList<String>();
        List<EffortCertificationDetail> allObjectCodesList = this.getEffortCertificationDetailLines();
        for (EffortCertificationDetail detail : allObjectCodesList) {
            if (!uniqueObjectCodeList.contains(detail.getFinancialObjectCode())) {
                uniqueObjectCodeList.add(detail.getFinancialObjectCode());
            }
        }

        return uniqueObjectCodeList;
    }

    /**
     * Finds the list of unique position numbers for this document
     *
     * @return list of unique position numbers
     */
    public List<String> getPositionList() {
        List<String> uniquePositionList = new ArrayList<String>();
        List<EffortCertificationDetail> allPositionsList = this.getEffortCertificationDetailLines();
        for (EffortCertificationDetail detail : allPositionsList) {
            if (!uniquePositionList.contains(detail.getPositionNumber())) {
                uniquePositionList.add(detail.getPositionNumber());
            }
        }

        return uniquePositionList;
    }

    /**
     * This is a marker setter method and does nothing.
     */
    public void setTotalOriginalPayrollAmount(KualiDecimal totalOriginalPayrollAmount) {
        return;
    }

    /**
     * Gets the summarizedDetailLines attribute.
     *
     * @return Returns the summarizedDetailLines.
     */
    public List<EffortCertificationDetail> getSummarizedDetailLines() {
        return summarizedDetailLines;
    }

    /**
     * Sets the summarizedDetailLines attribute value.
     *
     * @param summarizedDetailLines The summarizedDetailLines to set.
     */
    public void setSummarizedDetailLines(List<EffortCertificationDetail> summarizedDetailLines) {
        this.summarizedDetailLines = summarizedDetailLines;
    }

    /**
     * Provides answers to the following splits:
     * Do Award Split
     * Do Recreate Split
     * @see org.kuali.kfs.sys.document.FinancialSystemTransactionalDocumentBase#answerSplitNodeQuestion(java.lang.String)
     */
    @Override
    public boolean answerSplitNodeQuestion(String nodeName) throws UnsupportedOperationException {
        if (nodeName.equals(EffortCertificationDocument.DO_AWARD_SPLIT)) {
            return isDoAwardSplit();
        }
        if (nodeName.equals(EffortCertificationDocument.DO_RECREATE_SPLIT)) {
            return isDoRecreateSplit();
        }
        if (nodeName.equals(KFSConstants.REQUIRES_WORKSTUDY_REVIEW)) {
            return checkOjbectCodeForWorkstudy();
        }
        throw new UnsupportedOperationException("Cannot answer split question for this node you call \""+nodeName+"\"");
    }


    /**
     * KFSMI-4606
     * @return boolean
     */
    protected boolean checkOjbectCodeForWorkstudy(){
        Collection<String> workstudyRouteObjectcodes = SpringContext.getBean(ParameterService.class).getParameterValuesAsString(KfsParameterConstants.FINANCIAL_SYSTEM_DOCUMENT.class, KFSConstants.WORKSTUDY_ROUTE_OBJECT_CODES_PARM_NM);

        List<EffortCertificationDetail> effortCertificationDetails = getEffortCertificationDetailLines();

        // check object code in accounting lines
        for (EffortCertificationDetail effortCertificationDetail : effortCertificationDetails){
            if (workstudyRouteObjectcodes.contains(effortCertificationDetail.getFinancialObjectCode())) {
                return true;
            }
        }

        return false;
    }

    /**
     * Checks system parameter that indicates whether routing to project directors should occur only on
     * lines with federal accounts or all lines.
     *
     * @return detail lines with federal accounts if parameter is true, otherwise all detail lines
     */
    public List<EffortCertificationDetail> getDetailLinesForPDRouting() {
        boolean federalOnlyRouting = EffortCertificationParameterFinder.getFederalOnlyRouteIndicator();
        if (!federalOnlyRouting) {
            return this.effortCertificationDetailLines;
        }

        List<EffortCertificationDetail> federalDetailLines = new ArrayList<EffortCertificationDetail>();
        for (EffortCertificationDetail detail : this.effortCertificationDetailLines) {
            if (detail.isFederalOrFederalPassThroughIndicator()) {
                federalDetailLines.add(detail);
            }
        }

        return federalDetailLines;
    }

    /**
     * @return boolean value
     */
    protected boolean isDoAwardSplit() {
        return this.isEffortDistributionChanged();
    }

    /**
     * @return boolean value
     */
    protected boolean isDoRecreateSplit() {
        return this.getEffortCertificationDocumentCode();
    }
}

