-
-
Notifications
You must be signed in to change notification settings - Fork 671
[FIX] duplicate container_deposit products in history #1448
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 16.0
Are you sure you want to change the base?
Conversation
eb99ea5 to
a60c3b7
Compare
|
summary of technical findings TL;DR: The module adds an extra orderline for products that have a deposit product. Unfortunately, when loading history, the "deposit product" orderline , is both loaded from the backend and then re-added with the same logic, resulting in a double deposit product line. We need to distinguish orders loaded from backend from live orders loaded from pos.db. We have found that the order state is a reliable criteria to stop re-adding the deposit product , and determine it is already coming from the backend. https://github.com/odoo/odoo/blob/16.0/addons/point_of_sale/static/src/js/models.js#L2664 https://github.com/odoo/odoo/blob/16.0/addons/point_of_sale/static/src/js/models.js#L1032 We can see it is removed from the pos.db, and not synced anymore. In conclusion: Orders loaded from backend will have "state" in there Json and be set as "locked" (unmodifiable). These orders are written as pos.order records in the backend at the moment of payment. All other orders are saved in pos.db, do not have state. Implementing the connection between the product and it's added deposit in the backend too, would also be a solution and stop the addition , but if the user changes the backend in any way (quantity, removing or adding deposit products) this type of sync would force additions customer may not want. We do not want this module to force modifications the user may have overridden. |
thomaspaulb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So yes I feel I can approve this because even though I think the "proper" solution would have been that we also save "container_deposit_line" on the sale.order.line id in the backend, to hard-link the product line with its deposit line, so that when reloading it from the backend the both are linked:
-
The "state === undefined" criterion also works because at least in 16.0
point_of_sale, the only function that really loads orders from the backend is_fetchSyncedOrders, and that one always loads finished orders anyway, so state !== undefined and it does solve the bug of the historic orders that are loaded, having the duplicate lines. -
Looking at state is actually better, because in fact you never want a deposit product to be (re)added if it is not already present in a paid order: the order is finalized and should not be changed. People could have manually removed the deposit product as a correction and then that manual correction should be respected.
So I can live with this
|
@thomaspaulb In certain circumstances we find our order.state is still undefined. new solution is better. To distinguish payed orders and not payed orders , all we need to do is fetch unpayed orders from posGlobalState object: If our line.order is not in the unpayed orders, we do not apply the logic. |
535ec1d to
9bd97cd
Compare
9bd97cd to
ce572bc
Compare
| **/ | ||
| super.add_orderline(...arguments); | ||
| if (line.container_deposit_product && !line.container_deposit_line) { | ||
| // Get unpayed orders orders from db.pos |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If anything this would be pos.db, but get_order_list does not get from pos.db (=localStorage), but directly from this.orders, which as far as I can see is just a list of all orders that have been touched since this particular browser tab was opened. So the claim that this comment does is false.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thomaspaulb
pos.db.. i will correct my typo now. but get_orders is connected to pos.db
You can see that the orders attribute of the pos object is taken from pos.db: https://github.com/odoo/odoo/blob/16.0/addons/point_of_sale/static/src/js/models.js#L246
get_orders fetches pos.orders, pos.orders is taken on session load from pos.db.orders
the comment is true.
| if (line.container_deposit_product && !line.container_deposit_line) { | ||
| // Get unpayed orders orders from db.pos | ||
| const all_unpaid = this.pos.get_order_list().map((x) => x.cid); | ||
| const is_unpaid = all_unpaid.includes(line.order.cid); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it is a good criterium, I tested on Runboat and it seems like this is indeed a measure of which orders are open in the current session and not paid yet.
thomaspaulb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nonblocking but the comment is technically false
When visualizing paid orders, the container_products associated to a product would show duplicated.
this is because after loading an existing pos.order from the backend, the code would still add another container_deposit_product, therefore duplicating them all , in visualization.
the problem was seen by users when accessing the "orders" icon, and visualizing paid orders, they would appear with duplicates. also the receipts, generated from that visualization were also incorrect.
This would only be a POS visualization problem, because the pos.order had been payed and closed and was not editable, but the visualization was broken, and also the receipts were printed wrong on every step of the way.
I initially tried to put a check on init_from_Json, to stop the orders coming from json to have duplicates re-added, but thiswould not stop the duplicates from appearing on the currently active order, wich was also, at times loaded form json (e.g. page reload of the same session).
a simple way to stop the addition of the lines was to check the state, an open active order needs the container_deposit_product , all the orders that have a state do not, they already have the container products added.
i prefer to check for
order.state == undefinedto determine currently active order instead of!['done', 'invoiced', 'paid'].includes(order.state)to cover future state extensions.after few temporary solutions, i found no need to add flags in constructor of the order or in init_from_Json.
The option of sanitizing json source from the container_products and leaving the auto-add active for all orders is a bad idea, because it de-syncs odoo and pos. if someone were to manually removes the container_deposit_product line from the backend , this will show the correct lines, without re-adding.
tested 25 minutes in various settings. undergoing more testing from others.