Daily updates from Odoo
Friday, August 8, 2025
16 changes · 18.0
New functionality added to Odoo
Point of Sale restaurants using UrbanPiper can now connect with Wolt as an additional delivery provider. This expands delivery channel options and may help businesses reach more customers through Wolt orders.
Original PR description
Following this commit: - Integrated Wolt as delivery provider in pos_urban_piper. task-4882282
Enhancements to existing features
Invoice document layout settings now show the same options whether users send, print, or configure layouts from settings. Tax ID, bank account number, and QR code previews are kept consistent, helping businesses avoid surprises in customer-facing invoice documents.
Original PR description
Previously, the document layout wizard used when sending invoices included fields for Tax ID, Bank Account Number, and QR Code. However, these fields were missing from the wizard accessed via the…
Previously, the document layout wizard used when sending invoices included fields for Tax ID, Bank Account Number, and QR Code. However, these fields were missing from the wizard accessed via the `Print` button and from the layout configurator under `General Settings > Configure Document Layout`. This was because only the send flow was using the inherited report layout from the `account` module, while the print and settings flows were using the base layout from `web` directly. Additionally, the preview template in web did not include the bank account number or QR code With this **PR**: 1. The `Print` button now uses the inherited layout from `account`. 2. The settings configurator button also uses the correct layout from `account`. 3. The bank account number and QR code fields are now dependencies of the _compute_preview method, making the preview responsive to their changes. 4. Both fields are now shown in the preview when configuring the layout in settings. This ensures the document layout behaves consistently across send, print, and settings configurator flows. **task**-4954030
The online shop now retrieves product attribute filters more efficiently during searches. This can dramatically reduce loading times on large product catalogs, improving the shopping experience and reducing server strain.
Original PR description
### Description: The default query to fetch attributes for searched products needs to join on the `product_tmpl_ids` Many2Many field. This can be slow, as it requires a join on an intermediate table. This change avoids that by directly querying the attribute lines and grouping by `attribute_id` to remove duplicates. ### Benchmark (in 18.0): | N° of products | Before | After | |----------------|--------|-------| | 3708 | 400ms | 200ms | | 128539 | 4 min | 800ms | | 484798 | 6 min | 3s | ### Reference: opw-4937361 Forward-Port-Of: odoo/odoo#222064
Resolved issues and error corrections
Sales orders linked to a project will now keep that project connection when they create purchase orders through make-to-order buying or drop-shipping. This helps businesses track purchasing costs and delivery activity against the correct customer project without manual correction.
Original PR description
This commit fixes two issues related to project propagation from Sale Order to Purchase Order: **1. Project not propagated when using MTO+Buy route** **Steps to reproduce:** - Install only…
This commit fixes two issues related to project propagation from Sale Order to Purchase Order: **1. Project not propagated when using MTO+Buy route** **Steps to reproduce:** - Install only `sale_project_stock` and `purchase` - Enable multi-step routes and unarchive the "MTO" route - Create a storable product "P1" with: - Routes: MTO + Buy - Vendor: any - Create a Sale Order with: - 1 unit of P1 - Any project set in "Other Info" - Confirm the SO **Issue:** A Purchase Order is created but the project is not propagated to it. This propagation was previously ensured by `project_mrp_sale`, via: https://github.com/odoo/odoo/blob/238a41e35280256382f6509182b9e900fb4f7aba/addons/project_mrp_sale/models/stock_move.py#L9 --- **2. Project not propagated when using drop-shipping** **Steps to reproduce:** - Enable drop-shipping - Create a product "P2" with: - Route: Drop-Ship - Create a Sale Order with: - 1 unit of P2 - Any project set - Confirm the SO **Issue:** A Purchase Order is created, but the project is again missing. --- **Fix:** - Move the `_prepare_procurement_values` override from `project_mrp_sale` to `sale_project_stock` to ensure project propagation regardless of the presence of `project_mrp_sale` - Also adapt `sale_project` to ensure project is retrieved from the Sale Order if not set on the Sale Order Line. opw-4976606
Outgoing emails now include links for attachments that are stored in cloud storage, not only for files that exceed the email size limit. This prevents recipients from missing purchase order or other email attachments that were uploaded to cloud storage.
Original PR description
Before this commit, when sending emails with attachments stored in the cloud, the attachments's links were not included in the email body, as we only included the links for attachments exceeding the max email size. With this commit, we ensure that all attachments stored in the cloud are converted to links in the email body and included in the the email. opw-4717083
Marketing card previews and test mailings now use the right preview card, avoid recording preview clicks as real engagement, and show translated default email content. Campaigns tied to removed models are also cleaned up, with small usability improvements to related field selectors.
Original PR description
- Avoid counting "clicks" on archived (implicitly preview) cards - Pick the preview card when building the default mailing body - Translate the default mailing body - If a card targets a model that has been uninstalled, remove the campaign as is done for mailings task-4247003
Product forecasts now correctly account for outgoing stock moves created by multi-step delivery routes. This prevents sales orders from showing an incorrect available forecast when stock is already committed for delivery.
Original PR description
### Steps to reproduce: - In the settings enable Multi-Steps routes - Put your warehouse in delivery in 2 steps - Create and confirm a sale order for 1 units of a storable product #### > While the…
### Steps to reproduce: - In the settings enable Multi-Steps routes - Put your warehouse in delivery in 2 steps - Create and confirm a sale order for 1 units of a storable product #### > While the pick move was created and confirmed the forecast is still at 0 even tho it should be at -1 and the outgoing pick move should be matched with the SO line in the forecast report. ### Cause of the issue: The issue has been introduced by commit 5b40fb086a0e5677678c312b42dc1f2c8991dc9e The issue being that since the `location_final_id` should not have been considered for the past forecast based on done move chains (because each done move of the chain will refer to the same external `final_dest_id`). The proposed fix was therefore to change the dest_loc_domain as such: https://github.com/odoo/odoo/commit/5b40fb086a0e5677678c312b42dc1f2c8991dc9e#diff-1f24ce9f94c5795040749acca5924384d7d17c0ac39b1993cef3b484e4bd30afR324-R326 However, the new domain: https://github.com/odoo/odoo/blob/995a7072cb3315fc03544b281b1ed5ca4e81e901/addons/stock/models/product.py#L322-L326 ignores completely the part of the condition refering to `final_dest_id` for outgoing moves since the condition is negated here: https://github.com/odoo/odoo/blob/995a7072cb3315fc03544b281b1ed5ca4e81e901/addons/stock/models/product.py#L328-L333 The logical `OR` (`|`) becoming an `AND` (`&`) for the `domain_move_out_loc`. opw-4997982 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale now ignores canceled payment attempts when matching responses from payment terminals such as Adyen. This prevents a previously canceled payment from blocking a later order, so staff can complete the new sale normally.
Original PR description
If you made an order and tried to pay with a payment terminal (like Adyen) then canceled the payment on the terminal. Then leave the order and create a new order, add different products, and try to…
If you made an order and tried to pay with a payment terminal (like Adyen) then canceled the payment on the terminal. Then leave the order and create a new order, add different products, and try to pay again, pay on the terminal, the payment will not be transmitted to the PoS and the order would still be waiting for payment. Steps to reproduce: ------------------ * Create a pos payment method using adyen * Open a PoS session * Create an order with a product * Pay with the adyen payment method * Cancel the payment on the terminal * Leave the order * Create a new order with different products * Try to pay with the adyen payment method * Validate the payment on the terminal > Observation: The payment will not be transmitted to the PoS and the order will still be waiting for payment. Why the fix: ---------------- The issue occurs because the canceled payment line is still considered as a pending payment line. And when the payment will be receiven on the pos it would take the canceled payment line as the pending one. opw-4805704
Fixed an issue that prevented users from creating down payment invoices on Indian sales quotations when a reseller was selected. This keeps invoicing workflows from being blocked in reseller sales scenarios.
Original PR description
**Issue** When creating a down payment invoice for a quotation that includes a reseller, an error is raised and the operation is aborted. **Steps to Reproduce** 1. Install Accounting, Studio, and…
**Issue** When creating a down payment invoice for a quotation that includes a reseller, an error is raised and the operation is aborted. **Steps to Reproduce** 1. Install Accounting, Studio, and l10n_in_sale 2. Open the Quotation view in Studio 3. Set the "Referrer" field (i.e., l10n_in_reseller_partner_id) to be always visible and remove group restrictions 4. Create a new quotation and set a reseller in the Referrer field 5. Confirm the quotation 6. Click "Create Invoice" 7. Choose "Down Payment (percentage)" with 10% 8. Click "Create Draft" **Root Cause** The `_prepare_invoice_values()` method was assigning the full `res.partner` record to the `l10n_in_reseller_partner_id` field instead of its ID. Since the `account.move` model expects an integer ID for many2one fields, this caused a `psycopg2.ProgrammingError` due to the database adapter not being able to serialize a recordset. **Fix** Ensure the value passed to l10n_in_reseller_partner_id is the .id of the partner record, not the recordset itself. Opw-4899919 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes website menu setup so users cannot create menu structures that the website cannot display properly. It also enforces clearer rules for mega menus, helping keep navigation consistent and predictable for visitors.
Original PR description
Steps to Reproduce: 1. Go to the website. 2. Create a new menu (e.g., 'Test 1') using the 'Edit Menu' option and add it under another menu (e.g., 'Contact Us'), creating a sub-menu. 3. Turn on the…
Steps to Reproduce:
1. Go to the website.
2. Create a new menu (e.g., 'Test 1') using the 'Edit Menu' option and add it under another menu (e.g., 'Contact Us'), creating a sub-menu.
3. Turn on the developer mode.
4. Go to Configuration -> Menus and add two menus (e.g., 'menu 1' and 'menu 2') under the new sub-menu (e.g., 'Test 1').
5. Notice that the two menus ('menu 1' and 'menu 2') are not visible on the website.
Description:
As per functional specifications, creation of multi-level sub-menus should not be allowed.
Key Changes:
raises a `UserError` if a menu exceeds the two-level hierarchy by checking the parent and grandparent levels.
- Implements mega menu restrictions:
- A mega menu cannot have a parent menu.
- A mega menu cannot have child menus.
- Any menu cannot be a child of a mega menu.
- Prevents menus with child menus from being added as submenus to existing menus.
This ensures that the website menu structure adheres to the defined functional specifications, providing a consistent and predictable user experience.
task-3901371
Forward-Port-Of: odoo/odoo#168801The Spanish VAT books export now handles a missing company tax activity setting gracefully. Instead of showing an error, it directs users to complete the required company configuration so they can export the report successfully.
Original PR description
**Steps to reproduce:** 1. Install the `l10n_es_reports` module. 2. Remove the value from the `IAE Group or Heading` field in company settings. 3. Navigate to `Accounting -> Reporting -> Tax Report -> Generic Tax Report`. 4. Click the down arrow and select `VAT Record Books (XLSX)`. **Observed behavior:** * A traceback error occurs when attempting to export the VAT books. **Root cause:** * The system attempts to traverse the `IAE Group or Heading` field, which is empty, causing the traceback. **ref**: https://github.com/odoo/enterprise/blob/d8539dff5f3dcecfeb99fd7fc22a6915aaa02c4b/l10n_es_reports/models/libros_export.py#L126-L138 **Solution:** * If field `IAE Group or Heading` not configured, a RedirectWarning is raised to guide the user to the company form view for proper setup. opw-4981531 Forward-Port-Of: odoo/enterprise#91607
Odoo now avoids running out of memory when WhatsApp users send large files, such as uploads over 35 MB. This helps ensure incoming WhatsApp messages with larger attachments are received reliably instead of failing or missing content.
Original PR description
Currently a below occurs or content is not receiving to odoo WhatsApp when the user uploads a large file (tried with > 35 MB). Stack Trace: ``` MemoryError: null File "odoo/http.py", line 2383, in…
Currently a below occurs or content is not receiving to odoo WhatsApp when the user uploads a large file (tried with > 35 MB).
Stack Trace:
```
MemoryError: null
File "odoo/http.py", line 2383, in __call__
response = request._serve_db()
File "odoo/http.py", line 1913, in _serve_db
return self._transactioning(
File "odoo/http.py", line 1976, in _transactioning
return service_model.retrying(func, env=self.env)
File "odoo/service/model.py", line 134, in retrying
result = func()
File "odoo/http.py", line 1943, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "odoo/http.py", line 2187, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "odoo/addons/base/models/ir_http.py", line 227, in _dispatch
result = endpoint(**request.params)
File "odoo/http.py", line 757, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "home/odoo/src/enterprise/saas-17.4/whatsapp/controller/main.py", line 42, in webhookpost
wa_account_id._process_messages(value)
File "home/odoo/src/enterprise/saas-17.4/whatsapp/models/whatsapp_account.py", line 206, in _process_messages
datas = wa_api._get_whatsapp_document(messages[message_type]['id'])
File "home/odoo/src/enterprise/saas-17.4/whatsapp/tools/whatsapp_api.py", line 236, in _get_whatsapp_document
file_response = self.__api_requests("GET", file_url, auth_type="bearer", endpoint_include=True)
File "home/odoo/src/enterprise/saas-17.4/whatsapp/tools/whatsapp_api.py", line 46, in __api_requests
if 'error' in res.json():
File "requests/models.py", line 971, in json
return complexjson.loads(self.text, **kwargs)
File "requests/models.py", line 928, in text
encoding = self.apparent_encoding
File "requests/models.py", line 793, in apparent_encoding
return chardet.detect(self.content)["encoding"]
File "__init__.py", line 49, in detect
detector.feed(byte_str)
File "chardet/universaldetector.py", line 274, in feed
if prober.feed(byte_str) == ProbingState.FOUND_IT:
File "chardet/charsetgroupprober.py", line 70, in feed
state = prober.feed(byte_str)
File "chardet/hebrewprober.py", line 240, in feed
byte_str = self.filter_high_byte_only(byte_str)
File "chardet/charsetprober.py", line 73, in filter_high_byte_only
buf = re.sub(b"([\x00-\x7F])+", b" ", buf)
File "__init__.py", line 186, in sub
return _compile(pattern, flags).sub(repl, string, count)
```
At line [1], the code `'error' in res.json()` is used, which reads all the json content of `res`, but at times users upload large files, it will cause the above error because the `json()` tries to read all bytes from res, which is a very large amount to handle in memory.
This commit will fix the above issue by returning a response if the response
contains content_length more than 10 MB.
[1] - https://github.com/odoo/enterprise/blob/aca7ae2a7cf4aad5427a60d5cad60d08774357d0/whatsapp/tools/whatsapp_api.py#L46
sentry-5810101850
Forward-Port-Of: odoo/enterprise#70001Project profitability reports now keep previously invoiced amounts from subscriptions that were renewed. This prevents revenue from disappearing after renewal, giving businesses a more accurate view of project performance.
Original PR description
To reproduce: ============= - create a subscription with a service and link it to a project - confirm the subscription and invoice it - check the profitability of the project, everything is fine - renew the subscription and invoice it - check the profitability of the project, the invoiced amount is not taking into account the previous invoiced amount Problem: ======== renewed subscriptions are excluded from the profitability computation because they are closed by the renewal and not bringing any profitability, but with that we loose the profitability of the previous invoiced amount. Solution: ========= keep renewed subscriptions in computing `Invoiced` amount. opw-4755016 Forward-Port-Of: odoo/enterprise#91437
Fixes an issue where rental orders could incorrectly show products as unavailable after another order was picked up, even though stock was still available. Businesses using rentals without transfer documents now see accurate availability, reducing false warnings and order confusion.
Original PR description
Steps to reproduce:
- Do not enable “Rental Transfer” in settings
- Create a storable product “P1”:
- Enable “Can be rented”
- update available quantity to 10 units
- Create a first rental order for 24h:
- 9 units of P1
- Confirm the order
- Create a second rental order for the same 24h period:
- 1 unit of P1
-> Expected: The availability widget is green and indicates 1 unit available (correct).
Problem:
After picking up the first order, the widget on the second order turns red and incorrectly shows no availability.
The current logic checks virtual_available (1 unit) and subtracts rented_qty_during_period (9 units), resulting in -8. It then takes max(0, -8) → 0. However, the actual picked quantity should be taken into account, regardless of whether “Rental Transfer” is enabled, since disabling it merely omits the creation of a picking—not the move itself.
opw-4901017
opw-4906162
Forward-Port-Of: odoo/enterprise#91155The GSTR-1 document summary now excludes cancelled invoices that were never officially posted, improving the accuracy of Indian GST reporting. It also keeps the document summary visible and checks serial continuity within the relevant return period/company context.
Original PR description
Before: The document summary included all cancelled invoices, even those that were never posted. After: Only invoices that were posted and subsequently cancelled are now considered in the summary. Additional Changes: - Updated check_serials to validate serial continuity within current company. - Made the document summary view always visible in the GSTR-1 section. opw-4940053 Forward-Port-Of: odoo/enterprise#91965 Forward-Port-Of: odoo/enterprise#90160
EC sales list reports now correctly populate additional columns beyond the standard goods, services, and triangular columns. This prevents country-specific reports, such as Slovenia's five-column report, from showing empty values where data should appear.
Original PR description
Before this commit, when an ec sales list report had more than the 3 bases columns (goods, service, triangular) the value was not filled. For example in slovinia, the ec sales list has 5 columns, the two extras columns where always empty. task-4963633 Forward-Port-Of: odoo/enterprise#90669