<commit_before>/*
 * Copyright 2008 The Kuali Foundation
 * 
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.opensource.org/licenses/ecl2.php
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.kfs.coa.identity;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Account;
import org.kuali.kfs.coa.businessobject.AccountDelegate;
import org.kuali.kfs.coa.service.AccountDelegateService;
import org.kuali.kfs.coa.service.AccountService;
import org.kuali.kfs.integration.cg.ContractsAndGrantsModuleService;
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.kfs.sys.document.FinancialSystemMaintainable;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.core.framework.parameter.ParameterService;
import org.kuali.rice.core.mail.MailMessage;
import org.kuali.rice.core.web.format.CurrencyFormatter;
import org.kuali.rice.kim.api.KimConstants;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.identity.principal.Principal;
import org.kuali.rice.kim.api.role.RoleMembership;
import org.kuali.rice.kim.api.services.IdentityManagementService;
import org.kuali.rice.kns.kim.role.DerivedRoleTypeServiceBase;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.MailService;
import org.kuali.rice.krad.util.ObjectUtils;

public class AccountDerivedRoleTypeServiceImpl extends DerivedRoleTypeServiceBase {

    protected AccountService accountService;
    protected ContractsAndGrantsModuleService contractsAndGrantsModuleService;
    protected AccountDelegateService accountDelegateService;
    protected ConfigurationService configurationService;
    protected IdentityManagementService identityManagementService;
    protected MailService mailService;
    protected ParameterService parameterService;
    
    protected final static String DERIVED_ROLE_MEMBER_INACTIVATION_NOTIFICATION_EMAIL_ADDRESSES_PARAMETER_NAME = "DERIVED_ROLE_MEMBER_INACTIVATION_NOTIFICATION_EMAIL_ADDRESSES";

    /**
     * Attributes: Chart Code Account Number Requirements: - KFS-COA Account Supervisor: CA_ACCOUNT_T.ACCT_SPVSR_UNVL_ID - KFS-SYS
     * Fiscal Officer: CA_ACCOUNT_T.ACCT_FSC_OFC_UID - KFS-SYS Fiscal Officer Primary Delegate: CA_ACCT_DELEGATE_T.ACCT_DLGT_UNVL_ID
     * where ACCT_DLGT_PRMRT_CD = Y - KFS-SYS Fiscal Officer Secondary Delegate: CA_ACCT_DELEGATE_T.ACCT_DLGT_UNVL_ID where
     * ACCT_DLGT_PRMRT_CD = N - KFS-SYS Award Project Director: use the getProjectDirectorForAccount(String chartOfAccountsCode,
     * String accountNumber) method on the contracts and grants module service
     * 
     * @see org.kuali.rice.kns.kim.role.RoleTypeServiceBase#getPrincipalIdsFromApplicationRole(java.lang.String,
     *      java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
     */
    @Override
    public List<RoleMembership> getRoleMembersFromApplicationRole(String namespaceCode, String roleName, Map<String,String> qualification) {
        // validate received attributes
        validateRequiredAttributesAgainstReceived(qualification);
        List<RoleMembership> members = new ArrayList<RoleMembership>();
        if(qualification!=null && !qualification.isEmpty()){
            String chartOfAccountsCode = qualification.get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE);
            String accountNumber = qualification.get(KfsKimAttributes.ACCOUNT_NUMBER);
    
            String financialSystemDocumentTypeCodeCode = qualification.get(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME);
            String totalDollarAmount = qualification.get(KfsKimAttributes.FINANCIAL_DOCUMENT_TOTAL_AMOUNT);
    
            String fiscalOfficerPrincipalID = qualification.get(KFSPropertyConstants.ACCOUNT_FISCAL_OFFICER_SYSTEM_IDENTIFIER);
            String accountSupervisorPrincipalID = qualification.get(KFSPropertyConstants.ACCOUNTS_SUPERVISORY_SYSTEMS_IDENTIFIER);
            String principalId = qualification.get(KimConstants.AttributeConstants.PRINCIPAL_ID);
    
            // Default to 0 total amount
            if (StringUtils.isEmpty(totalDollarAmount)) {
                totalDollarAmount = getDefaultTotalAmount();
            }
    
            Map<String,String> roleQualifier = new HashMap<String,String>();
            roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
            roleQualifier.put(KfsKimAttributes.ACCOUNT_NUMBER, accountNumber);
    
            if (chartOfAccountsCode == null && accountNumber == null && StringUtils.isNotBlank(principalId)) {
                RoleMembership roleMembershipInfo = getRoleMembershipWhenAccountInfoUnavailable(roleName, principalId, roleQualifier);
                if(ObjectUtils.isNotNull(roleMembershipInfo)) {
                    members.add(roleMembershipInfo);
                }
            }
    
            if (KFSConstants.SysKimApiConstants.ACCOUNT_SUPERVISOR_KIM_ROLE_NAME.equals(roleName)) {
                Account account = getAccount(chartOfAccountsCode, accountNumber);
                if (account != null) {
                    members.add(new RoleMembership(null, null, account.getAccountsSupervisorySystemsIdentifier(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier));
                }
                // only add the additional approver if they are different
                if (StringUtils.isNotBlank(accountSupervisorPrincipalID) && (account == null || !StringUtils.equals(accountSupervisorPrincipalID, account.getAccountsSupervisorySystemsIdentifier()))) {
                    members.add(new RoleMembership(null, null, accountSupervisorPrincipalID, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier));
                }
            }
            else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME.equals(roleName)) {
                Account account = getAccount(chartOfAccountsCode, accountNumber);
                if (account != null) {
                    members.add(new RoleMembership(null, null, account.getAccountFiscalOfficerSystemIdentifier(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier));
                }
                // only add the additional approver if they are different
                if (StringUtils.isNotBlank(fiscalOfficerPrincipalID) && (account == null || !StringUtils.equals(fiscalOfficerPrincipalID, account.getAccountFiscalOfficerSystemIdentifier()))) {
                    members.add(new RoleMembership(null, null, fiscalOfficerPrincipalID, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier));
                }
            }
            else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_PRIMARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
                AccountDelegate delegate = getPrimaryDelegate(chartOfAccountsCode, accountNumber, financialSystemDocumentTypeCodeCode, totalDollarAmount);
                if (delegate != null) {
                    roleQualifier.put(KfsKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE, delegate.getFinancialDocumentTypeCode());
                    roleQualifier.put(KfsKimAttributes.FROM_AMOUNT, (delegate.getFinDocApprovalFromThisAmt() == null) ? "0" : delegate.getFinDocApprovalFromThisAmt().toString());
                    roleQualifier.put(KfsKimAttributes.TO_AMOUNT, (delegate.getFinDocApprovalToThisAmount() == null) ? "NOLIMIT" : delegate.getFinDocApprovalToThisAmount().toString());
                    members.add(new RoleMembership(null, null, delegate.getAccountDelegateSystemId(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier));
                }
            }
            else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_SECONDARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
                List<AccountDelegate> delegates = getSecondaryDelegates(chartOfAccountsCode, accountNumber, financialSystemDocumentTypeCodeCode, totalDollarAmount);
                for (AccountDelegate delegate : delegates) {
                    roleQualifier.put(KfsKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE, delegate.getFinancialDocumentTypeCode());
                    roleQualifier.put(KfsKimAttributes.FROM_AMOUNT, (delegate.getFinDocApprovalFromThisAmt() == null) ? "0" : delegate.getFinDocApprovalFromThisAmt().toString());
                    roleQualifier.put(KfsKimAttributes.TO_AMOUNT, (delegate.getFinDocApprovalToThisAmount() == null) ? "NOLIMIT" : delegate.getFinDocApprovalToThisAmount().toString());
                    members.add(new RoleMembership(null, null, delegate.getAccountDelegateSystemId(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier));
                }
            }
            else if (KFSConstants.SysKimApiConstants.AWARD_SECONDARY_DIRECTOR_KIM_ROLE_NAME.equals(roleName)) {
                Person person = getProjectDirectorForAccount(chartOfAccountsCode, accountNumber);
                if (person != null) {
                    members.add(new RoleMembership(null, null, person.getPrincipalId(), KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier));
                }
            }
        }
        return members;
    }

    // build memebership information based on the given role name for the given principal when account information is unavailable
    protected RoleMembership getRoleMembershipWhenAccountInfoUnavailable(String roleName, String principalId, Map<String,String> roleQualifier) {
        BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
        Map<String, Object> fieldValues = new HashMap<String, Object>();
        
        RoleMembership roleMembershipInfo = null;

        if ((KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME.equals(roleName))) {
            fieldValues.put(KFSPropertyConstants.ACCOUNT_FISCAL_OFFICER_SYSTEM_IDENTIFIER, principalId);

            if (businessObjectService.countMatching(Account.class, fieldValues) > 0) {
                roleMembershipInfo = new RoleMembership(null, null, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier);
            }
        }
        else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_PRIMARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
            fieldValues.put(KFSPropertyConstants.ACCOUNT_DELEGATE_SYSTEM_ID, principalId);
            fieldValues.put(KFSPropertyConstants.ACCOUNTS_DELEGATE_PRMRT_INDICATOR, Boolean.TRUE);

            if (businessObjectService.countMatching(AccountDelegate.class, fieldValues) > 0) {
                roleMembershipInfo = new RoleMembership(null, null, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier);
            }
        }
        else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_SECONDARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
            fieldValues.put(KFSPropertyConstants.ACCOUNT_DELEGATE_SYSTEM_ID, principalId);
            fieldValues.put(KFSPropertyConstants.ACCOUNTS_DELEGATE_PRMRT_INDICATOR, Boolean.FALSE);

            if (businessObjectService.countMatching(AccountDelegate.class, fieldValues) > 0) {
                roleMembershipInfo = new RoleMembership(null, null, principalId, KimConstants.KimGroupMemberTypes.PRINCIPAL_MEMBER_TYPE, roleQualifier);
            }
        }
        
        return roleMembershipInfo;
    }

    protected Account getAccount(String chartOfAccountsCode, String accountNumber) {
        return getAccountService().getByPrimaryId(chartOfAccountsCode, accountNumber);
    }

    protected AccountDelegate getPrimaryDelegate(String chartOfAccountsCode, String accountNumber, String fisDocumentTypeCode, String totalDollarAmount) {
        return getAccountService().getPrimaryDelegationByExample(getDelegateExample(chartOfAccountsCode, accountNumber, fisDocumentTypeCode), totalDollarAmount);
    }

    protected List<AccountDelegate> getSecondaryDelegates(String chartOfAccountsCode, String accountNumber, String fisDocumentTypeCode, String totalDollarAmount) {
        return getAccountService().getSecondaryDelegationsByExample(getDelegateExample(chartOfAccountsCode, accountNumber, fisDocumentTypeCode), totalDollarAmount);
    }

    protected Person getProjectDirectorForAccount(String chartOfAccountsCode, String accountNumber) {
        return getContractsAndGrantsModuleService().getProjectDirectorForAccount(chartOfAccountsCode, accountNumber);
    }

    // Default to 0 total amount
    protected String getDefaultTotalAmount() {
        return "0";
    }<commit_msg>KFSMI-7116 Makes use of builder for RoleMember<commit_after>/*
 * Copyright 2008 The Kuali Foundation
 * 
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.opensource.org/licenses/ecl2.php
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.kuali.kfs.coa.identity;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.kuali.kfs.coa.businessobject.Account;
import org.kuali.kfs.coa.businessobject.AccountDelegate;
import org.kuali.kfs.coa.service.AccountDelegateService;
import org.kuali.kfs.coa.service.AccountService;
import org.kuali.kfs.integration.cg.ContractsAndGrantsModuleService;
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.kfs.sys.document.FinancialSystemMaintainable;
import org.kuali.kfs.sys.identity.KfsKimAttributes;
import org.kuali.rice.core.api.config.property.ConfigurationService;
import org.kuali.rice.core.api.membership.MemberType;
import org.kuali.rice.core.framework.parameter.ParameterService;
import org.kuali.rice.core.mail.MailMessage;
import org.kuali.rice.core.web.format.CurrencyFormatter;
import org.kuali.rice.kim.api.KimConstants;
import org.kuali.rice.kim.api.identity.Person;
import org.kuali.rice.kim.api.identity.principal.Principal;
import org.kuali.rice.kim.api.role.RoleMembership;
import org.kuali.rice.kim.api.services.IdentityManagementService;
import org.kuali.rice.kns.kim.role.DerivedRoleTypeServiceBase;
import org.kuali.rice.krad.service.BusinessObjectService;
import org.kuali.rice.krad.service.MailService;
import org.kuali.rice.krad.util.ObjectUtils;

public class AccountDerivedRoleTypeServiceImpl extends DerivedRoleTypeServiceBase {

    protected AccountService accountService;
    protected ContractsAndGrantsModuleService contractsAndGrantsModuleService;
    protected AccountDelegateService accountDelegateService;
    protected ConfigurationService configurationService;
    protected IdentityManagementService identityManagementService;
    protected MailService mailService;
    protected ParameterService parameterService;
    
    protected final static String DERIVED_ROLE_MEMBER_INACTIVATION_NOTIFICATION_EMAIL_ADDRESSES_PARAMETER_NAME = "DERIVED_ROLE_MEMBER_INACTIVATION_NOTIFICATION_EMAIL_ADDRESSES";

    /**
     * Attributes: Chart Code Account Number Requirements: - KFS-COA Account Supervisor: CA_ACCOUNT_T.ACCT_SPVSR_UNVL_ID - KFS-SYS
     * Fiscal Officer: CA_ACCOUNT_T.ACCT_FSC_OFC_UID - KFS-SYS Fiscal Officer Primary Delegate: CA_ACCT_DELEGATE_T.ACCT_DLGT_UNVL_ID
     * where ACCT_DLGT_PRMRT_CD = Y - KFS-SYS Fiscal Officer Secondary Delegate: CA_ACCT_DELEGATE_T.ACCT_DLGT_UNVL_ID where
     * ACCT_DLGT_PRMRT_CD = N - KFS-SYS Award Project Director: use the getProjectDirectorForAccount(String chartOfAccountsCode,
     * String accountNumber) method on the contracts and grants module service
     * 
     * @see org.kuali.rice.kns.kim.role.RoleTypeServiceBase#getPrincipalIdsFromApplicationRole(java.lang.String,
     *      java.lang.String, org.kuali.rice.kim.bo.types.dto.AttributeSet)
     */
    @Override
    public List<RoleMembership> getRoleMembersFromApplicationRole(String namespaceCode, String roleName, Map<String,String> qualification) {
        // validate received attributes
        validateRequiredAttributesAgainstReceived(qualification);
        List<RoleMembership> members = new ArrayList<RoleMembership>();
        if(qualification!=null && !qualification.isEmpty()){
            String chartOfAccountsCode = qualification.get(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE);
            String accountNumber = qualification.get(KfsKimAttributes.ACCOUNT_NUMBER);
    
            String financialSystemDocumentTypeCodeCode = qualification.get(KimConstants.AttributeConstants.DOCUMENT_TYPE_NAME);
            String totalDollarAmount = qualification.get(KfsKimAttributes.FINANCIAL_DOCUMENT_TOTAL_AMOUNT);
    
            String fiscalOfficerPrincipalID = qualification.get(KFSPropertyConstants.ACCOUNT_FISCAL_OFFICER_SYSTEM_IDENTIFIER);
            String accountSupervisorPrincipalID = qualification.get(KFSPropertyConstants.ACCOUNTS_SUPERVISORY_SYSTEMS_IDENTIFIER);
            String principalId = qualification.get(KimConstants.AttributeConstants.PRINCIPAL_ID);
    
            // Default to 0 total amount
            if (StringUtils.isEmpty(totalDollarAmount)) {
                totalDollarAmount = getDefaultTotalAmount();
            }
    
            Map<String,String> roleQualifier = new HashMap<String,String>();
            roleQualifier.put(KfsKimAttributes.CHART_OF_ACCOUNTS_CODE, chartOfAccountsCode);
            roleQualifier.put(KfsKimAttributes.ACCOUNT_NUMBER, accountNumber);
    
            if (chartOfAccountsCode == null && accountNumber == null && StringUtils.isNotBlank(principalId)) {
                RoleMembership roleMembershipInfo = getRoleMembershipWhenAccountInfoUnavailable(roleName, principalId, roleQualifier);
                if(ObjectUtils.isNotNull(roleMembershipInfo)) {
                    members.add(roleMembershipInfo);
                }
            }                        
    
            if (KFSConstants.SysKimApiConstants.ACCOUNT_SUPERVISOR_KIM_ROLE_NAME.equals(roleName)) {
                Account account = getAccount(chartOfAccountsCode, accountNumber);
                if (account != null) {
                    members.add(RoleMembership.Builder.create(null, null, account.getAccountsSupervisorySystemsIdentifier(), MemberType.PRINCIPAL, roleQualifier).build());
                }
                // only add the additional approver if they are different
                if (StringUtils.isNotBlank(accountSupervisorPrincipalID) && (account == null || !StringUtils.equals(accountSupervisorPrincipalID, account.getAccountsSupervisorySystemsIdentifier()))) {                    
                    members.add(RoleMembership.Builder.create(null, null, accountSupervisorPrincipalID, MemberType.PRINCIPAL, roleQualifier).build());
                }
            }
            else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME.equals(roleName)) {
                Account account = getAccount(chartOfAccountsCode, accountNumber);
                if (account != null) {                    
                    members.add(RoleMembership.Builder.create(null, null, account.getAccountFiscalOfficerSystemIdentifier(), MemberType.PRINCIPAL, roleQualifier).build());
                }
                // only add the additional approver if they are different
                if (StringUtils.isNotBlank(fiscalOfficerPrincipalID) && (account == null || !StringUtils.equals(fiscalOfficerPrincipalID, account.getAccountFiscalOfficerSystemIdentifier()))) {
                    members.add(RoleMembership.Builder.create(null, null, fiscalOfficerPrincipalID, MemberType.PRINCIPAL, roleQualifier).build());                    
                }
            }
            else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_PRIMARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
                AccountDelegate delegate = getPrimaryDelegate(chartOfAccountsCode, accountNumber, financialSystemDocumentTypeCodeCode, totalDollarAmount);
                if (delegate != null) {
                    roleQualifier.put(KfsKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE, delegate.getFinancialDocumentTypeCode());
                    roleQualifier.put(KfsKimAttributes.FROM_AMOUNT, (delegate.getFinDocApprovalFromThisAmt() == null) ? "0" : delegate.getFinDocApprovalFromThisAmt().toString());
                    roleQualifier.put(KfsKimAttributes.TO_AMOUNT, (delegate.getFinDocApprovalToThisAmount() == null) ? "NOLIMIT" : delegate.getFinDocApprovalToThisAmount().toString());
                    members.add(RoleMembership.Builder.create(null, null, delegate.getAccountDelegateSystemId(), MemberType.PRINCIPAL, roleQualifier).build());                       
                }
            }
            else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_SECONDARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
                List<AccountDelegate> delegates = getSecondaryDelegates(chartOfAccountsCode, accountNumber, financialSystemDocumentTypeCodeCode, totalDollarAmount);
                for (AccountDelegate delegate : delegates) {
                    roleQualifier.put(KfsKimAttributes.FINANCIAL_SYSTEM_DOCUMENT_TYPE_CODE, delegate.getFinancialDocumentTypeCode());
                    roleQualifier.put(KfsKimAttributes.FROM_AMOUNT, (delegate.getFinDocApprovalFromThisAmt() == null) ? "0" : delegate.getFinDocApprovalFromThisAmt().toString());
                    roleQualifier.put(KfsKimAttributes.TO_AMOUNT, (delegate.getFinDocApprovalToThisAmount() == null) ? "NOLIMIT" : delegate.getFinDocApprovalToThisAmount().toString());
                    members.add(RoleMembership.Builder.create(null, null, delegate.getAccountDelegateSystemId(), MemberType.PRINCIPAL, roleQualifier).build());                    
                }
            }
            else if (KFSConstants.SysKimApiConstants.AWARD_SECONDARY_DIRECTOR_KIM_ROLE_NAME.equals(roleName)) {
                Person person = getProjectDirectorForAccount(chartOfAccountsCode, accountNumber);
                if (person != null) {
                    members.add(RoleMembership.Builder.create(null, null, person.getPrincipalId(), MemberType.PRINCIPAL, roleQualifier).build());                    
                }
            }
        }
        return members;
    }

    // build memebership information based on the given role name for the given principal when account information is unavailable
    protected RoleMembership getRoleMembershipWhenAccountInfoUnavailable(String roleName, String principalId, Map<String,String> roleQualifier) {
        BusinessObjectService businessObjectService = SpringContext.getBean(BusinessObjectService.class);
        Map<String, Object> fieldValues = new HashMap<String, Object>();
        
        RoleMembership roleMembership = null;

        if ((KFSConstants.SysKimApiConstants.FISCAL_OFFICER_KIM_ROLE_NAME.equals(roleName))) {
            fieldValues.put(KFSPropertyConstants.ACCOUNT_FISCAL_OFFICER_SYSTEM_IDENTIFIER, principalId);

            if (businessObjectService.countMatching(Account.class, fieldValues) > 0) {
                roleMembership = RoleMembership.Builder.create(null, null, principalId, MemberType.PRINCIPAL, roleQualifier).build();
            }
        }
        else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_PRIMARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
            fieldValues.put(KFSPropertyConstants.ACCOUNT_DELEGATE_SYSTEM_ID, principalId);
            fieldValues.put(KFSPropertyConstants.ACCOUNTS_DELEGATE_PRMRT_INDICATOR, Boolean.TRUE);

            if (businessObjectService.countMatching(AccountDelegate.class, fieldValues) > 0) {
                roleMembership = RoleMembership.Builder.create(null, null, principalId, MemberType.PRINCIPAL, roleQualifier).build();
            }
        }
        else if (KFSConstants.SysKimApiConstants.FISCAL_OFFICER_SECONDARY_DELEGATE_KIM_ROLE_NAME.equals(roleName)) {
            fieldValues.put(KFSPropertyConstants.ACCOUNT_DELEGATE_SYSTEM_ID, principalId);
            fieldValues.put(KFSPropertyConstants.ACCOUNTS_DELEGATE_PRMRT_INDICATOR, Boolean.FALSE);

            if (businessObjectService.countMatching(AccountDelegate.class, fieldValues) > 0) {
                roleMembership = RoleMembership.Builder.create(null, null, principalId, MemberType.PRINCIPAL, roleQualifier).build();
            }
        }
        
        return roleMembership;
    }

    protected Account getAccount(String chartOfAccountsCode, String accountNumber) {
        return getAccountService().getByPrimaryId(chartOfAccountsCode, accountNumber);
    }

    protected AccountDelegate getPrimaryDelegate(String chartOfAccountsCode, String accountNumber, String fisDocumentTypeCode, String totalDollarAmount) {
        return getAccountService().getPrimaryDelegationByExample(getDelegateExample(chartOfAccountsCode, accountNumber, fisDocumentTypeCode), totalDollarAmount);
    }

    protected List<AccountDelegate> getSecondaryDelegates(String chartOfAccountsCode, String accountNumber, String fisDocumentTypeCode, String totalDollarAmount) {
        return getAccountService().getSecondaryDelegationsByExample(getDelegateExample(chartOfAccountsCode, accountNumber, fisDocumentTypeCode), totalDollarAmount);
    }

    protected Person getProjectDirectorForAccount(String chartOfAccountsCode, String accountNumber) {
        return getContractsAndGrantsModuleService().getProjectDirectorForAccount(chartOfAccountsCode, accountNumber);
    }

    // Default to 0 total amount
    protected String getDefaultTotalAmount() {
        return "0";
    }
{'fraction_non_alphanumeric': 0.0788378659533363, 'fraction_numerical': 0.0012631891811561897, 'mean_word_length': 3.8789197027369946, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6818539', 'n_tokens_mistral': 7705, 'n_tokens_neox': 7353, 'n_words': 1218}