/* * 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.ar.identity; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.kuali.kfs.module.ar.ArConstants; import org.kuali.kfs.module.ar.businessobject.OrganizationOptions; import org.kuali.kfs.module.ar.businessobject.SystemInformation; import org.kuali.kfs.sys.KFSPropertyConstants; import org.kuali.kfs.sys.businessobject.ChartOrgHolder; import org.kuali.kfs.sys.businessobject.ChartOrgHolderImpl; import org.kuali.kfs.sys.identity.KfsKimAttributes; import org.kuali.kfs.sys.service.FinancialSystemUserService; import org.kuali.kfs.sys.service.UniversityDateService; import org.kuali.rice.kim.api.KimConstants; import org.kuali.rice.kim.api.role.RoleMembership; import org.kuali.rice.kns.kim.role.DerivedRoleTypeServiceBase; import org.kuali.rice.krad.service.BusinessObjectService; public class AccountsReceivableOrganizationDerivedRoleTypeServiceImpl extends DerivedRoleTypeServiceBase { protected static final String PROCESSOR_ROLE_NAME = "Processor"; protected static final String UNMATCHABLE_QUALIFICATION = "!~!~!~!~!~"; protected BusinessObjectService businessObjectService; protected FinancialSystemUserService financialSystemUserService; protected UniversityDateService universityDateService; protected ChartOrgHolder getProcessingChartOrg( Map<String,String> qualification ) { ChartOrgHolderImpl chartOrg = null; if ( qualification != null && !qualification.isEmpty() ) { chartOrg = new ChartOrgHolderImpl(); // if the processing org is specified from the qualifications, use that chartOrg.setChartOfAccountsCode( qualification.get(KFSPropertyConstants.PROCESSING_CHART_OF_ACCT_CD) ); chartOrg.setOrganizationCode( qualification.get(KFSPropertyConstants.PROCESSING_ORGANIZATION_CODE) ); // otherwise default to the normal chart/org values and derive the processing chart/org if (StringUtils.isBlank(chartOrg.getChartOfAccountsCode()) || StringUtils.isBlank(chartOrg.getOrganizationCode())) { chartOrg.setChartOfAccountsCode( qualification.get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE) ); chartOrg.setOrganizationCode( qualification.get(KfsKimAttributes.ORGANIZATION_CODE) ); if (StringUtils.isBlank(chartOrg.getChartOfAccountsCode()) || StringUtils.isBlank(chartOrg.getOrganizationCode())) { return null; } Map<String, Object> arOrgOptPk = new HashMap<String, Object>( 2 ); arOrgOptPk.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, chartOrg.getChartOfAccountsCode()); arOrgOptPk.put(KFSPropertyConstants.ORGANIZATION_CODE, chartOrg.getOrganizationCode()); OrganizationOptions oo = getBusinessObjectService().findByPrimaryKey(OrganizationOptions.class, arOrgOptPk); if (oo != null) { chartOrg.setChartOfAccountsCode( oo.getProcessingChartOfAccountCode() ); chartOrg.setOrganizationCode( oo.getProcessingOrganizationCode() ); } else { chartOrg.setChartOfAccountsCode( UNMATCHABLE_QUALIFICATION ); chartOrg.setOrganizationCode( UNMATCHABLE_QUALIFICATION ); } } } return chartOrg; } public boolean hasProcessorRole(ChartOrgHolder userOrg, Map<String,String> qualification) { ChartOrgHolder processingOrg = getProcessingChartOrg(qualification); // if no org passed, check if their primary org is a processing org if ( processingOrg == null ) { // check the org options for this org Map<String, Object> arProcessOrgCriteria = new HashMap<String, Object>( 2 ); arProcessOrgCriteria.put(KFSPropertyConstants.PROCESSING_CHART_OF_ACCT_CD, userOrg.getChartOfAccountsCode()); arProcessOrgCriteria.put(KFSPropertyConstants.PROCESSING_ORGANIZATION_CODE, userOrg.getOrganizationCode()); arProcessOrgCriteria.put(KFSPropertyConstants.ACTIVE, "Y"); arProcessOrgCriteria.put(KFSPropertyConstants.UNIVERSITY_FISCAL_YEAR, universityDateService.getCurrentFiscalYear()); // return true if any matching org options records return getBusinessObjectService().countMatching(SystemInformation.class, arProcessOrgCriteria) > 0; } else { // org was passed, user's org must match return processingOrg.equals(userOrg); } } public boolean hasBillerRole(ChartOrgHolder userOrg, Map<String,String> qualification) { ChartOrgHolderImpl billingOrg = new ChartOrgHolderImpl(); if ( qualification != null && !qualification.isEmpty()) { billingOrg.setChartOfAccountsCode( qualification.get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE) ); billingOrg.setOrganizationCode( qualification.get(KfsKimAttributes.ORGANIZATION_CODE) ); } if (StringUtils.isBlank(billingOrg.getChartOfAccountsCode()) || StringUtils.isBlank(billingOrg.getOrganizationCode())) { Map<String, Object> arOrgOptPk = new HashMap<String, Object>( 2 ); arOrgOptPk.put(KFSPropertyConstants.CHART_OF_ACCOUNTS_CODE, userOrg.getChartOfAccountsCode()); arOrgOptPk.put(KFSPropertyConstants.ORGANIZATION_CODE, userOrg.getOrganizationCode()); return getBusinessObjectService().countMatching(OrganizationOptions.class, arOrgOptPk) > 0; } else { return billingOrg.equals(userOrg); } } /** * @see org.kuali.rice.kns.kim.role.RoleTypeServiceBase#hasDerivedRole(java.lang.String, java.util.List, java.lang.String, java.lang.String, java.util.Map) */ @Override public boolean hasDerivedRole(String principalId, List<String> groupIds, String namespaceCode, String roleName, Map<String,String> qualification) { validateRequiredAttributesAgainstReceived(qualification); if (getFinancialSystemUserService().isActiveFinancialSystemUser(principalId)) { ChartOrgHolder userOrg = getFinancialSystemUserService().getPrimaryOrganization(principalId, ArConstants.AR_NAMESPACE_CODE); if (PROCESSOR_ROLE_NAME.equals(roleName)) { return hasProcessorRole(userOrg, qualification); } else { // billing role return hasBillerRole(userOrg, qualification) || hasProcessorRole(userOrg, qualification); } } return false; } public List<RoleMembership> getRoleMembersFromApplicationRole(String namespaceCode, String roleName, Map<String,String> qualification) { validateRequiredAttributesAgainstReceived(qualification); List<RoleMembership> results = new ArrayList<RoleMembership>(); Set<String> principalIds = new HashSet<String>(); if (PROCESSOR_ROLE_NAME.equals(roleName)) { ChartOrgHolder processingOrg = getProcessingChartOrg(qualification); if ( processingOrg == null ) { // get all users for all processing orgs // build a set List<OrganizationOptions> ooList = (List<OrganizationOptions>)getBusinessObjectService().findAll(OrganizationOptions.class); for ( OrganizationOptions oo : ooList ) { principalIds.clear(); principalIds.addAll( getFinancialSystemUserService().getPrincipalIdsForFinancialSystemOrganizationUsers( namespaceCode, new ChartOrgHolderImpl( oo.getProcessingChartOfAccountCode(), oo.getProcessingOrganizationCode() ))); if ( !principalIds.isEmpty() ) { Map<String,String> roleQualifier = new HashMap<String,String>(2); roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, oo.getProcessingChartOfAccountCode()); roleQualifier.put(KfsKimAttributes.ORGANIZATION_CODE, oo.getProcessingOrganizationCode()); for ( String principalId : principalIds ) { RoleMembership.Builder builder = RoleMembership.Builder.create( null, null, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier ); results.add(builder.build()); } } } } else { // get all users for the given org principalIds.addAll( getFinancialSystemUserService().getPrincipalIdsForFinancialSystemOrganizationUsers(ArConstants.AR_NAMESPACE_CODE, processingOrg) ); if ( !principalIds.isEmpty() ) { Map<String,String> roleQualifier = new HashMap<String,String>(2); roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, processingOrg.getChartOfAccountsCode()); roleQualifier.put(KfsKimAttributes.ORGANIZATION_CODE, processingOrg.getOrganizationCode()); for ( String principalId : principalIds ) { RoleMembership.Builder builder = RoleMembership.Builder.create( null, null, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier ); results.add(builder.build()); } } } } else { // billing role ChartOrgHolderImpl billingOrg = new ChartOrgHolderImpl(); if ( qualification != null && !qualification.isEmpty() ) { billingOrg.setChartOfAccountsCode( qualification.get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE) ); billingOrg.setOrganizationCode( qualification.get(KfsKimAttributes.ORGANIZATION_CODE) ); } if (StringUtils.isBlank(billingOrg.getChartOfAccountsCode()) || StringUtils.isBlank(billingOrg.getOrganizationCode())) { // get all users for all billing orgs List<OrganizationOptions> ooList = (List<OrganizationOptions>)getBusinessObjectService().findAll(OrganizationOptions.class); for ( OrganizationOptions oo : ooList ) { principalIds.clear(); principalIds.addAll( getFinancialSystemUserService().getPrincipalIdsForFinancialSystemOrganizationUsers( namespaceCode, new ChartOrgHolderImpl( oo.getChartOfAccountsCode(), oo.getOrganizationCode() ))); if ( !principalIds.isEmpty() ) { Map<String,String> roleQualifier = new HashMap<String,String>(2); roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, oo.getChartOfAccountsCode()); roleQualifier.put(KfsKimAttributes.ORGANIZATION_CODE, oo.getOrganizationCode()); for ( String principalId : principalIds ) { RoleMembership.Builder builder = RoleMembership.Builder.create( null, null, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier ); results.add(builder.build()); } } } } else { // get all users for given org principalIds.addAll( getFinancialSystemUserService().getPrincipalIdsForFinancialSystemOrganizationUsers(ArConstants.AR_NAMESPACE_CODE, billingOrg) ); if ( !principalIds.isEmpty() ) { Map<String,String> roleQualifier = new HashMap<String,String>(2); roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, billingOrg.getChartOfAccountsCode()); roleQualifier.put(KfsKimAttributes.ORGANIZATION_CODE, billingOrg.getOrganizationCode()); for ( String principalId : principalIds ) { RoleMembership.Builder builder = RoleMembership.Builder.create( null, null, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier ); results.add(builder.build()); } } } } return results; } @Override protected BusinessObjectService getBusinessObjectService() { return businessObjectService; } public void setBusinessObjectService(BusinessObjectService businessObjectService) { this.businessObjectService = businessObjectService; } public final FinancialSystemUserService getFinancialSystemUserService() { return financialSystemUserService; } public void setFinancialSystemUserService(FinancialSystemUserService financialSystemUserService) { this.financialSystemUserService = financialSystemUserService; } public void setUniversityDateService(UniversityDateService universityDateService) { this.universityDateService = universityDateService; } }