Daily updates from Odoo
Monday, July 28, 2025
23 changes · master
Security fixes and vulnerability patches
A new shared helper standardizes how web links are combined across several Odoo apps and integrations. This reduces the risk of malformed or manipulated links, helping protect redirects, API calls, and shared URLs without changing everyday user workflows.
Original PR description
This commit adds a default odoo url joining helper function that basically does the same as base.rstrip('/') + '/' + url.lstrip('/'), but with schema, hostname, path traversal and better fragments/query handling.
Most url parsing libraries like urllib and werkzeug (at least try to) follow RFC 3986 which explains in detail how to do relative resolutions. But developers usually expect simple concatenation behaviour like "api.example.com/v1/" + endpoint, but by passing a user-controlled data to urljoin, they end up giving room for people to tinker with things nobody ever expected were possible, which can lead to some nasty stuff. So the motivation here is to give a function that is somewhat better aligned with what devs expect it to do.
Community: https://github.com/odoo/odoo/pull/219623
task-3792184New functionality added to Odoo
VoIP users get better call history, search, and reporting tools, plus a new way to record, transcribe, and summarize calls using AI. This can help teams review customer conversations faster and keep clearer records directly linked to calls.
Original PR description
# WIP Dependency on other PRs in progress Let's make it messy, hoping it will speed up work 🤞  ATM: Only the last commit is here to stay. Rest of them will get in merged beforehand.
Odoo Sign now integrates with emSigner so users can digitally sign PDFs using Aadhaar-based verification and OTP. This enables compliant digital signing through an external gateway, with some workflow limits such as one Aadhaar signer at a time and no bundle signing support.
Original PR description
**Overview**: - This PR integrates Odoo Sign with **emSigner**, a secure digital signing gateway that supports **Aadhaar-based eSignatures**. - emSigner allows you to digitally sign a PDF by sending…
**Overview**: - This PR integrates Odoo Sign with **emSigner**, a secure digital signing gateway that supports **Aadhaar-based eSignatures**. - emSigner allows you to digitally sign a PDF by sending an HTTPS POST request with required data. - Once the signing is complete, it returns the signed PDF in base64 format. **purpose**: - Connect Odoo with emSigner to enable digital document signing. **Integration Steps**: - Step 1: Generate unique Session Key for each request - Step 2: Create JSON data and encrypt using unique Session key (Step 1) - Step 3: Generate Hash of data - Step 4: Encrypt generated Hash (Step3) with the unique Session Key (Step1) - Step 5: Encrypt the unique Session Key (Step 1) using public key of the emSigner - Step 6: HTTPS Post request with step2+step4+step5 output - Step 7: Decrypt encrypted signed data (Step6) with session key (Step1) **Workflow**: - User will upload pdf on Odoo sign. user need to set auth method to emSigner. - When the user clicks Validate& send button, they are redirected to emSigner for Aadhaar verification. - The user enters their Aadhaar number, receives an OTP on their registered mobile, and completes verification. - After successful Sign, emSigner redirects the user back to Odoo with the signed PDF. **JSON data**: - Here we have listed some of the important parameters. - We need to send the PDF name, filetype(pdf), base64 data of the PDF, signature position where the signature will be added when user will sign. - You can refer to the documentation for a detailed explanation of the payload. **Response from emSigner**: - It will return a base64 data of pdf after digitally signing the pdf, and attaching digital certificate for signature integrity to all the signature positions we have provided in json data. **Known limitation**: - As emSigner takes only one pdf at a time, it will not work with bundle signing flow. - After successful signing, emSigner will return pdf base64 data with the digital signature attached, so writing anything after signing can break certificate integrity. - On emSigner other fields like name, email, company, selection etc is not supported, which is supported by odoo. As we need to write those values from odoo side which will break the certificate. - It allows having multiple signatories, we need to pass `isCosign=True`, but again the issue will arise when writing odoo fields data on pdf will result in certification lose. - Currently, due to this issue, we are allowing only one signer to use Aadhaar-based signing (via emSigner). Any other signers will use the regular signing method However, the regular signers must complete their signing before the Aadhaar signer can sign. - To make this work, we have set a default signing order whenever an Aadhaar (emSigner) method is used. - When using eMSigner, the final signed document will not include the certificate from Odoo. IAP PR: https://github.com/odoo/iap-apps/pull/1009 **Emsigner Documentation** : https://developers.emsigner.com/signer-gateway/api-reference/signing-documents.html task-4164342
Enhancements to existing features
A Web Studio automated test was updated to reflect a recent platform change in how field information is handled. This helps keep quality checks aligned with the product and reduces the risk of false test failures during development.
Original PR description
This commit adapts a test to the addition of the copy attribute in fields_get made in https://github.com/odoo/odoo/pull/219253 task-4920305
Added a button in the website settings that redirects to the website generator configurator. The goal is to have a standard way to import a website without necessarily it being part of the onboarding flow. closes odoo/enterprise#88334 Forward-Port-Of: odoo/enterprise#90071
Original PR description
Added a button in the website settings that redirects to the website generator configurator. The goal is to have a standard way to import a website without necessarily it being part of the onboarding flow. closes odoo/enterprise#88334 Forward-Port-Of: odoo/enterprise#90071
Online orders received through UrbanPiper now calculate and display taxes more accurately based on the restaurant’s country and fiscal setup. This helps businesses avoid tax mismatches, especially for Indian GST rules where aggregator-paid and merchant-paid taxes are handled differently.
Original PR description
**: pos_urban_piper_zomato, pos_urban_piper_swiggy After this commit: --- - For orders outside India, price are received from UrbanPiper as tax-inclusive. Odoo now properly computes the unit price and applies taxes based on the fiscal position. - For India, special handling is implemented: - 5% GST is collected and paid by the aggregator, so only this tax is added via fiscal position mapping. - For other tax rates like 12% or 18%, the merchant is responsible, so these must be configured explicitly in the fiscal position. Note: --- - If a user does **not** want to receive a particular tax in the order, they must manually add a line for it in the fiscal position. Task: 4862417 Forward-Port-Of: odoo/enterprise#91036 Forward-Port-Of: odoo/enterprise#88118
Helpdesk ticket updates made from the customer portal now show the customer as the author in the chatter instead of OdooBot. This makes ticket history clearer for support teams, while still using OdooBot when no customer is linked.
Original PR description
- When closing the ticket form portal, the customer's name appears in the chatter instead of OdooBot. - When the ticket is closed by a public user, the customer appears in the chatter. - When no customer is specified, the OdooBot will appear in the chatter. task-4809115
The editing toolbar now offers font color instead of strikethrough in compact mode, making common formatting easier to access. Knowledge article formatting options are also shown more selectively, so users only see relevant paragraph or normal text choices based on the editor context.
Original PR description
I. This PR replaces strike through with font color in compact toolbar. II. This PR replaces the baseContainer config with baseContainers, a list that defines the allowed base containers. The first element of the list now serves as the default, equivalent to the previous baseContainer. This change enables conditional display of "Normal" and "Paragraph" options in the toolbar. For example, if baseContainers only includes "DIV", only the "Normal" option will be shown. Similarly, if it only includes "P", only the "Paragraph" option will be shown. community-https://github.com/odoo/odoo/pull/216884 task-4770922
Users now see a confirmation popup when moving documents to a folder that would change who can access them. This helps prevent accidental permission changes and makes folder access implications clearer before the move is completed.
Original PR description
Purpose ======= Making sure people are aware of the access rights change when moving documents to a different folder. Specification ============= When moving documents to a target folder, add a confirmation popup specifying the target folder access rights if making the move will impact the dragged documents access rights. Task-4822908
The database expiration message now reflects the updated timing based on the next invoice date, giving customers a clearer payment window. This helps encourage earlier payments and reduces last-minute renewal risk.
Original PR description
Previously, the database expiration date was set to the same date as the expiration field, which is now defined as 15 days after the next invoice date. Issue: Users tend to wait until the last minute to pay. This improvement aims to better handle expiration timing and encourage timely payments. TaskID: 4384877 Forward-Port-Of: odoo/enterprise#90931 Forward-Port-Of: odoo/enterprise#90664
Resolved issues and error corrections
The WhatsApp module’s automated checks were updated to match a related change that now includes timezone information for contacts. This keeps internal validation aligned with the latest contact data and helps prevent false test failures during releases.
Original PR description
Purpose of this commit: The fields which are passed in res.partner have been added a new field tz, adapt the conflicting testcases accordingly. community: https://github.com/odoo/odoo/pull/210094 task-4613148
Commission plans can now be saved safely when an end date is cleared or missing. This prevents an error that interrupted users while editing existing commission plans, improving reliability for sales compensation setup.
Original PR description
Currently, an error occurs when clear the date_to field from an already created record. Steps to Reproduce: - Install the `sale_commission` module. - Go to `Commission Plans` and create a record. -…
Currently, an error occurs when clear the date_to field from an already created record. Steps to Reproduce: - Install the `sale_commission` module. - Go to `Commission Plans` and create a record. - Now, clear the `date_from` field and save. `TypeError: '>' not supported between instances of 'bool' and 'datetime.date'` This error occurs when we clear the date_to field from an already created record. The error started occurring after https://github.com/odoo/enterprise/commit/926c8f041b51a04f0153be27cfcc8658a07be5b0 this commit that introduced the daterange widget for the date_from field. And when we clear the date_to field and try to save, it triggers the constraint [1] and raises the error. [1] https://github.com/odoo/enterprise/blob/377321fd7e7b1b2026734b75c79c74c8947e2e6c/sale_commission/model/commission_plan.py#L64 This commit ensures that the record is saved only if the date_to field is also present in the record. sentry-6710699656 Forward-Port-Of: odoo/enterprise#88769
The disallowed expenses reports now create unique identifiers for lines with a zero or missing rate. This prevents duplicate-key errors and helps users open the report reliably in affected expense and fleet scenarios.
Original PR description
Before this **PR**: When only the account_disallowed_expenses module was installed, the report failed with a duplicate key error if a line had a 0 rate or no rate at all. This was because such child lines were assigned the same line_id as their parent. After this **PR**: Lines with a 0 or no rate have the parent account appended to their line_id to ensure uniqueness and avoid key collisions. Forward-Port-Of: odoo/enterprise#90236
Balance sheet reports in multiple country-specific Odoo localizations now correctly support the Split Horizontally option. This fixes missing report configuration so users in affected countries can view balance sheet sections side by side as intended.
Original PR description
Before this PR: Some localizations (e.g., Switzerland, Germany and others) were missing the `horizontal_split_side` field in their report templates to support the `Split Horizontally` feature in the balance sheet report. After this PR: Balance sheets in these localizations now properly support the `Split Horizontally` feature after adding the missing `horizontal_split_side` field to their report templates. Task: 4791197
Customer statement emails and reports now handle selected contacts that do not have a name. This prevents scheduled sending from failing, so businesses can continue sending statements even when some customer records are incomplete.
Original PR description
**PROBLEM** In the accounting app, when selecting multiples customers, if one of them doesn't have a name, the cron sending the report will traceback. **STEP TO REPRODUCE** - On a clean db, install…
**PROBLEM** In the accounting app, when selecting multiples customers, if one of them doesn't have a name, the cron sending the report will traceback. **STEP TO REPRODUCE** - On a clean db, install the account_reports module - From the accounting app, create a new company customer (Customers/Customers) - From that new company customer form view, add a new contact of type "other" and don't specify a name for it. - Create an invoice for the company - From the customer list view, select all, and trigger the action "Open Customer Statements" - Send -> Print and Send - Check the console, the cron task should traceback on the template **CAUSE** In accout_report.py, we get the name of each selected partners, and we don't check if the name doesn't exist. In the template `pdf_export_filters`, we try to join all the name in a string, it fails because one of the name isn't a string (its value is False because it doesn't exist on the partner record). **FIX** When getting the partners names, filter out the partners without names. opw-4916660 Forward-Port-Of: odoo/enterprise#90154
Uploading an attachment from the chatter in Documents no longer creates a temporary progress card or row in the main kanban or list view. This keeps folder and document views cleaner and avoids confusing users with upload status items that should not be shown there.
Original PR description
Step to reproduce: - In Documents, open the chatter either on a folder or a document. - Upload an attachment through the chatter. - You will see the upload kanban card / list row showing the progression. There should be no visual in kanban/list views showing the progression. Task-4863051 Forward-Port-Of: odoo/enterprise#90836 Forward-Port-Of: odoo/enterprise#87410
This fixes when company and website fields appear in Documents, so users only see them when relevant and permitted. Internal users see these fields only in multi-company or multi-website setups, while non-internal users do not see them.
Original PR description
Fixes the visibility of the `website_id` and `company_id` fields. These fields other than hidden from non internal users, they should be visible to internal users only when multiple websites or multiple companies are available, respectively. Partial revert of: ddf102e5 task-4505668 Forward-Port-Of: odoo/enterprise#90965 Forward-Port-Of: odoo/enterprise#86181
This fix prevents an error when Belgian reporting data exists for a shared contact and the Inventory app is installed afterward. It keeps Belgian 281.50/325 tax reporting records valid while avoiding unnecessary company consistency failures, improving reliability for Belgian accounting workflows.
Original PR description
### Steps to reproduce: - Install l10n_be_reports & account_accountant. - Switch to "BE Company CoA" company. - Add "281.50" tag to "YourCompany" contact. - Accounting > Configuration > Accounting >…
### Steps to reproduce: - Install l10n_be_reports & account_accountant. - Switch to "BE Company CoA" company. - Add "281.50" tag to "YourCompany" contact. - Accounting > Configuration > Accounting > Chart of Accounts > Add "281.50 - Commissions" tag to 600000 account in CoA. - Create a Vendor Bill for partner "YourCompany" selling "[E-COM11]". Date it sometime in 2024 and confirm. - Go to Accounting > Reporting > Open 325 Forms. - Create a new form for 2024. - Verify that there is a line for "YourCompany" in the form and generate the XML. - Try to install Inventory. #### > Traceback due to a company inconsistencies. ### Cause of the issue: When creating the new `l10n_be.form.281.50` form for 2024, we create a record for "BE Company CoA" and which `partner_id` is the `res.partner` "YourCompany" which does not belong to any company (and hence is accessible from any). However, on the `forms_281_50` related field of the `res.partner` model is `check_company=True`: https://github.com/odoo/enterprise/blob/bc36a68b68c3d0296ee18c3a121b029dd418f430/l10n_be_reports/models/res_partner.py#L15-L23 Currently, this did not matter because we did no call of the `_check_company`. But if we where to launch a call of the `_check_company` on "YourCompany" `res.partner` we would raise a company error. Now, when you install stock 2 things happen and provoke this call: 1) The `res.partner` model becomes `_check_company_auto`: https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/res_partner.py#L8-L10 2) We create a warehouse for "Your company and update the `partner_data` https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/stock_warehouse.py#L143-L145 https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/stock_warehouse.py#L315 However, the `property_stock_customer` and `property_stock_supplier` are `check_company` related fields: https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/addons/stock/models/res_partner.py#L12-L17 Therefore, writing on them for a `_check_company_auto` record will launch a call of the `check_company` for all the fields of the record (including the already inconsistent `forms_281_50`): https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/odoo/models.py#L3780-L3781 https://github.com/odoo/odoo/blob/b7dbf15aa8116e51708bd51b8dda9bd12bba0a9e/odoo/models.py#L3867-L3868 ### Fix: We loosen the company check on the `forms_281_50` to not rely on the `_check_company` since the current workflow lead functionally to valid record data's that will always be considered invalid by this method. opw-4845434 Forward-Port-Of: odoo/enterprise#89590
Belgian point of sale configurations using a blackbox now load the required fiscal data category automatically without adding it to the user-managed list of limited categories. This keeps category settings cleaner while preserving the required fiscal compliance behavior.
Original PR description
Before this commit, we added automatically the fiscal data module category to the list of limited categories for config with blackbox in order to be sure to load it. Now we load it automatically without the need of adding it to the list of limited categories. Forward-Port-Of: odoo/enterprise#91048
Project profitability now includes budget lines linked through the correct analytic plan, even when a project's account is associated with a different plan after migration. This prevents valid budget information from being hidden, giving users a more complete view of project performance.
Original PR description
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have…
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have not adapted the code in project profitability, to take those changes into account. A problematic situation could be the following: 1. We have a project where the account "X" is set to the main project plan (the first one) "Projects" BUT the account "X" actually belongs to the analytic plan "Departments" (yes, it's possible that there is a mismatch between the project plan and the analytic plan, especially after the 18.0 upgrade where "analytic_account_id" just became "account_id", no matter in which plan it was). 2. We have a budget line linked to the account "X" for the plan "Departments". 3. We want to display the budget lines in project profitability, but this line does not appear. That's because we currently only look for the budget lines belonging to the analytic plan "Projects" aka the main/first plan, that match the account "X" of the project. But as account "X" actually belongs to the analytic plan "Departments", no budget lines are found. task-4901400 version-18.0 Forward-Port-Of: odoo/enterprise#88658
This fixes a small data naming mismatch in the Belgian point-of-sale fiscal device integration. It helps ensure the blackbox device driver reads fiscal responses consistently, reducing the risk of processing errors during POS operations.
Original PR description
We missed a 'value' key in the driver.data dictionnary when we updated to 'result' key. Forward-Port-Of: odoo/enterprise#91057
This update fixes how formatted text is handled for Twitter and YouTube social posts. It helps ensure posts display correctly and consistently when users prepare social media content in Odoo.
Original PR description
Follow up of https://github.com/odoo/enterprise/pull/88683
The point of sale configuration now correctly shows only compatible Belgian blackbox devices when settings are displayed through related configuration screens. This prevents users from seeing or selecting unrelated IoT devices, reducing setup confusion.
Original PR description
The domain to display only blackboxes in the IoT devices configuration on pos.config was a string, so not correctly passed to res.config.settings in the related field. This commit fixes this issue by computing the domain with a lambda method. Forward-Port-Of: odoo/enterprise#90613