Daily updates from Odoo
Friday, May 22, 2026
59 changes · saas-19.3
New functionality added to Odoo
This update includes basic tests for recently added 'all' category and billable type options within the Odoo sale project modules. These tests ensure the system correctly handles these new features, improving the reliability and stability of the sales process. This is a standard improvement to maintain code quality.
Original PR description
This commit's purpose is to add a few basic test case for the all category and billable type that were added recently. task-6147696 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Enhancements to existing features
This update simplifies the payment process by removing a rarely used field – the Payment Identifier – from the payment form. This change improves the user experience by reducing clutter and focusing on the essential information needed to complete payments. The change was driven by a community suggestion to improve clarity.
Original PR description
The Payment Identifier field has been permanently hidden from the payment form view, as it does not provide actionable or useful information to the end user. see community pr - https://github.com/odoo/odoo/pull/266072 task-6237870
This update allows Odoo to send invoices in larger batches, streamlining the process of transmitting invoices to tax authorities. The system now handles multiple invoices simultaneously, reducing the number of individual transmissions and improving overall efficiency. This change enhances the speed and reliability of invoice submission.
Original PR description
This commit allows sending invoices in batches. - Invoices are now chunked into safe batch sizes. - The web service response logic is updated to handle and map results for multiple documents at the same time. task-6139646
Resolved issues and error corrections
This update fixes an issue where the Point of Sale system incorrectly defaulted to using AvaTax fiscal positions even when AvaTax wasn't activated in the POS. The system now correctly ignores AvaTax fiscal positions when a customer doesn't have a defined fiscal position, ensuring accurate tax calculations for US customers. This ensures consistent and reliable tax reporting.
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 POS system incorrectly applied AvaTax fiscal positions even when AvaTax wasn't activated in the POS settings. The change ensures that AvaTax is only used when it's explicitly enabled, preventing incorrect tax calculations for customers without a defined fiscal position. This improves the accuracy of sales tax processing.
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 corrects a bug where changing the standard price of a lot-valued product didn't correctly update the product's cost. The fix ensures that the product's cost accurately reflects the weighted average of its lots when the standard price is modified. This prevents inconsistencies in product valuation.
Original PR description
**Problem:** change of standard price on a product valued by lot and with standard price category does not work **Steps to reproduce:** - create a storable product tracked and valued by lot - set…
**Problem:** change of standard price on a product valued by lot and with standard price category does not work **Steps to reproduce:** - create a storable product tracked and valued by lot - set category as standard price - set a cost of 10 and save - click on the quantity smart button and then "update quantity" - add a quantity of 1 in a new lot - on the product form, change the cost to 12 and save - reload the page **Current behavior:** the cost is back to 10 **Expected behavior:** it should stay 12 **Cause of the issue:** when we change the standard_price of the product, _change_standard_price() is called from the write method https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L293 Inside _change_standard_price(): step 1: a new product.value is created step 2 : we set the standard_price of the lots to be the same as the one of the product https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L319-L323 In the create method for product.value (step 1), we call _set_value() on the moves with a remaining quantity https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product_value.py#L95 At the end of set_value we call _update_standard_price() on our product https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/stock_move.py#L337 Because the product is lot_valuated we update the standard_price based on the avg_cost of the product (this is needed because for instance if the prod is avco we can not simply use _run_average_batch as it is the case for non lot valuated avco product, because then the result won't be a weighted average of each lot, whereas avg_cost does take this into account) https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L633-L634 To compute the avg_cost, inside _compute_value(), we use the total value of each lot https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L226 The lots total value is computed inside the _compute_value() method of stock.lot. In this method, because the product is valued by standard_price we use the standard price of the lot https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/stock_lot.py#L40 But this value hasn't been updated yet (it will be at the time of step 2) so it's still the old value (10 in our case). So the avg_cost of the product will also be the old value and the standard price will be udpated back the old value Then, at the end of _change_standard_price() (at the time of step 2) the standard price of the lots are set based on the standard price of the product (so it stays the old value) **fix:** Inside _update_standard_price(), if the product is valued by standard price we do nothing https://github.com/odoo/odoo/blob/eaa6c4352aec2be8519360c282f3f6504a2f263c/addons/stock_account/models/product.py#L639-L640 We apply the same logic for the lot_valued product, if it's standard_price there is nothing to update opw-5949146 Forward-Port-Of: odoo/odoo#265623 Forward-Port-Of: odoo/odoo#264991
This update fixes a confusing naming convention for quarterly returns. Previously, returns were labeled with just 'Q1,' 'Q2,' etc., regardless of the company's fiscal year. Now, returns are named with the actual month and year range (e.g., 'January 2024 - March 2024'), providing clearer and more accurate reporting.
Original PR description
Currently, if the company fiscal year doesnot align with calender year, i.e Fiscal year end is not december and any month in between like India (March 31), while creating quarterly returns, the return name has Q1 for Jan - Mar, Q2 for Apr - Jun, and so on, which is not aligned with the fiscal year quarters. This commit fixes that issue by naming it like "From Month Year - To Month Year" for quarterly returns. task-6124692 Forward-Port-Of: odoo/enterprise#114438
This update fixes an error in how VAT reimbursement moves are generated when carrying over unclaimed tax amounts. Previously, incorrect calculations led to inaccurate reimbursement amounts. The fix ensures that VAT amounts are properly accounted for, improving the accuracy of financial reporting for French businesses.
Original PR description
When generating a VAT return with an unclaimed tax amount carried to the next month, the carryover reimbursement move amounts are computed with an incorrect ratio. Steps to reproduce: - Create and…
When generating a VAT return with an unclaimed tax amount carried to the next month, the carryover reimbursement move amounts are computed with an incorrect ratio. Steps to reproduce: - Create and post a bill in May containing a VAT amount. - Create and post a bill in June containing a VAT amount. - Create a VAT return for May to carry over the VAT amount to the next month. - Create a VAT return for June, requesting the full VAT amount to be reimbursed. - Validate and send the June VAT return. - Check the generated reimbursement move Issue: Line values does not correspond to anything real/tangible. It occurs because when computing the ratio for the move we check the last tax report entry, where we find the amount of tax from the past months and a line balancing the last month that should not be taken into account. The "Balance tax current account (receivable)" line from the tax closing entry is mistakenly picked up as a tax carried forward line, throwing off the amounts. opw-5961836 Forward-Port-Of: odoo/enterprise#117927 Forward-Port-Of: odoo/enterprise#115451
This update ensures that event tickets are automatically created and generated when selling event tickets through the POS system while offline. Previously, a page reload would cause the system to lose the ticket information. Now, the system correctly creates and retains event registration data until the order is fully synced with the server, guaranteeing accurate ticket generation.
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 an issue where guests rejoining a public discuss meeting would be redirected to a welcome page without their name pre-filled. Now, the guest name automatically populates the input field, streamlining the process for users to quickly rejoin and participate in the meeting. This improves the user experience for both hosts and guests.
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 fixes a bug where the HTML editor wouldn't correctly select tables when a user started a selection within a table cell and then moved the selection outside of it. Previously, the entire table was selected in this scenario. This change ensures the HTML editor accurately reflects user selections within tables, improving usability and data editing.
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 window. The change ensures that the original XML invoice attachment is linked to the chatter message, providing better visibility for users. This improves the tracking and management of Peppol invoices within the Odoo system.
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 minor visual issue on the Odoo website's shop pages. Previously, the 'clear' buttons within the product selection area were shrinking unexpectedly, creating a less polished user experience. This change ensures the buttons maintain their intended size and appearance, improving overall website usability.
Original PR description
task-6145581 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265494 Forward-Port-Of: odoo/odoo#262183
This update optimizes how Odoo searches for records with binary attachments. Previously, searching for 'false-ish' attachments generated a slow query. By switching to a more efficient 'NOT EXISTS' search, we significantly reduce query execution time, especially on databases with many attachments. This results in faster response times for common searches.
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 users were encountering errors when creating group holiday allocations due to an unnecessary approval step. The fix removes a redundant approval process and streamlines the allocation generation workflow, ensuring a smoother experience for users managing time off requests. This improves the reliability of the holiday allocation feature.
Original PR description
**Steps to Reproduce:** 1. Go to Time Off > Management > Allocations 2. Create new group allocation 3. Invalid operation error **Bug Cause:** In this commit 1b6f3a1335302ca029ab62a25c7bcff0953b99be, an additional approval line was introduced which tried to approve allocations which were already approved. **Solution:** Remove this line and move the accrual filter right before the first action approve. Added test. **Task:** 6218151 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where discounted UBL invoice lines were being incorrectly filtered out during import. The fix ensures that lines with zero totals, including those representing supplier discounts or taxes, are retained, allowing for accurate reconciliation between invoices and original documents. This improves the reliability of our UBL invoice processing.
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 error that prevented users from initiating replenishment when specific routing configurations were in place. The fix ensures the system correctly handles scenarios where no routes match the product's company settings, preventing a technical error and ensuring replenishment functionality works as expected.
Original PR description
## Steps to Reproduce: 1. Install the stock module. 2. Activate "Multi-Step Routes" from settings. 3. Activate the "My Company (Chicago)" company. 4. Create a route for the Chicago company. 5. Create a new product and enable the created route on it. 6. Click on the "Replenish" button. ## Error: `IndexError - tuple index out of range` ## Cause: At [1], when none of the product routes belong to the current company or are shared routes, the filtering returns an empty recordset. As a result, trying to access the first route from the empty result raises an index error. ## Fix: This commit only assigns `route_id` when a route matches the given condition. Otherwise, it keeps the value as `False`. [1] - https://github.com/odoo/odoo/blob/13c0e082c260381a332fe1425fe2ba83a1c0c579/addons/stock/wizard/product_replenish.py#L78 sentry-7488075413 Forward-Port-Of: odoo/odoo#265707 Forward-Port-Of: odoo/odoo#265179
This update resolves an issue that caused Odoo to crash when importing large PDF files into the Documents App. The fix disables a memory-intensive process within the PDF indexing library, preventing Out-of-Memory errors and improving the reliability of this key feature. This ensures smoother document uploads for users.
Original PR description
### Description: When trying to import a large PDF file into the Documents App, it can sometimes fail because of an Out-of-Memory error (OOM). This is caused by the library `pdfminer.six` and the function `group_textboxes` that helps order the result of the indexing. This function is memory heavy and is not useful for our use case. To avoid it, we can just disable the "advanced layout analysis" by disabling `boxes_flow`. ### Reference: opw-6164752 Forward-Port-Of: odoo/odoo#264301
This update resolves an issue where the eCommerce mega menu builder would display incorrectly when a website had categories linked to products that were not yet published. The fix ensures the mega menu toggle is only shown when there are actually published products to display, preventing errors and a blank menu.
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 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 calculation, 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#265159This update fixes an issue where Odoo incorrectly processed only the first business document within a multi-bill XML file. The fix ensures that all bills contained within a single XML file are now correctly imported and processed, aligning with Italian tax regulations. This improves the accuracy of financial data import.
Original PR description
### Issue before this commit: When importing an XML file containing multiple business documents (multiple bodies with a single header), the system correctly split the file into separate attachments…
### Issue before this commit: When importing an XML file containing multiple business documents (multiple bodies with a single header), the system correctly split the file into separate attachments but failed to process any document beyond the first one. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it 2. Go to Vendor -> Bills 3. Try to upload a xml with multiple bodies and one header 4. See only the first bill is correctly imported ### Cause of the issue: The splitting logic renamed subsequent attachments with numeric suffixes but then this function incorrectly checked the name of the document. https://github.com/odoo/odoo/blob/29805eec2b70144edf9441cffe7e69e39fd4ba0e/addons/l10n_it_edi/models/account_move.py#L297-L305 We can not rely only on the name of the document but we need to check also its content. Refer to the rules for the name of the attachments: https://www.fatturapa.gov.it/export/documenti/Specifiche-tecniche-relative-al-Sistema-di-Interscambio-versione-1.8.4.pdf In summary what we need in the document (page 9): > The unique progressive of the file is represented by an alphanumeric string up to 5 characters long and with allowed values. [az], [AZ], [0-9]. The unique progressive of the file has the sole purpose of differentiating the name of the files transmitted to the Interchange System by the same entity; it does not necessarily have to follow a strict progressive nature and may also present different numbering styles. ### Reason to introduce the fix: This fix ensures that the function not only checks the name but also the content to be sure that the xml or p7m file contains a valid structure to be registered. Ticket [link](https://www.odoo.com/odoo/project.task/6072258) opw-6072258 Forward-Port-Of: odoo/odoo#265079 Forward-Port-Of: odoo/odoo#259887
A visual bug where a message badge remained visible after removing a note from the Point of Sale (POS) system has been fixed. The fix ensures that the badge disappears correctly when a note is deleted, improving the user experience. This change was triggered by a correction in how empty notes are handled.
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. This improves order accuracy and streamlines the preparation process.
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 resolves an issue where the generic tax report wouldn't display error messages when dealing with negative net values. The fix ensures that the report accurately checks for tax discrepancies, even when balances are negative, preventing misleading error notifications.
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 fixes a bug that caused the Point of Sale module to crash when a user dragged a product to the end of a list and then removed it. The issue stemmed from incorrect handling of list elements. Testing on other platforms suggests this was a platform-specific problem.
Original PR description
When dragging a product from the end of the list, the code was trying to access a null element which caused a traceback. Note: this issue looks to not be reproducible on macOS likely due to difference in drag events. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a visual issue where the drag-and-drop overlay for moving table rows and columns in email templates was misaligned. The fix ensures the overlay appears correctly, regardless of whether the table is displayed within an iframe, improving the user experience when creating and editing email marketing content.
Original PR description
Steps to Reproduce: - Navigate to Email Marketing and open any template. - Insert a table into the template. - Long-press on the column or row options. Description of the issue: - The blue overlay used for moving rows/columns appears misaligned. Cause: - The position of the drag-and-drop overlay is calculated without considering the iframe. When the table is inside an iframe and the overlay is rendered outside of it, the position calculation becomes incorrect. Solution: - Update the position calculation logic to account for the iframe. This ensures that when the table is inside an iframe, the drag-and-drop overlay is displayed at the correct position. task-6059715 Forward-Port-Of: odoo/odoo#264085 Forward-Port-Of: odoo/odoo#256347
This update fixes a discrepancy in how contract types are defined within the Odoo Enterprise system, specifically for the Belgian localization. The definition of the contract type ID was standardized across modules, resolving potential conflicts and ensuring accurate reporting. This change improves data consistency and reliability.
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 fixes an issue where vendor bills were incorrectly using Swiss tax rates when the invoice originated from a Belgian company. The change ensures that the correct tax rate, based on the invoice's fiscal localization, is applied during the import process. This prevents billing errors and maintains accurate tax calculations.
Original PR description
**Steps to reproduce:** - Create a company in Belgium and set the fiscal localisation accordingly. - In the same company, create a fiscal position in Switzerland, set the foreign tax ID and then…
**Steps to reproduce:** - Create a company in Belgium and set the fiscal localisation accordingly. - In the same company, create a fiscal position in Switzerland, set the foreign tax ID and then generate the taxes for it. - Install the module account_edi_ubl_cii. - Create and invoice for a belgian customer, with one product line having a 0% tax. - Export the invoice as XML. - Go to taxes, filter by purchase, and make sure that the 0% switzerland tax has a higher sequence than the belgian 0% tax. - Import the previous invoice XML as a vendor bill. **Issue:** After importing the bill, the switzerland tax is used even though the fiscal localisation is belgian, which is wrong as it violates the constraint _validate_taxes_country **Solution:** Added a more selective domain to _import_fill_invoice_line_taxes opw-5467936 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265200 Forward-Port-Of: odoo/odoo#255848
This update resolves a confusing user experience where discount codes wouldn't work after being discarded. Now, users can successfully re-apply previously discarded codes, ensuring rewards are correctly applied without creating duplicate entries. This improves the overall efficiency and usability of the loyalty program.
Original PR description
Issue: --- ### Steps to reproduce: 1- Create a `Discount Code` program. 2- In SO, use `Coupon Code` wizard and use the code. 3- After available rewards are shown, discard the wizard. 4- Re-apply the code. Validation Error: The promo code is already applied. As the reward is not applied, this is functionally confusing. At this point We can see the reward only inside the rewards wizard view. If we allow re-apply the code in case no reward line is created for the `rule.program_id`, we can still see the reward by re-applying the same code, without any side effects. opw-6164198 Forward-Port-Of: odoo/odoo#264105 Forward-Port-Of: odoo/odoo#261950
This update resolves an issue where users would encounter an error when attempting to sign in to planning slots that lacked a defined end date. The fix ensures the system handles slots without end dates gracefully, preventing the error and allowing users to proceed with scheduling.
Original PR description
Currently, an error occurs when user tries to signin on a planning slot which doesnt have an end date selected.
Steps to replicate:
- Install `planning_field_service` and open Planning.
- Click New > Add a Customer > Change status to `Scheduled`.
- Remove end datetime (right one) > Click `Sign In`.
Error:
```
File '/home/odoo/odoo19/enterprise/planning_field_service/models/planning_slot.py', line 264, in action_sign_in
if now > self.end_datetime.astimezone(ZoneInfo('UTC')):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'bool' object has no attribute 'astimezone'
```
Cause:
- As the user removed value from end datetime, `self.end_datetime` is False so we get this error when trying to access `self.end_datetime.astimezone()`.
Solution:
- Added a conditonal check for `self.end_datetime` before accessing `self.end_datetime.astimezone()`.
sentry-7480608465
Forward-Port-Of: odoo/enterprise#117425This update resolves an issue where validating opening financial moves would trigger an error. Now, users can successfully validate these moves, ensuring accurate initial accounting setup for each company within the Odoo system. The change addresses a context issue where the company ID wasn't consistently defined, causing the error.
Original PR description
Issue:
Posting and validating an opening move raises a UserError.
Steps to reproduce:
- With accounting
- Accounting -> Settings -> Initial setup
- Add some opening credit/debit values
- Click on "Validate and post"
- On the confirm window, click on Post
Current behavior:
- Raise a UserError
Expected behavior:
- Post the entry for the current company only
Cause:
As "company_id" is not always defined in the context, `get('company_id')` return None and trigger the UserError.
Instead, warn the user it will be validated only for the current company.
opw-6164885
Forward-Port-Of: odoo/odoo#263871This update fixes an issue where users could set assets to 'draft' after locking accounting dates. This prevented incorrect accounting entries and maintained data integrity. The change ensures that assets remain in their finalized state once lock dates are applied, upholding accounting standards.
Original PR description
Steps to reproduce: 1- Install Accounting 2- Go to [Accounting -> Assets] and create a new asset with start date 1/1/2025 3- Specify the fixed asset account and confirm the asset 4- Open [Accounting…
Steps to reproduce: 1- Install Accounting 2- Go to [Accounting -> Assets] and create a new asset with start date 1/1/2025 3- Specify the fixed asset account and confirm the asset 4- Open [Accounting -> Lock Dates] 5- Set a Lock date on everything with the date 31/12/2025 and save 6- Cancel the asset, set to draft and confirm again Issue: `Invalid Operation: The remaining value on the last depreciation line must be 0` Expected behavior: Should not be able to set to draft once the asset is cancelled Why this happens: Commit 66db1d5 introduced a new condition on the `Set to Draft` button which results in the button being visible when it should not be. If a Lock Date is set after an asset is confirmed, the acquisition and any depreciation entries are effectively finalized in the accounting history. Allowing a user to "Set to Draft" at that point would involve deleting or modifying entries in a closed period, which violates accounting integrity. opw-6152777 Forward-Port-Of: odoo/enterprise#116900
This update resolves an issue where the ecommerce website displayed multiple file viewers simultaneously when the live chat feature was enabled. The fix ensures that only one file viewer appears, improving the user experience and preventing visual clutter. This was a minor technical adjustment to address a flicker.
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 resolves a bug that prevented invoices from being sent correctly in the Nemhandel demo mode. The issue stemmed from a change in how the system sends data to Nemhandel, requiring a small update to the underlying code. This ensures invoices can now be successfully processed in demo mode.
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 fixes a visual issue in the stock picking operations report, which previously lacked table borders, making it difficult to read. The change restores the standard table borders, significantly improving the report's clarity and usability for users.
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 an error that occurred when selecting shift templates on planning slots, specifically when dealing with long time differences in resource schedules. The change ensures the system gracefully falls back to a previously calculated end date if the initial template calculation fails, preventing the application from crashing. This improves the reliability of shift planning.
Original PR description
Currently, an error occurs when a user selects a shift template on a planning slot. **Steps to Reproduce:** - Install the `Planning` module with demo data. - Create a `Resource Time Off` record with…
Currently, an error occurs when a user selects a shift template on a planning slot. **Steps to Reproduce:** - Install the `Planning` module with demo data. - Create a `Resource Time Off` record with `start` and `end date` separated by more than `1400 days (around 3.9 years)`, and Set the Working Hours field to Standard 40 hours/week. - Go to `Planning` > `Configuration` > `Shift Templates`, open an `existing record` or create a `new one`, and set the `Working Days` to more than 1 day. - Create a new `planning slot`, Assign the resource `Abigail Peterson`, and select the above `shift template`. `AttributeError: 'bool' object has no attribute 'replace'` This error occurs because when the user sets the shift template, the compute method runs to calculate the start and end datetimes [1]. It computes the end datetime by adding the template duration in working days from the given start datetime using the resource working calendar within a searchable range of around 1400 days [2]. During this computation, leaves and non-working days are skipped [3]. If no valid working interval is found within the searchable range, then it returns False [4], which raises the error [5]. This commit ensures that if plan_days returns False, the computation falls back to the previously calculated end date. [1]: https://github.com/odoo/enterprise/blob/6ae5d3df6e9305416e4d6f74259cd01753025f42/planning/models/planning.py#L662-L671 [2]: https://github.com/odoo/odoo/blob/a439bd305112f6efc752ce900f7782e7faaf7312/addons/resource/models/resource_calendar.py#L826-L835 [3]: https://github.com/odoo/odoo/blob/a439bd305112f6efc752ce900f7782e7faaf7312/addons/resource/models/resource_calendar.py#L533-L537 [4]: https://github.com/odoo/odoo/blob/a439bd305112f6efc752ce900f7782e7faaf7312/addons/resource/models/resource_calendar.py#L835 [5]- https://github.com/odoo/enterprise/blob/6ae5d3df6e9305416e4d6f74259cd01753025f42/planning/models/planning.py#L653-L654 sentry-7472958590 Forward-Port-Of: odoo/enterprise#117926 Forward-Port-Of: odoo/enterprise#117073
This update fixes an issue where the 'Company Name' field on the customer website form wasn't syncing properly. The change ensures that if a parent company doesn't exist, it's created and linked to the customer contact, preventing data loss and maintaining consistent information across the website and backend systems.
Original PR description
Steps to reproduce: 1. Add a Website Form snippet 2. Set the action to "Create a Customer" 3. The "Company Name" field is not synced with the builder option (the "Type" dropdown shows "None") Reason: In PR[1], the company field was removed, resulting in an unexpected `None` value and potential data loss. Fix: Restore the expected behavior by ensuring that: - A parent company is created if it does not exist - The contact is linked to this parent This prevents data loss and ensures consistency between the form and backend data. [1] https://github.com/odoo/odoo/pull/211043 task-5979184 Forward-Port-Of: odoo/odoo#260101
The HTML Editor's code toolbar was displaying incorrectly on mobile devices due to a font size conflict. This update resolves this issue, ensuring the code toolbar appears correctly and consistently across all devices, improving the user experience for mobile users. This is a minor fix to enhance usability.
Original PR description
Currently syntax highlighting toolbar UI is broken in mobile devices. This happens because code toolbar button's font-size (12px) is overridden by webclient.css `.btn` class font-size (14px). This PR aims to fix the code toolbar's broken UI for mobile devices. task-6201174 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where tax calculations were incorrectly split on discount lines, particularly when changing the fiscal position to Quebec. The fix ensures accurate tax application by preventing the duplication of tax rates, maintaining the original tax structure for consistency.
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 fixes an issue where a white background on the website would interfere with the appearance of product details. The change removes a conflicting white background from the product information card, ensuring a cleaner and more visually appealing design when using website backgrounds. This improves the overall user experience.
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 potential error that could cause a traceback when users deleted images from media items on the website. The change now gracefully hides the image option and provides an 'add image' option instead, ensuring a smoother user experience. This prevents disruptions and maintains website functionality.
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 a visual issue where content in the user rights widget sometimes overflowed, causing a cluttered display. The change adds scrolling functionality to the popover component, ensuring all information is visible and accessible. This improves the user experience for managing user permissions.
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 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 accurate VAT breakdown generation, correcting a previous error where duplicate tax categories were created and a hardcoded tax code was used. This ensures invoices meet regulatory standards and avoids potential processing delays.
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 a warning error that appeared during payrun creation when multiple payruns were generated or the payroll schedule was adjusted. The issue stemmed from an error in how the system processed domain settings, which was corrected to prevent the warning. This ensures consistent and reliable payrun processing.
Original PR description
[FIX] hr_payroll: fix payrun warning bug Bug reproduction: When we select Employee Type and all employees and create a payrun. Do this twice at least. Then set your schedule in the dashboard of payroll app. Error will appear. Bug cause: There was ast.literal_eval(action['domain']) part where action refers to action_hr_payslip_run but action['domain'] is False and ast.literal_eval(action['domain']) throws and error Bug solution: I said ast.literal_eval(action['domain'] or '[]'), in case action['domain'] is False, we should return [] domain to prevent throwback. task - 6227118
This update fixes a potential issue where spreadsheet formulas referencing list headers could break due to translation changes. The update ensures list headers remain stable, preventing formula errors and improving the overall reliability of spreadsheet calculations. This change simplifies the spreadsheet behavior and enhances user confidence.
Original PR description
Description: With odoo/odoo#261686, list headers became translatable by default and we only stored explicit labels again when a pivot was created from a list range. This kept pivots stable, but formulas using list headers could still break when labels changed with translations. It also made the behavior harder to understand, as some headers were translated while others became fixed later on. In this commit: - store `string` again for newly inserted and user-edited lists so their headers stay stable - keep `string` optional for existing spreadsheets so they preserve their current behavior - remove the pivot-specific list header conversion logic - validate source dashboards in tests so their list columns keep omitting `string` and fall back to translated field labels Task: 6204484 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an issue where spreadsheet formulas could break due to translation changes in list headers. By ensuring list headers remain stable, the update enhances spreadsheet reliability and simplifies the user experience. It removes complex conversion logic, making the system more predictable and easier to maintain.
Original PR description
With odoo/odoo#261686, list headers became translatable by default and we only stored explicit labels again when a pivot was created from a list range. This kept pivots stable, but formulas using list headers could still break when labels changed with translations. It also made the behavior harder to understand, as some headers were translated while others became fixed later on. In this commit: - store `string` again for newly inserted and user-edited lists so their headers stay stable - keep `string` optional for existing spreadsheets so they preserve their current behavior - remove the pivot-specific list header conversion logic - validate source dashboards in tests so their list columns keep omitting `string` and fall back to translated field labels Task: 6204484
This update resolves an issue where clicking on archived users in the member list caused errors. By preventing clicks on archived users, we've improved the user experience and eliminated these technical problems. This change aligns with how archived users are handled in other parts of the system.
Original PR description
Previously, clicking on an archived user from the channel or group member list triggered a traceback. This PR prevents archived users from being clickable, aligning the behavior with the message model where the popover is not opened for archived users, thus avoiding the traceback. enterprise: https://github.com/odoo/enterprise/pull/117480 task-6179486 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265544 Forward-Port-Of: odoo/odoo#262247
This update resolves a test failure in the Odoo WhatsApp app's discuss sidebar. The change ensures the test accurately reflects the new system behavior of only considering active users when determining available commands. This improves the reliability of the test and ensures the app functions correctly for users.
Original PR description
This PR updates the discuss sidebar testcase to match the new behavior where only active users are considered when computing main_user_id, reducing the number of available commands and fixing the failing assertion. community: https://github.com/odoo/odoo/pull/262247 task-6179486 Forward-Port-Of: odoo/enterprise#117902 Forward-Port-Of: odoo/enterprise#117480
Internal users could previously not access certain agent tools due to an access error. This update corrects a previous change that removed necessary permissions, ensuring internal users can now properly utilize menu-related agent functionalities. This resolves a critical issue impacting agent performance.
Original PR description
Purpose: -------- Currently an internal user can't use an agent that requires the list of available menus or get the details of any menu: an access error is raised stating that the user can't access ir.actions.client records. The issue for the get_available_menus was introduced by commit 15df7f50f67 in which the sudo was dropped when calling the tool. The sudo has been moved inside it when fetching the actions of the available menus. Task-6240831
This update fixes an issue where receipt QR codes weren't correctly using invoice data. Now, the QR code generated on the receipt will automatically reflect the information from the invoice, ensuring accurate record-keeping and compliance with Saudi regulations. This resolves a previous error during receipt preview in POS.
Original PR description
Description of the issue/feature this PR addresses: in this PR we are computing the qr code on the receipt to be taken from the invoice qr field when the document is sent Current behavior before PR: pr receipt qr codes are always created with the logic used by phase 1 qr codes regardless if the invoice was sent. there was a traceback that also occurs during receipt preview in POS. Desired behavior after PR is merged: after this pr the qr code will reflect the value computed on the invoice if it was set (i.e. sent). task-6217641 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where the receipt preset section incorrectly displayed 'false' when certain information was missing. Now, the preset section is hidden when no identification is provided (Dine In) and missing values in Delivery are handled correctly. Additionally, customer names are now included on the receipt header for retail and Dine In orders.
Original PR description
Before this commit: ==== - When a preset ( Dine In or Delivery) was selected and no time slot was set, the receipt displayed false in the preset section. After this commit: ==== - Hide the preset section when no identification is defined ( Dine In ). - Properly handle missing values in Delivery to avoid displaying false. - Added customer name on receipt header in retail and Dine In. task-6141964
This update corrects an issue where the 'Send to Kitchen' toast message in the restaurant ordering system was displaying incorrect formatting for items in languages other than English. The fix utilizes a language-aware method to properly combine item descriptions, ensuring accurate messaging for all users regardless of their selected language. This improves the clarity and professionalism of the order preparation process.
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 corrects a translation issue in the Odoo Gantt view. The button used to toggle display modes was not correctly translated, preventing users from seeing the view in their preferred language. This commit ensures the button title is dynamically translated based on the current display mode setting.
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 two issues related to Odoo's eTransport functionality. Previously, errors during transport setup resulted in technical tracebacks. Now, the system will display a clear validation message on the delivery document itself, providing better guidance to users. This improves the user experience and simplifies troubleshooting.
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 ensures that users are prevented from booking rental services when resources are unavailable during the selected time period. Previously, the system didn't check availability for rentals with the ‘website_sale_renting_stock’ module. This change improves the user experience by preventing incorrect bookings and ensuring accurate resource management.
Original PR description
Before this commit, when the user goes to the webshop to take a rental service with rental service unavailable at a certain period, the system does not block the user when the resource is not available during 2 hours in the period chosen by the user. The reason is because the hours are not checked when website_sale_renting_stock is not installed. This commit moves the code checking the time of the rental period made in website_sale_renting_stock in website_sale_renting to be able to have that verification for rental service used with planning to make sure the system will prevent the user to add the product in his cart when the resource is unavailable. task-5123239 Forward-Port-Of: odoo/enterprise#114285
This update resolves an issue where barcode settings for Manufacturing Orders weren't consistently applied, allowing users to bypass mandatory scan requirements. The fix ensures that barcode configurations, including lot/serial tracking, are correctly utilized when creating Manufacturing Orders through the Barcode app. This improves data accuracy and control over production processes.
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 Point of Sale 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 POS 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#259636This update resolves an issue where UBL invoices sent via Peppol were failing due to incorrect VAT number formatting for Norwegian suppliers. The fix ensures the VAT number is correctly pre-formatted with 'NO' and 'MVA' when creating the UBL document, allowing invoices to be successfully transmitted.
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-6215400
Forward-Port-Of: odoo/odoo#264679Features or functions removed from Odoo
This update removes the ‘account.group’ model from the l10n_dk module in the saas-19.3 release. This change was necessary to resolve an error that occurred when accessing records. The removal ensures the Danish localization module functions correctly within the Odoo SaaS platform.
Original PR description
account.group model is removed in saas-19.3, in this commit odoo/odoo@aecbd819664613aaa7e302fc24c8f1c6505eaef5 , so we will get an error while trying to access this record. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr