Monday, April 7, 2025
25 changes · 18.0
Enhancements to existing features
This update improves Odoo’s internal unit testing tools, especially the Hoot test framework used by developers. It makes test results clearer, fixes several edge cases, and improves simulated user interactions so future changes can be tested more reliably without affecting normal business features.
Original PR description
## Pull Request HOOT (PRHOOT) 30 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Enterprise: https://github.com/odoo/enterprise/pull/82351 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Canadian EFT payment files now automatically replace special characters with standard plain-text equivalents. This helps files meet CPA005 banking requirements and reduces the risk of payment file rejection.
Original PR description
- Replacing all special characters in generated EFT files with normal ascii counterparts to fit the requirements of the CPA005 standard. - Adding an assert for it in tests. task-4609483
Resolved issues and error corrections
This fixes an issue where the website pages board view could fail when a database had only one website. Users managing a single website can now open and use the pages view normally, reducing disruption for content management.
Original PR description
Description of the issue/feature this PR addresses: Kanban view of the website pages not working (opw-4651572) Current behavior before PR: The kanban view was not working if the database only contains one website because of the group multi-website not set on the users so the t-if="record.website_id.value" cannot be evaluated. Desired behavior after PR is merged: The group attribute is now set correctly on the parent div so the if statement is working properly --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Documentation and clarification updates
This pull request records a signed Individual Contributor License Agreement for a new contributor. It helps ensure the contributor's future work can be accepted under Odoo's legal contribution requirements.
Original PR description
Hello, I am submitting my signed Individual Contributor License Agreement (CLA) to contribute to the Odoo project. This PR adds my CLA file under `doc/cla/individual/`. Thank you! 😊
Miscellaneous changes
Forward-Port-Of: odoo/odoo#203325
Original PR description
Forward-Port-Of: odoo/odoo#203325
This fix keeps long questions and answers from overlapping the wizard when users drag items by the handle. It improves readability and makes the drag-and-drop experience smoother in list views.
Original PR description
**Before this commit:** Long question and answers overlap the wizard while dragging with the handler. **After this commit:** Long question and answers do not overlap the wizard while dragging with handler. task-4452311 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Fixes an editor issue where changing an internal link between HTTP and HTTPS could trigger an error. Links now use the current page protocol, improving reliability and avoiding mixed-content problems for users editing content.
Original PR description
### Current behavior before PR: - Changing the protocol (http ↔ https) of an internal link in the editor caused a traceback due to a failed fetch request. ### Desired behavior after PR is merged: - The URL now always follows the current page's protocol, preventing mixed content issues and fetch errors. task-4531783 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When users copy editor content that includes images stored in Odoo and paste it into external tools such as Gmail, the images now keep the full address needed to display correctly. This prevents pasted messages or documents from showing broken images.
Original PR description
**Problem**: On copy as HTML, if the content contains images saved on the server, the URLs will not include the origin. When pasted outside of Odoo (for example, in Gmail), the images will not be loaded. **Solution**: Add the origin to `img` tag `src` attributes when copying content. **Steps to reproduce**: 1. Paste an image in the editor. 2. Copy all content (including the image). 3. Paste it elsewhere as HTML (e.g., Gmail). 4. Observe that the HTML is pasted but the image is not loaded. **opw-4652753** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix stops Odoo from trying to write field-deletion messages for a model that has already been removed. It prevents module updates from failing when a deleted custom model previously had tracked fields in the mail/chatter system.
Original PR description
Fixes ``` File "/home/odoo/src/odoo/odoo/addons/base/models/ir_model.py", line 2647, in _process_end self._process_end_unlink_record(record) File…
Fixes
```
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_model.py", line 2647, in _process_end
self._process_end_unlink_record(record)
File "/home/odoo/src/odoo/addons/website/models/ir_model_data.py", line 35, in _process_end_unlink_record
return super()._process_end_unlink_record(record)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/odoo/addons/base/models/ir_model.py", line 2576, in _process_end_unlink_record
record.unlink()
File "/home/odoo/src/odoo/addons/mail/models/ir_model_fields.py", line 52, in unlink
'sequence': self.env[field.model_id.model]._mail_track_get_field_sequence(field.name),
~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^
File "/home/odoo/src/odoo/odoo/api.py", line 612, in __getitem__
return self.registry[model_name](self, (), ())
~~~~~~~~~~~~~^^^^^^^^^^^^
File "/home/odoo/src/odoo/odoo/modules/registry.py", line 240, in __getitem__
return self.models[model_name]
~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'my.custom.model'
```
To reproduce:
* add a model with a tracked field to a module
* create a record and update field value to create a tracking message
* remove the model from the module and update the module
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prOdoo now handles web pages that include an XML-style header when generating link previews. This prevents an error that could block users from saving certain links in Documents workspaces and other areas that use link previews.
Original PR description
## Details: The function get_link_preview_from_html is a common tool used in many modules, one of them documents. When you add a link on a workspace that response with a content with a xml…
## Details: The function get_link_preview_from_html is a common tool used in many modules, one of them documents. When you add a link on a workspace that response with a content with a xml declaration (ex. <!--?xml version="1.0" encoding="UTF-8"?-->), this will raise the next ValueError: "Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration." At the moment that the string is being parsed as a html element, this string has been cleaned, to avoid the issue, we can only remove this xml declaration because this element is only being used to extract information about the page. ## Impacted versions: 18.0 and later ## Steps to reproduce: 1. Go to Documents App 2. Add a link in any workspace with xml declaration (ex. https://www.buffalo.jp/s3/guide/crmm/userguide/99/en/pc_index.html) ## Current behavior: Raise Value Error "Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration." ## Expected behavior: Link should be saved. ### Task OPW-4675813
Point of Sale searches now match customers even when mobile numbers are entered with spaces or common punctuation. This helps cashiers find the right customer record more reliably during checkout.
Original PR description
Issue: ======== When searching for a partner using a mobile number with spaces (e.g., `+91 123456789`), the expected partner is not displayed. Cause: ======== The code removes spaces from stored phone numbers but does not modify the search input, leading to a mismatch: - Stored: `+91123456789` - Search input: `+91 123456789` Fix: ====== Added a regex to standardize mobile numbers on the frontend by removing `+, -, (), and spaces`. The same transformation is applied during search to ensure correct matches. Task-4675406
The point-of-sale certification flow now handles connection failures properly when the required server cannot be reached. This prevents automated checks and related operations from crashing, improving reliability for German POS certification setups.
Original PR description
Before this commit, the fetch error was not correctly caught, leading to a crash of the runbot when the server was not reachable. runbot: 160959
This update adjusts accounting-related automated tests so they work correctly with recent changes to the internal test tooling. It helps keep Odoo's test suite reliable while limiting the change to test code only, reducing risk for business operations.
Original PR description
## Pull Request HOOT (PRHOOT) 30 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Community: https://github.com/odoo/odoo/pull/203713 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Steps to reproduce: - Install accounting - Go to Reporting, Invoice Analysis in pivot view - Select Untaxed amount and Average price - Or (Select Product Quantity and Average Price) Issue: If the `average_price` is selected, the `untaxed_amount` becomes empty and not read, and it is the same case for the `product_quantity`. In pivot view, the frontend sends the fields to the backend in this format field_name:agg https://github.com/odoo/odoo/blob/36e6d6ea6792d5e549a7794f111a65fc32decd1c/a
Original PR description
Steps to reproduce: - Install accounting - Go to Reporting, Invoice Analysis in pivot view - Select Untaxed amount and Average price - Or (Select Product Quantity and Average Price) Issue: If the…
Steps to reproduce: - Install accounting - Go to Reporting, Invoice Analysis in pivot view - Select Untaxed amount and Average price - Or (Select Product Quantity and Average Price) Issue: If the `average_price` is selected, the `untaxed_amount` becomes empty and not read, and it is the same case for the `product_quantity`. In pivot view, the frontend sends the fields to the backend in this format field_name:agg https://github.com/odoo/odoo/blob/36e6d6ea6792d5e549a7794f111a65fc32decd1c/addons/web/static/src/views/pivot/pivot_model.js#L1142-L1143 In [d741788](https://github.com/odoo/odoo/commit/d7417883062e14c4a0a58978463f181b3811d19d), read_group is overridden to correctly handle the `average_price`, and uses both the `untaxed_amount` and the `product_quantity` to compute it. If the `untaxed_amount` and `product_quantity` weren’t in the original fields sent from the frontend by the user, they are removed from the result data. But the problem they are named incorrectly in the if conditions, and because of the format sent from the frontend, the if condition will always succeed (because the name in the fields array is not the same as the one checked in the if condition) leading to the removal of both `untaxed_amount` and `product_quantity` from the result whenever selecting the `average_price`. opw-4644004 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#204638
I spotted three mistakes in the naming of the lines in the Modelo 303 and 390 reports. This PR fixes them and updates the .po, .pot files accordingly. Forward-Port-Of: odoo/odoo#200544 Forward-Port-Of: odoo/odoo#200201
Original PR description
I spotted three mistakes in the naming of the lines in the Modelo 303 and 390 reports. This PR fixes them and updates the .po, .pot files accordingly. Forward-Port-Of: odoo/odoo#200544 Forward-Port-Of: odoo/odoo#200201
This is a followup on [1]. Restricted users are not allowed to apply shapes on images because: - it involves the duplication of the image attachment, and - SVGs mimetype is kept only for users allowed to write views. This commit verifies that the user has restricted edition rights and makes it possible for them to apply shapes on images. Steps to reproduce: - Install eCommerce. - Create a user with sales administrator rights. - Connect as that user. - Go to a product page. - Edi
Original PR description
This is a followup on [1]. Restricted users are not allowed to apply shapes on images because: - it involves the duplication of the image attachment, and - SVGs mimetype is kept only for users allowed to write views. This commit verifies that the user has restricted edition rights and makes it possible for them to apply shapes on images. Steps to reproduce: - Install eCommerce. - Create a user with sales administrator rights. - Connect as that user. - Go to a product page. - Edit. - Drop a "Text - Image" block. - Set a shape on the image. - Save. => Did trigger an error popup. [1]: https://github.com/odoo/odoo/commit/d5aa54ca108eb99c7eb855a7d456bfe2f208a8eb task-2830084 Forward-Port-Of: odoo/odoo#92540
Steps to reproduce: - Force _verify_updated_quantity returns warning - Add product to cart - exception shown Explanation: - When _verify_updated_quantity returns warning, it will use WarningNotification in CartNotification only. However CartNotification required currency_id for AddToCartNotification, therefore exception throw. Forward-Port-Of: odoo/odoo#204585
Original PR description
Steps to reproduce: - Force _verify_updated_quantity returns warning - Add product to cart - exception shown Explanation: - When _verify_updated_quantity returns warning, it will use WarningNotification in CartNotification only. However CartNotification required currency_id for AddToCartNotification, therefore exception throw. Forward-Port-Of: odoo/odoo#204585
Versions -------- - 17.0+ Steps ----- 1. Have a product with a custom attribute; 2. create a sales order with the product; 3. enter a value for the customer product; 4. confirm order & go to delivery; 5. print delivery slip. Issue ----- The product's name is displayed twice. Cause ----- The product's name is used as default description. There is currently logic in place to prevent duplicate printing if there's an exact match. If the product has certain attributes, they will
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a product with a custom attribute; 2. create a sales order with the product; 3. enter a value for the customer product; 4. confirm order & go to delivery; 5. print delivery slip. Issue ----- The product's name is displayed twice. Cause ----- The product's name is used as default description. There is currently logic in place to prevent duplicate printing if there's an exact match. If the product has certain attributes, they will get added to the description, making the strings no longer equal. Solution -------- Instead of checking for exact matches, use `startswith` and `removeprefix` to remove the duplicate product name from the description. opw-4637449 Forward-Port-Of: odoo/odoo#201010
Steps: - install `contacts` and `sale_management` - Open a contact in a form view and add a sub-contact - Don't fill contact name field - Save & Close - Go to Quotations - Select this new contact as Customer (it should have a name like Parent contact, Other Address) - Add any product - Save - Click on `Preview` - Click on `Sign & Pay` - Traceback When there is no signature name, `NameAndSignature` does not set `resetSignature` and `getSignatureImage` on `this.signature`. So after `
Original PR description
Steps: - install `contacts` and `sale_management` - Open a contact in a form view and add a sub-contact - Don't fill contact name field - Save & Close - Go to Quotations - Select this new contact as Customer (it should have a name like Parent contact, Other Address) - Add any product - Save - Click on `Preview` - Click on `Sign & Pay` - Traceback When there is no signature name, `NameAndSignature` does not set `resetSignature` and `getSignatureImage` on `this.signature`. So after `SignatureForm` initialization, `onMounted` raise a traceback, because it calls directly `this.signature.resetSignature`. This commit adds default functions to `resetSignature` and `getSignatureImage` to prevent the crash. In addition to the this fix, I added a fallback to the default name on signature form to `sale_order.partner_id.commercial_partner_id.name` if `sale_order.partner_id.name` is not set. opw-4504223 Forward-Port-Of: odoo/odoo#202774 Forward-Port-Of: odoo/odoo#202318
**Before this commit:** The fiscal position computation method did not depend on `gst_treatment`, causing issues where changes to `gst_treatment` were not detected. As a result, the computation did not trigger as expected, leading to incorrect fiscal position determination. **After this commit:** The computation method now depends on `gst_treatment`, ensuring that any changes to it trigger a recalculation. This guarantees accurate fiscal position computation as required. --- I confi
Original PR description
**Before this commit:** The fiscal position computation method did not depend on `gst_treatment`, causing issues where changes to `gst_treatment` were not detected. As a result, the computation did not trigger as expected, leading to incorrect fiscal position determination. **After this commit:** The computation method now depends on `gst_treatment`, ensuring that any changes to it trigger a recalculation. This guarantees accurate fiscal position computation as required. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#203445
To replicate: 1. With `accountant` installed, activate Analytic Accounting in the Settings 2. Create an Analytic Plan with an Analytic Account 3. Create an Analytic Item with any amount, using the created account. 4. Verify that the Analytic Account has a balance associated to it. 5. Returning to the Analytic Plan, set a parent plan. 6. The Analytic Account has no balance associated to it, and the Analytic Item does not have the account anywhere. When changing the parent plan of an Anal
Original PR description
To replicate: 1. With `accountant` installed, activate Analytic Accounting in the Settings 2. Create an Analytic Plan with an Analytic Account 3. Create an Analytic Item with any amount, using the…
To replicate: 1. With `accountant` installed, activate Analytic Accounting in the Settings 2. Create an Analytic Plan with an Analytic Account 3. Create an Analytic Item with any amount, using the created account. 4. Verify that the Analytic Account has a balance associated to it. 5. Returning to the Analytic Plan, set a parent plan. 6. The Analytic Account has no balance associated to it, and the Analytic Item does not have the account anywhere. When changing the parent plan of an Analytic Plan, this change is not propagated correctly to the analytic items using the now child plan's accounts. This commit will update the lines using accounts from the now child plan, setting the accounts in the correct plan column if possible. If there are lines that already have a different account in the new parent plan column, a RedirectWarning is shown. opw-4607129 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#202028
_compute_current_session tried to filter `session_ids` to retrieve session states, but in databases with a large number of sessions, this caused excessive memory usage and a potential `MemoryError`. ``` select count(*) from pos_session +---------+ | count | |---------| | 3582911 | +---------+x` ``` opw-4544050 upg-2459515 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#202244
Original PR description
_compute_current_session tried to filter `session_ids` to retrieve session states, but in databases with a large number of sessions, this caused excessive memory usage and a potential `MemoryError`. ``` select count(*) from pos_session +---------+ | count | |---------| | 3582911 | +---------+x` ``` opw-4544050 upg-2459515 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#202244
Before this commit, the `Europe/Brussels` timezone was applied 2 times on the calculation of the end_datetime when the slot is linked to a template and so the end date time of the slot could suddenly be before the start date time, which should not be possible. The timezone is applied 2 times, because the start date time computed already got the right timezone, so it is not needed to apply again the timezone since the timezone is already defined thanks to the start date time used in the co
Original PR description
Before this commit, the `Europe/Brussels` timezone was applied 2 times on the calculation of the end_datetime when the slot is linked to a template and so the end date time of the slot could suddenly be before the start date time, which should not be possible. The timezone is applied 2 times, because the start date time computed already got the right timezone, so it is not needed to apply again the timezone since the timezone is already defined thanks to the start date time used in the computation. This commit makes sure the timezone is applied once during the calculation of the end datetime, to be sure the difference between UTC and the timezone to apply is not applied 2 times on the end date time. runbot-error-162055 Forward-Port-Of: odoo/enterprise#82529
According to the DATEV Format documentation, the VAT needs to be split into two columns instead of one. The first column being the country code (ISO 3166), and the second one being the remaining numbers. task-4600047 runbot : https://runbot.odoo.com/runbot/bundle/16-0-datev-export-roto-352476 Forward-Port-Of: odoo/enterprise#82104 Forward-Port-Of: odoo/enterprise#80843
Original PR description
According to the DATEV Format documentation, the VAT needs to be split into two columns instead of one. The first column being the country code (ISO 3166), and the second one being the remaining numbers. task-4600047 runbot : https://runbot.odoo.com/runbot/bundle/16-0-datev-export-roto-352476 Forward-Port-Of: odoo/enterprise#82104 Forward-Port-Of: odoo/enterprise#80843
Steps to Produce: - Generate offer contract from recruitment. - Sign the contract and submit it. - Open an existing offer and click on the stat button. issue: - stat button opens new contract from view as employee contract is False. Fix: - return applicant's newly created contract to the stat button. task-4610751 Forward-Port-Of: odoo/enterprise#80943
Original PR description
Steps to Produce: - Generate offer contract from recruitment. - Sign the contract and submit it. - Open an existing offer and click on the stat button. issue: - stat button opens new contract from view as employee contract is False. Fix: - return applicant's newly created contract to the stat button. task-4610751 Forward-Port-Of: odoo/enterprise#80943