Daily updates from Odoo
Friday, April 3, 2026
55 changes · saas-19.2
Resolved issues and error corrections
This update resolves an issue where rejecting a PoS order could trigger duplicate kitchen ticket printing. The fix prevents this by ensuring the print token is properly managed during order rejection, ensuring tickets are printed correctly and avoiding unnecessary operations. This improves the reliability of order processing for our restaurant clients.
Original PR description
Bug fix: - Prevent duplicate kitchen ticket printing on order rejection. When a user rejects an order, the reject RPC triggers a webhook that calls _fetchPlatformOrder on all devices. This led to deleteOrders being called twice (once by the reject flow, once by the webhook). Fix: claim the print token via mark_platform_prep_order_as_printed in _rejectOrder before sending the reject RPC, so no device gets isReadyToPrint=true from the webhook. - Preparation needs to be sent after PoS accepts the order. ticket-6071740 Forward-Port-Of: odoo/enterprise#112277
This update resolves an issue where users couldn't successfully undo rescheduling calendar events. The fix removes a problematic data field ('originId') before the system writes event data to the database, preventing a data error. This ensures the undo functionality works as expected.
Original PR description
Currently, an error occurs when user tries to undo a calendar event. Steps to replicate: - Install `appointment` with demo data. - Navigate to `Appointments > Schedule > Resource Booking`. - Drag to…
Currently, an error occurs when user tries to undo a calendar event. Steps to replicate: - Install `appointment` with demo data. - Navigate to `Appointments > Schedule > Resource Booking`. - Drag to create a calendar event. - Reschedule the event to a later time (drag and drop forward). - Click Undo on the notification that appears. Error: `ValueError: Invalid field 'originId' in 'calendar.event'` `KeyError: 'originId'` Cause: - The key `originId` was patched in the `getschedule()` [1] and later when user tried to undo the calendar event, the [fallbackschedule] included the key `originId` and made an [orm] call with it. - The [line] tries to write the data into the database where `originId` field doesnt exist and causes the error to occur. Solution: - Remove the `originId` key from `fallbackdata` before the orm call. [1]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/appointment/static/src/views/gantt/gantt_renderer.js#L110-L116 [fallbackschedule]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/web_gantt/static/src/gantt_renderer.js#L1425 [orm]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/web_gantt/static/src/gantt_renderer.js#L1473-L1477 [line]: https://github.com/odoo/enterprise/blob/e61eef059983bb0cdec4f156fb9283198b379863/web_gantt/models/models.py#L248 sentry-7020359653 Forward-Port-Of: odoo/enterprise#112766 Forward-Port-Of: odoo/enterprise#100570
This update resolves an issue where the 'Reconnect Bank' button was incorrectly displayed for synchronization jobs without an expiration date. Previously, all synchronization jobs defaulted to a 0-day expiration, causing the button to always appear. This change ensures the button only shows when a synchronization job has a valid expiration date, improving the accounting dashboard's clarity.
Original PR description
The aim of this commit is fixing the behavior of Reconnect bank button in accounting dashboard. Before this commit, a synchronization without any expiring date will always show the Reconnect bank button in the accounting dashboard because the expiring due days is set to 0 by default. The sync can only be expired or expiring soon if there is an expiring date. opw-6052451 Forward-Port-Of: odoo/enterprise#112195
This update addresses a previous memory issue that occurred when calculating depreciation for large customer records. The fix uses a more efficient method to process data, preventing the system from running out of memory and ensuring accurate depreciation calculations for all records. This resolves a problem previously impacting the 16.0 version.
Original PR description
The previous compute method loaded all moves records into memory, which caused an out-of-memory issue for large number of record. Replaced the logic with read_group aggregation to perform the…
The previous compute method loaded all moves records into memory, which caused an out-of-memory issue for large number of record. Replaced the logic with read_group aggregation to perform the calculation using sql and reduce memory usage.
Note: the issue is faced during 16.0 version too but as 16.0 is no more supported for bug fix. So, doing it from 17.0 version.
```
Traceback (most recent call last):
File "/tmp/tmpkvo8a96w/migrations/base/tests/test_mock_crawl.py", line 333, in crawl_menu
self.mock_action(action_vals)
File "/tmp/tmpkvo8a96w/migrations/base/tests/test_mock_crawl.py", line 346, in mock_action
return self.mock_act_window(action)
File "/tmp/tmpkvo8a96w/migrations/base/tests/test_mock_crawl.py", line 506, in mock_act_window
mock_method(model, view, fields_list, domain, group_by)
File "/tmp/tmpkvo8a96w/migrations/base/tests/test_mock_crawl.py", line 657, in mock_view_tree
self.mock_web_search_read(model, view, [domain], fields_list)
File "/tmp/tmpkvo8a96w/migrations/base/tests/test_mock_crawl.py", line 691, in mock_web_search_read
data = model.search_read(domain=domain, fields=fields_list, limit=80, order=filter_order(model))
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 5074, in search_read
result = records.read(fields, **read_kwargs)
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 3038, in read
return self._read_format(fnames=fields, load=load)
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 3219, in _read_format
vals[name] = convert(record[name], record, use_name_get)
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 6007, in __getitem__
return self._fields[key].__get__(self, self.env.registry[self._name])
File "/home/odoo/src/odoo/16.0/odoo/fields.py", line 1222, in __get__
self.compute_value(recs)
File "/home/odoo/src/odoo/16.0/odoo/fields.py", line 1404, in compute_value
records._compute_field_value(self)
File "/home/odoo/src/odoo/16.0/addons/mail/models/mail_thread.py", line 403, in _compute_field_value
return super()._compute_field_value(field)
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 4276, in _compute_field_value
fields.determine(field.compute, self)
File "/home/odoo/src/odoo/16.0/odoo/fields.py", line 98, in determine
return needle(*args)
File "/home/odoo/src/enterprise/16.0/account_asset/models/account_asset.py", line 293, in _compute_value_residual
posted_depreciation_moves = record.depreciation_move_ids.filtered(lambda mv: mv.state == 'posted')
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 5496, in filtered
return self.browse([rec.id for rec in self if func(rec)])
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 5496, in <listcomp>
return self.browse([rec.id for rec in self if func(rec)])
File "/home/odoo/src/enterprise/16.0/account_asset/models/account_asset.py", line 293, in <lambda>
posted_depreciation_moves = record.depreciation_move_ids.filtered(lambda mv: mv.state == 'posted')
File "/home/odoo/src/odoo/16.0/odoo/fields.py", line 1187, in __get__
recs._fetch_field(self)
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 3245, in _fetch_field
self._read(fnames)
File "/home/odoo/src/odoo/16.0/odoo/models.py", line 3351, in _read
self.env.cache.insert_missing(fetched, field, values)
File "/home/odoo/src/odoo/16.0/odoo/api.py", line 1123, in insert_missing
field_cache.setdefault(id_, val)
MemoryError
```
opw-5921410
upg-3891767
Forward-Port-Of: odoo/enterprise#109008This update fixes an error preventing Intervat from properly verifying Odoo's requests. The issue stemmed from outdated JWK keys being hidden from Intervat, causing authentication failures. A simple timeout addition has been implemented to ensure reliable connections.
Original PR description
When we open a connection in intervat, we initialize a JWK on IAP side,
then we use the private key linked with this JWK to sign our requests.
The problem is on IAP, we have a cron who archive JWK older than a week.
As the archived JWK are hidden in our JWKS endpoint, Intervat is no
longer capable of verifying our signatures, leading to this error:
`{"error_description":"JWT is not valid" "error":"invalid_client"}`.
To fix this, we might need to call IAP first to unarchive the JWK first.
no-task
Forward-Port-Of: odoo/enterprise#112719This update ensures that LNA (long polling) is correctly configured for IoT payment terminals, regardless of the printer type used. Previously, LNA setup was limited to IoT printers, but this change automatically enables it when LNA is set up on any printer, streamlining the process for users.
Original PR description
If we use an IoT payment terminal with an ePOS printer and check LNA on the printer record, we never setup LNA for the `longpolling`, as it's only done if we check LNA on the printer model with type "IoT". We now guess the user wants to use LNA with his terminal if he sets it up on any printer type. Forward-Port-Of: odoo/enterprise#112748
This update removes a confusing purple 'info pill' that appeared on mobile devices when using Web Studio's approval features. This change improves the user experience for mobile users by ensuring they can easily click on action buttons without unintended interactions. It addresses a reported usability issue.
Original PR description
Steps: - Install `web_studio` - Add an approval rule to any action in any form view (example preview button) - Open this form view - You will have a purple info pill in every action button in the form view This can be confusing for people wanting to click on the button on mobile but instead, they click on the purple pill + we don't even want this opw-5911667 Forward-Port-Of: odoo/enterprise#111770
This update fixes an issue where dropdown menus within the softphone wouldn't close when clicking outside the softphone. The change improves navigation and consistency with the softphone's modal behavior, ensuring dropdowns close as expected regardless of where the user clicks. This enhances the overall user experience.
Original PR description
Since [1] (and its follow-up commits), the softphone became the "UI active element" once it opens. This was required to solve multiple keyboard navigation issues that occurred while being on the app…
Since [1] (and its follow-up commits), the softphone became the "UI active element" once it opens. This was required to solve multiple keyboard navigation issues that occurred while being on the app switcher with the softphone opened. It also simply improved navigation any time the softphone is used, allowing it to close on ESC, etc. This is also consistent with what is being done at [2] where the softphone will get closer to modal behavior. However, it came with a bug: dropdown inside and outside the softphone were not closed anymore if clicking outside the softphone. E.g.: - Open the user dropdown menu - Click outside => it closes - Open the softphone - Open the user dropdown menu - Click outside => It does not close anymore This commit adds a test about it. The fix lies in the dropdown closing logic in the community counter-part of this PR. [1]: https://github.com/odoo/enterprise/commit/df1772e877a508150fd3f549526dec9d867354be [2]: https://github.com/odoo/enterprise/pull/111337 task-6055692
This update corrects an issue preventing the export of Profit & Loss reports with footnotes enabled in the l10n_lu_reports module. The fix addresses a dependency on an outdated model, ensuring proper XML generation and report functionality. This resolves a technical problem impacting report generation for Luxembourg accounting.
Original PR description
**Steps to reproduce:** * Install the **l10n_lu_reports** module. * Go to **Accounting → Reporting → Profit & Loss**. * Add a footnote on a report line (**⋮ → Annotate**). * Click **Export (XML)** to open the export wizard. * Enable **Import notes as references** and export. **Observed behavior:** * Export fails with `KeyError: 'account.report.manager'`. * XML file cannot be generated when references are enabled. **Cause:** * The export logic relied on the deprecated `account.report.manager` model. * This model was removed in v17([commit](https://github.com/odoo/enterprise/pull/33604/changes#diff-5fc5051f5c0211c0eec96b892e7d29e01b68d804417443502d17bccd8333d7ecL41)) and replaced by `account.report.footnote`. * The footnote retrieval code was not migrated accordingly. **Fix:** * Migrate reference retrieval to use `account.report.footnote`. opw-5890630 Forward-Port-Of: odoo/enterprise#112394 Forward-Port-Of: odoo/enterprise#107765
This update fixes an issue where flexible work schedules were incorrectly displaying an inflated number of expected hours (48 instead of 40). The fix addresses a time zone calculation error, ensuring that attendance hours are accurately reflected based on an employee's actual working time, regardless of their location.
Original PR description
__ ## Short functional explanation of the error When the time zone of an employee's schedule is different from the employee's time zone, and that the employee's time zone has more than 9 hours of…
__ ## Short functional explanation of the error When the time zone of an employee's schedule is different from the employee's time zone, and that the employee's time zone has more than 9 hours of difference with UTC. The schedule is flexible and is set to 40 hours per week. When we open the Attendances app, the expected hours for this employee show 48. ## Reproduction Steps 1. Create an employee. The time zone of the employee should be different from the one on his work schedule. To be sure to replicate the bug, set the time zone of employee's time zone to Pyongyang. 2. Open the work schedule and set it to Flexible. Set the weekly hours to 40, and the full time equivalent to 40. Set the work schedule to Europe/Brussels time. 3. Open Attendances. ### Expected behavior When we hover the name of our employee, we can see in white on green background 0/40h. ### Unexpected behavior Instead, we see 0/48h. ## Origin of the issue This line: https://github.com/odoo/odoo/blob/e49536031f61b90212eb6f0d1a8a3e15927e723d/addons/resource/models/resource_calendar.py#L419 is used to retrieve the correct date. We assume that `end_datetime` will be set at midnight, so subtracting one second gives us the day before, allowing us to ignore the date of `end_dt`, for which we don't need to compute the intervals. However, this doesn't take into account different time zones. Indeed, we compute `end_datetime_adjusted` from `end_datetime`, which has the user timezone, and not UTC, as defined here: https://github.com/odoo/odoo/blob/e49536031f61b90212eb6f0d1a8a3e15927e723d/addons/resource/models/resource_calendar.py#L402 As a result, if we set the user timezone to Pyongyang, `end_datetime` will be set at 8am, and `end_datetime_adjusted` will lead to the same date, instead of a day before. Hence, we would compute an additional interval for an additional day, which would in the end give us 48 hours expected instead of the 40 hours indicated in the contract. Therefore, we have to take into account the time zones, hours, minutes and seconds when checking the start and end dates. __ opw-5937298 Forward-Port-Of: odoo/enterprise#110011
This update resolves an issue where product exports from the Web Studio were not functioning correctly due to a change in how product creation logic was implemented. The fix adds a necessary context key, ensuring that product templates are properly created and exported, improving the reliability of this key business process.
Original PR description
This commit https://github.com/odoo/odoo/pull/254323 changed the way product( template)s are created, which now decouples the logic into two context attributes instead of one. This commit fixes this by adding the second one. Forward-Port-Of: odoo/enterprise#112753
This update resolves an issue where the LPP (Labor Pension Payment) was incorrectly applied to employee salaries in the Swiss payroll module, specifically when employees were not covered by insurance. The fix ensures accurate LPP calculations based on proper insurance status, improving payroll accuracy and compliance.
Original PR description
Forward-Port-Of: odoo/enterprise#112824
This update fixes an access error within the Frontdesk module that prevented users with limited employee permissions from creating new stations or visitors. The fix involved updating the Frontdesk module to adhere to a new Odoo standard regarding many2many fields linked to HR employees, ensuring proper access controls.
Original PR description
Issue: ---------------------------------------- When a user with administrator rights on frontdesk but no rights on employees try to create a new station or visitor, they get an access error. Steps to reproduce: ---------------------------------------- - Have a user with administrator rights on Frontdesk but no rights on Employees - Switch to this user - Open Frontdesk and try to create a new station - Access Error Cause: ---------------------------------------- Since [this commit](https://github.com/odoo/odoo/commit/71f662b827b58c4f8ed1260728dc5194201ec323) models having a many2many field on `hr.employee` must inherit from `hr.mixin` to avoid an access error. The Frontdesk module was not changed. Solution: ---------------------------------------- Make `frontdesk.visitor` and `frontdesk.frontdesk` inherit `hr.mixin` opw-6000417 Forward-Port-Of: odoo/enterprise#112893 Forward-Port-Of: odoo/enterprise#110084
This update prevents unnecessary rental planning slots from being created when the 'Plan Services' feature is turned off. Previously, updating a rental order would automatically generate slots, even if this feature wasn't enabled. This fix ensures that planning slots are only created when 'Plan Services' is active, streamlining the rental planning process.
Original PR description
Steps to reproduce: ------------------- 1. Install `sale_renting_planning`. 2. Create a rental service product with: - "Can be Sold" enabled - "Plan Services" disabled - UoM set to "Units" 3. Create and confirm a rental order with this product. 4. Go to Planning and check for slots related to this order. (no slots at this stage) 5. Update the quantity of the rental order. 6. Check Planning again for slots related to this order. Issue: ------ Planning slots are created after updating the quantity of the sale order, even when "Plan Services" is not enabled. Cause: ------ Slot records are created without checking whether "Plan Services" is enabled, which leads to unwanted planning entries. related commit: 74eef70 Solution: --------- Add a condition to ensure planning slots are created only when "Plan Services" is enabled. opw-6051012 Forward-Port-Of: odoo/enterprise#112355 Forward-Port-Of: odoo/enterprise#112278
This update resolves a translation issue that occurred when editing appointment details with guests enabled. The fix addresses a problem with how the system matched placeholder strings, specifically related to newline characters, preventing accurate translation. This ensures correct translations are displayed for appointment details pages.
Original PR description
When we are at the appointment details page, and have the option allow_guests turned on, and go to the editor for translation, we encounter the issue. Steps To Reproduce: 1. Create an appointment. 2.…
When we are at the appointment details page, and have the option allow_guests turned on, and go to the editor for translation, we encounter the issue. Steps To Reproduce: 1. Create an appointment. 2. Go to the "Options" tab, and click on "Allow Guests". 3. Go to the web page for the appointment, select the data and time. 4. Now, on the details page, go to any other language than the default, and click on edit/translate. 5. The issue occurs. The issue occurs when the regex tries to match the placeholder where the guests are added, which is enabled by the allow_guests. It contains strings with newline characters. The regex fails to take into consideration for these newlines and breaks causing the issue to appear. To fix the issue, we'll use regex to account for the new lines. Also the fix adapts [this commit](https://github.com/odoo/odoo/commit/bc30d2592d4a7913eddf30bac8be2d94b6c22ad4) to work with the [website refactoring](https://github.com/odoo/odoo/commit/9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2) opw-5412775 Forward-Port-Of: odoo/odoo#249195
This update corrects a visual glitch on mobile devices where the dynamic product snippet would jump unexpectedly when scrolling. The fix removes a setting that caused the snippet to repeatedly re-render, leading to inconsistent display behavior. This ensures a smoother and more reliable user experience across different screen sizes.
Original PR description
Scenario: - add the dynamic Products snippet on top of page and save - go to the website with browser address bar that change height when going when going down in the page (hide or change size of it…
Scenario: - add the dynamic Products snippet on top of page and save - go to the website with browser address bar that change height when going when going down in the page (hide or change size of it that is changing the viewport size) - scroll all the way up and down in the page Result: there is some jump that happen when the browser interface change size when scrolling down or up. Cause: When going down the page, the viewport size changes (because the address bar gets bigger / smaller). This causes the dynamic snippet to be re-rendered. Since February 2026 commit 2e5bd409581ddaab28084c42ab51b50b494f4876 to optimize performance, product blocks are only rendered when the are in the viewport (may depends on browser) with "content-visibility: auto". The combination of those two things, causes that if you scroll down, the widget is re-rendeded in owl, but it is only rendered in the page once you scroll in the viewport so the scroll jump up or down with the products snippet being rendered (going from 0 to eg. 300px when scrolling into viewport) or not being rendered (going from eg 300px to 0 when scrolling and the widget not being in viewport). Fix: remove the "content-visibility: auto" when we are in the dynamic "Products" snippet, it was intended for the shop view and not for the case where product block can be re-rendered outside of viewport. opw-6005340 Note: this is mainly happening on mobile browser (eg. safari on iOS) because of the viewport resize when scrolling, but this can somehow be reproduced on chrome desktop: - scroll below a "Products" snippet, change browser window size manually => the should be a jump of the content up - scroll up to go back to the product snippet => the content of product snippet should appear all at once when the 0 pixel heigh get in the viewport Forward-Port-Of: odoo/odoo#256815
This update corrects a display issue where generic 'VAT' labels appeared in error messages instead of country-specific labels. The change ensures that error messages accurately reflect the country's VAT rules, improving clarity and usability for users. This resolves a minor inconsistency in the application.
Original PR description
Before this **PR**, instead of the VAT label of each country, 'VAT' appeared in the error message. This was due to a mismatch in the matching of country codes. Forward-Port-Of: odoo/odoo#257030
This update addresses a visual glitch in the mass mailing theme selector on Chromium-based browsers. The fix prevents the theme selector from resizing unexpectedly, which previously caused scrollbars to flicker. This ensures a consistent and professional user experience when creating mass mailings.
Original PR description
In Chromium-based browsers, the mass_mailing theme selector attempts to resize the mass_mailing iframe to match the size of the theme selector wrapper. This allows the theme selector to take as much…
In Chromium-based browsers, the mass_mailing theme selector attempts to resize the mass_mailing iframe to match the size of the theme selector wrapper. This allows the theme selector to take as much screen space as possible while reducing unnecessary scrollbars. However, the resizing may cause "scrollbar flickering" issues on Chromium-based browsers, due to Chromium scrollbars taking up "physical" width to the right of the scrollable elements. In some instances, a scrollbar appearing causes the theme selector to scale down from the lost width just enough that this scrollbar becomes no longer necessary, causing the theme selector to be resized up, causing the scrollbar to appear, which causes the theme selector to scale down... Steps to reproduce: - On a Chromium-based browser, try to create a new mass_mailing. - Resize the window's height so that the bottom of the window almost touches the bottom of the form. Fix: The theme selector will no longer resize itself down if that resize were to remove scrolling from the form, except in the following edge case: If the difference between the ranges is larger than 20 pixels (arbitrary value), we resize anyways, as it's a large enough difference that it shouldn't trigger flickering. This prevents occasional oversized empty areas under the theme selector when a fullscreen window gets sized down -- 10156c10b09dc502a40253d64e2505e817a520bf removed the overflow: hidden; property away from the body.o_web_client element. As a result, the convert_inline iframe is able to affect the total height of the page when its height is higher than the page's height, resulting in the entire page seeming to have additional padding at the bottom. This is especially visible when convert_inline has been used at least once, as the iframe will have a height of 1300px. This commit adds overflow: hidden; and position: relative; styles to the convert_inline component div, removing them from view while still allowing the inlining process to proceed. Steps to reproduce: - Create a new mailing - Select the Events theme - Reduce window size to below ~1000 px - Scroll down task-6002993 Forward-Port-Of: odoo/odoo#253673
This update fixes a potential crash in the Odoo Gantt view when rescheduling work orders. The change adds a test case to handle scenarios where dependent operations have incomplete start or end dates, preventing errors and improving the overall stability of the scheduling process.
Original PR description
For PR https://github.com/odoo/enterprise/pull/112729, This commit adds a test case to ensure that rescheduling work orders from the Gantt view does not crash when dependent operations have missing start or end dates. Error: `TypeError - '>' not supported between instances of 'bool' and 'datetime.datetime'` sentry-7377739830
This update resolves an issue where canceling manufacturing orders could trigger an error when a move wasn't associated with a picking. The fix ensures the system verifies a picking exists before logging a 'cancel' activity, preventing the error and improving stability. This ensures accurate tracking of manufacturing processes.
Original PR description
Steps to reproduce the bug: - Unarchive the MTO route - Create a storable product P1: - Route: MTO + Manufacture - BoM: - Component: 1 unit of X1 - Create a storable product X1: - Component: 1 unit…
Steps to reproduce the bug:
- Unarchive the MTO route
- Create a storable product P1:
- Route: MTO + Manufacture
- BoM:
- Component: 1 unit of X1
- Create a storable product X1:
- Component: 1 unit of C1
- Create a manufacturing order for 1 unit of P1
- Confirm the MO -> A child MO is created
- Try to cancel the MO for P1
Problem:
A traceback is triggered:
IndexError: tuple index out of range
'origin_picking': moves.picking_id[0],
Explanation:
When the parent MO is cancelled, all the moves linked to this MO are
cancelled (finished moves and raw moves). While cancelling them, an
activity of type "cancel" is logged on the pickings linked to these
moves (if any), in order to warn the user that actions may be required
on those pickings.
However, we do not check whether the moves actually have a picking
linked before logging the activity. The code directly tries to access
the first picking linked to the move, which triggers the traceback when
there is none:
https://github.com/odoo/odoo/blob/796316c341c4346152ad9610c30679f47aaa2ff8/addons/mrp/models/stock_move.py#L442
When cancelling an MO, the method `_log_manufacture_exception` is already
called and logs an exception activity on the child MO.
Bug introduced by:
https://github.com/odoo/odoo/pull/254636/changes/7c68c3dbb29eaad4e09d59ef7c86bd525969caec
Forward-Port-Of: odoo/odoo#257011This update fixes an issue where email notifications were incorrectly routing external emails as internal aliases. The change enhances the system's ability to accurately filter internal system emails based on allowed domains, preventing potential notification errors. This ensures emails are delivered to the correct recipients.
Original PR description
The fix introduced in https://github.com/odoo/odoo/pull/216737 can lead to "over-eager" filtering when an external email address matches a localpart (left part) alias in a input email list contains…
The fix introduced in https://github.com/odoo/odoo/pull/216737 can lead to "over-eager" filtering when an external email address matches a localpart (left part) alias in a input email list contains internal emails (aliases to filter) AND external email addresses (should not be filtered). The `_find_aliases` method is used to identify internal system emails (aliases, bounces, catchalls) to prevent mail loops and ensure correct recipient filtering during notification grouping. Before this fix, when the `mail.catchall.domain.allowed` system parameter was set, the logic for local-part aliases (where `alias_incoming_local` is True) failed to correctly associate the local part with the allowed domains. This resulted in external email addressed being returned by the system, potentially leading to incorrect notification routing. We now use a more robust approach: - Pre-filter local parts based on the allowed domains to reduce DB load. - Utilize Python Sets for O(1) lookups of static and local aliases - Explicitly validate the (local_part, domain) combo during the final filtering. Example Scenario: - Config: mail.catchall.domain.allowed = "test1.com,test2.com" - Alias: "info" (alias_incoming_local=True) - Input: ["info@test1.com", "info@test3.com"] ### Output Before Fix: ["info@test1.com", "info@test3.com"] (The function failed to recognize info@test3.com as an external alias to be ignored based on the `mail.catchall.domain.allowed` config) ### Output After Fix: ["info@test1.com"] (Correctly identifies the internal alias tob filtered while ignoring the external one) OPW-5469264 OPW-5504201 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257266 Forward-Port-Of: odoo/odoo#244272
This update resolves an issue where prices were incorrectly displayed in sale order subsections, even when prices were hidden on the parent section. The fix ensures that price visibility aligns consistently across sections and subsections, improving the accuracy of sales order previews and reports. This improves the user experience and data reliability.
Original PR description
Steps to reproduce: --- - Install `Sales` module. - Create a Sale Order. - Add a section with products. - Add a subsection under it with products. - Enable `Hide Prices` on the section. - Enable…
Steps to reproduce: --- - Install `Sales` module. - Create a Sale Order. - Add a section with products. - Add a subsection under it with products. - Enable `Hide Prices` on the section. - Enable `Hide Composition` on the subsection. - Preview the Sale Order. Issue: --- - Prices are still visible in the subsection (grouped view) even though `Hide Prices` is enabled on the parent section. Root cause: --- - The variable `show_section_total` was defined only within the main rendering block and not reused in the grouped (`t-else`) block. - The grouped section summary (used when `collapse_composition=True`) did not respect the parent section's `collapse_prices` setting, causing prices to be displayed. Solution: --- - Moved `show_section_total` definition outside the main conditional block so it can be reused in both rendering paths. - Applied `t-if="show_section_total"` to price fields in the grouped section summary to ensure consistency with the parent section's price visibility. Before: --- <img width="1030" height="232" alt="image" src="https://github.com/user-attachments/assets/1ac05e5e-6841-420f-909f-994690656cc0" /> After: --- <img width="1023" height="232" alt="image" src="https://github.com/user-attachments/assets/921ae337-4d53-433a-a42b-bdc437181889" /> opw-5979807 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256447 Forward-Port-Of: odoo/odoo#255464
This update fixes a problem where combo prices were incorrectly distributed across items in a sale order, particularly when a combo included free items with a zero price. The change ensures accurate pricing calculations for combo orders, preventing revenue discrepancies. This improves the reliability of self-order sales.
Original PR description
In a specific scenario where a combo had combo choice with free quaitites and combo choice with only extra quantities and the price of the combo choice with free quantities was 0, the price of the combo product was distributed on the "free" lines and on the "extra" lines, which was causing the price to be wrong. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257367
This update resolves a bug preventing tour steps from appearing when a template is selected in the mass mailing module. The tour has also been updated to correctly function with any selected theme. This ensures a smoother and more reliable onboarding experience for new users.
Original PR description
## [FIX] mass_mailing: fix broken tour This commit fixes issues with the mass_mailing onboarding tour. The resolved issues are: * Tour steps when template is selected not shown: updated the trigger so that they are displayed. * Adapted the tour to handle selecting any theme task-5974184
This update resolves an issue where deleted messages in live chat transcripts were appearing as empty bubbles. The fix adds a necessary variable to the template, ensuring that deleted messages are now correctly displayed in the chat history. This improves the overall user experience and provides a more complete record of conversations.
Original PR description
Follow up of [1], the `is_deleted_message` template variable is not defined which lead to empty bubbles for deleted messages. [1]: https://github.com/odoo/odoo/pull/255325 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
This update corrects a technical issue related to how Odoo manages the 'activity_type_id' field in the mail module. By making a specific adjustment, we ensure the field functions correctly when customized, preventing potential data inconsistencies. This improves the reliability of activity tracking within the system.
Original PR description
The field ``ir.actions.server.activity_type_id`` is still a related field with ``_compute_related`` and ``_inverse_related`` even if we specify its compute methods as ``_compute_activity_type_id`` The base field of the field ``ir.actions.server.activity_type_id`` is in the model ``mail.activity.mixin``. It is a non-stored related field. When overriding the field with a customized compute method, we have to explicitly override the ``field.related`` attribute to prevent the orm populates attributes for related fields. Also since the field ``ir.actions.server.activity_type_id`` is stored, it doesn't need a search method. 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
This update resolves an issue where creating a task from a template after a page refresh would sometimes fail. The fix prevents errors related to virtual controllers, ensuring that task creation works reliably even after reloading the page. This improves the user experience and prevents data loss.
Original PR description
Steps to reproduce: - Open a project - Create a task and convert it into a template - Open another task (task A) - Reload the page - Create a task from the newly created template Refreshing the page causes `loadState` to rebuild the controller stack from the URL to represent the breadcrumb history. In this case, a virtual form controller is injected for the opened task A, due to the lack of context in the URL to reconstruct it fully. When creating the task from the template, a `switchView` to the new task's form view is triggered. However, only the controller for this new form view is fully populated with the relevant metadata, as the preceding ones are virtual (due to the above). This commit ensures that virtual controllers are excluded from the check on the `multiRecord` field, preventing an error since the `view` is undefined for virtual controllers. task-5876607 Forward-Port-Of: odoo/odoo#246346
This update resolves an error that occurred when rearranging sections within sale order lines. The fix ensures that the system correctly handles changes to order lines, preventing errors during editing and improving the user experience when managing sales quotes. This improves the reliability of the sales order management process.
Original PR description
Moving a section around in sale order lines when there is a line that can be abandoned throws an error Steps to reproduce: 1. Install Sales app 2. Go to Sales and create a new quotation 3. Add any…
Moving a section around in sale order lines when there is a line that can be abandoned throws an error Steps to reproduce: 1. Install Sales app 2. Go to Sales and create a new quotation 3. Add any product, then add a section: enter any name for the section and then immediately press Enter (it should create an empty product line) 4. Without leaving edit mode, drag and drop the section at the top of the sale order lines (the empty product line should still be there) 5. An error is thrown The same issue can be reproduced by moving a section down: 3b. Add any product, then add a section: move it to the top of the order lines then enter any name for the section and immediately press Enter (it should create an empty product line) 4b. Without leaving edit mode, drag and drop the section just between the product line and the empty product line Issue: `sortDrop` calls `leaveEditMode` at https://github.com/odoo/odoo/blob/e906eb23d698061f146ba67aae420eb7bb5e8a68/addons/web/static/src/views/list/list_renderer.js#L2242 which removes order lines that can be abandoned https://github.com/odoo/odoo/blob/e906eb23d698061f146ba67aae420eb7bb5e8a68/addons/web/static/src/model/relational_model/static_list.js#L379-L381 This can remove records from the recordMap generated before calling `super.sortDrop` in https://github.com/odoo/odoo/blob/e906eb23d698061f146ba67aae420eb7bb5e8a68/addons/sale_management/static/src/fields/sale_order_line_field/sale_order_line_field.js#L175-L182 so we end up calling `_handleQuantityAdjustment` with a recordMap that contains record ids that have been deleted, throwing an error when we try to access the deleted record Solution: Call `leaveEditMode` before computing recordMap in order to remove the records that can be abandoned. This prevents `this.props.list.records` from being different when we generate recordMap and when we call `_handleQuantityAdjustment`. We also need to set the record being moved as dirty. This prevents the record from being abandoned when `leaveEditMode` is called. opw-6022538 Forward-Port-Of: odoo/odoo#256662
This update fixes a problem where error messages for inherited views in Odoo contained sensitive development keys. The change ensures these keys are no longer translated, improving the user experience and preventing potential security risks. This update enhances the clarity and security of Odoo's error reporting.
Original PR description
Description of the issue/feature this PR addresses: Current behavior before PR: Validation Error message is being translated base on user message, including development keys <img width="1092" height="276" alt="image" src="https://github.com/user-attachments/assets/4c58f201-8bc6-4b5e-9510-e52f36e0cf2c" /> Desired behavior after PR is merged: development keys will not be translated <img width="1084" height="307" alt="image" src="https://github.com/user-attachments/assets/0ccbf570-b5a0-46ff-aaef-bc1aaa237371" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256982
This update corrects a visual glitch in the HTML editor where a placeholder hint would intermittently blink while users were editing fields. The fix ensures the hint only appears when a selection is actively being made within the editable area, improving the user experience and preventing distracting visual noise.
Original PR description
Problem: When the selection is updating, the hint is blinking in the editable. Cause: After 9df2662cc79c2d8277211f7ce0bdb389f783f933, `triggerDebouncedUpdateHints` clears the hint immediately and adds it back using a debounced version of `updateHints` which runs after a few seconds, thus causing this blink. Solution: We only update hint if the selection inside the editable. Steps to reproduce: - Create a new Todo. - Keep the editable empty. - Update the Todo title. - Observe the editable hint blinking. task-6025534 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#253846
This update resolves an issue where Safari on iOS devices, when the editor view is collapsed, wouldn't correctly update the cursor position after applying formatting (like bold). This fix ensures that the cursor behaves as expected in this scenario, improving the user experience for editing text in collapsed views. It's a minor bug fix that enhances usability.
Original PR description
Before this commit: when we applying format on collapsed cursor, we create a formatted element with ZWS, and set the cursor before the ZWS After this commit: we set the cursor after the ZWS, cause otherwise safari doesn't update the cursor properly leading to unformatted input task-4243977 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257161 Forward-Port-Of: odoo/odoo#249253
This update resolves a technical problem that was preventing some users of the Odoo Chile localization module (l10n_cl) from upgrading to newer versions. The fix corrects an error in a report view, preventing upgrade failures and simplifying maintenance for the development team.
Original PR description
There is a broken xpath in l10n_cl.report_invoice_document When the l10n_cl module is installed, it results in the faulty view being applied to v18 and later versions. This is particularly annoying because some rolling releases fail because a view with invalid locator is found. The view won't be disabled after a rolling release upgrade and many developers will be spared from checking the databases manually. Forward-Port-Of: odoo/odoo#254369 Forward-Port-Of: odoo/odoo#253588
This update resolves an issue preventing the demo installation of the Romanian EDI stock module. By disabling carrier validation for demo data, the installation process is now smooth and reliable. Additionally, the update includes a default stock valuation account for Romanian companies, streamlining financial reporting.
Original PR description
This commit ensures that stock picking carrier validation for Romanian EDI does not block demo data installation. task-3748978 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#239870
This change introduces a simple setting to prevent automatic translation updates when website content is modified. Currently, small changes trigger updates across all website languages, which can be disruptive for users. This new option allows administrators to disable this behavior for a smoother editing experience.
Original PR description
Delayed translation (draft version from change of main language that needs to be updated on each modified secondary language) on website were added or disabled with: -…
Delayed translation (draft version from change of main language that needs to be updated on each modified secondary language) on website were added or disabled with: - 2d08f97c0778469b409fca23f2be5f5a98ce3df8 (October 2023) in 17.0 added the delay translation feature - 0e0a74f8c5fc9f45311e629a76608c6c986d635d (December 2023) in 17.0 disabled the feature - 03a85b13b2c46ef7174123d902e95d5103031c6c (September 2025) in 19.0 enabled the feature again Some website editor users may not expect the behavior (eg. changing a background image, then needing to edit all secondary language so the drafted change is saved). For now we have not found a satisfying way to prevent delay translation for simple use case that should not break translations: eg. removing a snippet, changing attributes, ... Because if we did special case, it would then become unexpected: - will we need to update translations - if there was a previous change that needed translation update, then we do a change that would not need translation update, what should we do So this PR for now gives the option to create a ir.config_parameter: - key: website.disable_delay_translations - value: 1 That would disable the delay_translations feature for all websites if the user doesn't want the feature. opw-5187670 opw-5240423 opw-5250497 opw-5254832 opw-5344412 opw-5347408 opw-5419427 opw-5424761 opw-5481352 opw-5892371 opw-5931549 Forward-Port-Of: odoo/odoo#257370 Forward-Port-Of: odoo/odoo#243490
This update fixes a bug where dropdowns wouldn't close correctly when clicking outside the initial active UI element. The change expands the area where clicks trigger closing, ensuring consistent behavior with popovers and other UI elements, resolving a VoIP issue.
Original PR description
[FIX] web: fix dropdown closing logic when clicking outside active UI Before this commit, the dropdown were closed when clicking outside... but only if the element that was clicked belongs to the…
[FIX] web: fix dropdown closing logic when clicking outside active UI
Before this commit, the dropdown were closed when clicking outside...
but only if the element that was clicked belongs to the same "UI
active element" as the one that was the current one when the dropdown
was opened.
That is not perfect:
- Open some popover that becomes the "UI active element"
- Open the user menu dropdown (which is thus outside the current "UI
active element")
- Click just below that user menu dropdown
=> It does not close.
It will only close when clicking in the registered "UI active element",
which is not logical.
This commit improves the logic: the close also occurs if the click
occurs in *an ancestor* of the old registered "UI active element". That
still keep the idea of checking "UI active elements" at all, for example
in the case "dropdown -> dialog -> dropdown -> click outside", which
should not close the first dropdown, as in that case it is the opposite
situation: the click occurs in a *child* "UI active element" of the old
registered one.
This fix is needed to fix a VoIP issue, where the "popover" mentioned
in the example above is the VoIP softphone. See enterprise counter-part
for more precisions.
[FIX] web: fix dropdown closing logic after closing active UI elements
The parent commit fixes the dropdown closing logic when clicking outside
"UI active elements". But it was not enough:
- Open some popover that becomes the "UI active element"
- Open the user menu dropdown (which is thus outside the current "UI
active element")
- Close the popover with some keyboard shortcut
- Click just below that user menu dropdown
=> It still does not close, although we are in a situation without any
"UI active element".
This commit improves the logic again: the close also occurs if the click
occurs while the old registered "UI active element" is gone.
This fix is needed to fix a VoIP issue, where the "popover" mentioned
in the example above is the VoIP softphone. See enterprise counter-part
for more precisions.
task-6055692A recent update resolved an issue where the notebook test was unreliable due to asynchronous page switching. The fix ensures the test accurately identifies which button was clicked, preventing the test from repeatedly clicking the same tab and failing. This improves the overall stability of the notebook feature.
Original PR description
Since [1], switching between notebook pages is asynchronous. This test did not wait for the switch and dit not identify which button it used to click on either, relying on a simple toggle. When the runbot was slow, the test ended up clicking on the same tab twice, thus never returning to the one with the editor. runbot-241941 runbot-241258 [1]: https://github.com/odoo/odoo/commit/968dd2cd5d11ce9b39fbacfb60c37bc1bfaa1d9e Forward-Port-Of: odoo/odoo#257119 Forward-Port-Of: odoo/odoo#256782
This update fixes an issue where the HTML editor toolbar wasn't appearing on macOS when using Cmd+Shift+Arrow to select text. The fix addresses a conflict with the macOS operating system's handling of the Cmd key, which prevented the toolbar from updating correctly. This ensures consistent functionality for all users on macOS.
Original PR description
Problem: The toolbar does not open when using Cmd+Shift+Arrow to select text on macOS. Cause: On macOS, when the Cmd key is held down, the `keyup` event is never fired for other keys. The toolbar…
Problem:
The toolbar does not open when using Cmd+Shift+Arrow to select text on macOS.
Cause:
On macOS, when the Cmd key is held down, the `keyup` event is never fired for other keys. The toolbar relies on `keyup` for Arrow keys to re-enable `onSelectionChangeActive` and trigger the toolbar update, so it never opens.
See section ("Issue 3 - keyup event put on hold for other keys"): https://web.archive.org/web/20160304022453/http://bitspushedaround.com/on-a-few-things-you-may-not-know-about-the-hellish-command-key-and-javascript-events/
Solution:
Track when an Arrow key is pressed while Cmd is held (`pendingArrowKey`) and use a `selectionchange` listener as a fallback to re-enable the toolbar. The `selectionchange` event fires reliably on macOS even when `keyup` is suppressed. A `isMouseDown` guard ensures the listener does not interfere with the existing mousedown/mouseup flow.
Steps to reproduce:
1- Type some text
2- Use Cmd+Shift+Arrow (left or right) to select text 3- Observe the toolbar does not appear
task-6013408
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#257166
Forward-Port-Of: odoo/odoo#253293This update resolves a minor coding error that could have caused unexpected behavior in the holiday scheduling feature. The fix ensures correct variable usage, preventing potential issues with how holiday requests are processed. This improves the stability and reliability of the HR module.
Original PR description
A previous bugfix unintentionally used the same variable name twice within the same method which caused some unintended behavior Task-6092087 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257253
This update ensures that ticket and lead descriptions created after a chatbot restart only include messages from the current conversation, not outdated information from the previous session. This improves the clarity and accuracy of customer interactions linked to chatbot conversations, preventing confusion and providing a cleaner record of support requests.
Original PR description
Before this commit: When a chatbot conversation is restarted and the script creates a new ticket/lead, the description also includes messages from the previous session. After this commit: Only the messages sent after the chatbot conversation is restarted are included in the ticket/lead description. Task-5118966 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#256595 Forward-Port-Of: odoo/odoo#253566
This update fixes an issue where the departure date for Belgian employees wasn't editable after termination. The change allows HR staff to manually set the departure date when an employee is on 'partial working' notice, ensuring accurate payroll calculations and improved employee management. This resolves a conflict between automated and manual date adjustments.
Original PR description
Steps to reproduce: - Create an employee with a valid contract in a belgian company - End their colloboration with the reason 'Fired' - Set their notice_respect to 'partial working' - Edit the departure date to any date other than the pre-computed one and save your changes - The date will be automatically reverted to the precomputed one Cause: The cyclic dependency between the departure_date and the actual_notice_period fields where causing a conflict while trying to set the desired dates. Solution: Added a dummy inverse function that just permits manual changing of the departure date without triggering the computation function Task: 6036368 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update resolves an error that occurred when users paid for orders through the website using gift cards. The fix ensures that email notifications are properly processed without attempting to access deleted email records, preventing the error. This improves the reliability of the gift card ordering process.
Original PR description
Currently, an error occurs when a user pays for their order through the website. **Steps to Reproduce:** - Install the `website_sale` and `pos_loyalty` modules. - Create a `product`. - Go to `Gift…
Currently, an error occurs when a user pays for their order through the website. **Steps to Reproduce:** - Install the `website_sale` and `pos_loyalty` modules. - Create a `product`. - Go to `Gift Cards & eWallets` and create a program with the type set to `Gift Card`. - Generate at least `one gift card`. - In `Gift Card Products`, add the recently created `product`. - Ensure that the SMTP server is configured and the `Demo` payment provider is `enabled`. - Make sure that in the `Gift Card: Gift Card Information` email template, the `Send From` field is set. - Now, go to the `shop`, add the product to the cart, and proceed to `Checkout` > `Pay`. - And the error appears in the `logs`. **Error:** `odoo.exceptions.MissingError: Record does not exist or has been deleted.` `(Record: mail.mail(5,), User: 1)` After this [recent commit], when user pays for their order, the Payment: Post-process transactions step confirms the order and attempts to send reward coupon email [1] if any coupon is applied to the product. The system sends the email with force_send=True [2] and retrieves the sent mail_ids [3]. because force_send=True, the email is sent immediately [4] instead of being queued. Once the email is successfully sent [5], _postprocess_sent_message [6] is triggered. Since there is no failure in sending the email, the corresponding mail record is deleted [7], because the email template has auto_delete=True. Later, when the system tries to access the deleted mail.mail record using the previously returned mail_ids, it raises error [8]. This commit ensures that only existing mail records are used when processing mail_ids, preventing access to deleted records. [recent commit]: https://github.com/odoo/odoo/commit/80d80a007131827ddd231bed320708068d0086b6 [1]: https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/sale_loyalty/models/sale_order.py#L188 [2]- https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/sale_loyalty/models/sale_order.py#L245 [3]: https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/pos_loyalty/models/loyalty_card.py#L73 [4]- https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/mail/models/mail_template.py#L815-L816 [5]: https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/mail/models/mail_mail.py#L871-L872 [6]: https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/mail/models/mail_mail.py#L919 [7]- https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/mail/models/mail_mail.py#L288-L289 [8]: https://github.com/odoo/odoo/blob/0f395269e9815977263f27fa85855096166e15a2/addons/pos_loyalty/models/loyalty_card.py#L73-L76 sentry-7367887795 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes a bug where flexible work schedules with different time zones were incorrectly displaying an inflated number of expected hours (48 instead of 40). The change ensures accurate hour calculations by properly accounting for time zone differences, preventing overestimation of work time.
Original PR description
__ ## Short functional explanation of the error When the time zone of an employee's schedule is different from the employee's time zone, and that the employee's time zone has more than 9 hours of…
__ ## Short functional explanation of the error When the time zone of an employee's schedule is different from the employee's time zone, and that the employee's time zone has more than 9 hours of difference with UTC. The schedule is flexible and is set to 40 hours per week. When we open the Attendances app, the expected hours for this employee show 48. ## Reproduction Steps 1. Create an employee. The time zone of the employee should be different from the one on his work schedule. To be sure to replicate the bug, set the time zone of employee's time zone to Pyongyang. 2. Open the work schedule and set it to Flexible. Set the weekly hours to 40, and the full time equivalent to 40. Set the work schedule to Europe/Brussels time. 3. Open Attendances. ### Expected behavior When we hover the name of our employee, we can see in white on green background 0/40h. ### Unexpected behavior Instead, we see 0/48h. ## Origin of the issue This line: https://github.com/odoo/odoo/blob/e49536031f61b90212eb6f0d1a8a3e15927e723d/addons/resource/models/resource_calendar.py#L419 is used to retrieve the correct date. We assume that `end_datetime` will be set at midnight, so subtracting one second gives us the day before, allowing us to ignore the date of `end_dt`, for which we don't need to compute the intervals. However, this doesn't take into account different time zones. Indeed, we compute `end_datetime_adjusted` from `end_datetime`, which has the user timezone, and not UTC, as defined here: https://github.com/odoo/odoo/blob/e49536031f61b90212eb6f0d1a8a3e15927e723d/addons/resource/models/resource_calendar.py#L402 As a result, if we set the user timezone to Pyongyang, `end_datetime` will be set at 8am, and `end_datetime_adjusted` will lead to the same date, instead of a day before. Hence, we would compute an additional interval for an additional day, which would in the end give us 48 hours expected instead of the 40 hours indicated in the contract. Therefore, we have to take into account the time zones, hours, minutes and seconds when checking the start and end dates. __ opw-5937298 Forward-Port-Of: odoo/odoo#252847
This update fixes an issue where timesheets were incorrectly calculating hours for employees on past contracts. The change ensures that leave periods under a historical contract accurately reflect the standard working hours from that period, resolving a discrepancy between the current and past contract schedules.
Original PR description
Currently on creating a time off that falls under a past contract still generates timesheet hours based on the employee's current contract. ### **Steps to Reproduce:** 1) Install…
Currently on creating a time off that falls under a past contract still generates timesheet hours based on the employee's current contract. ### **Steps to Reproduce:** 1) Install `project_timesheet_holidays` module with demo data. 2) Create an employee with two contracts/versions: - Past contract: 1 Jan 2025 to 31 Dec 2025 with standard 40h/week (8h/day). - Current contract: 1 Jan 2026 to indefinite with standard 35h/week (7h/day). 3) Create and validate Time off for this employee in the past (e.g, 29 Dec 2025) 4) Navigate to `Timesheets>All Timesheets`, search for this employee and switch list view for clear view. ### **Observed Behavior:** 7:00 hours are displayed on the timesheet, pulling from the employee's current active contract calendar. ### **Expected Behavior:** 8:00 hours should be displayed, as the leave date falls under the 40h/week past contract. ### **Root Cause:** In the `_generate_timesheets`, the caledar values is fetched using `employee_id.resource_calendar_id` see[1], which always points to the employee's currently active calendar. Furthermore, this calendar is not explicitly passed to `_list_work_time_per_day` see[1], causing the method to fall back on the current default. [1]- https://github.com/odoo/odoo/blob/c2595e47e3b36120f4c3da8bfe8c16f6c5969a70/addons/project_timesheet_holidays/models/hr_leave.py#L36-L55 ### **Fix:** Resolve the applicable contract version based on the leave period instead of relying on `employee.resource_calendar_id`, which always points to the current calendar after the `resource_calendar` [refactor](https://github.com/odoo/odoo/commit/47f20c293787710e9501b7fd378239813875864a). This fix fetches the version overlapping the leave dates and use its `resource_calendar_id` to compute work hours. Pass this calendar explicitly to `_list_work_time_per_day` to avoid fallback to the current employee calendar. This ensures that leaves created in past contract periods generate timesheets using the correct historical working schedule. **opw-5922695** Forward-Port-Of: odoo/odoo#254296 Forward-Port-Of: odoo/odoo#248207
This update resolves an issue preventing internal employees from accessing their overtime data within the employee dashboard. The fix adds a necessary security permission, ensuring all users can see their own overtime hours as intended. This improves usability and data visibility for all employees.
Original PR description
Steps to reproduce: 1. Enable "Display Extra Hours" in Attendance settings. 2. Assign an overtime ruleset to an employee. 3. Ensure the employee does not have the "Officer: Manage attendances" group.…
Steps to reproduce: 1. Enable "Display Extra Hours" in Attendance settings. 2. Assign an overtime ruleset to an employee. 3. Ensure the employee does not have the "Officer: Manage attendances" group. 4. Create an attendance that generates extra hours for this employee. 5. Log in as the employee and open the Employees app to view Extra Hours. Issue: An Access Error is raised because `get_overtime_data_by_employee` in `hr_holidays_attendance/models/hr_employee.py` performs a `_read_group` on `hr.attendance.overtime.line`. In 19.0, the only ACL for this model grants access to `group_hr_attendance_officer`: https://github.com/odoo/odoo/blob/95c73aa4dd7433f394799fdaaad57a84d750ec5a/addons/hr_attendance/security/ir.model.access.csv#L1-L11 Users with `group_hr_attendance_own_reader` (implied by `base.group_user`, i.e. all internal users) have no read access to `hr.attendance.overtime.line`. In later versions, this was already fixed by adding a read-only ACL for `group_hr_attendance_own_reader` on this model: https://github.com/odoo/odoo/blob/ad4a2ec11fea2058445e4003099af3a5caa1ef22/addons/hr_attendance/security/ir.model.access.csv#L13 This is why forward-ports are not needed. Solution: Add the missing `access_hr_attendance_overtime_line_own_reader` ACL to grant read-only access to `group_hr_attendance_own_reader` on `hr.attendance.overtime.line`, matching the approach used in later versions. This is preferred over using `.sudo()` as it properly grants the intended access right rather than bypassing security checks entirely. opw-6055081 Forward-Port-Of: odoo/odoo#257301 Forward-Port-Of: odoo/odoo#255576
This update prevents unnecessary calls to IAP (a data service) when Odoo databases aren't set up to automatically receive VIES updates. By sending a dummy token, the system avoids polluting IAP with requests from databases without the necessary cron job, improving efficiency and reducing potential costs.
Original PR description
If the user contacts us from an unreachable db (localhost, firewall, .. .), we currently rely on a cron on the db to pull updates by calling `vies_check_update`. Currently, all dbs, even those that don't have the cron (i.e. haven't yet upgraded the `iap` module) will send the `client_identifier/token` upon calling `vies_check_validity`. However, since they don't have the cron, they won't be able to pull updates from IAP. Thus, if we detect that the crond does not exist, we will now send dummy `client_identifier/token` to avoid poluting IAP. task-none Forward-Port-Of: odoo/odoo#257493
This update resolves an issue where the mapping of PEPPOL invoice data was failing when the 'Invoice period extra field' was initially empty. The fix ensures the field is correctly initialized as a dictionary, preventing mapping errors and improving the accuracy of PEPPOL invoice processing. This ensures proper data exchange for international transactions.
Original PR description
When mapping the Invoice period extra field and updating the xml nodes, if the invoice period was originally empty, it would be initialized to an empty list not a dict which was breaking the mapping. task-6076624 Forward-Port-Of: odoo/odoo#256594
This update resolves an issue where Ctrl+A followed by Delete wouldn't remove all content from editable areas when the first element was non-editable. The fix ensures the selection correctly anchors and removes the entire editable content, improving the editor's functionality and user experience.
Original PR description
Description of the issue this PR addresses: - When an element with `contenteditable="false"` is the first node in the editable, pressing Ctrl+A followed by Delete does not remove the entire selection and instead deletes only the last character. Desired behavior after PR is merged: - Ensure that the selection is anchored to the deepest editable position when performing a select-all operation so that the full editable content is correctly selected and removed. Steps to reproduce: - Insert a toggle list using `/togglelist` in a new todo - Add one or more paragraphs below it and enter some text - Select all content using Ctrl+A - Press Backspace to delete the selection - Observe that only the last character is removed Backport of: 67e6a617def3bf4f9eb6b63b0850f5cfc773bccc task-5363926 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257070 Forward-Port-Of: odoo/odoo#241696
This update resolves a crash that occurred when deleting HTML fields used in website forms. The issue stemmed from the way these fields were initially parsed as XML, leading to an error. This fix ensures that field deletions are handled correctly, preventing website disruptions.
Original PR description
Steps to reproduce ================== tl;dr: html fields are parsed as xml - Go to Helpdesk > Tickets > Warranty - Open studio - Add a new text field named "TEST" - Remove it from the view - Exit studio - Go to the website - Click on new - Add a new blogpost - Set a title and save - Click on "Contact & Forms" - Click on the first block - Click on the form - Change the form action to "Create a ticket" - Click on "+ Field" - Change the Type selection to "TEST" - Click on save - Enable debug mode - Go to "Settings / Technical / Database Structure / Fields" - Type x_ in the search bar and press enter - Delete the field => lxml.etree.XMLSyntaxError Cause of the issue ================== When deleting a field, `_check_if_used_in_website_form` is called to prevent the deletion if a field is used in an html field. The html fields were parsed with an xml parser.. opw-5946029 Forward-Port-Of: odoo/odoo#257245 Forward-Port-Of: odoo/odoo#256066
This update resolves a technical bug that was causing errors when users selected multiple work entries within the employee scheduling feature. The fix eliminates duplicate work entry types, preventing a crash in the user interface. This ensures a smoother and more reliable experience for employees managing their work schedules.
Original PR description
### Steps to reproduce: - Download Payroll app - From the top bar 'Employees' > 'Employees', create a new employee - Select the created employee > click 'Work Entries' smart button, add 2 Attendance…
### Steps to reproduce: - Download Payroll app - From the top bar 'Employees' > 'Employees', create a new employee - Select the created employee > click 'Work Entries' smart button, add 2 Attendance work entries on different days, with different creation days (either wait 24h between creations, or adjust one create_date in DB) - Click on any day, you'll find the "Replace by Attendance" smart button replicated > If you activate debug mode and click on any cell > **UncaughtPromiseError > OwlError** ### Cause of issue: https://github.com/odoo/odoo/blob/72be98d705e225f663b65e289e11d0b8642ec6f8/addons/hr_work_entry/static/src/views/work_entry_calendar/work_entry_calendar_model.js#L30-L58 `formattedReadGroup` is called with both `work_entry_type_id` and `create_date:day`. If the user has created several work entries of the same type on different days, we would get multiple group results having the same `work_entry_type_id`. These duplicated records later produce an Owl crash because the button list uses `t-key="workEntry.id"`. https://github.com/odoo/odoo/blob/72be98d705e225f663b65e289e11d0b8642ec6f8/addons/hr_work_entry/static/src/views/work_entry_calendar/work_entry_multi_selection_buttons.xml#L16-L17 ### Fix: Since the goal of the above method is to extract the favorite work entries to later use in smart buttons and `userFavoritesWorkEntriesIds.map((r) => r.work_entry_type_id?.[0]).filter(Boolean)` extracts all the entries' `work_entry_type_id` (including duplicates), the easiest way to get rid of these duplicates is to create a `Set`. opw-5953671 Forward-Port-Of: odoo/odoo#253387 Forward-Port-Of: odoo/odoo#252478
This update resolves an issue where submitting the 'Create a Task' form would fail if an invalid email address was entered. The fix removes a problematic field that was incorrectly adding invalid email addresses to task records, preventing the form from submitting successfully. This ensures users can consistently create tasks with valid email information.
Original PR description
Currently, an error occurs when a user submits the Create a Task form. **Steps to Reproduce:** - Install the `website_project` module. - Go to `website` > `Click on Edit` > `Drag and drop` form. -…
Currently, an error occurs when a user submits the Create a Task form. **Steps to Reproduce:** - Install the `website_project` module. - Go to `website` > `Click on Edit` > `Drag and drop` form. - Click on the form and, set the action to `Create a Task`, then save. - Fill in the required data in the form. - In the `Email Address` field, enter an email that does not correspond to any existing partner. - `Submit` the form, and the `error appears in the logs`. `ValueError: Invalid field 'email_cc' in 'project.task'` With this [recent commit], the email_cc field has been removed from project.task, along with the mail.thread.cc inheritance, because threads are now able to find CC recipients. so, when user submits the form with an email address that does not correspond to any existing partner, the system adds email_cc to the record [1], and when it attempts to create the record [2], it raises an error. This commit ensures that email_cc is no longer added to the record. [recent commit]: https://github.com/odoo/odoo/commit/3c26c0553754a75d9440097ad473be3cc8bcb320#diff-93ba226020add6481cfeab916e69980a59163e2925a5c2c9a3bc0aaceb484cdf [1]- https://github.com/odoo/odoo/blob/21aa7e7eca0bf78978e0667cee43129985833166/addons/website_project/controllers/main.py#L61 [2]: https://github.com/odoo/odoo/blob/21aa7e7eca0bf78978e0667cee43129985833166/addons/project/models/project_task.py#L1167 sentry-7374084515 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update optimizes the HTML editor's performance by making several key changes to how it processes HTML content. Specifically, it reduces unnecessary calculations and delays certain checks, resulting in faster rendering times. This improves the overall responsiveness and efficiency of the Odoo application.
Original PR description
Description of the issue/feature this PR addresses: This PR improves the performance of several `normalize_handlers` by reducing expensive DOM/style checks, avoiding unnecessary layout recalculations. This PR: 1. Replaces the usage of `fillEmpty` with manual filling of empty blocks. 2. Replaces `isBlock` with `!isPhrasingContent`, which better matches the actual use case and avoids unnecessary work. 3. Optimizes list normalization by reducing checks for `isBlock`. 4. Avoids style recalculations in `normalizeInline` of `qweb_plugin`. 5. Delays the `isBlock` check at certain places so it is only performed when needed. 6. Reduces the number of `isBlock` calls in `selection_placeholder_container_predicates` and `selection_blocker_predicates`. 7. Fixes layout thrashing by separating style reads from style writes. task-5245157 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#255310
This update resolves an issue where deleting a public holiday incorrectly created timesheets for all related leave requests, even canceled ones. Now, deleting or modifying a holiday will only generate timesheets for valid, approved leaves, streamlining the timesheet process and preventing unnecessary entries. This ensures accurate timesheet reporting.
Original PR description
…d leaves Description of the issue/feature this PR addresses: When a public holiday is edited or deleted, the timesheet re-creation is erroneously done for *all* leaves, even those which are canceled or still in draft. Steps to Reproduce: 1. Create a Time Off request for a timesheet-creating leave type (i.e. `timesheet_generate = True`) that overlaps with a public holiday. 2. Refuse the Time Off request. 3. Delete the public holiday the request overlaps with. Current behavior before PR: The deletion of the holiday causes timesheet entries to be created, even though it's a refused request. Desired behavior after PR is merged: The deletion or editing of the public holiday only re-creates the timesheets for the leaves that are actually valid and thus need timesheet entries. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#255155 Forward-Port-Of: odoo/odoo#250372
This update resolves an issue preventing website users from seeing product ratings on certain items. Previously, access to rating data was restricted, causing an error for public visitors. This change ensures all users can view and interact with product ratings on the website.
Original PR description
**Steps to produce:** - Install the `Ecommerce` module. - Create a product. - In the Sales tab, set an alternative product and ensure both are published. - Open the product page on the website and enable `reviews` from the editor. - Open the same product page in incognito mode. **Issue:** ``` AccessError: You do not have enough rights to access the field "rating_avg" on Product Variant (product.product). ``` Root cause: --- - Currently, product records in dynamic snippets to be fetched without superuser privileges. Since the `rating_avg` field is restricted to internal users, public visitors encounter an `AccessError` when viewing snippets with ratings enabled. - Similar approach used [here]. [here]: https://github.com/odoo/odoo/commit/12bb994da4c3222e8c7fb2df95c202a6c45a28b0 opw-6065319 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257400 Forward-Port-Of: odoo/odoo#256570
This update fixes a potential issue where invoices with both price-included and zero-price excluded taxes were incorrectly calculating tax totals. The change ensures that tax calculations are accurate, regardless of whether a price excluded tax line is present, improving invoice accuracy and financial reporting. This resolves a previous bug reported in opw-6060486.
Original PR description
…xes_data Suppose an invoice with price-included taxes but with a zero price excluded one. We don't want to fallback on the excluded mode just for that. opw-6060486 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257495
This update fixes an issue where new projects created from CRM leads were incorrectly defaulting to the project template's company instead of the lead's company. This resulted in data inconsistencies and a user error. The change ensures that the project inherits the correct company information, improving data accuracy and the user experience.
Original PR description
When creating a project from a CRM lead using a template, the `default_company_id` set by `_get_project_create_from_lead_context` is ignored because `company_id` is not in the template default…
When creating a project from a CRM lead using a template, the `default_company_id` set by `_get_project_create_from_lead_context` is ignored because `company_id` is not in the template default context whitelist. This causes the new project to inherit the template's company instead of the lead's company, resulting in a company mismatch with the partner and a UserError. https://github.com/odoo/odoo/blob/2b89db4af2265e5cec8feb11853364e293de203e/addons/crm_sale_project/models/crm_lead.py#L37-L45 https://github.com/odoo/odoo/blob/2b89db4af2265e5cec8feb11853364e293de203e/addons/project/models/project_project.py#L1413-L1419 Steps To Reproduce: 1. Go to CRM, create or open a lead. 2. Clear the contact field and save. 3. Click the gear icon → Create Project. 4. Select any project template (not empty) and submit. Ticket [link](https://www.odoo.com/odoo/project.task/5933253) opw-5933253 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#250087