Monday, February 24, 2025
48 changes · 18.0
Enhancements to existing features
The point of sale interface now highlights the More action button when a customer reward is available. This helps cashiers spot loyalty rewards more quickly, making it easier to apply benefits during checkout.
Original PR description
In this commit: === - When a reward is available, the More action button is visually highlighted .
This update improves Odoo's internal unit testing tools, especially the Hoot test framework, so automated tests are more stable, easier to interpret, and less likely to interfere with each other. The changes are limited to test infrastructure, reducing risk for day-to-day product behavior while helping developers catch issues more reliably.
Original PR description
## Pull Request HOOT (PRHOOT) 28 This pull requests brings various improvements and fixes to Hoot and the Odoo unit test ecosystem. See the different commit messages for more details. Note: these changes are made in stable to avoid having to support multiple versions of the HOOT API. As such, these changes are intended to be strictly limited to unit tests as to not put the rest of the code base at risk. Enterprise: https://github.com/odoo/enterprise/pull/78636 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The country/state reference data now includes Papua Barat Daya as an official Indonesian province. This helps businesses keep addresses, localization data, and regional records aligned with Indonesia's current administrative structure.
Original PR description
Official Document, [link](https://peraturan.bpk.go.id/Details/232726/uu-no-29-tahun-2022) Wikipedia in English, [link](https://en.wikipedia.org/wiki/Southwest_Papua) 
This update keeps journal entries in sync when analytic items are changed or deleted. It helps prevent accounting discrepancies by automatically updating the related analytic distribution, reducing manual corrections and improving financial data reliability.
Original PR description
created a synchronzing function then overrode the write and unlink functions related to the analytic_line so that it calls the synchronization function when someone deletes or modify an account on an analytic item, a discrepency is created on the analytic distribution of the journal item. so a synchronization function had to be implemented to make sure that there is no discrepency when a customer edit or delete the analytic account on an analytic item task-4378407 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
Resolved issues and error corrections
A notice was added for combo products on the website when prices are configured to include VAT. This helps shoppers understand that taxes may not be shown on combo product prices upfront, but they will still be calculated correctly during checkout.
Original PR description
**Issue:** When the website is configured to display prices VAT included, combo products incorrectly show their prices VAT excluded. **Steps to Reproduce:** - in website setting check tax included of `Display Product Prices` - Sales > Products > Products - Create a new product of type "Combo" and set a price - click on go to website The price displayed on the website is VAT excluded, even though VAT inclusion is configured. To address this issue, a disclaimer has been added to inform users that while taxes are not displayed for combo products, they will be properly calculated during checkout. opw-4454112
Miscellaneous changes
Before this commit, searching emoji required at least 2 chars. There is no reason to not allow 1 char, especially when searching some emoji that are best found with a single char, e.g. "9️⃣" with "9". Forward-Port-Of: odoo/odoo#198759
Original PR description
Before this commit, searching emoji required at least 2 chars. There is no reason to not allow 1 char, especially when searching some emoji that are best found with a single char, e.g. "9️⃣" with "9". Forward-Port-Of: odoo/odoo#198759
This fixes a crash in the HTML editor that could happen when attempting to delete embedded component data that was not actually present. The editor now safely ignores this no-op situation, improving stability for users editing embedded content.
Original PR description
Issue: Deleting a non-existing property in the embeddedState of an EmbeddedComponent would produce a traceback. Expected: If no embeddedState snapshot was done (previousEmbeddedState is null), it means that no effective change was performed, and in that case `changeState` should return early to prevent the traceback. task-4600079
This fixes how tax subtotals are calculated on accounting documents. Subtotals now build from the untaxed amount plus earlier taxes, making displayed totals more consistent and easier to understand.
Original PR description
The first subtotal is always the untaxed amount of the document. All following subtotals are just the previous one plus the previous taxes. So the subtotal no longer depend of the taxes under it. opw-4571908 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes intermittent failures in the two-factor authentication test flow. The change helps keep automated checks stable so releases are less likely to be delayed by false errors.
Original PR description
Following https://github.com/odoo/odoo/pull/196980 There is still a few non-deterministic errors in auth_totp modules We will assume that the issue cause is the same thus solving them in the same way. Note: None of them were able to be reproduced more easily by toggling the browser CPU rb-135125,135120,135113
The sample payload shown for webhook server actions has been corrected to match the actual data sent when the action runs. This helps users configure and test webhook integrations with more accurate example information.
Original PR description
Before this commit, the sample payload displayed next to server actions of type 'webhook' didn't respect the format of the actual payload sent by `_run_action_webhook`. This commit fixes that by adjusting the `_compute_webhook_sample_payload` method so it includes the exact same keys and values that will be sent by the server action when ran. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
PayPal payments no longer fail when started by guests or PoS sessions that use the public user. The payment request now avoids sending missing customer email data and uses the company country code when needed, preventing malformed PayPal payloads.
Original PR description
When making a payment from the PoS, the user would always be the Public User. This would cause the payload sent to paypal to be incorrect and the payment to fail. This happens because we are trying…
When making a payment from the PoS, the user would always be the Public User. This would cause the payload sent to paypal to be incorrect and the payment to fail. This happens because we are trying to make a payment without any user, so this can be reproduced in other workflows. Like making a donation Steps to reproduce: ------------------- * Setup paypal payment provider * Create a PoS payment method with the paypal provider * Create a PoS order and pay with the paypal payment method > Observation: You get an error saying that something is malformed Alternative steps to reproduce: -------------------------------- * Make sure you are not connected on Odoo * Go to the `donation/pay` url * Fill out the form and make the payment via paypal > Observation: You get an error saying that something is malformed Why the fix: ------------ When using the public user, we cannot provide an email address or a country code. To fix this we make sure to not send the email address at all when there is none available. And we send the country code of the company instead of none. opw-4446219
Point of Sale product searches now find items when staff enter only part of an internal reference, rather than requiring the full exact code. This makes checkout product lookup faster and reduces missed search results when users know only part of a reference.
Original PR description
Currently searching with the reference requires to enter the full reference to find the product Steps to reproduce: ------------------- * Modify the Acoustic bloc screen product with an internal reference as TEST_01 * Open pos session * Search TEST > Observation: The Acoustic bloc screen is not in the result Why the fix: ------------ We don't require the `default_code` to be an exactMatch anymore, we make it an inclusion matching. opw-4587548
This fixes an intermittent issue where guest users could sometimes see a blank or missing Discuss conversation if the page loaded slowly. The change makes the public Discuss page wait and update correctly, improving reliability for users accessing shared conversations.
Original PR description
Before this PR, the `discuss_channel_as_guest_tour` would sometimes fail. Discuss is displayed once the thread is restored. However, one patch removes the `useState` from the store of the component, which leads to the `hasRestoredThread` flag not being observed. If `restoreDiscussThread` is too slow to execute, no render occur, no thread is displayed. This PR fixes the issue. runbot-106455 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 fixes an eCommerce product page issue where customers could see both “Add to cart” and “Contact Us” after selecting a product option that makes a zero-priced product sellable. The page now shows the appropriate purchase option, reducing customer confusion and improving the shopping flow.
Original PR description
Versions -------- - 18.0+ Steps ----- 1. Enable Prevent Sale of Zero Priced Product; 2. have a product with attributes; 3. set its list price to 0; 4. add a price extra to one of its attributes; 5. go to its eCommerce page; 6. select the price extra attribute. Issue ----- Both the "Add to cart" and "Contact Us" buttons are shown. Cause ----- - Commit 8f4c8ada7e9fe refactored the `website_sale.product` template, moving the "Contact Us" button outside of the `div.js_product` element. - This element gets passed as `$parent` to the `_onChangeCombination` method, which ought to handle these changes. - Because the `#contact_us_wrapper` is no longer in `$parent`, it fails to find it and change its classes accordingly. Solution -------- Instead of querying for the `#contact_us_wrapper` element directly in `$parent`, look for the `#product_details` element first, then query it. opw-4423323
The online store add-to-cart snippets now correctly read true/false settings instead of treating every value as enabled. This ensures quantity options appear only when intended, including outside standard product pages, reducing customer confusion during shopping.
Original PR description
We forgot to parse a boolean which was stored as a string so it was always considered true (both the strings `'true'` and `'false'` evaluate to `true` in a boolean context. This change also fixes the `showQuantity` computation in the product and combo configurators (the computation assumed the user was on the product page, which isn't necessarily the case for "add to cart" snippets).
This fixes a test issue around recalculating allocated hours on project tasks when timesheet-related behavior is overridden. It helps ensure the timesheet and project task logic is validated correctly, reducing the risk of incorrect hour allocation handling.
Original PR description
In this PR https://github.com/odoo/enterprise/pull/78465 the test is failing because it is not taking the override into account as it is not a post_install. opw-4192775
Images in the HTML editor now keep their resized dimensions after using the transform option. This prevents images from jumping back to their original size or shifting position when rotated, making content editing more reliable.
Original PR description
### Steps to Reproduce: - Open the To-Do App. - Upload an image (e.g., `/image`). - Resize the image to 25%, 50%, or 100%. - Click the `Transform` button in the toolbar. ### Approach: - Initially,…
### Steps to Reproduce: - Open the To-Do App. - Upload an image (e.g., `/image`). - Resize the image to 25%, 50%, or 100%. - Click the `Transform` button in the toolbar. ### Approach: - Initially, `this.transfo.settings.style = this.image.style` created a shared reference to the same `CSSStyleDeclaration` object, meaning changes to one were reflected in both. - Later, when `this.image.style = settings.style` was executed, the inline styles were lost because it reassigned the same reference instead of copying the styles individually, resulting in properties like `width` being reset. ### Description of the issue/feature this PR addresses: - Resizing an image (e.g., 25%, 50%, or 100%) would revert it to its original size after clicking the `Transform` button. - Rotating the image would cause it to be misplaced. ### Desired behavior after PR is merged: - The image retains its resized dimensions after transformation. - The image remains correctly positioned during rotation. task-4251410
Recruitment users can now update interviewers for multiple applications at the same time without triggering an error. This makes bulk editing in the Applications list more reliable and avoids interruptions for HR teams managing candidate records.
Original PR description
Currently, An error occurs when trying to change(update) all interviewers at once from the (hr)'Applications' list view. Step to produce: - Install the `hr_recruitment` module. - Open Recruitment / Applications / All Applications and add the Interviewers field in the list view, Select all records, and try to change or add interviewers to any of them. `ValueError: Expected singleton: hr.applicant(800, 799, 798, 797, 819)` The error occurs because the system attempts to access a single value from multiple records at [1]. Link [1]: https://github.com/odoo/odoo/blob/f1637a10db2f34ca3a272792079115e0192489f8/addons/hr_recruitment/models/hr_applicant.py#L384-L385 To resolve this issue, Use an iteration(for loop) to process each record one by one. Sentry-6229305438 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix makes the internal test setup for Odoo Discuss display properly when simulating multiple browser tabs. It helps developers verify cross-tab behavior more reliably, reducing the chance of issues reaching users.
Original PR description
Discuss test helpers provide an `asTab` parameter to mount two main clients, simulating odoo being opened in two different tabs and a dropdown is available to switch from one view to the other. However, height is not propagated to the parent div. As a result, discuss components are invisible, as height is not working properly. This PR ensures the parent div is properly configured, allowing to see discuss UI. 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
Have an x2many list (non editable) or kanban, such that editing a record of the relation is done through the form view dialog. Have a default_order on the x2many view containing at least a field that isn't in the view. Before this commit, there were two issues occurring when the user clicked on "Save" (in the dialog footer) after editing a record in the dialog. 1) if the first field of the order wasn't in the view, e.g. `default_order="x"` but x wasn't in the view: there was a crash, because
Original PR description
Have an x2many list (non editable) or kanban, such that editing a record of the relation is done through the form view dialog. Have a default_order on the x2many view containing at least a field that…
Have an x2many list (non editable) or kanban, such that editing a record of the relation is done through the form view dialog. Have a default_order on the x2many view containing at least a field that isn't in the view. Before this commit, there were two issues occurring when the user clicked on "Save" (in the dialog footer) after editing a record in the dialog. 1) if the first field of the order wasn't in the view, e.g. `default_order="x"` but x wasn't in the view: there was a crash, because we tried to sort records on a field that is unknown. 2) if it wasn't the first field of the order, e.g. `default_order="x,y"` but y wasn't in the view: the changes done in the dialog were lost, so it was no possible to edit records. Both issues had the same root cause. After the edition, we tried to sort the relation (as the order might have changed). We do that since [1], but it wasn't the main purpose of this commit. It has been done because it looked like a quick win at the time, and we thought it was a good idea. However, functionally speaking, sorting the records after the edition isn't wanted. If I just clicked on a record, edited it, I expect the record to remain where it was after closing the dialog. So as sorting isn't necessarily wanted, and it even produces issues in some cases, this commit reverts that "feature". [1] https://github.com/odoo/odoo/commit/17e198153ecfd9c5c32b3b22f43e2f1b8100a1c3 Closes #197867 opw-4499150 (case (2)) 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#198918 Forward-Port-Of: odoo/odoo#198757
At some point, servers started to return `image/svg+xml; charset=utf-8` instead of `image/svg+xml` in the `content-type` header of SVG images. Because of this, dynamic SVGs were not properly handled anymore. This commit adapts the mimetype comparisons to cope for this extra `charset` info inside the mimetype. Steps to reproduce: - Drop an image block inside a website page. - Replace the image. - Search for e.g. "city". - Pick an undraw illustration. => The image was lost because its
Original PR description
At some point, servers started to return `image/svg+xml; charset=utf-8` instead of `image/svg+xml` in the `content-type` header of SVG images. Because of this, dynamic SVGs were not properly handled anymore. This commit adapts the mimetype comparisons to cope for this extra `charset` info inside the mimetype. Steps to reproduce: - Drop an image block inside a website page. - Replace the image. - Search for e.g. "city". - Pick an undraw illustration. => The image was lost because its `src` became `false`. Forward-Port-Of: odoo/odoo#198267
Add "(copy)" to the name of the duplicated payment term. task-4227445 Forward-Port-Of: odoo/odoo#198913 Forward-Port-Of: odoo/odoo#197605
Original PR description
Add "(copy)" to the name of the duplicated payment term. task-4227445 Forward-Port-Of: odoo/odoo#198913 Forward-Port-Of: odoo/odoo#197605
Description of the issue/feature this PR addresses: allow portal attendees to be synced by google calendar Current behavior before PR: There was an `AccessError` happening when: - One portal user was invited to more than one event. - At least one of them was going to be notified in the future. - Google cancelled the first of those. <details> ``` 2024-12-11 10:19:02,144 31 INFO odoo odoo.addons.base.models.ir_cron: Manually starting job `Google Calendar: sincronización`. 2024-12-1
Original PR description
Description of the issue/feature this PR addresses: allow portal attendees to be synced by google calendar Current behavior before PR: There was an `AccessError` happening when: - One portal user was…
Description of the issue/feature this PR addresses:
allow portal attendees to be synced by google calendar
Current behavior before PR:
There was an `AccessError` happening when:
- One portal user was invited to more than one event.
- At least one of them was going to be notified in the future.
- Google cancelled the first of those.
<details>
```
2024-12-11 10:19:02,144 31 INFO odoo odoo.addons.base.models.ir_cron: Manually starting job `Google Calendar: sincronización`.
2024-12-11 10:19:02,151 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(29,)
2024-12-11 10:19:02,539 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(15,)
2024-12-11 10:19:03,029 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(50,)
2024-12-11 10:19:03,414 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(40,)
2024-12-11 10:19:03,823 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(52,)
2024-12-11 10:19:04,219 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(10,)
2024-12-11 10:19:04,580 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(28,)
2024-12-11 10:19:04,936 31 INFO odoo odoo.addons.google_calendar.models.res_users: Calendar Synchro - Starting synchronization for res.users(2,)
2024-12-11 10:19:05,501 31 INFO odoo odoo.models.unlink: User #2 deleted mail.message records with IDs: [1055490, 1055487, 1055480, 1055478, 1055403]
2024-12-11 10:19:05,518 31 INFO odoo odoo.models.unlink: User #2 deleted calendar.event records with IDs: [2920874, 2920875, 2920880]
2024-12-11 10:19:05,520 31 INFO odoo odoo.models.unlink: User #2 deleted mail.followers records with IDs: [6232226, 6232227, 6232228, 6232229, 6232230, 6232231, 6232232, 6232233, 6232234, 6232235, 6232236, 6232237, 6232238, 6232239, 6232240, 6232241, 6232242, 6232243, 6232270, 6232271, 6232272, 6232283]
2024-12-11 10:19:05,544 31 INFO odoo odoo.addons.base.models.ir_model: Access Denied by ACLs for operation: read, uid: 65, model: calendar.alarm
2024-12-11 10:19:05,545 31 INFO odoo odoo.addons.base.models.ir_model: Access Denied by ACLs for operation: read, uid: 65, model: calendar.alarm
2024-12-11 10:19:05,545 31 ERROR odoo odoo.addons.google_calendar.models.res_users: [res.users(2,)] Calendar Synchro - Exception : No puede ingresar a los registros 'Event Alarm' (calendar.alarm)
Se permite esta operación para los grupos siguientes:
- User types/Internal User
Póngase en contacto con su administrador para solicitar acceso si es necesario. !
Traceback (most recent call last):
File "/opt/odoo/custom/src/odoo/odoo/api.py", line 997, in get
cache_value = field_cache[record._ids[0]]
KeyError: 8
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/odoo/custom/src/odoo/odoo/fields.py", line 1161, in __get__
value = env.cache.get(record, self)
File "/opt/odoo/custom/src/odoo/odoo/api.py", line 1004, in get
raise CacheMiss(record, field)
odoo.exceptions.CacheMiss: 'calendar.alarm(8,).alarm_type'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/odoo/custom/src/odoo/odoo/fields.py", line 1187, in __get__
recs._fetch_field(self)
File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3210, in _fetch_field
self._read(fnames)
File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3220, in _read
self.check_access_rights('read')
File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3480, in check_access_rights
return self.env['ir.model.access'].check(self._name, operation, raise_exception)
File "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_model.py", line 1924, in check
raise AccessError(msg)
odoo.exceptions.AccessError: No puede ingresar a los registros 'Event Alarm' (calendar.alarm)
Se permite esta operación para los grupos siguientes:
- User types/Internal User
Póngase en contacto con su administrador para solicitar acceso si es necesario.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/odoo/auto/addons/google_calendar/models/res_users.py", line 100, in _sync_all_google_calendar
user.with_user(user).sudo()._sync_google_calendar(google)
File "/opt/odoo/auto/addons/google_calendar/models/res_users.py", line 79, in _sync_google_calendar
synced_events = self.env['calendar.event'].with_context(write_dates=events_write_dates)._sync_google2odoo(events - recurrences, default_reminders=default_reminders)
File "/opt/odoo/auto/addons/google_calendar/models/google_sync.py", line 185, in _sync_google2odoo
cancelled_odoo._cancel()
File "/opt/odoo/auto/addons/google_calendar/models/calendar.py", line 326, in _cancel
super(Meeting, my_cancelled_records)._cancel()
File "/opt/odoo/auto/addons/google_calendar/models/google_sync.py", line 152, in _cancel
self.unlink()
File "/opt/odoo/auto/addons/calendar/models/calendar_event.py", line 721, in unlink
self.env['calendar.alarm_manager']._notify_next_alarm(partner_ids)
File "/opt/odoo/auto/addons/calendar/models/calendar_alarm_manager.py", line 242, in _notify_next_alarm
notif = self.with_user(user).with_context(allowed_company_ids=user.company_ids.ids).get_next_notif()
File "/opt/odoo/auto/addons/calendar/models/calendar_alarm_manager.py", line 210, in get_next_notif
last_found = self.do_check_alarm_for_one_date(in_date_format, meeting, max_delta, time_limit, 'notification', after=partner.calendar_last_notif_ack)
File "/opt/odoo/auto/addons/calendar/models/calendar_alarm_manager.py", line 130, in do_check_alarm_for_one_date
if alarm.alarm_type != alarm_type:
File "/opt/odoo/custom/src/odoo/odoo/fields.py", line 1189, in __get__
record._fetch_field(self)
File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3210, in _fetch_field
self._read(fnames)
File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3220, in _read
self.check_access_rights('read')
File "/opt/odoo/custom/src/odoo/odoo/models.py", line 3480, in check_access_rights
return self.env['ir.model.access'].check(self._name, operation, raise_exception)
File "/opt/odoo/custom/src/odoo/odoo/addons/base/models/ir_model.py", line 1924, in check
raise AccessError(msg)
odoo.exceptions.AccessError: No puede ingresar a los registros 'Event Alarm' (calendar.alarm)
Se permite esta operación para los grupos siguientes:
- User types/Internal User
Póngase en contacto con su administrador para solicitar acceso si es necesario.
2024-12-11 10:19:05,547 31 INFO odoo odoo.addons.base.models.ir_cron: Job `Google Calendar: sincronización` done.
```
</details>
Desired behavior after PR is merged:
Google Sync works.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
@moduon MT-8345
cc @arj-odoo
Forward-Port-Of: odoo/odoo#190708
Forward-Port-Of: odoo/odoo#190356Splitting the function `click` on the Pricelist Button to make it inheritable, by creating a new function called `getPricelistList` that will allow filtering them whenever needed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#196813 Forward-Port-Of: odoo/odoo#173010
Original PR description
Splitting the function `click` on the Pricelist Button to make it inheritable, by creating a new function called `getPricelistList` that will allow filtering them whenever needed. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#196813 Forward-Port-Of: odoo/odoo#173010
Forward-Port-Of: odoo/odoo#198651 Forward-Port-Of: odoo/odoo#198352
Original PR description
Forward-Port-Of: odoo/odoo#198651 Forward-Port-Of: odoo/odoo#198352