org.kuali.kfs.module.cg.document.validation.impl.CGMaintenanceDocumentRuleBase.java Source code

Java tutorial

Introduction

Here is the source code for org.kuali.kfs.module.cg.document.validation.impl.CGMaintenanceDocumentRuleBase.java

Source

/*
 * 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.cg.document.validation.impl;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.integration.ar.AccountsReceivableModuleBillingService;
import org.kuali.kfs.module.cg.businessobject.Agency;
import org.kuali.kfs.module.cg.businessobject.AwardFundManager;
import org.kuali.kfs.module.cg.businessobject.CGProjectDirector;
import org.kuali.kfs.module.cg.businessobject.Primaryable;
import org.kuali.kfs.sys.KFSConstants;
import org.kuali.kfs.sys.KFSKeyConstants;
import org.kuali.kfs.sys.KFSPropertyConstants;
import org.kuali.kfs.sys.context.SpringContext;
import org.kuali.rice.kim.api.identity.CodedAttribute;
import org.kuali.rice.kim.api.identity.PersonService;
import org.kuali.rice.kim.api.role.RoleService;
import org.kuali.rice.kim.api.services.KimApiServiceLocator;
import org.kuali.rice.kns.maintenance.rules.MaintenanceDocumentRuleBase;
import org.kuali.rice.kns.service.DataDictionaryService;
import org.kuali.rice.krad.bo.BusinessObject;
import org.kuali.rice.krad.util.ObjectUtils;

/**
 * Rules for the Proposal/Award/Agency maintenance document.
 */
public class CGMaintenanceDocumentRuleBase extends MaintenanceDocumentRuleBase {

    protected static final String PROJECT_DIRECTOR_DECEASED = "D";
    protected static final String[] PROJECT_DIRECTOR_INVALID_STATUSES = { PROJECT_DIRECTOR_DECEASED };

    protected static final String AGENCY_TYPE_CODE_FEDERAL = "F";

    protected boolean contractsGrantsBillingEnhancementActive;

    public CGMaintenanceDocumentRuleBase() {
        super();
        contractsGrantsBillingEnhancementActive = SpringContext
                .getBean(AccountsReceivableModuleBillingService.class).isContractsGrantsBillingEnhancementActive();
    }

    /**
     * Checks to see if the end date is after the begin date
     *
     * @param begin
     * @param end
     * @param propertyName
     * @return true if end is after begin, false otherwise
     */
    protected boolean checkEndAfterBegin(Date begin, Date end, String propertyName) {
        boolean success = true;
        if (ObjectUtils.isNotNull(begin) && ObjectUtils.isNotNull(end) && !end.after(begin)) {
            putFieldError(propertyName, KFSKeyConstants.ERROR_ENDING_DATE_NOT_AFTER_BEGIN);
            success = false;
        }
        return success;
    }

    /**
     * @param <E>
     * @param primaryables
     * @param elementClass
     * @param collectionName
     * @param boClass
     * @return
     */
    protected <E extends Primaryable> boolean checkPrimary(Collection<E> primaryables, Class<E> elementClass,
            String collectionName, Class<? extends BusinessObject> boClass) {
        boolean success = true;
        int count = 0;
        for (Primaryable p : primaryables) {
            if (p.isPrimary()) {
                count++;
            }
        }
        if (count != 1) {
            success = false;
            String elementLabel = SpringContext.getBean(DataDictionaryService.class)
                    .getCollectionElementLabel(boClass.getName(), collectionName, elementClass);
            switch (count) {
            case 0:
                putFieldError(collectionName, KFSKeyConstants.ERROR_NO_PRIMARY, elementLabel);
                break;
            default:
                putFieldError(collectionName, KFSKeyConstants.ERROR_MULTIPLE_PRIMARY, elementLabel);
            }

        }
        return success;
    }

    /**
     * @param <T>
     * @param projectDirectors
     * @param elementClass
     * @param collectionName
     * @return
     */
    protected <T extends CGProjectDirector> boolean checkProjectDirectorsExist(List<T> projectDirectors,
            Class<T> elementClass, String collectionName) {
        boolean success = true;
        final String personUserPropertyName = KFSPropertyConstants.PROJECT_DIRECTOR + "."
                + KFSPropertyConstants.PERSON_USER_IDENTIFIER;
        String label = SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(elementClass,
                personUserPropertyName);
        int i = 0;
        for (T pd : projectDirectors) {
            String propertyName = collectionName + "[" + (i++) + "]." + personUserPropertyName;
            String id = pd.getPrincipalId();
            if (StringUtils.isBlank(id) || (KimApiServiceLocator.getIdentityService().getPrincipal(id) == null)) {
                putFieldError(propertyName, KFSKeyConstants.ERROR_EXISTENCE, label);
                success = false;
            }
        }
        return success;
    }

    /**
     *
     * @param fundManagers
     * @param collectionName
     * @return
     */
    protected boolean checkFundManagersExist(List<AwardFundManager> fundManagers, String collectionName) {
        boolean success = true;
        final String personUserPropertyName = KFSPropertyConstants.FUND_MANAGER + "."
                + KFSPropertyConstants.PERSON_USER_IDENTIFIER;
        String label = SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(AwardFundManager.class,
                personUserPropertyName);
        int i = 0;
        for (AwardFundManager fm : fundManagers) {
            String propertyName = collectionName + "[" + (i++) + "]." + personUserPropertyName;
            String id = fm.getPrincipalId();
            if (StringUtils.isBlank(id) || (SpringContext.getBean(PersonService.class).getPerson(id) == null)) {
                putFieldError(propertyName, KFSKeyConstants.ERROR_EXISTENCE, label);
                success = false;
            }
        }
        return success;
    }

    /**
     * @param <T>
     * @param projectDirectors
     * @param elementClass
     * @param collectionName
     * @return
     */
    protected <T extends CGProjectDirector> boolean checkProjectDirectorsAreDirectors(List<T> projectDirectors,
            Class<T> elementClass, String collectionName) {
        boolean success = true;
        final String personUserPropertyName = KFSPropertyConstants.PROJECT_DIRECTOR + "."
                + KFSPropertyConstants.PERSON_USER_IDENTIFIER;
        String label = SpringContext.getBean(DataDictionaryService.class).getAttributeLabel(elementClass,
                personUserPropertyName);
        RoleService roleService = KimApiServiceLocator.getRoleService();

        List<String> roleId = new ArrayList<String>();
        roleId.add(roleService.getRoleIdByNamespaceCodeAndName(KFSConstants.ParameterNamespaces.KFS,
                KFSConstants.SysKimApiConstants.CONTRACTS_AND_GRANTS_PROJECT_DIRECTOR));

        int i = 0;
        for (T pd : projectDirectors) {
            String propertyName = collectionName + "[" + (i++) + "]." + personUserPropertyName;
            String id = pd.getProjectDirector().getPrincipalId();
            if (!roleService.principalHasRole(id, roleId, null)) {
                putFieldError(propertyName, KFSKeyConstants.ERROR_NOT_A_PROJECT_DIRECTOR, id);
                success = false;
            }
        }
        return success;
    }

    /**
     * This method takes in a collection of {@link ProjectDirector}s and reviews them to see if any have invalid states for being
     * added to a {@link Proposal}. An example would be a status code of "D" which means "Deceased". Project Directors with a status
     * of "D" cannot be added to a {@link Proposal} or {@link Award}.
     *
     * @param projectDirectors Collection of project directors to be reviewed.
     * @param elementClass Type of object that the collection belongs to.
     * @param propertyName Name of field that error will be attached to.
     * @return True if all the project directors have valid statuses, false otherwise.
     */
    protected <T extends CGProjectDirector> boolean checkProjectDirectorsStatuses(List<T> projectDirectors,
            Class<T> elementClass, String propertyName) {
        boolean success = true;
        for (T pd : projectDirectors) {
            String pdEmplStatusCode = pd.getProjectDirector().getEmployeeStatusCode();
            if (StringUtils.isBlank(pdEmplStatusCode)
                    || Arrays.asList(PROJECT_DIRECTOR_INVALID_STATUSES).contains(pdEmplStatusCode)) {
                String pdEmplStatusName = "INVALID STATUS CODE " + pdEmplStatusCode;
                if (StringUtils.isNotBlank(pdEmplStatusCode)) {
                    CodedAttribute empStatus = KimApiServiceLocator.getIdentityService()
                            .getEmploymentStatus(pdEmplStatusCode);
                    if (empStatus != null) {
                        pdEmplStatusName = empStatus.getName();
                    }
                }
                String[] errors = { pd.getProjectDirector().getName(),
                        pdEmplStatusCode + " - " + pdEmplStatusName };
                putFieldError(propertyName, KFSKeyConstants.ERROR_INVALID_PROJECT_DIRECTOR_STATUS, errors);
                success = false;
            }
        }
        return success;
    }

    /**
     * This method checks to see if the two agency values passed in are the same {@link Agency}. The agency for a C&G document
     * cannot be the same as the Federal Pass Through Agency for that same document.
     *
     * @param agency
     * @param federalPassThroughAgency
     * @param agencyPropertyName
     * @return True if the agencies are not the same, false otherwise.
     */
    protected boolean checkAgencyNotEqualToFederalPassThroughAgency(Agency agency, Agency federalPassThroughAgency,
            String agencyPropertyName, String fedPassThroughAgencyPropertyName) {
        boolean success = true;
        if (ObjectUtils.isNotNull(agency) && ObjectUtils.isNotNull(federalPassThroughAgency)
                && ObjectUtils.isNotNull(agency.getAgencyNumber())
                && ObjectUtils.isNotNull(federalPassThroughAgency.getAgencyNumber())
                && agency.equals(federalPassThroughAgency)) {
            putFieldError(agencyPropertyName, KFSKeyConstants.ERROR_AGENCY_EQUALS_FEDERAL_PASS_THROUGH_AGENCY);
            putFieldError(fedPassThroughAgencyPropertyName,
                    KFSKeyConstants.ERROR_FEDERAL_PASS_THROUGH_AGENCY_EQUALS_AGENCY);
            success = false;
        }
        return success;
    }

    /**
     * Checks if the required federal pass through fields are filled in if the federal pass through indicator is yes.
     *
     * @return True if all the necessary rules regarding the federal pass through agency input fields are met, false otherwise.
     */
    protected boolean checkFederalPassThrough(boolean federalPassThroughIndicator, Agency primaryAgency,
            String federalPassThroughAgencyNumber, Class propertyClass,
            String federalPassThroughIndicatorFieldName) {
        boolean success = true;

        // check if primary agency is federal
        boolean primaryAgencyIsFederal = false;

        if (ObjectUtils.isNotNull(primaryAgency)) {
            primaryAgencyIsFederal = AGENCY_TYPE_CODE_FEDERAL.equalsIgnoreCase(primaryAgency.getAgencyTypeCode());
        }

        String indicatorLabel = SpringContext.getBean(DataDictionaryService.class)
                .getAttributeErrorLabel(propertyClass, federalPassThroughIndicatorFieldName);
        String agencyLabel = SpringContext.getBean(DataDictionaryService.class)
                .getAttributeErrorLabel(propertyClass, KFSPropertyConstants.FEDERAL_PASS_THROUGH_AGENCY_NUMBER);

        if (primaryAgencyIsFederal) {
            if (federalPassThroughIndicator) {
                // fpt indicator should not be checked if primary agency is federal
                putFieldError(federalPassThroughIndicatorFieldName,
                        KFSKeyConstants.ERROR_PRIMARY_AGENCY_IS_FEDERAL_AND_FPT_INDICATOR_IS_CHECKED,
                        new String[] { primaryAgency.getAgencyNumber(), AGENCY_TYPE_CODE_FEDERAL });
                success = false;
            }
            if (!StringUtils.isBlank(federalPassThroughAgencyNumber)) {
                // fpt agency number should be blank if primary agency is federal
                putFieldError(KFSPropertyConstants.FEDERAL_PASS_THROUGH_AGENCY_NUMBER,
                        KFSKeyConstants.ERROR_PRIMARY_AGENCY_IS_FEDERAL_AND_FPT_AGENCY_IS_NOT_BLANK,
                        new String[] { primaryAgency.getAgencyNumber(), AGENCY_TYPE_CODE_FEDERAL });
                success = false;
            }
        } else {
            if (federalPassThroughIndicator && StringUtils.isBlank(federalPassThroughAgencyNumber)) {
                // fpt agency number is required if fpt indicator is checked
                putFieldError(KFSPropertyConstants.FEDERAL_PASS_THROUGH_AGENCY_NUMBER,
                        KFSKeyConstants.ERROR_FPT_AGENCY_NUMBER_REQUIRED);
                success = false;
            } else if (!federalPassThroughIndicator && !StringUtils.isBlank(federalPassThroughAgencyNumber)) {
                // fpt agency number should be blank if fpt indicator is not checked
                putFieldError(KFSPropertyConstants.FEDERAL_PASS_THROUGH_AGENCY_NUMBER,
                        KFSKeyConstants.ERROR_FPT_AGENCY_NUMBER_NOT_BLANK);
                success = false;
            }
        }

        return success;
    }

}