Friday, July 17, 2026
268 changes
3 changes
Resolved issues and error corrections
The more() action helper caches the More Actions object and only refreshes its inner actions list, leaving disabledCondition unchanged. As a result, if the dropdown is created while disabled, it remains disabled even after the composer is re-enabled. Individual actions (e.g., Attach files) don't exhibit this issue because they use a dynamic callback `(({ owner }) => owner.areAllActionsDisabled)` that is evaluated when needed. task-6393956 --- I confirm I have signed the CLA and read th
Original PR description
The more() action helper caches the More Actions object and only refreshes its inner actions list, leaving disabledCondition unchanged. As a result, if the dropdown is created while disabled, it remains disabled even after the composer is re-enabled.
Individual actions (e.g., Attach files) don't exhibit this issue because they use a dynamic callback `(({ owner }) => owner.areAllActionsDisabled)` that is evaluated when needed.
task-6393956
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#276870Steps to produce: --- - Install the `sales` module. - Create a product and `enable track inventory.` - Log in as user with only view access rights in products and also have the sales access rights. - Create a sale order containing product and confirm it. Issue: --- - An access error is raised during order confirmation. Root cause: --- - In [commit], to handle inventory tracking, the `qty_available` field was moved to `product.product`. Unlike before, this value is increased or
Original PR description
Steps to produce: --- - Install the `sales` module. - Create a product and `enable track inventory.` - Log in as user with only view access rights in products and also have the sales access rights. -…
Steps to produce: --- - Install the `sales` module. - Create a product and `enable track inventory.` - Log in as user with only view access rights in products and also have the sales access rights. - Create a sale order containing product and confirm it. Issue: --- - An access error is raised during order confirmation. Root cause: --- - In [commit], to handle inventory tracking, the `qty_available` field was moved to `product.product`. Unlike before, this value is increased or decreased depending on the operation performed. - As a consequence, creating or updating a sale order triggers a write to this `qty_available` field on the related product. This write happens under the current user's permissions, so users who only have read access to products (but can create/edit sale orders) hit an `AccessError`, since they lack write access on `product.product`. Solution: --- - Use `sudo()` when accessing the required product quantity information to ensure the operation can be completed without requiring additional product access rights. The same issue also occurs when confirming a purchase order. [commit]: https://github.com/odoo/odoo/commit/ca96992919b11105da44238c3e522f8eec4a740b opw-6290608 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276563 Forward-Port-Of: odoo/odoo#270067
Version: --------- - 19.0+ Steps to Reproduce: ----------------------- 1. Install sale_management, purchase, stock modules. 2. Create a storable product with Tracking: By Lot, 3. Create two Purchase Orders, each for 10 units. Receive PO-1 → 10 units with tagged as lot-1 Receive PO-2 → 10 units with tagged as lot-2 4. Create two Sale Orders: SO-1 → deliver 2 units from lot-1 (validate) SO-2 → deliver 4 units from lot-2 (validate) 5. Open Inventory > Reporting > Stock,
Original PR description
Version: --------- - 19.0+ Steps to Reproduce: ----------------------- 1. Install sale_management, purchase, stock modules. 2. Create a storable product with Tracking: By Lot, 3. Create two Purchase…
Version:
---------
- 19.0+
Steps to Reproduce:
-----------------------
1. Install sale_management, purchase, stock modules.
2. Create a storable product with Tracking: By Lot,
3. Create two Purchase Orders, each for 10 units.
Receive PO-1 → 10 units with tagged as lot-1
Receive PO-2 → 10 units with tagged as lot-2
4. Create two Sale Orders:
SO-1 → deliver 2 units from lot-1 (validate)
SO-2 → deliver 4 units from lot-2 (validate)
5. Open Inventory > Reporting > Stock,
click "Total Value", then check the "Remaining Quantity" column
Issue:
-------
Observed : remaining_qty = 10 for lot-2 receipt, 4 for lot-1 receipt
Expected : remaining_qty = 8 for lot-1 receipt (10−2), 6 for lot-2 receipt (10−4)
Cause:
--------
When the "Remaining Quantity" column is computed, the following call
chain executes:
stock.move._compute_remaining_qty()
→ calls product.product._get_remaining_moves()
→ calls product._run_fifo_get_stack() ← HERE is the problem
https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/stock_account/models/product.py#L372
`_get_remaining_moves` calls `_run_fifo_get_stack()` with NO lot
argument. Inside `_run_fifo_get_stack`, because no lot is given, it
computes the stack size from the TOTAL product qty across all lots:
https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/stock_account/models/product.py#L583
fifo_stack_size = 14 (10 received lot-1 + 10 received lot-2
− 2 delivered lot-1 − 4 delivered lot-2)
It then builds a domain to find incoming moves with NO lot filter:
https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/stock_account/models/product.py#L607
https://github.com/odoo/odoo/blob/f4d079cc5a9c47672cf1a6747bb073e8e74f7350/addons/stock_account/models/product.py#L614-L618
```Domain: [('is_in', '=', True), ('product_id', '=', X)]
↳ returns both receipts ordered:
[lot-2 receipt (10 qty), lot-1 receipt (10 qty)]
then walks this list consuming `fifo_stack_size = 14`:
So it take: [move_lot1_receipt(10)] First Lot
remaining_qty_on_first = min(10, 14) = 10
after consuming fifo_stack_size → 14−10=4 left → move_lot1 gets 4
```
So back in `_get_remaining_moves`:
qty_by_move = {
lot-2 receipt → 10, ← wrong (should be 6)
lot-1 receipt → 4, ← wrong (should be 8)
}
- The root cause: `_run_fifo_get_stack` is designed for products that
have one shared FIFO stack. For lot-valuated products, each lot is an
independent inventory layer. Running a single combined stack mixes both
lots together, so the deductions (2 from lot-1, 4 from lot-2) are not
attributed to the correct receipt moves — the algorithm just consumes
from the oldest receipts first with no awareness of which lot was
actually delivered.
Fix:
-----
`_run_fifo_get_stack` already accepts a `lot=` argument that:
- sets `fifo_stack_size = lot.product_qty` (correct per-lot qty)
- adds `('move_line_ids.lot_id', 'in', lot.id)` to the domain
so only the receipts that touched that specific lot are returned
The only missing piece was calling it per lot instead of once globally.
- With the fix, the stack for each lot is built correctly:
lot-1: fifo_stack_size = 8 → lot-1 receipt remaining_qty = 8 ✓
lot-2: fifo_stack_size = 6 → lot-2 receipt remaining_qty = 6 ✓
---
opw-6311341
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#276690
Forward-Port-Of: odoo/odoo#2724116 changes
Resolved issues and error corrections
In previous refactor [1], we wrapped the "vat" field under a "vat_div" div. This broke some xpath depending on the "vat". This commit repair those views. [1]: https://github.com/odoo/odoo/commit/825e7c803a4effd601fb247c660416f1cc6d26d7 task-6382108
Original PR description
In previous refactor [1], we wrapped the "vat" field under a "vat_div" div. This broke some xpath depending on the "vat". This commit repair those views. [1]: https://github.com/odoo/odoo/commit/825e7c803a4effd601fb247c660416f1cc6d26d7 task-6382108
11 changes
Resolved issues and error corrections
Issue: There is a missing closing curly bracket on line 67 in odoo/addons/stock/static/src/stock_forecasted/forecasted_details.xml (View) This PR corrects this error opw-6367046 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274575
Original PR description
Issue: There is a missing closing curly bracket on line 67 in odoo/addons/stock/static/src/stock_forecasted/forecasted_details.xml (View) This PR corrects this error opw-6367046 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#274575
2 changes
Enhancements to existing features
Move French e-invoicing technical statuses out of the main invoice UI and into the chatter. The PPF status is kept available in debug mode for troubleshooting, while regular users get a concise chatter summary with the PA status, PPF status, and any returned errors. Duplicate Lifecycle XML attachments are no longer posted in the chatter. Task-6273270 Forward-Port-Of: odoo/odoo#276770 Forward-Port-Of: odoo/odoo#269465
Original PR description
Move French e-invoicing technical statuses out of the main invoice UI and into the chatter. The PPF status is kept available in debug mode for troubleshooting, while regular users get a concise chatter summary with the PA status, PPF status, and any returned errors. Duplicate Lifecycle XML attachments are no longer posted in the chatter. Task-6273270 Forward-Port-Of: odoo/odoo#276770 Forward-Port-Of: odoo/odoo#269465
1 change
Resolved issues and error corrections
### Issue: The 'Schedule an appointment' and 'Next Events' CTA buttons were not updated even when their conditions were satisfied. ### Steps to reproduce: - Install only Website. - In the configurator, choose 'Schedule Appointments' as the main objective. - Complete the setup and create the website. - The CTA button remains 'Contact Us' instead of 'Schedule an appointment'. ### Reason: The `get_cta_data()` method is overridden in specific modules to update the CTA button base
Original PR description
### Issue: The 'Schedule an appointment' and 'Next Events' CTA buttons were not updated even when their conditions were satisfied. ### Steps to reproduce: - Install only Website. - In the configurator, choose 'Schedule Appointments' as the main objective. - Complete the setup and create the website. - The CTA button remains 'Contact Us' instead of 'Schedule an appointment'. ### Reason: The `get_cta_data()` method is overridden in specific modules to update the CTA button based on conditions. However, it is called before those modules are installed, so the overridden logic is never executed. ### Fix: Ensure that `get_cta_data()` is called and the CTA button is updated after the required modules are installed. task-[6383681](https://www.odoo.com/odoo/project/974/tasks/6383681) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261781
2 changes
Resolved issues and error corrections
### Issue: The 'Schedule an appointment' and 'Next Events' CTA buttons were not updated even when their conditions were satisfied. ### Steps to reproduce: - Install only Website. - In the configurator, choose 'Schedule Appointments' as the main objective. - Complete the setup and create the website. - The CTA button remains 'Contact Us' instead of 'Schedule an appointment'. ### Reason: The `get_cta_data()` method is overridden in specific modules to update the CTA button base
Original PR description
### Issue: The 'Schedule an appointment' and 'Next Events' CTA buttons were not updated even when their conditions were satisfied. ### Steps to reproduce: - Install only Website. - In the configurator, choose 'Schedule Appointments' as the main objective. - Complete the setup and create the website. - The CTA button remains 'Contact Us' instead of 'Schedule an appointment'. ### Reason: The `get_cta_data()` method is overridden in specific modules to update the CTA button based on conditions. However, it is called before those modules are installed, so the overridden logic is never executed. ### Fix: Ensure that `get_cta_data()` is called and the CTA button is updated after the required modules are installed. task-[6383681](https://www.odoo.com/odoo/project/974/tasks/6383681) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261781
A previous commit updated the `commonExtraData` from `GeneratePrinterData` in order to update the style from the pdis tickets. However, since `commonExtraData` is used for both receipt and pdis tickets, the change caused a bug for receipts tickets. This commit reverts the `commonExtraData` and update the code in order to still have the correct data dunble for pdis tickets. --- FIX Task: https://www.odoo.com/odoo/project/1737/tasks/6133403 Forward-Port-Of: odoo/odoo#276909
Original PR description
A previous commit updated the `commonExtraData` from `GeneratePrinterData` in order to update the style from the pdis tickets. However, since `commonExtraData` is used for both receipt and pdis tickets, the change caused a bug for receipts tickets. This commit reverts the `commonExtraData` and update the code in order to still have the correct data dunble for pdis tickets. --- FIX Task: https://www.odoo.com/odoo/project/1737/tasks/6133403 Forward-Port-Of: odoo/odoo#276909
### Steps to reproduce: - Open the Todo app - In the editor, insert the following content: `<p>a</p><div class="oe_unbreakable"><br></div><p>b</p>` - Double-click the empty unbreakable node - Open the color picker and hover over a color - Toolbar and color picker get closed ### Root cause: - Hovering a color in an empty unbreakable node replaces the `<br>` with a `<font data-oe-zws-empty-inline>` containing a ZWS (`\u200b`). This triggers a selectionchange where `isToolbarVisible()`
Original PR description
### Steps to reproduce: - Open the Todo app - In the editor, insert the following content: `<p>a</p><div class="oe_unbreakable"><br></div><p>b</p>` - Double-click the empty unbreakable node - Open…
### Steps to reproduce: - Open the Todo app - In the editor, insert the following content: `<p>a</p><div class="oe_unbreakable"><br></div><p>b</p>` - Double-click the empty unbreakable node - Open the color picker and hover over a color - Toolbar and color picker get closed ### Root cause: - Hovering a color in an empty unbreakable node replaces the `<br>` with a `<font data-oe-zws-empty-inline>` containing a ZWS (`\u200b`). This triggers a selectionchange where `isToolbarVisible()` finds no `<br>` and no visible text, returns false, and closes the toolbar — which reverts the preview, reopens the toolbar, and causes a flicker loop. ### Solution: - Instead of calling `fillEmpty()` (which inserts a ZWS placeholder) on empty blocks containing `<br>` preserve the `<br>` element by appending it directly inside the `<font>` tag which keeps toolbar open. task-6312933 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276776 Forward-Port-Of: odoo/odoo#271507
### Issue: The 'Schedule an appointment' and 'Next Events' CTA buttons were not updated even when their conditions were satisfied. ### Steps to reproduce: - Install only Website. - In the configurator, choose 'Schedule Appointments' as the main objective. - Complete the setup and create the website. - The CTA button remains 'Contact Us' instead of 'Schedule an appointment'. ### Reason: The `get_cta_data()` method is overridden in specific modules to update the CTA button base
Original PR description
### Issue: The 'Schedule an appointment' and 'Next Events' CTA buttons were not updated even when their conditions were satisfied. ### Steps to reproduce: - Install only Website. - In the configurator, choose 'Schedule Appointments' as the main objective. - Complete the setup and create the website. - The CTA button remains 'Contact Us' instead of 'Schedule an appointment'. ### Reason: The `get_cta_data()` method is overridden in specific modules to update the CTA button based on conditions. However, it is called before those modules are installed, so the overridden logic is never executed. ### Fix: Ensure that `get_cta_data()` is called and the CTA button is updated after the required modules are installed. task-[6383681](https://www.odoo.com/odoo/project/974/tasks/6383681) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#261781
[FIX] fleet: fix vendor bill vehicle association bug Bug reprod: Go to 19.2 or above 1 - Go to vendor bills. 2 - Create an invoice line add vehicle. 3 - Click to vehicle via the link 4 - You will see fleet model and try to press to some smart buttons, traceback will occur (Odometer, Services...) Bug cause: 1 - When we press to smart buttons for Odometer or Services we are going to return_action_to_open function. 2 - In this function corresponding action's
Original PR description
[FIX] fleet: fix vendor bill vehicle association bug Bug reprod: Go to 19.2 or above 1 - Go to vendor bills. 2 - Create an invoice line add vehicle. 3 - Click to vehicle via the link 4 - You will see…
[FIX] fleet: fix vendor bill vehicle association bug
Bug reprod: Go to 19.2 or above
1 - Go to vendor bills.
2 - Create an invoice line add vehicle.
3 - Click to vehicle via the link
4 - You will see fleet model and try to press to some smart buttons, traceback will occur (Odometer, Services...)
Bug cause:
1 - When we press to smart buttons for Odometer or Services we are going to return_action_to_open function.
2 - In this function corresponding action's xml id is calculated and we are calling that action and that will load some view.
3 - self.env.context is passed directly as a context
4 - In the view_move_form (That include invoice lines, account_id and vehicle_id fields), account_id has a context list_view_ref="account.view_account_list_from_entry"
5 - This context is passed in self.env.context and that's why it tries to load this list_view when we press to odometer,service smart buttons, which shouldn't be the case.
6 - In 19.1 this context is not in self.env.context because >=19.2 m2o_cell_with_extra_m2o_fields is used for account_id and account_id and vehicle_id fields are combined in the single cell.
7 - That's why the context of account_id is passed to the vehicle page as well.
Bug solution:
1 - In the return_action_to_open function I'm dropping the list_view_ref context and we can load the correct related views about odometer or service or other ones.
task - 6385611
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#276167Before this commit, a crash could occur in kanban views but it required a very precise timing. If 2 renderings of the kanban renderer occurred at the same time, one coming from a group that has just been opened, and one coming from a new groupby being applied in the search view, we tried to scroll to the opened group to ensure that it is in the viewport, but we couldn't find it. Task~6391414 Forward-Port-Of: odoo/odoo#276750 Forward-Port-Of: odoo/odoo#276488
Original PR description
Before this commit, a crash could occur in kanban views but it required a very precise timing. If 2 renderings of the kanban renderer occurred at the same time, one coming from a group that has just been opened, and one coming from a new groupby being applied in the search view, we tried to scroll to the opened group to ensure that it is in the viewport, but we couldn't find it. Task~6391414 Forward-Port-Of: odoo/odoo#276750 Forward-Port-Of: odoo/odoo#276488
The "Opening thread with needaction messages should mark all messages of thread as read" test opens a channel that holds an inbox (needaction) message and asserts mark_all_as_read is sent. Two flows can mark that message as read: the channel messages fetch, through set_message_done, and mark_all_as_read, sent by markAsRead when the channel gets focused on open. When the self member's new_message_separator is 0, opening the channel fetches its messages around 0, and that fetch marks the messag
Original PR description
The "Opening thread with needaction messages should mark all messages of thread as read" test opens a channel that holds an inbox (needaction) message and asserts mark_all_as_read is sent. Two flows can mark that message as read: the channel messages fetch, through set_message_done, and mark_all_as_read, sent by markAsRead when the channel gets focused on open. When the self member's new_message_separator is 0, opening the channel fetches its messages around 0, and that fetch marks the message as read and drops the needaction counter to 0 before markAsRead runs. mark_all_as_read is then skipped and the step assertion receives nothing. Give the member a non-zero separator (the pre-existing message is already read) so opening the channel no longer fetches around 0, leaving mark_all_as_read as the flow that marks the inbox message read. https://runbot.odoo.com/odoo/error/243651 Forward-Port-Of: odoo/odoo#276181
**Purpose of this PR:** Before this PR, the Voice detection sensitivity indicator in call settings could get stuck showing the last detected level after clicking "Stop" right after "Test". The `AudioWorkletNode`'s port kept receiving tic messages briefly after `disconnect()`, since disconnecting only unroutes the audio graph and does not stop the worklet from posting pending messages. <img width="546" height="73" alt="voice_test_bug" src="https://github.com/user-attachments/assets/05a10d23
Original PR description
**Purpose of this PR:** Before this PR, the Voice detection sensitivity indicator in call settings could get stuck showing the last detected level after clicking "Stop" right after "Test". The…
**Purpose of this PR:** Before this PR, the Voice detection sensitivity indicator in call settings could get stuck showing the last detected level after clicking "Stop" right after "Test". The `AudioWorkletNode`'s port kept receiving tic messages briefly after `disconnect()`, since disconnecting only unroutes the audio graph and does not stop the worklet from posting pending messages. <img width="546" height="73" alt="voice_test_bug" src="https://github.com/user-attachments/assets/05a10d23-fe60-4a85-b906-bfec6d235ec5" /> Steps to reproduce: 1. Open Voice & Video Settings. 2. Start the Voice detection sensitivity test. 3. Quickly click Stop immediately after clicking Test. 4. It may take a few tries, but eventually the Voice detection sensitivity indicator remains stuck at the last detected level. > [!NOTE] > this is timing-dependent. A tic message must already be in-flight from the worklet thread when `disconnect()` runs, so it won't happen every attempt. This race condition existed in the `disconnect` callback of `_loadAudioWorkletProcessor` since #66611, but stayed silent until #183969 introduced the Voice detection sensitivity feature in call settings, exposing it. This PR clears `port.onmessage` before disconnecting so late tic messages can no longer update the Voice detection sensitivity indicator after monitoring has stopped. Forward-Port-Of: odoo/odoo#275933
When a push subscription is renewed by the browser (typically every few days), the pushsubscriptionchange event fires and the service worker attempts to re-register the new subscription endpoint via register_devices(). However, the VAPID public key was missing from the request kwargs. The server-side register_devices() always validates the VAPID key first and raises InvalidVapidError when it is absent. This caused the renewed subscription to never be saved in the database, silently breaking p
Original PR description
When a push subscription is renewed by the browser (typically every few days), the pushsubscriptionchange event fires and the service worker attempts to re-register the new subscription endpoint via…
When a push subscription is renewed by the browser (typically every few days), the pushsubscriptionchange event fires and the service worker attempts to re-register the new subscription endpoint via register_devices(). However, the VAPID public key was missing from the request kwargs. The server-side register_devices() always validates the VAPID key first and raises InvalidVapidError when it is absent. This caused the renewed subscription to never be saved in the database, silently breaking push notifications after the first subscription renewal. Fix by extracting the applicationServerKey from the new subscription's options and encoding it as a base64url string (without padding) — matching the existing logic in webclient.js _arrayBufferToBase64(). Description of the issue/feature this PR addresses: Current behavior before PR: Subscriptions don't get renewed causing push notifications to stop eventually. Desired behavior after PR is merged: Subscriptions get renewed successfully. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#276085 Forward-Port-Of: odoo/odoo#275217
This fixes two bugs in the web push subscription flow: - register_devices() compared partner records with 'is not' instead of '!='. Records loaded via sudo() live in a different environment than self.env.user, so 'is not' was always True and the ownership guard never behaved as intended. Use '!=', which compares record identity by model and id as Odoo's ORM intends. - webclient.js sent the previous subscription endpoint under the snake_case key 'previous_endpoint', while the server reads i
Original PR description
This fixes two bugs in the web push subscription flow:
- register_devices() compared partner records with 'is not' instead of '!='. Records loaded via sudo() live in a different environment than self.env.user, so 'is not' was always True and the ownership guard never behaved as intended. Use '!=', which compares record identity by model and id as Odoo's ORM intends.
- webclient.js sent the previous subscription endpoint under the snake_case key 'previous_endpoint', while the server reads it as 'previousEndpoint' (kw.get('previousEndpoint', endpoint)). The mismatch meant the lookup always fell back to the new endpoint, so a refreshed subscription created a duplicate device instead of updating the existing one. Send the camelCase key to match the server.
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#276082Since 414e55cf7c397, we can assign multiple users to a user-defined filter but because it's now a many2many, any user that got archived won't be shown in the `user_ids` fields anymore, it could mislead the filter being a global filter; whereas it's not. This commit also display archived users so we can see all users effectively assigned to the user-defined filter. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275841
Original PR description
Since 414e55cf7c397, we can assign multiple users to a user-defined filter but because it's now a many2many, any user that got archived won't be shown in the `user_ids` fields anymore, it could mislead the filter being a global filter; whereas it's not. This commit also display archived users so we can see all users effectively assigned to the user-defined filter. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#275841
Remove the generic active 296 and 297 impairment accounts and make the existing French PCG 296/297 subaccounts active instead, because what we use in the balance sheet formulas are the subaccounts, and it's better to remove the generic ones to not give users the ability to post on these generic accounts, also adapt their translations to be aligned with PCG wording. Move pcg_2962 from the companies chart file to the base French chart file, as 2962 is a general PCG account and not a compa
Original PR description
Remove the generic active 296 and 297 impairment accounts and make the existing French PCG 296/297 subaccounts active instead, because what we use in the balance sheet formulas are the subaccounts, and it's better to remove the generic ones to not give users the ability to post on these generic accounts, also adapt their translations to be aligned with PCG wording. Move pcg_2962 from the companies chart file to the base French chart file, as 2962 is a general PCG account and not a company related one. Note: this is how things were already in 19.0 and this is how they should be, the changes happened by mistake as an unwanted side effect of commit 4f6068a6c88bf0530c19254df403e1194823b415 task-[6226138](https://www.odoo.com/odoo/project/967/tasks/6226138) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#265196
### Overview The SMS Queue Manager cron throws a traceback in a multi company environment when processing sms's that belong to distinct companies. ### Changes Before this commit, the _process_queue method tied to the cron was blindly batching sms's belonging to multiple companies without an sms_api context. The error results because the _send method that's called expects a singleton company when it tries to set the sms_api for the record set, but this isn't the case when the selected sm
Original PR description
### Overview The SMS Queue Manager cron throws a traceback in a multi company environment when processing sms's that belong to distinct companies. ### Changes Before this commit, the _process_queue…
### Overview The SMS Queue Manager cron throws a traceback in a multi company environment when processing sms's that belong to distinct companies. ### Changes Before this commit, the _process_queue method tied to the cron was blindly batching sms's belonging to multiple companies without an sms_api context. The error results because the _send method that's called expects a singleton company when it tries to set the sms_api for the record set, but this isn't the case when the selected sms batch is multi company. After this commit, the _process_queue method now follows the same pattern as the send method, grouping by sms_api / company within the batch, and eliminating the need to check for singleton, as all calls to _send will now have the sms_api context passed in. ### Steps to Reproduce on fresh 19.0 db: 1. Make sure sms / sms_twilio are installed. 2. Create two companies with their own SMS config. 3. Create two sms records, one with each company. 4. Ensure the state of the sms's is 'outgoing'. 5. Execute the SMS Queue Manager Cron. Observe the traceback: ValueError: Expected singleton... opw-6371272 Forward-Port-Of: odoo/odoo#276426
Problem: When importing XML files to generate vendor bills, the system uses UBL parser and assumes that the PriceAmount node needs to be divided by the BaseQuantity node to obtain the exact price unit. However, in Colombia, the DIAN treats the PriceAmount node as the exact price unit. This was not flagged in the system so the parser incorrectly divides the PriceAmount by BaseQuantity, resulting in negative discounts to be added to match the subtotal. Solution: Extract the basis_qty logic into
Original PR description
Problem: When importing XML files to generate vendor bills, the system uses UBL parser and assumes that the PriceAmount node needs to be divided by the BaseQuantity node to obtain the exact price…
Problem: When importing XML files to generate vendor bills, the system uses UBL parser and assumes that the PriceAmount node needs to be divided by the BaseQuantity node to obtain the exact price unit. However, in Colombia, the DIAN treats the PriceAmount node as the exact price unit. This was not flagged in the system so the parser incorrectly divides the PriceAmount by BaseQuantity, resulting in negative discounts to be added to match the subtotal. Solution: Extract the basis_qty logic into a helper method so other localizations can override when needed. Current behavior: When importing a Colombian XML with a product that has a BaseQuantity greater than 1, the PriceAmount gets incorrectly divided, resulting in negative discounts on the vendor bill. Expected Behavior: When importing a Colombian XML with a product that has a BaseQuantity greater than 1, the PriceAmount gets parses as the exact unit price with no negative discounts applied. Task [link](https://www.odoo.com/odoo/project.task/6215466) task-6215466 Forward-Port-Of: odoo/odoo#276430 Forward-Port-Of: odoo/odoo#273129
Before this commit: If a user, with crm.leads linked to it, decided to request a password reset AND during that password reset process decided to activate the google oauth for their account, it would cause a crash. The reason is, during the password rest + oauth activation, self.env.user is an empty record set, which obviously will fail during the _is_portal check, due to its call to ensure_one() opw-6347228 Forward-Port-Of: odoo/odoo#275375
Original PR description
Before this commit: If a user, with crm.leads linked to it, decided to request a password reset AND during that password reset process decided to activate the google oauth for their account, it would cause a crash. The reason is, during the password rest + oauth activation, self.env.user is an empty record set, which obviously will fail during the _is_portal check, due to its call to ensure_one() opw-6347228 Forward-Port-Of: odoo/odoo#275375
Steps to reproduce: - Go to Website - Upload an image in the company logo (navbar) - Open the website editor and click on the logo - Open the image info panel Current behavior: When clicking on the website logo in the editor, the size shown is always a constant number ~5.9kB, regardless of the actual size of the uploaded logo. The correct size is visible in the browser DOM. This gives users the wrong impression that their image is being heavily compressed or losing quality when it isn'
Original PR description
Steps to reproduce: - Go to Website - Upload an image in the company logo (navbar) - Open the website editor and click on the logo - Open the image info panel Current behavior: When clicking on the…
Steps to reproduce: - Go to Website - Upload an image in the company logo (navbar) - Open the website editor and click on the logo - Open the image info panel Current behavior: When clicking on the website logo in the editor, the size shown is always a constant number ~5.9kB, regardless of the actual size of the uploaded logo. The correct size is visible in the browser DOM. This gives users the wrong impression that their image is being heavily compressed or losing quality when it isn't. Reason: When clicking the logo, the editor tries to find the original, unprocessed version of the image so it can support cropping and other edits. It does this by asking the server to match the image's URL to a stored attachment. The website logo is served through a dynamic link (`/web/image/website/<id>/logo/<name>`) that isn't tied to a regular attachment record the way normal content images are, since it isn't uploaded through the usual media picker. Because of this, the server can't find a matching original, and the editor is left without a valid image source to work with. As a fallback, the editor tries to load a placeholder path instead of a real image. This request fails and silently resolves to Odoo's generic "image not found" placeholder. All further processing (and the size calculation) then happens on this small placeholder image instead of the actual logo, which is why the size shown never changes. Fix: When `get_image_info` does not return a usable `original`, `loadImageInfo` now falls back to using the image's own current src as `originalSrc`, instead of leaving it unset. This ensures `loadImage` always receives a valid, resolvable URL, so image processing (and the size shown) reflects the actual logo. opw-6260496 Forward-Port-Of: odoo/odoo#273542
Resolved issues and error corrections
Currently, overlays remain open when the POS screensaver is loaded [^1]. #### Steps to reproduce: - Open the POS interface. - Open a dropdown/popover menu (e.g., the navbar hamburger menu). - Wait for the screensaver (SaverScreen) to trigger due to inactivity. - The open dropdown menu remains visible on top of the screensaver. #### Issue Dropdowns and popovers are rendered as active overlays outside the main screen container. While the screensaver setup closes active dialogs, it doe
Original PR description
Currently, overlays remain open when the POS screensaver is loaded [^1]. #### Steps to reproduce: - Open the POS interface. - Open a dropdown/popover menu (e.g., the navbar hamburger menu). - Wait for the screensaver (SaverScreen) to trigger due to inactivity. - The open dropdown menu remains visible on top of the screensaver. #### Issue Dropdowns and popovers are rendered as active overlays outside the main screen container. While the screensaver setup closes active dialogs, it does not handle active overlays. #### Fix Retrieve the overlay service in SaverScreen and close all active overlays during its setup phase using a dedicated `closeAllOverlays` method. [^1]:  Forward-Port-Of: odoo/odoo#276672 Forward-Port-Of: odoo/odoo#274716
Users cannot navigate to the next page in the message list view when hidden records cause the current page to appear incomplete. ### Steps to reproduce 1. Create many messages, ensuring some are hidden from a specific user via access rules. 2. Open the message list view as that user. 3. Pagination incorrectly shows a total matching the current page (e.g., "1-68 / 68") instead of the full count (e.g., "1-80 / 5000+"). 4. Because the system believes all records are displayed, the "Next" p
Original PR description
Users cannot navigate to the next page in the message list view when hidden records cause the current page to appear incomplete. ### Steps to reproduce 1. Create many messages, ensuring some are…
Users cannot navigate to the next page in the message list view when hidden records cause the current page to appear incomplete. ### Steps to reproduce 1. Create many messages, ensuring some are hidden from a specific user via access rules. 2. Open the message list view as that user. 3. Pagination incorrectly shows a total matching the current page (e.g., "1-68 / 68") instead of the full count (e.g., "1-80 / 5000+"). 4. Because the system believes all records are displayed, the "Next" page button is disabled, leaving the user stuck on the current page despite more records existing in the database. ### Cause The `mail.message` model filters records in Python after fetching them from the database to enforce complex access rules. 1. The system queries the database for a batch of records up to the view's limit. 2. The `_search` method removes inaccessible records from this batch. 3. The web client receives fewer records than the requested limit. 4. Interpreting this as the end of the dataset, the web client skips the count query and displays the current batch size as the total. ### Fix Add `'force_search_count': 1` to the action context. This forces the web client to execute a separate count query to determine the total number of records, regardless of the batch size returned. opw-5425361