def declare_logic(): Rule.sum(derive=Customer.Balance, as_sum_of=Order.AmountOwed) Rule.formula(derive=Order.AmountOwed, as_expression=lambda row: row.AmountTotal - row.AmountPaid) Rule.sum(derive=Order.AmountPaid, as_sum_of=PaymentAllocation.AmountAllocated) Rule.formula( derive=PaymentAllocation.AmountAllocated, as_expression=lambda row: min(Decimal(row.Payment.AmountUnAllocated), Decimal(row.Order.AmountOwed))) Rule.early_row_event(on_class=Payment, calling=allocate_payment) """
def load_rules(self): def my_early_event(row, old_row, logic_row): logic_row.log("early event for *all* tables - good breakpoint, time/date stamping, etc") def check_balance(row: Customer, old_row, logic_row) -> bool: """ Not used... illustrate function alternative (e.g., more complex if/else logic) specify rule with `calling=check_balance` (instead of as_condition) """ return row.Balance <= row.CreditLimit def compute_amount(row: OrderDetail, old_row, logic_row): return row.UnitPrice * row.Quantity Rule.formula(derive="OrderDetail.Amount", calling=compute_amount) Rule.formula(derive="OrderDetail.Amount", calling=lambda Customer: Customer.Quantity * Customer.UnitPrice) Rule.early_row_event(on_class="*", calling=my_early_event) # just for debug Rule.constraint(validate="Customer", calling=check_balance, error_msg="balance ({row.Balance}) exceeds credit ({row.CreditLimit})")