Commit Graph
3 Commits
Author SHA1 Message Date
efrilm 582dc75543 Reapply "feat(loyalty): EnakPoint & EnakCoin" (#32)
This reverts commit 4e24f9bbb0.
2026-09-30 15:31:44 +07:00
efrilmandClaude Opus 5.5 4e24f9bbb0 Revert "feat(loyalty): EnakPoint & EnakCoin" (#32)
This reverts merge commit 645da30, returning main to f0ff59f.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 15:16:15 +07:00
efrilmandClaude Opus 5.5 eb5b63677f feat(loyalty): take back earning when an order is voided or refunded
Adds earning reversal (docs/prd-point-coin.md F10, Q3, PC-204).

VoidOrder, RefundOrder and RefundPayment now end with an onOrderRefunded
hook, called once their writes have committed and, like onOrderPaid,
detached from the request so it can never block or fail the void or
refund. For RefundPayment that is after its transaction.

EarningProcessor.ReverseForOrder computes how much of each EARN row should
have come back in total: everything for a void, otherwise
floor(earned × refunded / basis) with the order's cumulative refund and
the basis frozen on the EARN row, never more than was earned (a refund
including tax can pass the basis). It takes only what has not been asked
back yet, what was taken plus any shortfall, so repeats and successive
partial refunds never add up to more than the earning. It writes an
EARN_REVERSAL pointing at the EARN with DebitUpTo, drawing from the lots
the EARN created first, and records the shortfall when the balance was
already spent.

When the balance is empty there is no ledger row to carry the shortfall;
that case is logged. VoidOrder still refuses fully paid orders, so a void
has nothing to take back today; the hook keeps it correct if that changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 10:45:33 +07:00