Tuesday, December 2, 2025
13 changes · saas-18.2
Resolved issues and error corrections
The employee creation button is now hidden from administrators who do not have HR permissions. This prevents users from reaching an action they are not allowed to complete and avoids confusing access error messages.
Original PR description
**Version:** - 17.0 **Steps to reproduce:** - Make sure Marc Demo is an Administrator but has no Employees (HR) access rights. - Log in as Marc Demo. - Go to Settings → Users → Create a new user. - Enter a name and email, then Save. - You’ll see the "Create Employee" button it appears even though the user has no HR rights. - Click it → an Access Error occurs. **Isuue:** - The "Create Employee" button is visible for users who don’t have HR permissions, causing an access error when clicked. **Solution:** - Hide the "Create Employee" button for users without HR access by adding the correct group restriction. task-5212464 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#235258
This fix ensures Odoo can correctly neutralize Peppol connection settings even when a required configuration entry is missing. It helps prevent leftover Peppol settings from remaining active in copied or neutralized databases.
Original PR description
There can be some siutations where you can not have the key account_peppol.edi.mode while having a connection. But the neutralize only updates and so, if the key is not present, it does nothing. So change it to insert the key if no present --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#238184
This fix updates Argentine localization demo data so the module can be installed successfully when using Python 3.10. It prevents an installation failure caused by incompatible formatting in demo tax references, improving reliability for demo and test environments.
Original PR description
**Steps to reproduce:**
- Use Python 3.10
- Install l10n_ar
**Issue:**
The installation fails with a SyntaxError.
**Cause:**
Some demo data use the following format for the taxes definition:
`ref(f'account.{ref('base.company_ri')}_ri_tax_vat_0_compras')`
However, in python 3.10, a quote cannot be used inside f''.
opw-5376152
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#238186Email marketing test messages now generate their “view online” preview link using an existing mailing contact instead of accidentally using the sender’s user ID. This prevents broken preview links when a matching contact record does not exist, making test emails more dependable before campaigns are sent.
Original PR description
In the email marketing, when you add "view_online" and dynamic placeholder "object.name", and try doing a test email, it creates a url token for the "view online" with the res_id as the user's id which grabs the record from the mailing_contact with that res_id. So, in case the mailing_contact with the res_id is deleted, the "view_online" gives you error saying record with id "res_id" cannot be find. Our fix is to search the mailing_contact and grab the id of the first record. This fix updates the code from this commit: [8a9981e](https://github.com/odoo/odoo/commit/8a9981e78a438ceb53a4fdc0445ebed2170c6624) opw-5049654 Forward-Port-Of: odoo/odoo#232440
This fixes a website header issue where the header could disappear unexpectedly after users quickly scrolled back to the top with the Fade Out scroll effect enabled. The change keeps the header behavior consistent, improving the editing and browsing experience for website pages.
Original PR description
Steps to reproduce the issue: - Go to Edit mode - Click on the Header - In the "Scroll Effect" dropdown, select "Fade Out" - Drop some snippets to allow scrolling on the page - Scroll down then scroll to top QUICKLY The timeout to hide the header after the fade animation end is not cleared. Therefore, after 400ms, the header is shifted upward and disappears, even if the user scrolled up and made the header reappear. task-5357217
This fix prevents discounts from purchase order lines from being automatically applied when importing them into sales orders. It helps ensure sales orders start with the expected zero discount and avoids unexpected pricing changes for users.
Original PR description
Discounts are always sent by `_retrieve_line_vals` in `account_edi_ubl_cii` In Sale orders, discounts aren't expected to be automatically imported from the purchase order, it should always be 0. `test_so_import_product_from_po` didn't use to fail because discount wasn't checked until the recent refactor https://github.com/odoo/odoo/pull/190310 Check was added in 18.0 to avoid this error in the future. Steps to reproduce: - Disable discount in sale app - Create a PO with a discount on any POL - Enable discounts - Import SO from PO Issue: Discount is added to the Sale order lines. Runbot: 232724 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#237743
The website cookie consent button now responds correctly even when its text size has been customized in the editor. This prevents visitors from seeing the cookie bar disappear without their consent choice being properly applied, helping embedded content such as maps load as expected.
Original PR description
The "I agree" button in the cookie bar would stop working if its font size was changed. Steps to reproduce: =================== - Enable the cookie bar in website settings. - Go to the website and…
The "I agree" button in the cookie bar would stop working if its font size was changed.
Steps to reproduce:
===================
- Enable the cookie bar in website settings.
- Go to the website and enter Edit mode.
- Click on the cookie bar.
- Select the "I agree" button's text and change its font size.
- Save and visit the page as a guest (e.g., in a private window).
- Click on the "I agree" button text.
-> The maps doesn't show and the Cookie bar disappear.
Cause:
======
Applying a font size to the button's text wraps that text within a `<span>` element.
The event listener for accepting cookies is attached to the elements with IDs `#cookies-consent-essential` and `#cookies-consent-all`. in that case it ID `cookies-consent-essential` exist in the parent element. However, the code was checking the ID of `event.target`. When a user clicks directly on the newly created
`<span>`, `event.target` refers to the `<span>` itself, not the element who owns the event.
Since the `<span>` does not have the required ID ('cookies-consent-all'), the condition to accept the cookies was false.
Solution:
=========
Use `event.currentTarget` instead of `event.target`.
Unlike `event.target`, `event.currentTarget` always refers to the element to which the event handler was attached—in.
check:
https://developer.mozilla.org/en-US/docs/Web/API/Event/currentTarget
opw-5004645
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#237786This fix makes automated test retries correctly recognize more logged error details, including tracebacks that appear directly in messages. It also avoids unnecessary failures when a browser connection closes during testing, helping builds complete more reliably.
Original PR description
The auto-retry is supposed to catch error logs as well as tracebacks. In some cases a traceback is logged as a message, and not as a logger arg, bypassing the replace already in place. This pr simply replaces the traceback string in the message as well. Build error [234619](https://runbot.odoo.com/odoo/runbot.build.error/234619) Also fixes OSError while handling request paused Build error [229906](https://runbot.odoo.com/odoo/runbot.build.error/229906) Forward-Port-Of: odoo/odoo#238133
The POS digest email link now opens a report matching the uninvoiced orders used in the digest metrics. This prevents users from landing on an empty report when their POS activity has not yet been invoiced.
Original PR description
The POS digest email shows metrics based on *uninvoiced* POS orders, but the “Open Report” link in the digest opens a report filtered to *invoiced* orders only. As a result, when all POS orders are uninvoiced, the link leads to an empty view. ### Steps to reproduce 1. Ensure that all existing POS orders are **uninvoiced**. 2. Enable Developer Mode, then navigate to **Settings → Technical → Email → Digest Email**. 3. Open any digest and click **"Send Now"** to generate a new digest email. 4. Open the generated digest and click the **POS report** link. This results in a blank page. ### Cause There is a mismatch between: * the digest computation (showing only uninvoiced orders), and * the report view called by the digest link (showing only invoiced orders). ### Fix Ensure the POS report shows unvoiced orders. opw-5087701
Users are now only assigned document upload activities when they have the required access rights to complete the upload. This prevents confusing errors when users without sufficient permissions try to upload documents from an activity.
Original PR description
Step To Reproduce: - install Project - login with admin and open any Project settings, say Project 1. - create a upload document activity for 'marc demo' - ensure marc demo has 'User' access for…
Step To Reproduce: - install Project - login with admin and open any Project settings, say Project 1. - create a upload document activity for 'marc demo' - ensure marc demo has 'User' access for project - login with marc demo - open same project (kanban card -> view) - upload a document for the created activity Observation: - Traceback ``` TypeError: Cannot destructure property 'id' of '(intermediate value)' as it is undefined at Activity.onFileUploaded ``` Cause: - upload request to `/mail/attachment/upload` , calls `mail_attachment_upload` which then tries to access thread for 'write' mode, 'project.project ' model . - as marc demo does not have write access to this model, no thread is returned - so `NotFound()` is raised https://github.com/odoo/odoo/blob/322c6d0468bf79e9d29e1375c49aa13d4a7b7a67/addons/mail/controllers/attachment.py#L48-L55 Fix: - we check if selected user has appropriate rights or not for upload activity opw-5160132 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#234936
This update fixes a bug that occurred when users duplicated approvers within an approval request. The duplication caused a system error, preventing users from accessing the request. The fix ensures that duplicate approvers are handled correctly, eliminating the error and improving the approval process stability.
Original PR description
When User duplicates the approver for any approval request and tries to open that approval request, A traceback will appear. Steps to reproduce the error: - Activate the developer mode - Go to Approvals > Create a new approval request > add any approver > Save - Click on the ``View`` button in the approver line - Now, In the Form view > Actions > Duplicate - Go back to that approval request through breadcrumbs Traceback: ``` ValueError: Expected singleton: approval.approver(1, 3) ``` https://github.com/odoo/enterprise/blob/83b6c0e1c052b08bd23c5e009773b5a3148ddeec/approvals/models/approval_request.py#L270 When the customer duplicates the approver, ``user_id`` will be also duplicated. So, Now Same User is linked with multiple approver. So, It will lead to the above traceback. sentry-6642840799 Forward-Port-Of: odoo/enterprise#87164
This update resolves an issue preventing payroll officers from accessing salary offers. The fix prevents access errors when opening offers by intelligently handling permission restrictions related to candidate records. This ensures payroll officers can continue to perform their duties without needing recruitment rights.
Original PR description
steps to reproduce: - Install l10n_be_hr_contract_salary - Log in as a payroll officer (without recruitment rights) - Go to Payroll > Contracts > Offers - Open any offer - Notice an 'Access Error' appears: You are not allowed to access 'Candidate' (hr.candidate) records. cause: The module tries to read `employee_id.candidate_id.partner_id` in offer computations. Since payroll officers lack recruitment rights accessing `hr.candidate` triggers an access error. fix: Wrap candidate access in try/except to handle missing permissions. - If accessible, candidate partner data is used as before. - If not accessible, skip without raising an error. This allows payroll officers to open and generate salary offers without requiring recruitment rights. task - 5039712 Forward-Port-Of: odoo/enterprise#95869
This update optimizes how Odoo calculates mobility budgets for Belgian employees. By switching to a more efficient search method, the calculation process is now significantly faster, particularly for larger datasets. This improves the overall performance and responsiveness of the HR module.
Original PR description
- optimized the method `_compute_l10n_be_mobility_budget_amount` to use binary search instead of linear loop task-id: 5173389 Forward-Port-Of: odoo/enterprise#99505