Friday, July 10, 2026
240 changes
16 changes
Enhancements to existing features
Point of Sale screens and related add-ons now include more complete translations for messages that staff may see during daily use. This improves clarity for users working in different languages, especially for dialogs, errors, alerts, and warnings.
Original PR description
pos* = All POS module In this commit: -------------------------------- Add missing translations for user-visible strings across POS modules. - Translated dialogs, errors, alerts, and other UI-visible messages - Updated Python-side UserError, ValidationError, and warning messages Task-5406947 Related PR-https://github.com/odoo/odoo/pull/239972 Forward-Port-Of: odoo/enterprise#122764 Forward-Port-Of: odoo/enterprise#102094
This update adds automated checks to ensure emails linked to newly generated coupons from helpdesk tickets remain traceable. It helps protect the reliability of customer communication history without changing day-to-day user workflows.
Original PR description
Added tests for email traceability when generating a new coupon in a ticket --- task-6341030 Forward-Port-Of: odoo/enterprise#122508
The printer setup screen now only shows the O-Box IP address setting when it is relevant for ePOS printers. It also hides technical service details from the O-Box view, making configuration clearer for business users.
Original PR description
This PR adapts the view to only allow the user to set obox ip if the type of printer used is epos as it doesnt matter otherwise It also hides the services installed on the obox as it's not useful for the user task-6330864 Forward-Port-Of: odoo/enterprise#123271
The Grid and Gantt views were updated to work with a newer internal rendering method. This helps keep these views reliable and easier to maintain, with no expected change to day-to-day workflows.
Original PR description
- community: https://github.com/odoo/odoo/pull/273956 This commit follows changes in the `useVirtualGrid` hook regarding reactivity. The users of this hook, namely: the Gantt and Grid views' renderers, have been adapted to use its new API.
Resolved issues and error corrections
Marketing Automation now shows the correct reason when a participant is removed from a campaign. If a record still exists but no longer matches the campaign filter, users will see that explanation instead of the misleading “Record deleted” message.
Original PR description
`sync_participants` calls `action_set_unlink` on every participant whose record is no longer in the campaign domain, and `action_set_unlink` writes "Record deleted" on each scheduled trace. The…
`sync_participants` calls `action_set_unlink` on every participant whose record is no longer in the campaign domain, and `action_set_unlink` writes "Record deleted" on each scheduled trace. The removed bucket also contains records that still exist but no longer match the campaign filter, so the cancelled trace dialog shows "Record deleted" even when the record was only filtered out. In `sync_participants`, the to_remove participants are split between those whose record still exists in the database (filtered out by the campaign domain) and those whose record was actually deleted. `action_set_unlink` accepts an optional `trace_message` argument, defaulting to "Record deleted", and the filtered-out batch passes "Record no longer matches campaign filter" so the cancelled trace dialog reflects the real cause. Steps to reproduce: 1. Install Marketing Automation and CRM. 2. Open Marketing Automation, create a campaign on Lead with filter Stage = New. 3. Add a begin activity to the workflow. 4. Open CRM, create a Lead in the New stage. 5. Back in the campaign, click Generate Participants. 6. In the CRM pipeline, drag the Lead from New to Qualified. 7. Back in the campaign, click Generate Participants again. 8. Open the Participants smart button, click the participant for the moved Lead. 9. Click the cancelled activity in the workflow timeline. => The activity dialog shows "Error message: Record deleted" although the Lead still exists. Ticket [link](https://www.odoo.com/odoo/project/49/tasks/6251264) opw-6251264 Forward-Port-Of: odoo/enterprise#118692
9 changes
Enhancements to existing features
Loss amounts in the Lithuanian Profit and Loss report are now displayed in red instead of grey with only a negative sign. This makes negative results more visible and helps users review financial performance more quickly.
Original PR description
Before this commit: - The losses in the Lithuanian P&L report are shown in grey with only a -ve sign After this commit: - The losses in the P&L report are shown in red now. Related PR: https://github.com/odoo/odoo/pull/239388 Task-5269617
This fix prevents delivery tracking from failing when EasyPost returns an empty tracker value. Users can continue working without seeing an error caused by incomplete carrier response data.
Original PR description
The PR https://github.com/odoo/enterprise/pull/111833 handled the specific case when the tracker data is missing from the EasyPost response, however in certain cases `tracker` key exists, but it has a `None` value, which leads to a traceback when trying to access the stock move:
```
File "/home/odoo/src/enterprise/18.0/delivery_easypost/models/easypost_request.py", line 392, in get_tracking_link
public_url = shipment.get('tracker', {}).get('public_url')
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'
```
This commit provides a fallback to avoid getting the error from the side of the user.
opw-6270242
Forward-Port-Of: odoo/enterprise#119400Hong Kong payroll payslips no longer crash when a user clears the start or end date. This helps payroll users safely edit draft payslips and keeps Average Daily Wage and end-of-year pay calculations from running on incomplete date information.
Original PR description
Currently, an error occurs when a user removes the payslip date. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Go to `Payroll` >…
Currently, an error occurs when a user removes the payslip date. **Steps to Reproduce:** - Install `l10n_hk_hr_payroll` with demo data. - Switch to the `Hong Kong` company. - Go to `Payroll` > `Payslips` > `Payslips`. - Create a `payslip` and remove the `start` or `end` period. **Error 1:** `TypeError: unsupported operand type(s) for +: 'bool' and 'relativedelta'` **Error2:** `AttributeError: 'bool' object has no attribute 'month'` When a user removes the start or end date of a payslip, the system computes the Average Daily Wage. Based on the payslip dates, it finds the previous year's payslips [1]. If the start or end date is not set, it raises an error [2]. For the second error, when computing whether to include EOY pay, it compares the company's EOY pay date with the end date's month. If the end date is not set, accessing its month raises an error [3]. This commit ensures that when retrieving previous-year payslips, if the start or end date is not set, it returns an empty payslip recordset. It also ensures that when computing whether to include EOY pay, if the end date is not set, `include_eoy_pay` is set to `False`. [1]: https://github.com/odoo/enterprise/blob/ec8a009794863090351d91650aff727e6fbeab7e/l10n_hk_hr_payroll/models/hr_payslip.py#L124 [2]- https://github.com/odoo/enterprise/blob/ec8a009794863090351d91650aff727e6fbeab7e/l10n_hk_hr_payroll/models/hr_payslip.py#L209-L215 [3]- https://github.com/odoo/enterprise/blob/ec8a009794863090351d91650aff727e6fbeab7e/l10n_hk_hr_payroll/models/hr_payslip.py#L141 Forward-Port-Of: odoo/enterprise#123135 Forward-Port-Of: odoo/enterprise#120586
Popover content in dark mode now looks more consistent and easier to use. Secondary buttons stand out as clickable actions, and forms inside popovers better match the surrounding popover background.
Original PR description
Before this commit, content like form & secondary button rendered inside popovers had inconsistent styling in dark mode: - secondary buttons did not stand out properly from the popover background, making them look like plain text blocks rather than actionable buttons; - forms rendered inside popovers (such as the multi-create popover) kept their default background, which visually clashed with the popover background. This commit fixes these issues by: - adding dedicated secondary button background colors for popovers, including hover state; - aligning form backgrounds inside popovers with the popover background. task-6249985 Forward-Port-Of: odoo/enterprise#121631
The French Intrastat export wizard now opens warning links filtered to the specific journal entries with missing required Intrastat information. This prevents users from being sent to unrelated accounting entries, making correction of export issues faster and clearer.
Original PR description
Steps to reproduce: 1. Have a French company with intrastat report module installed 2. Create and validate a bill to another EU country, without filling out at least one of the required intrastat fields 3. Go to the intrastat report, and export it as XML DEBWEB2 4. In the export wizard, click on the internal links on the warning messages Issues: 1. In the Intrastat report in French localization, when there are missing values detected in the export, the Export Wizard shows internal links that lead to every journal entries - instead of showing only the relevant entries. The warning banner on the report uses the action action_invalid_code_moves which has a domain to limit what is shown on the view form. However in the method _fill_value_errors there was no domain. opw-6215339 Forward-Port-Of: odoo/enterprise#117997
Pasting document links into an empty message no longer adds an unnecessary blank line at the start. This keeps shared document messages tidier while still separating links from any existing text.
Original PR description
Before this commit, adding document links always prepended a line break before the generated links. When the composer was empty, this resulted in messages starting with an unnecessary blank line. This commit only inserts a line break when the composer already contains text, avoiding the extra spacing while preserving the separation between existing content and pasted links. task-[5947683](https://www.odoo.com/odoo/project/1519/tasks/5947683) Forward-Port-Of: odoo/enterprise#123201 Forward-Port-Of: odoo/enterprise#120952
A small compatibility fix keeps Knowledge file navigation behaving as expected in newer Chrome versions. This prevents browser changes from altering how scroll actions complete, reducing the risk of unexpected behavior for users.
Original PR description
Since Chrome 150, scrolling methods like `scrollIntoView()` return a Promise instead of `undefined`. This commit adds block braces to ensure the action returns `undefined` and keeps the same behavior as before. Reference: - https://chromestatus.com/feature/5082138340491264 - https://chromium.googlesource.com/chromium/src/+/50f3e3d0a9bc02aad8b8161dbdd59046991dd2c7 runbot-941309 Forward-Port-Of: odoo/enterprise#123231 Forward-Port-Of: odoo/enterprise#123031
Grid views now display the user-friendly label for grouped selection values when opening related records from the cell magnifier. This avoids confusing internal codes such as "non_billable" appearing in list titles, making the view easier to understand for users.
Original PR description
When grouping a grid view by a selection field and clicking on the cell magnifier, the list title showed the technical name (e.g. non_billable) instead of the display name (e.g. "Non Billable"). This commit adds a condition specifically for selection fields, ensuring that their display names are used. task-5980035 Forward-Port-Of: odoo/enterprise#122303 Forward-Port-Of: odoo/enterprise#120894
Fixed an issue in Accounting where choosing certain actions from the bank reconciliation control panel could fail with an error. Users can now use those actions reliably without being interrupted by a missing service problem.
Original PR description
Fixed an issue where selecting any action from the control panel that would use orm would result in an error because the orm service was undefined. no task id Forward-Port-Of: odoo/enterprise#123480
Payroll processing now evaluates only the warnings that apply to the payslips being computed, instead of checking every possible warning. This reduces unnecessary work and helps payroll calculations run more efficiently without changing the payroll results.
Original PR description
Ensure that we do not evaluate unnecessary warnings by only evaluating the warnings relevant to the payslips being computed; instead of evaluating all of them. task-6371828 Forward-Port-Of: odoo/enterprise#123401
The Swiss payroll time off request form now always shows the start date field. This prevents confusion and ensures employees can consistently enter the required date for any type of time off request.
Original PR description
The time off request view was showing the request_date_from field conditionally, which makes no sense as you would always need to pick a date for a time off no matter which unit the request uses. runbot-241099 Forward-Port-Of: odoo/enterprise#122278
This fix prevents AI markdown-related tests from failing when an optional markdown component is not installed. It keeps automated checks reliable without changing functionality for users.
Original PR description
markdown2 is an optional dependency, so `markdown_format` can fail to process markdown, in which case all the markdown tests fail. Skip the markdown rendering test if there's no markdown rendering to test. Forward-Port-Of: odoo/enterprise#123484 Forward-Port-Of: odoo/enterprise#123002
Resolved issues and error corrections
The Colombian DIAN invoicing module now correctly hides the Reset to Draft option for credit notes that have already been accepted by DIAN. This helps prevent users from accidentally changing official documents after they have been validated by the tax authority.
Original PR description
Issue: The reset button would still appear for credit notes that were already accepted by the DIAN. Steps to reproduce: Create a credit note, confirm it and send it to DIAN. You will be able to select Reset to Draft even though it shouldn't be possible to convert to draft after accepted by DIAN. Cause: The function to compute if the reset button would appear or not was only taking into account Invoices. Solution: Added credit notes, to the function that verifies if the reset button should appear. opw-6219265
The AI website builder now shows the correct preview image for the AI live chat snippet when the related live chat app is not installed. This helps users understand what the snippet will look like before adding or enabling it.
Original PR description
Commit [1] removed the snippet preview since it mismatched the actual result, but it was overlooked that there's another use of this preview. This commit adds an updated image back. [1]: df05441e469157890253b5550b5f8735723b28fb task-6379796
This change ensures subscription commission tests correctly clear currency rate data across companies when demo data is present. It prevents false test failures and helps keep commission calculations reliably validated.
Original PR description
Steps to reproduce: 1- Initialize a new database with demo data 2- Run the test `test_sub_commission_no_currency_rate` Issue: `AssertionError: 0 != 10 : Regular invoice, 10 percent of 100` Why this happens: The test used to delete all rows in the res_currency_rate table for the current company only. When we load the database with demo data, the query in `_get_subscription_currency_rates` would find entries for the other companies and wouldn't resort to the default. Later when joining, it would find no rates for the current company and the test fails. runbot-243440
This fix ensures status messages in French reporting are displayed properly when documents are accepted or rejected. It prevents error details from appearing incorrectly, helping users understand report outcomes without confusion.
Original PR description
A mismatch between error titles and status logs was introduced in 18.0. Markup wasn't added to the status logs, leading to a type mismatch (Markup + str) when displaying errors for 'accepted' or 'rejected' statuses. As a result, the logs were not interpreted as HTML. This commit ensures Markup is applied to each element to guarantee coherence and proper rendering. backport of 5113752 task-6053842 Forward-Port-Of: odoo/enterprise#123250
This fix ensures database API keys are accessed correctly during database management and synchronization workflows. It helps prevent access issues in user management and sync operations, improving reliability for teams managing databases.
The Argentine VAT Book export now handles foreign partners marked as overseas providers without blocking the ZIP download. This avoids manual workarounds and lets businesses correctly generate VAT reports for transactions involving foreign suppliers or partners.
Original PR description
Steps to reproduce: - Create a partner with: - State: Ireland - Identification Number: Foreign ID 55000004153 - ARCA Responsibility Type: Proveedor del Exterior - Create an invoice for the partner - Accounting > Reporting > Tax report - Select Report: VAT Book (AR), Tax Type: Sales - Click on gear icon > VAT Book (ZIP) Issue: Action will be blocked with error "No VAT configured for partner [58] <partner>" Analysis: Partners with ARCA responsibility type 'Proveedor del Exterior' (code 8) and a ForeignID identification type, causes a UserError when exporting the VAT Book (ZIP). Code 8 (foreign provider) is the purchase-side counterpart of code 9 (foreign customer), which already fell back to the country-level VAT. Extend the existing fallback branch to cover both codes. opw-6316008 Forward-Port-Of: odoo/enterprise#123506
This fixes an issue where the Sign app could fail when loading signing fields in debug mode. The change makes the page ignore hidden template comments so users and testers can continue working with documents without interruption.
Original PR description
Use lastElementChild when retrieving the sign item from the target element. In debug mode, inherited templates may introduce HTML comments into the DOM. Since lastChild return a comment node, accessing classList on the returned node raises an error. Using lastElementChild ensures that the last HTML element is always retrieved, regardless of comment nodes in the DOM.
The POS now loads only the Kenyan e-invoicing classification records that are actually used by available products. This avoids pulling unnecessary data into POS sessions, helping improve loading efficiency without changing cashier workflows.
Original PR description
Before `product.unspsc.code` and `l10n_ke_edi_oscu.code` records were loaded without domain, which could lead to loading all records of these models in POS, which is not necessary. This commit adds a domain to the loading of these records, so that only the records that are actually used in the products are loaded in POS.