Tuesday, May 13, 2025
16 changes · 17.0
Enhancements to existing features
Invoice emails will now show the Peppol-related footer only in more relevant cases, instead of displaying it regardless of the recipient's Peppol status. The footer wording is also made more neutral, preserving useful information without sounding like the user is personally endorsing Odoo.
Original PR description
When the invoice can't be sent via Peppol, we are adding a footer in the Invoice email. We sent this regardless of the partner Peppol status. This PR narrows the cases when we sent the footer. Another issue is that "we recommend" Odoo, we are speaking in the name of our user. A better phrasing will make things fairer, such as this footer keeps its informative value, without being too pushy. task-4782004
Resolved issues and error corrections
This fix removes an unnecessary blank line that appeared after a live chat rating when no reason was provided. It keeps chat feedback messages cleaner and avoids awkward spacing for users and support teams.
Original PR description
This commit removes a useless break line added to the end of chat ratign. Break line is used to put the reason on a different line than the rating smiley but is useless when no reason is passed. task-4791376 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
Miscellaneous changes
When computing the payment state fetching the payment data from the database is only necessary for posted invoices. Previously it was fetched all the time which causes unnecessary requests to the database and can cause performance issues when a lot of non invoice entries are being processed concurrently. With inventory valuation for instance. opw-4724142 Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: ---
Original PR description
When computing the payment state fetching the payment data from the database is only necessary for posted invoices. Previously it was fetched all the time which causes unnecessary requests to the database and can cause performance issues when a lot of non invoice entries are being processed concurrently. With inventory valuation for instance. opw-4724142 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#208850
Copying an accounting report now also updates its subformulas, not just the main formulas. This prevents copied reports from keeping incorrect links or calculations, helping users rely on duplicated reports without manual corrections.
Original PR description
Fixes an issue where copying an account report correctly update the formulas of the report but not the subformulas. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Customers who claim a free shipping reward during checkout will no longer continue to see that same reward as available on the order. This avoids confusion and prevents shoppers from trying to claim a one-time reward more than once.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Set up a Next Order Coupon program; 2. add Free Shipping as a reward; 3. create a coupon for current user with enough points to claim reward; 4. add a product to your cart; 5. go to check out; 6. claim Free Shipping. Issue ----- Free Shipping is still displayed as claimable Cause ----- The `_get_claimable_and_showable_rewards` method does not factor in whether the rewards have already been claimed on the current order. For discounts & free products, this isn't an issue, as claiming them will use as many points as possible, meaning there's no points left to claim more, but free shipping can only be claimed once per order. Solution -------- Filter out rewards that have already been claimed. opw-4784359
This fix updates an automated sales signature test so it runs reliably in both full Odoo installations and smaller single-app setups. It helps prevent false build failures and supports smoother validation of the Sales app.
Original PR description
Before this commit this test `test_04_portal_sale_signature_without_name_tour` was only working with all modules installed (classic runbot build) but was failing in singleapp mode (with just `sale_management`). With this commit this test works as expected in both of them. A solution was to use `alt_trigger` instead of "," to separate two css selector, as it was not working as expected inside tour triggers runbot error linked: https://runbot.odoo.com/odoo/runbot.build.error/161357/runbot.build.error.content/runbot.build.error.content/162311
This change reverts a recent adjustment that caused the automated build to fail for Danish electronic invoicing checks. It restores the previous partner identifier lookup so Peppol-related validation continues to use the expected Danish company/VAT identifier.
Original PR description
This reverts commit 7ce1ba9f29f9b1edd5f2507492e45ef92d9ba868. Before the commit (1) We would iterate through the possible items and see if the partner has the field. As the partner in the test setup…
This reverts commit 7ce1ba9f29f9b1edd5f2507492e45ef92d9ba868. Before the commit (1) We would iterate through the possible items and see if the partner has the field. As the partner in the test setup does not have `company_registry`, it will iterate on the second value, `vat`, which is set on the partner https://github.com/odoo/odoo/blob/037fabd81efc28c12359700ee8e21e0454e0535e/addons/l10n_dk/models/res_partner.py#L7-L18 which will be the key `0198` For this key, we have mocked the response: https://github.com/odoo/odoo/blob/e62a86939b0b327e2c16a82b0829dac80ef1ff32/addons/account_peppol/tests/test_peppol_messages.py#L153-L155 After the commit (1), we stop at the first iteration since `vat` is defined on the partner's fields. The key is `0184` -> we don't have any mocked response for this key, we we wazt to load the response's body which does not exist -> kaboom I'm not sure that we wanted to change this value in the first place as from Julien, we wanted the company registry https://github.com/odoo/odoo/commit/ad37ebefb9fb7cb3c9593730f174dd6f1d73a31e https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-peppol/DK-R-014/ + the company registry == the vat for the danish localisation https://github.com/odoo/odoo/blob/037fabd81efc28c12359700ee8e21e0454e0535e/addons/l10n_dk/models/res_partner.py#L7-L18 --- commit (1) https://github.com/odoo/odoo/commit/7ce1ba9f29f9 runbot-163142
This fixes an issue where the cursor could fail to move correctly when editing text that includes tabs or mixed content. It improves the reliability of keyboard navigation in the web editor, reducing frustration during content editing.
Original PR description
Problem:
In `getAdjacentCharacter`, accessing `focusNode.textContent[focusOffset - 1]` directly fails when there are child nodes between text nodes.
Example:
Given `<p>ab<span>\u0009</span>\u200B[]</p>`:
- `focusNode.childNodes` → [text("ab"), span, text("\u200B")]
- `focusNode.textContent` → ["a", "b", "/TAB/", "/ZWS/"]
- `focusOffset` → 3 (nodes offset not text offset)
- Accessing `focusNode.textContent[2]` is wrong because `focusOffset` counts nodes, not characters, it should return `/ZWS/` not `/TAB/`.
Solution:
Align with 18.0+ (`html_editor`) behavior by calling `getDeepestPosition(focusNode, focusOffset)` inside `getAdjacentCharacter`.
Steps to reproduce:
1. Type `ab`
2. Press `Tab`
3. Press `Arrow Left` → Caret does not move left as expected.
opw-4720904
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prWhen a customer or vendor name is updated, related bank account holder names will now update automatically. This prevents outdated names from appearing on bank account records and helps keep business data consistent.
Original PR description
In the case where the name of the related partner is changed, the bank account holder name will not reflect the changes, we add here a dependency on partner_id.name
The attachment form no longer shows the File Content label when the attachment is a URL. This removes a confusing field label and makes the attachment screen clearer for users.
Original PR description
**Purpose:** - The label `File Content (base64)` is still visible even if the attachment type is URL. **Specifications:** - Hide label `File Content (base64)` when attachment type is URL. task-4778138 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents a crash when a window action is saved with an invalid context value, such as an empty list. The system now safely falls back to an empty context, helping administrators avoid errors from misconfigured actions.
Original PR description
This error occurs when a user provides a `non-dictionary` value, such as list, in the `context` field of `window action`. Steps to Reproduce: - Install the `base` module. - Navigate to `Settings` > `Technical` > `Actions` > `Window Actions`. - Edit any window action and set the `context` field to an `empty list`. - Save the changes. `TypeError: odoo.orm.models.BaseModel.with_context() argument after ** must be a mapping, not list` This error occurs when the system attempts to invoke the `with_context()` method with a non-dictionary value, which leads to a TypeError. This commit ensures the context is a valid dictionary before usage. If the provided context is not a dictionary, it is replaced with an `empty dictionary` to maintain compatibility and prevent error. Sentry-6558123477 I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Scenario: add a popup on a website page with enough text above the button so the button is not visible on the page without scrolling. Display the popup. Result: the popup is opened scrolled at the bottom (depends on if we are logged in or not), this usually works in incognito. Issue: in 89e2513f577e9455d5bfd933d7e479b295d45a26 we focused on the first tabbable element in the modal, but if that element is not in the view, the browser automatically scrolls to it. So there is this side effect tha
Original PR description
Scenario: add a popup on a website page with enough text above the button so the button is not visible on the page without scrolling. Display the popup. Result: the popup is opened scrolled at the bottom (depends on if we are logged in or not), this usually works in incognito. Issue: in 89e2513f577e9455d5bfd933d7e479b295d45a26 we focused on the first tabbable element in the modal, but if that element is not in the view, the browser automatically scrolls to it. So there is this side effect that happen if the first tabbable element is hidden by the scroll. Fix: after we focus to the element, we reset the scrollTop to 0 to ensure we stay at the top of the popup. opw-4647172 Forward-Port-Of: odoo/odoo#206318
Versions -------- - 16.0+ Steps ----- 1. Have multiple companies; 2. create an eWallet program available to all companies; 3. set its email template to "Gift Card: Gift Card Information"; 4. create & confirm an order containing the "Top-up eWallet" product; 5. switch to a different company; 6. create an new order for the same client. Issue ----- Access Error Cause ----- Commit eaa6f6c5a415f added the `_get_mail_author` method to ensure gift card emails always have an author
Original PR description
Versions -------- - 16.0+ Steps ----- 1. Have multiple companies; 2. create an eWallet program available to all companies; 3. set its email template to "Gift Card: Gift Card Information"; 4. create &…
Versions -------- - 16.0+ Steps ----- 1. Have multiple companies; 2. create an eWallet program available to all companies; 3. set its email template to "Gift Card: Gift Card Information"; 4. create & confirm an order containing the "Top-up eWallet" product; 5. switch to a different company; 6. create an new order for the same client. Issue ----- Access Error Cause ----- Commit eaa6f6c5a415f added the `_get_mail_author` method to ensure gift card emails always have an author. When using the gift card template for eWallets, this can cause an issue for 2 reasons: 1. When creating an eWallet via the top-up product, its `order_id` is the order that created the eWallet. This order may belong to a different company than the one it is getting used for. 2. The `send_reward_coupon_mail` method fetches its coupons by calling `_get_reward_coupons` on the order. This returns any applied eWallets, therefore calling `_send_creation_communication` whenever the eWallet gets used. The reason it returns applied eWallets as a "reward coupon" is because `_update_programs_and_rewards` creates `sale.order.coupon.points` records with 0 points when applying a `loyalty.card`, which then get assumed to be a reward, despite not granting any points: https://github.com/odoo/odoo/blob/9e22dbb7b6fb581d2f11bf0ec48b230047686050/addons/sale_loyalty/models/sale_order.py#L499-L504 Solution -------- 1. In the `_get_mail_author` yield to `super` if the order's company isn't in `self.env.companies`. 2. In the `_get_points_programs` and `_get_reward_coupons` methods, filter out `coupon_point_ids` that don't grant any points. (Alternatively, we could avoid creating `sale.order.coupon.points` records with 0 points, but this might be risky for stable.) opw-4731588 Forward-Port-Of: odoo/odoo#208637
Versions -------- - 16.0+ Steps ----- 1. Enable abandoned cart reminder emails; 2. have an event with a limited number of seats; 3. open a cart for a ticket to the event; 4. abandon the cart; 5. have available seats fill up. Issue ----- You still get an email reminding you to buy the ticket, even though it's no longer available. As a consequence, you can still pay the sales order, but it won't get confirmed. Cause ----- There is no custom logic in place for `website_event_sa
Original PR description
Versions -------- - 16.0+ Steps ----- 1. Enable abandoned cart reminder emails; 2. have an event with a limited number of seats; 3. open a cart for a ticket to the event; 4. abandon the cart; 5. have…
Versions -------- - 16.0+ Steps ----- 1. Enable abandoned cart reminder emails; 2. have an event with a limited number of seats; 3. open a cart for a ticket to the event; 4. abandon the cart; 5. have available seats fill up. Issue ----- You still get an email reminding you to buy the ticket, even though it's no longer available. As a consequence, you can still pay the sales order, but it won't get confirmed. Cause ----- There is no custom logic in place for `website_event_sale` to filter out abandoned carts with tickets that are no longer eligible. Additionally, the `is_sold_out` field of tickets can be `False` while the event's `event_registrations_sold_out` field is `True`. Solution -------- - Add the event's `event_registrations_sold_out` field as a dependency to `event.event.ticket`'s `_comute_is_sold_out` method. - Add an override for `_filter_can_send_abandoned_cart_mail` which filters out carts with tickets that are sold out, or events with no free places remaining. opw-4453539 Forward-Port-Of: odoo/odoo#199877
Previously, the `referral_state` was not reset when reprocessing an applicant, which could lead to inconsistencies in the referral tracking. This commit ensures that the `referral_state` is explicitly set to `'progress'` when the applicant is reset, maintaining proper state management in the referral process. opw-4523156 Forward-Port-Of: odoo/enterprise#79767
Original PR description
Previously, the `referral_state` was not reset when reprocessing an applicant, which could lead to inconsistencies in the referral tracking. This commit ensures that the `referral_state` is explicitly set to `'progress'` when the applicant is reset, maintaining proper state management in the referral process. opw-4523156 Forward-Port-Of: odoo/enterprise#79767
In case of a multi-company enabled database, it was possible to assign a journal to an online account of a different company, which didn't make much sense. Forward-Port-Of: odoo/enterprise#82080
Original PR description
In case of a multi-company enabled database, it was possible to assign a journal to an online account of a different company, which didn't make much sense. Forward-Port-Of: odoo/enterprise#82080