001/*
002 * The Kuali Financial System, a comprehensive financial management system for higher education.
003 * 
004 * Copyright 2005-2014 The Kuali Foundation
005 * 
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU Affero General Public License as
008 * published by the Free Software Foundation, either version 3 of the
009 * License, or (at your option) any later version.
010 * 
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU Affero General Public License for more details.
015 * 
016 * You should have received a copy of the GNU Affero General Public License
017 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018 */
019package org.kuali.kfs.fp.document.validation.impl;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import org.kuali.kfs.fp.document.BudgetAdjustmentDocument;
025import org.kuali.kfs.fp.document.service.BudgetAdjustmentLaborBenefitsService;
026import org.kuali.kfs.fp.document.web.struts.BudgetAdjustmentForm;
027import org.kuali.kfs.fp.service.AccountingDocumentPreRuleService;
028import org.kuali.kfs.sys.KFSConstants;
029import org.kuali.kfs.sys.KFSKeyConstants;
030import org.kuali.kfs.sys.businessobject.AccountingLine;
031import org.kuali.kfs.sys.context.SpringContext;
032import org.kuali.kfs.sys.document.AccountingDocumentBase;
033import org.kuali.rice.core.api.config.property.ConfigurationService;
034import org.kuali.rice.kew.api.WorkflowDocument;
035import org.kuali.rice.kns.rules.PromptBeforeValidationBase;
036import org.kuali.rice.krad.document.Document;
037import org.kuali.rice.krad.util.KRADConstants;
038import org.kuali.rice.krad.util.ObjectUtils;
039
040/**
041 * Checks warnings and prompt conditions for ba document.
042 */
043public class BudgetAdjustmentDocumentPreRules extends PromptBeforeValidationBase {
044    protected ConfigurationService kualiConfiguration;
045
046
047    /**
048     * Execute pre-rules for BudgetAdjustmentDocument
049     * 
050     * @document document with pre-rules being applied
051     * @return true if pre-rules fire without problem
052     * @see org.kuali.rice.kns.rules.PromptBeforeValidationBase#doRules(org.kuali.rice.kns.document.MaintenanceDocument)
053     */
054    @Override
055    public boolean doPrompts(Document document) {
056        boolean preRulesOK = true;
057
058        BudgetAdjustmentDocument budgetDocument = (BudgetAdjustmentDocument) document;
059        preRulesOK = askLaborBenefitsGeneration(budgetDocument);
060        
061        preRulesOK &= SpringContext.getBean(AccountingDocumentPreRuleService.class).expiredAccountOverrideQuestion((AccountingDocumentBase) document, this, this.event);
062
063        return preRulesOK;
064    }
065
066
067    /**
068     * Calls service to determine if any labor object codes are present on the ba document. If so, asks the user if they want the
069     * system to automatically generate the benefit lines. If Yes, calls service to generate the accounting lines.
070     * 
071     * @param budgetDocument submitted budget document
072     * @return true if labor benefits generation question is NOT asked
073     */
074    protected boolean askLaborBenefitsGeneration(BudgetAdjustmentDocument budgetDocument) {
075        // before prompting, check the document contains one or more labor object codes
076        final boolean hasLaborObjectCodes = SpringContext.getBean(BudgetAdjustmentLaborBenefitsService.class).hasLaborObjectCodes(budgetDocument);
077        final boolean canEdit = ((BudgetAdjustmentForm)form).getDocumentActions().containsKey(KRADConstants.KUALI_ACTION_CAN_EDIT);
078        final boolean canGenerateLaborBenefitsByRouteStatusResult = canGenerateLaborBenefitsByRouteStatus(budgetDocument);
079        if (canEdit && hasLaborObjectCodes && canGenerateLaborBenefitsByRouteStatusResult) {
080            final String questionText = SpringContext.getBean(ConfigurationService.class).getPropertyValueAsString(KFSKeyConstants.QUESTION_GENERATE_LABOR_BENEFIT_LINES);
081            final boolean generateBenefits = super.askOrAnalyzeYesNoQuestion(KFSConstants.BudgetAdjustmentDocumentConstants.GENERATE_BENEFITS_QUESTION_ID, questionText);
082            if (generateBenefits) {
083                SpringContext.getBean(BudgetAdjustmentLaborBenefitsService.class).generateLaborBenefitsAccountingLines(budgetDocument);
084                // return to document after lines are generated
085                super.event.setActionForwardName(KFSConstants.MAPPING_BASIC);
086                return false;
087            }
088        }
089
090        return true;
091    }
092
093    /**
094     * TODO: remove this method once baseline accounting lines has been removed
095     */
096    protected List deepCopyAccountingLinesList(List originals) {
097        if (originals == null) {
098            return null;
099        }
100        List copiedLines = new ArrayList();
101        for (int i = 0; i < originals.size(); i++) {
102            copiedLines.add(ObjectUtils.deepCopy((AccountingLine) originals.get(i)));
103        }
104        return copiedLines;
105    }
106    
107    /**
108     * Based on the routing status of the document, determines if labor benefits can be generated on the document
109     * @param budgetAdjustmentDocument the budget adjustment document that labor benefits would be generated on
110     * @return true if labor benefits can be generated, false otherwise
111     */
112    protected boolean canGenerateLaborBenefitsByRouteStatus(BudgetAdjustmentDocument budgetAdjustmentDocument) {
113        final WorkflowDocument workflowDocument = budgetAdjustmentDocument.getDocumentHeader().getWorkflowDocument();
114        if (workflowDocument.isInitiated() || workflowDocument.isSaved()) return true; // we're pre-route; we can add labor benefits
115        if (workflowDocument.isEnroute() && workflowDocument.getCurrentRouteNodeInstances().contains(KFSConstants.RouteLevelNames.ACCOUNT)) return true; // we're fiscal officers approving; we can add labor benefits
116        return false; // we're someone else and we're plum out of luck
117    }
118}
119