I'm working on a promotion system in ASP.NET Core using the RulesEngine library (RulesEngine.Models). My goal is to apply multiple promotion rules, but I have an issue where if the first rule fails, the remaining rules are not evaluated.
What I Want to Achieve: Fetch active promotion rules from the database. Evaluate each rule independently (so that even if one fails, others still run). If a rule condition is not met, skip it but continue evaluating the next rules. Ensure discounts apply only once per item (avoid duplicate calculations).
Problem Description:
Currently, I retrieve rules from the database and execute them one by one. However, if the first rule's condition is false, the next rules do not execute. Example of Rules:
"Receipt.Rows.Sum(r => r.Qta) > 10"
"Receipt.Rows.Any(r => r.Cd_AR == \"1\")"
If the first condition (Receipt.Rows.Sum(r => r.Qta) > 10) is false, → The second condition (Receipt.Rows.Any(r => r.Cd_AR == "1")) is never checked. I need all rules to be evaluated, even if some fail.
My Current Code: ApplyPromozioni (Controller)
`[HttpPost("apply")]
public async Task<IActionResult> ApplyPromozioni(Receipt receipt)
{
RuleEvaluator.SetReceipt(receipt, clusterARRepository);
var regole = await GetRegoleAttive();
if (!regole.Any()) return Ok(receipt);
var orderedRules = regole.OrderBy(r => r.Priorita).ToList();
Console.WriteLine($"[DEBUG] Total Rules to Evaluate: {orderedRules.Count}");
var reSettings = new ReSettings
{
CustomActions = new Dictionary<string, Func<ActionBase>>(),
IgnoreException = true,
};
foreach (var rule in orderedRules)
{
if (!reSettings.CustomActions.ContainsKey(rule.Azione))
{
reSettings.CustomActions[rule.Azione] = () => CreateActionInstance(rule.Azione, receipt);
}
}
var engine = new RulesEngine.RulesEngine(reSettings);
foreach (var rule in orderedRules)
{
try
{
Console.WriteLine($"[DEBUG] Evaluating Rule: {rule.Condizione}");
bool conditionMet = RuleEvaluator.EvaluateGeneralCondition(rule.Condizione);
Console.WriteLine($"[DEBUG] Rule Result: {rule.Condizione} => {conditionMet}");
if (!conditionMet)
{
Console.WriteLine($"⚠️ [DEBUG] Rule {rule.Condizione} FAILED, skipping...");
continue;
}
var workflow = new Workflow
{
WorkflowName = $"Workflow_{rule.Nome}",
Rules = new List<Rule>
{
new Rule
{
RuleName = rule.Nome,
Expression = "true", //