Friday, August 21, 2026
33 changes · saas-19.1
Enhancements to existing features
Guadeloupe, Martinique, and Réunion are now treated like mainland France when determining the electronic invoicing address type. This helps companies in these regions get the correct France FRCTC Electronic Address automatically, reducing manual setup and improving Peppol/PDP compliance.
Original PR description
In France, some drom-com (Guadeloupe, Martinique and Réunion) needs to use pdp just like France. So we should add those 3 for the computation of `peppol_eas`, so it will autocomplete to **France FRCTC Electronic Address**. task-6344558 Forward-Port-Of: odoo/odoo#282995 Forward-Port-Of: odoo/odoo#278272
This update enables an additional automated quality check for the web module's document-related tests. It helps maintain more consistent test code and reduces the chance of test maintenance issues over time.
Original PR description
Task-5180137 Forward-Port-Of: odoo/odoo#280233
HR managers can now see and configure whether a specific time off type creates a related Calendar entry. This makes the existing setting easier to use and helps teams control when leave requests appear in calendars.
Original PR description
The `create_calendar_meeting` field on `hr.leave.type` allows users to choose if leave requests created with a given time off type generate a corresponding entry in the Calendar app. However, this field was not displayed on the form view. This commit adds `create_calendar_meeting` to the `hr.leave.type` form view inside the configuration section, along with dedicated help text explaining its behavior. Task: 6445794 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283450
The General Ledger report can now include invoice dates when that column is configured. This gives finance teams more useful reporting detail without needing a separate lookup.
Original PR description
If a column is added with `expression_label` equal to `invoice_date`, include that in results of `_report_custom_engine_general_ledger`. task-5917897 Forward-Port-Of: odoo/enterprise#113774
Resolved issues and error corrections
Fixes an Email Marketing editor issue where image movement or deletion controls could appear on top of replacement dialogs. This keeps dialog windows clearly visible and easier to use when editing mailing content.
Original PR description
Problem: Overlay option buttons for mailing element movement, duplication & deletion are displayed in front of other modals/dialogs. Cause: `useOverlayServiceOffset` offsets all `MassMailingIframe`…
Problem: Overlay option buttons for mailing element movement, duplication & deletion are displayed in front of other modals/dialogs. Cause: `useOverlayServiceOffset` offsets all `MassMailingIframe` overlay sequences by `+1000` (default sequence `50` becomes `1050`). Dialog modals do not have that +1000 sequence and appear behind the buttons. Solution: remove the `useOverlayServiceOffset` hook as it is not needed anymore. Steps to reproduce: - Create a new Email Marketing record. - Add an Image snippet, with the image set to the right. - Click on the image so that the Replace option button appears on the side panel, and movement/deletion controls are right under the image. - Click the Replace option button. - Observe that the movement/deletion controls appear above the dialog when your mouse hovers over the editor Backport of c2e0e89ac95a51682df92e883438c7e0bce16335 , opw-6203734 Co-Authored-By: Guce <guce@odoo.com> task-5477951 X-original-commit: c2e0e89ac95a51682df92e883438c7e0bce16335
Documentation and clarification updates
Sahil Singh added an individual contributor license agreement for contributions to Odoo. This is a legal documentation update that helps ensure current and future code contributions are properly authorized.
Original PR description
Signing the Individual Contributor License Agreement to authorize my recent and future code contributions to the Odoo repository. Forward-Port-Of: odoo/odoo#281366
This fixes an issue where color labels used outside the standard color picker did not display correctly. Planning resource entries now keep their intended colors consistently, including in dark mode.
Original PR description
The `o_colorlist_item_color_*` classes were scoped to `.o_colorlist > button` by 1aa9b957afdd , but they are also used standalone outside any colorlist, e.g. in Planning's `many2one_avatar_resource` field. `web_enterprise`'s dark-mode counterpart also defines them unscoped, so the two stylesheets disagreed. Move the color rules back to the root scope. The colors themselves and the `color-contrast()` text color introduced by the refactoring are kept. Steps to reproduce: - Go to "Planning" - Open "Configuration" => the resources in the "Resources" column. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283232
Blog pages now count only real public discussions as comments, instead of including internal chatter logs. This keeps visible comment counts accurate for visitors and editors when internal notes are added to a blog post.
Original PR description
Issue: The internal chatter logs were being counted as regular comments in the blog. Steps to reproduce: Create a website with a blog. Create a page for the blog and activate comments. While editing go into blog post. Send a log in the chatter, and the blog will show one more message than it should. Cause: Both logs and comments have the same type: `Comment` and when doing the counting of comments we used this broader type, encompassing all of them. Fix: Corrected it to use the subtype `Discussions` as this one seems to be more relevant to actual blog post comments. opw-6287196 Forward-Port-Of: odoo/odoo#270998
The Sales app now uses clearer, grammatically correct help text for the Expiration field on sales orders. This small wording fix makes the field easier to understand when users hover over it.
Original PR description
Steps to produce: --- - Install the Sales module. - Create a new Sales Order. - Hover over the `Expiration` field. Issue: --- - The help text of the Expiration field contains a grammatical error and the overall sentence is slightly awkward. Improve the help text to make it grammatically correct and more natural. opw-6481226 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#283187
Clicking a related field in the HTML editor now selects its readable display name by default instead of the less useful technical ID. This makes dynamic placeholders clearer for users while still allowing the ID to be selected manually when needed.
Original PR description
*: project Before this commit: when clicking a field having sub fields (canFollowRelationFor is true), we just return this field's id, which is not very useful in most cases. After this commit: We created subclass of DynamicPlaceholderPopover, EditorDynamicPlaceholderPopover, which uses EditorModelFieldSelectorPopover. We use the display name of the followable field by default and if the user really want the id, they may choose the id subfield. We also show the followable field's name as the default placeholder instead of "Display name". task-6265223 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272129
This fix ensures that read-only connections to replica databases are closed using the correct replica configuration. It prevents unused database connections from remaining open when replica settings differ from the primary database, improving reliability and resource usage.
Original PR description
close_db matched readonly connections against the primary DSN. When db_replica_* differs, those connections were left open. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282671
Searching messages in Discuss now handles accidental extra spaces without causing an error. This prevents interruptions when users search conversations and improves reliability of message lookup.
Original PR description
**Steps to reproduce:**
- Go to Discuss app
- Open a conversation
- Click on the Search Messages button
- Enter a word, then a lot of spaces
- `RangeError: Maximum call stack size exceeded`
**Issue:**
During highlighting, if the search term contains multiple spaces, `searchTerm.split(" ")` produces empty terms `""`. Then the empty regex will match on every character, creating a lot of highlight `<span>` elements and eventually causing the error on `element.replaceChildren(...newNode);`.
**Fix:**
Filter out empty terms before processing.
opw-6446173
Forward-Port-Of: odoo/odoo#282059This fixes an issue where importing electronic invoices could fail when a line had a 100% discount and tax already included in the price. Odoo now recalculates the tax from the original price in that case, allowing these invoices to import correctly.
Original PR description
Due to the following commit: 01efd8cfcce3269ca6b88d549a670b08a90298cb, a division by zero error is raised when a 100% discount is used with a price-included tax. When the discount is 100%, it is impossible to retrieve the original tax amount before discount using a simple multiplication as the current raw_tax_amount_currency is zero. In that case, we need to recompute taxes using the original unit price before discount. opw-6242701 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282430
This fix ensures Odoo correctly recognizes when the email queue process is being run by a scheduled action, so progress handling works as intended. It also adds logging of the email sending limit to help support teams investigate silent email queue failures, especially when memory limits are involved.
Original PR description
The changes introduced by https://github.com/odoo/odoo/commit/19d5367862528979abdcd411095f18d36bdbe7b8 aimed at aligning the mailing cron job logic with the new `_commit_progress` system. While doing…
The changes introduced by https://github.com/odoo/odoo/commit/19d5367862528979abdcd411095f18d36bdbe7b8 aimed at aligning the mailing cron job logic with the new `_commit_progress` system.
While doing so, it accidentally added an if condition based on `self.env.get('ir_cron')`, which will always return False and never run the progress commit as intended.
To address this, in this PR:
- we change the condition to `if self.env.context.get('cron_id'):`, the cron_id context variable being set when the method was called from a scheduled action
- additionally we take the occassion to add an info log that outputs the computed send limit at the time the method was triggered. This will make it easier to investigate the logs ad-hoc in situations where the "Mail: Email Queue Manager" cron job fails silently because of a memory limit error. A high send limit (batch_size) increases the chances of memory errors proportionally. Knowing what the exact sending limit was at a given point in time makes investigation easier when trying to build a sequence of past events that could explain issues related to email sending.
OPW-6396087
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#282892This fix updates the mail compose process to use the current progress-tracking method instead of an outdated one. It prevents unnecessary warning messages from filling server logs during automated mail queue processing, making operations easier to monitor without changing user-facing behavior.
Original PR description
Since 19.0 `_notify_progress`` is deprecated in favor of `_commit_progress``. See: https://github.com/odoo/odoo/commit/ee337934f9885834d95592946f435c6e1c8ef970 Currently, the mail compose wizard still calls an explicit _notify_progress followed by an explicit commit. This leads to warning tracebacks being dumped into the server logs (for example everytime the "Mail Marketing: Process queue" cron runs). We replace it with an equivalent `_commit_progress` call, which should log the progress and implicitly take care of the cursor commit. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282926
This fix prevents the Point of Sale from showing an error when users click the cashier status icon in configurations where employee login is disabled. It keeps the cashier selector from opening unless the employee login feature is available, making the checkout screen more stable for affected Belgian fiscal setups.
Original PR description
Steps: ----------- - Install pos_blackbox_be. - Configure a PoS with Blackbox Belgium enabled and `Log in with Employees` disabled. - Open a PoS session and click exactly on the session status circle on the cashier icon. Issue: ----------- - A traceback is raised with the following error: `this.cashierSelector is not a function`. Cause: ----------- - Installing pos_blackbox_be makes the cashier icon appear clickable by adding the `pe-auto` class to the cashier icon's session status circle, even when `Log in with Employees` is disabled. In this configuration, the cashier selector is unavailable, causing the click handler to fail. Fix: ----------- - Add a dedicated onClick handler to the CashierName button. - Return early when `module_pos_hr` is not enabled before calling `selectCashier`, ensuring that `selectCashier` is called only when the `module_pos_hr` configuration is enabled. Task-6369404 Forward-Port-Of: odoo/odoo#282656
This fix prevents the online shop product page from accidentally targeting unrelated form fields when handling product option choices. It helps ensure customers see and select the correct product variants during checkout-related shopping flows.
Original PR description
The selector was matching unrelated inputs because it wasn't specific enough. Forward-Port-Of: odoo/odoo#283464
Chat windows on mobile now use a configurable display layer instead of a fixed setting. This helps other parts of Odoo control which elements appear on top, reducing visual overlap issues without changing the default behavior.
Original PR description
The z-index of chat windows on mobile views was previously fixed at `1020`, preventing other modules from adjusting their stacking order. This commit introduces a configurable z-index for chat windows, defaulting to `1020` while allowing other modules to override it when needed. task-6412411 Forward-Port-Of: odoo/odoo#283178
This fix ensures an automated blog editor test starts with the right settings so the dynamic blog snippet is available when needed. It helps prevent false test failures and supports more reliable website blog quality checks without changing the customer-facing product.
Original PR description
The blog post dynamic snippet options tour needs debug mode because the dynamic snippet belongs to the Debug snippet group. The tour used to put `debug=1`in the preview iframe path, while the initial website preview client action was opened without debug. This meant `request.session.debug` was only updated once the iframe request was handled. If the snippet template was rendered before that request, QWeb used the empty session debug value and omitted the Debug snippet group. After this commit, we open the preview action directly in edit and debug mode from the Python test instead, so the first server request sets `request.session.debug` before the website builder loads the snippets. Forward-Port-Of: odoo/odoo#281433
Email sending now handles certain database concurrency issues more reliably by avoiding extra database lookups after a failed notification update. This helps preserve the original error information, making failures easier to diagnose without changing normal user workflows.
Original PR description
When updating mail notifications during `mail.mail._send()`, a `SerializationFailure` raised while flushing the notification recordset leaves the current transaction in an aborted state. As `_send()`…
When updating mail notifications during `mail.mail._send()`,
a `SerializationFailure` raised while flushing the notification recordset leaves the current transaction in an aborted state.
As `_send()` continues handling the exception, accessing fields:
- https://github.com/odoo/odoo/blob/127f1316540ec6cc6880ea3515e6923ba3903bc7/addons/mail/models/mail_mail.py#L816
So, any subsequent SQL query fails with
`InFailedSqlTransaction`, masking the original concurrency error.
Avoid accesing to `mail.message_id` with aborted cursor, preserving the original `SerializationFailure`.
A regression test is added to simulate a concurrency failure during
`flush_recordset()` and verify that the cursor is no longer used dirty
The logger for the unittest without the fix is the following:
```log
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "odoo/addons/mail/models/mail_mail.py", line 719, in _send
notifs.flush_recordset(['notification_status', 'failure_type', 'failure_reason'])
File "<string>", line 3, in flush_recordset
File "unittest/mock.py", line 1139, in __call__
return self._mock_call(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "unittest/mock.py", line 1143, in _mock_call
return self._execute_mock_call(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "unittest/mock.py", line 1204, in _execute_mock_call
result = effect(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^
File "odoo/addons/test_mail/tests/test_message_post_concurrent.py", line 93, in mocked_mail_notification_flush_recordset
return original_flush_recordset(self, *vals, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "odoo/odoo/models.py", line 6788, in flush_recordset
self._flush(fnames)
File "odoo/odoo/models.py", line 6852, in _flush
model.browse(some_ids)._write_multi(vals_list)
File "odoo/odoo/models.py", line 4938, in _write_multi
self.env.execute_query(SQL(
File "odoo/odoo/api.py", line 993, in execute_query
self.cr.execute(query)
File "odoo/odoo/sql_db.py", line 371, in execute
res = self._obj.execute(query, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.SerializationFailure: could not serialize access due to concurrent update
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "odoo/addons/test_mail/tests/test_message_post_concurrent.py", line 107, in test_mail_send_dirty_cursor
mails.send()
File "odoo/addons/mail/models/mail_mail.py", line 652, in send
self.browse(batch_ids)._send(
File "odoo/addons/mail/models/mail_mail.py", line 818, in _send
mail.id, mail.message_id)
^^^^^^^^^^^^^^^
File "odoo/odoo/fields.py", line 1309, in __get__
self.compute_value(recs)
File "odoo/odoo/fields.py", line 1491, in compute_value
records._compute_field_value(self)
File "odoo/odoo/models.py", line 5302, in _compute_field_value
fields.determine(field.compute, self)
File "odoo/odoo/fields.py", line 113, in determine
return needle(records, *args)
^^^^^^^^^^^^^^^^^^^^^^
File "odoo/odoo/fields.py", line 710, in _compute_related
record[self.name] = self._process_related(value[self.related_field.name], record.env)
~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
File "odoo/odoo/models.py", line 7083, in __getitem__
return self._fields[key].__get__(self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "odoo/odoo/fields.py", line 1272, in __get__
recs._fetch_field(self)
File "odoo/odoo/models.py", line 4120, in _fetch_field
self.fetch(fnames)
File "odoo/addons/mail/models/mail_message.py", line 756, in fetch
return super().fetch(field_names)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "odoo/odoo/models.py", line 4158, in fetch
fetched = self._fetch_query(query, fields_to_fetch)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "odoo/odoo/models.py", line 4245, in _fetch_query
rows = self.env.execute_query(query.select(*sql_terms))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "odoo/odoo/api.py", line 993, in execute_query
self.cr.execute(query)
File "odoo/odoo/sql_db.py", line 371, in execute
res = self._obj.execute(query, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
psycopg2.errors.InFailedSqlTransaction: current transaction is aborted, commands ignored until end of transaction block
```
Real error in production:
```log
2023-04-15 10:43:14,978 106451 ERROR my_db odoo.sql_db: bad query: UPDATE "mail_notification" SET "failure_reason" = "__tmp"."failure_reason"::text, "failure_type" = "__tmp"."failure_type"::VARCHAR, "notification_status" = "__tmp"."notification_status"::VARCHAR FROM (VALUES (4426629, 'Error without exception. Probably due to concurrent access update of notification records. Please see with an administrator.', 'unknown', 'exception')) AS "__tmp"("id", "failure_reason", "failure_type", "notification_status") WHERE "mail_notification"."id" = "__tmp"."id" ERROR: could not serialize access due to concurrent update
```
```log
2023-04-14 10:43:14,978 106451 ERROR my_db odoo.sql_db: bad query: UPDATE "mail_mail" SET "failure_reason"='Error without exception. Probably due do sending an email without computed recipients.',"headers"='{''X-SMTPAPI'': ''{"ip_pool": "Transactional"}'', ''X-Odoo-Objects'': ''sale.order-1436960''}',"state"='exception',"write_uid"=1,"write_date"=(now() at time zone 'UTC') WHERE id IN (2548540)
ERROR: current transaction is aborted, commands ignored until end of transaction block
```
Description of the issue/feature this PR addresses:
Current behavior before PR:
Desired behavior after PR is merged:
# UPDATE 2026-07-22
The reviewer requested to remove the large docstring
For record, the docstring was
```python
"""Reproduces a concurrency scenario where `mail_mail._send()` fails with a PSQL SerializationFailure after
flushing `mail.notification` records. After such a failure, the cursor is left in an aborted
(`InFailedSqlTransaction`) state, so any further SQL access (e.g. reading `mail.message_id` like
https://github.com/odoo/odoo/blob/127f1316540ec6cc68/addons/mail/models/mail_mail.py#L816)
would raise a new error masking the original SerializationFailure.
Setup:
- Uses a separate `cursor()` to create and commit a message with its `mail.mail` and `mail.notification`
records, so they are visible to a second, concurrent transaction.
Concurrency simulation:
- `MailNotification.flush_recordset` is patched so that, right before the real flush runs, a second cursor
updates the same `mail.notification` records (`failure_reason`). This forces PSQL to raise a
SerializationFailure when the original transaction tries to flush those rows.
Assertions:
- `SerializationFailure` is raised confirming the concurrency conflict.
- `mail_mail._send()` logs the expected error message containing the mail `id` and `message-id`
Cleanup: created records are unlinked in `finally`
"""
```
# UPDATE 2026-07-23
The reviewer requested to remove the unittest
For record, the unittest was
```diff
diff --git a/addons/test_mail/tests/test_message_post.py b/addons/test_mail/tests/test_message_post.py
index 53dd5b9eec52..46a3958a5bff 100644
--- a/addons/test_mail/tests/test_message_post.py
+++ b/addons/test_mail/tests/test_message_post.py
@@ -7,17 +7,21 @@ from datetime import datetime, timedelta
from freezegun import freeze_time
from itertools import product
from markupsafe import escape, Markup
+from psycopg2.errorcodes import SERIALIZATION_FAILURE as SERIALIZATION_FAILURE_CODE
+from psycopg2.errors import SerializationFailure
from unittest.mock import patch
-from odoo import tools
+from odoo import SUPERUSER_ID, api, tools
from odoo.addons.base.tests.test_ir_cron import CronMixinCase
-from odoo.addons.mail.tests.common import mail_new_test_user, MailCommon
+from odoo.addons.mail.models.mail_notification import MailNotification
+from odoo.addons.mail.tests.common import mail_new_test_user, MailCommon, MockEmail
from odoo.addons.test_mail.data.test_mail_data import MAIL_TEMPLATE_PLAINTEXT
from odoo.addons.test_mail.models.test_mail_models import MailTestSimple
from odoo.addons.test_mail.tests.common import TestRecipients
from odoo.api import call_kw
from odoo.exceptions import AccessError
-from odoo.tests import tagged
+from odoo.modules.registry import Registry
+from odoo.tests import TransactionCase, get_db_name, tagged
from odoo.tools import mute_logger, formataddr
from odoo.tests.common import users
@@ -2244,3 +2248,49 @@ class TestMessagePostLang(MailCommon, TestRecipients):
self.assertIn('html lang="es_ES"', email['body'])
else:
self.assertIn('html lang="en_US"', email['body'])
+
+
+@tagged('database_breaking')
+class TestMessagePostConcurrent(MockEmail, TransactionCase):
+ """Mail concurrency edge cases that require real, separately committed transactions
+ instead of the usual rollback-based TransactionCase isolation.
+ """
+
+ def test_mail_send_dirty_cursor(self):
+ """Reproduces SerializationFailure `mail_mail._send()` fails,
+ the cursor is left in an aborted state, so any further SQL access would raise a new error
+ (e.g. reading `mail.message_id` like
+ https://github.com/odoo/odoo/blob/127f1316540ec6cc68/addons/mail/models/mail_mail.py#L816)
+ """
+ original_flush_recordset = MailNotification.flush_recordset
+
+ def mocked_mail_notification_flush_recordset(self, *args, **kwargs):
+ with Registry(get_db_name()).cursor() as cr:
+ cr.execute('UPDATE mail_notification SET failure_reason = %s WHERE id IN %s', ('Forced Concurrent Update', tuple(self.ids)))
+ return original_flush_recordset(self, *args, **kwargs)
+
+ recs2unlink = []
+ with Registry(get_db_name()).cursor() as cr:
+ env = api.Environment(cr, SUPERUSER_ID, {})
+ partner = env.ref('base.user_admin').partner_id
+ try:
+ message = partner.message_post(body='Hello', message_type='comment', partner_ids=[partner.id], mail_auto_delete=False, force_send=False)
+ notifs = env['mail.notification'].search([('notification_type', '=', 'email'), ('mail_mail_id', 'in', message.mail_ids.ids)])
+ self.assertTrue(notifs)
+ mails = message.mail_ids
+ recs2unlink.extend([notifs, mails, message])
+ cr.commit()
+
+ mails = self.env[mails._name].browse(mails.ids)
+ with (
+ mute_logger('odoo.sql_db'), self.assertRaises(SerializationFailure) as exc, self.mock_mail_gateway(),
+ patch(f'{MailNotification.__module__}.{MailNotification.__name__}.flush_recordset', autospec=True, side_effect=mocked_mail_notification_flush_recordset),
+ self.assertLogs('odoo.addons.mail.models.mail_mail', level='ERROR') as log_capture,
+ ):
+ mails.send()
+ finally:
+ for rec2unlink in recs2unlink:
+ env[rec2unlink._name].browse(rec2unlink.ids).unlink()
+
+ self.assertEqual(exc.exception.pgcode, SERIALIZATION_FAILURE_CODE)
+ self.assertIn(f'Exception while processing mail with ID {mails.id} and Msg-Id \'{mails.message_id}\'.', [record.message for record in log_capture.records])
```
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#279897
Forward-Port-Of: odoo/odoo#274089The point of sale now stops showing optional products after a cashier cancels the product configurator. This avoids suggesting add-ons for a product that was not added, reducing confusion during checkout.
Original PR description
When discarding the product configurator, we still showed the optional product. We no longer do that as no one wants to add optional products to a not-added product. task-6442422 Forward-Port-Of: odoo/odoo#282916
This update keeps an image-related automated test working on Ubuntu Jammy by using a Pillow setting that is supported across older and newer versions. It helps maintain reliable test results without changing business functionality.
Original PR description
`Image.Palette.ADAPTIVE` is not available in the Pillow version provided by Ubuntu Jammy, causing the animated GIF test to fail. Use `Image.ADAPTIVE` instead, which is compatible with both older and newer Pillow versions. Description of the issue/feature this PR addresses: Current behavior before PR: Desired behavior after PR is merged: --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#282223
This fix prevents an error when users reopen a note composer and press Escape or arrow keys in the “Continue with Full Composer?” popup. The popup now ignores those keys instead of crashing, keeping the chatter note-taking flow stable.
Original PR description
Reproduction steps: - Open a record that has a chatter where you can log notes - Start logging a note in the composer - Close the composer - Click log note again - See "Continue with Full Composer?" popup - Hit escape, up, or down - See traceback This shouldnt really do anything, so this fix makes it do nothing instead of crashing. opw-6476660 Forward-Port-Of: odoo/odoo#282803
This fixes an incorrect duplicate mention in a French VAT report identifier field that was reintroduced during a previous update. It helps ensure the generated VAT reporting file uses the expected wording and avoids potential filing confusion.
Original PR description
While forward-porting https://github.com/odoo/enterprise/commit/9b31a9cb65f1a37f953cf296cbc6cfa361cf7f62 ("[FIX] l10n_fr_reports: only attach a telereglement when VAT is due") to saas-19.1, I wrongly
rebased and resolved a conflict incorrectly. The resulting commit,
https://github.com/odoo/enterprise/commit/90059d0c39b1c385c057318112b146e4b7a77efc, reintroduced the express-mention-in-T-IDENTIF bug
previously fixed
opw-6275695Bank journal pages now hide the "send now" action and connection request when the selected bank statement source is not online synchronization. This prevents users from seeing irrelevant banking options after changing how statements are imported.
Original PR description
Before this commit, the "send now" button and the connection request were shown as soon as we had an account online account link to the journal. But when changing the bank statement source, the information would still be there. Changing the invisible condition to hide it when the bank statement source is different from only_sync no task id Forward-Port-Of: odoo/enterprise#128367
Fixed an issue where opening spreadsheet version history could trigger an unnecessary retry behind the scenes. This makes access to version history more direct and reliable for users, without changing spreadsheet features or data.
Original PR description
The get_spreadsheet_history method is marked as readonly, causing RPC requests to use a read-only transaction. However, retrieving the metadata of a document spreadsheet updates its spreadsheet contributors. Opening the version history consequently attempts an UPDATE in a read-only transaction and forces the request to be retried with a read-write cursor. Remove the readonly decorator so the request uses a read-write cursor directly. Task-6176364 Forward-Port-Of: odoo/enterprise#126626
When choosing appointment-related placeholder fields, the system now defaults to the readable field name instead of a technical ID when available. This makes generated content easier to understand while still allowing users to select the ID if needed.
Original PR description
Before this commit: when clicking a field having sub fields (canFollowRelationFor is true), we just return this field's id, which is not very useful in most cases. After this commit: We created subclass of DynamicPlaceholderPopover, EditorDynamicPlaceholderPopover, which uses EditorModelFieldSelectorPopover. We use the display name of the followable field by default and if the user really want the id, they may choose the id subfield. We also show the followable field's name as the default placeholder instead of "Display name". task-6265223 Forward-Port-Of: odoo/enterprise#121785
This change updates automated checks for the subscription sales area so they match related platform changes. It helps keep future subscription updates reliable without changing the customer-facing subscription experience.
Original PR description
See also: - https://github.com/odoo/odoo/pull/280403 Forward-Port-Of: odoo/enterprise#127041
Social users can now like Facebook and Twitter stream posts without running into an access error. This keeps social engagement actions working smoothly for users who do not have broader editing rights on the post.
Original PR description
Bug === When a social user like a stream post, an access error is raised because he has no write access on it. Task-6425391 Forward-Port-Of: odoo/enterprise#125973
A website rental planning purchase test has been temporarily disabled because the related sales rental flow is still changing quickly. This avoids unstable automated test results while the final process is being defined, with no direct change to customer-facing features.
Original PR description
Given the rapid changes in spec for `{website_}sale_renting_planning` it doesn't make sense to fix the tour only for the flow to break right away after. Therefore, the tour is temporarily disabled until the flow of the module(s) is finalized.
task-6389324
Forward-Port-Of: odoo/enterprise#128170On mobile screens, AI chat windows now open in front of existing chats instead of being hidden behind them. This makes the AI assistant easier to access when using fullscreen message composition in Odoo.
Original PR description
AI chats opened on mobile views could appear behind other chats. This was inconsistent with the expected stacking behavior, where newly opened chats should appear on top of existing ones. To reproduce: * Open the chatter of any module. * Open the message composer in fullscreen mode. * Click the AI button. This commit increases the z-index of AI chats on mobile views so they are displayed on top of other chats. task-6412411 Forward-Port-Of: odoo/enterprise#128346
This fixes a test issue in the Peru electronic invoicing module caused by small wording differences between software library versions. It helps keep automated validation reliable across different server environments without changing customer-facing invoicing behavior.
Original PR description
### Issue: `test_invoice_down_payment_with_withholding_tax` fails on RunBot when using `num2words==0.5.10` (Python < 3.12) The expected XML contains `DIECISÉIS` but older versions of `num2words` generate `DIECISEIS` without the accent ### Cause: The accent on `DIECISÉIS` was added in `num2words` PR #443, between versions `0.5.10` and `0.5.13` RunBot uses different versions depending on the Python version: `num2words==0.5.10` for Python < 3.12 (Jammy / Bookworm) `num2words==0.5.13` for Python >= 3.12 ### Steps to reproduce: - Run the test with `num2words==0.5.10` Before the fix, the test fails on the `cbc:Note` comparison runbot-945461 Forward-Port-Of: odoo/enterprise#127356
Fixed an issue in the Timesheet Assistant where unselecting one suggestion could leave its project or task selected when choosing another suggestion. This helps users create timesheets with the intended project details and avoids accidental entries on the wrong project.
Original PR description
Steps to reproduce: ------------ - install timesheet_grid. - activate assistant. - select a suggestion and then unselect it. - select a different project suggestion. Issue: ----------- the project from the previous suggestion remains selected. cause: --------- currentRecord is not reset when a suggestion is unselected, so the previous suggestion's project and task are still reused. Fix: --------- reset currentRecord to null when the suggestion is unselected and showCreateForm is false. Effected pr-https://github.com/odoo/enterprise/pull/126450 task-6482312