Daily updates from Odoo
Monday, October 13, 2025
58 changes · 19.0
Resolved issues and error corrections
This fixes an issue in the Turkish Nilvera integration that could trigger a server error when handling failed HTTP responses. Businesses using this localization should now see the intended error handling instead of an unexpected crash.
Original PR description
The http response object doesn't have a `code` attribute, this commit fixes this typo which has already been fixed in 19.0 as a part of #222869 task-5050516 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#228088
This update adjusts customer portal templates so invoices, terms, and sales documents display correctly after a recent template engine change. It prevents missing layout details caused by the new way template information is passed behind the scenes.
Original PR description
In this commit(#197296), the behavior of `<t t-call>` has been updated to support parametric template calls. Variables defined inside a nested <t t-set> within a `<t t-call>` block are no longer visible to the called template due to lazy XML evaluation. This commit updates QWeb templates to: Pass parameters directly as attributes on <t t-call> instead of using inner <t t-set> tags. Before fix: <img width="1875" height="985" alt="image" src="https://github.com/user-attachments/assets/c55d42bc-69a5-42d7-9878-e8334b3cebd9" /> After fix: <img width="1869" height="974" alt="image" src="https://github.com/user-attachments/assets/62286ffe-879a-4741-a83f-7fbb8d94bb2c" /> opw-5152781 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 issue where a document selected for a draft chatter note could become linked to the underlying record before the note was posted. Attachments now stay tied to the draft composer until the user posts the message, preventing unintended document links and disruptive preview behavior.
Original PR description
When adding attachment from documents in the composer, link the attachment to the composer and not to the thread as it must be linked to the thread only once the message is posted. How to reproduce: - Install the app documents and crm - Open a lead - In the chatter click on "Log a note" - Then click on "Add from Documents" - Select a document and click on "Add from Documents" - Reload the page without posting the message The attachment selected in document is now linked to the lead which shouldn't be the case. Note that if you do the same for an expense, as the attachment is linked to the expense right away when added, the preview panel open immediately, and you have to reopen "Log a note". That was the original bug detected. Task-5075835
This change prevents Danish Nemhandel electronic invoicing connections from accidentally using production systems in neutralized environments. Existing proxy clients are switched to demo mode, and new registrations are directed to the test server, reducing operational risk during testing or copied database use.
Original PR description
To avoid sending/registering on production, add a neutralize script. The existing proxy client are put in demo mode. The new connections will be registered on the test server. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#229934
The India localization test setup was adjusted so it no longer depends on the US accounting module when demo data is unavailable. This reduces avoidable test failures and helps keep the India localization more reliable during development and maintenance.
Original PR description
Standalone `l10n_in` tests were failing when running without demo data because outside-India companies (e.g., US) were defaulting to their country-based chart of accounts. This required the `l10n_us_account` module, causing errors when the module was not installed. <img width="518" height="28" alt="image" src="https://github.com/user-attachments/assets/748663a0-f329-459c-b0e8-0c3de7019258" /> This commit adapts the test cases to run without l10n_us_account dependency. task- 5116352 Forward-Port-Of: odoo/odoo#230041
Fixed an issue where changing a coupon reward on a confirmed sales order could deduct the wrong number of points. Coupon balances now stay accurate when customers switch rewards, reducing billing and loyalty program discrepancies.
Original PR description
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10…
Versions -------- - 17.0+ Steps ----- 1. Have a coupon program; 2. add a 10% discount on order reward for 1 point; 3. add a 50% discount on order reward for 5 points; 4. generate a coupon with 10 points; 5. use coupon code on a confirmed order; 6. select 10% discount reward; 7. change to a 50% discount reward; 8. check coupon point total. Issue ----- Even though the 5 point reward was used, only 4 out of 10 points remain. Cause ----- When updating the reward line of a confirmed order, it keeps track of point cost changes before & after a write. Its purpose is to restore back the point difference on the coupon record. The issue is that while point changes are stored, coupon changes are not. When updating reward lines, `_reset_loyalty` is used, which removes the `coupon_id` from the lines. As a consequence, attempting to restore the point difference on `line.coupon_id` after an update, it writes to an empty record. Solution -------- Store both coupons & their used points before write. After write, restore the previous points to the previous coupon, and subtract the current point cost from the current coupon. This way, any combination of coupon/point changes should have the points updated as expected. opw-4910922 Forward-Port-Of: odoo/odoo#230907 Forward-Port-Of: odoo/odoo#222054
User forms now handle cases where login and email differ more safely, especially when the HR app is installed on databases created during a recent transition. The update prevents setup errors, keeps email/login fields aligned, and adjusts the user image area so the form remains readable.
Original PR description
[1] adds back the login button on the user form when login and email are different. However as the override in hr is based on the new base view, this causes issues for people installing hr if they created their database before that commit was live. The login can be moved inside the email div and simply duplicated so that the hr module doesn't need to know about the new div. Although it may cause the field to appear twice on databases created the week this commit was live, it's a lesser issue than throwing a traceback. Icon margins are also tweaked to be consistent accross base and the hr override task-5130854 [1]: https://github.com/odoo/odoo/commit/db3dee12d7c17ad485800d000ec4cdd87fcfd18b
This fix makes all fields and action buttons in the appraisal skills list accessible again on mobile devices. Employees and managers can now scroll horizontally to view justification details and add or remove skill entries as intended.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 Forward-Port-Of: odoo/enterprise#96579 Forward-Port-Of: odoo/enterprise#91882
Location barcode images are now hidden when the stored barcode contains characters that cannot be displayed in the required format. This prevents upgrade failures for customers with unsupported barcode values while keeping valid barcodes visible as before.
Original PR description
A new field `barcode_img` was added odoo/enterprise@53d008e9ce11bbf870e5d2f248fd591fa679be0e to display location barcodes in the form view. It uses the `barcode` field of the location, but some clients have values with unsupported characters (e.g., `Ž`, `بيع`) that cannot be encoded in Code128. This caused upgrade failures as such barcodes could not be rendered. Now, Don't show barcode in the form view if it fails to render. opw-5129150
Video call links for appointments now use the correct website address when multiple company websites are configured. This prevents customers from receiving links with the wrong domain, improving reliability for businesses running appointments across different websites.
Original PR description
**Steps to reproduce:** - Create 2 companies - Create a website for each company - Set a custom website domain on the second one - Create appointement type for each website - Create an appointement on both websites - The link created for the video call has the wrong base for one of them **Issue:** Appointment `get_base_url` finds its base_url without considering the current website. **Fix:** Compute the base_url according to the appointement type to ensure the current website is taken into account. opw-4880715 Forward-Port-Of: odoo/enterprise#96826 Forward-Port-Of: odoo/enterprise#92734
Maintenance equipment pages now open reliably even when a repaired request has had its close date or request date manually cleared. This prevents customized or manually adjusted records from blocking users while still keeping repair metrics usable.
Original PR description
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them…
Using standard Odoo, `maintenance.request.close_date` should never be `False` when its `stage_id == 'done'`, but customizations/manual overrides allow users to force it to be `False` and block them from opening equipment views that displayed fields that depended on it. Steps to reproduce: - Create new maintenance request for an equipment - Put maintenance request into a `maintenance.stage` where `done=True` (e.g. "Repaired") - Force `close_date` to not be `readonly` in form view + set it to `False` - Try to open the assigned equipment's form view Expected result: Form view opens without issue Actual result: `unsupported operand type(s) for -: 'bool' and 'datetime.date'` Issue was due to `mttr` calculation in `_compute_maintenance_request` not expecting `close_date` to be `False`. Since we want the request to still be considered for the rest of the compute, we count its "Time to Repair" as 0 in this case since we cannot use infinity in this case. Additionally, we also gracefully fail in the same way in case `request_date` is also forced to be `False` since it is not a mandatory field and can cause the same issue. 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#230942 Forward-Port-Of: odoo/odoo#230821
The appraisal skills list now allows horizontal scrolling on mobile, so users can access the justification field and add or remove buttons. This restores important appraisal editing actions for employees and managers using smaller screens.
Original PR description
Horizontal scrolling has been disabled on the appraisal skills list. An unwanted side effect of that is that the justification field along with the add and remove buttons are not visible on mobile. This PR re-enables the scrolling and removes some dead css. task-5001344 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230430 Forward-Port-Of: odoo/odoo#222161
The color picker now remembers where users last chose a color and opens that same tab the next time. This avoids extra clicks when editing website snippets, text colors, backgrounds, or gradients, making page customization smoother.
Original PR description
*web, website Before this commit, `BuilderColorPicker` had no memory of the last used tab and always opened on the first tab, regardless of whether the user had previously selected a color. After this commit, if the user has done a selection, the color picker opens on the tab of that selection. How to reproduce the problem: 1. Drop a new snippet, e.g. `s_text_block`, 2. Click on the snippet, then open the "Background" color picker 3. Pick a custom color or a gradient 4. If the color picker is stil open, press ESC 5. Open the color picker again 6. PROBLEM: the color picker is opened on the "theme" tab task-4367641 Forward-Port-Of: odoo/odoo#227197
Batch transfer confirmation now preserves the barcode settings needed to read location barcodes correctly. This prevents scans such as WH-Stock from being split into individual characters, allowing warehouse staff to continue batch picking without scan failures.
Original PR description
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and…
### Steps to reproduce: - In the settings enable: "Batch, Wave & Cluster Transfers" - Create 2 deliveries - Barcode > operations > Delivery orders > Batches > New - Add your two deliveries and confirm - Scan WH-Stock #### > The scan fails considering you scanned each letter independently. ### Cause of the issue: When the barcode is scanned a call of the split barcode will be launched to split the barcode in multiple barcodes according to the `barcode_separator_regex` present in the config: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_model.js#L613-L632 The issue lies in the fact that even thought the is `barcode_separator_regex` was conrrectly populated at the onWillStart of the mainComponent: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L209-L213 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L97 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/components/main.js#L229 https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/static/src/models/barcode_picking_model.js#L36-L38 It was reset by the batch confirmation here: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode_picking_batch/static/src/models/barcode_picking_batch_model.js#L123-L135 because this part of the config is not meant to be returned by the private method `_get_barcode_data` but rather by public complete version `get_barcode_data`: https://github.com/odoo/enterprise/blob/aeb9343f4b7dfab0fbc04bca4623ae85b3ea6030/stock_barcode/controllers/stock_barcode.py#L91-L98 Now, since no `barcode_separator_regex` was provided to our new config, each character will be considered to be considered as an independent barcodes and the `WH-Stock` barcode will not match any location. opw-5062331 Forward-Port-Of: odoo/enterprise#95295 Forward-Port-Of: odoo/enterprise#94056
This fix ensures purchase stock valuations based on vendor bills correctly account for differences in units of measure and currency. Businesses get more accurate inventory values and financial reporting when bills use different units or currencies than the related stock move.
Original PR description
Currently the move valuation base on BILL use the value define on the BILL without checking the currency nor the UoM. 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 a Sales module issue where automated checks could fail if a customized sales order line view showed another field before the product field. The change makes the product configurator test flow more resilient, helping prevent false failures for customized Sales setups.
Original PR description
To reproduce: 1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:…
To reproduce:
1. Manually modify the SO view `view_order_form` notebook SO lines list view to make visible any column before `product_id` For example:
https://github.com/odoo/odoo/blob/18.0/addons/sale/views/sale_order_views.xml#L521 making the field `display_type` visible
2. Run the tests of `sale` module
=> `sale` module tests will fail on test `test_sale_combo_configurator_preconfigure_unconfigurable_ptals`
```
FAILED: [18/22] Tour sale_combo_configurator_preconfigure_unconfigurable_ptals → Step Verify that configurable ptals are now configured (trigger:
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")).
Element (
.sale-combo-configurator-dialog
.combo-item-grid
.product-card:has(.card-title:contains("Test product"))
:contains("Attribute B: B")) has not been found.
TIMEOUT step failed to complete within 10000 ms.
```
see runbot build fail at:
https://runbot.odoo.com/runbot/build/89552334
The issue happen as - for some dark magic JS/XML reason - adding the field before product_id make fail the step to click the checkbox using the span.
Fix was suggested by PIPU to solve/workaround the issue
In practice, this issue was discovered accidentally with a customisation which was willing to add a custom field at the start of the list
opw-5068699
Forward-Port-Of: odoo/odoo#228029The point of sale now shows a clear "Device disconnected" message when the Belgian blackbox is unplugged, instead of a vague unknown error. This helps store staff understand the issue faster and take the right action without confusion.
Original PR description
When the blackbox is being disconnected the user gets "unknown blackbox error" instead of "Device disconnected" explicit message. This PR removes this vague error message introduced in https://github.com/odoo/enterprise/pull/93468 Forward-Port-Of: odoo/enterprise#95587 Forward-Port-Of: odoo/enterprise#95489
This fix prevents payroll work entries from crashing or staying in the wrong status when no work entry type is selected. Entries without a type are now handled consistently as conflicts, helping users spot and correct incomplete records instead of encountering errors.
Original PR description
If the user creates a work entry without a work entry type, it will fetch "false" id work entry type. It raises a traceback task-5078885
This fixes an issue where a date or time range picker in a list could reopen immediately after being closed, forcing users to close it twice. The change makes list editing smoother while keeping the picker opening automatically when a new empty date range is added.
Original PR description
Before this commit, the datetime picker would reopen after being closed, requiring it to be closed a second time. The issue was caused by the list view automatically focusing on the first cell or the…
Before this commit, the datetime picker would reopen after being closed, requiring it to be closed a second time. The issue was caused by the list view automatically focusing on the first cell or the last edited field after the picker was closed. When the <button> element received focus, the activeInput value was updated, causing the <button> to switch to an <input> due to reactivity. As a result of this remounting, the useEffect() hook was triggered, which caused the picker to reopen (see openPicker()). An alternative solution would be to call `leaveEditMode()` before the focus, but that's not feasible since `onGlobalClick` is triggered later, after the update. To fix this, we prevented the list view from automatically focusing the date range field except if the field is empty. This preserves the intended behavior of opening the picker when adding a new item to the list. With this change, after selecting a value in the picker, no focus occurs, and therefore the picker does not reopen after being closed. Steps to reproduce: - Go to "Appointments" - Configure -> Option - Set "Schedule" as "Flexible" - In the "Availabilities" tab, - Add a new line - After selecting a range, close the picker -> The picker is still open task-5080321 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 fix ensures that status indicators show the latest value after a record is moved or updated elsewhere. Users will no longer see outdated stages when returning to a form view, improving confidence in pipeline and workflow data.
Original PR description
Before this commit, there was a race condition with the statusbar field because of which the current status wasn't correctly updated when the rpc returned. For instance, in CRM pipeline, open the records in form view (to put them in cache). Then, go back in kanban and drag a record from a column to another. Re-open a record in form view, and use to pager to browse to the updated record. It still displayed the former value. This was due to an optimization attempt to prevent from re-computing too often the items of the statusbar. 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 keeps the restaurant appointment floor screen working correctly after related changes in the underlying point-of-sale system. It helps prevent display or interaction issues for restaurant staff managing appointments and floor plans.
Original PR description
This commit adapts an overriding method to reflect changes in the base method done in this pr https://github.com/odoo/odoo/pull/176016. Forward-Port-Of: odoo/enterprise#91334
This fix ensures the Community menu button is properly shown on event forms when the Track Quiz feature is installed. It prevents users from missing a relevant website event option in setups that do not also include the event meeting feature.
Original PR description
In the event form the "community" button is supposed to be shown when "track quiz" is installed. However when this was done in [1] there a mistake was made and only the label was removed, as well as the wrong field added after it. That field was removed in [2] but it was again not noticed that only the label was made visible. It may not appear easily because installing website_event_meet also unhides both the label and the field. Hence you only ge this issue when installing track quiz without it. However in 18.3 [3] removed website_event_meet which means the issue is not corrected anymore. task-5159806 [1]: https://github.com/odoo/odoo/commit/147cf5f328f5a55882a62a4279d1d92511628320 [2]: https://github.com/odoo/odoo/commit/c0f0f9f47573b74ca6b1fcdc3383e43f28f7a2e1 [3]: https://github.com/odoo/odoo/commit/9cab4f8f77f71e405971c184544765e8f252a012 Forward-Port-Of: odoo/odoo#231020
This fix ensures time off entries in the French HR localization use the employee's own working schedule, even when it starts earlier or ends later than the company's schedule. This prevents incorrect leave hour totals in timesheets and payroll-related records.
Original PR description
This bug is in France localization. In some cases employee schedule seems ignored in timesheet entry (`account.analytic.line`) creation, and the duration field is created using the company schedule.…
This bug is in France localization. In some cases employee schedule seems ignored in timesheet entry (`account.analytic.line`) creation, and the duration field is created using the company schedule. The reason is the case which the employee schedule starts before company scheudle or ends after it. To reproduce the bug: 1- Make a db with fr company (install l10n_fr) 2- Make two working schedule: - Company schedule with working day on Monday from 8:00-12:00 13:00-17:00 - Employee schedule with working day on Monday from 8:30-12:25 13:30-17:15 3- Assign company schedule to company in `Company Working Hours` in Setting and apply employee schedule to an employee from `Payroll` tab of employee 4- Allocate some time off to the employee and take a time off on Monday 5- Check the work entries for the day you took the day off on timesheet app 6- 7:24 `Worked Hour` is shown instead of 7:40 The bug occurs because in calling `adjust_date_range`, the case which employee's schedule ends after company schedule is not considered. opw-4868643 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230621 Forward-Port-Of: odoo/odoo#222262
Creating a work entry without selecting a type no longer causes an error. This helps HR users complete scheduling or attendance updates more reliably, even when optional information is missing.
Original PR description
If the user creates a work entry without a work entry type, it will fetch "false" id work entry type. It raises a traceback task-5078885
Demo Discuss messages from Alex now display Alex as the sender instead of Odoobot. This keeps demo conversations accurate and avoids confusion when users review or test the Discuss experience.
Original PR description
Before this commit, Alex's messages in discuss demo data were displayed as "Odoobot" rather than Alex. This happens because message had proper author_guest_id but no author_id defined, thus it had default value Odoobot and since [1] the author_id has precedence over `author_guest_id`. Before [1] there was no bug because the server returned formatted data of a single author as a persona, and guest_author_id had precedence over author_id. [1]: https://github.com/odoo/odoo/pull/211868 Before <img width="811" height="279" alt="Screenshot 2025-10-10 at 16 18 53" src="https://github.com/user-attachments/assets/862cfd18-24a0-485f-89b6-77277b9098ad" /> After <img width="815" height="280" alt="Screenshot 2025-10-10 at 16 17 45" src="https://github.com/user-attachments/assets/f83b98dd-ffb1-4419-851c-f34f3261792d" /> Forward-Port-Of: odoo/odoo#231047
This fixes an internal test issue where payment follow-up report checks could fail if they ran across midnight. The change helps keep automated validation stable without changing customer-facing behavior.
Original PR description
Tests https://runbot.odoo.com/odoo/runbot.build.error/159772 where failing when setUpClass run before midnight and the test itself run at/after midnight because `today` was not the same. As follow-up report divides the lines per partner to due/overdue utilizing `today` in comparison, This resuls in different lines than expected. Forward-Port-Of: odoo/enterprise#96486
Salary rules now prevent changing the salary structure once the rule is linked to an employee property. This helps avoid accidental payroll configuration changes that could affect employee salary calculations.
Original PR description
As some other `hr.salary.rule` fields (like Section and Unit), Salary Structure is now readonly when the rule has a property on an employee. 5135927 [task-5135927](https://www.odoo.com/odoo/project/1251/tasks/5135927)
Mexican DIOT reports now correctly identify suppliers or records from the United Kingdom instead of grouping them under "Other country." This helps businesses produce more accurate tax reporting and reduces the risk of manual corrections.
Original PR description
The DIOT country adaptation map lacked the ISO 3-letter code for the UK, causing records with country 'GB' to be reported as 'ZZZ' ("Other country").
Added mapping 'GB' → 'GBR' to ensure correct DIOT country code generation.

Forward-Port-Of: odoo/enterprise#96771When a website is configured only for events, the ecommerce app is no longer installed automatically. This avoids adding unnecessary sales features and keeps the website setup aligned with the user's selected purpose.
Original PR description
Steps to reproduce: 1. Install website module 2. Select events in configurator 3. Build website. => Ecommerce is installed, which should not as it does not make sense with only the events. After this commit: - Ecommerce will no longer be installed when the events is configured. task-4922600 Forward-Port-Of: odoo/odoo#221527
This change rolls back earlier accounting changes for manufacturing unbuild operations because they caused inconsistent stock valuation and errors in some cost scenarios. The team is returning to the previous behavior while a cleaner long-term solution is prepared.
Original PR description
This commit reverts [1], [2], [3], and [4]. (It actually results in minimal changes since those commits were already removing parts of each other.) Issue before those commits: 1. Setup a auto-fifo…
This commit reverts [1], [2], [3], and [4]. (It actually results in minimal changes since those commits were already removing parts of each other.) Issue before those commits: 1. Setup a auto-fifo category and two storable products (a component and a finished product) 2. Receive one compo at 10, then one at 25 3. Produce two MO with one finished product 4. Unbuild the second one Error: - For the component, we just use the value of the consumed components: IN 1 @ 25 - For the finished product, we process it as a classic out. Reminder, we are in FIFO: OUT 1 @ 10 As a result, thanks to the unbuild, we have created - A over-valuation of the stock (+15) - An outstanding balance of the "Cost of Production" This is why [1] has been merged. However, it brought some other issues, cf [2], [3] and [4]. Unfortunately, it still has some issues - After the above use case, the difference between the debit and the credit of the stock valuation account is no longer the sum of the remaining values of the layers - Adding some landed costs on MOs will lead to a traceback when undbuilding - The over-valuation of the stock (that was already present before [1], cf above) is still present Following some discussions with R&D and the product owners, we have decided to start over from scratch, which means: - Revert all commits - Try another approach (if so, the new PR will be linked to the PR related with this commit) [2], [3], and [4] are partially reverted: the tests can remain, as they were only failing due to a sequence of changes. [1] https://github.com/odoo/odoo/commit/84dda968146d2f3743ab7fc516300e50780725e3 [2] https://github.com/odoo/odoo/commit/49565cdd9007ac66a3b835dc073777e2e6c48f2c [3] https://github.com/odoo/odoo/commit/3a69456a291da593748475c86e7efc6234019e47 [4] https://github.com/odoo/odoo/commit/fb30cde9a320c245cf1321c9dc2ea2e67a53d0a0 OPW-5036574 Forward-Port-Of: odoo/odoo#226380 Forward-Port-Of: odoo/odoo#225728
Belgian payroll rules were updated so deduction 3000 uses the correct values through July 2025. This helps keep payroll calculations aligned with current Belgian requirements and reduces the risk of incorrect payslips.
Draft payslips can now be saved even when the payslip period date is left empty. This prevents an unexpected error during payroll preparation and keeps the payslip editing flow reliable.
Original PR description
When removing the date in a draft payslip an exception was raised. This was fixed and a test was added to check the flow. task-5159666
The online shop category sidebar now keeps nested category items within the correct width, even when category names are long. This prevents layout distortion and keeps product browsing pages visually consistent for shoppers.
Original PR description
__Issue:__ In the product categories sidebar (`#products_grid_before`), nested `<li>` elements could become wider than their parent `<ul>` when the category names were long (e.g., "Untersuchungshandschuhe"). This caused the parent <ul> to expand in height before the child and broke the visual layout. __Fix:__ Force `<li>` elements inside the `#categories_recursive` list to respect their parent width by applying `width: 100%` This keeps the sidebar layout consistent even with long category names. - opw-5075226 Forward-Port-Of: odoo/odoo#228343
Belgian Group S payroll reports can now be generated without triggering an error. This ensures payroll teams can complete the report export process reliably, with test coverage added to help prevent the issue from returning.
Original PR description
Generating a Group S report caused a traceback. Fixed by replacing 'date_start' with 'date' in the 'l10n.be.hr.payroll.export.group.s' model. Added a test to validate the change is working with the whole flow from creating a work entry till exporting the file. task-5005925
Spanish point-of-sale orders now keep the cashier’s selected fiscal position during payment validation instead of reverting to the default. This prevents incorrect tax amounts from appearing as change on receipts when taxes were intentionally removed or changed before payment.
Original PR description
Currently, when you use a default fiscal position in the pos, if you switch to no fiscal position, upon order validation the tax amount is counted as change. Steps to reproduce: ------------------- *…
Currently, when you use a default fiscal position in the pos, if you switch to no fiscal position, upon order validation the tax amount is counted as change. Steps to reproduce: ------------------- * Install l10n_es_pos, switch to es company * In the config of a shop, use fiscal position, set some as available, one as default * Open shop session * Add a product that has taxes * Switch fiscal position to one that has 0% taxes * There should not be taxes in the cart at this point * Go to pay the order (cash or bank) > Observation: On the receipt the previous tax value is counted as change Why the fix: ------------ The issue happens because of the simplified invoice mechanism present in the ES localization. When you validate an order and that order can apply for simplified invoice, if there is no customer on the order the partner is set with the simplified partner. When setting a partner on the order we update the fiscal position and pricelist. https://github.com/odoo/odoo/blob/1358f93a4c73de5a28cda72ec78769625c863efd/addons/point_of_sale/static/src/app/models/pos_order.js#L929 The fiscal position is updated with the partner's fiscal position or the default one if none on the partner. https://github.com/odoo/odoo/blob/1358f93a4c73de5a28cda72ec78769625c863efd/addons/point_of_sale/static/src/app/models/pos_order.js#L986-L995 Instead of the fallback on the default fiscal position in the case it is not set on a partner we fallback on the order current fiscal position. If it is different than the default one is means that it was changed intentionally and there's a high chance we want to keep it, otherwise it will already be the default fp. opw-5051231 Forward-Port-Of: odoo/odoo#229237
Restaurant point-of-sale bill splitting now correctly closes once the last split item has been paid. This prevents staff from seeing an empty bill-splitting screen after the bill is fully settled, reducing confusion during payment workflows.
Original PR description
When splitting a bill, a specific flow would leave the bill splitting screen open event when everything was paid. Steps to reproduce: ------------------- * In pos restaurant add 2 product to the order * Select Action > Split * Select a product * Click Pay(ment) and validate the payment * Continue * Select the last product * Click Pay(ment) and validate the payment * Continue > Observation: The Bill splitting screen is still open at 0$ Why the fix: ------------ When one or more products are selected a new order is created with those products. If the quantities match, it's the last payement for that bill, we can directly pay. The original order will then be closed. opw-5006042 Forward-Port-Of: odoo/odoo#230536 Forward-Port-Of: odoo/odoo#228991
Product category images in the website Catalog dynamic block now use the correct category URL when a custom website domain is configured. This prevents broken images and keeps storefront catalog sections looking complete for visitors.
Original PR description
Steps to reproduce: ==================== - Add a Catalog dynamic block. - Set a custom domain for the website. → Product category images do not display. Why? ==== Image URLs were generated using the website base domain, not the category's base url. As a result, links pointed to non-existent resources. Fix: ==== Generate image URLs using the category URL instead of the website's base URL. opw-5143162 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix prevents failures when creating GST return records for tax units that include multiple companies. The system can now use a valid purchase journal from any company in the tax unit, reducing setup-related errors for multi-company configurations.
Original PR description
Before this PR: - The system searched for a purchase journal only in `company_id`. - In a tax unit with multiple companies, if the main company had no purchase journal configured, record creation failed with a 'NOT NULL constraint violated' error. After this PR: - The journal search now checks all companies in `company_ids` (or falls back to `company_id`), - allowing the system to find a valid purchase journal across the tax unit. OPW: 5159518 Forward-Port-Of: odoo/enterprise#96919 Forward-Port-Of: odoo/enterprise#96838
This fix prevents Odoo 19 from failing during startup on Python 3.11 and later because of a changed web address handling dependency. It helps businesses run Odoo reliably on supported modern Python environments without encountering this import error.
Original PR description
Description of the issue/feature this PR addresses: - In Python 3.11+, urllib3 stopped relying on its internal _WHATWG_C0_CONTROL_OR_SPACE constant directly in newer releases Current behavior before PR: - As described in #230990 Desired behavior after PR is merged: - Running Odoo19 on Python 3.11+ should not throw a `_WHATWG_C0_CONTROL_OR_SPACE missing` error --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fixes an issue where Safari users could not select a website type or objective in the website setup wizard because the dropdown closed too early. The change ensures mouse selections are recognized properly, helping users complete website creation without browser-specific disruption.
Original PR description
Problem Using Safari, in the website configuration wizard, when selecting a website type or an objective by mouse clicking, nothing would get selected, and the dropdown would close prematurely. Steps - Using Safari - In Odoo with the Website addon installed - Create a new website in the website settings - Try to select any type of website by mouse clicking - Nothing would get selected, and the dropdown closes before pointerUp Cause On Safari, buttons are not focusable by default. So if we want good accessibility on these dropdowns, a workaround is needed. Fix Delay focusout actions until a pointerUp event is triggered on the dropdown, if the Safari user uses its mouse to choose an option. task-5139708 Closes https://github.com/odoo/odoo/pull/226637
This fix prevents users from creating a to-do item without a name, avoiding an error that could appear during quick creation. It also adds a safeguard for existing records with missing names so they no longer trigger the same failure.
Original PR description
Currently, an error occurs when user tries to create a to-do with no name. Steps to replicate: - Install Project. - Go to `To-Do > Click New > Click Add`. - Error will occur on the terminal. Error:…
Currently, an error occurs when user tries to create a to-do with no name. Steps to replicate: - Install Project. - Go to `To-Do > Click New > Click Add`. - Error will occur on the terminal. Error: `TypeError: expected string or bytes-like object, got 'bool'` Cause: - The error occurs after a recent [PR], that changed `name` field in the to-do app's kanban view to `display_name`. - As `display_name` is not a required field this will allow the creation of task and trigger the method `_inverse_display_name`. - This will cause the error to occur at line [1] (because `task.display_name` is False). Solution: - Made the field required through xml similar to the `project.task` kanban view in the project app [2]. - Also handled the case when `display_name` is received falsy at [1] by skipping the execution and continuing the loop (this is mostly for the existing DBs). [PR]: https://github.com/odoo/odoo/pull/205354 [1]: https://github.com/odoo/odoo/blob/b81d119fae5f5194334cee94bacffefeb1cd8c6e/addons/project/models/project_task.py#L801 [2]: https://github.com/odoo/odoo/blob/b81d119fae5f5194334cee94bacffefeb1cd8c6e/addons/project/views/project_task_views.xml#L609 sentry-6913627252 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Creating a company in the Belgium localization no longer crashes when an alphanumeric ZIP code is entered. The system now skips region calculation for invalid Belgian ZIP codes, preventing disruption during company setup.
Original PR description
Currently, in the Belgium localization, creating a company with an alphanumeric ZIP code raises an error. **Steps to Reproduce:** 1) Install **account,l10n_be_reports** module 2) Navigate to…
Currently, in the Belgium localization, creating a company with an alphanumeric ZIP code raises an error. **Steps to Reproduce:** 1) Install **account,l10n_be_reports** module 2) Navigate to **Settings>Users & Companies>Companies**. 3) Create a New Company and first set country as `Belgium` and then set a alpha-numeric value to `ZIP=(e.g. R93R2R3)` 4) Click anywhere on the screen **Error:** `ValueError: invalid literal for int() with base 10: 'R93R2R3'` **Root Cause:** since [this commit](https://github.com/odoo/enterprise/pull/93219/commits/d9f116b5ceda85a11c997b8d46ec9af5425cbf09), a new field `l10n_be_region_id` is computed based on zip as shown at [1]. When an alphanumeric `ZIP` is added, the computation searches the company region based on `zip_start` and `zip_end` as shown at [1]. However, `zip_start` and `zip_end` expect integer values only, as mentioned at [2], which causes the error. **Fix:** Prevent calculation of region for companies with invalid zip code for belgium localization. [1]- https://github.com/odoo/enterprise/blob/424a470188756fffed4437b83d127039795fbe59/l10n_be_reports/models/res_company.py#L37-L45 [2]- https://github.com/odoo/enterprise/blob/71cc92c9526234dcd44ec756375647a67729029f/l10n_be_reports/models/l10n_be_company_region.py#L17-L18 sentry-6931185627
Colombian website checkout now correctly saves customer addresses when a selected tax obligation type has a double-digit identifier. This prevents the checkout page from getting stuck and allows shoppers to continue to delivery.
Original PR description
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and…
Problem: When there is an obligation type code with id greater than 9, and it is selected in the dropdown of the website sale address form for obligation type, the screen keeps loading forever and there is an “expected singleton” traceback in the logs. This is because in the method `_parse_form_data` in `l10n_co_website_sale`, the obligation type field on `form_data` is set to be a list of “type ids” which leads to an error when `convert_to_cache` is called as the browse function in this attempts to convert the list to a tuple of single characters. For example, if the list is ["10"], it gets converted to ("1","0") hence leading to the expected singleton traceback.
Purpose: Instead of passing a form list to form_data,we pass the record set which will correctly set the values in the address, much like how `default_obligations_ids` is also currently set. After this correction, the website address screen will save the address properly and redirect to the delivery screen for further actions.
Steps to Reproduce on Runbot:
1. Create a Colombian company, make sure l10n_co is installed
2. Set the company on the website to this company
3. Ensure that there is a record in the table `l10n_co_edi_obligation_type_ids` with id > 9. Create one if it does not exist.
4. Open the /shop page in incognito mode as a public user.
5. Add a product, go to the checkout page, proceed to the address page.
6. Enter all the information including the Identification Number (e.g. 623.456.789-1). Choose “NIT” in identification type and select the type code from step 3 in the dropdown for obligation type. Choose country “Colombia” along with a state and city
7. Click on "Continue checkout". The page gets stuck in a loading state
forever.
opw-4776301
Forward-Port-Of: odoo/enterprise#90862Purchase orders now keep the same unit of measure shown in the product catalog when products are added, avoiding accidental ordering by vendor packs instead of individual units. This helps buyers create accurate orders and prevents quantity or pricing surprises, with related tests updated for purchasing and stock workflows.
Original PR description
Steps to reproduce the bug:
- Create a storable product “P1”:
- UoM: unit
- Purchase tab:
- Vendor: Azure interior
- UoM: Pack of 6
- Create a purchase order:
- Vendor: Azure interior
- Click the Catalog button:
- Select 1 unit of P1 (note: UoM cannot be changed in the catalog)
Problem:
The purchase order line is created, but with 1 pack of 6 instead of 1 unit
Fix:
Ensure the selected product quantity and UoM from the catalog are correctly applied to the PO line.
Opw-4794362
Forward-Port-Of: odoo/odoo#227212
Forward-Port-Of: odoo/odoo#224231This fix updates test data so products are treated as properly configured for manufacturing instead of missing setup details. It prevents false test failures caused by inflated lead times, helping keep planning and rental workflows reliable during validation.
Original PR description
This PR addresses the issue where tests were failing due to unconfigured products (no vendor/ no BoM). Now unconfigured products' lead_time is incremented by 365 due to this PR: https://github.com/odoo/odoo/pull/216293 Before this fix: Products have `buy` route by default and no vendor, so they are considered unconfigured products and lead time is incremented by 365, and tests fail as any lead time refers to a date earlier than today would only affect the first period in the MPS which is not intended in the tests. After this fix: Products have `manufacture` route and there is BoM, so they are considered configured products and lead time is calculated normally from BoM which is 0. Task-4779057 Forward-Port-Of: odoo/enterprise#88766
Employee contracts in multi-company setups now only show insurance options that belong to the relevant company. This prevents users from accidentally selecting insurance records from another company, improving payroll data accuracy.
Original PR description
Currently, in a multi-company setup, you are able to select insurances from other companies on the employee contract task-5157106 Forward-Port-Of: odoo/enterprise#96932 Forward-Port-Of: odoo/enterprise#96821
Fixes an issue in the HTML editor where undoing image rotations, resizing, or dragging required several undo actions. Users can now press Ctrl+Z once to restore the image to its original state, making content editing more predictable and efficient.
Original PR description
**Current behavior before PR:** - When rotating, resizing, or dragging an image using the transform container, pressing Ctrl+Z did not revert the image to its initial state (when the transform container was opened). - Instead, it required multiple undo operations to return to the initial state. **Desired behavior after PR is merged:** - Pressing Ctrl+Z now correctly reverts the image to its initial state in a single undo, after a transformation. task-5114320 Forward-Port-Of: odoo/odoo#230211 Forward-Port-Of: odoo/odoo#228720
This fixes an issue where applying multiple global discounts to a sales order could create extra discount lines. Businesses will see cleaner, more accurate order and tax calculations when using cumulative discounts.
Original PR description
Because of the grouping on the computation_key in the taxes engine, when a second global discount was applied on a SO, it was creating two additional lines instead of one. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#230494
This fix keeps all selected tags visible when users refresh, search, or open the website editor on blog and eLearning pages. It prevents filters from being unexpectedly lost, making content browsing and editing more reliable.
Original PR description
Before the change in the blog/slides pages of a website every tag but one disappears when opening the editor or when the search bar is used. Steps to reproduce: - Log in Odoo with a user that can access the website editor Open the Website - Install the blog app if it is not already present - Open the blog app - Click on two or more tags to add them to the filter Open the Website editor or use the search bar - Every tag but one will be removed After the change all the tags will be kept when opening the editor or using the searchbar. task-4216129 Fixes #164577 Forward-Port-Of: odoo/odoo#226898
This update ensures multiple quote carousel sections on a website page each get their own unique identifier. As a result, navigation controls like next and previous now operate the correct carousel instead of accidentally moving another one.
Original PR description
The selector used to target the carousel, to generate unique ID, did not include some carousels (s_quotes[...]). This led to issues with the controllers that would not be linked to the correct carousel. Steps to reproduce the issue: - Go to Edit - Drop two "s_quotes_carousel" - Save - Click on the "next" arrow of the second carousel => The second carousel does not slide, but the first one does. Forward-Port-Of: odoo/odoo#230541
Products without a bill of materials or vendor will now appear on the replenishment report much earlier instead of only on the delivery day. This helps teams spot missing product configuration in time and avoid last-minute supply issues.
Original PR description
Before this commit, RR for unconfigured products (no BoM/ no vendor), was not created until the same day of the delivery date (lead_time=0). Now, RR for unconfigured products is created considering the lead_time is incremented by 365 days. Note that this commit reverts the effect of the commit: https://github.com/odoo/odoo/commit/40d0bc0df0dc09f5138aa747cbbc715ae77f104c It's functionally decided to make the total lead_days for products with no bom to be 365 days without adding the security_lead_days. It's meant just to warn the user on the RR dashboard that the product needing replenishment is not configured, no matter to the security_lead_days in this case. Task-4779057 Forward-Port-Of: odoo/odoo#216293
Phone numbers in the VoIP call list now stay properly aligned when no country flag is shown. This removes a small visual offset that affected calls to invalid or unrecognized numbers, making the list easier to read.
Original PR description
In the voip.call list view, when no flag is displayed, the phone number is slightly offset to the right. This is because the margin that separates the flag from the phone number is still present. This commit moves the margin from the phone number (always displayed) to the flag (sometimes absent). How to reproduce: 1. Make a call to an invalid phone number 2. Go to voip.call list view 3. Look at the numbers without a flag
The command palette now keeps all repeated characters visible when highlighting search matches in app names. This prevents confusing or misspelled-looking results, such as “Meeting Rooms” appearing with a missing letter during search.
Original PR description
**Before this commit :** When searching for apps whose names contain repeated characters, the command palette incorrectly omitted the second occurrence of that repeated character while searching for it. Example: App name: Meeting Rooms input: o Result: Meeting Roms(missing the second `o`), which was incorrect. **After this commit:** The command palette now correctly displays all characters without skipping any repeated ones. task-5129947 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Restores the blue banner shown when staff preview sales orders and invoices in the customer portal. This makes it easy to return from portal preview back to backend edit mode, avoiding confusion and extra navigation.
Original PR description
## Versions
19.0+
## Issue
The blue banner ("This is a preview of the customer portal. → Back to edit mode") does not appear when previewing a Sale Order or Invoice from the backend.
## Steps to reproduce
Open a SO:
- Click the "Preview" button;
- The portal preview page opens, but the top blue banner to return to the backend is missing.
## Cause
This regression appeared after the QWeb refactor (https://github.com/odoo/odoo/commit/eb6e88a25050fff2bd09317739dd51ba451450df) which changed how template variables propagate:
- `t-call` is now parametric, variables defined inside a `t-call` no longer affect the outer scope;
- The inner content of a `t-call` only sees variables defined before the call;
- Lazy XML evaluation means `t-set` values defined after the layout call are not yet in scope during rendering.
Previously, `o_portal_fullwidth_alert` was set **after** the layout was called, so the variable was invisible when the alert banner was rendered.
opw-5096001This fix reduces the risk of duplicate commission achievement records being generated when subscription commission adjustments happen close together. It helps keep commission reporting accurate and avoids conflicts that could affect sales compensation calculations.
Original PR description
This commit 5b6fdda126e4cfa5ebf92f7b96d1805f6c4b992b introduce an entropy date to avoid having two separate achievment.report record with the same ID. Entropy date for log where based on the write_date, this commit 03d1ee3495a4936fbff0d21743bb784c85b50b12 add the sign of the amount. Unfortunatly this is not enough, the adjustment after the transfer can be positive as well and thus two achievment ends-up with the same ID anyway. This commit use the id of the log to add more entropy to the entropy_date, since log are created in the same transaction, they are likely to have id just seperate by one or only few number, id % 10 seems enough, therefore two log on the same order, with the same create_date will have different entropy date and end up with a different id. Forward-Port-Of: odoo/enterprise#96622
Fixes the default end date used in sales commission achievement reports so it consistently uses the latest end date across relevant commission plans. This helps ensure reports cover the full intended period and avoids accidentally cutting off commission data too early.
Original PR description
When there is active_plan_ids in the context the date_to are the max of plans' date_to when not it's the min, this is wrong it should be the maw as well Forward-Port-Of: odoo/enterprise#96526
SEPA payment files will now mark payments as high priority only for Belgian companies. This helps companies in other countries avoid unnecessary bank fees that can be charged for high-priority payments.
Original PR description
Having priority set as HIGH for SEPA payments can induce extra fees (ex. in CH). This commit only sets the priority to HIGH for BE companies. task-4874217 Forward-Port-Of: odoo/enterprise#96869 Forward-Port-Of: odoo/enterprise#95420
This change prevents uninstalling worksheet-related modules from failing after database fields have already been removed. It helps avoid broken uninstall/reinstall flows that could leave business data tables in an inconsistent state.
Original PR description
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks…
Recently pull request https://github.com/odoo/enterprise/pull/86084 introduced an ondelete method on `ir.model` that retrieves some worksheet templates to delete them. However, this method breaks when uninstalling module `worksheet`:
```
ir.model.data._module_data_uninstall():
... records are deleted ...
ir.model.fields.unlink():
drop column of corresponding fields
delete ir.model.field records
ir.model.unlink():
drop table of corresponding models
ir.model._unlink_if_uninstalling():
self.env['worksheet.template'].search([('model_id', ...)]).unlink()
delete ir.model records
```
The call to `ir.model.unlink()` crashes when searching for worksheet templates, since column `model_id` has been dropped already. This makes the transaction fail, and it is rolled back to a savepoint just before the call to `ir.model.unlink()`. In other words, the uninstallation manages to drop most of the columns that must go, but fails to drop all the tables that must go. And the uninstallation proceeds anyway...
Now consider uninstalling module `resource`. That module defines model `resource.calendar` with required field `name`, and also defines a record in that model (a default calendar). When the module is uninstalled, module `worksheet` is also uninstalled (because it depends on `resource`), and so the situation above happens. Consequently, most of the columns of table `resource_calendar` are dropped, but the table is not. If we reinstall module `resource` after that, the ORM re-creates column `name` (which is `NULL` on the default calendar at least), but fails to add the `NOT NULL` constraint on that column.
The fix consists in avoiding the `search()` above in the ondelete method if the column `model_id` does not exist anymore.
Forward-Port-Of: odoo/enterprise#96845