Daily updates from Odoo
Tuesday, June 30, 2026
15 changes · saas-18.3
Resolved issues and error corrections
This change prevents the Intrastat report from failing when a company does not have a country set. It corrects the fallback used in the report query so the system can generate the report reliably instead of stopping with a database error.
Original PR description
When there is no `country_id` on the company we get `False`. The generated query then fail at: ``` ... CASE WHEN (code.country_id IS NULL OR code.country_id = false) THEN code.code ELSE NULL END AS commodity_code, ... ``` with: ``` ERROR: operator does not exist: integer = boolean LINE 12: ... WHEN (code.country_id IS NULL OR code.country_id = false) T... ``` Forward-Port-Of: odoo/enterprise#121798 Forward-Port-Of: odoo/enterprise#121608
This change makes an automated website checkout test wait until the page interactions are fully ready before continuing. It reduces random test failures in Odoo’s build system and makes checkout-related validation more reliable.
Original PR description
Before this commit, it could happen that the tour would click too quickly on a button in the step "Billing address is not same as delivery address", before the corresponding interaction was ready. This would then result in the tour failing. To fix this, we could try to have a system to retrigger the events on the interaction, but it feels fragile, and may cause subtle issues in the future. Another way to fix this is to simply make sure that the tour is waiting for all interactions to be ready. This is obviously not perfect, because it kind of hides the reality of the situation: with a slow network connection, a real user may encounter the problem, clicking on something and not seeing anything happens because the js is not ready yet. However, until we find a perfect solution, this commit will solves the random failing builds that we see on the runbot. error-230070 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When employees check in or out from kiosk mode using the barcode scanner, Odoo now uses the browser’s location data instead of a less precise fallback. This makes the recorded attendance location much closer to the actual place where the action happened.
Original PR description
**Issue** Check-in and check-out performed in kiosk mode via the barcode scanner were less accurate than those made via the manual selection. The reported inacurracy between the actual and real locations was several kilometers. **Cause** `attendance_barcode_scanned` was called without a location coming from the browser's geolocation API. In that case, the location was determined by the geoip database https://github.com/odoo/odoo/blob/51f59a293de1e86f66f30257f8fc0c419463d18c/addons/hr_attendance/controllers/main.py#L69-L70 which is generally not as accurate as the location provided by the browser. opw-5889102 Forward-Port-Of: odoo/odoo#270878 Forward-Port-Of: odoo/odoo#251478
This fix ensures that when a POS order is changed and the online payment option is added again, the updated order amount is sent to the server. It prevents customers from paying an outdated total after the order has already been synced once.
Original PR description
When an online payment line is added, the order is synced to the server so the customer can pay it online. This sync was only performed when the order did not yet exist on the server (string id). As a result, once an order had already been synced, modifying it (e.g. increasing the amount) and adding the online payment line again did not push the new amount to the server. opw-6314690 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272572 Forward-Port-Of: odoo/odoo#271542
The Balance Sheet report no longer crashes when an analytic account is selected in a database with Studio customizations on journal items. This fixes a recursion error and keeps the accounting report usable in that setup.
Original PR description
Steps to reproduce ================== - Activate Analytic Accounting. - Go to Accounting > Accounting > Reconcile. - Open Studio. - Add a new many2many field. - Set Journal Item as the related model. - Go to Reporting > Balance Sheet. - Select an analytic account. => RecursionError: maximum recursion depth exceeded Cause of the issue ================== Calling `self.env['account.move.line'].fields_get()` will cause a recursion error. `account.report::_prepare_lines_for_analytic_groupby()` calls `account.move.line::_where_calc()` which in turns calls _prepare_lines_for_analytic_groupby again Solution ======== It turns out we don't actually need to retrieve the groupable attribute, thus bypassing the error. opw-6129149 Forward-Port-Of: odoo/enterprise#116251
This fix removes an incorrect validation that blocked invoices when more than one pension fund tax was set on the same line. It now matches the Italian e-invoicing rules, so affected invoices can be sent and printed without errors.
Original PR description
### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_withholding 2. Switch to IT company 3. Create 2 taxes with a Pension fund type set (in Advanced Options) 4. Create an invoice…
### Steps to reproduce the issue: 1. Download Accounting and l10n_it_edi_withholding 2. Switch to IT company 3. Create 2 taxes with a Pension fund type set (in Advanced Options) 4. Create an invoice and set on the same line the 2 taxes created 5. Click on send and print and see the error: Invoices must have at most one Pension Fund tax set per line. (even if it's not true) ### Cause of the issue: The following function check how many taxes we have per line but this limit is incorrect because it is accepted by the Italian electronic invoicing specifications to have also more than 1 tax. https://github.com/odoo/odoo/blob/bd095fe286930acc54d85bdf7f92af15569f5b82/addons/l10n_it_edi/models/account_move.py#L1268-L1273 ### Reference documentation: 1. [Art. 10 della Legge n. 183_2011, successivamente integrato dal D.L. n. 1_2012 (art. 9-bis)..pdf](https://github.com/user-attachments/files/29056003/Art.10.della.Legge.n.183_2011.successivamente.integrato.dal.D.L.n.1_2012.art.9-bis.pdf) 2. Following image: <img width="823" height="580" alt="estrattoEppi" src="https://github.com/user-attachments/assets/e79be16f-651e-467a-84f4-8400185ceea4" /> opw-6264685 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272874 Forward-Port-Of: odoo/odoo#269456
When opening the full message composer, recipients that only have an email address and no linked contact are now ignored instead of causing an error. This prevents a crash when users expand the message window and click the recipient tag, while keeping valid contacts available as before.
Original PR description
The full composer builds default_partner_ids by doing recipient.persona.id over allRecipients. When a recipient is not linked to a partner, the chatter input inserts it with persona: false here:…
The full composer builds default_partner_ids by doing recipient.persona.id over allRecipients. When a recipient is not linked to a partner, the chatter input inserts it with persona: false here: https://github.com/odoo/odoo/blob/28c11a068b2ecf521f8ba1da271ebee24f5345ae/addons/mail/static/src/core/web/recipients_input.js#L151 false.id is undefined, so the wizard gets a bad id and clicking the recipient tag crashes with `Invalid ids list: false`. The persona is false because /mail/partner/from_email returns no partner for unresolved emails when the user does not have base.group_partner_manager. That matches the gate _prepare_post_data already uses for the simple post flow: https://github.com/odoo/odoo/blob/28c11a068b2ecf521f8ba1da271ebee24f5345ae/addons/mail/controllers/thread.py#L153,L155 The full composer just was not handling that case. Filter out persona-less recipients from default_partner_ids so the wizard only sees real partner ids. The full composer now drops them the same way the simple post path already does. Steps to reproduce: 1. As Administrator, create a user with the Sales group only (no Contact Creation). 2. Log in as that user. 3. Open a CRM lead whose Email is set but Customer is empty. 4. Click Send message. 5. Click the expand icon to open the full composer. 6. Click the recipient tag in the To field. => Recipient shows as Unnamed and clicking it raises an RPC error. Ticket [link](https://www.odoo.com/odoo/project.task/5974081) opw-5974081 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#251780
This update corrects how payroll deductions are matched to attachment codes. It prevents partial text matches from selecting the wrong deduction line, which helps ensure employee payroll calculations are accurate.
Original PR description
Currently we have for deduction_codes, attachments in slip.salary_attachment_ids.grouped( lambda x: x.other_input_type_id.code ) salary_lines = slip.line_ids.filtered( lambda r: r.code in deduction_codes ) I believe the intent in the second line is to check either r.code is in deduction_codes. This assumes deduction codes is an array. the issue is that it is not an array. The return of "grouped" on the first line implies that deduction_code will always have a string that describe which is the deduction_code, and attachment_ids will be an array Now the bug happens on the comparison "in" on the second line. Since we are matching against a string, suposing we had 2 codes like TEST_CODE and TEST, both would match positively using "in" changing "in" to "==" will ensure we match codes properly opw-6206134 Forward-Port-Of: odoo/enterprise#121022
The product UNSPSC list now correctly includes code 10171500, which corresponds to Organic fertilizers and plant nutrients. This fixes a missing option in product accounting so users can select the right classification when needed.
Original PR description
The code 10171500 - Organic fertilizers and plant nutrients wasn't appearing. In the file that has the unspsc product codes this one was set to False. Steps to reproduce: - Activate module product_unspsc. - Go to product > accounting. - Verify that this code is not listed. Ticket [link](https://www.odoo.com/odoo/project.task/4461974) opw-4461974 Forward-Port-Of: odoo/enterprise#121914
This update prevents popup content from being inserted inside another popup, which could create confusing nested popups on the website. It also fixes the cookie bar layout so buttons keep the correct spacing when editors choose the discrete style, improving the page appearance for visitors.
Original PR description
Steps to reproduce: - Enable the cookies bar in the website settings. - Go to the website and enter edit mode. - Open the cookies bar from the invisible elements panel. - Open the snippet dialog. => Popup snippets are still visible even though they cannot be dropped inside another popup. Before this commit, popup snippets could still use dropzones located inside another popup in some cases, such as cookie bars or newsletter popups. After this commit, when the dragged snippet is a popup, dropzones inside an existing popup are filtered out, so nested popups cannot be inserted. task-6251151 Forward-Port-Of: odoo/odoo#267488
This update brings the spreadsheet component to a newer version with a few user experience and display fixes. It improves color selection behavior, adds better support for sheet tab colors, and makes fonts render more consistently on Linux, helping spreadsheets look and work more reliably across environments.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/c80dc2e26b [REL] 18.3.53 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/c80dc2e26b [REL] 18.3.53 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/a075f2eeae [FIX] sheet: close the color picker on external click [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/7fd938ed02 [FIX] sheet: add sheet tab color to custom colors [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/f706fda1b0 [FIX] Fonts: Add default font for Linux [Task: 6328646](https://www.odoo.com/odoo/2328/tasks/6328646) https://github.com/odoo/o-spreadsheet/commit/d8da52b51c [IMP] package: add runbot script [Task: 6316690](https://www.odoo.com/odoo/2328/tasks/6316690) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
The website language selector now includes descriptive text for flag images when the flag is the only visible indicator. This makes the selector easier to understand for screen reader users and gives search engines clearer context.
Original PR description
Steps to reproduce: 1. Enable the language selector in the website header. 2. Enable the "Inline" and "Flag" options. 3. Inspect the flag images rendered in the inline variant. Issue: Flag images in the list items have an empty `alt=""` attribute in "Flag only" mode, where the flag is the sole visual indicator of the language, making the selector inaccessible to screen readers and providing no context for search crawlers. Expected behavior: Inline + Flag should have a descriptive ALT tag since there is no adjacent text or code to identify the language, the flag is not decorative. opw-6246464 Forward-Port-Of: odoo/odoo#271362
Creating payslips from a parent company now correctly includes employees who belong to its branch companies. This fixes a case where some employees were missing from the employee selection list, helping payroll teams process Belgian branch payslips consistently.
Original PR description
Bug: employees registered on branch companies don't appear in the
employee_id field when creating a payslip from the parent company.
Reason: the domain used ('company_id', '=', company_id) which only
matches the exact company, not its children.
Solution: replaced '=' with 'child_of' to include all descendant
companies in the hierarchy.
task - 6299634
Forward-Port-Of: odoo/enterprise#121193
Forward-Port-Of: odoo/enterprise#120974This fix ensures subscription rules are enforced whether a recurring product is added manually or through the product catalog. It prevents orders from being saved without a subscription plan when one is required, avoiding inconsistent behavior and unexpected errors later in the sales process.
Original PR description
Steps to reproduce: --------------------------------------- 1. Install Subscription Module 2. Create and Confirm SO with no recurring plan and a non-recurring product 3. Add a recurring product >…
Steps to reproduce: --------------------------------------- 1. Install Subscription Module 2. Create and Confirm SO with no recurring plan and a non-recurring product 3. Add a recurring product > Save SO > Observe the User Error 4. Now add the same recurring product through Catalog View Observation: --------------------------------------- No User Error raised stating 'You cannot save a sale order with recurring product and no subscription plan.' Issue: --------------------------------------- When you manually add a line and click 'Save', the constraint (`_constraint_subscription_plan`) is triggered and raised `UserError` https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/sale_subscription/models/sale_order.py#L176-L177 When you add a product via the catalog view, it calls `_update_order_line_info` which directly creates/updates order lines, Which do not trigger the python constraint. https://github.com/odoo/odoo/blob/ef9772bba1515bdaf5410c3af5a3e395f562d513/addons/sale/models/sale_order.py#L1926-L1933 Solution: --------------------------------------- Two private helpers are introduced: * `_is_exempt_from_subscription_plan_check`: single source of truth for all exempt states (draft, cancelled, upsell, and legacy upgrade orders). * `_check_recurring_plan_mismatch`: raises a `UserError` when the order has or will have a recurring product but no subscription plan, reusing the exemption helper so both call sites stay in sync. `_constraint_subscription_plan` is refactored to delegate to these helpers, and `_update_order_line_info` is overridden to call `_check_recurring_plan_mismatch` before the catalog update is applied, ensuring consistent validation across both entry points. opw-6194865 Forward-Port-Of: odoo/enterprise#121886 Forward-Port-Of: odoo/enterprise#117879
Expense reports now enforce limits on attached files, helping keep submissions within expected size and number constraints. This reduces the risk of overly large expense claims and improves reliability when employees submit expenses.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272732