Daily updates from Odoo
Monday, August 18, 2025
60 changes · saas-18.4
Resolved issues and error corrections
Image resizing or transforming in the website editor now records only the final result when the mouse is released, instead of saving every small movement. This makes undo history cleaner and easier to use when adjusting images.
Original PR description
When using image transform, steps are added to the history for every intermediate change during mouse moves. This commit adapts this behavior so that only the states reached when releasing the mouse button are recorded in the history. task-4367641
The website builder now includes a toggle to highlight animated text elements, restoring an option that was lost during the builder redesign. This makes it easier for users editing pages to find and manage animated text, while also correcting a related automated test so the behavior is properly checked.
This change restores the previous sales behavior to prevent crashes when creating rental orders from planning resources. It unblocks rental demonstrations and workflows where currency information may be missing or inconsistent.
Original PR description
"line.currency_id" might be empty or contain more than 1 value, resulting in a crash of the method. This reverts commit ced1335c38834d5ac31f27705a2f7a0047ca8cc2. Traceback discovered when creating a rental order from a resource (planning flow). <img width="1607" height="907" alt="image" src="https://github.com/user-attachments/assets/0980b89b-fc2a-4bfe-a4c7-a290c92bb0e4" /> Quick revert needed to unblock the flow and allow a demo of hotel industry rentals. Forward-Port-Of: odoo/odoo#222826
The website theme switcher now properly restarts its loading progress bar each time a theme is changed. This prevents the loader from appearing stuck when users switch themes more than once, making the website builder experience smoother and clearer.
Original PR description
__Current behavior before commit:__ When switching a theme, the website loader is displayed with a progress bar. When the operation is finished, the loader is hidden and the progress bar interval is cleared. However, the variable holding the interval ID is not being reset. If the user switch theme a second time, the `initProgressBar` method doesn't start a new interval because its initial guard finds the old interval ID and exit prematurely. This resulted in the progress bar appearing to be stuck. __Description of the fix:__ This commit fixes the issue by removing the initial guard of the `initProgressBar` method. __Steps to reproduce:__ 1. Open the Website builder 2. Click on the "Theme" tab 3. Click on "Switch Theme" 4. Choose a Theme 5. The loader is progressing 6. Do every steps again 7. The loader is stuck at the beginning Forward-Port-Of: odoo/odoo#222373 Forward-Port-Of: odoo/odoo#218356
This update fixes a display issue where decimal values in website builder controls could show long, inaccurate numbers such as 10.299999999 instead of 10.3. It makes editing numeric settings, such as carousel speed, clearer and more reliable for users.
Original PR description
Sometimes in `BuilderNumberInput` we receive a floating point precision error (IEEE-754). To see the issue: - Open website and drop a carousel snippet - Start incrementing its speed option with the arrow up key => Soon enough, you see that instead of 10.3 it displays 10.299999999... --- This happens because 0.1 can't be stored exactly right. Explanation of this can be found [here]. [here]: https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems
This fix ensures the website builder prepares uploaded images and other pending changes before saving a reusable snippet. It prevents snippets from storing raw image data, helping saved website blocks work reliably and remain properly optimized.
Point of Sale loyalty rewards now correctly add the free product when the qualifying item has multiple variants. This prevents missed rewards at checkout and helps ensure customers receive the promotion they earned.
Original PR description
Before this commit, when using a free product reward on multi products that have several variants, adding the desired product to the order would not always trigger the automatic addition of the free product as expected. opw-4841759 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222979 Forward-Port-Of: odoo/odoo#215576
This fixes tax calculations for down payments and global discounts when invoices use multiple currencies or manually adjusted tax amounts. Businesses should see more consistent totals between foreign and company currencies, reducing rounding discrepancies on sales, purchases, accounting, and point-of-sale documents.
Original PR description
When using 'manual_tax_amounts', both 'raw_tax_amount' & 'tax_amount' get the forced tax amount. However, by doing that, we lost accuracy in the raw amount. With this commit, the manual_tax_amounts…
When using 'manual_tax_amounts', both 'raw_tax_amount' & 'tax_amount' get the forced tax amount. However, by doing that, we lost accuracy in the raw amount. With this commit, the manual_tax_amounts become a way to ensure some results in '_round_base_lines_tax_details'. So after this commit, the manual_tax_amounts won't be manage in '_get_tax_details' anymore. That way, we could also use the manual_tax_amounts for amounts in company's currency. For down payment/global discount, let's handle both currencies instead of only the foreign one. Also, the percentage is applied for each line to keep the whole thing as most accurate and close to the input percentage. If we don't do that, we could end up with a base of 99.99 and a tax amount of 15.01 for a tax of 15%. Since the percentage is applied in a more "global" way, this commits also partially revert https://github.com/odoo/odoo/commit/3a269864534f234127c87ff1567f796904a27d5b This approach is more complex and doesn't give always better results when using round_per_line either. Let's keep it simple and come back to a global approach. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222881
This fix prevents HTML formatting tags from appearing in Italian electronic withholding tax descriptions. It keeps generated XML content clean and avoids disruptions in the Italian tax reporting flow.
Original PR description
The description field of the tax record was changed from char to html. This can break the dit functionality, as it now inserts the html tags into the description field. This PR aims to format the field as plaintext before rendering the XML to avoid such isses. opw-4985645 Forward-Port-Of: odoo/odoo#222948
This update fixes an internal database selection check so it correctly handles multiple configured database names. It helps prevent configuration-related issues when systems are upgraded or forward-ported across Odoo versions.
Original PR description
A fix was introduced in https://github.com/odoo/odoo/pull/222805 to check config['db_name'], but this was replaced by a list in 18.2 and it was missed by the forwardport Forward-Port-Of: odoo/odoo#223170
Website editors can now replace form fields that do not have predefined options without triggering an error. This prevents interruptions while configuring website forms and improves reliability for common field types such as email, date, and text fields.
Original PR description
Steps to reproduce: 1. Open the website form snippet in edit mode. 2. Add a new field and replace it with a field without options (e.g., `email_cc`, `contents`, `reply_to`, `date`, etc.). 3. You will receive a traceback for a TypeError. Root cause: Issue started appearing after commit https://github.com/odoo/odoo/commit/69e45976106c93d887d4fe31cdada3a6a2a393c2. In the `replaceField` method inside `FormOptionPlugin`, there is a refresh-visibility logic where we traverse the records using `field.records.map(...)`. For backend fields like `datetime`, `html`, or other free-text types, `field.records` is not set because they don’t have predefined option values. Calling `.map()` on `undefined` caused a TypeError. Fix: Added a fallback to return an empty array when `field.records` is not defined. Related to task-4367641
This update brings the spreadsheet component to the latest version and fixes several issues affecting pivot data, formulas, side panels, and clickable cells. Users should see more reliable spreadsheet calculations and a cleaner interface when working with spreadsheet panels.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/9c7c14319 [REL] 18.4.6 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/9c7c14319 [REL] 18.4.6 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/59701a014 [FIX] Pivot: sanitize measure id [Task: 4876828](https://www.odoo.com/odoo/2328/tasks/4876828) https://github.com/odoo/o-spreadsheet/commit/dce5aae09 [FIX] Functions: OFFSET dependencies are not correctly added [Task: 5001405](https://www.odoo.com/odoo/2328/tasks/5001405) https://github.com/odoo/o-spreadsheet/commit/313928857 [FIX] side_panel: replace side panel instead of stacking it [Task: 4911603](https://www.odoo.com/odoo/2328/tasks/4911603) https://github.com/odoo/o-spreadsheet/commit/83019c0ae [FIX] ClickableCells: cache empty positions as well [Task: 5007745](https://www.odoo.com/odoo/2328/tasks/5007745) Co-authored-by: Anthony Hendrickx (anhe) <anhe@odoo.com> Co-authored-by: Alexis Lacroix (laa) <laa@odoo.com> Co-authored-by: Lucas Lefèvre (lul) <lul@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@odoo.com> Co-authored-by: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya <rmbh@odoo.com> Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> Co-authored-by: Rémi Rahir (rar) <rar@odoo.com> Co-authored-by: Pierre Rousseau (pro) <pro@odoo.com> Co-authored-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
This fix makes an automated live chat test run consistently by clearing pending notification data before the test starts. It reduces false failures in validation systems, helping teams trust test results when checking live chat and Discuss navigation.
Original PR description
Before this commit, `test_session_history_navigation_back_and_forth` was sometimes failing. This test checks that browser history works correctly when navigating between a live chat session and the discuss app. The test creates a live chat channel via the `/get_session` route, then starts a tour which clicks the related record in the list view to open it in the Discuss app. However, `/get_session` initially sets `is_pinned` to False for the agent. When the active discuss channel is unpinned, another thread is set as the active thread. According to the timing, it can make the test fail. The fix resets bus notifications before starting the tour, ensuring consistent results. fixes runbot-230334,230340 Forward-Port-Of: odoo/odoo#223110 Forward-Port-Of: odoo/odoo#222991
This fix makes an automated live chat bot test wait until changes are fully saved before continuing. It helps prevent false test failures, improving confidence in release validation without changing customer-facing behavior.
Original PR description
This commit fixes the "change_chatbot_step_type" tour which fails because it doesn't wait for the form to be properly saved. This commit fixes the issue by waiting until the save button disappears. fixes runbot-229962 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#223097 Forward-Port-Of: odoo/odoo#222994
Purchase catalog prices now convert vendor prices into the purchase order currency. This prevents mismatched unit prices when buyers add products from vendors using a different currency, improving quote accuracy.
Original PR description
Before this commit, the unit price in the catalog for purchase order wasn't converted from other currencies to the order one It was just set to the price regardless of the vendor currency This fix will automatically convert the catalog prices from seller's currency to purchase.order's currency Steps to reproduce: - Create a product to Purchase - Add a vendor in the Purchase Tab - Set quantity to 1, price to 100 and currency to EUR - Create a RFQ - Select the Vendor from the product created - Check to currency to be USD - Add the product and take note of the Unit Price - Remove the product line - Go to Catalog - Compare the Price with the Unit Price (They doesn't match before the fix) opw-4909789 Forward-Port-Of: odoo/odoo#217285
Users with purchase access but without inventory manager rights can now save settings without encountering an access error. This prevents an unnecessary blockage in the settings workflow while preserving the intended configuration behavior.
Original PR description
**PROBLEM** Saving the settings with a user that have access to the purchase app, but doesn't have the manager right on the stock app will cause an access error. **STEP TO REPRODUCE** 1. On runbot connect as Mitchell Admin. 2. Remove your manager right to the inventory apps (set to User or None). 3. Go to the setting app and save. 4. There is a record access error (no right to modify stock.route). **CAUSE** The field `replenish_on_order` is set when creating the `res.config.settings`, this calls its inverse function which tries to write on the 'stock.route_warehouse0_mto' record. With the purchase_stock module installed, `replenish_on_order` appear is inserted in the purchase settings tab, so saving does create a `res.config.settings` and try setting this field. **FIX** To access to the purchase or stock settings, the user need to be a manager of those apps. Adding a sudo() to `_inverse_replenish_on_order()` fixes the issue. opw-4977223
Fixes an issue where choosing and applying a due date in the website builder's Countdown block appeared to work but was not actually saved. This ensures selected dates persist after repainting or saving and restores expected undo behavior.
Original PR description
In [1] the builder date picker was adapted in order to have the text version of the date updated upon date selection preview (without apply). In [2] that was changed to use the state to reflect the…
In [1] the builder date picker was adapted in order to have the text version of the date updated upon date selection preview (without apply). In [2] that was changed to use the state to reflect the value. But by doing that, on apply, the datetime picker service considered that the applied date was already known and did not call `onApply` anymore, thus not triggering the actual action. This commit fixes the issue by adding a state that contains the value to be displayed in the input. So we have two states: one that contains the DOM value (not in preview mode) and the new state that contains the value to be displayed in preview mode. The datetipicker no longer thinks that the value displayed in the input is the one already applied. So it calls onApply. Steps to reproduce: - Drop a "Countdown" snippet - Open "Due Date" - Select a date - Click on Apply => No undo was available, value was lost on repaint or save. [1]: https://github.com/odoo/odoo/commit/2d1a39f7224495ea04aa8765ae5ac11145a84398 [2]: https://github.com/odoo/odoo/commit/97a49dcec8f2ef7f6b6ec3113fd1b11eb121c610 task-4367641 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
The JSON-2 API now returns clearer and more structured error information, making it easier for customers and integrators to understand what went wrong. This improves troubleshooting for common issues such as missing database selection, expired sessions, or incorrect request formats.
Original PR description
This work incorporates several improvements for the error handling in JSON-2. The goal was to be able to "discover" how the JSON-2 API works with the help of every error message, starting with a…
This work incorporates several improvements for the error handling in JSON-2. The goal was to be able to "discover" how the JSON-2 API works with the help of every error message, starting with a simple `GET /json/2`. 1. The response body now holds the result of `http.serialize_exception`: an object with name, message, arguments, context, debug (traceback); instead of only `str(message)`. 2. The order in the `serialize_exception` object nows have the traceback last, this improve the readability of the json response on the wire. 3. Make the 404 - Not Found message more explicit when the database is missing. Make regular users go to /web/login (which is going to redirect to /web/database/selector) and programmers use the X-Odoo-Database header. The latter is for `auth='bearer'` controllers, as it doesn't use the session. 4. Make the 415 - Unsupported Media Type message more explicit. The HTTP stack sends this error when the `Content-Type` of a request is not compatible with the `@route(type=...)` of a controller. For JSON-2 any request that is not `Content-Type: application/json` will receive this message. The message now explicitely states that it is the request `Content-Type` that is likely at fault. 5. There was a complicated conditional in the JSON-2 `_handle_error` to attempt to jsonify the werkzeug's html, or to keep the existing response under some condition. Error handling is not the place to have anything complicated. The code was simplified to: have a response attached already? use it (even if it is not JSON); otherwise, use `serialize_exception` with status code and description. 6. `odoo.http.SessionExpiredException` now has a `http_status` like the other Odoo exceptions. It is 403 - Forbidden, the generic status for anything related to access errors. This simplifies the error handling in JSON-2 a bit. The other dispatchers have dedicated conditions and routines to handle this exception, and are not impacted by this change. We could (and maybe should) had split this single commit in six, one for every case above... but we were lazy.
Product forecasts now correctly account for chained stock movements created by multi-step delivery routes. This helps sales and warehouse teams see expected outgoing quantities accurately, preventing stock availability from appearing higher than it really is.
Original PR description
### Steps to reproduce: - In the settings enable Multi-Steps routes - Put your warehouse in delivery in 2 steps - Create and confirm a sale order for 1 units of a storable product #### > While the…
### Steps to reproduce: - In the settings enable Multi-Steps routes - Put your warehouse in delivery in 2 steps - Create and confirm a sale order for 1 units of a storable product #### > While the pick move was created and confirmed the forecast is still at 0 even tho it should be at -1 and the outgoing pick move should be matched with the SO line in the forecast report. ### Cause of the issue: The issue has been introduced by commit 5b40fb086a0e5677678c312b42dc1f2c8991dc9e The issue being that since the `location_final_id` should not have been considered for the past forecast based on done move chains (because each done move of the chain will refer to the same external `final_dest_id`). The proposed fix was therefore to change the dest_loc_domain as such: https://github.com/odoo/odoo/commit/5b40fb086a0e5677678c312b42dc1f2c8991dc9e#diff-1f24ce9f94c5795040749acca5924384d7d17c0ac39b1993cef3b484e4bd30afR324-R326 However, the new domain: https://github.com/odoo/odoo/blob/995a7072cb3315fc03544b281b1ed5ca4e81e901/addons/stock/models/product.py#L322-L326 ignores completely the part of the condition refering to `final_dest_id` for outgoing moves since the condition is negated here: https://github.com/odoo/odoo/blob/995a7072cb3315fc03544b281b1ed5ca4e81e901/addons/stock/models/product.py#L328-L333 The logical `OR` (`|`) becoming an `AND` (`&`) for the `domain_move_out_loc`. opw-4997982 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222241
This fix prevents an error when users load sample data for the Clothes point-of-sale setup without demo data installed. It improves setup reliability by avoiding missing sample product attribute references.
Original PR description
Currently, an error occurs when the user tries to load the sample data. Steps to reproduce: --- - Install `pos_restaurant` module (without demo) - Open `Clothes` and click on `Load Sample` in pos…
Currently, an error occurs when the user tries to load the sample data.
Steps to reproduce:
---
- Install `pos_restaurant` module (without demo)
- Open `Clothes` and click on `Load Sample` in pos config
Traceback:
---
```py
ValueError: External ID not found in the system: product.pa_color
ParseError: while parsing /home/odoo/src/odoo/saas-18.4/addons/point_of_sale/data/scenarios/clothes_data.xml:31, somewhere inside <record model="product.template.attribute.line" id="product_attribute_line_color">
<field name="product_tmpl_id" ref="point_of_sale.casual_t_shirt_product_template"/>
<field name="attribute_id" ref="product.pa_color"/>
<field name="value_ids" eval="[Command.set([ ref('product.pav_color_black'), ref('product.pav_color_white'), ref('product.pav_color_purple'), ref('product.pav_color_green'), ])]"/>
</record>
```
The issue arises because the `pos_restaurant` module uses a custom `scenario` flow, where demo data is loaded only for a specific scenario. This means that demo records—like `Color` defined in `product_attribute_demo.xml`—are only available when demo data is explicitly installed. If the database is set up without demo data, these records won't exist. As a result, any part of the POS data that directly references such demo records (e.g., 'Color') will lead to errors due to missing dependencies.
- Commit https://github.com/odoo/odoo/commit/ffb976c3ed5fbcff2e5d06a3183bab2fbe0307ff moved demo data from `point_of_sale` to `product`
- Related PR: https://github.com/odoo/odoo/pull/221801
sentry-6790044159
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prPayments made to settle a customer's Point of Sale account are now automatically matched with the related customer account charge. This prevents settled POS amounts from incorrectly appearing as available credit for other invoices, reducing accounting confusion for users.
Original PR description
### Problem: When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create…
### Problem:
When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create another account move line crediting Account Receivable (represents the payment). The second move line is considered, by Odoo, as an outstanding amount, and this amount can be used to pay another invoice (sale order invoice). The moves affecting Account Receivable are still correct. However, unreconciling the two lines created from PoS will cause a confusion for clients who may use this amount to pay other invoices.
### How to reproduce:
* Open a PoS session.
* Create an order and pay using customer account.
* Settle this customer's account (inside PoS).
* Create a Sale Order and invoice it (or just an invoice).
* The amount settled can be used as outstanding amount and can be used to pay the created invoice.
enterprise PR: https://github.com/odoo/enterprise/pull/86114
opw-4794793
Forward-Port-Of: odoo/odoo#222980
Forward-Port-Of: odoo/odoo#210619The default Admin employee now gets the required payroll structure information when HR data is installed. This prevents edit errors in databases created without demo data after installing Payroll.
Original PR description
Reproduce: 1. create a DB without demo data 2. install hr_payroll 3. try to edit the Admin employee Issue: When a database is created without demo data, the admin employee lacks a `structure_type_id`. Since this field is required by the `hr_payroll` module, any attempt to edit the admin employee fails unless the field is manually set. Now: This commit adds a default `structure_type_id` for the admin employee in base HR data, ensuring compatibility with `hr_payroll` regardless of demo data. Task: 4925858 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Employees with overlapping contract versions and different work schedules can now request time off when the requested dates fit within the relevant schedule period. This prevents valid leave requests from being incorrectly blocked, reducing HR administration friction.
Original PR description
When an employee has multiple versions with the same contract start and end dates but different working schedules, the system incorrectly blocks time off requests, even if the time off period lies entirely within a single schedule or even a single version. This fix adjusts the significant constraint logic to filter the versions with overlapping contracts to those only overlapping with the leave period. Task-4981318
Non-admin users can now update recurring calendar events without running into an access error. This keeps routine calendar management working smoothly for users who do not have administrator or settings permissions.
Original PR description
**Issue:** An access error occurs when a non-admin user attempts to modify the meeting settings of a recurring calendar event. **Steps to reproduce:** - Log in as non admin user - Go to Calendar > Create new meeting. - Set Reminders - Check the Recurrent checkbox and save the event. - Edit the Recurring Event settings and save again (2–3 times) An access error is raised as non admin users aren't allowed to read ir.cron.trigger opw-4899572 Forward-Port-Of: odoo/odoo#222855
This fix ensures the employee archiving process uses the employee the user actually selected. It prevents the departure workflow from targeting the wrong or invalid employee, reducing the risk of accidental record changes.
Original PR description
Description of the issue/feature this PR addresses: This pr addresses the issue of the `HrDepartureWizard` attempting to archive an employee that was not initially selected. Current behavior before PR: The `HrDepartureWizard`'s `employee_ids` field is filled with a different employee id than the selected employee, also sometimes may be assigned a non existing id. Desired behavior after PR is merged: The mentioned field is filled with the id of the selected employee. Solved by: Setting the `active_ids` context field within action `action_archive` of `HrEmployeeDeleteWizard`. The related subtask: https://www.odoo.com/odoo/project/1251/tasks/4844003 Forward-Port-Of: odoo/odoo#212734
Fixes an issue where selecting and applying a due date in the website builder's Countdown block did not actually save the change. Users can now apply the chosen date reliably, so it remains after saving or refreshing and undo support works as expected.
Original PR description
In [1] the builder date picker was adapted in order to have the text version of the date updated upon date selection preview (without apply). In [2] that was changed to use the state to reflect the value. But by doing that, on apply, the datetime picker service considered that the applied date was already known and did not call `onApply` anymore, thus not triggering the actual action. This commit fixes this but not updating the state during preview. However as a side effect, the text version of the date is not updated during previews anymore. Steps to reproduce: - Drop a "Countdown" snippet - Open "Due Date" - Select a date - Click on Apply => No undo was available, value was lost on repaint or save. [1]: https://github.com/odoo/odoo/commit/2d1a39f7224495ea04aa8765ae5ac11145a84398 [2]: https://github.com/odoo/odoo/commit/97a49dcec8f2ef7f6b6ec3113fd1b11eb121c610 task-4367641
Updating a resource's working schedule now also updates the linked employee's calendar. This prevents mismatched schedules in HR records and helps keep planning and employee availability accurate.
Original PR description
Before this commit, when the user updates the working schedule of a human resource, the resource calendar of the employee linked to that resource is not altered as well. This commit makes sure the working schedule between employee and resource is synchronised. task-4916569
This update makes live chat test navigation more reliable by opening the relevant session view directly instead of relying on the command palette. It helps ensure live chat sessions consistently open the conversation thread as intended, reducing false test failures.
Original PR description
The `test_session_history_open`, in later versions renamed `test_form_view_embed_thread`, ensures that clicking on a live chat session in the list view opens the thread, not the default form view. To do so, we first access the `/web` url, then open the command palette, and finally find the correct live chat view. However, such tests are known to be non-deterministic as the command palette is not always available at the start of the tour. Several live chat tours have been updated to directly access the view, providing the correct URL to `start_tour`: command palette part of the tour is meaningless. fixes runbot-161482 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#223016
This fix stabilizes automated checks for website live chat ratings by verifying messages after the chat thread is fully saved. It helps prevent false test failures and supports more reliable live chat quality assurance without changing the customer-facing chat experience.
Original PR description
The website live chat rating tours share common steps, among them, the `start` steps. Those steps check if the first message is not duplicated by: - Waiting for the `.o-mail-Thread` selector. -…
The website live chat rating tours share common steps, among them, the `start` steps. Those steps check if the first message is not duplicated by: - Waiting for the `.o-mail-Thread` selector. - Checking if there is only one message. - Adding a class to this message if that is the case. - Adding a step that looks for the added class. This approach is flawed because: - The thread will be persisted once the first message is sent. If the class is added to the transient message but the next assertion runs after persistence, the message with the class is no longer in the DOM. - The class can be overridden if the message re-renders before the next assertion. - There is no guarantee the message is in the DOM when executing `queryAll`. There is no reliable way to check the state before persistence because the thread may change between "trigger" and "run". This commit updates the assertions to ensure the message is sent correctly and no duplicates exist once the thread is fully persisted. fixes runbot-229822 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#223036
This fixes a validation issue where a legitimate advanced view customization could be incorrectly shown as faulty in Odoo. Business users and administrators should see fewer false error warnings when maintaining customized screens.
Original PR description
Have an arch that will move a subchild of a parent effectively replacing the parent ```xml <data> <xpath expr="/form/div/div" position="replace"> <xpath expr="/form/div/div/span" position="move" /> </xpath> </data> ``` Before this commit, the move xpath was marked as faulty in the IrUiView's form in the interface. After this commit, the xpath is not marked as invalid, because it is not. read `@def apply_inheritance_specs` to get a grasp on the supported semantics for xpaths arch. opw-4965869 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#220834
Website names containing special characters, such as backslashes, no longer cause the website configurator to crash. This makes setup more reliable for users who use punctuation or unusual characters in their website name.
Original PR description
Currently, using special characters like backslashes `(\)` in the website name would cause a regex substitution error during website configuration. **Steps to Reproduce:** - Install the `website`…
Currently, using special characters like backslashes `(\)` in the website name would cause a regex substitution error during website configuration. **Steps to Reproduce:** - Install the `website` module. - Go to Settings and change the website name (e.g; "`test\`"). - Navigate to the URL: "http://localhost:8069/website/configurator" - Select a theme and a color palette for the website, then apply the changes. Error: `error - bad escape (end of pattern) at position 19` **Cause:** At [1], a backslash in the `website.name` string leads to a malformed replacement string in `re.sub()`, causing a regex syntax error due to an invalid escape sequence. [1]: https://github.com/odoo/odoo/blob/b8edcd131b3288d037bee9ee03726153932d82f1/addons/website/models/website.py#L678 **Fix:** This PR escapes the `website.name` using `re.escape()` before using it in regex substitution, prevents runtime errors during website configuration. sentry-6651288996,6557563272 Forward-Port-Of: odoo/odoo#213083
Manufacturing users can now stop work order operations linked to billable projects even when the operation runs longer than expected. The fix prevents an accounting-related access error from interrupting production tracking while preserving the intended analytic cost recording.
Original PR description
To reproduce:
=============
- create a BOM with an operation having an expected duration
- make sure the product of BOM has MTO and Manufacturing routes
- create a Billable project with visibility=portal
- create an SO with the product of BOM and set the project for analytic distribution
- confirm the SO -> a MO is created
- with a user having:
- hr.group_hr_user
- mrp.group_mrp_manager
- project.group_project_user
- hr_timesheet.group_hr_timesheet_approver
- go to the MO and start the first operation and wait to exceed the expected duration
- stop the operation -> access error on the analytic account line
Problem:
========
when the user tries to stop the operation, at first moment AAL will be created, as we exceed the expected duration, we will try to update the AAL which leads to an access error as the user does not have accounting rights.
Solution:
=========
deal with AAL records as sudo
opw-4897142
Forward-Port-Of: odoo/enterprise#92422The Belgian payroll salary configurator now calculates the laptop benefit in kind consistently with other benefits such as internet and mobile phone. This prevents incorrect salary package values when employees or HR teams configure compensation involving a company laptop.
Original PR description
The benefit in kind laptop salary rule was not adapted for the salary configurator. This commit fixes the issue by always returning the correct laptop value if the salary rule is used in a salary configurator, like it is already the case for the internet and mobile benefits. task-4971722 Forward-Port-Of: odoo/enterprise#92216 Forward-Port-Of: odoo/enterprise#91201
Peru PLE reports 5.1 and 6.1 now keep the original account move name exactly as entered instead of removing spaces or slashes. This helps preserve complete audit information and reduces the risk of discrepancies with tax authorities.
Original PR description
Problem: For PLE reports 5.1 and 6.1, the value for `glosa` was being modified (i.e. blank spaces and slashes removed). Although SUNAT accepts the modified value, no information should be removed in the case it might lead to issues with tax authorities during an audit. Solution: The value for `glosa` on the reports should be the exact account move name. opw-4803060 Forward-Port-Of: odoo/enterprise#92271 Forward-Port-Of: odoo/enterprise#91967
A test in the timesheet holiday area was updated so it no longer depends on the current date or Belgian timezone. This prevents false failures in automated checks and helps keep releases moving smoothly.
Original PR description
Before this commit, when the `test_timer_methods_handle_project_access_restrictions` test is executed after 22h in UTC the test failed because the timezone of the current user is the belgian one. This commit makes sure the date and timezone no longer affects this test since it is not the purpose of this test. runbot-error-230490 Forward-Port-Of: odoo/enterprise#92264
Swiss payroll-specific employee fields are now only shown for Swiss companies in multi-company setups. This prevents users in other countries from seeing irrelevant Swiss payroll information, reducing confusion and improving data entry clarity.
Original PR description
When using odoo in multi company with Swiss installed, we can see the fields from any other company. They should be hidden if the country is not Swiss. Task: 4788657
When Excel files shared by portal users are converted into Odoo spreadsheets, portal users are now kept at view-only access. This prevents conversion errors and preserves the rule that external portal users cannot edit spreadsheets.
Original PR description
Let's say a Document Folder is shared with a portal user with 'edit' access. The portal user shares a .xlsx file to the folder, and an internal user later try to convert the file to odoo spreadsheet. During the conversion, the portal user has 'edit' role on the folder, which is copied to the documents.access records of the converted sheet. Since Odoo prevents Spreadsheets from being shared in edit mode to portal users, _check_spreadsheet() raises a Validation Error. <img width="544" height="188" alt="image" src="https://github.com/user-attachments/assets/48426ff8-0cd9-4fb0-8e52-31099e586064" /> To resolve this issue, we force portal users to have `view` role on Spreadsheets during the XLSX to Spreadsheet conversion. opw-4753670 Forward-Port-Of: odoo/enterprise#92427 Forward-Port-Of: odoo/enterprise#92134
Rental invoice lines are now excluded from automatic cost-of-goods-sold entries in Anglo-Saxon accounting. This prevents rental sales from generating inappropriate inventory cost accounting, helping keep financial records accurate.
Original PR description
…entries Modified the COGS generation logic to skip any invoice lines that come from a rental sales order. task-4919306 Forward-Port-Of: odoo/enterprise#91472 Forward-Port-Of: odoo/enterprise#90901
This fix corrects a small typo in the accounting automation that selects the company context for currency rate updates. It helps ensure scheduled accounting processes use the right company information, reducing the risk of incorrect currency rates in multi-company environments.
Original PR description
In this commit: https://github.com/odoo/enterprise/commit/5466daa617faef99a2bb5c06beefb3e2d082f459, we fixed a bug where the cron would be trigger with the wrong company which impacted the currency rate. But we did a typo in one of the change of the company. no task id Forward-Port-Of: odoo/enterprise#92475
This fix ensures manually stored external tax amounts also keep the related taxable base amounts. It helps tax calculations and reporting stay accurate when using external tax providers such as AvaTax, including localized integrations.
Original PR description
…unts
This fixes an error that could appear when viewing product variant data with the POS Pricer module installed. The price display field now always receives a safe default value, preventing disruptive tracebacks for users or administrators inspecting product records.
Original PR description
**Step to reproduce:** 1. Install pos_pricer module: 2. Open the Point of Sale app and create a product. 3. Go to the Product Variants menu. 4. Open that product. 5. Activate developer mode. 6. Click…
**Step to reproduce:** 1. Install pos_pricer module: 2. Open the Point of Sale app and create a product. 3. Go to the Product Variants menu. 4. Open that product. 5. Activate developer mode. 6. Click on the Bug icon (top-right corner). 7. Click on Data. **Issue:** A traceback is raised with the error: `Compute method failed to assign product.product(191,).pricer_display_price` The method `_compute_pricer_display_price` was removed in this commit https://github.com/odoo/enterprise/commit/87b1672ac7c1d27cd9eab05138b78f6a9439fea7 , and was reintroduced in a later commit https://github.com/odoo/enterprise/commit/4575d3dfdbd0ccd9bf57bddbd35a89bd47c48798 to avoid the AttributeError. **Cause:** The computed field `pricer_display_price` is a type Char and and is non-stored was not being assigned a value inside the compute method. So ORM requires that records to be assigned a value in a compute method. **Solution:** To fix this, assign a default value to `pricer_display_price` inside the compute method to prevent the error. opw-4887318 Forward-Port-Of: odoo/enterprise#88517
The employee name filter now works correctly when creating a new pay run. This helps payroll users find the right employees faster and avoids confusion during payroll preparation.
Original PR description
Originally, when creating a new payrun, if you filter by employee name, the filter doesn't work. The filter logic has been adjusted to search for the correct field.
Opening a spreadsheet filter editor now replaces the existing side panel instead of stacking another panel on top. This prevents broken Cancel and Remove actions, making filter editing more reliable for users.
Original PR description
Steps to reproduce: - Open the global filter side panel (list of all filters) - Pin the panel - Click on a specific filter to view/edit it Before this commit: - A second side panel was opened instead of replacing the current one - Clicking 'Cancel' on the new panel had no effect - Clicking 'Remove' caused a traceback After this commit: - The new side panel replaces the current one (main or secondary) - The previous panel is restored correctly on 'Cancel' or 'Remove' - If the new panel is already open, we simply close the current one Task: 4911603
A payroll-related test was moved to the correct accounting test area because it relied on accounting features. This prevents Belgian payroll checks from failing when only a single app is being tested, improving reliability without changing user-facing functionality.
Original PR description
Previously a test created on l10n_be_hr_payroll depended on account module, which broke single app tests. This commit moves the test from l10n_be_hr_payroll to test_l10n_be_hr_payroll_account [Old PR](https://github.com/odoo/enterprise/pull/89149) Task: 4942293
This fixes an issue where expanding or collapsing grouped account report lines could leave child lines visible and trigger an error. Users can now fold and unfold nested grouped report lines reliably, improving report usability and avoiding interruptions.
Original PR description
Steps to reproduce: - Create an Account Group - Create a new Account Report as follows: * Name: any * Lines: 1. [test line] * Group By: partner_id,account_id * Expressions: 1. [test expression] *…
Steps to reproduce:
- Create an Account Group
- Create a new Account Report as follows:
* Name: any
* Lines:
1. [test line]
* Group By: partner_id,account_id
* Expressions:
1. [test expression]
* Computation Engine: Odoo Domain
* Formula: [('account_id.account_type', '=', 'asset_receivable')]
* Subformula: sum
- Actions > Create Menu Item
- Open the new report
- Try to unfold/fold a partner line
Issue:
Folding will not fold the first child (representing the created account group). Also, error will raise
```
Uncaught Promise > Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
Occured on odoo.nas.cpolar.cn on 2025-04-26 04:58:53 GMT
OwlError: Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
Error: Got duplicate key in t-foreach: ~account.report~37|~account.report.line~255|{'groupby': 'partner_id'}~res.partner~4226|~account.group~90
at AccountReport.template (eval at compile (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:13743:20), <anonymous>:138:49) (/web/static/lib/owl/owl.js:5752)
at App.callTemplate (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:11363:50) (/web/static/lib/owl/owl.js:3372)
at AccountReport.template (eval at compile (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:13743:20), <anonymous>:9:12) (/web/static/lib/owl/owl.js:5752)
at RootFiber._render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:9774:38) (/web/static/lib/owl/owl.js:1783)
at RootFiber.render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:9766:18) (/web/static/lib/owl/owl.js:1775)
at ComponentNode.render (https://odoo.nas.cpolar.cn/web/assets/debug/web.assets_web.js:10493:23) (/web/static/lib/owl/owl.js:2502)
```
Analysis:
Folding issues occurs because of a mismatch in the grouping markup quote escape. If we don't have the very same string the controller cannot properly recognize the parent line and then is unable to fold/unfold properly.
This eventually led to the mentioned error at unfold as the backend will try to generate the apparently missing lines to unfold, only to create duplicate lines
opw-4754241
Forward-Port-Of: odoo/enterprise#89726Opening a Swiss payroll wage type could fail because the activity and message area was no longer available on salary rules. This fix restores that support so payroll configuration forms open normally and users can continue using the existing communication history area.
Original PR description
To reproduce: ============= 1- Install Swiss payroll 2- go to payroll configurations 3- wage types 4- open the form view of one wage type Problem: ======== The hr_salary_rule no longer inherits mail.thread due to this PR : https://github.com/odoo/enterprise/pull/83136 So we cannot load the chatter and a traceback will happen Fix: ===== inherit mail.thread in hr_salary rule so the chatter can work properly There's another solution to do which is removing the chatter from the view But the chatter exists in the previous versions and we try to make it work in 18.4 opw-5015226
The project settings tooltip now accurately explains how document folders work with project tasks. This avoids confusion by no longer suggesting that task-related documents are automatically moved into the selected folder.
Original PR description
Before this commit, the tooltip displayed for `documents_folder_id` defined in `project.project` model, said all documents linked to a task of a project will be automatically added inside that folder but it is no longer the case since the refactoring of Documents to simplify the implementation but also let the documents user sorts his documents as he wants since now the access rights are defined by folder. This commit updates the tooltip accordingly. PR simplifying the bridge between documents and project apps: #75214 opw-5000224 Forward-Port-Of: odoo/enterprise#92189 Forward-Port-Of: odoo/enterprise#92164
Tickets created from Timesheets now default to the Helpdesk Team linked to the selected project. This helps prevent tickets from being assigned to the wrong team and keeps timesheet-related support work routed correctly.
Original PR description
Steps to Reproduce: - 1. Go to Timesheets > My Timesheets, start the timer, and select the project linked to the helpdesk team. 2. In the timer header, quick-create a new ticket via the "Ticket" field dropdown 3. Observe that the default helpdesk team on the new ticket is incorrect. Issue: - - When creating a ticket from the Timesheets module (e.g., via timer header or views), the system selects an incorrect default helpdesk team, leading to misassigned tickets. Cause: - - The core default logic for team_id prioritizes user membership or the first team without considering the selected project's linked helpdesk team. Fix: - - Override `_default_team_id` to set the correct Helpdesk Team based on the selected project. - A domain has been added to the team selection field within the timesheet views to only show teams that have the timesheet feature enabled. task-4885679 Forward-Port-Of: odoo/enterprise#92112 Forward-Port-Of: odoo/enterprise#89503
The employee form now shows the seniority-at-hiring field under Education instead of Citizenship. This makes the Belgian payroll employee record better organized and places the information where users are more likely to expect it.
Original PR description
Move Seniority at hiring from Citizenship to Education group in employee form. In this PR, we moved seniority at hiring from the Citizenship to the Education group in the employee form. Related task: 4936767.
Payroll teams can now correct validated work entries as long as they have not yet been used in a payslip. This helps fix attendance or payroll input mistakes earlier without undoing unrelated payroll work, while preserving protection for entries already tied to payslips.
Original PR description
Originally, the validated work entries cannot be modified, either they have been included in payslips or not. This logic has been adjusted to allow for modifying the work entries marked as "validated" if they are not linked to a payslip. Task #4921300
Fixed an issue where the General Ledger could crash when users enabled the Account Types filter and expanded an account. This ensures accounting users can review payable and receivable activity without interruption.
Original PR description
Steps to reproduce:
- Open general ledger configuration
- Under Options tab, set filter Account Types as "Payable and receivable"
- Open General Ledger report
- Unfold an account
Traceback will raise
```
File "[...]/odoo/tools/query.py", line 101, in add_join
assert self._joins[alias] == (sql_kind, table, condition)
AssertionError
```
Because of the account types filter we already add a "LEFT JOIN" between account_move_line and account_account
Then, trying to add a "JOIN" between the same tables, the system find a different type of JOIN and fails the assert
opw-4742411
Forward-Port-Of: odoo/enterprise#87431Odoo now automatically matches Point of Sale customer account charges with their related settlement payments. This prevents settled POS balances from incorrectly appearing as available credit for other invoices, reducing customer account confusion.
Original PR description
### Problem: When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create…
### Problem:
When paying a PoS order using customer account, an account move line debiting Account Receivable will be created. Settling this amount inside the PoS (by depositing money) will create another account move line crediting Account Receivable (represents the payment). The second move line is considered, by Odoo, as an outstanding amount, and this amount can be used to pay another invoice (sale order invoice). The moves affecting Account Receivable are still correct. However, unreconciling the two lines created from PoS will cause a confusion for clients who may use this amount to pay other invoices.
### How to reproduce:
* Open a PoS session.
* Create an order and pay using customer account.
* Settle this customer's account (inside PoS).
* Create a Sale Order and invoice it (or just an invoice).
* The amount settled can be used as outstanding amount and can be used to pay the created invoice.
commmunity PR: https://github.com/odoo/odoo/pull/210619#pullrequestreview-2853451890
opw-4794793
Forward-Port-Of: odoo/enterprise#92374
Forward-Port-Of: odoo/enterprise#86114DHL rate checks during ecommerce checkout now use a planned date in the future, matching DHL's requirements. This prevents customers from seeing an error when shipping rates are requested with the default current date and time.
Original PR description
Before this commit: During checkout on Ecommerce website the default date of the order is current date and time. There is no option to change the date when getting rate. Which results in an error that the date must be in the future. After this commit: `Planned_date` for getting rate is set in furture to avoid the error. Docs reference: https://developer.dhl.com/api-reference/dhl-express-mydhl-api#reference-docs-section under rating endpoints. opw-4849754 Forward-Port-Of: odoo/enterprise#91705
The restaurant floor plan now only shows appointments scheduled for the current day. Late appointment labels are also highlighted correctly, helping staff focus on relevant reservations and spot delayed customers faster.
Original PR description
Steps to reproduce: =================== 1. Install `pos_restaurant_appointment`. 2. From the Appointments menu, schedule an appointment for tomorrow for a table. 3. Open the restaurant floor plan. Issue 1: ======== - Appointments scheduled for tomorrow are incorrectly shown on the floor plan. Issue 2: ======== - When a customer is late, the appointment label is not displayed in red. Common Cause: ============= - The appointment's `start` field is already a `DateTime` object, but it is being deserialized again, which leads to incorrect time-based comparisons. Fix: ==== - Avoid deserializing the `start` field if it is already a `DateTime` object. Task: 4845006 Forward-Port-Of: odoo/enterprise#86997
This change corrects the provision code used in Swiss payroll salary rules. It helps ensure payroll provisions are calculated and recorded consistently, reducing the risk of incorrect payroll accounting.
Payslips now show the correct weekly hours when an employee uses a flexible working schedule. This prevents payroll documents from displaying outdated schedule hours and improves accuracy for employees and HR teams.
Original PR description
> note: this PR should only be FW'd till `saas~18.4`, after that for `saas~18.5` (i.e., `master`), [this PR](https://github.com/odoo/enterprise/pull/85557) should be merged. ### Steps to reproduce: -…
> note: this PR should only be FW'd till `saas~18.4`, after that for `saas~18.5` (i.e., `master`), [this PR](https://github.com/odoo/enterprise/pull/85557) should be merged. ### Steps to reproduce: - Enable "Flexible Hours" in a working schedule. - Assign the schedule to an employee. - Generate a payslip for the employee. - Observe that the "Working Schedule" section always shows `hours_per_week` from the total hours calculated from the Work Schedule defined before turning on "Flexible Hours" ### Description: - the payslip incorrectly displayed the weekly working hours from the Work Schedule regardless of whether the employee's schedule used flexible hours. ### Cause: - the report template did not check for the `flexible_hours` flag and always rendered the value from `contract_id.hours_per_week`. ### Fix: - added a condition in the payslip template to check if `flexible_hours` is enabled. - if true, it displays `full_time_required_hours` from the working schedule instead of the contract's `hours_per_week`. task: 4719717 Forward-Port-Of: odoo/enterprise#83910
Fixed an issue where exporting the Journal Audit report to PDF could fail when filtering by receivable or payable account types. This ensures users can generate audit PDFs reliably with those common filters applied.
Original PR description
- In the Journal Audit report options, set the Account Type (filter_account_type) to either receivable, payable, or both. - Attempt to export the PDF of the Journal Audit report. A traceback occurs because, in _generate_document_data_for_export, we attempt to add a join using an alias. However, if the filter_account_type option is enabled, there is already a left join in the query with the same alias: account_move_line__account_id. opw-4926547 Forward-Port-Of: odoo/enterprise#91683
Printer tests from the device form now show a clear message if the IoT device does not respond in time. This prevents a confusing error and helps users understand that the communication timed out.
Original PR description
When testing printers from the device form, if no response was received from the IoT after the websocket timeout, we did not provide any message. This resulted in errors when providing `undefined` to the notification service.
The Belgian payroll departure wizards now show only employees from the company the user is currently logged into. This prevents confusion in multi-company environments and helps users select the correct employee when processing departure-related documents.
Original PR description
Added a domain to employees to limit the employee field in the departurre wizard to the logged in company **Steps to reproduce:** - Log into a Blgian Company - Access the Departure wizard through Payroll/Reporting or through the cog actions in an employee. **Issue:** Previously, when using the departure wizard, the employees shown were all the employees across different companies, when in reality it should be employees of the logged in company only **Fix:** Added employee domain so that it allows employees from the current logged in company only Task: 4965719 Forward-Port-Of: odoo/enterprise#92224 Forward-Port-Of: odoo/enterprise#90813
This fix allows Swiss payroll contracts to duplicate monthly wage type entries when needed. It prevents unnecessary blocking during contract setup and helps payroll teams manage valid wage configurations more smoothly.
Original PR description
task-5008742 Forward-Port-Of: odoo/enterprise#92089