Daily updates from Odoo
Navigate
Branch
Friday, May 22, 2026
263 changes
35 changes
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
Features 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
17 changes
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
11 changes
Resolved issues and error corrections
This update optimizes PDF report generation by compressing files after merging, reducing file sizes and memory usage. This addresses a previous memory leak and leverages newer PDF library versions for better performance, particularly with large reports. The result is faster report generation and smaller file sizes.
Original PR description
When merging pages with pypdf, the resulting content is uncompressed. A compression pass should be done right after to reduce the resulting file size. Additionally, this helps alleviate a memory leak in PyPDF2 where resources in the merged page are not properly released. Newer versions of pypdf (>=3.15.4) do not have this leak but still see benefits in the output file size. In practice the CPU overhead is negligible, and we actually see a speed increase in cases with high memory usage. Benchmark Printing 400 page annual report | |Print Time|Peak Memory|Output File| |------|----------|-----------|-----------| |Before|142s |3.6GB |103MB | |After |127s |0.4GB |5MB | opw-6148786 Forward-Port-Of: odoo/odoo#264451 Forward-Port-Of: odoo/odoo#261879
This update optimizes PDF generation within Odoo by compressing merged documents, reducing file sizes and improving performance. It addresses a previous memory leak issue and leverages newer PDF library versions for better results. The change results in significantly smaller PDF files and faster processing times, particularly with large documents.
Original PR description
When merging pages with pypdf, the resulting content is uncompressed. A compression pass should be done right after to reduce the resulting file size. Additionally, this helps alleviate a memory leak in PyPDF2 where resources in the merged page are not properly released. Newer versions of pypdf (>=3.15.4) do not have this leak but still see benefits in the output file size. In practice the CPU overhead is negligible, and we actually see a speed increase in cases with high memory usage. Benchmark Printing 400 page annual report | |Print Time|Peak Memory|Output File| |------|----------|-----------|-----------| |Before|142s |3.6GB |103MB | |After |127s |0.4GB |5MB | opw-6148786 Forward-Port-Of: odoo/enterprise#117308 Forward-Port-Of: odoo/enterprise#115550
This update resolves an issue where users without specific accounting permissions would encounter an error when loading certain knowledge article templates. The fix delays access to sensitive audit reporting data, ensuring that only authorized users can perform this action. This improves the stability and usability of the knowledge article feature.
Original PR description
Steps to reproduce: 1. Install `accountant_knowledge` with `demo data` 2. Remove demo user from bookkeeper access right and give some lesser right 3. Open knowledge and create a new artical with demo user 4. Click on Load template for example `Meeting Minutes` Issue: It gives a access error: `This operation is allowed for the following groups: - Accounting/Bookkeeper` Cause: - accountant_knowledge was doing accounting-only work during generic template loading. Immediately calling `target_article._get_inherited_audit_report()` that returns `inherited_audit_report_id`, which is a computed relation to audit report. `audit.report` is only readable by `account.group_account_user` Solution: - delay that access until it is actually needed, - only if the template contains data-embedded="accountReport" opw-6067390 Forward-Port-Of: odoo/enterprise#112946
This update corrects a bug where tax calculations were incorrectly split on discount lines, particularly when orders were set to the Quebec fiscal position. The fix ensures that taxes are applied correctly, avoiding duplicate tax displays and maintaining accurate financial reporting. This improves order accuracy and reduces potential accounting errors.
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 the Point of Sale system incorrectly applied 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 configured fiscal position, ensuring accurate tax calculations. This prevents unintended tax application and improves POS functionality.
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 system now correctly ignores AvaTax fiscal positions when a customer doesn't have a defined fiscal position, ensuring accurate tax calculations for Point of Sale transactions. This improves the reliability of the POS tax functionality.
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 created when an offline POS sale is later synced to the system. Previously, a page reload would cause the ticket creation to fail. The fix corrects a logic error in how the system manages offline order data, 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 resolves an issue where signed PDFs lost their original bookmarks and links, disrupting navigation and document integrity. The fix ensures that signed documents retain their original structure and functionality, allowing users to easily navigate and access information within the signed PDF.
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 Peppol-imported invoices weren't automatically shown in the chatter window alongside their attachments. The change ensures that the XML invoice files generated from Peppol are correctly linked to the chatter message, providing better visibility for users. This improves the tracking and management of these invoices.
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 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, leading to lost data. Now, the system correctly retains lines with zero totals or discounts, ensuring accurate reconciliation with original invoices.
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 fixes an issue where calls were not accurately reflecting the number of open tickets associated with their parent partners. Previously, open tickets on child partners weren't counted. Now, all open tickets linked to a call's parent partner are correctly displayed, providing a more complete view of support requests.
Original PR description
Unlike most of *_count fields on res.partner, for example ticket_count, open_ticket_count didn't take into account of its child partners. To reproduce: 1. create parent parent P and child partner C 2. create a ticket for partner C and put it in a unfold stage 3. call partner P and open form view of this call the open ticket count on the smart button is 0 instead of 1 In this commit, we change it that when a child partner has open tickets, they will also be counted as parent partner's. Forward-Port-Of: odoo/enterprise#115303
4 changes
Resolved issues and error corrections
A recent update caused errors when downloading signed documents through the Sign app. This fix corrects a problem related to how Odoo handles PDF compression, specifically with newer versions of the pypdf library. The change ensures documents download correctly without errors.
Original PR description
This [related PR] introduced a compression pass after calls to mergePage(). However in newer versions of pypdf (>=3.5.2), compress_content_streams() can only be called on pages of PdfWriter. An error would be raised when called on pages of a PdfReader. Steps to reproduce ----- 1. Run Odoo with pypdf>=3.5.2 2. Sign and download a document in the Sign app 3. Traceback occurs Fix ---- This commit moves the compression to the writer object, after the merged page has been added. Related pr: https://github.com/odoo/odoo/pull/261879 runbot-937761 Forward-Port-Of: odoo/enterprise#117999 Forward-Port-Of: odoo/enterprise#117756
This update resolves an issue where removing a general note from an orderline on the preparation display would 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 accurately 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 the POS incorrectly applied AvaTax tax rates even when AvaTax wasn't activated in the POS settings. The system now correctly ignores AvaTax fiscal positions when a customer doesn't have a defined fiscal position, ensuring accurate tax calculations for Point of Sale transactions. This improves the reliability of the POS tax functionality.
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 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
13 changes
Resolved issues and error corrections
A recent update to Odoo's document processing caused errors when downloading signed documents. This fix corrects a problem related to how PDF compression was handled with newer versions of the pypdf library. By moving the compression step, the download process is now reliable.
Original PR description
This [related PR] introduced a compression pass after calls to mergePage(). However in newer versions of pypdf (>=3.5.2), compress_content_streams() can only be called on pages of PdfWriter. An error would be raised when called on pages of a PdfReader. Steps to reproduce ----- 1. Run Odoo with pypdf>=3.5.2 2. Sign and download a document in the Sign app 3. Traceback occurs Fix ---- This commit moves the compression to the writer object, after the merged page has been added. Related pr: https://github.com/odoo/odoo/pull/261879 runbot-937761 Forward-Port-Of: odoo/odoo#265699 Forward-Port-Of: odoo/odoo#265304
A recent update caused errors when downloading signed documents through the Sign app. This fix addresses a compatibility issue with a newer version of the pypdf library, ensuring documents are downloaded correctly. The change ensures compression happens only on the correct object, resolving the error.
Original PR description
This [related PR] introduced a compression pass after calls to mergePage(). However in newer versions of pypdf (>=3.5.2), compress_content_streams() can only be called on pages of PdfWriter. An error would be raised when called on pages of a PdfReader. Steps to reproduce ----- 1. Run Odoo with pypdf>=3.5.2 2. Sign and download a document in the Sign app 3. Traceback occurs Fix ---- This commit moves the compression to the writer object, after the merged page has been added. Related pr: https://github.com/odoo/odoo/pull/261879 runbot-937761 Forward-Port-Of: odoo/enterprise#117971 Forward-Port-Of: odoo/enterprise#117756
This update enhances the accessibility of carousels on our website, making them easier to navigate using a keyboard. Specifically, it adds visual focus indicators and allows users to control the carousel with 'home' and 'end' keys, improving usability for all users, especially those with disabilities.
Original PR description
[FIX] website: improve carousel accessibility To improve keyboard accessibility on carousels, the indicators container is not focusable anymore, and the indicators themselves now only have one…
[FIX] website: improve carousel accessibility
To improve keyboard accessibility on carousels, the indicators container
is not focusable anymore, and the indicators themselves now only have
one focusable button at a time.
The tab order is thus: previous button > active indicator > next button.
(The previous and next button may both appear before.)
You can still navigate among indicators with the left and right arrows,
which also moves the focus to the newly targetted indicator.
Note that other accessibility improvements remain to be done on the
carousels (add a pause/play button on auto-sliding carousels, place the
buttons before the carousel slide in the tab order, add some aria
attributes (roledescription, live), adaptative labels...).
[FIX] website: make focus visible on carousel arrows
When focusing manually (with tab / shift+tab) the previous/next arrows
in carousels, it is hard to follow where the focus is, because there is
no outline and the contrast is too small.
This commit adds a specific outline if the button is `:focus-visible`
(with both black and white to work on any background).
[IMP] website: pause carousel on focus within
Carousels are paused on hover (or touchstart), but if the focus is
inside one, it won't pause. That can make it hard to navigate within
interactive carousels during the sliding interval (e.g. the dynamic
products, which by default has 4 different products with 3 different
focusable links/buttons).
This commit applies the same behavior on focusin as Bootstrap's default
on mouseover, and on focusout as on mouseout.
[IMP] website: support home/end keys on carousels
When the focus is in a carousel, pressing the "home" key displays the
first slide and pressing the "end" key displays the last slide.
task-5470023
Forward-Port-Of: odoo/odoo#244939This update corrects a bug where previously validated manual bank statement entries continued to be incorrectly suggested for matching with new transactions. This issue was causing reconciliation errors and has now been resolved to ensure accurate bank statement matching within the accounting system. The fix improves the reliability of automated reconciliation processes.
Original PR description
Currently, after validating a transaction with a manual operation, the aml resulting from the manual operation can still be selected and matched with other transactions. Steps to reproduce: - Create…
Currently, after validating a transaction with a manual operation, the aml resulting from the manual operation can still be selected and matched with other transactions. Steps to reproduce: - Create a transaction for 500 dollars - Create a manual counterpart line for the bank statement line with label "test123" and validate - Create another transaction of -1000 dollars and label "test123" Issue: The manual counterpart line matched before is being suggested against the new transaction. The perfect match reconciliation model will reconcile the manual counterpart line with the new bank statement line. Analysis: During the retrieval of possible aml to match we only look at the aml reconciliation state. Manual counterpart lines created during the validation of a previous statement line are still selectable candidates, causing false positive matches in automated reconciliation models. Test in Enterprise: https://github.com/odoo/enterprise/pull/115847 opw-6045050 Forward-Port-Of: odoo/odoo#264522 Forward-Port-Of: odoo/odoo#262295
This update corrects a bug where previously validated manual bank statement entries continued to be incorrectly suggested for matching with new transactions. The fix ensures that only the most recent bank statement entry is considered for reconciliation, improving the accuracy of financial records. This resolves a potential issue with mismatched accounts.
Original PR description
Currently, after validating a transaction with a manual operation, the aml resulting from the manual operation can still be selected and matched with other transactions. Steps to reproduce: - Create a transaction for 500 dollars - Create a manual counterpart line for the bank statement line with label "test123" and validate - Create another transaction of -1000 dollars and label "test123" Issue: The manual counterpart line matched before is being suggested against the new transaction. The perfect match reconciliation model will reconcile the manual counterpart line with the new bank statement line. Adding test for community branch opw-6045050 Forward-Port-Of: odoo/enterprise#117351 Forward-Port-Of: odoo/enterprise#115847
A test was failing due to a mismatch between the timezone used in the test and the date calculations within the HR holiday allocation system. This update ensures that all date calculations are performed using UTC, resolving the issue and preventing incorrect leave allocation counts. This fix improves the reliability of the holiday calculations.
Original PR description
Issue: ----------------------------------- At certain times of the day (e.g., around midnight UTC), the test would fail deterministically ``` test_allocation_stats_with_duplicate_leave_type_names…
Issue:
-----------------------------------
At certain times of the day (e.g., around midnight UTC), the test would fail deterministically
```
test_allocation_stats_with_duplicate_leave_type_names
self.assertEqual(leave_type_no_comp.with_context(employee_id=employee_id).max_leaves, 10)
AssertionError: 0.0 != 10
```
Cause:
-----------------------------------
This occurred due to a timezone mismatch during the test execution. When creating the `hr.leave.allocation`, `date_from` implicitly defaults to `fields.Date.context_today(self)` (which evaluates the date based on the test user's timezone, e.g., Europe/Brussels). However, the `max_leaves` computation in `hr.leave.type` evaluates valid allocations using `fields.Date.today()` as the target date (which strictly evaluates to the UTC date)
At certain times of day, this caused the allocation's `date_from` to evaluate to 'tomorrow' relative to the UTC `target_date`. Because the allocation was technically in the future relative to UTC, it was skipped during the computation causing `max_leaves` to return 0.0 instead of 10.
Solution:
-----------------------------------
Explicitly define `'date_from': date.today()` when creating the allocation in the test case. This perfectly aligns the allocation's starting date with the strict UTC evaluation used by the `max_leaves` computation under the hood.
Runbot Error: [937759](https://runbot.odoo.com/odoo/runbot.build.error/937759)
Related PR: https://github.com/odoo/odoo/pull/261680
Forward-Port-Of: odoo/odoo#265717
Forward-Port-Of: odoo/odoo#265703This update resolves an issue where discount lines were incorrectly displaying duplicate tax calculations (GST + QST) when changing the fiscal position to Quebec. The fix ensures that taxes are handled correctly, preventing inaccurate tax reporting on sale orders. This improves the accuracy of financial data 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 fixes an issue where pension fund taxes weren't being correctly applied to Italian vendor bills imported using the AssoSoftware standard. The change ensures that the system now accurately processes XML files, even if they don't include optional reference tags, guaranteeing correct tax calculations for Italian businesses.
Original PR description
### Issue before this commit: When importing an Italian electronic vendor bill using the AssoSoftware standard, pension fund taxes (Cassa Previdenziale) are not applied to the invoice lines. ###…
### Issue before this commit: When importing an Italian electronic vendor bill using the AssoSoftware standard, pension fund taxes (Cassa Previdenziale) are not applied to the invoice lines. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_witholding 2. Change VAT number of IT company with the one in the xml 3. Go to Taxes > 4%F.Pens. > Advanced Options and change Pension Fund Type with TC02 4. Import xml of the ticket in vendor bills 5. P.Fund tax is not assigned ### Cause of the issue: The issue is caused by the following line: https://github.com/odoo/odoo/blob/669b9b84f4d5c8765dc4b451d5da6a95dbb9ded8/addons/l10n_it_edi_withholding/models/account_move.py#L247 Currently, the parser strictly expects the optional <RiferimentoTesto> tag alongside <TipoDato>AswCassPre</TipoDato>. However, several third-party software providers generate valid XML files containing only the AswCassPre block without any optional child tags. ### Reason to introduce the fix: Ensure that the pension fund tax mapped to the line's VAT rate is correctly applied whenever the AswCassPre data type is present, even if the optional reference tags are omitted. opw-6189225 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264083
This update corrects a bug in the UBL invoice import process. Previously, lines with zero amounts (fully-discounted items) were incorrectly removed, preventing accurate reconciliation with original invoices. This fix ensures that discounted lines, like ecotaxes or returns, are retained, allowing for proper financial reporting and customer billing matching.
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 significantly speeds up the process of finding BOMs for product records, resolving a performance bottleneck. By optimizing how BOMs are identified, the system now responds much faster, especially when dealing with large product lists. This change improves overall MRP efficiency and reduces potential delays.
Original PR description
Before this commit, finding a bom for a recordset of `products` involved looping over all the boms and it will loop over all the `product_variant_ids` of `bom.product_tmpl_id` if the bom's…
Before this commit, finding a bom for a recordset of `products` involved looping over all the boms and it will loop over all the `product_variant_ids` of `bom.product_tmpl_id` if the bom's `product_id` is NULL. This approach might loop over variants which we are not trying to find a bom for. In additon to that, due to the fact that multiple boms might have the same `product_tmpl_id`, this approach might consider the same variants in the inner loop redundantly even though we matched the variant with a bom in a previous itration.
Worst case, this might result in a time complexity of $O(N * M)$ where N is the number of boms and M is the number of variants.
To improve the performance, I only considered the variants given in the paramater `products` and in addition to that, I created a new dictionary mapping a `product_tmpl_id` to its bom if the bom doesn't have a variant set. By doing this, I can loop over the `products` given and if it doesn't have a bom set then it will be set to the one its template had taken from the previos loop.
In a method call with the following constraints
- **2** products the method was finding a bom for
- The 2 products had the same template and the template contained **550** active variants
- The boms were only related to the template rather than the variants themselves.
| Input Size | Before | After |
| :--- | :--- | :--- |
| 100 | 0.78s | 0.03s |
| 1000 | 8.53s | 0.11s |
| 10000 | 80.99s | 0.73s |
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#247465This 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 resolves an issue where Jofotara was rejecting invoices due to extremely small negative discount amounts. The change ensures that discount amounts are always non-negative by applying an absolute value function, preventing errors and ensuring proper invoice processing with Jofotara.
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 resolves an error that occurred when users removed the date field in the Accrued Expense Entry wizard. The fix adds a check to ensure the date field has a valid value before performing comparisons, preventing a type error. This ensures the wizard functions correctly when users adjust date information.
Original PR description
Currently, error occurs when user removes date on Accrued Expense Entry wizard. Steps to replicate: - Install `purchase` and `accountant` with demo. - Open any Purchase Order > Click on cog menu >…
Currently, error occurs when user removes date on Accrued Expense Entry wizard.
Steps to replicate:
- Install `purchase` and `accountant` with demo.
- Open any Purchase Order > Click on cog menu > Accrued Expense Entry.
- Remove value from `date` and click else where.
Error:
```
File '/home/odoo/odoo19/community/addons/account/wizard/accrued_orders.py', line 67, in _compute_reversal_date
if not record.reversal_date or record.reversal_date <= record.date:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'datetime.date' and 'bool'
```
Cause:
- As the user removed value from `date`, [here] `record.date` is received as False.
- As a result the comparison `record.reversal_date <= record.date` causes this error to occur.
Solution:
- Added a conditional check for `date` before the date comparison.
[here]: https://github.com/odoo/odoo/blob/8791cdcd89ea3cb56b1fac63b3e2ffbd2956a912/addons/account/wizard/accrued_orders.py#L67
No ID
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#2625682 changes
Resolved issues and error corrections
A technical issue where a test was incorrectly marked as commented instead of updated has been resolved. This fix ensures that the test accurately reflects the functionality of the l10n_be_coda module for the Belgian accounting integration. The change improves the reliability of the testing process.
Original PR description
Test was commented instead of updated in this commit https://github.com/odoo/enterprise/commit/f1fafe0060c221e4a268c897af30455cc3d029ef task-none Forward-Port-Of: odoo/enterprise#117924
This update corrects a bug in the generic tax report that prevented error messages from appearing when dealing with negative net values. The fix ensures that the report accurately checks for discrepancies in tax amounts, even when balances are negative, improving report reliability.
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
5 changes
Enhancements to existing features
This update simplifies the calculations for 'Retained Earnings' and 'Result for the Year' within the French Balance Sheet report. These changes improve the accuracy and reliability of the financial reporting for French-speaking businesses using Odoo Enterprise. This is an internal improvement.
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
Resolved issues and error corrections
This update fixes an error that prevented users from viewing historical payslip data. The issue stemmed from a recent change that removed a key component, causing a system error. The fix ensures that users can now access and review their payslip history without encountering this problem.
Original PR description
Currently, an error occurs when users click on View GROSS/PPH21/JHT/JP History to see historical payslip line values. Steps to Reproduce: - Install the `l10n_id_hr_payroll` module with demo data. -…
Currently, an error occurs when users click on View GROSS/PPH21/JHT/JP History to see historical payslip line values. Steps to Reproduce: - Install the `l10n_id_hr_payroll` module with demo data. - Switch to the `Indonesian` company. - Go to `Employees` and open an `existing record or create a new one`. - Click on `GROSS/PPH21/JHT/JP History` button. `ValueError: External ID not found in the system: hr_payroll.act_contribution_reg_payslip_lines` The issue occurs because, in [this commit], the act_contribution_reg_payslip_lines window action was removed. However, when viewing historical lines, and it still tries to retrieve this action using its XML ID [1] and then updates its domain, context, and views. As a result, it raises an error due to the missing XML ID. This commit ensures that the method returns a standalone window action dictionary instead of relying on the removed window action record. [this commit]: http://github.com/odoo/enterprise/pull/112571/changes/7094cdc033591258cae7c7df46888c29eaae6248 [1]- https://github.com/odoo/enterprise/blob/103500a805d1ffc1185ed639d613c2d1ede492cb/l10n_id_hr_payroll/models/hr_employee.py#L17-L24 sentry-7489148694 Forward-Port-Of: odoo/enterprise#117683
This update resolves an issue preventing users from adding multiple images to product pages within the AI website sale module. The fix corrects a technical error related to how image loading was handled, ensuring the feature now works as intended. This improves the presentation of products with multiple images.
Original PR description
Steps to reproduce: =================== 1. Install ai_website_sale 2. Go to a product page and enter edit mode 3. In the right panel => Images => click "Add More" (Extra Media) 4. Select a PNG or JPG image and click Add => TypeError: loadPromiseResolveFunction is not a function Cause: ====== The `ai_website_sale` patch for `ProductAddExtraImageAction.getMediaDialogProps` destructures the argument with key `loadResolveFunction` (renamed to `loadPromiseResolveFunction` locally), but the caller in `load()` passes `loadPromiseResolveFunction` as the key. The key mismatch means the local variable is always `undefined`, and the `save` closure in the parent's `getMediaDialogProps` closes over `undefined` instead of the Promise's `resolve` function. Fix: ==== align the parameter key. It's a backport of this commit https://github.com/odoo/enterprise/commit/e5b89df328601af881af115c6083a648af0cc1a1 opw-6215476 Forward-Port-Of: odoo/enterprise#117454
This 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#118119 Forward-Port-Of: odoo/enterprise#113514
Code cleanup and technical improvements
This update transitions Odoo's user interface framework, Owl, to its latest version (3). The team has made necessary adjustments to ensure compatibility, though some changes required a phased approach. This upgrade improves performance and introduces new features, but users should review the migration guide for important updates.
Original PR description
This PR updates owl to version 3 and adapts the codebase accordingly. A compatibility layer has been introduced to ease the transition. However, for some breaking changes, such a compatibility layer…
This PR updates owl to version 3 and adapts the codebase accordingly. A compatibility layer has been introduced to ease the transition. However, for some breaking changes, such a compatibility layer wasn't possible. Migration guide: https://odoo.github.io/owl/documentation/v3/owl/migration_owl2_to_owl3.html OWL3 documentation: https://odoo.github.io/owl/documentation/v3/owl/ Community PR: https://github.com/odoo/odoo/pull/247747 Co-authored-by: Aaron Bohy <aab@odoo.com> Co-authored-by: Achraf <abz@odoo.com> Co-authored-by: Alex Kühn <aku@odoo.com> Co-authored-by: Géry Debongnie <ged@odoo.com> Co-authored-by: Bastien Pierre <ipb@odoo.com> Co-authored-by: Jean Schoenlaub <jesc@odoo.com> Co-authored-by: Julien Mougenot <jum@odoo.com> Co-authored-by: Lucas Perais <lpe@odoo.com> Co-authored-by: Michaël Mattiello <mcm@odoo.com> Co-authored-by: Nicolas Bayet <nby@odoo.com> Co-authored-by: Pierre Rousseau <pro@odoo.com> Co-authored-by: Stephane Vanmeerhaeghe <stva@odoo.com>
5 changes
Resolved issues and error corrections
This update resolves an error that occurred when automatically checking out employees with no defined check-out date, particularly when using the hr_work_entry_attendance module. The fix corrects a timezone calculation issue that was creating duplicate overtime entries, preventing the scheduled checkout action from functioning correctly. This ensures accurate overtime calculations for employees.
Original PR description
__ ## Short functional explanation of the error While investigating for bug reported on ticket 6036064, I found this other bug. It only occurs when hr_attendance and hr_work_entry_attendance are both…
__ ## Short functional explanation of the error While investigating for bug reported on ticket 6036064, I found this other bug. It only occurs when hr_attendance and hr_work_entry_attendance are both installed. When setting an attendance for an employee that has a check-in date but no check-out date, and running the scheduled action `Automatically check-out employees`, an `expected singleton` error occurs. ## Reproduction Steps 1. Install hr_work_entry_attendance. 2. Create an Employee. In the Payroll tab, set a start date for the contract. In the Settings tab, make sure their timezone is set to Brussels, and set the Overtime Ruleset field to Default Ruleset. 3. In Settings, check the Automatic Check-out box. 4. Go to Attendances. Create an attendance for the employee you just created. Set a Check-in date to 8 am on April 17th, for example, and leave the check-out field empty. 5. Open Scheduled Actions. Search the action Automatically check-out employees and click Run Manually. ### Expected behavior The attendance check-out should be set at the end of April 17th. ### Unexpected behavior An error occurs: `Expected singleton: hr.attendance.overtime.line(39, 40)` ## Origin of the issue When the attendance goes over several days, we set the check-out date to: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L618 This is a Naive date. However, it will later be considered as a UTC date. Because the employee's timezone is Brussels, this time will be transformed to 2 am next day when we retrieve attendance intervals. This will result in the creation of overtime entries for both days, causing the Expected Singleton error. https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L687 https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L667-L672 In our case, `self.check_in` = April 17th at 06:02:00 and `self.check_out` = April 17th at 23:59:59. Converted, we will obtain April 17th at 08:02:00 and April 18th at 1:59:59. Because of that, at the return: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L706 We will return a dict containing 2 intervals: one for 17th April and one for 18th April. We will then create overtime entries with such attendances: https://github.com/odoo/odoo/blob/b293ce50e0fc9355ffd233557f079916b514eac7/addons/hr_attendance/models/hr_attendance.py#L333 leading to the creation of 2 different overtimes for the same attendance. So, when we retrieve the overtime for that attendance: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/hr_work_entry_attendance/models/hr_version.py#L185, We get the 2. Thus when trying to access their status with: https://github.com/odoo/enterprise/blob/2d2056766441157dc45ebc37b677841c44e5c513/hr_work_entry_attendance/models/hr_version.py#L191 An Expected Singleton Occurs. __ opw-6036064
This update fixes a visual issue where long text in m2m tags' avatar fields would overflow and be cut off. The change adds a 'truncate' class to the spans, ensuring text is neatly cut off with an ellipsis when it exceeds the available space, improving the overall user experience.
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
This update resolves an issue where branch VAT settings were incorrectly inheriting from the parent company, causing confusion and manual VAT adjustments. The change defaults branches to no VAT, ensuring the parent company remains the key provider and simplifies operations. Key settings are now restricted to the base group system.
Original PR description
Branches copied the parent's VAT, which made them their own signing entity and forced users to clear the VAT so the branch would reuse the parent's keys. Default branches to no VAT so the parent remains the key provider. Setting a VAT on a branch still exposes the key settings for the rare case separate keys are needed. Also restrict the key settings to base.group_system task_id - 6087168
This update fixes an issue preventing rental orders from being confirmed during public holidays. The original code incorrectly blocked resources due to overlapping holiday leaves, even when those leaves were specific to a resource's calendar. The fix ensures that holiday leaves are handled accurately, allowing rental orders to proceed smoothly during these times.
Original PR description
### **Steps to Reproduce:** 1) Install sale_renting_planning, hr_holidays with demo data. 2) Create a public holiday for Standard 40 hours/week 3) Create a service product with below configuration: -…
### **Steps to Reproduce:** 1) Install sale_renting_planning, hr_holidays with demo data. 2) Create a public holiday for Standard 40 hours/week 3) Create a service product with below configuration: - check Plan Service as Projector click on internal link and check `Sync Shifts and Rental Orders`. 4) Planning>Configuration>Materials for projector 1 and 2 remove working time. 5) create a rental order for this product during public holiday and click on confirm. ### **Error:** ``` ValidationError: This Sales Order can't be confirmed. No resources are available for the shifts in: Test. ``` ### **Root Cause:** while evaluating resource availability during a rental confirmation from [_planning_slot_vals_list_per_sol](https://github.com/odoo/enterprise/blob/a65723cae215495f0d18cb64b3da36ae6f06affd/sale_renting_planning/models/sale_order_line.py#L30-L117), it retrieved all leaves overlapping the rental period. If any of those leaves were global leaves(`resource_id=False`), then `all_resource_leave` is set to `True` at [1]. This forcefully marked all available resources as unavailable. It failed to check if the global leave actually belonged to the specific `calendar_id` of the available resources. which leads to blocking fully flexible resources or resource with different working calendar. [1]- https://github.com/odoo/enterprise/blob/a65723cae215495f0d18cb64b3da36ae6f06affd/sale_renting_planning/models/sale_order_line.py#L57-L60 ### **Fix:** - Update the `resource.calendar.leaves` search domain to explicitly filter for global leaves that have no `calendar_id` or that share a `calendar_id` with the available resources. - Modify the leave processing loop so that calendar-specific global leaves are only applied to resources operating on that exact calendar, rather than indiscriminately blocking all resources. **opw-6166749**
This update simplifies the process of creating intercompany sale and purchase documents by removing a redundant step. Previously, the system explicitly generated document sequences, which was causing issues with extensibility. Now, the system relies on the standard sequence assignment process, ensuring greater flexibility and ease of customization.
Original PR description
The intercompany sale and purchase document creation explicitly calls next_by_code to generate document names, even though sequence assignment is already handled in create(). This explicit sequence generation is redundant and reduces the extensibility of the sequence flow. Remove the redundant next_by_code calls and rely on the standard create() flow for sequence assignment. e.g. in custom implementations with separate Quotation and Sale Order sequences, the inter-company flow directly calls next_by_code, bypassing the standard sequence handling. Removing this call has no functional impact since `create()` already generates the sequence.
8 changes
Resolved issues and error corrections
This update fixes an issue where Italian electronic vendor bills weren't correctly applying pension fund taxes (Cassa Previdenziale) during import. The change ensures that the system accurately processes invoices generated by various software providers, even if they don't include optional XML tags. This ensures accurate tax calculations for Italian businesses.
Original PR description
### Issue before this commit: When importing an Italian electronic vendor bill using the AssoSoftware standard, pension fund taxes (Cassa Previdenziale) are not applied to the invoice lines. ###…
### Issue before this commit: When importing an Italian electronic vendor bill using the AssoSoftware standard, pension fund taxes (Cassa Previdenziale) are not applied to the invoice lines. ### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_witholding 2. Change VAT number of IT company with the one in the xml 3. Go to Taxes > 4%F.Pens. > Advanced Options and change Pension Fund Type with TC02 4. Import xml of the ticket in vendor bills 5. P.Fund tax is not assigned ### Cause of the issue: The issue is caused by the following line: https://github.com/odoo/odoo/blob/669b9b84f4d5c8765dc4b451d5da6a95dbb9ded8/addons/l10n_it_edi_withholding/models/account_move.py#L247 Currently, the parser strictly expects the optional <RiferimentoTesto> tag alongside <TipoDato>AswCassPre</TipoDato>. However, several third-party software providers generate valid XML files containing only the AswCassPre block without any optional child tags. ### Reason to introduce the fix: Ensure that the pension fund tax mapped to the line's VAT rate is correctly applied whenever the AswCassPre data type is present, even if the optional reference tags are omitted. opw-6189225 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#264083
This change fixes an issue where job applications were incorrectly creating `res.partner` records with the applicant's email address as their name instead of using the provided name. The fix ensures that a new partner is created with both a name and email address, as intended, resulting in more accurate contact information. This improves the reliability of recruitment data within Odoo.
Original PR description
## Issue When creating a job application with a new email address, a `res.partner` is created with both its name and email set to the email address, even if a `partner_name` is provided. ## Steps to…
## Issue
When creating a job application with a new email address, a `res.partner` is created with both its name and email set to the email address, even if a `partner_name` is provided.
## Steps to reproduce
1. Install *Recruitment* (`hr_recruitment`) and *Contacts* (`contacts`)
2. In Recruitment, create a job application:
- Any Subject
- Name N
- Email E
3. Save the job application
4. Go to Contacts
5. **The partner created from the job application has both its name and email set to the Email E used to create the job application.**
## Cause
The `_inverse_partner_email` passes the email address to `find_or_create` to create the new res.partner:
https://github.com/odoo/odoo/blob/fc58ff23f491a2063b10ffcd6393a08b90dc7975/addons/hr_recruitment/models/hr_applicant.py#L317-L324
This method is implemented to parse both a name and an email address in the same string.
https://github.com/odoo/odoo/blob/fc58ff23f491a2063b10ffcd6393a08b90dc7975/odoo/addons/base/models/res_partner.py#L937-L945
We can thus provide both the `partner_name` and the `email_from` to the method to create a user with a name and an email address properly set.
## POS tests modifications
Before this first commit, some partners in `hr_recruitment` demo data were created with their email address as their name. This is the case, for example, for "Johan Duck", whose name was set to `coincoin@gmail.example.com`.
<img width="627" height="86" alt="260296" src="https://github.com/user-attachments/assets/e4bab843-8ba3-4930-af20-ca8603983929" />
In the POS tours, the list of loaded partners is limited to 100 partners and ordered by their order count (which is often null), __and their name__.
https://github.com/odoo/odoo/blob/e7345340efbd66473da70ccf6680181b158047ce/addons/point_of_sale/models/pos_config.py#L845-L865
By "renaming" the partners from `hr_recruitment`, they started appearing higher up in the list because their name now starts with capital letters whereas their email began with lower letters, which are sorted after capital letters by the `ORDER BY` SQL clause. As a result, partners from multiple tours were pushed out of the 100 first partners, meaning they were no longer loaded during the tours, causing the tests to fail.
One solution, which is already used in other tests, is to give the test partners names that make them appear higher in the partner list, ensuring they remain within the first 100 loaded partners.
opw-6111598
Forward-Port-Of: odoo/odoo#260296This update resolves an issue where sending an email from a quotation's action menu didn't properly update the quotation's status to 'sent'. The fix ensures that quotations are correctly marked as sent after email transmission, streamlining the sales process. This prevents delays and ensures accurate order tracking.
Original PR description
Steps to reproduce 1. Create a quotation 2. From the list view, select it and click Actions > Send an email 3. Pick the quotation template and send 4. The order stays in 'draft' Issue The Actions…
Steps to reproduce 1. Create a quotation 2. From the list view, select it and click Actions > Send an email 3. Pick the quotation template and send 4. The order stays in 'draft' Issue The Actions menu calls `action_quotation_send` with `hide_default_template=True`: https://github.com/odoo/odoo/blob/38734e4bc7d841a30524a2bc17fc94c9a83b5aa0/addons/sale/views/sale_order_views.xml#L1128-L1131 which skips the branch that sets `mark_so_as_sent` in context: https://github.com/odoo/odoo/blob/38734e4bc7d841a30524a2bc17fc94c9a83b5aa0/addons/sale/models/sale_order.py#L1068-L1071 Without that flag, neither `message_post` (single order) nor the mass-mail path (multi order) transitions the order to 'sent'. The flag cannot be set unconditionally in `action_quotation_send` because the same method also opens the composer for non-quotation emails (e.g. `website_sale` cart recovery), which must stay in 'draft'. Detect the quotation template at send time in `_action_send_mail` and add `_message_mail_after_hook` for the mass-mail path. opw-5248931
This update resolves an error occurring when sending purchase bills with agricultural tax (ClaveRegimenIvaOpTrascendencia) via TicketBAI. The issue stemmed from an incorrect value being submitted, which the update corrects. This ensures proper invoice processing for Spanish businesses using this tax regime.
Original PR description
…hase bills **STEP TO REPRODUCE** 1. Create a bill with a invoice line with a regimen agricultura tax. 2. send the bill using TicketBAI. 3. You will get the following error: Error:cvc-enumeration-valid: Value '19' is not facet-valid with respect to enumeration '[01, 02, 03, 04, 05, 06, 07, 08, 09, 12, 13]'. It must be a value from the enumeration. opw-6200686 Forward-Port-Of: odoo/odoo#264037
This update resolves an issue where translated text was incorrectly displayed as HTML spans within blog post placeholders. The fix ensures that placeholder text always shows the original, un-translated value, improving the consistency and readability of blog posts across different languages. This ensures a better user experience for our customers.
Original PR description
Since placeholder attribute is translated, for non-form elements placeholder attributes that contain a translation <span/> need to be unwrapped to restore the plain text value. Steps to reproduce the issue: - Have website and website_blog installed - Add a second language - Open a blog post in your second lanuage - Start translating - Remove the blog title => Shown placeholder text is <span ...> task-5190459 Forward-Port-Of: odoo/odoo#263320
This update corrects a bug where the analytic account wasn't consistently linked to stock valuation layers during invoice creation, leading to unbalanced reporting. By linking the analytic account to both invoice cost lines, the system now accurately tracks inventory costs in project reports. This ensures accurate financial reporting and avoids discrepancies.
Original PR description
Steps to reproduce: - Activate Anglo-Saxon accounting - Create a product with track inventory and an automated inventory valuation product category - Define MTO on the product - Add this product to…
Steps to reproduce: - Activate Anglo-Saxon accounting - Create a product with track inventory and an automated inventory valuation product category - Define MTO on the product - Add this product to an Analytic Distribution Model (i.e. Legal) - Create a SO for this product - Create and confirm the PO related to it, the Analytic account is set on the PO. - Confirm the reception of the product - This creates a Stock valuation layer with the Analytic account - Confirm the SO - Confirm the delivery of the product - This creates a Stock valuation layer with the Analytic account too - Create the Invoice Issue: Missing analytic account on the 110300 Stock Interim (Delivered) creating unabalanced analytic accounting Other: test_report_invoice_items_anglo_saxon_automatic_valuation introduced in this PR https://github.com/odoo/odoo/pull/205777 checks that in a project's analytic report, the values based on cogs lines are displayed in the cost section. With this fix, both cogs lines will have an analytic account so their impact on the project analytic report will even out. This made the test fail. To keep the benefit of this test, we simulate that the user manually removes the analytic account on some of the cogs lines (those targetting stock interim received). opw-6060567
This update resolves a bug that prevented users from uploading attachments via the `/web/binary/upload_attachment` route when experiencing a session timeout. The fix ensures the session state is correctly tracked, preventing a 500 error. Applying this change corrects a persistent issue.
Original PR description
1. Apply the below diff. 2. Login using the same account in two independent tabs (e.g. one regular tab, and a private one). 3. In the first tab, change the account password. 4. In the second tab, go…
1. Apply the below diff.
2. Login using the same account in two independent tabs (e.g. one regular tab, and a private one).
3. In the first tab, change the account password.
4. In the second tab, go to `/web/binary/upload_attachment` (any `type='http', auth='user'` controller would do) => 500 error.
> AttributeError: 'HttpDispatcher' object has no attribute 'env'
```
diff --git a/odoo/http.py b/odoo/http.py
index b0fd6197aea8..1ea817ec85cd 100644
--- a/odoo/http.py
+++ b/odoo/http.py
@@ -2309,7 +2309,7 @@ class HttpDispatcher(Dispatcher):
"""
if isinstance(exc, SessionExpiredException):
session = self.request.session
- was_connected = session.uid is not None
+ was_connected = True
session.logout(keep_db=True)
response = self.request.redirect_query('/web/login', {'redirect': self.request.httprequest.full_path})
if was_connected:
```
It is necessary to apply the diff because most places that raise `SessionExpiredException` also pro-actively `logout()`, i.e. they reset `session.uid` and when the exception reaches handle-error `was_connected` is always `False`. For the bug to occur, we need a way to be in the `was_connected == True` case but we found no way in standard Odoo (this also explains how this bug is still present, 2 years later). The diff is the easiest way we found to reproduce it.
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-prThis update resolves an issue preventing session closure with Fiskaly by ensuring cash register move types are handled correctly. The system previously removed internal capital letters (camelCase) when processing data, leading to mismatches with Fiskaly's requirements. This fix ensures accurate communication with the Fiskaly system, improving integration and functionality.
Original PR description
Fiskaly cash register move types must match the keywords listed in the documentation: https://developer.fiskaly.com/dsfinvk/process_types_business_transaction_types#business-transaction-types-business-cases Some values are camelCase (e.g. ZuschussEcht) and are set in the frontend as zuschussEcht. Using capitalize() removes internal capital letters, causing a mismatch with Fiskaly expectations and preventing session closing. Steps to reproduce: - Set up Fiskaly - Open a PoS session - Add an "in" cash move with category Cash Supplement - Create and validate an order - Close the session opw-6165687