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