[FIX] point_of_sale: do not unlink a reloaded orderline - #285662
Closed
fw-bot wants to merge 1 commit into
Closed
Conversation
Steps to reproduce:
- Restaurant config with two POS devices on the same session
- Device A: open a table, add two products, press Order (the order is
synced as a draft, its lines get server ids)
- Device A: remove both lines, without syncing
- Device B: touch the same order, so device A re-reads it from the
server through the synchronisation websocket
- Device A: pay and validate the order
Issue:
The order is saved as paid, with its total and its payment, but without
any orderline. The lines are deleted on the server:
odoo.models.unlink: deleted pos.order.line records with IDs: [...]
Cause:
Removing an orderline queues an unlink command in
models.commands['pos.order'].unlink['lines_<order id>'] (delete_ in
related_models.js). That command is only discarded by clearCommands(),
which syncAllOrders() calls after a successful sync, so it stays
pending in between.
Any read of the order in that window puts the line back: a deleted
record counts as missing in missingRecursive(), so it is fetched again
and loadData() re-creates it with its server id.
serialize() then emits both the update of the live line and the still
pending unlink, and sync_from_ui writes
lines: [[1, id, {...}], [3, id]]. The ORM applies commands in order, and
pos.order.line.order_id is ondelete='cascade', so Command.UNLINK deletes
the line right after writing it.
Fix:
Skip a removal command when the record is still linked to the parent at
serialization time. A record cannot be both linked and removed in the
same payload, so the pending command is stale and dropping it keeps the
local state. Genuine removals, where the record is no longer linked, are
still sent.
opw-6401146
X-original-commit: 4001c60
Contributor
Contributor
Author
|
This PR targets saas-18.4 and is part of the forward-port chain. Further PRs will be created up to master. More info at https://github.com/odoo/odoo/wiki/Mergebot#forward-port |
Contributor
Author
|
@pedrambiria @stva-odoo ci/runbot failed on this forward-port PR |
robodoo
pushed a commit
that referenced
this pull request
Sep 1, 2026
Steps to reproduce:
- Restaurant config with two POS devices on the same session
- Device A: open a table, add two products, press Order (the order is
synced as a draft, its lines get server ids)
- Device A: remove both lines, without syncing
- Device B: touch the same order, so device A re-reads it from the
server through the synchronisation websocket
- Device A: pay and validate the order
Issue:
The order is saved as paid, with its total and its payment, but without
any orderline. The lines are deleted on the server:
odoo.models.unlink: deleted pos.order.line records with IDs: [...]
Cause:
Removing an orderline queues an unlink command in
models.commands['pos.order'].unlink['lines_<order id>'] (delete_ in
related_models.js). That command is only discarded by clearCommands(),
which syncAllOrders() calls after a successful sync, so it stays
pending in between.
Any read of the order in that window puts the line back: a deleted
record counts as missing in missingRecursive(), so it is fetched again
and loadData() re-creates it with its server id.
serialize() then emits both the update of the live line and the still
pending unlink, and sync_from_ui writes
lines: [[1, id, {...}], [3, id]]. The ORM applies commands in order, and
pos.order.line.order_id is ondelete='cascade', so Command.UNLINK deletes
the line right after writing it.
Fix:
Skip a removal command when the record is still linked to the parent at
serialization time. A record cannot be both linked and removed in the
same payload, so the pending command is stale and dropping it keeps the
local state. Genuine removals, where the record is no longer linked, are
still sent.
opw-6401146
closes #285662
X-original-commit: 4001c60
Signed-off-by: Stéphane Vanmeerhaeghe (stva) <stva@odoo.com>
Signed-off-by: Pedram Bi Ria (pebr) <pebr@odoo.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Steps to reproduce:
Issue:
The order is saved as paid, with its total and its payment, but without any orderline. The lines are deleted on the server: odoo.models.unlink: deleted pos.order.line records with IDs: [...]
Cause:
Removing an orderline queues an unlink command in
models.commands['pos.order'].unlink['lines_'] (delete_ in related_models.js). That command is only discarded by clearCommands(), which syncAllOrders() calls after a successful sync, so it stays pending in between.
Any read of the order in that window puts the line back: a deleted record counts as missing in missingRecursive(), so it is fetched again and loadData() re-creates it with its server id.
serialize() then emits both the update of the live line and the still pending unlink, and sync_from_ui writes
lines: [[1, id, {...}], [3, id]]. The ORM applies commands in order, and pos.order.line.order_id is ondelete='cascade', so Command.UNLINK deletes the line right after writing it.
Fix:
Skip a removal command when the record is still linked to the parent at serialization time. A record cannot be both linked and removed in the same payload, so the pending command is stale and dropping it keeps the local state. Genuine removals, where the record is no longer linked, are still sent.
opw-6401146
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: #285427
Forward-Port-Of: #284695