Every lot now gets its expiry when it is created (docs/prd-point-coin.md
F12, PC-502), where it used to never expire until note N4 was settled:
- EARN and an ADJUSTMENT that adds: ComputeExpiry of the organization's
settings for that currency, from the moment received.
- EXCHANGE_IN: the sooner of the EnakCoin lot's expiry and when EnakPoint
received now expire (F4).
- PAYMENT_REFUND: the expiry of the lot the EnakPoint came from, but at
least seven days from the refund (N4, decided). A lot that never expired
stays so.
- TRANSFER_IN: unchanged, exactly the sender's expiry.
Turning expiry on for a currency for the first time dates every lot of the
organization that still holds something and has no expiry, MIGRATION lots
included, in the same transaction as the setting: a full period from now
when ROLLING, the second fixed date on or after today when FIXED_DATE, so
no customer loses a balance soon after the rule is announced (N4,
decided). Turning it off leaves dated lots as they are. PUT
/marketing/loyalty-settings reports these as expiry_activations (currency,
lots, amount, expires_at); a dry run counts them without dating anything.
The earning processor now also reads the organization settings, and the
wallet admin processor takes the settings reader.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds refunds of EnakPoint payments (docs/prd-point-coin.md F9, K7, Q13,
PC-307).
After a void or refund, onOrderRefunded now returns EnakPoint before taking
earning back. For each EnakPoint payment of the order it returns everything
on a void, and floor(refunded rupiah / the frozen point_value) when the
payment itself was refunded, so a later change of the point value does not
change how many come back and a remainder below one EnakPoint is lost. It
never returns more than the payment used, and only what has not come back
yet, so repeating is safe. PAYMENT_REFUND rows point at the PAYMENT they
reverse, and the EnakPoint go back into lots with the expiry of the lots
they were taken from, longest-lasting first (the 7-day extension waits on
note N4).
RefundOrder, which hands money back in cash or another method, is now
limited to what was paid with other methods; the EnakPoint part has to be
refunded through its own payment. That answers 400.
Fixes earning reversal from PC-204: a refund of the EnakPoint part raised
orders.refund_amount and so took earning back, although that part never
earned. It is now left out of the refund the reversal uses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>