Daily updates from Odoo
Tuesday, June 30, 2026
202 changes
16 changes
Resolved issues and error corrections
This update corrects the color shown in the Timesheets grid when an employee’s schedule includes fractional working hours. It prevents the app from marking a cell as warning/orange by mistake when the worked time exactly matches what is expected.
Original PR description
## Issue In the Timesheets app, the color of the *Time Spent* cell at the end of a row indicates the current status of the timesheets based on the expected number of working hours. The selected color…
## Issue
In the Timesheets app, the color of the *Time Spent* cell at the end of a row indicates the current status of the timesheets based on the expected number of working hours. The selected color (green/orange/red) is sometimes wrong when an employee has a work schedule with fractional hours.
## Steps to reproduce
1. Install *Timesheets* (`timesheet_grid`)
2. For an employee E, edit the *Standard 40 hours/week* schedule:
- Change *Monday Afternoon* "Work to" column from 17:00 to 17:20.
3. In Timesheets > All Timesheets, go back one week and fill the timesheet for the employee E. We need 8 hours everyday but on Monday, where we need 8 hours and 20 minutes.
4. __The background of the *Time Spent* cell is orange, even though there's no overtime anywhere, and the value in the cell is precisely 40:20, which is the expected amount of hours worked.__
## Cause
When comparing the amount of hours worked and the expected amount of hours, small rounding errors occur. At this point of the execution:
https://github.com/odoo/enterprise/blob/19b7f5a6961dbce7367c07fcc55eea1925832634/timesheet_grid/static/src/views/timesheet_grid/timesheet_grid_renderer.js#L157
We obtain the following values:
```js
> monday = section.cells[1]
> monday.value
8.333333333333336
> workingHours[monday.column.value]
8.333333333333332
> monday.value - workingHours[monday.column.value]
3.552713678800501e-15
```
This small difference differing from 0, the wrong color is selected by `_getSectionTotalCellBgColor`:
https://github.com/odoo/enterprise/blob/19b7f5a6961dbce7367c07fcc55eea1925832634/timesheet_grid/static/src/views/timesheet_grid/timesheet_grid_renderer.js#L160-L172
## Fix
The same issue was fixed elsewhere by https://github.com/odoo/enterprise/commit/3340c0610ae6d7d3087f20da04309512771cc4b7. The same fix is applied here for consistency.
opw-6193181
Forward-Port-Of: odoo/enterprise#121463This update prevents the AI assistant from asking for confirmation twice when creating project tasks. It checks that all required information is available before showing the preview or creating the item, which avoids confusion and makes the task creation flow more reliable.
Original PR description
This commit removes an issue where the LLM would retry on error when performing a creation which would give the impression that it created items twice. To do so, this commit now validates that the fields exists before calling the `create()` method, and before showing the preview to the user. Ensuring it avoids throwing an error after the message has been confirmed (resulting in the double preview). task-6229596 X-original-commit: c21dcfe8e4a2c399ee25ebeadd408ce303ce2ff9
This update adjusts the holiday calendar side panel to work with the latest Owl framework version used in Odoo. It helps keep the scheduling interface stable and prevents issues caused by outdated component behavior.
Original PR description
This commit is a follow-up of 197d0ca5, as part of the Owl 3 migration, replace onWillUpdateProps hook with the appropriate Owl 3 alternatives 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
When users switch companies while viewing a payroll pay run, the system now checks access before reloading the page. This prevents a brief error message from appearing and takes users directly back to the pay run list when the record is not accessible in the new company context.
Original PR description
Steps to reproduce: 1- Open a payrun 2- Switch companies Issue: You get an access error for a moment and then get redirected to payrun list view Cause: When switching companies, the payrun reloads but since it is in the context of a different company, you get an access error. Solution: First check in js before fetching that you have access to the payrun, if not, redirect to the list view instead. Task-6008140 Forward-Port-Of: odoo/enterprise#120004
Fixed an issue where some conversation threads could fail to show their messages after reloading. This helps ensure users reliably see the latest messages instead of an empty placeholder.
Original PR description
The Thread component mirrors `thread.isLoaded` into the `state.mountedAndLoaded` flag that gates whether the real messages (as opposed to the empty phantom placeholder) are rendered. The mirroring…
The Thread component mirrors `thread.isLoaded` into the `state.mountedAndLoaded` flag that gates whether the real messages (as opposed to the empty phantom placeholder) are rendered. The mirroring effect both read `mountedAndLoaded` as a dependency and wrote it. `useEffect` records its dependency array before running the body, so right after the effect sets `mountedAndLoaded` to true the recorded dependencies still hold the pre-write pair `[isLoaded=true, mountedAndLoaded=false]`; that update only settles on a later, microtask-deferred patch. When a second reload runs `reset()` in that window, it drives `mountedAndLoaded` back to false while `isLoaded` stays true. The settling patch then computes the very `[true, false]` pair that was already recorded, so the effect never re-runs: `mountedAndLoaded` is stranded at false and no message is ever rendered. Depend on a monotonic `resetCount` bumped by `reset()` instead of on `mountedAndLoaded` itself. It is never written by the effect, so the recorded dependencies can no longer match the current ones after a reset and the effect always re-runs to re-sync `mountedAndLoaded` with `isLoaded`. `reset()` keeps clearing `mountedAndLoaded` as before (the false dip is needed for the reload scroll handshake), so the behaviour is otherwise unchanged. https://runbot.odoo.com/odoo/error/940032 Forward-Port-Of: odoo/odoo#272589 Forward-Port-Of: odoo/odoo#272281
We fixed an automated test in the chat features that was sometimes failing at random. The check now looks directly at the chat title instead of relying on a brief loading moment, making test runs more reliable and reducing false failures.
Original PR description
The hoot `:text('X')` pseudo-class matches an element only when its whole inline text equals "X". `.o-mail-ChatWindow:text('slytherins')` therefore matched the chat window only during the brief frame where it showed nothing but its title, before the thread body (start message, composer) was rendered. Catching that frame is a race, so the assertion times out intermittently on runbot.
Assert against the title element itself: add a dedicated `o-mail-ChatWindow-name` class on it and match it with `.o-mail-ChatWindow-name:text('X')`. This is exact and no longer depends on the rest of the window being empty.
https://runbot.odoo.com/odoo/error/939914
Forward-Port-Of: odoo/odoo#272567
Forward-Port-Of: odoo/odoo#272380This update corrects how sales margins are calculated when different tax display modes are used on documents. It ensures the reported margin stays accurate and consistent for users regardless of how taxes and prices are shown.
Original PR description
A newly introduced feature in commit 001d3255cd134656970c98b6e367d6ae3ec77124 caused the tax and price computation to differ, making the margin computation to be inaccurate depending on the document tax mode chosen. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an issue where the ticket screen numpad could appear when it should stay hidden in certain point-of-sale setups. It improves the consistency of the interface for users working with specific POS configurations, such as Urban Piper and HR-related flows.
Original PR description
Steps to reproduce: =================== - Ensure `pos_hr` and `pos_urban_piper` is installed. - Install `l10n_in_pos_urban_piper`. - Open a draft Urban Piper order and notice that the numpad is visible. Cause: ====== - The numpad visibility depends on a `t-if` condition in XML. - Due to the asset loading order, this condition gets overridden by another module. Fix: ==== - Move the visibility logic to a getter method. - Override the getter in other modules instead of using XML to control the visibility. Task-6299415 Related Enterprise PR: https://github.com/odoo/enterprise/pull/120571 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This update fixes an unstable automated test in the messaging app that could fail intermittently under slower conditions. It does not change user behavior, but it helps ensure future releases are tested more reliably.
Original PR description
The "Jump to old reply should prompt jump to present (RPC small delay)" test clicked the jump-to-present button right after clicking the in-reply, without waiting for the jump to the old reply to render. The button only shows once that load has settled, so under load the button could still be absent when the click polled for it, making the test flaky. Wait for the messages to be reloaded around the old reply before clicking, mirroring the non-delayed sibling test. https://runbot.odoo.com/odoo/error/941200
This update corrects a display issue in the Point of Sale ticket screen where some buttons and the numpad could appear when they should be hidden. It also improves consistency across installed extensions and fixes a dark-mode styling issue for the prep order time field.
Original PR description
Issue 1: ====== Numpad Visibility in TicketScreen of draft urban piper orders Steps to reproduce: =================== - Ensure `pos_hr` and `pos_urban_piper` is installed. - Install…
Issue 1: ====== Numpad Visibility in TicketScreen of draft urban piper orders Steps to reproduce: =================== - Ensure `pos_hr` and `pos_urban_piper` is installed. - Install `l10n_in_pos_urban_piper`. - Open a draft Urban Piper order and notice that the numpad is visible. Cause: ====== - The numpad visibility depends on a `t-if` condition in XML. - Due to the asset loading order, this condition gets overridden by another module. Fix: ==== - Move the visibility logic to a getter method. - Override the getter in other modules instead of using XML to control the visibility. - Also fixed the css issue for prep order time input when using it in dark mode --- Issue 2: ====== Invoice button visible on Chile Company's TicketScreen Steps to reproduce: =============== - Ensure `pos_urban_piper` is installed, open the Chile company's PoS Config - In the ticket screen, we have an invoice button on paid orders. Cause: ===== - Button visibility handled through XML conditions; this condition gets overridden by another module. Fix: === - Move the visibility logic to the getter method and override it in submodules to control visibility. Task-6299415 Related Community PR: https://github.com/odoo/odoo/pull/270088
This change prevents a crash that could happen when a user canceled a new webhook record and then tried to create another one right away. It improves stability in Studio’s Webhook screen and avoids an interruption caused by a timing issue after a frontend update.
Original PR description
Go in studio => Webhook tab Click on new Click cancel and back to list view again click on new Before this commit, there was a crash due to a race condition that appeared after owl3 migration. This commit solves this by protecting the first update in favor of the second opw-6332360 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 spreadsheet app was updated to the latest version, bringing several usability fixes and small interface improvements. Users should see smoother chart interactions, better font handling on Linux, and fewer pop-up issues when editing spreadsheets and charts.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b0b4c4027f [REL] version 19.4.0 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b0b4c4027f [REL] version 19.4.0 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/4ce11c6918 [IMP] package: update to owl alpha 40 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/209e5072a9 [IMP] header_size: make getters consistent [Task: 6332479](https://www.odoo.com/odoo/2328/tasks/6332479) https://github.com/odoo/o-spreadsheet/commit/4520b613fe [IMP] statistic bottom bar : close the menu [Task: 6316288](https://www.odoo.com/odoo/2328/tasks/6316288) https://github.com/odoo/o-spreadsheet/commit/2ab649b389 [FIX] sheet: close the color picker on external click [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/2ab8f9a641 [IMP] charts: annotation tool [](https://www.odoo.com/odoo/2328/tasks/) https://github.com/odoo/o-spreadsheet/commit/0ff30dd158 [REV] typing: exclude non-exported symbols in type resolution [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/f982c69ff5 [IMP] package: update owl to 3.0.0-alpha.39 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/e40bf0cc08 [IMP] tools: run esm version is node [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/61f99a225c [FIX] Fonts: Add default font for Linux [Task: 6328646](https://www.odoo.com/odoo/2328/tasks/6328646) https://github.com/odoo/o-spreadsheet/commit/2687933537 [FIX] typing: exclude non-exported symbols in type resolution [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/1263a6e8de [FIX] components: use owl3 syntax [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> 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: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@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> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update prevents a rare conflict when uploading vendor bills with automatic OCR enabled. It makes sure the bill’s access token is saved earlier, so OCR processing no longer clashes with the bill creation flow and cause processing failures.
Original PR description
When a new bill is created from an attachment, the import flow may commit inside `_extend_with_attachments`. If automatic OCR is enabled, this commit can run the OCR postcommit callback, which writes on the same account.move. The access token was flushed after that import flow, so it races with the OCR callback and triggers a serialization failure. Create and flush the access token before entering the import flow, so the write happens before OCR postcommit callbacks can run. task-[6340793](https://www.odoo.com/odoo/project/967/tasks/6340793) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This change moves a self-order-related check out of the standard Point of Sale flow and into the self-order feature where it belongs. It helps prevent failures in automated testing and keeps the regular Point of Sale behavior aligned with its intended scope.
Original PR description
This commit moves the usage of `has_valid_self_payment_method` from `point_of_sale` to `pos_self_order`, where it belongs. The method usage was introduced in https://github.com/odoo/odoo/pull/269502, causing runbot failures Runbot Errors- [941124](https://runbot.odoo.com/odoo/error/941124), [941125](https://runbot.odoo.com/odoo/error/941125), [941126](https://runbot.odoo.com/odoo/error/941126)
The chatter now refreshes properly when a record is reloaded without changing to a different record. This means new attachments and similar updates appear immediately, instead of requiring a full browser refresh or showing outdated indicators.
Original PR description
Since 71336f7f7d25 ("[REF] mail: introduce useOnChange hook"), the chatter only refetched its data (attachments, followers, ...) when the thread identity changed. A same-record form reload keeps the same thread, so nothing was refetched: an attachment created on the record without a message_post (e.g. the pdf generated by "Send & Print", or an account return validation) only showed up after a full browser refresh, the paperclip icon staying stale.
The messages were still refreshed because Thread listens to MAIL:RELOAD-THREAD and calls fetchNewMessages(); the chatter had no such listener. Add the symmetric listener so the chatter reloads its data on a same-record reload too.This fix ensures an employee’s basic salary is classified correctly on Form 2316. Salaries below the tax-exempt cap are now reported as non-taxable, while salaries above the cap remain taxable, which helps prevent incorrect payroll tax reporting.
Original PR description
Previously, a regular (non-MWE) employee's basic salary was always reported as taxable (item 39), regardless of amount. This commit fixes that by checking the yearly basic salary against the tax-exempt cap. If it is below the cap, it is now reported as non-taxable (item 29) and when the amount is above the cap it will be taxable (item 39) Backport of odoo/enterprise@a7362ad273ba8c38aa0908f0765526f8ed8b8193 task-6328424
14 changes
Resolved issues and error corrections
This update brings the spreadsheet component up to its latest version and includes a set of small fixes and improvements. It addresses issues like color picker behavior, font display on Linux, chart rendering, and find-and-replace selection handling, helping the spreadsheet feel more reliable and consistent for users.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/446def9ad1 [REL] 19.3.9 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/446def9ad1 [REL] 19.3.9 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/9af0bc5b97 [FIX] package: 19.3 is no longer the latest version [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/9a69c22cd2 [FIX] sheet: close the color picker on external click [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/ae520eaad2 [FIX] sheet: add sheet tab color to custom colors [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/54af665a85 [FIX] Fonts: Add default font for Linux [Task: 6328646](https://www.odoo.com/odoo/2328/tasks/6328646) https://github.com/odoo/o-spreadsheet/commit/babbc57eee [FIX] chart: zoomable chart height issue with rjsmin minification [Task: 6306092](https://www.odoo.com/odoo/2328/tasks/6306092) https://github.com/odoo/o-spreadsheet/commit/4fd1a3439e [FIX] package-lock: revert changes [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/4dc969c14e [IMP] package: add runbot script [Task: 6316690](https://www.odoo.com/odoo/2328/tasks/6316690) https://github.com/odoo/o-spreadsheet/commit/be5939bcfb [FIX] Find and replace : selection after an UPDATE_CELL [Task: 4818132](https://www.odoo.com/odoo/2328/tasks/4818132) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> 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: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@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> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update stops users from choosing a private task as the parent of another task. It helps keep private work items properly hidden and avoids accidental exposure through task hierarchy relationships.
Original PR description
In this commit, we ensure that private tasks can never be selected as parent tasks. task-5119141 Forward-Port-Of: odoo/odoo#272263 Forward-Port-Of: odoo/odoo#270795
The Point of Sale stock tests were updated so lot tracking is set on the product template instead of the product variant. This keeps the tests working with the current Odoo behavior and helps avoid validation errors during automated testing.
Original PR description
`tracking` is no longer writable on `product.product` on 19.3/master. Update lot-related POS tests to write it on `product.template` instead. original task: 6274744 runbot error: 940485
Financial budget lines can now use accounts classified as Other Expenses. This fixes a selection issue that prevented some valid profit-and-loss accounts from being added to budgets, making budget setup more complete and consistent.
Original PR description
Currently, accounts with the `Other Expenses` account type cannot be selected in financial budget lines. **Steps to reproduce:** - Install the `accountant` module. - Go to `Chart of Accounts` and…
Currently, accounts with the `Other Expenses` account type cannot be selected in financial budget lines. **Steps to reproduce:** - Install the `accountant` module. - Go to `Chart of Accounts` and create a new account with `Type: Other Expenses`. - Go to Accounting > Configuration > Financial Budgets. - Create a new budget and add a budget line. - Try to select the newly created account. **Observation:** Accounts with the `Other Expenses` type are not available for selection in budget lines. **Root Cause:** At [1], the `expense_other` account type is missing from the `account_id` domain. **Expected Behavior:** Financial budgets should allow all Profit & Loss accounts, since the feature relies on P&L reporting. **Reference**: https://www.odoo.com/odoo/project/49/tasks/4314709 **Fix:** This commit ensures that users can add `Other Expenses` accounts to budget lines. [1]: https://github.com/odoo/enterprise/blob/41b66ba081f3938f7e55da209506c637850ae4ec/account_reports/models/budget.py#L114-L120 opw-6313835 Forward-Port-Of: odoo/enterprise#121735
This fixes an issue where a customer's chosen delivery and billing addresses could be replaced when the cart was refreshed after checkout. The selected addresses now stay in place when they still belong to the same customer, preventing incorrect sales orders and reducing order errors.
Original PR description
Steps to reproduce: =================== 1. Add several delivery addresses & billing addresses 2. Add a product to the cart and go to checkout. 3. Select a specific delivery address and a different…
Steps to reproduce: =================== 1. Add several delivery addresses & billing addresses 2. Add a product to the cart and go to checkout. 3. Select a specific delivery address and a different invoice address. 4. Pay and click "Skip" immediately on that page. 5. Open the resulting sales order. => The delivery address is reset to the company's first delivery child instead of the one selected during checkout. Root cause: =========== `partner_shipping_id` and `partner_invoice_id` are stored computed fields (compute + store + readonly=False) that depend on `partner_id`. Any write that includes `partner_id`, even writing the same value, retriggers the compute and overwrites a manually selected address with the result of `partner_id.address_get()`. `_get_and_cache_current_cart` resurrects the customer's draft cart when it is no longer referenced in the session and re-runs `_update_address(partner, ['partner_id'])` on it to refresh the pricelist and fiscal position. Clicking "Skip" runs `sale_reset()`, which clears the session cart key while the order is still draft, so the next cart access takes that abandoned-cart branch and the redundant `partner_id` write discards the selected delivery/invoice address. Waiting a few seconds lets the order reach the 'sale' state first, so the draft search no longer matches and the address is kept, which is why the issue is timing dependent. Fix: ==== In `_update_address`, when partner_id is written, keep the delivery and invoice addresses already set on the cart if they still belong to the new partner's company (same `commercial_partner_id`) by writing them in the same `write()` so the recompute does not override them. Addresses that do not belong to the new partner are still recomputed to the partner's defaults. opw-6267188 Forward-Port-Of: odoo/odoo#270300
This update corrects the alignment of the link popover’s URL field and its icon in Notes. It ensures the input keeps the same height as its container, so the interface looks consistent even when autocomplete is available.
Original PR description
Steps to Reproduce: - open notes - type `/link` to open link popover Issue: - The url input field and its icon are misaligned. Cause: - When url autocomplete are enabled in the link popover, the input field height is reduced, causing it to become smaller than its container. This results in misalignment between the input field and the icon. Solution: - Set the link popover url input height to 100% so it always matches the height of its container, ensuring proper alignment even when autocomplete is avaialble. task-6201175
This fix prevents a crash when portal users open Knowledge articles that include author information in list items. It ensures those users can see shared article content without running into access permission errors.
Original PR description
Problem: Since saas-19.2 (99f38be260c3c5523306e4ffcb4cf18436d40568), portal users crash when opening a Knowledge article containing items with "Created by" or "Last edited by" columns. Cause: Portal…
Problem: Since saas-19.2 (99f38be260c3c5523306e4ffcb4cf18436d40568), portal users crash when opening a Knowledge article containing items with "Created by" or "Last edited by" columns. Cause: Portal users are restricted to their own res.users record. Reading create_uid and last_edition_uid of internal users raises an AccessError. This was not raised in 19.0. Specifically, the `many2one_avatar_user` field widget defines `write_date` in `relatedFields`, which forces the RPC to read the `write_date` field of the target user. Since portal users cannot read other users' records, it raises an AccessError. Solution: Only include `write_date` in the field widget's `relatedFields` if the current user is an internal user. For portal users, `relatedFields` will be empty, avoiding the AccessError. Steps to reproduce: 1. Create a Knowledge article. 2. Add an "Item list" element. 3. Add some items to the list. 4. Share the article with a portal user. 5. Open the article as the portal user. 6. Observe that only the list header is visible and the items are not displayed. opw-6199714 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#269479
This fix brings back the intended behavior for pages using the `s_nb_column_fixed` class, which hides the column count option in the builder. It ensures that layouts marked this way no longer show an option that should be locked, improving consistency for content editors.
Original PR description
The class 's_nb_column_fixed' was used to hide the column count option, but it got lost during the refactoring and doesn't work since 18.4. This commit restores it. task-6234267 Forward-Port-Of: odoo/odoo#271975 Forward-Port-Of: odoo/odoo#268005
This fix keeps overtime durations more accurate when they are recorded for payroll calculations. It prevents small rounding errors from affecting the amount paid for overtime work.
Original PR description
Overtime duration computed as fractional hours was rounded to 3 decimal places before being stored on the overtime line. Since 1 decimal hour = 3600 seconds, this gives only 3.6 seconds of precision and the rounding can go in the wrong direction due to floating-point representation. The fix consists in replacing the duration rounding to 4 decimals when building overtime work entries so stored durations keep sub-second precision needed for money computation. task-6212231 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#270417 Forward-Port-Of: odoo/odoo#268889
Overtime hours are now stored with more precise decimal values, so small time differences are not lost before payroll calculations. This helps ensure overtime pay is computed more accurately and consistently.
Original PR description
Overtime duration computed as fractional hours was rounded to 3 decimal places before being stored on the overtime line. Since 1 decimal hour = 3600 seconds, this gives only 3.6 seconds of precision and the rounding can go in the wrong direction due to floating-point representation. The fix consists in replacing the duration rounding to 4 decimals when building overtime work entries so stored durations keep sub-second precision needed for money computation. task-6212231 Forward-Port-Of: odoo/enterprise#120786 Forward-Port-Of: odoo/enterprise#119721
This update corrects how the Peru address fields are linked in the website checkout form. It prevents an error that could stop customers from completing checkout after upgrading, ensuring the page loads correctly again.
Original PR description
Issue: ------ `l10n_pe.address_form_fields` inherits from `portal.address_form_fields` but targets a `<div>` element that has been moved to `portal_address_extended.address_extended_form_fields` in…
Issue:
------
`l10n_pe.address_form_fields` inherits from `portal.address_form_fields` but targets a `<div>` element that has been moved to `portal_address_extended.address_extended_form_fields` in [saas~19.2].
Traceback:
----------
```py
Error while rendering the template:
ValueError: Element '<div id="div_city_id">' cannot be located in parent view (view: l10n_pe.address_form_fields)
Template: website_sale.address
Reference: 1973
Path: /t/t/div/div/form/div/t
Element: <t t-call="website_sale.address_form_fields"/>
```
Steps to reproduce:
-------------------
1. Install `l10n_pe` and `website` in v19
2. Upgrade to v19.2
3. Go to the website and add a product to the cart
4. Go to checkout → Traceback
Root cause:
-----------
The view is adapting an element owned by a sibling view, making the inheritance hierarchy conceptually wrong and fragile.
Solution:
---------
Update the `inherit_id` of `l10n_pe.address_form_fields` to `portal_address_extended.address_extended_form_fields` so it correctly inherits from the view that owns the targeted element.
opw: [6302145]
[saas~19.2]: https://github.com/odoo/odoo/commit/026c6f9f2a388ee509a135c53e38f5bb3d08ff73#diff-83bb066f4477532b76aadd957ae736d0c0b67bc66b48d6f47c035e8cfb4773deR7-R21
[6302145]: https://www.odoo.com/odoo/70/tasks/6302145?debug=1
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#271246This fix prevents cost-of-goods-sold entries from being treated like regular tax base lines when bills are confirmed. As a result, manually adjusted taxes on vendor bills are no longer overwritten during the accounting update, reducing unexpected changes for users.
Original PR description
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new…
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new product category with the costing method Standard Price and the inventory valuation Automatic. 4. Navigate to Products, click into any product. 5. Add the new product category to this product under General Information. 6. Add any tax in the purchase tax field. 7. In the Accounting tab of the product, add any account to the Price Difference Account field. https://drive.google.com/file/d/1i2DHEt0g9G5Edad_QB3QaFkOT49cbMAZ/view?usp=sharing Instructions to reproduce error 1. Navigate to Purchase. 2. Add a customer, then add the configured product. 3. Add a tax to the line. Ensure that the tax and price_unit are nonzero. 4. Confirm the order. 5. Receive the product. 6. Create the bill. 7. Edit the tax on the vendor bill, then save the changes. Notice that the changes are kept. 8. Select Confirm. Notice that the changes to the tax line are not kept, and that the COGS lines appeared (with taxes applied to them). 9. Reset the bill to draft. 10. Click into the configured product and remove the product category. 11. Repeat steps 7-8 . No COGS lines, and the tax line is the manually set value. ## Current behavior before PR: COGS lines with taxes have no net effect on any tax lines as they cancel each other out. However, their creation triggers the recalculation of all tax lines, undoing any manual adjustments to tax lines. ## Desired behavior after PR is merged: This commit ensures that COGS lines are not considered base tax lines, so that their creation does not trigger the recalculation of other base tax lines. opw-5387248 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271262 Forward-Port-Of: odoo/odoo#262442
This update makes the public chat test flow more reliable by ensuring the attachment menu closes before the message is sent. It also corrects a test setup issue so the right conversation data is updated between runs, helping prevent flaky failures during automated testing.
Original PR description
Attempt at fixing the following race condition. It's not clear what causes it, but these changes make the test more robust and might help future investigations. discuss_channel_public_tour opens the composer "More Actions" menu to attach files but feeds the hidden file input directly, so the menu is never closed and is still open when Send is clicked. Close it and wait for it to disappear before sending, to avoid clicking Send while the dropdown is dismissing. Also fix _open_group_page_as_user, which updated the last message body of self.channel instead of self.group between the two tour runs. https://runbot.odoo.com/odoo/error/243436 Forward-Port-Of: odoo/odoo#272606 Forward-Port-Of: odoo/odoo#272425
This change prevents Romanian-specific stock batch behavior from being applied in situations where it should not be. It fixes an error that affected automated system checks and helps keep the stock workflow stable.
Original PR description
The Romanian specifics were applied without condition which caused runbot errors. Note that this was revealed later on (saas-19.3) after a change in the generic stock test setup. runbot-241098 Forward-Port-Of: odoo/odoo#271985
26 changes
Resolved issues and error corrections
The Planning app now calculates weekly hours correctly when the user's week starts on a different day than the default locale setting. This prevents employees with flexible schedules from showing more expected hours than their calendar allows, improving the accuracy of planning information.
Original PR description
**Steps to reproduce** - Install planning - Switch to English (UK) and change the "First day of the week" to Sunday in the technical settings - Have an employee with a flexible schedule with a total of 40h/week, average 8h/day - In the planning app, after creating a shift to display the employee in the gantt view, notice that when hovering over the progress bar on the left, 48 worked hours are expected for the current week, which is more than what is defined in the employee's calendar **Cause** The displayed week, starting on Sunday, could accumulate more hours than the weekly cap due to the Sunday being part of another week with the locale default first day (Monday). opw-6110395 Forward-Port-Of: odoo/odoo#270926 Forward-Port-Of: odoo/odoo#259600
This fix prevents project, task, and description values from disappearing when users close the Timesheets systray. It ensures the details entered after saving or resetting are preserved, improving reliability and reducing repeated data entry.
Original PR description
## Issue When using the Timesheets systray, if we set a project after clicking the *Save* or *Reset* button, the project is not saved after closing the systray. ## Steps to reproduce 1. Install…
## Issue When using the Timesheets systray, if we set a project after clicking the *Save* or *Reset* button, the project is not saved after closing the systray. ## Steps to reproduce 1. Install *Timesheets* (`timesheet_grid`) 2. Open the Timesheets systray 3. Click *Reset* and set a description, a project and/or a task, then close the systray 4. Open the systray again 5. **The description/project/task set in step 3 do(es) not appear anymore.** ## Cause Commit https://github.com/odoo/enterprise/commit/b9b7f8a0acf7a1c545c6613cf8bbc29871632e26 introduced the `preventUnmountSave` attribute. The attribute is set to `true` after saving and discarding an entry. When the systray is unMounted, the manual values (e.g., description, project and task) are not saved if the attribute is set to `true`: https://github.com/odoo/enterprise/blob/7cd8dd008eb88d6c12f3e65fb8d311058290a301/timesheet_grid/static/src/components/timesheet_timer_inline_form/timesheet_timer_inline_form.js#L171-L174 ## Fix After discussing with the author of the previous commit, it appears this was done to prevent an issue with values stored in cache, but that issue does not seem to occur anymore, which leads to believe that the attribute is not required anymore. opw-6284016
We fixed an issue on product pages where selecting a variant could incorrectly show a product from a content snippet instead of the chosen item. The page now consistently uses the main product's information, so prices and images stay accurate when customers browse variants.
Original PR description
When a "Products" snippet is dropped above the variant selector on a product page, selecting a variant displays one of the snippet's products instead of the chosen variant (its image/price take over…
When a "Products" snippet is dropped above the variant selector on a product page, selecting a variant displays one of the snippet's products instead of the chosen variant (its image/price take over the page).
Steps to reproduce
===================
1. Create a product with 2+ variants and publish it.
2. Edit the product page, drag any block above the variant selector and add the "Products" dynamic snippet, then save.
3. Select a variant. => The page shows the snippet's first product instead of the variant.
Root cause
==========
`ProductPage._getCombinationInfo` reads the product ids from `parent.querySelector('button[name="add_to_cart"]')`, with `parent` being the whole `.js_product`. `querySelector` returns the first match in DOM order, and the dynamic "Products" snippet's cards reuse the same `button[name="add_to_cart"]` markup with their own product ids. When the snippet sits above the variants, its button comes first, so `/website_sale/get_combination_info` is called with the snippet product's ids and the page is updated with that product's data.
The interaction was introduced in saas-19.1 (See [1]) and the lookup switched from the unique `#add_to_cart` id to the by-name selector in (See [2]), which is what started matching the snippet's cards.
Fix
===
Pick the first `add_to_cart` button that is not inside a product card (`.oe_product_cart`), i.e. the main product's button.
[1]: https://github.com/odoo/odoo/commit/4682748e6e3c#diff-7e1a99da9e95d0c4df79ee4d7aa718e46bcb8b7f1ed78cde58782e075c833cd1R326
[2]: https://github.com/odoo/odoo/commit/1c732cf75a4a4faa960d6a98f08ae9dbe99b2b69#diff-7e1a99da9e95d0c4df79ee4d7aa718e46bcb8b7f1ed78cde58782e075c833cd1R329
opw-6248285
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#268518This change fixes an automated test so it no longer leaves temporary code behind after it runs. It keeps the test environment clean and prevents unnecessary test failures during development and validation.
Original PR description
Avoid polluting the Odoo model registry and failing `test_lint_override_signature` by using `patch.object` instead of manual assignment. This ensures the injected method is properly torn down after the test block, keeping the registry clean and bypassing static analysis failure as the patched method is only used for tests. runbot-939298
This fix prevents private tasks from being assigned as a parent for other tasks. It helps keep task relationships consistent and avoids exposing private work in places where it should not appear.
Original PR description
In this commit, we ensure that private tasks can never be selected as parent tasks. task-5119141 Forward-Port-Of: odoo/odoo#272263 Forward-Port-Of: odoo/odoo#270795
This update improves the way Point of Sale loyalty tests are temporarily modified during testing. It keeps those test changes isolated and automatically cleaned up afterward, which prevents unrelated test failures and helps maintain overall system stability.
Original PR description
Avoid polluting the Odoo model registry and failing `test_lint_override_signature` by using `patch.object` instead of manual assignment. This ensures the injected method is properly torn down after the test block, keeping the registry clean and bypassing static analysis failure as the patched method is only used for tests. runbot-939298
Users can now select accounts marked as Other Expenses when creating financial budget lines. This fixes a limitation that prevented some valid profit and loss accounts from being used in budgets, making budget setup more complete and accurate.
Original PR description
Currently, accounts with the `Other Expenses` account type cannot be selected in financial budget lines. **Steps to reproduce:** - Install the `accountant` module. - Go to `Chart of Accounts` and…
Currently, accounts with the `Other Expenses` account type cannot be selected in financial budget lines. **Steps to reproduce:** - Install the `accountant` module. - Go to `Chart of Accounts` and create a new account with `Type: Other Expenses`. - Go to Accounting > Configuration > Financial Budgets. - Create a new budget and add a budget line. - Try to select the newly created account. **Observation:** Accounts with the `Other Expenses` type are not available for selection in budget lines. **Root Cause:** At [1], the `expense_other` account type is missing from the `account_id` domain. **Expected Behavior:** Financial budgets should allow all Profit & Loss accounts, since the feature relies on P&L reporting. **Reference**: https://www.odoo.com/odoo/project/49/tasks/4314709 **Fix:** This commit ensures that users can add `Other Expenses` accounts to budget lines. [1]: https://github.com/odoo/enterprise/blob/41b66ba081f3938f7e55da209506c637850ae4ec/account_reports/models/budget.py#L114-L120 opw-6313835 Forward-Port-Of: odoo/enterprise#121735
This update refreshes the spreadsheet component to its latest version and includes several fixes for everyday editing. It improves color selection behavior, adds support for a missing default font on Linux, and resolves a chart display issue that could appear after file optimization. Overall, it should make spreadsheets feel more reliable and consistent for users.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b76d689853 [REL] 19.2.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/b76d689853 [REL] 19.2.18 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/d398a74044 [FIX] sheet: close the color picker on external click [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/5235a56ab4 [FIX] sheet: add sheet tab color to custom colors [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/7ac62df228 [FIX] Fonts: Add default font for Linux [Task: 6328646](https://www.odoo.com/odoo/2328/tasks/6328646) https://github.com/odoo/o-spreadsheet/commit/18b9293819 [FIX] chart: zoomable chart height issue with rjsmin minification [Task: 6306092](https://www.odoo.com/odoo/2328/tasks/6306092) https://github.com/odoo/o-spreadsheet/commit/11fb7c91cf [IMP] package: add runbot script [Task: 6316690](https://www.odoo.com/odoo/2328/tasks/6316690) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> 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: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@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> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update makes a public chat test more reliable by ensuring a menu closes before the Send action is triggered. It also corrects a test helper so it updates the right conversation data between runs, which helps prevent flaky failures and improves confidence in messaging behavior.
Original PR description
Attempt at fixing the following race condition. It's not clear what causes it, but these changes make the test more robust and might help future investigations. discuss_channel_public_tour opens the composer "More Actions" menu to attach files but feeds the hidden file input directly, so the menu is never closed and is still open when Send is clicked. Close it and wait for it to disappear before sending, to avoid clicking Send while the dropdown is dismissing. Also fix _open_group_page_as_user, which updated the last message body of self.channel instead of self.group between the two tour runs. https://runbot.odoo.com/odoo/error/243436 Forward-Port-Of: odoo/odoo#272606 Forward-Port-Of: odoo/odoo#272425
This change fixes an unstable automated test in the messaging app that could occasionally fail because of timing, not because of a real product issue. It makes the retry scenario behave more like a real user experience, reducing false test failures and improving release reliability.
Original PR description
The "Retry loading more messages on failed load more messages" test drove load-more by scrolling (real IntersectionObserver) and failed the fetch synchronously, then clicked retry immediately. The observer could fire the older-fetch twice and leave a second fetch in flight at the retry click, which then no-op'd (fetchMoreMessages bails while a fetch is loading), leaving 30 messages instead of 60. This is a test-timing artifact: a real user retries long after any fetch has settled. Fail the load-more through a Deferred rejected only once the fetch is in flight, like jump_to_present.test.js. While it is pending, duplicate observer fires no-op, so no orphan fetch can race the retry. https://runbot.odoo.com/odoo/error/242113 Forward-Port-Of: odoo/odoo#272605 Forward-Port-Of: odoo/odoo#272430
Importing product categories now handles parent category names more reliably and no longer shows a blocking “multiple matches” warning for valid entries. This makes category imports smoother and prevents unnecessary interruptions when organizing products into hierarchies.
Original PR description
When trying to import Product Categories, importing the Parent Category may raise blocking warnings. Steps to reproduce: - Open Sales > configuration > Categories - Import records - Select a file containing the parent category name - Import category name and parent category Issue: A warning will raise Found multiple matches for value "Furniture" in field "Parent Category" (2 matches) It occurs because, while searching by name, the system will use the complete name of the category so it will match multiple times the same name. This behaviour has been introduced in https://github.com/odoo/odoo/pull/236067/changes/0f788b8105c715681d67fdac04fa82c4c4d48e5e opw-6283004
Printing the Planning report now works reliably even when it is grouped by fields other than Employee, such as Role or Project. This prevents report generation failures and ensures multi-day shifts are handled correctly in all supported groupings.
Original PR description
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or…
### Issue: When printing the Planning report (PDF) and grouping by a field other than Employee (e.g., Role, Project, or a Char/Selection field), the server crashes with a `TypeError` or `AttributeError`. ### Cause: The `action_print_plannings` method hardcoded the assumption that the `group_by` key would always be a `resource.resource` recordset. 1. When the user grouped by other fields, it returned strings, booleans, or empty recordsets, causing crashes when the code blindly called `.id` and `.display_name`. 2. During the sorting phase, mixing `False` (for unassigned empty recordsets) with strings caused a `TypeError`. 3. For multi-day shifts, the method failed to extract the actual resource to calculate the shift splits if the grouping was not explicitly set to `resource_ids`. ### Fix: - Implement safe attribute checks (`hasattr`) when extracting group IDs and display names. - Ensure unassigned empty recordsets properly fall back to the "Undefined" string and empty strings during sorting to prevent TypeErrors. - Universally fallback to extracting the resource directly from the slot (`slot.resource_ids[:1]`) for multi-day time splitting when grouped by non-resource fields. - Add a unit test to ensure stability when grouping by `role_id` with multi-day shifts. Task: 6244057
Invoices in Saudi Arabia and the UAE will now use the customer’s language when showing the invoice title. This fixes cases where Arabic-speaking customers were seeing the title in English on printed invoices.
Original PR description
### Issue: On invoices in SA and AE, the invoice title was always rendered in English even when the customer's language is Arabic ### Cause: In 19.2, the report view `report_invoice_document` was…
### Issue: On invoices in SA and AE, the invoice title was always rendered in English even when the customer's language is Arabic ### Cause: In 19.2, the report view `report_invoice_document` was refactored to require `t-set` declarations before `t-call` In 19.1, `o` was reassigned early with the customer language via `t-value="o.with_context(lang=lang)"`, so all subsequent calls on `o` inherited the correct language https://github.com/odoo/odoo/blob/3d2d8cc498a56faac31e95fb854a94e4011d812d/addons/account/views/report_invoice.xml#L4-L6 After the refactor, `o` no longer carries the customer language context at the point where `l10n_gcc_settings` is evaluated `_l10n_gcc_get_invoice_title()` was therefore called with the connected user's language instead of the customer's ### Steps to reproduce: - Install `l10n_sa` or `l10n_ae` and switch to the corresponding company - Create and confirm an Invoice (any data) - Set the customer language to Arabic - Print the Invoice Before the fix, the invoice title is displayed in English opw-6333472
This change makes the avatar card tour test run on a fixed mid-week date instead of depending on the current day. It prevents the test from failing intermittently on Fridays and Saturdays, improving the reliability of automated checks without changing customer-facing behavior.
Original PR description
The avatar card tours create a time off relative to "today" and assert the "Back on" out-of-office indicator. When the test runs on a Friday or Saturday, today+1 is a weekend, so the leave's date_to lands on that weekend day's 00:00 and the "currently on leave" window closes at midnight. Once the run crosses that boundary the leave is no longer active, the indicator disappears and the tour fails at the "Back on" step, deterministically on that weekday. Freeze setUpClass to a fixed mid-week day so the time off always ends on a working day. https://runbot.odoo.com/odoo/error/242512
This change prevents a crash when translating a report’s XML in Studio on databases where English is not installed. It makes the translation flow work more reliably for users who operate in other languages only.
Original PR description
Init a db with a language different from en_US install other languages, except en_US Try to translate via studio a report's XML This gives a crash, because the baseLang is not installed After this commit, there is no crash. opw-6239938
This fix prevents inventory-related actions from breaking when a product template has no variant yet. It hides or blocks actions like forecast, on-hand quantity, and replenish until the product is in a valid state, avoiding errors and unexpected behavior for users.
Original PR description
Issue: --- Not having at least one variant created for a product template with dynamic attributes can cause issues as it's expected a product template to have at least one variant. To reproduce: 1-…
Issue: --- Not having at least one variant created for a product template with dynamic attributes can cause issues as it's expected a product template to have at least one variant. To reproduce: 1- Create a dynamic attribute with values. 2- Create a product and without saving: - Enable track inventory. - Add the dynamic attributes and values. 3- Save the product. 4- Click on forecasted quantity smart button: - There is a traceback. 5- Click on Replenish: - Unexpected behavior. 6- Click on `Product On Hand Quantity`: - No product will be shown if you try to add quantity. Cause: --- This is caused because there is no variant created. In the steps, if you save the template once before adding dynamic attributes, a single variant will be created which allows it to work without issue. Fix: --- we can fix the TB by hiding the forecasted qty smart button, when there is no variant. However, there will be still issue with `Replenish` flow, which requires a variant. We could do the prevent the issue by ensuring there is at least one variant. opw-6260253 Forward-Port-Of: odoo/odoo#272614 Forward-Port-Of: odoo/odoo#268879
When a sign template was duplicated, both copies could accidentally share the same role settings. This fix makes each duplicated template keep its own independent roles, so changes in one template no longer affect the other.
Original PR description
When duplicating a sign template, its sign items were copied but their `responsible_id` was kept as a reference to the same `sign.item.role` records. As a result, editing a role on one template (e.g. assigning a partner through `assign_to`) leaked to the other template sharing it. Copy the role when copying a sign item so each template owns its own roles. task-6288951 Forward-Port-Of: odoo/enterprise#119864
This fix brings back the behavior that hides the column count option when a specific layout class is used. It ensures website content editors see the intended editing options again, matching how the builder worked before the refactoring.
Original PR description
The class 's_nb_column_fixed' was used to hide the column count option, but it got lost during the refactoring and doesn't work since 18.4. This commit restores it. task-6234267 Forward-Port-Of: odoo/odoo#271975 Forward-Port-Of: odoo/odoo#268005
This change updates a salary configurator test so it includes the employee’s private address information. It helps ensure the test reflects real-world employee data and prevents false failures in the salary setup flow.
Original PR description
Task-6329628 Forward-Port-Of: odoo/enterprise#121935 Forward-Port-Of: odoo/enterprise#121626
This update keeps restaurant order quantities correctly in sync after split payments when the Germany Fiskaly setup is enabled. It prevents already-paid items from remaining on the parent order, so staff cannot accidentally charge the same lines multiple times from the Orders view.
Original PR description
In POS Restaurant with Germany Fiskaly enabled, splitting and paying from a table works once, but repeating the same flow from the Orders tab lets the parent order show lines that were already paid…
In POS Restaurant with Germany Fiskaly enabled, splitting and paying from a table works once, but repeating the same flow from the Orders tab lets the parent order show lines that were already paid in previous splits. Functionally, the cashier can keep splitting and paying the same line again and again because the parent draft order is not updated consistently in that path. Steps to reproduce: ------------------- * Enable POS Restaurant with l10n_de Fiskaly * Create a table order (e.g. 3 meals + 3 drinks) * Open Split Bill, move 1 meal + 1 drink, and pay * From Orders tab, open the remaining parent order and repeat split + pay * Reopen the parent order from Orders tab > Observation: The parent order still contains quantities that were already split/paid, so the same items can be paid multiple times from the Orders tab. Why the fix: ------------ The Fiskaly `syncAllOrders` override diverged from core sync behavior in the split flow: it ignored explicit `options.orders` and did not await transaction creation for inactive transactions. In the split-bill path this could skip or desynchronize parent-order updates, leaving stale quantities on the parent order. The fix restores expected sync semantics by honoring `options.orders` and awaiting transaction creation before deciding sync eligibility. opw-6175880 Forward-Port-Of: odoo/enterprise#117206
When a POS order is edited in the backend, taxes on new lines could disappear after saving even though they were shown correctly on screen. This update makes sure those tax values are saved properly, preventing incorrect totals during returns or exchanges.
Original PR description
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly…
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly sets `tax_ids` from the product, and the computed `tax_ids_after_fiscal_position` displays the mapped taxes in the UI. However, because `tax_ids` is readonly, the web client does not include it in the save payload. As a result, the taxes are silently dropped on save and `tax_ids_after_fiscal_position` recomputes to empty. Steps to reproduce: 1. Create and pay a POS order with a product that has taxes 2. Go to the backend (Point of Sale > Orders) and open that order 3. Initiate a return for the order 4. In the return order, add a new product (exchange scenario) 5. Observe that taxes are correctly shown on the new line 6. Click Save 7. The taxes disappear from the order line The fix adds `force_save="1"` to the `tax_ids` field in both the list and form views of `pos.order.line`, consistent with how `price_subtotal` and `price_subtotal_incl` are already handled in the same views. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261672 Forward-Port-Of: odoo/odoo#253680
This fix prevents inventory cost adjustment lines from being treated like normal tax bases when bills are confirmed. As a result, manually edited tax amounts on vendor bills are no longer overwritten during confirmation, which avoids unexpected changes for users.
Original PR description
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new…
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new product category with the costing method Standard Price and the inventory valuation Automatic. 4. Navigate to Products, click into any product. 5. Add the new product category to this product under General Information. 6. Add any tax in the purchase tax field. 7. In the Accounting tab of the product, add any account to the Price Difference Account field. https://drive.google.com/file/d/1i2DHEt0g9G5Edad_QB3QaFkOT49cbMAZ/view?usp=sharing Instructions to reproduce error 1. Navigate to Purchase. 2. Add a customer, then add the configured product. 3. Add a tax to the line. Ensure that the tax and price_unit are nonzero. 4. Confirm the order. 5. Receive the product. 6. Create the bill. 7. Edit the tax on the vendor bill, then save the changes. Notice that the changes are kept. 8. Select Confirm. Notice that the changes to the tax line are not kept, and that the COGS lines appeared (with taxes applied to them). 9. Reset the bill to draft. 10. Click into the configured product and remove the product category. 11. Repeat steps 7-8 . No COGS lines, and the tax line is the manually set value. ## Current behavior before PR: COGS lines with taxes have no net effect on any tax lines as they cancel each other out. However, their creation triggers the recalculation of all tax lines, undoing any manual adjustments to tax lines. ## Desired behavior after PR is merged: This commit ensures that COGS lines are not considered base tax lines, so that their creation does not trigger the recalculation of other base tax lines. opw-5387248 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271262 Forward-Port-Of: odoo/odoo#262442
Employees can now submit expenses even if they do not have a manager assigned, avoiding an error that blocked the process. They can also continue adding comments and attachments to their own expenses after they are no longer in draft, which makes it easier to answer questions and provide supporting documents.
Original PR description
# [FIX] hr_expense: Submitting an expense without a manager doesn't work If a user tries to submit an expense without having a manager, this will fail with "You are neither a Manager nor a HR Officer". To fix this, we are not going to check when the manager is the user that expense is linked to. --------- # [FIX] hr_expense: Employee cant use chatter on his own expenses An employee that created his expense was only able to add attachments and post message in the chatter when the expense was in draft. After this, it will still be able to attach attachment and post message without having the right to edit the expense. This is better as the employee will be able to answer questions that have been asked or add more proof if required. [task-4966942](https://www.odoo.com/odoo/all-tasks/4966942) Forward-Port-Of: odoo/odoo#272957 Forward-Port-Of: odoo/odoo#224575
Odoo has updated the GIF integration settings to use Klipy instead of Tenor. This change helps ensure GIF features keep working after Tenor’s service is retired, but existing API keys must be replaced with valid Klipy keys.
Original PR description
Tenor API will be terminated on June 30, 2026: https://developers.google.com/tenor/guides/quickstart This commit makes the Tenor API key input settings use a Klipy GIF API key instead of a Tenor GIF API key. To keep GIF working after this commit, the API key must necessarily be changed to a Klipy GIF API key, as the old Tenor API key would be considered as an invalid Klipy API key. Task-5491965 Upgrade: https://github.com/odoo/upgrade/pull/10516 Forward-Port-Of: odoo/odoo#272630 Forward-Port-Of: odoo/odoo#250113
This update ensures Romanian-specific stock handling is only applied when it should be. It prevents test and system errors caused by those settings being enabled unconditionally, improving stability for automated checks and future updates.
Original PR description
The Romanian specifics were applied without condition which caused runbot errors. Note that this was revealed later on (saas-19.3) after a change in the generic stock test setup. runbot-241098 Forward-Port-Of: odoo/odoo#271985
This update fixes the Peru Kardex PLE inventory reports so they calculate quantities and values more accurately, especially when there are later purchases or negative opening balances. It also keeps landed costs visible as separate report lines, improving compliance and making the report easier to reconcile.
Original PR description
*Continuing on the work from https://github.com/odoo/enterprise/pull/111526, new PR because we cannot push to it.* Adapt the Kardex PLE 12.1/13.1 reports from the SVL-based approach in 18.0 to the stock.move-based approach required in 19.0. Key changes: - Use traceable IDs (account_move_id/stock_move_id) for CUO field - Back-calculate opening balance cost at report date instead of using current standard_price, which is wrong when post-period purchases have changed the average cost - Filter storable products only (is_storable) matching v17/v18 behavior - Handle negative opening balance quantities correctly - Add bridge module l10n_pe_reports_stock_landed_costs to show landed costs as separate Kardex lines (operation_type=26) without forcing stock_landed_costs as a hard dependency Forward-Port-Of: odoo/enterprise#121855
8 changes
Resolved issues and error corrections
When a POS order is edited in the backend, taxes on new lines are now preserved after saving. This prevents taxes from disappearing during return or exchange workflows, avoiding incorrect totals and manual corrections.
Original PR description
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly…
The `tax_ids` field on `pos.order.line` is defined with `readonly=True`. When editing a POS order from the backend (e.g. during a return/exchange flow), the `_onchange_product_id` method correctly sets `tax_ids` from the product, and the computed `tax_ids_after_fiscal_position` displays the mapped taxes in the UI. However, because `tax_ids` is readonly, the web client does not include it in the save payload. As a result, the taxes are silently dropped on save and `tax_ids_after_fiscal_position` recomputes to empty. Steps to reproduce: 1. Create and pay a POS order with a product that has taxes 2. Go to the backend (Point of Sale > Orders) and open that order 3. Initiate a return for the order 4. In the return order, add a new product (exchange scenario) 5. Observe that taxes are correctly shown on the new line 6. Click Save 7. The taxes disappear from the order line The fix adds `force_save="1"` to the `tax_ids` field in both the list and form views of `pos.order.line`, consistent with how `price_subtotal` and `price_subtotal_incl` are already handled in the same views. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261672 Forward-Port-Of: odoo/odoo#253680
This change prevents an error that could occur when the system looks up an IoT device and finds more than one match. As a result, IoT device access is more reliable and users are less likely to encounter interruptions.
Original PR description
Currently, a singleton error occurs while accessing the `type` field on `iot_device`, as the search assigned to `iot_device` returns multiple `iot.device` records. Error: `ValueError: Expected singleton: iot.device(5, 10)` This commit fixes the above issue by adding `limit=1` to the search, ensuring that `iot_device` always contains a single record and preventing the singleton error. Sentry-7579060623
This update fixes an issue in POS Restaurant with German Fiskaly where repeating a split-and-pay flow from the Orders screen could leave already-paid items on the parent order. As a result, the same items could be split and paid again; the fix keeps the order totals and line quantities synchronized so paid items are removed correctly.
Original PR description
In POS Restaurant with Germany Fiskaly enabled, splitting and paying from a table works once, but repeating the same flow from the Orders tab lets the parent order show lines that were already paid…
In POS Restaurant with Germany Fiskaly enabled, splitting and paying from a table works once, but repeating the same flow from the Orders tab lets the parent order show lines that were already paid in previous splits. Functionally, the cashier can keep splitting and paying the same line again and again because the parent draft order is not updated consistently in that path. Steps to reproduce: ------------------- * Enable POS Restaurant with l10n_de Fiskaly * Create a table order (e.g. 3 meals + 3 drinks) * Open Split Bill, move 1 meal + 1 drink, and pay * From Orders tab, open the remaining parent order and repeat split + pay * Reopen the parent order from Orders tab > Observation: The parent order still contains quantities that were already split/paid, so the same items can be paid multiple times from the Orders tab. Why the fix: ------------ The Fiskaly `syncAllOrders` override diverged from core sync behavior in the split flow: it ignored explicit `options.orders` and did not await transaction creation for inactive transactions. In the split-bill path this could skip or desynchronize parent-order updates, leaving stale quantities on the parent order. The fix restores expected sync semantics by honoring `options.orders` and awaiting transaction creation before deciding sync eligibility. opw-6175880 Forward-Port-Of: odoo/enterprise#117206
This change replaces the previous memory-tracking approach with a lighter method that reduces the slowdown caused during profiling. It helps ensure profiling remains usable on longer requests and provides a more practical view of where memory growth is happening.
Original PR description
The previous memory profiler was causing a lot of performance issues. This is because tracemalloc tracks the allocations that happens at the python interpreter level by attaching to the cpython…
The previous memory profiler was causing a lot of performance issues. This is because tracemalloc tracks the allocations that happens at the python interpreter level by attaching to the cpython allocators. This first meant each allocation that happens through python has to go through a callstack while holding the GIL and preventing the thread and other threads from operating. This callstack does multiple things, first is walking the allocation back from the current frame up until the specified frame depth at the start of collection. The other is updating the internal object that keeps track of the allocations and what cause them up until now which degrades the performance even more when the allocator keeps running for a long time. Increasing the frame depth also means the partitioning becomes even more fragmented in the internal object and leads to higher memory usage. This in turns means lower performance as well. The issue becomes more evident when the overhead of tracemalloc blocks any execution even turning it off because the gil cannot be released until the full allocation execution happens. Currently this would happen on long enough requests or a high enough depth. Two PRs were made to try to address this issue. 1- https://github.com/odoo/odoo/pull/251950 : This PR tries the solution of having a lower frame depth but matching the frames based on a window of frames so that we can reconstruct an approximation of the flamegraph, for example: matching window of 2 frames 1 - > 2 - > 3 - > 4 2 - > 3 - > 4 - > 5 would mean that we would match frames 2 and 3 in both stack traces and append the first frame to the second callstack which would look like 1 - > 2 - > 3 - > 4 - > 5 Neverthless this was deemed to have too big of an assumption in the building heuristic. 2- https://github.com/odoo/odoo/pull/253120: This PR was supposed to be introducing memray as a profiler. Memray is the best tool for this usecase. First because it attaches on the native system allocation calls, and uses a file to append to on allocations. This solves both of the issues that we had in the beginning but the issue with memray is that it's an external tool that was deemed unnecessary to add. The final solution is this PR: The PR assumes a heuristic that in worker mode, a single worker handles one thread which mean that the process memory can be fully attributed to the request. The heuristic is also based that on a high enough sampling rate, the delta can be fully attributed to the current frame. This is a close enough approximation to know where to look but not what is the actual memory usage by line. Forward-Port-Of: odoo/odoo#253604
This change prevents inventory cost lines from being treated like tax base lines when a vendor bill is confirmed. As a result, manually adjusted taxes on bills are no longer unexpectedly reset after receiving goods with automatic valuation enabled.
Original PR description
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new…
## Description of the issue/feature this PR addresses: Setup plus video 1. Go to settings, enable "Automatic Valuation" and "Storeable Locations". 2. Navigate to Product Categories. 3. Create a new product category with the costing method Standard Price and the inventory valuation Automatic. 4. Navigate to Products, click into any product. 5. Add the new product category to this product under General Information. 6. Add any tax in the purchase tax field. 7. In the Accounting tab of the product, add any account to the Price Difference Account field. https://drive.google.com/file/d/1i2DHEt0g9G5Edad_QB3QaFkOT49cbMAZ/view?usp=sharing Instructions to reproduce error 1. Navigate to Purchase. 2. Add a customer, then add the configured product. 3. Add a tax to the line. Ensure that the tax and price_unit are nonzero. 4. Confirm the order. 5. Receive the product. 6. Create the bill. 7. Edit the tax on the vendor bill, then save the changes. Notice that the changes are kept. 8. Select Confirm. Notice that the changes to the tax line are not kept, and that the COGS lines appeared (with taxes applied to them). 9. Reset the bill to draft. 10. Click into the configured product and remove the product category. 11. Repeat steps 7-8 . No COGS lines, and the tax line is the manually set value. ## Current behavior before PR: COGS lines with taxes have no net effect on any tax lines as they cancel each other out. However, their creation triggers the recalculation of all tax lines, undoing any manual adjustments to tax lines. ## Desired behavior after PR is merged: This commit ensures that COGS lines are not considered base tax lines, so that their creation does not trigger the recalculation of other base tax lines. opw-5387248 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#271262 Forward-Port-Of: odoo/odoo#262442
This change fixes an error that could appear when deleting a newly created receipt. The stock status bar now safely handles cases where nothing is selected, preventing the page from showing a traceback.
Original PR description
# How to reproduce - Create a new Receipt - Save - Delete the new Receipt # The issue A traceback is shown : `TypeError: Cannot read properties of undefined (reading 'label')` # Cause This is caused…
# How to reproduce - Create a new Receipt - Save - Delete the new Receipt # The issue A traceback is shown : `TypeError: Cannot read properties of undefined (reading 'label')` # Cause This is caused by the custom status bar for pickings `StockPickingLockedStatusBarField`. In its template, we replace the display of the current label : https://github.com/odoo/odoo/blob/490c355ae0bc77c1106e22b3afb2206583980324/addons/stock/static/src/fields/stock_picking_locked_statusbar_field.xml#L20-L23 https://github.com/odoo/odoo/blob/490c355ae0bc77c1106e22b3afb2206583980324/addons/stock/static/src/fields/stock_picking_locked_statusbar_field.xml#L4-L9 The issue is that the base implementation of the current label properly handles the case were no item is currently selected: https://github.com/odoo/odoo/blob/7630f8fe2d5198b7a1ed538241795dc26a497fa0/addons/web/static/src/views/fields/statusbar/statusbar_field.js#L298-L300 But the picking implementation does not : https://github.com/odoo/odoo/blob/490c355ae0bc77c1106e22b3afb2206583980324/addons/stock/static/src/fields/stock_picking_locked_statusbar_field.js#L12-L14 And it seems that the template is quickly rendered without any selected item before deletion. opw-6345192
This update corrects the Peru Kardex PLE stock reports so they produce more accurate inventory and cost figures in 19.0. It also adds support for showing landed costs separately, while keeping that functionality optional so businesses do not need an extra dependency unless they use it.
Original PR description
*Continuing on the work from https://github.com/odoo/enterprise/pull/111526, new PR because we cannot push to it.* Adapt the Kardex PLE 12.1/13.1 reports from the SVL-based approach in 18.0 to the stock.move-based approach required in 19.0. Key changes: - Use traceable IDs (account_move_id/stock_move_id) for CUO field - Back-calculate opening balance cost at report date instead of using current standard_price, which is wrong when post-period purchases have changed the average cost - Filter storable products only (is_storable) matching v17/v18 behavior - Handle negative opening balance quantities correctly - Add bridge module l10n_pe_reports_stock_landed_costs to show landed costs as separate Kardex lines (operation_type=26) without forcing stock_landed_costs as a hard dependency Forward-Port-Of: odoo/enterprise#121855
Fixed an issue where Auto Plan could assign a person based only on the project, even if that person was not linked to the selected role. This ensures planning suggestions stay consistent with the role chosen on the slot, avoiding incorrect assignments.
Original PR description
## Issue When using the *Auto Plan* feature on a planning slot with a Role and a Project set, a resource which operated on the same project will be chosen if available, without taking into account…
## Issue
When using the *Auto Plan* feature on a planning slot with a Role and a Project set, a resource which operated on the same project will be chosen if available, without taking into account the Role set on the slot.
## Steps to reproduce
1. Install Project Planning (`project_forecast`)
2. In Planning > Configuration > Roles, create two planning roles A and B
- Role A: Assign a resource R
- Role B: No resource
3. Open Planning (Schedule by Resource), and go back a few weeks (to prevent overlaps with potential demo data)
4. Create two new slots:
1. Set Role B and a random Project P, then click Auto Plan: there should be no available resource (because we didn't set any resource for Role B)
2. Set Role A and the same Project P, then click Auto Plan: it should assign the resource R assigned to Role A
5. After assigning a resource to the slot for Role A, edit the Open Shift for Role B again and click Auto Plan: **it assigns the same resource R, even though that resource is not assigned to Role B.**
## Cause
The `_get_open_shifts_resources` override in `project_forecast` looks for resources that were assigned to slots related to the same project. It does not filter resources based on the requested role.
https://github.com/odoo/enterprise/blob/885edbc270a86ab76e0a6eff4acb5767c0fe29d1/project_forecast/models/planning_slot.py#L104-L116
This means that resources that are not part of the requested role can be assigned to the slot, as long as the resource operated on another slot for the same project.
opw-6325744
Forward-Port-Of: odoo/enterprise#1220356 changes
Resolved issues and error corrections
This update prevents popup content from being inserted inside another popup, which could create confusing nested popups on the website. It also fixes the cookie bar layout so buttons keep the correct spacing when editors choose the discrete style, improving the page appearance for visitors.
Original PR description
Steps to reproduce: - Enable the cookies bar in the website settings. - Go to the website and enter edit mode. - Open the cookies bar from the invisible elements panel. - Open the snippet dialog. => Popup snippets are still visible even though they cannot be dropped inside another popup. Before this commit, popup snippets could still use dropzones located inside another popup in some cases, such as cookie bars or newsletter popups. After this commit, when the dragged snippet is a popup, dropzones inside an existing popup are filtered out, so nested popups cannot be inserted. task-6251151 Forward-Port-Of: odoo/odoo#267488
This update brings the spreadsheet component to a newer version with a few user experience and display fixes. It improves color selection behavior, adds better support for sheet tab colors, and makes fonts render more consistently on Linux, helping spreadsheets look and work more reliably across environments.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/c80dc2e26b [REL] 18.3.53 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/c80dc2e26b [REL] 18.3.53 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/a075f2eeae [FIX] sheet: close the color picker on external click [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/7fd938ed02 [FIX] sheet: add sheet tab color to custom colors [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/f706fda1b0 [FIX] Fonts: Add default font for Linux [Task: 6328646](https://www.odoo.com/odoo/2328/tasks/6328646) https://github.com/odoo/o-spreadsheet/commit/d8da52b51c [IMP] package: add runbot script [Task: 6316690](https://www.odoo.com/odoo/2328/tasks/6316690) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> 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: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@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> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
The website language selector now includes descriptive text for flag images when the flag is the only visible indicator. This makes the selector easier to understand for screen reader users and gives search engines clearer context.
Original PR description
Steps to reproduce: 1. Enable the language selector in the website header. 2. Enable the "Inline" and "Flag" options. 3. Inspect the flag images rendered in the inline variant. Issue: Flag images in the list items have an empty `alt=""` attribute in "Flag only" mode, where the flag is the sole visual indicator of the language, making the selector inaccessible to screen readers and providing no context for search crawlers. Expected behavior: Inline + Flag should have a descriptive ALT tag since there is no adjacent text or code to identify the language, the flag is not decorative. opw-6246464 Forward-Port-Of: odoo/odoo#271362
Creating payslips from a parent company now correctly includes employees who belong to its branch companies. This fixes a case where some employees were missing from the employee selection list, helping payroll teams process Belgian branch payslips consistently.
Original PR description
Bug: employees registered on branch companies don't appear in the
employee_id field when creating a payslip from the parent company.
Reason: the domain used ('company_id', '=', company_id) which only
matches the exact company, not its children.
Solution: replaced '=' with 'child_of' to include all descendant
companies in the hierarchy.
task - 6299634
Forward-Port-Of: odoo/enterprise#121193
Forward-Port-Of: odoo/enterprise#120974This fix ensures subscription rules are enforced whether a recurring product is added manually or through the product catalog. It prevents orders from being saved without a subscription plan when one is required, avoiding inconsistent behavior and unexpected errors later in the sales process.
Original PR description
Steps to reproduce: --------------------------------------- 1. Install Subscription Module 2. Create and Confirm SO with no recurring plan and a non-recurring product 3. Add a recurring product >…
Steps to reproduce: --------------------------------------- 1. Install Subscription Module 2. Create and Confirm SO with no recurring plan and a non-recurring product 3. Add a recurring product > Save SO > Observe the User Error 4. Now add the same recurring product through Catalog View Observation: --------------------------------------- No User Error raised stating 'You cannot save a sale order with recurring product and no subscription plan.' Issue: --------------------------------------- When you manually add a line and click 'Save', the constraint (`_constraint_subscription_plan`) is triggered and raised `UserError` https://github.com/odoo/enterprise/blob/434d88960abb5e424fdc1106fc93935d328bff78/sale_subscription/models/sale_order.py#L176-L177 When you add a product via the catalog view, it calls `_update_order_line_info` which directly creates/updates order lines, Which do not trigger the python constraint. https://github.com/odoo/odoo/blob/ef9772bba1515bdaf5410c3af5a3e395f562d513/addons/sale/models/sale_order.py#L1926-L1933 Solution: --------------------------------------- Two private helpers are introduced: * `_is_exempt_from_subscription_plan_check`: single source of truth for all exempt states (draft, cancelled, upsell, and legacy upgrade orders). * `_check_recurring_plan_mismatch`: raises a `UserError` when the order has or will have a recurring product but no subscription plan, reusing the exemption helper so both call sites stay in sync. `_constraint_subscription_plan` is refactored to delegate to these helpers, and `_update_order_line_info` is overridden to call `_check_recurring_plan_mismatch` before the catalog update is applied, ensuring consistent validation across both entry points. opw-6194865 Forward-Port-Of: odoo/enterprise#121886 Forward-Port-Of: odoo/enterprise#117879
Expense reports now enforce limits on attached files, helping keep submissions within expected size and number constraints. This reduces the risk of overly large expense claims and improves reliability when employees submit expenses.
Original PR description
--- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272732
3 changes
Resolved issues and error corrections
When Belgian CODA bank statements are imported, the full communication text is now used as the payment reference in cases where the reference was not structured. This makes imported transactions easier to identify and match with the right payments.
Original PR description
### Issue: When a CODA file was imported, the communication was fetched but it wasn't use as the payment ref Causing difficulty to match with the transactions ### Cause: For simplicity reason, the payment_ref and the communication where different The `payment_ref` was fetched once and replace The `communication` was always completed by new lines ### Steps to reproduce: - Install `l10n_be_coda` - Set the account on the Bank Journal to GR5605700000000928073840752 - Import the Simplied CODA (On the ticket) from the bank dashboard Before the fix, the ref was just `Liquidation des ventes par carte Mastercard` instead of the full communication that can be found in the chatter opw-6245848
The test for the Colombia POS flow was adjusted so it no longer expects one exact document number. This prevents occasional failures when the document number increases during repeated test runs, making the test more stable without changing business behavior.
Original PR description
**Why the fix:** This step failed from time to time as we did some batch testing on the runbot with the same database, and because of this, the Número de Documento increased, making it SETF990000002 or more. This error existed before 68da209 but by fixing the refund flow in said commit, this error has been appearing way more frequently. As this has already happened a few times in 18.2, it is still the targeted version for this fix. We now use a regex to make sure that we have **Número de Documento: SETF** followed by some numbers, but we do not specify that it should be SETF990000001 anymore. runbot-241997
This change fixes an issue that prevented PDF downloads for a specific type of Guatemalan vendor bill. Users can now generate and download the document successfully after sending it to SAT, without running into error messages.
Original PR description
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding…
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding 12%` and `ISR Withholding 5%` in Invoice lines. - `Confirm` the bill and `Send to SAT`. - From the gear icon, click `Download` > `PDF`. **Error1:** `KeyError: 'gran_total'` **Error2:** `KeyError: 'retencion_grand_total'` **Root Cause:** In commit [1], the code at [2] missed calling `_l10n_gt_edi_add_base_values()` before `_l10n_gt_edi_add_withholding_values()`. However, `_l10n_gt_edi_add_withholding_values()` uses the `gran_total` value, which is initialized by `_l10n_gt_edi_add_base_values()`, resulting in a `KeyError`. Additionally, the report template at [3] references `retencion_grand_total` instead of the correct key `retencion_gran_total`, causing another `KeyError`. **Fix:** This commit prevents errors and ensures users can successfully download the PDF by applying a fix similar to [4], [1]: https://github.com/odoo/enterprise/commit/44afd19e4ed0827e343af0e584c81e579935c9e8 [2]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L305-L328 [3]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/views/report_invoice.xml#L72 [4]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L790-L800 opw-6323049 Forward-Port-Of: odoo/enterprise#122030
8 changes
Resolved issues and error corrections
This change corrects how the Intrastat report builds its database query when a company has no country set. It prevents the report from failing with an error, so users can generate Intrastat data reliably in those cases.
Original PR description
When there is no `country_id` on the company we get `False`. The generated query then fail at: ``` ... CASE WHEN (code.country_id IS NULL OR code.country_id = false) THEN code.code ELSE NULL END AS commodity_code, ... ``` with: ``` ERROR: operator does not exist: integer = boolean LINE 12: ... WHEN (code.country_id IS NULL OR code.country_id = false) T... ``` Forward-Port-Of: odoo/enterprise#121798 Forward-Port-Of: odoo/enterprise#121608
This update fixes the deadline rules used for Austrian VAT returns and EC sales lists. It now follows the real filing schedule instead of using the same fixed 15-day offset for both, helping users prepare and submit reports on time.
Original PR description
**[FIX] l10n_at_reports: correct Austrian return deadlines** The Austrian localization used a fixed `15 days` rule for both VAT returns and EC sales lists. This does not match the filing deadlines: the VAT return is due on the 15th day of the second following month while the EC sales list is due by the end of the following month (sources below). This fix replaces the hardcoded day offset with month-based deadline computation sources: https://www.usp.gv.at/themen/steuern-finanzen/umsatzsteuer-ueberblick/weitere-informationen-zur-umsatzsteuer/umsaetze-mit-auslandsbezug/zusammenfassende-meldung-zm.html https://www.usp.gv.at/en/themen/steuern-finanzen/umsatzsteuer-ueberblick/weitere-informationen-zur-umsatzsteuer/entstehen-der-steuerschuld-und-pflichten/umsatzsteuervoranmeldung.html opw-6147343 Forward-Port-Of: odoo/enterprise#117212 Forward-Port-Of: odoo/enterprise#116212
A test for WhatsApp channel “seen” updates was adjusted so the message notification is sent only after the browser connection is subscribed. This prevents the update from being missed, ensuring seen indicators appear correctly and the test no longer times out.
Original PR description
The "Allow SeenIndicators in WhatsApp Channels" test delivers the seen update over the bus with `_sendone`, but nothing waited for the websocket to subscribe to the channel first. When the notification was sent before the subscription landed it was dropped, the member's seen_message_id was never updated client-side and the seen indicators never rendered, so the assertion timed out. The current user is a member of the channel, so it is subscribed at connection time: wait for the subscription together with `start()` (listener registered first) before opening the channel and sending the notification. https://runbot.odoo.com/odoo/error/242021 Forward-Port-Of: odoo/enterprise#121857
Fixed an issue where the Time Spent cell in Timesheets could show the wrong status color when work schedules included fractional hours. This ensures the displayed color now matches the actual timesheet totals, avoiding misleading orange or red warnings for employees who have no overtime.
Original PR description
## Issue In the Timesheets app, the color of the *Time Spent* cell at the end of a row indicates the current status of the timesheets based on the expected number of working hours. The selected color…
## Issue
In the Timesheets app, the color of the *Time Spent* cell at the end of a row indicates the current status of the timesheets based on the expected number of working hours. The selected color (green/orange/red) is sometimes wrong when an employee has a work schedule with fractional hours.
## Steps to reproduce
1. Install *Timesheets* (`timesheet_grid`)
2. For an employee E, edit the *Standard 40 hours/week* schedule:
- Change *Monday Afternoon* "Work to" column from 17:00 to 17:20.
3. In Timesheets > All Timesheets, go back one week and fill the timesheet for the employee E. We need 8 hours everyday but on Monday, where we need 8 hours and 20 minutes.
4. __The background of the *Time Spent* cell is orange, even though there's no overtime anywhere, and the value in the cell is precisely 40:20, which is the expected amount of hours worked.__
## Cause
When comparing the amount of hours worked and the expected amount of hours, small rounding errors occur. At this point of the execution:
https://github.com/odoo/enterprise/blob/19b7f5a6961dbce7367c07fcc55eea1925832634/timesheet_grid/static/src/views/timesheet_grid/timesheet_grid_renderer.js#L157
We obtain the following values:
```js
> monday = section.cells[1]
> monday.value
8.333333333333336
> workingHours[monday.column.value]
8.333333333333332
> monday.value - workingHours[monday.column.value]
3.552713678800501e-15
```
This small difference differing from 0, the wrong color is selected by `_getSectionTotalCellBgColor`:
https://github.com/odoo/enterprise/blob/19b7f5a6961dbce7367c07fcc55eea1925832634/timesheet_grid/static/src/views/timesheet_grid/timesheet_grid_renderer.js#L160-L172
## Fix
The same issue was fixed elsewhere by https://github.com/odoo/enterprise/commit/3340c0610ae6d7d3087f20da04309512771cc4b7. The same fix is applied here for consistency.
opw-6193181
Forward-Port-Of: odoo/enterprise#121463This change separates the calculation of the worker-specific social contribution base into its own rule. It makes the payroll logic clearer and helps ensure the correct contribution amount is applied for worker employees in Belgium.
Original PR description
Add a new intermediary salary rule `ONSS_BASE_WORKER` that computes the ONSS base at 108% exclusively for worker employees. This rule is conditioned on `version.is_worker()` and replaces the inline `if` branch that was previously embedded in the main `ONSS` rule. A new salary rule category `ONSS_BASE_WORKER` is introduced to accumulate the worker-specific base, allowing the main `ONSS` rule to reference it via `categories['ONSS_BASE_WORKER']`. Task: 6253670
This change fixes an issue that could prevent appraisal email templates from being read correctly. As a result, automated appraisal messages should now send without errors, reducing disruptions for HR teams.
Original PR description
Task#6309699 Forward-Port-Of: odoo/enterprise#121115
This change stops an automated accounting test from failing when the ISO 20022 module is not installed. It keeps the test suite stable in environments where that optional payment setup is unavailable.
Original PR description
The test_batch_payment_deletion test is currently failing when `account_iso20022` is not installed because the sepa_ct payment method doesn't exists. Add a skipTest in case the module is not installed. runbot-940257 Forward-Port-Of: odoo/enterprise#121511
This fix lets the Barcode app correctly register several serial numbers or lots during one manufacturing session instead of keeping only the last one. It prevents validation errors and ensures the finished product is saved with the right production details, which makes manufacturing workflows more reliable.
Original PR description
Steps to reproduce ------------------ Serial-tracked finished product: 1. Create a serial-tracked finished product and an un-tracked component. 2. Create a Manufacturing Order with quantity 2 and…
Steps to reproduce ------------------ Serial-tracked finished product: 1. Create a serial-tracked finished product and an un-tracked component. 2. Create a Manufacturing Order with quantity 2 and confirm it. 3. Open the Barcode app, scan the MO, then scan a first serial number SN_X1. 4. Scan a second serial number SN_X2. 5. Validate. Lot-tracked finished product: 1. Create a lot-tracked finished product with a one-component BoM and an existing lot LOT_A. 2. Create a Manufacturing Order and confirm it. 3. Open the Barcode app, scan the MO, then scan the existing lot LOT_A. 4. Scan a different, not-yet-existing lot LOT_B. 5. Validate. Issue ----- Only the last scanned serial is registered on the MO, and validation then fails because the count of producing serials does not match qty_producing for a serial-tracked finished product. updateLine overwrote lot_producing_ids with [args.lot_id] on every scan, so the first serial was dropped when the second one was scanned, and the same branch never staged a freshly typed lot_name, so a brand-new serial typed on a serial-tracked MO was lost before reaching the backend. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/models/barcode_mrp_model.js#L407 Two behaviours of the shared barcode dispatcher make a single accumulating branch insufficient. The final-product line must keep exposing a producing lot, otherwise the base hasUnassignedQty check counts a scanned serial as zero once a quantity is already set, leaving qty_producing stuck below the demand. https://github.com/odoo/enterprise/blob/f622064871bf55b93890606d16407c50cf4419a6/stock_barcode/static/src/models/barcode_model.js#L1446 But exposing a producing lot makes the dispatcher treat the next serial as a conflicting tracking number, since the base _canOverrideTrackingNumber considers a different lot name non-overridable. https://github.com/odoo/enterprise/blob/f622064871bf55b93890606d16407c50cf4419a6/stock_barcode/static/src/models/barcode_model.js#L796-L798 So the scan is diverted to a new line through the override gate instead of updating the header line. https://github.com/odoo/enterprise/blob/f622064871bf55b93890606d16407c50cf4419a6/stock_barcode/static/src/models/barcode_model.js#L1585 For a lot-tracked finished product the producing lot can be corrected by scanning a different value, but the lot branch only stored a freshly typed value in lot_name and overwrote lot_producing_ids with the single existing lot. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/models/barcode_mrp_model.js#L404-L407 The header reads its lot from lot_producing_ids whenever that relation is set and only falls back to lot_name when it is empty. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/components/header.js#L45-L58 The save path only promotes lot_name to a producing lot when lot_producing_ids is empty, so scanning an existing lot then a new one neither displayed nor recorded the new lot and the finished product was produced under the old lot. https://github.com/odoo/enterprise/blob/4a2f1da5466740b7758d1962e5241620845d616b/stock_barcode_mrp/static/src/models/barcode_mrp_model.js#L628 Solution -------- Accumulate scanned serials by appending to lot_producing_ids instead of replacing it, and stage a freshly typed lot_name as a new producing lot when the finished product is tracked by serial, so every serial reaches the backend. Keep the final-product line exposing the last producing lot so each scanned serial is still counted as one unit instead of resetting the quantity to zero once several serials are registered. Override _canOverrideTrackingNumber for the final-product line so a serial scan updates the header line rather than being diverted to a new line, which is the only valid path for the finished product since it is a single header line backed by the lot_producing_ids relation. Persist the producing serials with explicit x2many commands, separating already-existing lots from freshly typed ones, so both are written on the MO. Reject a serial that is already registered on the MO so the same number cannot be produced twice in one session. For a lot-tracked finished product, build a producing lot from the scanned value, using the existing lot or a freshly typed lot name, and store it in lot_producing_ids so the new lot is both displayed and persisted through the same x2many commands as the serial case. Leave the produced quantity unchanged when the scanned lot differs from the one already registered, since replacing the lot is a correction and not an extra unit, and keep incrementing it when the same lot is scanned again. opw-6189620 Forward-Port-Of: odoo/enterprise#121849 Forward-Port-Of: odoo/enterprise#116890
4 changes
Resolved issues and error corrections
Folders connected to a project will no longer be removed by the automatic trash cleanup, preventing errors during cleanup jobs. This keeps project documents safe and ensures the trash can be emptied normally without breaking linked records.
Original PR description
## Problem
When a folder linked to a project gets archived, the documents trash autovacuum unlinks it along with regular trash. That triggers the constrains . This happens whether the project is still active or also archived.
## Fix
Add one leaf on the GC domain: `('project_ids', '=', False)`. so the document is not deleted if linked to a projectThis fix prevents Auto Plan from assigning a worker just because they previously worked on the same project. The system now checks the role on the slot first, so only resources assigned to that role can be selected. This avoids incorrect scheduling and makes planning results more reliable.
Original PR description
## Issue When using the *Auto Plan* feature on a planning slot with a Role and a Project set, a resource which operated on the same project will be chosen if available, without taking into account…
## Issue
When using the *Auto Plan* feature on a planning slot with a Role and a Project set, a resource which operated on the same project will be chosen if available, without taking into account the Role set on the slot.
## Steps to reproduce
1. Install Project Planning (`project_forecast`)
2. In Planning > Configuration > Roles, create two planning roles A and B
- Role A: Assign a resource R
- Role B: No resource
3. Open Planning (Schedule by Resource), and go back a few weeks (to prevent overlaps with potential demo data)
4. Create two new slots:
1. Set Role B and a random Project P, then click Auto Plan: there should be no available resource (because we didn't set any resource for Role B)
2. Set Role A and the same Project P, then click Auto Plan: it should assign the resource R assigned to Role A
5. After assigning a resource to the slot for Role A, edit the Open Shift for Role B again and click Auto Plan: **it assigns the same resource R, even though that resource is not assigned to Role B.**
## Cause
The `_get_open_shifts_resources` override in `project_forecast` looks for resources that were assigned to slots related to the same project. It does not filter resources based on the requested role.
https://github.com/odoo/enterprise/blob/885edbc270a86ab76e0a6eff4acb5767c0fe29d1/project_forecast/models/planning_slot.py#L104-L116
This means that resources that are not part of the requested role can be assigned to the slot, as long as the resource operated on another slot for the same project.
opw-6325744The GSTR-1 spreadsheet now shows the Invoice Value for SEZ invoices in company currency (INR) instead of the foreign invoice currency. This ensures the export matches the expected tax return format and avoids incorrect values in the report.
Original PR description
Currently, when generatign GSTR-1 return spreadshee, SEZ invoices issued in a foreign currency are exported with their totals in the foreign currency rather than the company currency (INR) Steps to reproduce: - Create a B2B SEZ invoice in foreign currency - Go to Accounting > Reporting > [India] GST Return periods - Generate the GSTR-1 report for the period Issue: In the resulting spreadsheet, the "Invoice Value" column takes the invoice total in USD rather then INR opw-6292913 Forward-Port-Of: odoo/enterprise#121864 Forward-Port-Of: odoo/enterprise#121157
We fixed an issue in Kenyan PoS orders where selling a combo could wrongly trigger an eTIMS registration warning and block payment. The combo itself is now ignored for eTIMS checks, so only the actual products inside the combo need to be registered, allowing the order to be completed normally.
Original PR description
Steps to reproduce ------------------ 1. Install l10n_ke_edi_oscu_pos. 2. Select the Kenyan company. 3. Enable eTIMS on the PoS. 4. Register the products inside a combo, but not the combo itself. 5.…
Steps to reproduce ------------------ 1. Install l10n_ke_edi_oscu_pos. 2. Select the Kenyan company. 3. Enable eTIMS on the PoS. 4. Register the products inside a combo, but not the combo itself. 5. Sell the combo in the PoS. Observation ----------- We see a warning that the combo must be registered to eTIMS, and the order can't be validated. What's happening ---------------- In the PoS a combo adds a 0 price parent line for the combo product, but the combo is not a real item to send to eTIMS, only the products inside it are, and (as per step 4) the combo is not registered. `checkEtimsFields` sees the combo as not registered, so it raises the warning in `showUnregisteredProductsWarning` and blocks the payment in `validateOrder`. Fix --- In the backend, we skip sending the parent combo line to eTIMS, and on the frontend, we make the combo parent line not need eTIMS registration, so the warning and the block don't apply to it. opw-6253306 Forward-Port-Of: odoo/enterprise#121991 Forward-Port-Of: odoo/enterprise#119362
11 changes
Resolved issues and error corrections
This update refreshes the spreadsheet component to its latest version and brings in several small fixes behind the scenes. It improves everyday usability, such as better color picker behavior and more reliable font display on Linux, while also updating package settings to stay compatible with the current development environment.
Original PR description
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/ad313f6500 [REL] 18.0.72 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0)…
### Contains the following commits: https://github.com/odoo/o-spreadsheet/commit/ad313f6500 [REL] 18.0.72 [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/d1524238a3 [FIX] sheet: close the color picker on external click [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/f164e6b3a0 [FIX] sheet: add sheet tab color to custom colors [Task: 6322171](https://www.odoo.com/odoo/2328/tasks/6322171) https://github.com/odoo/o-spreadsheet/commit/dc7a2b1c99 [FIX] Fonts: Add default font for Linux [Task: 6328646](https://www.odoo.com/odoo/2328/tasks/6328646) https://github.com/odoo/o-spreadsheet/commit/9027b97d4a [IMP] package: add runbot script [Task: 6316690](https://www.odoo.com/odoo/2328/tasks/6316690) https://github.com/odoo/o-spreadsheet/commit/855ec0dadf [FIX] package-lock: re-run npm install [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/4af8d893d8 [FIX] rolldown: Fix cjs file extension [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/48f0cd7b8a [FIX] package-lock: update with removing node_modules [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) https://github.com/odoo/o-spreadsheet/commit/08175c6cb8 [FIX] package.json: Update Node.js and npm engine requirements [Task: 0](https://www.odoo.com/odoo/2328/tasks/0) Co-authored-by: Florian Damhaut (flda) <flda@odoo.com> 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: Adrien Minne (adrm) <adrm@odoo.com> Co-authored-by: Ronak Mukeshbhai Bharadiya (rmbh) <rmbh@odoo.com> Co-authored-by: Dhrutik Patel (dhrp) <dhrp@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> Co-authored-by: Marceline Thomas (matho) <matho@odoo.com>
This update fixes an error that could prevent PDF downloads for Guatemalan vendor bills of type FESP. It ensures the required totals are calculated and displayed correctly, so users can generate the document without interruptions.
Original PR description
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding…
**Steps to reproduce:** - Install the `l10n_gt_edi` module and switch to a `GT Company`. - Create a new vendor bill with: - Vendor: GT Company - GT Document Type: `FESP` - Add taxes `VAT Withholding 12%` and `ISR Withholding 5%` in Invoice lines. - `Confirm` the bill and `Send to SAT`. - From the gear icon, click `Download` > `PDF`. **Error1:** `KeyError: 'gran_total'` **Error2:** `KeyError: 'retencion_grand_total'` **Root Cause:** In commit [1], the code at [2] missed calling `_l10n_gt_edi_add_base_values()` before `_l10n_gt_edi_add_withholding_values()`. However, `_l10n_gt_edi_add_withholding_values()` uses the `gran_total` value, which is initialized by `_l10n_gt_edi_add_base_values()`, resulting in a `KeyError`. Additionally, the report template at [3] references `retencion_grand_total` instead of the correct key `retencion_gran_total`, causing another `KeyError`. **Fix:** This commit prevents errors and ensures users can successfully download the PDF by applying a fix similar to [4], [1]: https://github.com/odoo/enterprise/commit/44afd19e4ed0827e343af0e584c81e579935c9e8 [2]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L305-L328 [3]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/views/report_invoice.xml#L72 [4]: https://github.com/odoo/enterprise/blob/9846b337cfe1876017c7c2ce3041569d7a2ac03f/l10n_gt_edi/models/account_move.py#L790-L800 opw-6323049
This change prevents folders tied to projects from being automatically deleted by the trash cleanup process. It avoids cleanup errors and ensures archived project folders are handled correctly when users open them from the project screen.
Original PR description
## Problem When a folder linked to a project gets archived, the documents trash autovacuum unlinks it along with regular trash. That triggers the constrains . This happens whether the project is still active or also archived. ## Fix Exclude in the domain the documents attached to projects so the document is not deleted if linked to a project
This update fixes several issues with badge-based login in Point of Sale. Employees can now scan their badge even when the PIN field is active, the PIN prompt no longer closes incorrectly after a badge scan, and scanning another cashier’s badge now correctly switches to that cashier.
Original PR description
See commit messages. [[FIX] pos_hr: scanning badge should work with PIN input focused](https://github.com/odoo/odoo/commit/95d9329674e81b2659445e2021a35b21bbbc81a3) [[FIX] point_of_sale: scanning a badge should not auto confirm the PIN](https://github.com/odoo/odoo/commit/d59fb1f6fe27d117579b3945c5bba400d17d0014) (Note: this is only needed up to saas-18.4 included -- 19.0 already has this diff) [[FIX] pos_hr: scanning another cashier's badge switches to that cashier](https://github.com/odoo/odoo/commit/c812fe596694b16a494e3dcf908d17f621f7ce92) opw-6125029
This change prevents invoice email notifications from crashing when they are generated in a different language than the one used during invoice entry. It ensures notifications can be sent normally after Quick Edit, avoiding interruptions for users and customers.
Original PR description
**Steps to Reproduce:** - Install the Accounting and Contacts modules. - Enable Quick Encoding for Customer Invoices and Vendor Bills in the company settings. - Create a new customer: Assign a…
**Steps to Reproduce:**
- Install the Accounting and Contacts modules.
- Enable Quick Encoding for Customer Invoices and Vendor Bills in the company
settings.
- Create a new customer: Assign a salesperson.
- Ensure:
- The salesperson is not a login user.
- The customer language, salesperson's language, and Login user's language
are different. Example:
- Customer language: English
- Salesperson language: French
- Login user language: French
- Create a customer invoice using the Upload Document functionality.
- Select the customer created above.
- Use Quick Edit mode and enter an amount and Click Confirm.
**Issue:**
- When the invoice notification is rendered in a language different from the one
used during the write operation, the notification rendering flow calls
_notify_by_email_prepare_rendering_context().
- During rendering, the code executes:
```
self.tax_totals.get('total_amount_currency', 0)
```
- Since tax_totals is protected, the ORM returns False instead of the expected
dictionary, leading to:
```
AttributeError: 'bool' object has no attribute 'get'
```
**Root Cause:**
- This issue occurs in Quick Edit mode because tax_totals is [not read-only](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/views/account_move_views.xml#L1359)
in Quick Edit mode and is included in [the values](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/web/static/src/model/relational_model/record.js#L708) sent by the web client during write().
- During create()/write(), _get_protected_vals() marks tax_totals as protected.
- Since tax_totals is a [@api.depends_context('lang')](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/models/account_move.py#L975) computed field, it
maintains a separate cache per language. [During write()](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/models/account_move.py#L3955), the [field becomes
protected](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/addons/account/models/account_move.py#L3863) by [env.protecting()](https://github.com/odoo/odoo/blob/1f7a62d38303a992f501b4ecdb1bee437f7279b8/odoo/orm/fields.py#L1738). While the protection is still active, the mail
notification flow renders the email using the recipient's language. If the
corresponding language-specific cache entry for tax_totals is not available,
the ORM cannot recompute the protected field and returns False instead
of the expected dictionary.
- The rendering code assumes tax_totals is always a dictionary and directly
calls .get(), leading to the crash.
**Solution:**
- Exclude tax_totals from _get_protected_vals().
- tax_totals is already handled explicitly after create()/write(), so protecting
it is unnecessary. This allows the field to be recomputed during notification
rendering when required.
**Result:**
- Invoice notifications render correctly in all languages.
- No RPC crash occurs when rendering notifications after Quick Edit.
**Runbot reproduction: [video](https://github.com/user-attachments/assets/5f045efb-37de-40aa-b135-1368b1601d61)**
**opw-6209647**This change prevents previously invoiced service hours from being billed again after a partial refund. It ensures the next invoice only includes the remaining unpaid hours, avoiding overbilling and invoice corrections.
Original PR description
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h…
### Steps to reproduce: - Download 'Sales' and 'Timesheets' apps - Create a service product invoiced on delivered quantities with timesheet tracking - Create and confirm a SO for quantity 1 - Log 20h on timesheets - Invoice the SO - Create a credit note for 11 hours => only 9 hours are invoiced - Log 5h more on timesheets - Back to the SO > create invoice again > All the 25hrs are to invoiced, although 9 of them were invoiced before ### Cause of Issue: When generating the new invoice, `_recompute_qty_to_invoice` calls `_get_delivered_quantity_by_analytic` which retrieves the analytic values for the SO line. The values retrieved are later used to determine the delivered quantity, which is later assigned to be `line.qty_to_invoice` without taking into account the already invoiced hours. https://github.com/odoo/odoo/blob/7a6518e39d34575a3977e7c4a0053a45223e203c/addons/sale_timesheet/models/sale_order_line.py#L176-L186 ### Fix: Ensures that hours that have already been completely invoiced are deducted from the quantity to invoice. opw-6253650
The signature certificate now shows the applicant’s actual email address instead of a generic placeholder. This ensures recruitment documents remain accurate and easier to verify for HR and candidates.
Original PR description
When generating an offer from the recruitment application and signing it, the applicant's email address is incorrectly displayed. ### **Steps to Reproduce:** 1) Install sign, recruitment,…
When generating an offer from the recruitment application and signing it, the applicant's email address is incorrectly displayed. ### **Steps to Reproduce:** 1) Install sign, recruitment, hr_contract_salary 2) Create an new application and add basic detail like name and email as (path and `path@test.com`) 3) Generate offer and sign with all the required signer(applicant and Marc Demo). 4) Open the application form view and open the certificate. ### **Observed Behavior:** Email is not set correctly in the generated certificate (appearing as `john@example.com`). ### **Expected Behavior:** The email of the applicant should be correctly set(e.g as `path@test.com`) ### **Root Cause:** When the applicant signs the document, their email is explicitly set to `False` at [1]. This is done because the applicant is not linked to any user yet. Later, when generating the certificate, the system attempts to display the user's partner email at [2], which is `False`, causing the default fallback value (`john@example.com`) to be printed. [1]- https://github.com/odoo/enterprise/blob/49226f4109c7d7bb48340949951e70f4245d0e5b/hr_contract_salary/controllers/main.py#L53-L54 [2]- https://github.com/odoo/enterprise/blob/49226f4109c7d7bb48340949951e70f4245d0e5b/sign/report/sign_log_reports.xml#L59 ### **Fix:** Use `signer_email` instead of the partner's email to ensure the correct email is displayed on the certificate every time. opw-6280170
This change resolves a test failure affecting Swedish SEPA payments when two related modules are installed together. It updates the test setup so the payment format works consistently and avoids false failures in automated checks.
Original PR description
Here https://github.com/odoo/enterprise/pull/114662 we changed the way the CdtrAgt node is used in the SEPA XML file for Sweden. But this change broke a test when both account_iso20022 & l10n_se_bban are installed, leading to a Non-expected child error. This commit skip the failling test if l10n_se_bban is installed, and add a new one to replace it. runbot-938366 runbot-938367
This change updates an accounting import test to use a smaller, prebuilt XML example instead of a generated one. It makes the test easier to maintain and more reliable, helping ensure partner bank details are retrieved correctly during invoice imports.
Original PR description
Move the partner retrieval bank account number test to the `test_ubl_import_bis3_invoice_be_retrieve_partner.py` file and use a partial XML instead of a generated XML.
Mass mailing emails now build unsubscribe and related links from the recipient’s own website instead of a global default. This prevents users in multi-company setups from being sent to a login page when they try to opt out, making the unsubscribe flow reliable and consistent.
Original PR description
In a multi-company setup with a website per company, the unsubscribe link in mass mailing emails could send recipients to the login page instead of the unsubscribe confirmation page. ### Steps to…
In a multi-company setup with a website per company, the unsubscribe link in mass mailing emails could send recipients to the login page instead of the unsubscribe confirmation page.
### Steps to reproduce
1. Enable multi-company and create a second company `Company B`.
2. Create two websites with different domains, one per company:
- `Website A` on the main company, domain `http://website-a.test`
- `Website B` on `Company B`, domain `http://website-b.test`
3. Set the system parameter `web.base.url` to `http://website-a.test`. System parameters are global, so this value applies to the whole database regardless of the company you switch to.
4. Create a contact and set its `Company` field to `Company B`.
5. In Email Marketing, create a mailing with recipient model `Contact`, target the contact above, pick any template with an unsubscribe link, and send it.
6. Open the email in an incognito window and click the unsubscribe link: you land on the login page instead of the unsubscribe page.
### Cause
Mass mailing builds the unsubscribe link in two steps.
First, each email body is rendered for its recipient. While rendering, relative URLs like `/unsubscribe_from_list` are turned into absolute URLs by prepending a base URL. That base URL comes from the recipient record itself: `recipient.get_base_url()`. The `website` module overrides this so that, when the record has a company, it returns that company's website domain. For a contact in `Company B`, the body ends up with `http://website-b.test/unsubscribe_from_list`.
Second, right before sending, `mail_mail._prepare_outgoing_list` replaces that placeholder URL with a per-recipient signed URL pointing to `/confirm_unsubscribe`. It does this by plain string replacement: it looks for `{base_url}/unsubscribe_from_list` in the body and swaps it. The `base_url` used here came from `self.mailing_id.get_base_url()`. A mailing has no company, so its base URL falls back to the global `web.base.url`, which in our setup is `http://website-a.test`.
The two base URLs no longer match. The body contains the website B URL, but the replacement code searches for the website A URL. The search fails, the placeholder stays in the email, and the recipient clicks a link to `/unsubscribe_from_list`. That route only redirects to `/mailing/my`, which requires being logged in, so the user lands on the login page.
### Fix
Compute the base URL from the recipient record (the same record used when rendering the body) instead of the mailing. The two URLs then agree and the replacement works. Fall back to the mailing's base URL if there is no recipient model on the mail.
opw-4914203This update fixes a crash that could happen when a negative forecast demand was entered in the last planning period. It also ensures any leftover negative quantity is applied to the first forecast, matching the intended planning behavior.
Original PR description
Steps to reproduce: - Fresh DB - Add a negative number to the forecast demand in the last period Cause: A variable was used without declaration Fix: According to odoo/enterprise#56128, it was intended that any remaining negative quantity to add should be added to the first forecast.
4 changes
Resolved issues and error corrections
When users open the detailed list from a grid cell grouped by a selection field, the list title now shows the human-friendly label instead of the internal technical value. This makes the interface easier to understand and avoids confusing names like "non_billable" appearing to end users.
Original PR description
When grouping a grid view by a selection field and clicking on the cell magnifier, the list title showed the technical name (e.g. non_billable) instead of the display name (e.g. "Non Billable"). This commit adds a condition specifically for selection fields, ensuring that their display names are used. task-5980035
Uploaded WebP images are now checked against the same maximum resolution limit as other image formats. This prevents very large images from being accepted on the website or in attachments, helping keep uploads consistent and avoiding oversized files.
Original PR description
Since 17.0, `webp` images can be uploaded at any resolution, whereas every other format is refused above IMAGE_MAX_RESOLUTION (50 Mpx) when the attachment is created on the server. Root cause…
Since 17.0, `webp` images can be uploaded at any resolution, whereas every other format is refused above IMAGE_MAX_RESOLUTION (50 Mpx) when the attachment is created on the server. Root cause =========== `ImageProcess` grouped webp together with empty sources and SVG and set `self.image = False`, returning before the `verify_resolution` check. As a result the resolution limit enforced for `png/jpeg/...` was never applied to `webp`. Fix === Split `webp` out of the skip branch: it is still not processed as before, but its resolution is now read from the RIFF header with `get_webp_size()` and checked against `IMAGE_MAX_RESOLUTION`, so oversized webp images are refused on upload like any other format. Steps to reproduce =================== 1. Edit any page with the website editor 2. Upload a `webp` image larger than 50 Mpx (e.g. 8000x8000) => The image is accepted, while a `png/jpeg` of the same size is refused task-4134430 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
This fix ensures users can only set default values for fields they are allowed to edit. It prevents people from creating defaults on restricted fields, which helps keep data entry behavior consistent with their permissions.
Original PR description
Users should be able to set default values only for fields they have access to. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
The Mexican trial balance XML report now follows the SAT-recommended order for account nodes. This brings the generated file in line with the official structure, helping avoid validation or review issues when submitting reports.
Original PR description
**Steps to reproduce:** - Install the `l10n_mx_reports` module and switch to a Mexican company. - Navigate to Accounting > Reporting > Trial Balance. - From the dropdown menu, click `SAT (XML)`. -…
**Steps to reproduce:** - Install the `l10n_mx_reports` module and switch to a Mexican company. - Navigate to Accounting > Reporting > Trial Balance. - From the dropdown menu, click `SAT (XML)`. - Open the generated XML file and inspect the `<BCE:Ctas>` nodes. **Observation:** - The generated XML uses the following attribute order: `Debe > NumCta > Haber > SaldoFin > SaldoIni` - However, the SAT-recommended structure is: `NumCta > SaldoIni > Debe > Haber > SaldoFin` **Root Cause:** At [1], the attributes of the `<BCE:Ctas>` node are defined in an order that differs from the SAT-recommended structure. While the XML remains valid, the generated report does not match the layout recommended by the Mexican government specification. **Fix:** This commit reorders the `<BCE:Ctas>` attributes to follow the SAT-recommended structure, aligning the generated XML with the behavior introduced at [2] for `saas-19.3`. backport-of: https://github.com/odoo/enterprise/pull/115374 [1]: https://github.com/odoo/enterprise/blob/cb9c19272309d793379fa4d23145162f72fa5552/l10n_mx_reports/data/templates/cfdibalance.xml#L15-L20 [2]: https://github.com/odoo/enterprise/blob/acf0929a88ec788aecd44f6b4c647e468dc0a319/l10n_mx_reports/data/templates/cfdibalance.xml#L17-L22 opw-6297711