Tuesday, March 25, 2025
55 changes · 18.0
Enhancements to existing features
Odoo now checks Peppol registration activation much sooner after a company signs up, reducing the wait before invoice receipt can be enabled. It also checks sent invoice status shortly after sending, improving visibility and helping on-premise users who cannot rely on webhooks.
Original PR description
Currently, registering as a receiver on Peppol via Odoo has a poor user experience due to the long delays in activation. The activation process requires a DNS lookup, which is performed on the IAP side every 6 hours. Additionally, the client db queries IAP for the user state every 6 hours before enabling the receipt of invoices, resulting in a typical delay of over 8 hours—often spanning more than a full workday. This commit, together with https://github.com/odoo/iap-apps/pull/989 tries speed things up by - fetching the activation status 1h after registration from IAP (client-db side) - fetching sent invoice status 5 minutes after having sent the invoice This is also a replacement for webhooks for on-prem users who won't be able to use webhooks from this PR: https://github.com/odoo/iap-apps/pull/1008 task-4395265
Editing product attributes on product forms is now faster for databases with very large numbers of product attribute lines. The change reduces waiting time when adding or changing attributes, improving day-to-day productivity for users managing large product catalogs.
Original PR description
When there are lots of `product_template_attribute_lines` the computation of the `product_tmpl_ids` field of `product.attribute` can take a bit of time. This in turn slows down the editing of attribute/attribute_values on product.template's FormView. This commit changes the compute method by first doing a `_read_group` to retrieve the templates by attribute. This skips the `__get__` call on `product_attribute.product_attribute_line_ids`. A compound index on `product_template_attribute_line` is also added to speedup the `_read_group` mentioned above. #### speedup Customer database with close to 900 000 product_template_attribute_lines and an average of 100 000 product_template_attribute_lines by attribute_id. Adding a new attribute in a template FormView: 3s -> 500ms. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
The Sales app now calculates the uninvoiced balance correctly when discounts are applied to sales order lines. This prevents discounted amounts from being reduced twice, giving users a more accurate view of what still needs to be invoiced.
Original PR description
Steps to reproduce: - Create SO with two products. - Apply 10% discount to both lines. - Confirm SO and create an invoice. - Confirm invoice for only one SOL. - Go to 'Orders to Invoice' and add uninvoiced-balance field to the view using Studio. - Check value of the uninvoiced-balance field. Issue: - The uninvoiced-balance field is not calculated correctly. Cause: - line.price_total already includes the discount, so applying the discount again results in an incorrect calculation. Fix: - Remove price_reduce and directly multiply unit_price_total by qty_to_invoice to ensure the correct calculation of amount_to_invoice. opw-4567563 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Miscellaneous changes
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#202455 Forward-Port-Of: odoo/odoo#202230
Original PR description
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#202455 Forward-Port-Of: odoo/odoo#202230
This fixes an issue where accounting document numbers could fail to continue correctly when multiple users or processes created documents at the same time. It helps keep invoice and journal entry numbering consistent and prevents disruptions in accounting workflows.
Original PR description
When looping inside of the `while True` loop because of concurrency, the `sequence_prefix` was not correctly set. This was breaking the behavior of `sequence.mixin` because we were not able to get the last number. Partial revert of 10565c6968a5d0f285f93c4bdc610350999a88e3
Odoo now correctly reads mail server capabilities needed to detect the maximum allowed email size. This helps prevent email sending issues caused by missing size-limit information.
Original PR description
The automatic detection of maximum email size was not working anymore. After this commit, the `esmtp_features` attribute is added, to ensure reliable detection of the email's size. opw-4673107 cc: @Julien00859 @Abridbus
Product images in kanban views now keep the same browser cache URL when the image field comes from the same record. This avoids repeatedly downloading the same images after opening a product and returning to the list, making navigation faster and reducing unnecessary network usage.
Original PR description
Steps to reproduce ================== - Go to the products kanban view - Open a record - Go back to the kanban view => Every product image is downloaded again Cause of the issue ==================…
Steps to reproduce
==================
- Go to the products kanban view
- Open a record
- Go back to the kanban view => Every product image is downloaded again
Cause of the issue
==================
There is a unique query param in the url as the browser doesn't fetch twice the same image from the same url in the same session.
For non related fields, we use the last record update as a unique timestamp.
For related fields, since we don't have the information about the last update, we generate a unique timestamp when instanciating an ImageField component.
It can happen that a related field points to the same model.
This is the case here where the product kanban view uses the "image_128" field.
```py
image_1920 = fields.Image("Image", max_width=1920, max_height=1920)
image_128 = fields.Image("Image 128", related="image_1920", max_width=128, max_height=128, store=True)
```
Solution
========
When a field is related but the relation points to the same model, we can still use the last record update
We can try to detect this by checking if there is a dot in the related path.This update adds automated coverage to ensure Point of Sale orders can be validated when the currency does not use decimal places. It helps prevent checkout issues in countries or setups using whole-unit currencies.
Original PR description
Before this commit, there was no test to ensure that orders could be validated correctly when using a currency with zero decimal places. This commit adds a test to validate an order with a zero decimal places currency, ensuring that the system handles such cases without errors. opw-4595028 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Users assigned to a child company in a Belgian company structure can now open the Point of Sale without running into an access error. This matters because shops operated under branch or subsidiary companies can use POS normally even when accounting setup is managed at the parent company level.
Original PR description
Some users are encountering access error when opening the pos from a child company Steps to reproduce: ------------------- * Create a child company for "My Belgian Company" * Register this company for the user Marc Demo * Create a shop in the brach * Now connect as Marc Demo * Try to open the PoS > Observation: Access error Why the fix: ------------ Account chart template are only defined in the parent company. opw-4644042
This fixes issues where employees or resources with flexible working hours could still be treated as having standard attendance hours. It prevents Attendance from failing with a division-by-zero error when a working schedule is changed to flexible hours.
Original PR description
## [FIX] resource: make sure flexible resource don't use attendances This commit makes sure the resource calendar attendance is not used for a flexible resource even if that resource has a working…
## [FIX] resource: make sure flexible resource don't use attendances This commit makes sure the resource calendar attendance is not used for a flexible resource even if that resource has a working schedule with hours per day equals to 0 hour. ## [FIX] hr: recompute is_flexible when working schedule becomes flexible Before this commit, when the user sets a working schedule to an employee and convert that working schedule into a flexible working schedule, the employee is not considered as working with flexible hours. This commit makes sure the `_compute_is_flexible` method defined in `hr.employee` model is triggered when the `flexible_hours` field of the working schedule linked to the employee is altered. Steps to reproduce the issue: ----------------------------- 0. Install Attendance app (`hr_attendance` module). 1. Set a working schedule A to employee E 2. Go to the form view of the working schedule A and check `Flexible Hours` field to convert the working schedule as flexible working schedule. 3. Go to Attendance app Expected Behavior: ----------------- The Attendance app should loaded without any issue. Current Behavior: ---------------- A traceback is occurred saying we have a division by zero. opw-4492625
Users who do not have permission to interact with comments will no longer see emoji reaction buttons. This prevents confusing error screens and creates a smoother experience on product and course review pages.
Original PR description
Before this PR: - A user with no access attempts to react with emojis on a comment, resulting in a traceback. After this PR: - The buttons for adding emoji reactions to comments will be hidden for that users. Task-4452408
This fixes a document layout issue where long customer address details could overlap with the shipping address on DIN 5008 quotation PDFs. Businesses using this German document format will get clearer, more professional printed quotes when customer addresses contain many lines.
Original PR description
The aim of this commit is to fix a display bug where the shipping adress is overlapping the address element when too many address lines are present Steps to reproduce: - Install l10n_din5008_sale - Configure the document to use the din5008 layout - Create a UK customer with all the adress fields filled + phone - Create a quotation for that customer and Print the PDF Quote opw-4575257  Becomes  --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Installing the Point of Sale event module no longer fails if the default Event Registration product was previously deleted. This helps businesses recover cleanly from product cleanup actions without blocking module installation.
Original PR description
Currently a `ParseError` is arising when the user installs the `pos_event` module after deleting `Event Registration` product from the products. Steps to reproduce: --- - Install `event_product`…
Currently a `ParseError` is arising when the user installs the `pos_event` module after deleting `Event Registration` product from the products.
Steps to reproduce:
---
- Install `event_product` application (without demo data).
- Delete `Event Registration` from products
- Now install `pos_event` module
Traceback:
---
```
Exception: Cannot update missing record 'event_product.product_product_event'
ParseError: while parsing /home/odoo/src/odoo/saas-18.1/addons/pos_event/data/event_product_data.xml:4, somewhere inside <record id="event_product.product_product_event" model="product.product">
<field name="available_in_pos">True</field>
<field name="pos_categ_ids" eval="[(6, 0, [ref('pos_event.pos_category_event')])]"/>
</record>
```
The error occurs because the user deleted the product, and then tried to install the other module.
This commit solves the above issue by using `forcecreate="False"` to bypass record creation if it violates checks.
https://github.com/odoo/odoo/blob/f5378fadf910d193cbb44a4d1c10a5a15d8b9a51/odoo/tools/convert.py#L364
sentry-5731062091
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prThis fix ensures loyalty history only counts activity tied to the correct sale order type. It prevents eWallet or loyalty amounts from being inflated when point-of-sale and online orders happen to share the same internal ID.
Original PR description
Description of the issue/feature this PR addresses: - Setup an eWallet for POS and website - Place an order of eWallet top up from POS - Place an order of eWallet top up from ecommerce - Make sure both has the same ID, or any POS order that has the same ID with sale.order ID - You will see the loyalty issued becomes the sum of the unrelated model Current behavior before PR: - The loyalty showed in Portal / Odoo will be wrong if it clashes with other model ID Desired behavior after PR is merged: - Only consider the order that comes from the sale order model --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The wording of an error message in the Point of Sale loyalty flow was corrected when a gift card has already been sold. This makes the message clearer and more professional for staff using the system.
Original PR description
Before this commit, the error message shown when a gift card had already been sold contained incorrect grammar: "This Gift card is already been sold." opw-4656131 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix improves Odoo IoT display handling so connected displays can be detected and rotated correctly when running under Wayland. It helps point-of-sale and IoT display setups remain reliable on newer Linux display environments.
Original PR description
This commit is a backport of the display driver changes from commit 078533b. These changes allow displays to be detected and rotated correctly under Wayland. task-4657986 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents errors when a user manages time off allocations but has no employee record in the current company. The system now checks for an available employee calendar before loading allocation data, improving reliability for HR workflows.
Original PR description
Issue: if user does not have employee in the current company in managment the allocation will try to load his employee calendar which raise the error Fix: check if there is an employee for the user before trying to fetch the data Task: 4660184 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update bundles several bug fixes across Odoo, including faster loading of image-heavy kanban views, corrected invoice dating for Argentina, improved checkout handling for Brazil, and compliance updates for German e-invoicing. It also resolves smaller issues in messaging, POS loyalty flows, inventory route searches, and spreadsheet styling, reducing user friction and business process errors.
Original PR description
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
This fixes an issue where reopening the website editor could fail after a user removed every tab from a Tabs block. The editor now handles that empty-tab situation gracefully, helping users continue editing without an error screen.
Original PR description
**Problem**: After commit [https://github.com/odoo-dev/odoo/commit/80fde992370e4474c27a383a61814ce1159f550c](https://github.com/odoo/odoo/commit/80fde992370e4474c27a383a61814ce1159f550c), if all tabs…
**Problem**: After commit [https://github.com/odoo-dev/odoo/commit/80fde992370e4474c27a383a61814ce1159f550c](https://github.com/odoo/odoo/commit/80fde992370e4474c27a383a61814ce1159f550c), if all tabs in a "Tabs" block are removed and saved, the next time the editor is opened, there is a traceback because `navEl` is `null`. **Solution**: Use the first value from `possibleValues` in case `navEl` is `null` this will prevent traceback in that case but does not prevent reaching the no tab situation (Still able to remove all tabs). **Steps to Reproduce**: 1. Add a **"Tabs"** block. 2. Click inside the first tab to edit its content. 3. Press **Backspace** repeatedly until the tab is completely removed. 4. Repeat for all remaining tabs until none are left. 5. Save and exit the editor. 6. Open the editor again. - **Issue**: A traceback occurs due to `navEl` being `null`. **opw-4608389** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue in the HTML editor where clicking text above a large image could unexpectedly scroll the page to the image, making the text difficult to edit. The editor now only scrolls when most of the selected content is out of view, keeping editing stable and predictable.
Original PR description
**Problem**: When adding text followed by **"Shift+Enter"** and a long image, clicking to edit the text triggers `scrollTo`, causing the view to jump to the image instead. This makes it impossible to edit the text, as the selection keeps switching to the image. This happens because, on `pointerdown`, the selection changes to text, triggering a scroll. On `pointerup`, the target becomes the image, changing the selection again. **Solution**: Scroll only if more than half of the content is not visible. **Steps to Reproduce**: 1. Add text and press **"Shift+Enter"**. 2. Insert a long image below the text. 3. Try to edit the text: - **Issue**: View scrolls to the image, making text uneditable. opw-4606741 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Since [1] the widget displayed on a server action form view when it is set up as "Update a o2m field on a record" was not displaying the fields in the proper way. Before: the value field was a text field expecting the user to input the record id by hand. After: the value field is now a many2one selector. [1]: https://github.com/odoo/odoo/commit/0a744accc2aaa965d5353e854317895d822ad954 Forward-Port-Of: odoo/odoo#203156 Forward-Port-Of: odoo/odoo#202930
Original PR description
Since [1] the widget displayed on a server action form view when it is set up as "Update a o2m field on a record" was not displaying the fields in the proper way. Before: the value field was a text field expecting the user to input the record id by hand. After: the value field is now a many2one selector. [1]: https://github.com/odoo/odoo/commit/0a744accc2aaa965d5353e854317895d822ad954 Forward-Port-Of: odoo/odoo#203156 Forward-Port-Of: odoo/odoo#202930
When we have an Analytic Plan being Mandatory, confirming an invoice from the form view, if it has a line without an Analytic distribution, correctly raises a ValidationError. Confirming invoices from the list view does not raise the same error, yet it should. To replicate: 1. [Activate](https://www.odoo.com/documentation/18.0/applications/finance/accounting/reporting/analytic_accounting.html) Analytic accounting: a. Install `accountant` b. In Settings, activate Analytic Accounting
Original PR description
When we have an Analytic Plan being Mandatory, confirming an invoice from the form view, if it has a line without an Analytic distribution, correctly raises a ValidationError. Confirming invoices…
When we have an Analytic Plan being Mandatory, confirming an invoice from the form view, if it has a line without an Analytic distribution, correctly raises a ValidationError. Confirming invoices from the list view does not raise the same error, yet it should. To replicate: 1. [Activate](https://www.odoo.com/documentation/18.0/applications/finance/accounting/reporting/analytic_accounting.html) Analytic accounting: a. Install `accountant` b. In Settings, activate Analytic Accounting c. Create an Analytic plan (with an Analytic account associated) 2. Set its default applicability to mandatory 3. Create two invoices, remove the analytic distribution from one of the lines in one invoice. 4. In the invoices list view, select both newly created invoices, click on Actions > Confirm Entries 5. Click Confirm 6. The invoices were posted, even though they have no analytic distributions. Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4603919) opw-4603919 Forward-Port-Of: odoo/odoo#203153 Forward-Port-Of: odoo/odoo#201560
Before this commit: When sample data was visible in the view, the pager was also displayed, showing a record count, which could be misleading. After this commit: Now, when sample data is visible, the pager is hidden. Task-4489033 Forward-Port-Of: odoo/odoo#203174 Forward-Port-Of: odoo/odoo#200624
Original PR description
Before this commit: When sample data was visible in the view, the pager was also displayed, showing a record count, which could be misleading. After this commit: Now, when sample data is visible, the pager is hidden. Task-4489033 Forward-Port-Of: odoo/odoo#203174 Forward-Port-Of: odoo/odoo#200624
**Problem**: When copying text from the editor that contains `nbsp`, pasting it into a code editor results in invalid characters, causing issues like compilation errors. **Solution**: Replace `nbsp` with normal spaces when copying text. **Steps to Reproduce**: 1. Add text: `"a b"` (with double spaces). 2. Copy the text. 3. Paste it into a **code editor**. - **Issue**: The invisible `nbsp` causes compilation errors. **opw-4645678** --- I confirm I have signed the CLA and re
Original PR description
**Problem**: When copying text from the editor that contains `nbsp`, pasting it into a code editor results in invalid characters, causing issues like compilation errors. **Solution**: Replace `nbsp` with normal spaces when copying text. **Steps to Reproduce**: 1. Add text: `"a b"` (with double spaces). 2. Copy the text. 3. Paste it into a **code editor**. - **Issue**: The invisible `nbsp` causes compilation errors. **opw-4645678** --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#202904
**Steps to reproduce:** - Use version 2.12.1 of PyPDF2 as required if python version > 3.10 - Install Accounting - Upload an encrypted PDF as a bill - Go to the bills list view - Select the uploaded bill - Print "Original Bills" **Issue:** A traceback is raised: "PyPDF2.errors.DependencyError: PyCryptodome is required for AES algorithm" **Cause:** When printing the original bill, we try to add a banner on the PDF. If the PDF is encrypted, PyPDF2 (2.12.1) will only try to decrypt
Original PR description
**Steps to reproduce:** - Use version 2.12.1 of PyPDF2 as required if python version > 3.10 - Install Accounting - Upload an encrypted PDF as a bill - Go to the bills list view - Select the uploaded…
**Steps to reproduce:** - Use version 2.12.1 of PyPDF2 as required if python version > 3.10 - Install Accounting - Upload an encrypted PDF as a bill - Go to the bills list view - Select the uploaded bill - Print "Original Bills" **Issue:** A traceback is raised: "PyPDF2.errors.DependencyError: PyCryptodome is required for AES algorithm" **Cause:** When printing the original bill, we try to add a banner on the PDF. If the PDF is encrypted, PyPDF2 (2.12.1) will only try to decrypt it if "PyCryptodome" library is installed. Otherwise, it will raise a "DependencyError", which is not handled in the "except" clause. As "PyCryptodome" library is not part of Odoo requirements, we should handle the raised "DependencyError". **Solution:** Try to import "DependencyError" from "PyPDF2.errors" and catch that exception when adding the banner to the PDF. Our own "DependencyError" exception should be created because version 1.26.0 of PyPDF2 doesn't declare "DependencyError" and therefore the import will fail. "NotImplementedError" is used instead in version 1.26.0 and is already handled. opw-4634417 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#203005 Forward-Port-Of: odoo/odoo#202129