I have a BO called Payment.
When a Customer makes a payment, I need to require that Customer to have a BillingAddress set, if it is an account payment.
However, I'm not sure how to do this in practice. What I have so far is shown below - it is throwing "given key not present in the dictionary". I can understand why. Really I just don't know if this is possible.
CODE:
private class ValidCustomerBusinessAddressRequiredForAccountPayments : BusinessRule
{
private readonly IBusinessRule _addressRequiredRule;
private readonly IBusinessRule _addressCompletedRule;
public ValidCustomerBusinessAddressRequiredForAccountPayments()
: base(MethodProperty)
{
InputProperties = new List<IPropertyInfo> { MethodProperty };
_addressRequiredRule = new Required(Customer.BillingAddressProperty);
_addressCompletedRule = new FullAddressRule(Customer.BillingAddressProperty);
}
protected override void Execute(RuleContext context)
{
var target = (Payment)context.Target;
var method = target.Method;
var customer = Customer.Get(target.PrimaryContactId);
if (customer != null && method == PaymentMethod.Account)
{
context.ExecuteRule(_addressRequiredRule); // throws exception
context.ExecuteRule(_addressCompletedRule);
}
}
}
No, this is not possible!
You may add code in OnChildChanged event on Customer and revalidate these fields on the customer object when child properties are changed.
What I do in a situation like this is create a command object that goes out to the database and does the check. I set a logical property on the command object which is checked when it returns to the rule.
/// <summary>
/// The UPS chargeback code validate billable rule.
/// </summary>
public class UpsChargebackCodeValidateBillableRule : BusinessRule
{
public UpsChargebackCodeValidateBillableRule(IPropertyInfo primaryProperty)
: base(primaryProperty)
{
ProvideTargetWhenAsync = true;
IsAsync = true;
AffectedProperties.Add(UpsChargebackCodeItem.BillableProperty);
}
/// <summary>
/// The execute.
/// </summary>
/// <param name="context">
/// The context.
/// </param>
protected override void Execute(RuleContext context)
{
UpsChargebackCodeItem target = (UpsChargebackCodeItem)context.Target;
if (target.Billable == false)
{
UpsChargebackCodeValidateBillableCommand.BeginExecute(target.Id, (o, e) =>
{
if (e.Error != null)
{
context.AddErrorResult(e.Error.Message);
context.Complete();
}
else
{
if (e.Object.OverrideUsed)
{
context.AddErrorResult("Code Is Overridden by Customer. Please Remove Code from Customer First.");
context.Complete();
}
else
{
context.AddSuccessResult(true);
}
context.Complete();
}
});
}
else
{
context.AddSuccessResult(true);
context.Complete();
}
}
}
Todd
Copyright (c) Marimer LLC