Daily updates from Odoo
Monday, August 3, 2026
19 changes · 18.0
Enhancements to existing features
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and /discuss/channel/messages. Measured from openDiscuss resolving to the message being in the DOM: - 250 to 460ms on an idle machine; - 867 to 5258ms over 10 runs with the CPU throttled 4x, which is what a busy runbot looks like, 3 of the 10 over 2 seconds; - 1474 to 6912ms with the CPU throttl
Original PR description
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and…
Before this commit, contains() and its variants gave the client 3 seconds, and the bus helpers 2 seconds. The problem is that the first wait after openDiscuss pays for the whole mount, /mail/data and /discuss/channel/messages. Measured from openDiscuss resolving to the message being in the DOM:
- 250 to 460ms on an idle machine;
- 867 to 5258ms over 10 runs with the CPU throttled 4x, which is what a
busy runbot looks like, 3 of the 10 over 2 seconds;
- 1474 to 6912ms with the CPU throttled 6x, 5 of 6 over 3 seconds.
"Reactions are ordered by id" fails 1 run in 60 at 4x for that reason.
Note that a longer timeout costs nothing on a green build: the timer is cleared as soon as the element is there, so it only delays the report of a test that was going to fail anyway.
This commit raises both to 10 seconds, the delay a tour step already gets in macro.js. test_js.py runs the presets with timeout=15000, so hoot fails the test itself at 15 seconds and 10 leaves room for the rest of the test.
This should also close most of the open runbot errors shaped like:
Failed to find x of "..." (Timeout of 3 seconds). Found 0 instead.
The element does show up in those, just after the wait gave up.
https://runbot.odoo.com/odoo/error/944188
web companion https://github.com/odoo/odoo/pull/279984Slovak entities are identified by three separate numbers: the company registry number (IČO), the income tax ID (DIČ) and the VAT number (IČ DPH). Odoo already stores IČO in company_registry and IČ DPH in vat, both on res.partner. DIČ is only defined on res.company, so it cannot be recorded for customers or vendors at all. This becomes a problem for the upcoming Peppol support in Slovakia. Slovak participants are identified on the network by EAS scheme 0245, which carries the DIČ. A field that
Original PR description
Slovak entities are identified by three separate numbers: the company registry number (IČO), the income tax ID (DIČ) and the VAT number (IČ DPH). Odoo already stores IČO in company_registry and IČ DPH in vat, both on res.partner. DIČ is only defined on res.company, so it cannot be recorded for customers or vendors at all. This becomes a problem for the upcoming Peppol support in Slovakia. Slovak participants are identified on the network by EAS scheme 0245, which carries the DIČ. A field that only exists on res.company therefore cannot be used for it, neither for the sender nor for the recipient. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
This fix corrects how Swiss payroll amounts are rounded to the nearest 0.05, avoiding tiny calculation differences caused by floating-point arithmetic. It helps produce more consistent payslip and Swissdec declaration values, reducing unexpected test or reporting discrepancies.
Original PR description
In multiple places within l10n_ch_hr_payroll_elm we use float_round to a precision of 0.01 but then manually round to 0.05 precision. 1. Open a python terminal 2. Enter 1000 % 0.05 >= 0.025 3. See this results to true, even though it shouldn't Fix this by using float_round with a precision of 0.05 instead. https://github.com/odoo/enterprise/blob/7f9cd01ff3dd470b06ae176982fd042243be8f3c/l10n_ch_hr_payroll_elm/models/hr_payslip.py#L102-L105 The change to `ema_declaration.json` is needed as previously it was expected that there was a small difference between salary over the months due to the odd rounding (a difference of like 0.000000000001). Adding the new rounding makes the values equal and test_ema_declaration_2023_01 would fail due to changeSalary no longer being in the computed dict. All the way to master! opw-6322937 Forward-Port-Of: odoo/enterprise#121401
Guatemalan invoice PDFs now show 'CF' consistently with the official electronic XML when customer tax details are missing or use placeholder values. The tax threshold check also uses the company currency, helping ensure legal limits are applied correctly for invoices in any currency.
Original PR description
with this commit:- - Display 'CF' in the invoice PDF whenever the generated XML uses CF. - Treat placeholder VAT values such as '/', 'NA', and 'na' as missing VAT. - Compare the invoice total using the company currency instead of the document currency when evaluating the 2,500 threshold, ensuring the legal limit is applied consistently regardless of the invoice currency task-6305333
Accounting-only users can now print Spanish VAT record books even when the report includes point-of-sale transactions. This prevents an access error and lets finance teams complete VAT reporting without needing extra POS permissions.
Original PR description
Steps to reproduce:
- With an ES Company
- Open a POS session, add product with tax and pay
- As a user with only accounting access
- Go to Accouting > Reporting > Tax report
- Select Generic Tax report
- Print "VAT record Books"
Issue:
An AccessError will raise
```
Access Error
You are not allowed to access 'Point of Sale Session' (pos.session) records.
This operation is allowed for the following groups:
- Point of Sale/User
Contact your administrator to request access if necessary.
```
Analysis:
Vat Record Books handler for POS needs to read pos.session and pos.order records. Currently, the action is performed with the rights of the user running the report, so accounting-only user face an error.
As POS records are only read internally to build the report, we add sudo call to get the data.
opw-5862529
Forward-Port-Of: odoo/enterprise#125980The UK CIS report now correctly includes payments linked to receipts that have CIS tax applied. This ensures businesses get a more complete and accurate CIS reporting view, matching the behavior already available for vendor bills.
Original PR description
With the l10n_uk_reports_cis module installed: - Create a vendor bills and add a CIS tax --> This vendor's bills appear correctly in the report. - Create a receipt and add a CIS tax --> This type of bill appears in the report, but the payment is not showing up. opw-6282548
UrbanPiper online orders with tax-included products now calculate the correct per-item price when customers order more than one unit. This prevents inflated Point of Sale order totals and keeps reporting and customer charges accurate.
Original PR description
Steps to reproduce: --- - Configure a Point of Sale with UrbanPiper credentials. - Create a product priced at 100 with a 5% GST (Tax Included). - Sync the product with UrbanPiper. - Place an online order with a quantity greater than 1. Issue: --- - `total_with_tax` was incorrectly treated as the unit price for multi-quantity tax-included orders. Fix: --- - Calculate the unit price by dividing `total_with_tax` by the ordered quantity before creating the POS order line. task-6427634
**Description of the issue/feature this PR addresses:** When adding a product with an analytic distribution to a Sales Order that is already linked to a project, the product's analytic distribution is not automatically applied to the order line. This occurs due to a previous commit that attempted to protect manually entered analytic distributions from being overwritten when an SO is confirmed and a project is generated. To do this, the old code filtered out any non-empty project lines and
Original PR description
**Description of the issue/feature this PR addresses:** When adding a product with an analytic distribution to a Sales Order that is already linked to a project, the product's analytic distribution…
**Description of the issue/feature this PR addresses:** When adding a product with an analytic distribution to a Sales Order that is already linked to a project, the product's analytic distribution is not automatically applied to the order line. This occurs due to a previous commit that attempted to protect manually entered analytic distributions from being overwritten when an SO is confirmed and a project is generated. To do this, the old code filtered out any non-empty project lines and bypassed calling `super()` on them. Consequently, if a line already had an analytic distribution (such as inheriting the project's), the system would skip computing the product's specific distribution rules entirely. This commit resolves the issue by reverting that change, ensuring the base compute method is always called so product-based rules execute correctly. While this means manual analytic entries added before the compute trigger might be overwritten, there is no perfect solution to prevent losing both manual and product distributions. As concluded with the Product Owner in a similar PR for Purchase Orders, we prioritize keeping the product's automated distribution, as it is much harder to manually reconstruct after its removal. The corresponding test is also reverted to its original state to reflect this expected behavior. A small test is added to ensure that the analytic distribution results are unchanged when adding a project to the SO. opw-6279406 **Steps to Reproduce:** - Accounting > Configuration > Settings > Analytics > enable Analytic Accounting - Accounting > Configuration > Analytic Accounting > Analytic Distribution Models - Create a new model with any product (e.g. “Bolt”) and any Analytic Distribution (e.g. “Production”) - Create SO, enable “Analytic Distribution” in filters - Add any customer, add the above product (e.g. “Bolt”), save - Observe that the “Production” Analytic Distribution is automatically populated - On the same SO > Other Info> Project > add (e.g. “Home Construction”) - Then go back to Order Lines and remove the previous SOL and create a new one with the same product > save - Observe that the “Production” Analytic Distribution is not added (although “Home Construction” is) **Current behavior before PR:** - Product analytic distributions are not automatically applied when the Sales Order is already linked to a project **Desired behavior after PR is merged:** - Product analytic distributions are automatically applied even when the Sales Order is linked to a project **Note:** This commit basically ports a fix/revert (https://github.com/odoo/odoo/commit/54852978617cfb2d8c5afdcf80adbf6c0605093c) introduced to the project_purchase module for the same issue. Their commit message is quite detailed in explaining the issue. To quote: >However, due to the agency of the code, we cannot prevent losing *both* manually added analytic distributions and product analytic distribution. After consulting the product owner, we concluded that there was no perfect solution in this case, but we'd rather keep the product analytic distribution, as it is much harder to add it again after its removal. Therefore, this commit reverts the previously mentioned commit, while keeping the refactor it introduced. The referenced initial commit is here: https://github.com/odoo/odoo/commit/3dfa98bd3b9d5ababe3a7548d604e22350023799
Before this fix, if a pivot table with comparison was inserted, it would not be displayed correctly in the spreadsheet. After this fix, the comparison is completely ignored when inserting a pivot into a spreadsheet. The domain of the comparison is ignored too. Task: 6429681 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279150
Original PR description
Before this fix, if a pivot table with comparison was inserted, it would not be displayed correctly in the spreadsheet. After this fix, the comparison is completely ignored when inserting a pivot into a spreadsheet. The domain of the comparison is ignored too. Task: 6429681 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279150
Current behaviour: In the Calendar view (day/week/month scale), when the user's timezone observes a DST transition that starts exactly at local midnight (e.g. Africa/Cairo, since 2023), the day column right after the transition gets the wrong weekday name, duplicating the previous day's name. For ex. it renders "... THU THU FRI ..." instead of "... THU FRI SAT ...", for the week surrounding April 30th 2027. To fix this we add 1 hour to the Date before reading its weekday/day from it, mirrori
Original PR description
Current behaviour: In the Calendar view (day/week/month scale), when the user's timezone observes a DST transition that starts exactly at local midnight (e.g. Africa/Cairo, since 2023), the day…
Current behaviour: In the Calendar view (day/week/month scale), when the user's timezone observes a DST transition that starts exactly at local midnight (e.g. Africa/Cairo, since 2023), the day column right after the transition gets the wrong weekday name, duplicating the previous day's name. For ex. it renders "... THU THU FRI ..." instead of "... THU FRI SAT ...", for the week surrounding April 30th 2027. To fix this we add 1 hour to the Date before reading its weekday/day from it, mirroring the workaround FullCalendar itself adopted for this same bug. It has no effect on any ordinary day (adding 1h to a correct local midnight stays within the same calendar day), and it cannot overshoot into the next day since no real-world DST gap exceeds that margin. Note: This is a known bug (https://github.com/fullcalendar/fullcalendar/issues/7633), fixed in FullCalendar v6.1.17, a major version ahead of the v4.4.0, so the fix can't be applied directly without a full library upgrade. opw-6370140 Forward-Port-Of: odoo/odoo#279343
The SIRET value on the contact form should not be overwritten when registering with the PDP. task-6442186
Original PR description
The SIRET value on the contact form should not be overwritten when registering with the PDP. task-6442186
This commit fixes the verification JSON. For OSS taxes no_sujeto_loc and no_sujeto, CuotaTotal and ImporteTotal must Only include the base amount, not the tax amount. See the chatter in the task for AEAT guidelines. Also removed the validation error blocking no_sujeto_loc taxes with a non-zero amount, since OSS taxes legitimately have one in Odoo accounting (e.g. 22% IT VAT) even though it is excluded from the Veri*Factu json. upgrade :- https://github.com/odoo/upgrade/pull/10799 tas
Original PR description
This commit fixes the verification JSON. For OSS taxes no_sujeto_loc and no_sujeto, CuotaTotal and ImporteTotal must Only include the base amount, not the tax amount. See the chatter in the task for AEAT guidelines. Also removed the validation error blocking no_sujeto_loc taxes with a non-zero amount, since OSS taxes legitimately have one in Odoo accounting (e.g. 22% IT VAT) even though it is excluded from the Veri*Factu json. upgrade :- https://github.com/odoo/upgrade/pull/10799 task-5411766 Forward-Port-Of: odoo/odoo#272068
Steps to reproduce: - Install employees and attendance app - Make sure there are 2 companies - Make user's employee record for Company B, but not A - Make company A the default company for user - Enable "attendances from backend" setting - Click on the attendance dot (systray) Current Behavior: The dot disappears and you can't check in Expected Behavior: You are able to check in Other bug scenario: If you have employee records in both Company A and Company B, you can check in.
Original PR description
Steps to reproduce: - Install employees and attendance app - Make sure there are 2 companies - Make user's employee record for Company B, but not A - Make company A the default company for user - Enable "attendances from backend" setting - Click on the attendance dot (systray) Current Behavior: The dot disappears and you can't check in Expected Behavior: You are able to check in Other bug scenario: If you have employee records in both Company A and Company B, you can check in. However, you can never check in for Company B as the default company is always selected in the server code opw-6392301 Forward-Port-Of: odoo/odoo#278377
### Steps to Reproduce: 1. Navigate to a conversation in the Discuss app 2. Find any attachment or image, or send one 3. Try to download it > 405 error ### Description of the issue/feature this PR addresses: **Issue:** Clicking the download button on an image or attachment within the Discuss module triggers a 405 Method Not Allowed error. This is because the frontend OWL component submits the file request via POST. However, the corresponding Python controllers in `binary.py` are strictly
Original PR description
### Steps to Reproduce: 1. Navigate to a conversation in the Discuss app 2. Find any attachment or image, or send one 3. Try to download it > 405 error ### Description of the issue/feature this PR…
### Steps to Reproduce: 1. Navigate to a conversation in the Discuss app 2. Find any attachment or image, or send one 3. Try to download it > 405 error ### Description of the issue/feature this PR addresses: **Issue:** Clicking the download button on an image or attachment within the Discuss module triggers a 405 Method Not Allowed error. This is because the frontend OWL component submits the file request via POST. However, the corresponding Python controllers in `binary.py` are strictly configured to only accept GET requests. Therefore, the server rejects the download attempt and throws an uncaught RPC exception. **Solution:** I updated the @http.route decorators for the download methods in` binary.py` to explicitly allow POST requests. This allows files to download correctly natively without framework errors. ### Current behavior before PR: Users receive a 405 error saying "Method Not Allowed" whenever they try to download either an image or an attachment from an open conversation in the Discuss app. ### Desired behavior after PR: Users will be able to download any and all images and/or attachments from the Discuss app. opw-6389550 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This RST syntax fix prevents warnings during system update. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
This RST syntax fix prevents warnings during system update. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Description of the issue/feature this PR addresses: Downloading an attachment from the file viewer fails with a `405 Method Not Allowed` error when the attachment belongs to a Discuss channel. I've already submitted a ticket to Odoo: #6430586 Steps to reproduce (on a 18.0 runbot): 1. open Discuss and send an image in a channel 2. click the image to open the file viewer 3. click the download button (either the one in the header or the one in the bottom toolbar) The server rejec
Original PR description
Description of the issue/feature this PR addresses: Downloading an attachment from the file viewer fails with a `405 Method Not Allowed` error when the attachment belongs to a Discuss channel. I've…
Description of the issue/feature this PR addresses:
Downloading an attachment from the file viewer fails with a `405 Method Not Allowed` error when the attachment belongs to a Discuss channel.
I've already submitted a ticket to Odoo: #6430586
Steps to reproduce (on a 18.0 runbot):
1. open Discuss and send an image in a channel
2. click the image to open the file viewer
3. click the download button (either the one in the header or the one in the bottom
toolbar)
The server rejects the request:
```
POST /discuss/channel/1/image/519861?filename=image.png&unique=32647b0f&download=true 405
```
and the user gets a `RPC_ERROR: Arbitrary Uncaught Python Exception` dialog reporting `405 Method Not Allowed`.
Cause: `download()` always issues a POST request, while the routes serving the attachments of a discuss channel only allow GET:
* `/discuss/channel/<int:channel_id>/attachment/<int:attachment_id>`
* `/discuss/channel/<int:channel_id>/image/<int:attachment_id>`
so the request never reaches the controller. Downloading the very same attachment from the attachment card in the conversation still works, because that one is a plain anchor navigation (GET).
This is a regression from fb152985f4b8 ("[FIX] web: download FileViewer files via blob helper"), which routed the file viewer download through `download()` in order to honor the filename sent by the server in the `Content-Disposition` header.
Only 18.0 is affected: saas-18.1 and saas-18.2 do not have the commit that introduced the regression, and from saas-18.3 on, the `urlRoute` override was dropped and channel attachments are served through the standard `/web/content` and /web/image` routes, which are not restricted to GET.
The download is still sent with POST on those branches though, hence forward-porting this up to master.
Current behavior before PR:
Downloading a Discuss channel attachment from the file viewer raises a 405 error and the file is not downloaded. Images and other file types are equally affected.
Desired behavior after PR is merged:
The file is downloaded, keeping the filename advertised by the server. The download is performed with a GET request through `downloadFile()`, which still goes through the blob helper, so the fix of fb152985f4b8 is preserved. This is already the way a file is downloaded from its url in `readonly_file.js`.
Added a test that downloads an image attachment of a channel from the file viewer and asserts the request is a GET on the channel attachment route. It fails before this fix with `POST /discuss/channel/1/image/1`.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr### Steps to reproduce: - Open Website app - Go to Theme > Fonts, select "Borel" as a Google Font (self-hosted, i.e. "Serve fonts from Google" toggle left off) > The text renders shifted upward relative to its container, appearing cut off at the top or off-center inside buttons/badges. ### Cause of Issue: When a Google Font is self-hosted, `Assets.make_scss_customization()` fetches the font's CSS from Google and rewrites only the `src: url(...)` declaration of each `@font-face` block t
Original PR description
### Steps to reproduce: - Open Website app - Go to Theme > Fonts, select "Borel" as a Google Font (self-hosted, i.e. "Serve fonts from Google" toggle left off) > The text renders shifted upward…
### Steps to reproduce: - Open Website app - Go to Theme > Fonts, select "Borel" as a Google Font (self-hosted, i.e. "Serve fonts from Google" toggle left off) > The text renders shifted upward relative to its container, appearing cut off at the top or off-center inside buttons/badges. ### Cause of Issue: When a Google Font is self-hosted, `Assets.make_scss_customization()` fetches the font's CSS from Google and rewrites only the `src: url(...)` declaration of each `@font-face` block to point at Odoo's own `ir.attachment`, leaving the rest of the block untouched: https://github.com/odoo/odoo/blob/5cbcf18762f08439c2dfeed17317a391fe89f074/addons/website/models/assets.py#L82-L103 Script fonts like Borel declare an ascent/descent ratio that is much larger than their visible glyph ink, so any layout that vertically centers text centers around a line box that sits noticeably higher than what's actually drawn on screen. ### Fix: Added a small dict (`GOOGLE_FONT_METRIC_OVERRIDES`) that maps affected font names to their tuned override values, so only fonts confirmed to have the issue are touched and every other Google Font keeps rendering exactly as before. This would also be useful in future use, in case it's needed to manipulate any fonts' aspects. opw-6373800
Before this commit: Deleting a record that uses a filterable selection field with `whitelist_fname` raises a traceback because the record field data becomes undefined during deletion. Steps to reproduce: 1. Install Belgium Accounting (l10n_be). 2. Create a contact and set a Peppol scheme and endpoint. 3. Delete the contact -> a traceback is raised. After this commit: The selection field safely handles undefined record field data during record deletion without causing an error. no-t
Original PR description
Before this commit: Deleting a record that uses a filterable selection field with `whitelist_fname` raises a traceback because the record field data becomes undefined during deletion. Steps to reproduce: 1. Install Belgium Accounting (l10n_be). 2. Create a contact and set a Peppol scheme and endpoint. 3. Delete the contact -> a traceback is raised. After this commit: The selection field safely handles undefined record field data during record deletion without causing an error. no-task
Miscellaneous changes
backport: [19.0](https://github.com/odoo/odoo/pull/266411) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
backport: [19.0](https://github.com/odoo/odoo/pull/266411) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr