I’ll address all three focus areas that are likely causing your issue:
Rule Registration:
Your custom rule needs proper registration beyond just showing up in the UI. Verify these registration aspects:
- Spring Bean Registration - your rule must be registered as a Spring bean:
@Component("customTierUpgradeRule")
@LoyaltyRule(type = "TIER_UPGRADE", priority = 100)
public class CustomTierUpgradeRule extends AbstractLoyaltyRule {
- Rule Configuration Entry - check
loyalty-rules-config.xml contains:
<rule id="customTierUpgrade"
class="CustomTierUpgradeRule"
enabled="true"
evaluationTrigger="POINTS_CHANGE,PURCHASE_COMPLETE"/>
- Tier Definition Link - the Gold tier definition must reference your custom rule in the tier progression rules.
Rule Engine Logs:
Enable detailed rule engine logging to diagnose the issue. Add to your logging configuration:
log4j.logger.com.sap.cx.loyalty.rule.engine=DEBUG
log4j.logger.com.sap.cx.loyalty.evaluation=TRACE
Then check logs for these specific patterns:
- “Evaluating rule: customTierUpgradeRule” - confirms rule is being invoked
- “Rule evaluation result: false” - shows your rule is running but returning false
- “Skipping rule: customTierUpgradeRule, reason: […]” - indicates why rule is being skipped
Most commonly, you’ll see “Context data not available” which leads to the next point.
Tier Evaluation:
The tier evaluation process has specific data requirements. Your current implementation has a critical flaw - getPurchaseCount(90) is likely returning 0 or null because the purchase data isn’t loaded in the evaluation context by default.
Fix this by implementing a custom context enricher:
@Component
public class TierEvaluationContextEnricher implements LoyaltyContextEnricher {
@Override
public void enrich(LoyaltyContext context) {
String customerId = context.getCustomerId();
int purchaseCount = purchaseService.getRecentPurchaseCount(customerId, 90);
context.setAttribute("purchase_count_90", purchaseCount);
}
}
Then modify your rule:
@Override
public boolean evaluate(LoyaltyContext context) {
int points = context.getCustomerPoints();
Integer purchases = (Integer) context.getAttribute("purchase_count_90");
if (purchases == null) {
logger.warn("Purchase count not available in context for customer {}",
context.getCustomerId());
return false;
}
return points >= 5000 && purchases >= 10;
}
Also ensure tier evaluation is triggered correctly. Register an event listener:
@EventListener
public void onPointsUpdate(PointsAccumulatedEvent event) {
tierEvaluationService.evaluateTierForCustomer(event.getCustomerId());
}
Finally, verify your rule’s execution by adding explicit logging in the evaluate method and checking that both conditions are being evaluated with the correct values. The rule engine logs will show you the exact data state when evaluation occurs, which is crucial for debugging why the tier upgrade isn’t happening.
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.