Thursday, September 24, 2026
2 changes · saas-19.2
Resolved issues and error corrections
Point of Sale orders now keep gift card, eWallet, and coupon rewards applied after the cashier refreshes the page or reopens an order. This prevents customers from being accidentally charged the full price when part of the order was already covered by a code-based reward.
Original PR description
Steps to reproduce: - Create a gift card program and a gift card with some balance - Open a PoS session, add a product to a new order and enter the gift card code: a reward line is added and the…
Steps to reproduce: - Create a gift card program and a gift card with some balance - Open a PoS session, add a product to a new order and enter the gift card code: a reward line is added and the total decreases - Refresh the page, or leave the order and take it back from the Orders screen Issue: The reward line disappears and the total goes back to the full price, while the server still holds the pos.order.line with `is_reward_line`, `coupon_id` and `points_cost`. Nothing warns the cashier, so the customer can be charged for a service already paid with the card. Cause: `_code_activated_coupon_ids` is a local field of pos.order: it is neither stored in IndexedDB nor sent to the server, so it is empty once the order is rebuilt on the client. `_updateRewardLines` deletes every reward line and only re-applies the ones whose coupon is found in `_code_activated_coupon_ids` or in `uiState.couponPointChanges`. `updatePrograms` only rebuilds the latter for programs detectable from the order content, so a gift card, eWallet or coupon card activated by code is never recognised again and its reward is dropped by the next `updateRewards` call (TicketScreen.setOrder, barcode scan, partner change, line added...). In 17.0 `codeActivatedCoupons` was exported and restored with the order; the field became local with the 18.0 models rewrite. Fix: Add `_restoreCodeActivatedCoupons` on pos.order and call it from `checkMissingCoupons`, which runs once per rebuilt order (`setup` flags it with `invalidCoupons`) before the programs and the reward lines are refreshed. It re-links every persisted coupon referenced by a reward line that is in neither structure. Nominative cards are excluded so that removing the partner still drops their reward. opw-6568849 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#290257 Forward-Port-Of: odoo/odoo#288102
Starshipit delivery rates now validate addresses before requesting prices, so incomplete wallet addresses no longer block the whole express checkout process. If Starshipit cannot quote because the address is partial or another carrier-specific issue occurs, other delivery options can still be shown and customers can continue paying.
Original PR description
#### Description of the issue/feature this PR addresses: Rating a Starshipit shipment for an incomplete delivery address makes the whole rating loop fail instead of skipping that carrier. This breaks…
#### Description of the issue/feature this PR addresses:
Rating a Starshipit shipment for an incomplete delivery address makes the whole rating loop fail instead of skipping that carrier. This breaks express checkout (Apple Pay / Google Pay), where the wallet only discloses a partial address before authorization: the customer gets "update postal address" and cannot pay, while manual checkout works.
#### Current behavior before PR:
delivery_starshipit is the only connector that rates a shipment without validating the addresses first, and it ignores the express_checkout_partial_delivery_address context key set by website_sale. The empty street is sent to /api/rates, which answers 200 with {"success": false, "errors": [{"details": "street parameter value is required"}]}, and _send_request turns that into a UserError. As starshipit_rate_shipment lets it propagate, it aborts the rating of every carrier instead of only this one, so no delivery method reaches the wallet. The same happens for errors only the api can report, such as invalid credentials.
#### Desired behavior after PR is merged:
Both the recipient and the warehouse address are validated before the api is called, as the other connectors already do, and the message is returned as an unsuccessful rate rather than raised. Starshipit requires the street, so a streetless address is still refused, but with a neutral message in the express checkout flow since the customer cannot complete it before paying. The Starshipit carrier is simply not proposed among the wallet's options, the other carriers are rated normally, and express checkout completes.
opw-6393393
Forward-Port-Of: odoo/enterprise#132515
Forward-Port-Of: odoo/enterprise#125117