Daily updates from Odoo
Friday, May 22, 2026
46 changes · saas-19.2
New functionality added to Odoo
This update adds a new test to ensure the structure of payment data sent to our payment processor (Odoofin) remains consistent. This helps prevent unexpected changes on their side and ensures that any necessary updates are made in our system as well, strengthening our payment processing reliability.
Original PR description
Add a test asserting the payment payload structure sent to Odoofin. The goal is to safeguard against unintended payload changes that are not handled on Odoofin's side by making such changes explicit during testing, and reminding developers that corresponding updates may also be required there. No task ID Forward-Port-Of: odoo/enterprise#117836 Forward-Port-Of: odoo/enterprise#117260
Enhancements to existing features
This update simplifies the calculations for 'Retained Earnings' and 'Result for the Year' on the French Balance Sheet report. This change ensures the financial reporting is more accurate and reliable for French-speaking businesses using Odoo Enterprise. It's a routine improvement to maintain the integrity of financial data.
Original PR description
Simplify the formulas of 'Retained earnings' and 'Result for the year' in the french Balance Sheet. task-6087994 Forward-Port-Of: odoo/enterprise#113949 Forward-Port-Of: odoo/enterprise#112731
This update adjusts the categorization of certain French accounting accounts (110000, 119000, 120000, 129000) to 'Current Year Earnings'. This change ensures accurate reporting for French tax regulations, aligning with updated accounting standards and improving financial data accuracy.
Original PR description
Change the type of french accounts 110000, 119000, 120000, 129000 for 'Current Year Earnings'. task-6087994 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#259374 Forward-Port-Of: odoo/odoo#257094
Resolved issues and error corrections
This update resolves an issue where signed PDF documents lost their original bookmarks and links. The fix ensures that signed documents remain fully navigable and preserve the original document structure and integrity, improving user experience and data consistency.
Original PR description
Version - 18.0 Steps to reproduce: 1. Upload a PDF document containing bookmarks and internal/external links. 2. Sign the document and download the signed PDF. 3. Open the downloaded file and check the bookmarks and links. Issue: When a signed document was downloaded, the original PDF bookmarks And the links were not working. This broke structured navigation and affected document integrity. Fix: The PDF signing process has been updated to preserve the original bookmarks and ensure internal and external links remain functional after signing. Impact: - Signed documents remain navigable and consistent with the original PDF. - Preserves document structure and integrity. Task- 4915124 Forward-Port-Of: odoo/enterprise#117881 Forward-Port-Of: odoo/enterprise#108684
This update fixes an issue where guests joining discuss meetings would be redirected to a welcome page without their name pre-filled. Now, when a page is reloaded, the guest's name automatically appears in the input field, making it easier and faster for guests to rejoin the meeting.
Original PR description
Previously, when a guest joined a discuss meeting, and the page was reloaded, the user was redirected to the welcome page without the guest name being pre-filled in the input. This PR restores the previous behavior by pre-filling the guest name in the input, allowing users to rejoin the meeting quickly with a single action. task-6192285 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#262978
This update resolves an issue where discount lines were incorrectly splitting taxes, resulting in duplicate tax calculations when changing the fiscal position (e.g., from GST/QST to Quebec). The fix ensures accurate tax handling on discount lines, preventing incorrect tax reporting and improving order accuracy for Canadian customers.
Original PR description
Steps to produce: --- - Install `website_sale`, `l10n_ca` & `accountant` modules with demo data. - Switch to a `Canadian (CA) company.` - Go to Settings and enable` Discounts, Loyalty & Gift Cards`.…
Steps to produce: --- - Install `website_sale`, `l10n_ca` & `accountant` modules with demo data. - Switch to a `Canadian (CA) company.` - Go to Settings and enable` Discounts, Loyalty & Gift Cards`. - Go to` Website > eCommerce > Loyalty > Discount & Loyalty.` - Create a new program > Set Program Type to Discount Code > Under Conditional Rules, set Minimum Purchase to 0 > Under Rewards, choose Discount on Order. - Go to `website > configuration > websites` > Create a new website for the CA company > Set it as default (first in sequence). - Create new product > Set Sales Taxes to` 14.975% GST + QST` > Publish the product. - Open the website in an incognito window > Add the product to the cart > Apply the discount code. - In the main tab > Go to Website > eCommerce > Orders > Open the corresponding order > In the Other Info tab, change the fiscal position to Quebec (QC) > Click to update taxes. Issue: --- - The tax on the discount line is split into: 14.975% GST + QST & 9.975% QST. Root cause: --- - When a discount is applied in the cart, the discount line initially carries split taxes: 5% GST and 9.975% QST. - After changing the fiscal position to Quebec (QC), the system replaces 5% GST with 14.975% GST + QST because 5% GST is present in replace of 14.975% GST. so at [1] it replaces 5% GST with 14.975% GST and do nothing for 9.975% QST. - In 17.0, the discount line directly uses 14.975% GST + QST (no tax splitting), so this issue does not occur. - In 18.0, at [2], taxes are explicitly split and added to the base line, and the same split taxes are reused during grouping. This leads to multiple taxes being displayed on the sale order line. Fix: --- - Avoid splitting taxes on the discount line in the sale order. - Keep the original tax structure intact to prevent duplication after fiscal position changes. [1]https://github.com/odoo/odoo/blob/c6d9fa5873eb759846e9be5b66eedb8b00c5ac11/addons/account/models/partner.py#L151-L156 [2]https://github.com/odoo/odoo/blob/c6d9fa5873eb759846e9be5b66eedb8b00c5ac11/addons/sale_loyalty/models/sale_order.py#L296 opw-6145674 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265233 Forward-Port-Of: odoo/odoo#262147
This update corrects a bug where the Point of Sale system incorrectly applied AvaTax fiscal positions even when AvaTax wasn't activated in the POS settings. The fix ensures that AvaTax fiscal positions are only used if AvaTax is actively enabled within the POS, aligning with the user's intended tax configuration. This prevents incorrect tax calculations during sales.
Original PR description
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make…
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make sure that the other fiscal positions don't have that option set or that they are ordered after the AvaTax one - Go to the settings of a point of Sale - Activate "Flexible Taxes" and configure "Default" and "Allowed" - Make sure that AvaTax fiscal position is not allowed - Do not activate "AvaTax PoS Integration" - Open a POS session - Select a customer with an address in the US and without fiscal position - Check the fiscal position **Issue:** The selected fiscal position is the AvaTax one even though AvaTax is not activated in the POS. **Cause:** We force the use of a fiscal position if it is configured on a customer. In this case, as no fiscal position is configured on the customer, we try to retrieve one that matches the condition and the AvaTax one is selected. **Solution:** When searching for the fiscal position of a customer, if AvaTax is not configured in the POS and if its fiscal positions are not allowed in POS, we ignore the fiscal positions using AvaTax. opw-6154089 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#263342
This update fixes an issue where the Point of Sale system incorrectly applied AvaTax fiscal positions even when AvaTax wasn't activated in the POS. The change ensures that if AvaTax isn't enabled, the system will ignore AvaTax fiscal positions when determining the correct tax settings for a customer, improving accuracy and preventing unexpected tax calculations.
Original PR description
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make…
**Steps to reproduce:** - Install Accounting and Point of Sale - In Accounting settings, activate "AvaTax" - Configure the AvaTax fiscal position and activate "Detect Automatically" option - Make sure that the other fiscal positions don't have that option set or that they are ordered after the AvaTax one - Go to the settings of a point of Sale - Activate "Flexible Taxes" and configure "Default" and "Allowed" - Make sure that AvaTax fiscal position is not allowed - Do not activate "AvaTax PoS Integration" - Open a POS session - Select a customer with an address in the US and without fiscal position - Check the fiscal position **Issue:** The selected fiscal position is the AvaTax one even though AvaTax is not activated in the POS. **Cause:** We force the use of a fiscal position if it is configured on a customer. In this case, as no fiscal position is configured on the customer, we try to retrieve one that matches the condition and the AvaTax one is selected. **Solution:** When searching for the fiscal position of a customer, if AvaTax is not configured in the POS and if its fiscal positions are not allowed in POS, we ignore the fiscal positions using AvaTax. opw-6154089 Forward-Port-Of: odoo/enterprise#116626
This update ensures that event tickets are automatically generated when a customer makes a payment in POS mode while offline. Previously, a page reload would cause the ticket creation to fail. The fix prevents data loss and guarantees that event registrations are created correctly, regardless of the POS session's online status.
Original PR description
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open…
When selling event tickets in POS while offline, the order could be synced later but without creating event registrations (tickets) after a page reload. Steps to reproduce: ------------------- * Open a POS session with `pos_event` * Sell an event ticket * Switch to offline mode * Validate payment while offline (order becomes paid but unsynced) * Reload/close and reopen POS, then reconnect * Let the order sync > Observation: The `pos.order` is created on the backend, but `event.registration` and `event.registration.answer` are missing so tickets are not generated. Why the fix: ------------ `pos_event` used `order.finalized` as IndexedDB cleanup condition for `event.registration` and `event.registration.answer`. For paid-but-unsynced orders, `finalized` is already true, so those records can be removed from IndexedDB too early. After reload, the order is restored/synced but without its event registration payload. Implementation: --------------- Use `order.canBeRemovedFromIndexedDB` instead of `order.finalized` for `event.registration` and `event.registration.answer` retention rules, so records are kept locally until the order is truly synced (server id assigned) or canceled. Test Note: --------------- Use case is hard to simulate exactly. Add a basic unit test to assert both registration models are kept for paid unsynced orders and only removable once synced. opw-6056079 Forward-Port-Of: odoo/odoo#265201 Forward-Port-Of: odoo/odoo#256615
This update fixes a bug where selecting a table cell would incorrectly select the entire table. Previously, selection only worked when starting outside the table cell. Now, the HTML editor correctly handles selections that begin within a table cell and extend beyond it, improving the user experience when working with tables.
Original PR description
The previous commit fixes a behavior that is expected when the user makes a selection that starts in any element and ends in a table cell (the whole table gets selected), but the reverse case was never handled, namely when the selection starts in a table cell and ends outside of it. backport-https://github.com/odoo/odoo/pull/239270/changes/68e71fad5bbb0445bb1850bf694235f3235b602f task-5420366 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265681 Forward-Port-Of: odoo/odoo#264722
This update fixes an issue where Peppol-imported invoices weren't correctly displayed in the chatter interface. The change ensures that the original XML invoice attachment is now linked to the chatter message, providing better visibility for users. This improves the tracking and management of Peppol invoices within Odoo.
Original PR description
**Steps to reproduce:** 1) Install l10n_be and configure Peppol demo mode. 2) Open debug mode, search for 'Peppol: retrieve new documents' in scheduled action. 3) Open the generated vendor draft…
**Steps to reproduce:** 1) Install l10n_be and configure Peppol demo mode. 2) Open debug mode, search for 'Peppol: retrieve new documents' in scheduled action. 3) Open the generated vendor draft bill. 4) Observe that the imported XML is present in attachments but not in chatter. **Cause:** In the (`_import_ubl_invoice_post_processing()`) https://github.com/odoo/odoo/blob/27cc9b920ad6818563b471dd3391548913790ef3/addons/account_edi_ubl_cii/models/account_edi_ubl.py#L3344 chatter attachments were built from: `self._import_attachments(invoice, collected_values['tree'])` This only includes embedded extra documents and emits the source imported XML attachment. As a result, the XML remained stored on the move (ubl_cii_xml_file) but was not linked to the chatter message. **Solution:** Include the source attachment when building the chatter attachment set. opw-6197738 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264399
This update fixes a discrepancy in how contract type IDs are defined within Odoo's payroll modules, specifically for the Belgium localization. The definitions have been standardized to ensure accurate reporting and calculations for Belgian employee contracts. This ensures consistent payroll processing.
Original PR description
[IMP] hr_contract_salary: fix contract_type_id definition The definitions of the contract_type_id in hr_contract_salary_offer and l10n_be_hr_contract_salary/hr_contract_salary_offer should be same I converted the definition of contract_type_id in the base module to the Belgium one. Also, the contract_type_id was inserted to the view in Belgium one as well, I deleted that part to prevent double appearance. This task is only for v.17, after this version I will open a new PR to handle them. Do not forward the task after v.17 (only for v.17) task - 6101717 Forward-Port-Of: odoo/enterprise#117925 Forward-Port-Of: odoo/enterprise#113244
This update optimizes how Odoo searches for records linked to binary attachments. Previously, searching for 'false-ish' attachments resulted in slow queries due to a large list of attachment IDs. Switching to a 'NOT EXISTS' query significantly speeds up these searches, especially on databases with many attachments, leading to a faster and more responsive system.
Original PR description
Description of the issue/feature this PR addresses: Searching for records without a binary attachment (e.g., `('binary_field', '=', False)`) previously generated a query using `NOT IN (SELECT res_id…
Description of the issue/feature this PR addresses:
Searching for records without a binary attachment (e.g., `('binary_field', '=', False)`) previously generated a query using `NOT IN (SELECT res_id FROM ir_attachment...)`. On databases with a large `ir_attachment` table, materializing this entire list of IDs causes a significant performance bottleneck.
Replacing NOT IN with a NOT EXISTS allows PostgreSQL to short-circuit the evaluation as soon as it find a matching document, drastically reducing query execution time.
Current behavior before PR:
Searching for a "false-ish" binary with attachment generates a query with a `NOT IN`, slow when `ir_attachment` is large.
```python
>>> env["ir.ui.menu"].search([("web_icon_data", "!=", False)])
2026-03-06 15:59:51,326 516177 DEBUG odoo19 odoo.sql_db: [1.076 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND "ir_ui_menu"."id" IN (SELECT res_id FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data')) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(15, 1, 16)
>>> env["ir.ui.menu"].search([("web_icon_data", "=", False)])
2026-03-06 15:59:54,439 516177 DEBUG odoo19 odoo.sql_db: [0.665 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND "ir_ui_menu"."id" NOT IN (SELECT res_id FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data')) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(62, 68, 3, 10, 43, 59, 4, 28, 44, 65, 6, 7, 29, 41, 45, 61, 66, 5, 18, 30, 31, 48, 49, 60, 69, 70, 9, 11, 12, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 32, 33, 34, 36, 37, 38, 39, 40, 42, 46, 47, 52, 54, 56, 57, 58, 63, 71, 73, 74, 76, 78, 79, 80, 81, 50, 64, 51, 72, 75, 77, 35, 14, 13, 53, 2, 55, 67, 8)
```
Desired behavior after PR is merged:
Searching for a "false-ish" binary with attachment generates a query with a `NOT EXISTS`
```python
>>> env["ir.ui.menu"].search([("web_icon_data", "!=", False)])
2026-03-06 15:59:04,847 513555 DEBUG odoo19 odoo.sql_db: [0.945 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND "ir_ui_menu"."id" IN (SELECT res_id FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data')) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(15, 1, 16)
>>> env["ir.ui.menu"].search([("web_icon_data", "=", False)])
2026-03-06 15:59:08,323 513555 DEBUG odoo19 odoo.sql_db: [0.628 ms] query: SELECT "ir_ui_menu"."id" FROM "ir_ui_menu" WHERE ("ir_ui_menu"."active" IS TRUE AND NOT EXISTS (SELECT 1 FROM ir_attachment WHERE res_model = 'ir.ui.menu' AND res_field = 'web_icon_data' AND res_id = "ir_ui_menu"."id")) ORDER BY "ir_ui_menu"."sequence" , "ir_ui_menu"."id"
ir.ui.menu(62, 68, 3, 10, 43, 59, 4, 28, 44, 65, 6, 7, 29, 41, 45, 61, 66, 5, 18, 30, 31, 48, 49, 60, 69, 70, 9, 11, 12, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 32, 33, 34, 36, 37, 38, 39, 40, 42, 46, 47, 52, 54, 56, 57, 58, 63, 71, 73, 74, 76, 78, 79, 80, 81, 50, 64, 51, 72, 75, 77, 35, 14, 13, 53, 2, 55, 67, 8)
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#265702
Forward-Port-Of: odoo/odoo#252525This update resolves an issue where the eCommerce mega menu was incorrectly displaying and causing errors when a website had categories but no published products. The fix ensures the mega menu toggle is only shown when there are actual products to display, improving the user experience and preventing errors.
Original PR description
Steps to reproduce: =================== 1. Create a product, link it to an eCommerce category, keep it unpublished. 2. Create a mega menu, edit it. 3. Enable "eCommerce Categories" and try to change…
Steps to reproduce:
===================
1. Create a product, link it to an eCommerce category, keep it unpublished.
2. Create a mega menu, edit it.
3. Enable "eCommerce Categories" and try to change the number of columns.
=> Mega menu is empty and a JS error is logged in the console.
Cause:
======
The "eCommerce Categories" toggle in the mega menu builder appears whenever any `product.public.category` exists for the website. Once toggled, the eCommerce mega menu templates (`s_mega_menu_multi_menus`, etc.) are server-rendered and the resulting HTML is stored on `website.menu.mega_menu_content`.
Since [1] , those templates filter their with
`('has_published_products', '=', True)`. So when the user has categories but no published product, enabling the toggle produces an empty `<div class="row"></div>`. Clicking the column-count option on that empty row which won't have any children and it will cause an error.
Solution:
=========
Adapt the toggle on the same condition the templates use, so it is only offered when there is at least one category that will actually be rendered.
[1]: https://github.com/odoo/odoo/commit/120a7633505891ba3e02e879f0c1a8287a690456
opw-6218503
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#265615
Forward-Port-Of: odoo/odoo#265190This update resolves a bug that prevented invoices from being successfully sent in demo mode when using the Nemhandel integration. The issue stemmed from a recent change in how data was passed to the Nemhandel system. The fix ensures invoices can now be sent correctly, improving the reliability of the demo environment.
Original PR description
Steps to reproduce:
1. Install l10n_dk_nemhandel.
2. Register user for Nemhandel in Demo mode.
3. Create and post an invoice.
4. Click Send, check 'By Nemhandel (Demo)', and send.
-> Traceback: IndexError: tuple index out of range in _mock_send_document.
Cause:
The Nemhandel mocking system was halfway refactored to align with the Peppol
mocking architecture. As a result, the `_call_nemhandel_proxy` method now
passes the request payload as a keyword argument (`params={...}`) instead of
positional argument (`args[1]`). The mock functions were still attempting to
access `args[1]`, causing the crash.
Solution:
Update the mock functions to extract the payload directly from
`kwargs.get('params', {})`, removing the obsolete positional argument (args)
fallback to align with the new EDI architecture.
task-6065372
Forward-Port-Of: odoo/odoo#260574This update resolves an issue where invoices sent to Jofotara were being rejected due to extremely small negative discount amounts. The fix ensures that discount amounts are always non-negative by applying an absolute value function, preventing errors and ensuring proper invoice processing. This improves compatibility with the Jofotara system.
Original PR description
Before this commit: 1. Create a POS order with no discount and a quantity that does not divide evenly into the unit price (e.g. price=10.0, qty=3) 2. Send the order to Jofotara Jofotara rejects the…
Before this commit:
1. Create a POS order with no discount and a quantity that does not divide evenly into the unit price (e.g. price=10.0, qty=3)
2. Send the order to Jofotara
Jofotara rejects the invoice because the AllowanceCharge/Amount on the invoice line is a small negative value like -0.000000001 with the error `"EINV_MESSAGE":"discount cannot be negative"`
This happens because _add_document_line_gross_subtotal_and_discount_vals computes the discount as: gross_subtotal - total_excluded_currency
where gross_subtotal goes through two independent rounding steps (round unit price, then round unit_price * qty). When the quantity is indivisible, the reconstituted gross_subtotal can land just below total_excluded_currency by a floating-point epsilon, producing a tiny negative discount. The same subtraction also produces a legitimate negative value for refund lines (negative quantity), which was already handled by abs() in _add_pos_order_discount_vals for the document-level total but was left unguarded at the per-line level.
After this commit:
Apply abs() to vals[f'discount_amount{currency_suffix}'] in _add_pos_order_line_allowance_charge_nodes so that discount_amount_currency is always non-negative.
opw-6183423
Forward-Port-Of: odoo/odoo#265159A bug was causing a notification badge to remain visible after a general note was removed from the Point of Sale (POS) system. This update corrects a technical issue where removing a note incorrectly signaled a change, leading to the badge persisting. The fix ensures the badge disappears correctly when a note is removed, improving the user experience.
Original PR description
Steps to reproduce:
-----------
- Open POS Restaurant
- Add a General Note
- Remove the General Note
- The message badge on “Send to Kitchen” remains visible
Issue:
-----------
Removing a General Note set `general_note` to `undefined`, which was
detected as a change and kept the badge visible.
Fix:
--------------
Normalize empty General Notes to an empty string ("") so removing a note
restores the correct initial state.
Task-6101501
Related PR: odoo/enterprise#113514
Forward-Port-Of: odoo/odoo#265652
Forward-Port-Of: odoo/odoo#258632This update resolves an issue where removing a general note from a restaurant orderline caused the preparation display to incorrectly mark the line as cancelled and create a new one. The fix ensures that note history is recorded regardless of whether the note is confirmed, allowing the system to update existing orderlines instead of creating duplicates.
Original PR description
Steps to reproduce: --------- 1. Create an order with an orderline general note. 2. Send the order to the preparation display. 3. Remove the note from orderline. 4. Resend the order Issue: --------------- Removing the note changes the preparation line key, so the preparation display marks the old line as cancelled and creates a new one instead of updating the existing line. Cause: ----------- The note history was only recorded when the note was confirmed. If the user simply removes/clears the note, no note history entry is generated, so the backend cannot match the previous key with the updated key. Fix: ---------- Record note history even when the note is discarded (not only when confirmed. This allows the backend to match the old and new keys and update the line instead of cancelling it. Task-6101501 Related PR - https://github.com/odoo/odoo/pull/258632 Forward-Port-Of: odoo/enterprise#117943 Forward-Port-Of: odoo/enterprise#113514
This update fixes an issue where discounted UBL invoice lines were being incorrectly removed during import. Previously, lines with a zero total amount were filtered out, even if the supplier had applied a discount. Now, the system correctly keeps these lines, ensuring accurate reconciliation between invoices and original documents, particularly for returns or discounts.
Original PR description
`_import_ubl_invoice_add_base_lines` filters out every imported line whose `total_included_currency` is zero, on the assumption that a zero-amount line carries no useful information. This is correct for truly empty rows, but wrong for 100%-discounted lines, an ecotax or excise row, or a returnable-packaging entry nets to zero precisely because the supplier discounted it entirely, and the line still carries data the customer needs to reconcile the bill against the original document opw-6176349 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265284
This update resolves an issue where PDFs with multiple XML attachments (using the /Kids structure) weren't being correctly extracted in Odoo bills. The fix ensures that all embedded XML files are now properly recognized, preventing empty bills and ensuring accurate data retrieval. This improves the reliability of bill generation.
Original PR description
Steps to reproduce: - From the accounting dashboard, upload a PDF containing intermediate /Kids nodes representing separate xml attachments Issue: No xml will be extracted, as result the bill will be empty. However, in the chatter pdf preview, the js pdf toolkit correctly show the xml attachemnts. Analysis: The PDF spec defines two ways to organize embedded files under /EmbeddedFiles in the document's name dictionary: - /Names: a flat array of pairs located directly under /EmbeddedFiles - /Kids: an array of child nodes, each of which carries its own /Names array. The extractor currently only handled the /Names case, not detecting embedded attachments in case of PDF using a /Kids tree. This change add lookup for both structures. opw-5929274 Forward-Port-Of: odoo/odoo#255798 Forward-Port-Of: odoo/odoo#252523
This update corrects a bug that allowed portal users to unintentionally delete documents they shouldn't have. The fix ensures that portal users can only delete documents they own, preventing data loss during the standard cron archiving process. This improves data integrity and user control.
Original PR description
Reproduce: with rpc call as portal user, you can archive documents you have access to. This is not desired as this may lead to records being deleted when the cron collects the trash, but we only wanted to support portal users deleting only records they own. What we did when calling toggle_active should be done for all calls to `write` with `active`. It also removes the need for `_raise_if_unauthorized_archive` and `_unlink_except_unauthorized`. Task-6205627 Forward-Port-Of: odoo/enterprise#117647 Forward-Port-Of: odoo/enterprise#116886
This update resolves an issue where the generic tax report wouldn't display an error message when dealing with negative net values. The fix ensures the report accurately checks for tax discrepancies, even when balances are negative, preventing misleading results.
Original PR description
**Issue:** In the generic tax report, a check is performed on the report lines to ensure that the declared tax amount is consistent with the expected amount. If the difference between the declared tax amount and the expected one is higher than 0.1% of the declared net amount, then a error message is displayed. If the net amount is negative, the error message is never displayed because the computed percentage of the tax difference is negative and therefore lower than 0.1% (i.e. 0.001). opw-6014350 Forward-Port-Of: odoo/enterprise#117990
This update resolves an issue where UBL invoices sent via Peppol were failing due to an incorrect VAT number format for Norwegian suppliers. The fix ensures the VAT number is correctly formatted ('NO179728982MVA') during invoice creation, allowing successful export and delivery.
Original PR description
**Steps to reproduce:** * Install a Norwegian localization (e.g. **l10n_no**). * Set up a company with a valid Norwegian VAT number (e.g. **NO179728982MVA** or just **179728982**). * Create a…
**Steps to reproduce:**
* Install a Norwegian localization (e.g. **l10n_no**).
* Set up a company with a valid Norwegian VAT number (e.g. **NO179728982MVA** or just **179728982**).
* Create a customer invoice and send it via **Peppol** (format: **UBL BIS Billing 3.0.12**).
**Observed behavior:**
* The EDI document creation fails with: "The VAT number of the supplier does not seem to be valid. It should be of the form: NO179728982MVA."
* The error occurs even when the VAT number is correctly formatted.
**Cause:**
* Commit 186ad1db refactored the party node building by removing `_get_party_node()` and replacing it with granular `_ubl_add_party_*_nodes()` methods. The Norwegian VAT normalization block (introduced in task-5448941) that set `supplierCompanyID` on the party node lived inside `_get_party_node()` and was not ported to the new architecture, leaving `supplierCompanyID` never set.
* The NO-R-001 constraint in `_invoice_constraints_peppol_en16931_ubl()` reads the VAT from `party_node.get('supplierCompanyID')`, which now always returns `None`, causing `mva.is_valid(None)` to return `False` and the constraint to always fail.
**Fix:**
* Port the missing normalization logic into `_ubl_add_accounting_supplier_party_tax_scheme_nodes()`: prepend `NO` and append `MVA` to the VAT if not already present, then assign the normalized value to `party_node['supplierCompanyID']` and update `PartyTaxScheme[0]/CompanyID` when a VAT node exists.
* Handle the `NO` case in `_ubl_add_party_legal_entity_nodes()` to write the normalized VAT into `PartyLegalEntity/CompanyID`.
opw-6215400This update increases the maximum time allowed for printing documents to 90 seconds. Previously, documents taking longer than 30 seconds would fail to print. This change ensures users can successfully print larger documents without interruption.
Original PR description
To allow printing large documents that take more than 30 seconds to print, we increase the timeout to 90 seconds. opw-6235827
This update simplifies the process of inserting Dynamic Fields within Odoo's Powerbox interface. The change adds a keyword search for 'dynamic placeholder,' catering to users accustomed to this method. This ensures a smoother experience and continued usability for existing workflows.
Original PR description
This PR adds a search keyword so users who were used to dynamic placeholder to insert the Dynamic Field command can still find it in powerbox. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where an error was incorrectly triggered when longpolling requests were aborted. The fix ensures that the 'unreachable' error is only sent when a request genuinely fails, improving the stability of the IoT service and its fallback to websocket listeners. This prevents unnecessary errors and maintains smooth operation.
Original PR description
In odoo/odoo#260931, new logic was added to raise an 'unreachable' error in the case where a longpolling listen request failed. This error was then used by the IoT HTTP service to fallback to a websocket listener. However, due to an oversight this 'unreachable' error was also being triggered whenever the longpolling listen request was aborted, which happens whenever a new listener is added. This commit fixes the issue by checking the error type and only sending the 'unreachable' error if the request was not aborted. opw-6175686 Forward-Port-Of: odoo/enterprise#117905
This update resolves an issue where the ecommerce file viewer on the website displayed multiple instances simultaneously when the livechat module was active. The fix ensures that only one file viewer appears, improving the user experience and preventing visual clutter. This was caused by a misconfiguration in how the livechat module passed its identification information.
Original PR description
Before this commit, ecommerce file viewer on website may show more than 1 file viewer at once. This happens because when livechat is installed, the overlay container of livechat mistakenly shows the overlay, therefore the overlay is displayed on main page's overlay container and on the livechat container. The regression was made with [1], where the root id is not longer picked from a target DOM but instead relies on the `env`. This change was motivated to fix a flicker, but the tradeoff is that this requires good passing of the `env` with `rootId`. This was properly set on `MainComponent`, but the overlay container of livechat is exceptionally not the `MainComponent` but instead in `LivechatRoot` that is manually mount. This app lacked the `rootId` in the `env`, which this commit solves. opw-6227540 [1]: https://github.com/odoo/odoo/pull/263860 Forward-Port-Of: odoo/odoo#265603
This update fixes a visual issue in the stock picking operations report, where the table lacked borders, making it difficult to read. The change restores table borders, improving the report's clarity and allowing users to easily distinguish between operations. This ensures a better user experience when reviewing stock movements.
Original PR description
Issue before this commit: ========================= The picking operations report displays the operations table without borders, making it difficult to read and distinguish between rows and columns.…
Issue before this commit: ========================= The picking operations report displays the operations table without borders, making it difficult to read and distinguish between rows and columns. Steps to Reproduce: ========================= - Install the stock module - Create a delivery order with products - Print the picking operations report Cause of the issue: ========================= In this commit (https://github.com/odoo/odoo/commit/21cd7e6), the `o_report_stockpicking_operations` class was added to a div, which removed the table borders. After This Commit: ========================= This change restores the table borders in the operations report, improving readability. Before: <img width="796" height="523" alt="2026-04-17_16-30" src="https://github.com/user-attachments/assets/084861e9-3c5b-4ca7-a237-32a56bf2267d" /> After: <img width="795" height="596" alt="2026-04-17_16-30_1" src="https://github.com/user-attachments/assets/e43ed341-8e8b-47c9-9820-66a53823b26c" /> Task: 5462122 Forward-Port-Of: odoo/odoo#253498
This update fixes a potential error that could cause a traceback when deleting images from media items in the website builder. The change hides the image option when no image is present and adds an 'add image' option, resulting in a smoother and more reliable editing experience. This prevents disruptions during website customization.
Original PR description
Before this commit, the deletion of a `s_media_list_item` image triggered a traceback because `SetMediaLayoutAction.isApplied()` attempted to calculate the option's state on a missing element. Steps to reproduce: - Enter edit mode - Drop `s_media_list` snippet - Select the first media item - Delete its image - The image is deleted, but a traceback appears This commit hides media layout options when the item has no image and introduces an add image option instead. task-6229179 Forward-Port-Of: odoo/odoo#265271
This update fixes an issue where long text in m2m tags avatars was being cut off, creating a poor user experience. The change adds a 'truncate' class to ensure text is properly displayed with an ellipsis when it exceeds the available space, resulting in a cleaner and more readable interface.
Original PR description
Currently, the m2m tags avatar field does not have the truncate class for the spans. When the text is too long, it overflows and the rest is cut off. This commit adds the truncate class to the spans of the m2m tags so that the text is truncated with an ellipsis when it exceeds the available space. task-4809319 Before: <img width="322" height="189" alt="c5f23b6aee6f63982f530c2e6a641d21" src="https://github.com/user-attachments/assets/b50fc70d-4d21-4023-8838-460f060a98fb" /> After: <img width="310" height="167" alt="5ccf4bb07603a3d8c50d3763bd112f6d" src="https://github.com/user-attachments/assets/fa7e4167-98d8-47d7-a1e2-6639da8e5d05" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256817
This update fixes an issue where long text in m2m tags' avatar fields would overflow and be cut off. By adding a 'truncate' class, text is now automatically clipped with an ellipsis when it exceeds the available space, ensuring a cleaner and more professional appearance.
Original PR description
Currently, the m2m tags avatar field does not have the truncate class for the spans. When the text is too long, it overflows and the rest is cut off. This commit adds the truncate class to the spans of the m2m tags so that the text is truncated with an ellipsis when it exceeds the available space. task-4809319 https://github.com/odoo/odoo/pull/256817 Forward-Port-Of: odoo/enterprise#112590
This update corrects a bug where re-invoiced expenses on sales orders were incorrectly displaying the total expense amount as the unit price. The fix ensures that the quantity of the expense is properly reflected on the sales order line, resolving a pricing discrepancy. This improves the accuracy of sales order reporting.
Original PR description
Currently, when re-invoicing an expense paid by company, the line added to the sale order will show a price unit equal to the whole expense amount. Steps to reproduce: - Create a new Expense Category with Re-Invoice Costs set to 'At cost' - Create a new Expense, set the new category, and set Paid By to 'Company' - Set Quantity to greater than 1, and Customer to Re-Invoice to any Sales Order - Confirm and Submit Journal Entry on the Expense record Issue: - On the linked Sales Order you will see the total of the expense is used as the unit price This occurs because we don't pass the quantity to the move line creation vals, which then default to 1. In turn, when the sale order line is added, the unit price will be based on the move line vals but the quantity will match the expense. opw-5883290 Forward-Port-Of: odoo/odoo#246816
This update fixes a design issue where a background image set on the website would create a distracting white block when viewing product details. The fix removes the unnecessary white background from the product detail card, ensuring a cleaner and more visually appealing website experience for customers. This improves the overall aesthetic of the e-commerce site.
Original PR description
When a background is set on the website, we can't remove the background of the product information card making the design unaesthetic Steps to reproduce: 1. Install eCommerce 2. Go to Website and click on Edit in the top right corner 3. Open the "Theme" tab, set an image (not plain white) to the website's background and save 4. Go to the shop and open any product 5. The product details are shown on a white block that disrupts the background image Issue: We set a background-color on `#product_details` with value `$body-bg` which is an opaque white Solution: Remove the white background of `#product_details` opw-6214514 Forward-Port-Of: odoo/odoo#265021
This update fixes a minor display issue within the user rights widget, preventing content from overflowing and disrupting the user experience. The change adds scrolling functionality to the popover component, ensuring all information is visible and accessible. This improves usability and consistency.
Original PR description
This PR adds the `overflow-auto` class to the popover component to enable scrolling and prevent content overflow. **Task-ID: 6137031** Forward-Port-Of: odoo/odoo#261216
This update corrects a bug where certain quality control test types were incorrectly visible during work order creation. This change ensures that these test types are only accessible for manufacturing operations, aligning with intended functionality. The issue was caused by an optimization in Odoo's domain filtering system.
Original PR description
### Issue: The `Print Label`, `Register Production`, `Register By-products`and `Register Consumed Materials` are all available in the test types at control point creation. ### Expected behavior:…
### Issue:
The `Print Label`, `Register Production`, `Register By-products`and `Register Consumed Materials` are all available in the test types at control point creation.
### Expected behavior:
These test types are only meant for manufacturing operations and are supposed to be hidden by the field domain:
https://github.com/odoo/enterprise/blob/f56aa85b4ad32c5d9ad5593df1366d72e88da0e4/mrp_workorder/models/quality.py#L102-L104 https://github.com/odoo/enterprise/blob/00d6cccd75c402378698a6fd11ee2692f2361c7f/mrp_workorder/models/quality.py#L20-L24
### Cause of the issue:
Since saas-18.1: 5ef007a2116e528b796ebe80fb291ba5f1a94c8f domains are optimised into equivalents SQL clause with better sql performances. This optimization results in the following match for boolean fields:
`('field', '=', True)` -> `('field', 'in', OrderedSet([True]))`
`('field', '=', False)` -> `('field', ' not in', OrderedSet([True]))`
Because of these:
https://github.com/odoo/odoo/blob/82b16e8feb3d60a9a3855e3adb3164ae5a6c041d/odoo/orm/domains.py#L1058-L1079 https://github.com/odoo/odoo/blob/82b16e8feb3d60a9a3855e3adb3164ae5a6c041d/odoo/orm/domains.py#L1215-L1236
Now the issue is that the specific `search_method` of the `allow_registration` field is then called with this optimized domain: https://github.com/odoo/odoo/blob/82b16e8feb3d60a9a3855e3adb3164ae5a6c041d/odoo/orm/domains.py#L860-L866 https://github.com/odoo/enterprise/blob/00d6cccd75c402378698a6fd11ee2692f2361c7f/mrp_workorder/models/quality.py#L20-L24
And since `value` is defined as a non empty ordered set in both cases it the search method returns a True leaf as search domain.
opw-5915197
Forward-Port-Of: odoo/enterprise#117973
Forward-Port-Of: odoo/enterprise#117068This update corrects a translation issue in the Odoo Enterprise Gantt view. The button used to toggle display modes was not properly translated, preventing users from seeing the view in their preferred language. This commit adds a mechanism to dynamically generate the button title based on the current display mode, ensuring accurate translations.
Original PR description
The title of the button allowing to toggle the display mode in the Gantt view was not translated. This commit adds a getter to compute the title based on the current display mode, and uses it in the template. Issue reported by translator. Forward-Port-Of: odoo/enterprise#117807 Forward-Port-Of: odoo/enterprise#117739
This update resolves a technical issue preventing invoices with Early Payment Discounts (EPD) and 0% tax from passing schematron validation, a requirement for Peppol compliance. The fix ensures correct VAT breakdown generation, addressing a previous error where duplicate tax categories were created and a hardcoded tax code was used. This ensures invoices are correctly formatted for international transactions.
Original PR description
Before this commit, creating an invoice with an Early Payment Discount (EPD) as a payment term could cause the schematron validation of the generated invoice to fail when an invoice line had a 0% tax. The issue was caused by generating two TaxSubtotal nodes for the same TaxCategory (0%, exemption code 'E'): - one for the 0% VAT - one for the EPD discount applied to the total amount However, Peppol requires a single VAT breakdown (TaxSubtotal) per VAT category (in this case: E) Additionally, when VAT was set to 0%, the allowance charge TaxSubtotal incorrectly used 'S' as a hardcoded tax category code. This commit fixes both issues. task-5900496 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264302 Forward-Port-Of: odoo/odoo#254199
This update fixes an issue where WhatsApp channel avatars were incorrectly displaying the default Discuss avatar after a new member was added. Now, avatars are automatically pulled from the channel's WhatsApp member, ensuring users see the correct representation of the conversation participants. This improves the user experience and visual consistency within the WhatsApp channel.
Original PR description
WhatsApp sidebar avatars should be resolved from the channel's whatsapp member, not from an arbitrary non-self member. Before this fix, adding a member to a WhatsApp channel caused the default Discuss avatar to be displayed instead of the actual WhatsApp member's avatar. This happened because the correspondent was not correctly computed for channels of type whatsapp. task-[5879840](https://www.odoo.com/odoo/project/1519/tasks/5879840) Forward-Port-Of: odoo/enterprise#117794 Forward-Port-Of: odoo/enterprise#115745
This update removes a confusing and outdated warning message related to background workers in the Odoo system. The new tab functionality addresses the original concern, making the warning redundant and simplifying the user experience. This change improves clarity and reduces potential user confusion.
Original PR description
Those warning are considered as cumbersome and new tabs will work anyway.
This update resolves an issue where timesheet data wasn't consistently synchronized between Odoo tabs. The fix ensures that changes made in one tab's timesheet are accurately reflected in all other tabs, improving data accuracy and user experience. This was a bug related to how the system saved and retrieved timesheet data across different windows.
Original PR description
This PR reworks the implementation of https://github.com/odoo/enterprise/pull/116007 Task-6180394
This update fixes a technical issue in the Gantt view that prevented users from correctly filtering work orders when using multiple grouping options. The fix ensures consistent data display and prevents errors related to incorrect data interpretation, improving the overall usability of the planning tool.
Original PR description
Before this commit: ------------------------- - When planning work orders in the Gantt view, applying a Group By on Work Center and then adding another grouping (e.g., Manufacturing Order or Status)…
Before this commit: ------------------------- - When planning work orders in the Gantt view, applying a Group By on Work Center and then adding another grouping (e.g., Manufacturing Order or Status) caused a traceback when clicking grouped rows in the panel. Steps to reproduce: ------------------------- 1. Install the `mrp_workorder` module. 2. Create and plan a Manufacturing Order. 3. Open the Planning Gantt view 4. Apply Group By → Work Center. 5. Add another group by (e.g., Manufacturing Order or Status) 6. Click on one of the groups (MO or Status) in the side panel. Cause of the issue: ------------------------- - Rows grouped by Work Center -> Manufacturing Order attempted to access a Work Center record that does not exist, leading to the error: `TypeError: Cannot read properties of undefined (reading 'display_name')` - Rows grouped by Work Center -> Status incorrectly treated the status value as a Work Center ID, leading to the error: `psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type integer` After this commit: ----------------------- - Rows created directly from the Work Center grouping are now correctly linked using their corresponding `workcenterIds` and remain clickable. - Rows created by additional groupings after Work Center (e.g., Manufacturing Order or Status) are no longer clickable. - This ensures a consistent interaction flow in the Gantt view and prevents the previous errors during filtering. Task ID: 6132396
This update fixes an error in how overtime hours are calculated for employees with flexible schedules. Previously, the system incorrectly generated excessive overtime hours. The fix ensures that overtime is accurately calculated based on the employee's actual working hours, addressing a discrepancy in the overtime rule logic.
Original PR description
__ ## Short functional explanation of the error When setting attendances on several consecutive days for a flexible employee, with an overtime ruleset containing a single rule. This rule being based…
__ ## Short functional explanation of the error When setting attendances on several consecutive days for a flexible employee, with an overtime ruleset containing a single rule. This rule being based on week and quantity. When regenerating overtimes for this ruleset, the overtime hours generated isn't correct. ## Reproduction Steps 1. Create an employee. In the Payroll tab, set a start date for their contract. Set Work Entry Source as Attendances. Set their Working Hours as a flexible schedule. Set their weekly hours at 40. 2. Create an Overtime Ruleset. Add a single rule, based on Quantity, if the worked hours on a `Week` differs `from the amount defined on the contract`. Check Pay Extra Hours and leave the Work Entry Type to use as Overtime Hours. 3. Go back to the employee. In Settings, set the Overtime Ruleset field as the new Overtime Ruleset you just created. 4. Create 5 attendances, each from 8 am to 6 pm, from Monday to Friday. 5. Go to the Overtime Ruleset you just created and click on Regenerate Overtimes. 6. Go back to Attendances. Search for your employee, and click on the list view. ### Expected behavior The employee's schedule is 40 hours per week. They worked 50 hours. 10 hours should be considered as Worked Extra Hours. ### Unexpected behavior 18 hours are considered as extra hours. ## Origin of the issue To compute the expected duration of the day, we run: https://github.com/odoo/odoo/blob/7fc5edc29f854d619dbcb5fcc3503fb18ca05335/addons/hr_attendance/models/hr_attendance_overtime_rule.py#L303-L304 where `schedule['work']` will contain intervals on 5 consecutive days, from 8 am to 4 pm. However, the last day of the employee's attendances isn't contained in these intervals. As a result, `period_schedule` will contain 4 days (the common days between the employee's Attendance days and `schedule['work']` ) and thus, `expected_duration` will be set at 36 hours instead of 40. In the case where overtimes are computed based on hours from the contract, for flexible employees, the expected hours are the ones indicated on their schedule. __ opw-6131543 Forward-Port-Of: odoo/odoo#263335
This update corrects an issue where the toast message displayed for restaurant order preparations was incorrectly formatted in French. The original system used a translation-dependent regex that failed when translating currency symbols. The fix now uses a language-aware function to correctly format the list of items in the toast message, ensuring accurate order details are communicated to the kitchen.
Original PR description
Steps to reproduce: ------------------- 1. Set the user language to French. 2. Configure a preparation display. 3. In PoS, add 2 products of different categories (e.g. 2 starter and 1 main) 4. Send to kitchen -> Toast shows "2 starter et 1 €, envoyé à la cuisine" instead of "2 starter et 1 main, envoyé à la cuisine". What's happening: ----------------- The summary is built with a regex that uses `$1` to replace the ", <last_item>" with an "and <last_item>", however, this `$1` in languages other than english is being translated, in our case to `1€`, and the regex replacement logic does not work properly anymore. The fix: -------- Use `formatList` to join the items, it uses the user language to apply locale-specific joining rules. opw-6149616 Forward-Port-Of: odoo/odoo#265712
This update resolves two issues related to sending deliveries via eTransport in Romania. Specifically, it corrects errors caused by incorrect warehouse addresses and invalid eTransport tokens. Now, instead of a technical traceback, users will receive a clear validation message when these problems occur, improving delivery reliability.
Original PR description
This commit fixes two corner case bugs:
1. Transport on National Territory with a warehouse in another country
- Setup eTransport data in settings
- Create a delivery to a Romanian customer
- in eTransport tab -> choose operation type: Transport on National
Territory
- Go to configuration -> warehouses -> change the address of the
warehouse to an address not in Romania
- send the eTransport
2. Sending to eTransport with invalid tokens
- Setup eTransport data in settings
- Remove a character from one of the tokens
- send a valid Delivery to eTransport
we get a traceback for both cases but we want a validation message on the
created document instead.
task-6217207
Forward-Port-Of: odoo/odoo#264747This update fixes an issue where barcode settings for Manufacturing Orders weren't consistently applied, allowing users to bypass mandatory scan requirements. The change ensures that barcode configurations, including lot/serial tracking, are correctly utilized when creating Manufacturing Orders through the Barcode app. This improves data accuracy and traceability in the production process.
Original PR description
Before this commit, the "Allow full order validation" were partially ignored in the Barcode app when used for Manufacturing Orders, and the "Mandatory scan" settings didn't work very well. For…
Before this commit, the "Allow full order validation" were partially ignored in the Barcode app when used for Manufacturing Orders, and the "Mandatory scan" settings didn't work very well. For example, setting the scan of lot/serial as mandatory didn't prevent the user to set automatically a SN on consummed component by generating a lot/serial on the produced product or by clicking on "Produce All" button. This commit adds some conditions to avoid to update barcode lines in case they should depending of the config. This commit also fixes a related issue where the MRP operation type's config wasn't used at all when a MO is created directly from the Barcode app. As the config is get from the MO's picking type and no MO exists when a new one is created from the Barcode app, there is no MO's config returned in the data send by the server. To fix that, the config is now updated clientside when the data are fetched after a save. [Task-5420762](https://www.odoo.com/odoo/project/966/tasks/4655907/project.task/5420762) [opw-5223507](https://www.odoo.com/odoo/project/49/tasks/5223507) Forward-Port-Of: odoo/enterprise#117816 Forward-Port-Of: odoo/enterprise#113318
This update fixes a problem where POS orders weren't correctly calculating payments and invoices, leading to errors. The fix ensures that order details are properly updated during validation and payment processing, resolving the 'entry not balanced' error when generating invoices. This improves the reliability of the Point of Sale system.
Original PR description
### Steps to reproduce: - Download 'Point of Sale' and 'Contacts' app - Create a customer with a pricelist that includes a percentage discount - Create a shop with the following properties: - Default…
### Steps to reproduce:
- Download 'Point of Sale' and 'Contacts' app
- Create a customer with a pricelist that includes a percentage discount
- Create a shop with the following properties:
- Default preset = 'Takeout' with a standard 40hr/week schedule
- Payments = 'Card' and 'Customer Account'
- Pricelists = a 'Default' and the discounted pricelist
- Create a POS order (without choosing a customer)
- Add products to the order, and select 'Customer Account' payment method
- Select the created customer
* Pricelist applies → Order total decreases.
* Payment now exceeds total → Negative change shown.
- Disable 'Invoice' checkbox.
- Click 'Validate' → Show popup 'No cash statement found for this session.'
- Again click 'Customer Account' → Add another payment line (negative).
- Process the order payment
- Close Session
- Try to create an invoice for the order
> Error: Entry not balanced
### Cause of Issue:
When 'Validate' is clicked for the first time and `syncAllOrders()` is called, `serializeForORM()`
clears the `_dirty` state tracking after the serialization. https://github.com/odoo/odoo/blob/418b103dab782d81a33d2a7afd8ec3767d7a82df/addons/point_of_sale/static/src/app/services/pos_store.js#L1501-L1534
When the 'No cash statement found' error occurs, the backend rolls back the changes made to the
order lines.
Then, since the `order.lines` weren't marked as dirty (no changes occured to them) and `payment.ids`
were marked as dirty, when 'Validate' is clicked for the second time, the js side doesn't send the
`order.lines` again, so the backend uses the existing, undiscounted lines.
The mismatch happens because while the product lines are undiscounted, the `payment.ids` are
correct (because a new 'Customer Account' line was added, so `payment.ids` were sent again).
Hence, `amount_total` and `amount_paid` were calculated with discounts applied, while individual
`line.price_unit` values remained at list price, resulting in invoice line amounts not matching
the amount paid and causing "entry not balanced" errors during invoice generation.
### Fix:
Preserved the `_ dirty` state commands, ensuring that when the order is reserialized on retry,
the line data are included in the second `sync_from_ui` payload.
opw-6080597
Forward-Port-Of: odoo/odoo#259636