Оцените каждое правило независимо (так что даже если кто -то не удается, другие все еще работают).
Если условие правила не выполнено, пропустите его, но продолжайте оценивать следующие правила. Br /> Убедитесь, что скидки применяются только один раз на элемент (избегайте дублирующих расчетов). < /p>
Описание задачи: < /p>
В настоящее время я получаю правила из базы данных и Выполните их один за другим.
Однако, если условие первого правила неверно, следующие правила не выполняются.
Пример правил: < /p>
"Receipt.Rows.Sum(r => r.Qta) > 10"
"Receipt.Rows.Any(r => r.Cd_AR == \"1\")"
< /code>
Если первое условие (receipt.rows.sum (r => r.qta)> 10) является false,
→ второе условие (chestipt.rows.any ( r => r.cd_ar == "1")) никогда не проверяется.
Мне нужны все правила, которые должны быть оценены, даже если некоторые сбой. < /p>
Мой текущий код: < Br /> ApplyProMozioni (Controller) < /p>
`[HttpPost("apply")]
public async Task 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(),
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($"
continue;
}
var workflow = new Workflow
{
WorkflowName = $"Workflow_{rule.Nome}",
Rules = new List
{
new Rule
{
RuleName = rule.Nome,
Expression = "true", //
Actions = new RuleActions
{
OnSuccess = new ActionInfo
{
Name = rule.Azione,
Context = new Dictionary { { "Receipt", receipt } }
}
}
}
}
};
engine.AddOrUpdateWorkflow(new[] { workflow });
var result = await engine.ExecuteAllRulesAsync(workflow.WorkflowName, new { Receipt = receipt });
foreach (var res in result)
{
Console.WriteLine($"
if (res.IsSuccess)
{
receipt = res.ActionResult.Output as Receipt;
Console.WriteLine($"
}
else
{
Console.WriteLine($"
}
}
}
catch (Exception ex)
{
Console.WriteLine($"
}
}
Console.WriteLine($"{JsonConvert.SerializeObject(receipt, Formatting.Indented)}");
return Ok(receipt);
}
`
< /code>
Applydiscountrule < /p>
public class ApplyDiscountRule : ActionBase
{
private readonly Receipt _receipt;
private readonly IPromozioneRuleRepository _promozioneRuleRepository;
private readonly IClusterARRepository _clusterARRepository;
public ApplyDiscountRule(Receipt receipt, IPromozioneRuleRepository promozioneRuleRepository, IClusterARRepository clusterARRepository)
{
_receipt = receipt;
_promozioneRuleRepository = promozioneRuleRepository;
_clusterARRepository = clusterARRepository;
}
public override async ValueTask Run(ActionContext context, RuleParameter[] ruleParameters)
{
// **Kuralları DB'den çek**
var rulesFromDb = (await _promozioneRuleRepository.GetActivePromotionRulesAsync())
.OrderBy(r => r.Priorita) // Önceliğe göre sırala
.ToList();
if (!rulesFromDb.Any())
{
Console.WriteLine($"
return _receipt;
}
RuleEvaluator.SetReceipt(_receipt, _clusterARRepository);
var generalRules = rulesFromDb
.Where(rule => !rule.Condizione.Contains("Receipt.Rows.Any(r => r.Cd_AR ==")) // Cluster ID içermeyen kurallar
.ToList();
foreach (var rule in generalRules)
{
if (RuleEvaluator.EvaluateGeneralCondition(rule.Condizione)) // Sadece genel koşulları değerlendir
{
Console.WriteLine($"
foreach (var row in _receipt.Rows)
{
string discountValue = DiscountHelper.ExtractDiscountValue(rule.Azione);
row.ScontoP = DiscountHelper.ApplySequentialDiscount(row.ScontoP ?? "0", discountValue);
Console.WriteLine($"
}
}
}
foreach (var row in _receipt.Rows)
{
Console.WriteLine($"
var matchingRules = rulesFromDb
.Where(r => r.Condizione.Contains("Receipt.Rows.Any(r => r.Cd_AR =="))
.ToList();
foreach (var rule in matchingRules)
{
var match = Regex.Match(rule.Condizione, @"Receipt\.Rows\.Any\(r => r\.Cd_AR == \""(\d+)\""\)");
if (!match.Success)
{
Console.WriteLine($"[DEBUG] Skipping rule, no Cluster ID found: {rule.Condizione}");
continue;
}
int clusterId = int.Parse(match.Groups[1].Value);
Console.WriteLine($"[DEBUG] Found Cluster ID: {clusterId} in PromozioneRule");
var clusterData = await _clusterARRepository.GetByIdAsync(clusterId);
if (clusterData == null)
{
Console.WriteLine($"[ERROR] No ClusterAR found for Cluster ID: {clusterId}");
continue;
}
string clusterCdAR = clusterData.Cd_AR;
Console.WriteLine($"[DEBUG] Found Cd_AR for Cluster {clusterId}: {clusterCdAR}");
if (row.Cd_AR != clusterCdAR)
{
Console.WriteLine($"[DEBUG] Skipping row {row.Cd_AR}, not matching ClusterAR Cd_AR.");
continue;
}
if (row.Qta >= clusterData.Quantity)
{
string discountValue = DiscountHelper.ExtractDiscountValue(rule.Azione);
row.ScontoP = DiscountHelper.ApplySequentialDiscount(row.ScontoP ?? "0", discountValue);
Console.WriteLine($"
}
else
{
Console.WriteLine($"
}
}
}
return _receipt;
}
}
< /code>
То, что я попробовал и не работал:
принуждение всех правил запустить
i set Expression = "true" в правилах Engine для заставления правил выполнять,
Но все же, когда первое правило не удалось, другие не выполняются правильно. .
вручную зацикливание по правилам
Даже если я прохожу через каждое правило один за другим,
Если первое не удалось, Applydiscountrule не выполняется для остальных. < /p>
Мой вопрос:
Как я могу убедиться, что все правила работают независимо, даже если некоторые терпят неудачу?
Я хочу, чтобы каждое правило было оценено одно за другим. Следует просто пропустить, но другие все еще должны работать.
Как я могу изменить свою реализацию для достижения этой < /p>
Подробнее здесь: https://stackoverflow.com/questions/794 ... t-executed