Central contract split fails when using custom field criteria in Business Rules Framework

We’re trying to implement automated central contract splitting in SAP CX based on custom field criteria, but the split operation consistently fails when Business Rules Framework evaluates our custom fields. Standard field-based splits work fine, but we need to split contracts based on a custom field called “ServiceRegion” (values: EMEA, APAC, AMERICAS).

The Business Rules Framework rule is configured to evaluate ServiceRegion and create separate child contracts for each region. However, when the split executes, we get this error:


Business Rule Evaluation Error
Rule: CONTRACT_SPLIT_BY_REGION
Error: Custom field 'ServiceRegion' not accessible

I’ve verified the custom field exists and is populated on the central contract. The field is defined as a picklist with the three region values. In the Business Rules Framework rule definition, I’m referencing it as contract.customFields.ServiceRegion, but this doesn’t seem to work. Does the Business Rules Framework have specific requirements for accessing custom fields during contract split logic? Are there limitations on which custom field types can be used in split criteria?

Let me provide a comprehensive solution for implementing central contract splits based on custom fields using Business Rules Framework, covering the central contract split logic, custom field support requirements, and proper Business Rules Framework integration.

Understanding Central Contract Split Architecture:

SAP CX central contract splitting uses a three-layer architecture:

  1. Contract Data Layer: Source contract with all fields (standard + custom)
  2. Business Rules Evaluation Layer: Rules engine that determines split criteria
  3. Contract Creation Layer: Generates child contracts based on split results

Custom fields exist in Layer 1 but aren’t automatically available in Layer 2. You need to bridge this gap.

Solution: Custom Attribute Provider Implementation

Step 1: Create Custom Attribute Provider Class

Create a Java class that exposes custom fields to the Business Rules Framework:

public class ContractCustomFieldProvider implements AttributeProvider {

    @Override
    public Map<String, Object> getAttributes(Object entity) {
        Map<String, Object> attributes = new HashMap<>();
        if (entity instanceof Contract) {
            Contract contract = (Contract) entity;
            attributes.put("ServiceRegion",
                contract.getCustomField("ServiceRegion"));
        }
        return attributes;
    }
}

Step 2: Register Provider in Business Rules Configuration

Add provider registration to your Business Rules Framework configuration XML:

<rule-configuration>
  <attribute-providers>
    <provider class="com.custom.ContractCustomFieldProvider"
              entity-type="Contract"
              priority="100"/>
  </attribute-providers>
</rule-configuration>

Step 3: Update Business Rule Definition

Modify your contract split rule to use the exposed custom field:

<rule id="CONTRACT_SPLIT_BY_REGION">
  <condition>
    <expression>contract.ServiceRegion != null</expression>
  </condition>
  <actions>
    <split-contract>
      <split-criteria field="ServiceRegion"/>
      <child-contract-template>REGION_CONTRACT</child-contract-template>
    </split-contract>
  </actions>
</rule>

Step 4: Custom Field Type Considerations

Business Rules Framework supports these custom field types for split criteria:

  • Picklist/Enumeration: Best for categorical splits (like your ServiceRegion)
  • Text Fields: Supported but requires exact string matching
  • Numeric Fields: Supported with range-based split logic
  • Date Fields: Supported with date range splits
  • Boolean Fields: Supported for binary splits

NOT Supported:

  • Multi-select picklists (ambiguous split logic)
  • Rich text fields (too complex for rule evaluation)
  • Related object fields (requires join logic)

Complete Implementation for ServiceRegion Split:

Here’s the full implementation addressing your specific use case:

1. Enhanced Attribute Provider with Validation:

public class ContractRegionAttributeProvider implements AttributeProvider {

    private static final Set<String> VALID_REGIONS =
        Set.of("EMEA", "APAC", "AMERICAS");

    @Override
    public Map<String, Object> getAttributes(Object entity) {
        Map<String, Object> attributes = new HashMap<>();

        if (entity instanceof Contract) {
            Contract contract = (Contract) entity;
            String region = contract.getCustomField("ServiceRegion");

            // Validate region value before exposing
            if (VALID_REGIONS.contains(region)) {
                attributes.put("ServiceRegion", region);
                attributes.put("isValidRegion", true);
            } else {
                attributes.put("ServiceRegion", "INVALID");
                attributes.put("isValidRegion", false);
            }
        }

        return attributes;
    }
}

2. Business Rule with Error Handling:

<rule id="CONTRACT_SPLIT_BY_REGION" priority="10">
  <condition>
    <and>
      <expression>contract.ServiceRegion != null</expression>
      <expression>contract.isValidRegion == true</expression>
      <expression>contract.status == 'ACTIVE'</expression>
    </and>
  </condition>

  <actions>
    <split-contract>
      <split-criteria field="ServiceRegion"/>
      <child-contract-properties>
        <inherit-fields>true</inherit-fields>
        <override-field name="contractType">REGIONAL_CONTRACT</override-field>
        <copy-custom-field source="ServiceRegion" target="ServiceRegion"/>
      </child-contract-properties>
      <split-mode>CREATE_CHILDREN</split-mode>
    </split-contract>
  </actions>

  <on-error>
    <log-message>Contract split failed for contract {contract.id}: Invalid ServiceRegion value</log-message>
    <set-field name="splitStatus" value="FAILED"/>
  </on-error>
</rule>

3. Deployment Configuration:

Update your SAP CX deployment descriptor to load the custom provider:

<extension name="customcontractsplit">
  <classes>
    <class>com.custom.ContractRegionAttributeProvider</class>
  </classes>
  <business-rules>
    <rule-file>contract-split-rules.xml</rule-file>
  </business-rules>
</extension>

Testing the Implementation:

  1. Unit Test Custom Attribute Provider:

    • Create test contract with ServiceRegion = “EMEA”
    • Call getAttributes() and verify ServiceRegion is returned
    • Test with invalid region value, verify validation logic
  2. Integration Test Business Rule:

    • Create central contract with line items for multiple regions
    • Trigger contract split process
    • Verify child contracts created for each unique ServiceRegion value
    • Confirm custom field values copied to child contracts
  3. End-to-End Test:

    • Create contract with mixed region line items
    • Execute split via UI or API
    • Validate:
      • Central contract status updated to SPLIT
      • Three child contracts created (one per region)
      • Each child contract has correct ServiceRegion value
      • Line items distributed correctly to regional contracts

Common Issues and Resolutions:

Issue 1: “Custom field not accessible” error persists Resolution: Verify attribute provider is registered BEFORE Business Rules Framework initialization. Check deployment order in extension configuration.

Issue 2: Split creates empty child contracts Resolution: Ensure split-criteria field matches EXACTLY the attribute name exposed by provider (case-sensitive).

Issue 3: Some line items not included in split Resolution: Add line-item-distribution logic to rule actions specifying how to distribute items based on their individual ServiceRegion values.

Issue 4: Performance degradation with large contracts Resolution: Implement caching in attribute provider - cache custom field values during provider initialization rather than fetching on every attribute access.

Best Practices for Custom Field-Based Splits:

  1. Validation: Always validate custom field values before split execution
  2. Logging: Add detailed logging in attribute provider for troubleshooting
  3. Error Handling: Implement on-error handlers in rules to prevent partial splits
  4. Testing: Test with edge cases (null values, empty strings, invalid enumerations)
  5. Documentation: Document which custom fields are exposed and their expected formats
  6. Performance: Cache custom field metadata to avoid repeated database queries
  7. Versioning: Version your attribute providers to handle schema changes

Alternative Approach: Pre-Processing Extension

If attribute provider approach proves too complex, consider a pre-processing extension:

  1. Create a custom contract split service that reads custom fields
  2. Map custom field values to standard contract attributes (like contract category)
  3. Use standard Business Rules Framework split logic on mapped attributes
  4. Post-process child contracts to restore original custom field values

This approach avoids Business Rules Framework custom field limitations but requires more custom code.

Verification of Success: Your implementation is working correctly when:

  1. Business Rule evaluation logs show ServiceRegion attribute available
  2. Contract split creates correct number of child contracts (one per unique region)
  3. Each child contract has appropriate ServiceRegion value
  4. No manual intervention required for region-based splits
  5. Split execution time remains under 5 seconds for contracts with up to 100 line items

This draft is based on general SAP Customer Experience (SAP CX) knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.

The Business Rules Framework has limited direct access to custom fields in contract objects. The standard contract split logic primarily works with predefined contract attributes like contract type, value, and date fields. Custom fields require explicit exposure through the contract data model.

You might need to extend the contract entity in the Business Rules data model to include your ServiceRegion field. Check the Business Rules Framework documentation for custom field mapping procedures.

I looked into the data model extension, but I’m not finding clear documentation on how to expose custom fields to Business Rules Framework for contract splitting specifically. The general custom field documentation covers field creation and API access, but not Business Rules integration.

Is there a specific XML configuration or Java extension needed to make custom fields available in the contract split context?

For custom field access in Business Rules Framework, you need to create a custom attribute provider. This is a Java class that implements the AttributeProvider interface and explicitly exposes your custom fields to the rules engine. The standard contract split process doesn’t automatically include custom fields in the evaluation context.

Without this provider, the rules engine can’t resolve contract.customFields.ServiceRegion because it’s not in the default contract attribute map.

That makes sense. I found some references to AttributeProvider in the SDK documentation. Do you have an example of how to implement this for contract custom fields? Specifically, what methods need to be implemented and how do I register the provider with the Business Rules Framework?

I’ve implemented custom attribute providers for similar use cases. The basic structure involves:

  1. Create a class implementing `com.sap.cxm.rules.AttributeProvider
  2. Override getAttributes() method to return a map of custom field names and values
  3. Register the provider in the Business Rules configuration XML

The tricky part is ensuring the provider is invoked during the contract split process specifically, not just general rule evaluation. Contract split has its own execution context that needs explicit provider registration.