Friday, July 25, 2025
52 changes
12 changes
Resolved issues and error corrections
The point of sale customer display now opens more reliably even when the IoT Box cannot be reached. This prevents error screens during checkout and keeps the customer-facing display available by using an alternate connection method when needed.
Original PR description
We fixed the customer display not opening and displaying a traceback when the Iot Box was not reachable, by calling the action via iot_http, fallbacking on websocket when needed. We also removed the "customer display with IoT Box" logic from the PoS to the module pos_iot. Community PR: odoo/odoo#219917 Forward-Port-Of: odoo/enterprise#90657
This fixes an error that could prevent employees from clocking out in restaurants using the Belgian blackbox POS setup. The POS now receives the required employee identification data during synchronization, so clock-in and clock-out actions work reliably.
Original PR description
How to reproduce: - Set up a restaurant with a Belgian blackbox - Create employees - Enable the POS setting "Log in with Employees" - Open the POS configuration - Select an employee - Click "Clock Out" - The following error is displayed:TypeError: Cannot read properties of undefined The required employee '_insz_or_bis_number' data was not properly transferred to the POS during incoming synchronization, causing undefined references when performing clock-in/clock-out actions.
Ecuador electronic invoice processing now handles empty or incomplete responses from the tax authority without crashing. This helps users continue processing invoices more reliably when the external service returns unexpected data.
Original PR description
The system will crash when we receive nothing in `response` and also tryig to retrieve values from response. **Error:-** `TypeError: 'NoneType' object is not subscriptable` **Root Cause:-** - While…
The system will crash when we receive nothing in `response` and also tryig to retrieve values from response. **Error:-** `TypeError: 'NoneType' object is not subscriptable` **Root Cause:-** - While we are in `EC Company`. - When we click `Process Now` on the invoice. It will call `button_process_edi_web_services` method. And while in execution when at [1], `move.company_id._l10n_ec_is_demo_environment()` is `False`, then it calls `_l10n_ec_send_document` method. - While submitting electronic invoices to SRI, the method `_l10n_ec_get_client_service_response_new()` sometimes returns `None` . - It may also lack expected keys like 'estado' or 'comprobantes', depending on SRI’s behavior. [1] https://github.com/odoo/enterprise/blob/ce9eed675db4de3bcd1b283688c5c44d2e1ecf12/l10n_ec_edi/models/account_edi_format.py#L425-L428 **Solution:-** - Wrapped the access to response and its keys inside a `try...except` block that catches:- - `TypeError`: for cases where the response is `None`. **Sentry - 6708486009, 6728767866** Forward-Port-Of: odoo/enterprise#88611
Belgian point-of-sale receipts are adjusted to meet blackbox certification requirements after recent receipt layout changes. Receipts now more clearly show whether a ticket is valid and whether it is a refund, while removing duplicated date and address details.
Original PR description
Since this revmap of the POS receipt (https://github.com/odoo/odoo/pull/201105), we have to make some changes on the receipt when using `pos_blackbox_be`: - Display if the ticket is valid or not (Pro Format) & increase its size. - Display if the order was a refund or not. - No need to display the `blackbox_date` since we now have the `date_order` inside `/point_of_sale/static/src/app/screens/receipt_screen/receipt/receipt_header/receipt_header.xml``. - No need to display the `order.company.street` since the whole adress is now displayed inside `/point_of_sale/static/src/app/screens/receipt_screen/receipt/order_receipt.xml`. task-id: 4848882 community PR: https://github.com/odoo/odoo/pull/214394 Forward-Port-Of: odoo/enterprise#90180 Forward-Port-Of: odoo/enterprise#87759
This update fixes issues that could prevent Gemini-based AI features from working correctly and improves how attachments are processed for AI use. It also prevents AI search data from different models being mixed, making results more reliable for users.
Original PR description
- Use correct gemini model names (gemini-2.5-flash instead of just gemini) - Fix google API endpoint to use openAI-compatible path (/v1beta/openai) - Introduce embedding_model field in ai.embedding to prevent cross-model mixing - Fix attachment processing percentage calculation to count unprocessed embeddings - Add proper provider detection and embedding model mapping - Handle None responses from embedding API gracefully - Fix AI agent duplication with proper name suffix - Add comprehensive gemini integration tests - Update settings UI labels for clarity Task-ID: 4778862
Fixes an error that could stop users from reconfirming a loan after cancellation when Accounting Audit Trail is enabled. This ensures loan workflows remain usable even when past accounting entries must be preserved for compliance.
Original PR description
Steps: - Activate Audit Trail in Accounting configuration - Create and confirm a loan, having some moves posted in the past - Cancel it, reset it to draft the re-confirm it again -> ValueError: Expected singleton This is because posted moves can not be unlinked when canceling/closing the loan if audit trail is activated. Therefore we try to access the `state` field from a recordset instead of a singleton. With this commit, we filter the generated move to get the newly created one. opw-4834361 Forward-Port-Of: odoo/enterprise#90578 Forward-Port-Of: odoo/enterprise#88286
Fixes formatting issues when inserting fields and records into AI prompts, making them easier to delete and edit. It also reduces unnecessary prompt update calls when the content has not changed.
Original PR description
Purpose: -------- Currently records and fields inserted in AI prompts are badly formatted, making it sometimes impossible to delete an inserted field or to place the cursor after a field or a record. This commit fixes their format: For standalone fields, we do not insert divs inside a span anymore For grouped fields, the container is now a div instead of a t (which was set as inlined by the qweb plugin while the group shouldn't) For records, the container is now a span instead of a div, since we want the records to be inlined. Also, ai prompt widget now only calls onChange when the prompt content changed (to not make useless calls to it) Task-4780975 Forward-Port-Of: odoo/enterprise#90774
This fixes issues in the salary package configurator and offer signing flow that could save employee details on the wrong record or select an archived contract version. It improves reliability when HR teams generate, sign, and countersign offers, especially for Belgian salary configuration data.
Original PR description
Forward-Port-Of: odoo/enterprise#90307
Worksheet fields on the customer portal now respect visibility rules configured in worksheet templates. This helps customers see only the relevant fields and keeps worksheet layouts clearer when answers or conditions change.
Original PR description
When the user configures the field in the worksheet template to be visible based on a
condition, but it is not applied in the portal because the 'invisible' attribute is not
working. We have used 't-if'.
Technical:
1) Due to dynamic row visibility, the server-side cannot determine if the row is odd or even,
so I have implemented it in SCSS.
2) When the value of the field changes, `_add_field_node_to_container()` method is not triggered. Hence, we cannot
evaluate the domain.
task-3686737Fixed an issue where confirming an upsell with a non-recurring product could incorrectly increase the quantity on the original subscription. This prevents subscription records from being changed by unrelated products, helping keep customer billing and subscription quantities accurate.
Original PR description
**Steps to reproduce:** - Install `sale_subscription` - Create a recurring product (P1) and a non-recurring product (P2) - Create a Sale Order (S1) with P1 (quantity > 0) and confirm it - Create an…
**Steps to reproduce:** - Install `sale_subscription` - Create a recurring product (P1) and a non-recurring product (P2) - Create a Sale Order (S1) with P1 (quantity > 0) and confirm it - Create an upsell of S1 (new child order S2) - In S2, edit the P1 line, and select P2 - Set quantity > 0 for P2 - Confirm S2 **Issue:** After confirming the upsell order (S2), the quantity of P1 on the original subscription (S1) is incorrectly increased by the quantity of P2 from S2. The _compute_parent_line_id method did not reset the parent_line_id when the product was not a subscription Product, which caused it to incorrectly update the subscription This issue is present in all three versions: **16.0, 17.0, and 18.0**. **Solution:** Reset parent_line_id to False if the product is not a subscription product to prevent incorrect subscription updates. [opw-4638955](https://www.odoo.com/odoo/project.task/project.task/4638955) Forward-Port-Of: odoo/enterprise#90871 Forward-Port-Of: odoo/enterprise#88282
Brazilian POS orders with a zero total now still send the required payment information to Avalara. This prevents invoice submission errors for free or fully discounted sales, helping affected businesses complete compliant electronic receipts without manual intervention.
Original PR description
Right now, for 0 cost POS orders no `paymentMode` section is sent to Avalara, which leads to an error from them when trying to submit the invoice: Code 899: incorrectly entered payment method field The proper fix is to always send `paymentMode` with a value of 0.00 and mode of `Other`. (Note that there is a payment mode that corresponds to no payment, 90, but it only available for NF-e not NFC-e so we use 99) opw-4874094 Forward-Port-Of: odoo/enterprise#90960 Forward-Port-Of: odoo/enterprise#90724
Chilean factoring AEC files now always report the total amount in Chilean pesos, even when the original invoice uses another currency. This prevents incorrect values in regulatory export files and helps ensure submissions match local requirements.
Original PR description
In this bug, when a currency other than CLP is selected in invoicing, the generated aec has MntTotal tag with the rate of selected currency, while it must always be in CLP. To reproduce the bug: 1- Create a database with invoice app and a Chilean company 2- Create an invoice with document type of 34 3- Choose a different currency than CLP 3- Click on Send Now to SII and Create AEC 4- Click on Yield Entry smart button 5- Download generated AEC xml file 6- You can see the value of MntTotal is in selected currency which is wrong related: https://github.com/odoo/enterprise/commit/4e97c5d008c2879c5d014203fafc2c125d6c5ae7 opw-4830957 Forward-Port-Of: odoo/enterprise#90858 Forward-Port-Of: odoo/enterprise#90232
13 changes
Resolved issues and error corrections
When a cashier enters a product barcode in Point of Sale, Odoo now uses that barcode to preselect the matching product variant options in the configuration popup. This reduces manual selection steps, speeds up checkout, and helps avoid mistakes for products with multiple attributes.
Original PR description
Before this commit, when a user manually entered a product barcode in the search bar, and the product had multiple attributes and values, the configuration popup required the user to manually select the correct attribute values—even though the barcode uniquely identified the product variant. This slowed down the selling process and caused unnecessary friction. With this commit, when a product is found via its barcode (including manual entry), the configuration popup is automatically preset to the correct attribute values associated with that barcode. This improves the user experience and speeds up sales, especially for products whose barcodes cannot be scanned and must be entered manually. opw-4635497 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents upgrades from failing when Documents folders with email aliases belong to different companies. Odoo now creates the related mail alias using the correct company context, avoiding domain ownership validation errors during migration.
Original PR description
**Step to reproduce:** 1. Install documents in version 17.0. 2. create new company for that create document folder and set alias_domain 3. upgrade to 18.0 below menitoned traceback will raise…
**Step to reproduce:**
1. Install documents in version 17.0.
2. create new company for that create document folder and set alias_domain
3. upgrade to 18.0 below menitoned traceback will raise
**Issue** :-
previously fix was deployed https://github.com/odoo/upgrade/commit/edae53792f81859dd4c843d8da4307e4eae8e0ff in the upgrade forcefully creating the incoming mails.
**Cause** :-
``mail.alias.mixin`` is introduced in existing [model]( https://github.com/odoo/enterprise/commit/a32825ee00f2b330d99113f4d8c1488903fe744e#diff-b394e0e6aa5c87ff7d84c0317fa2ed372a90b7d3e730c462fcb81d4b747f46ebL34) As ``alias_id`` is kept as false according to this new alias records are creating but as it sudo it bringing all company records due to this and during upgrade env company is admin related company which is letting alias_domain_id [here](https://github.com/odoo/odoo/blob/9719feb1fac64e06c988b336b077a0aa47a2b96a/addons/mail/models/mail_alias.py#L262) of that company which is leading to validation error
**Fix:**
for fixing this is record have company_id so create mail alias
according to that
```
Traceback (most recent call last):
File "/home/odoo/src/odoo/18.0/odoo/service/server.py", line 1361, in preload_registries
registry = Registry.new(dbname, update_module=update_module)
File "<decorator-gen-13>", line 2, in new
File "/home/odoo/src/odoo/18.0/odoo/tools/func.py", line 97, in locked
return func(inst, *args, **kwargs)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 129, in new
odoo.modules.load_modules(registry, force_demo, status, update_module)
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 480, in load_modules
processed_modules += load_marked_modules(env, graph,
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 365, in load_marked_modules
loaded, processed = load_module_graph(
File "/home/odoo/src/odoo/18.0/odoo/modules/loading.py", line 206, in load_module_graph
registry.init_models(env.cr, model_names, {'module': package.name}, new_install)
File "/home/odoo/src/odoo/18.0/odoo/modules/registry.py", line 617, in init_models
func()
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_alias_mixin.py", line 49, in _init_column_alias_id
alias = self.env['mail.alias'].sudo().create(record._alias_get_creation_values())
File "<decorator-gen-136>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 495, in _model_create_multi
return create(self, [arg])
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_alias.py", line 266, in create
return super().create(vals_list)
File "<decorator-gen-120>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 496, in _model_create_multi
return create(self, arg)
File "/tmp/tmppqp1_15u/migrations/util/orm.py", line 249, in wrapper
return f(*args, **kwargs)
File "/tmp/tmppqp1_15u/migrations/base/0.0.0/pre-models-match_uniq.py", line 25, in create
return super().create(vals_list)
File "<decorator-gen-31>", line 2, in create
File "/home/odoo/src/odoo/18.0/odoo/api.py", line 496, in _model_create_multi
return create(self, arg)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5017, in create
records = self._create(data_list)
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 5275, in _create
records._validate_fields(name for data in data_list for name in data['stored'])
File "/home/odoo/src/odoo/18.0/odoo/models.py", line 1631, in _validate_fields
check(self)
File "/home/odoo/src/odoo/18.0/addons/mail/models/mail_alias.py", line 159, in _check_alias_domain_id_mc
raise ValidationError(_(
odoo.exceptions.ValidationError: We could not create alias Inactive Alias because domain bsiri.co.th belongs to company BSIRI Company Limited (HeadOffice) while the owner document belongs to company MindGift LL>
```
upg-3017582
opw-4941387
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prSales quotations now calculate fixed taxes correctly when an early payment discount is applied. This prevents customers from seeing duplicated fixed tax amounts, improving billing accuracy and reducing invoice corrections.
Original PR description
### Issue: The fixed tax value is doubled in `sale` when an early payment discount is applied. Steps to reproduce: - Create a fixed tax of $20 for example - Create a payment term with an early…
### Issue: The fixed tax value is doubled in `sale` when an early payment discount is applied. Steps to reproduce: - Create a fixed tax of $20 for example - Create a payment term with an early discount of 10% if paid before 10 days - Select "Always (upon invoice)" - In Sale create a new quotation with a line of $100 and the fixed tax - Select the created payment term - The tax value is doubled ($40) ### Cause: To compute the payment terms `_add_base_lines_for_early_payment_discount` (added in this [commit](https://github.com/odoo/odoo/commit/781678fb07ab3dd4d132193a938bbb71e8395424)) is adding two lines: - one with the negative amount of the payment term and the taxes - one with the positive amount of the payment term The goal is to compute the taxes on the discounted untaxed amount of the line. The original line compute the taxes for the undiscounted amount. The first added line computes the taxes for the amount of the discount and is negative. When adding the two the result is the tax value computed from the discounted untaxed amount. The issue is that a fixed will always have the same value, this means that the tax amount of the first added line will be positive and the same as the original line. When adding the two the amount is doubled. ### Solution: We don't add taxes with fixed amount on the first add line. opw-4868011
Mobile users opening a subtask from a project task now see it in the main screen instead of a pop-up. This makes the discussion area available, so users can communicate with customers directly from the subtask.
Original PR description
Before this commit, when the user is in mobile view and go to a task with subtasks and selects a subtask, the form view of that subtask is opened inside a dialog form view instead of opening the…
Before this commit, when the user is in mobile view and go to a task with subtasks and selects a subtask, the form view of that subtask is opened inside a dialog form view instead of opening the record in the main view. Because of that, the chatter for that subtask is not displayed. This commit opens the form view in the main view instead of opening it inside a form view dialog to be able to display the chatter of the subtask selected. Steps to reproduce the issue: ---------------------------- 1. Install project and go to project app. 2. Create a project A. 3. Add a task inside the project A 4. Add a subtask inside the new task created in step 3 5. Open the form view of the task created in step 3 in mobile 6. Click on the kanban record contained the subtask created in step 4 Expected behavior: ----------------- The chatter should be displayed in the form view of that subtask to be able to communicate with the customer. Current behavior: ---------------- Since the form view of the subtask selected is opened inside a form view dialog the chatter for that subtask is not displayed. task-4278273
Imported sales orders in Point of Sale now keep the tax position set on the sales order, even when it differs from the customer's default tax position. This helps ensure taxes are calculated consistently with the original sale and reduces billing errors at checkout.
Original PR description
When a sales order is imported into the PoS, the tax position does not match if the sales order has a different tax position than the one assigned to the partner. This commit ensures that the tax position will always be the one assigned to the sales order and not that of the partner. taskId: 4963118
The mail activity counter in the systray now refreshes correctly when activities are archived, rescheduled, reassigned, created, or deleted in batches. This helps users see an accurate number of pending activities without needing a manual refresh.
Original PR description
Currently the systray counter is only updated at: - create - unlink - write, but only if the user changes We want to detect changes such as activities being archived or due dates being updated to properly reflect the changes as the user applies them. We now do a separate check for activity count per user before and after a write call that modifies these fields. Additionally since we now have a count we provide that as part of the bus notification so that it can be updated accurately when modifying/creation/deleting activities in batch. Common activity test utils are updated to avoid false negatives. task-4862215
This fixes an issue where some online bank synchronization fields could disappear because provider details are no longer sent by Odoofin. Businesses can keep viewing and managing the needed synchronization information, with a related search behavior also corrected; the module must be updated for the fix to apply.
Original PR description
The fields on the online synchronization were invisible if no provider_data wass put on the synchro. But now, this info is not given anymore from Odoofin. So, we should not hide these fields based on provider_data. Also fixed a search domain. It will need an update of the module. Forward-Port-Of: odoo/enterprise#90822 Forward-Port-Of: odoo/enterprise#90785
Tax reports grouped by account and tax now show the correct net base amounts when invoices use the same tax with different analytic distributions. This prevents understated or duplicated tax report bases, improving accuracy for accounting and reporting.
Original PR description
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales…
### Issue: When having two lines on an invoice with the same tax and different analytic distribution, the base value is doubled on the tax report. ### Steps to reproduce: - Create a new tax on sales (eg 10%) - Make sure the option "Analytic Accounting" is ticked in the settings - Create an invoice with a line, add the tax on it and change the analytic distribution - Do the same for another invoice with another analytic distribution - Confirm the invoices - Go to the tax report - Select the report "Group By: Account > Tax" - On the report the "Net" amount is only the one of the first invoice, the tax amount is correct ### Cause: The bug appeared after this [commit](https://github.com/odoo-dev/enterprise/commit/9a7142ef57503efad9538e571d2e35c4aaa59531) which fixed another issue with analytics. Now several lines with the same tax can be returned by the query if they have different analytics. This was used to avoid having the base amount doubled on the invoice when several lines from the same move had with different analytics: there is a line for each analytic but they all have the same base, in the end the base amounts was doubled for each different analytic. Now the query returns multiple lines but as they all have the same key the base amounts are not added together. This fixes the previous issue when several lines from the same move but with different analytics were added but it creates another issue when different invoices have the same tax and different analytics. Because these lines also have the same key. This result in only the base amount of the first invoice to be taken into account. ### Solution: The previous fix was incorrect. The correct fix is to not join the lines when there are two tax lines. To do this the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line_tax_details.py#L153) in the query needs to be the same as the [condition](https://github.com/odoo/odoo/blob/cf8d38205c09a2724f41907fa07c5f23ff2d46a3/addons/account/models/account_move_line.py#L984) that will duplicate the lines in python. The check on `use_in_tax_closing` was missing so we add it. opw-4766421 Forward-Port-Of: odoo/enterprise#90936
Barcode scanning now finds internal stock locations only within the active company. This prevents users in multi-company setups from being sent to the wrong location when different companies use the same barcode.
Original PR description
Description of the issue/feature this PR addresses: When scanning a location by barcode, the system may return the wrong location if multiple companies have internal locations with the same barcode. This is because the search does not currently filter by company. Current behavior before PR: The system searches for a location using only the barcode and usage='internal', without restricting by company. If multiple companies use the same barcode for different locations, the first match (regardless of company) is returned. Desired behavior after PR is merged: The location search is now restricted to the active company.
Users with Planning permissions but no Employee access can now open and view Planning roles without encountering an access error. This keeps role configuration available to planning users while respecting employee-related access restrictions.
Original PR description
Trying to display the roles in the planning app is not possible if the user doesn't have hr_rights even with full planning rights. ** Step to reproduce ** - Connect to Odoo with an user that only have acces right for "Planning" (no employees). - Open Planning app - Configuration>Roles - It will trigger an Access Error (If it didn't trigger add a user to Ressources) ** Cause of the issue ** The acces for the default_role_id is limited to hr.group_hr_user: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L27 But is used in _compute_display_name: https://github.com/odoo/enterprise/blob/a7122011a0b0cdd111eccf59c917c6b8e2c25137/planning/models/resource_resource.py#L73 ** Fix ** Retrieve the information about the role with sudo opw-4908979
Sales commission achievement reports now include down payments and invoice lines that do not have a product assigned. This fixes mismatches between invoice analysis totals and commission results, helping sales users and managers see more accurate commission achievements.
Original PR description
In the sale achievement report, down payments and other account move lines that have no product attached to them would not be accounted for in the sale commission achievement report. This was due to the fact that the table was being inner joined on product_id which would get rid of records that had no product. Because of this behavior there would be a mismatch between the invoice analysis of a user and their commission even if the rate was 100% on the commission plan. Left joining the products onto the account move line keeps the lines with no products and fixes the discrepancy between the report and the invoice analysis. opw-4625340
Creating a new helpdesk ticket from the timesheet timer now keeps the selected support project and applies the right helpdesk team. This prevents validation errors and ensures users see the ticket option even before any tickets exist for that project.
Original PR description
Steps to reproduce: ------------------- - Install 'helpdesk_timesheet' module - Go to Timesheets and click on `Start` to launch the timer - Select `VIP Support` as Project - Create a new ticket…
Steps to reproduce: ------------------- - Install 'helpdesk_timesheet' module - Go to Timesheets and click on `Start` to launch the timer - Select `VIP Support` as Project - Create a new ticket Issue: ------ 1. Validation error raised: `At least one analytic account must be set.` 2. When we select a helpdesk project that does not have any ticket linked to it already, the field next to it is set to `Task` (task_id) instead of `Ticket` (helpdesk_ticket_id). Cause: ------ 1. When creating the ticket, we don't provide the default project who got the analytic account linked to it. 2. The field `helpdesk_ticket_id` is hidden because we consider that we the project is not linked to any helpdesk team; this is because we retrieve the projects based on tickets already created only. Solution: --------- 1. Set the default project in the context when creating the ticket (like for a task). In the create method, if no team is provided and we have a default project (from `list_value` or the `env.context`), we set the team based on the project if the project is linked to a helpdesk team. 2. Fetch all projects that have `helpdesk_team` field set. opw-4404097
Products with GST rates above 5% now include the required packaged-good tag when synced to Swiggy and Zomato. This helps ensure product information is sent consistently to delivery partners, reducing listing or compliance issues.
Original PR description
*: pos_urban_piper_swiggy, pos_urban_piper_zomato Before this commit: --- - Products with GST != 5% were not receiving the `packaged-good` tag in the sync payload for Swiggy and Zomato. After this commit: --- - Now, products with GST != 5% correctly include the `packaged-good` tag in their respective provider tag list (`swiggy` or `zomato`). task-4954571