Friday, May 22, 2026
10 changes · saas-18.3
Resolved issues and error corrections
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
This 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 corrects a bug where the tax amount on purchase bills wasn't being calculated correctly. When a user manually sets the tax on a bill, the system was resetting it to a default value. This fix ensures the manually set tax amount remains accurate on the bill.
Original PR description
Issue is really similar to commit 21877c09863222a237fe99334787ac46935dcca4 except here the compensations amls are created in _stock_account_prepare_anglo_saxon_in_lines_vals because of a difference…
Issue is really similar to commit 21877c09863222a237fe99334787ac46935dcca4 except here the compensations amls are created in _stock_account_prepare_anglo_saxon_in_lines_vals because of a difference between bill price and product cost **Steps to reproduce:** - create storable product with category standard auto - on the category, set an account in the field 'price difference account' - set a cost of 10 - set a purchase tax - confirm a PO for 1 @ 15 and validate receipt - create bill, set a date, save - on the Bill set the total tax at 100 (it's bellow 'untaxed amount' on the bottom right of the bill and should be 2.25 before you change it, if the tax is 15%) - confirm the bill **Current behavior:** tax was reset to 2.25 **Expected behavior:** It should stay 100 as it was manually set **Cause of the issue:** The total tax amount is computed based on the tax lines in Journal Items https://github.com/odoo/odoo/blob/2744396733bb3ad60813e9e093d67192c0d38b36/addons/account/models/account_move.py#L1171 So the problem is actually that a recomputation of the balance of the tax account.move.line (the one with the account "tax paid" in journal items) is triggered when we confirm the Bill. That's because: When we confirm the bill, _stock_account_prepare_anglo_saxon_in_lines_vals() creates two amls : - one debiting 5 on the account set in the field 'price difference account' - one crediting 5 in the stock interim received account (This makes sense and is there to realign with the fact that, on the account move linked to the svl, the amount credited from stock interim received is rightfully 10 because that's cost of the product and it's a standard price product) When we create those amls from, the create method from account.move.lines calls super() inside a context manager calling _sync_dynamic_lines(). https://github.com/odoo/odoo/blob/5583cbcebae00d8122dce5ce929b650929966a90/addons/account/models/account_move_line.py#L1628-L1635 the yield of sync_dynamic_lines() is inside a context manager calling _sync_tax_lines. https://github.com/odoo/odoo/blob/5583cbcebae00d8122dce5ce929b650929966a90/addons/account/models/account_move.py#L3250 Therefore, the first half of sync_tax_lines() (untill the yield) is ran before the call to super and the rest (from the yield) is ran after the call to super. Because we added two lines in the account.move, get_changed_lines will return those 2 new line and because there is a tax_ids on the new lines round_from_tax will be False. https://github.com/odoo/odoo/blob/5583cbcebae00d8122dce5ce929b650929966a90/addons/account/models/account_move.py#L3034-L3041 Therefore we won't reach continue. https://github.com/odoo/odoo/blob/73d73c5c6606e0b34c754bfc4de035840951dd3b/addons/account/models/account_move.py#L3055-L3059 And the tax line will be recomputed using _prepare_tax_line() https://github.com/odoo/odoo/blob/73d73c5c6606e0b34c754bfc4de035840951dd3b/addons/account/models/account_move.py#L3065 Here is why there is a tax_ids on the new lines : The field is precompute so if we don't set a value for it, _compute_tax_ids will be ran to compute it. As the account move on which the lines are added is a bill, the tax_ids will the supplier_tax_id of the product. https://github.com/odoo/odoo/blob/73d73c5c6606e0b34c754bfc4de035840951dd3b/addons/account/models/account_move_line.py#L898-L901 **fix** There is no need for a tax_ids on these lines as they are not meant to (and should'nt) impact the taxes. opw-6014710 Forward-Port-Of: odoo/odoo#263306
This update fixes an issue where backorders created during POS sales weren't properly linked to the original order. Now, all backorder pickings are correctly associated with the POS order, improving inventory tracking and reporting in the Point of Sale module. This ensures accurate order history and simplifies inventory management.
Original PR description
The delivery transfer for a product tracked by serial number is not linked to the POS order when there is no available stock. When validating a POS delivery in real time, stock can split the transfer…
The delivery transfer for a product tracked by serial number is not linked to the POS order when there is no available stock. When validating a POS delivery in real time, stock can split the transfer into a completed picking and a backorder (e.g. one line fully delivered with lots, another serial-tracked line with no stock and no serial number). Steps to reproduce: ------------------- * Setup two products: one tracked by qunatity with some quantity on-hand an other tracked by SN but no quantity on-hand * Open Pos * Sell in one order, both products without providing SN * Validate payment * Open Inventory: two deliveries sould exist under Inventory Overview of PoS Orders > Observation: The first picking shows the POS order as Source Document but the backorder has no source document and is not linked to the POS order. Why the fix: ------------ Pos Origin (Source Document, POS order, session) was only written on the pickings returned by `_create_picking_from_pos_order_lines`, which did not include pickings created during `_action_done()`. Extend the write to the initial pickings and their backorders so every transfer stays tied to the originating `pos.order`. opw-6090606 Forward-Port-Of: odoo/odoo#264803 Forward-Port-Of: odoo/odoo#259370
This update resolves a bug that prevented users from uploading attachments when accessing certain Odoo web pages. The issue stemmed from how session timeouts were handled, leading to incorrect status codes. Applying this fix ensures consistent attachment upload functionality.
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-pr
Forward-Port-Of: odoo/odoo#265952