Friday, July 24, 2026
45 changes · saas-19.3
Enhancements to existing features
Task: 6167605 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#270801 Forward-Port-Of: odoo/odoo#261793
Original PR description
Task: 6167605 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#270801 Forward-Port-Of: odoo/odoo#261793
After this advisory: https://services.gst.gov.in/services/advisoryandreleases/read/661 It has become mandatory to pass `shipToGSTIN`, i.e. GST number of the ship-to partner during the generation of the e-waybill for `Bill-to-Ship-to` (type-2) and `Combination` (type-4) transaction types. task-6236778 Forward-Port-Of: odoo/odoo#266388
Original PR description
After this advisory: https://services.gst.gov.in/services/advisoryandreleases/read/661 It has become mandatory to pass `shipToGSTIN`, i.e. GST number of the ship-to partner during the generation of the e-waybill for `Bill-to-Ship-to` (type-2) and `Combination` (type-4) transaction types. task-6236778 Forward-Port-Of: odoo/odoo#266388
This commit adds `company_register` VAT Registry (VAT ID) to the invoice header for [legal reasons](https://lex.uz/ru/docs/4948595#5225819). Also, the condition for `TIN` has been updated to be 14 digits if the contact is a person and 9 digits if it is a company. task-6205255 Forward-Port-Of: odoo/odoo#273885
Original PR description
This commit adds `company_register` VAT Registry (VAT ID) to the invoice header for [legal reasons](https://lex.uz/ru/docs/4948595#5225819). Also, the condition for `TIN` has been updated to be 14 digits if the contact is a person and 9 digits if it is a company. task-6205255 Forward-Port-Of: odoo/odoo#273885
Resolved issues and error corrections
The salary attachment form now shows the refund option again, matching the information already stored in the system. This helps payroll users correctly identify refund-related salary attachments without needing a separate wizard or workaround.
Original PR description
In an old PR (https://github.com/odoo/enterprise/pull/109195) the is_refund field was removed from the salary attachment view, although the field itself was not removed from the db. In a later PR (https://github.com/odoo/enterprise/pull/114188) the field was removed from the database but later reverted (https://github.com/odoo/enterprise/pull/123728). As it stands now, the field is in the database and is present in the view of a wizard but not in the standard form view of the salary attachment. This PR is reintroducing it. Task: 6415857
Code cleanup and technical improvements
Description of the issue/feature this PR addresses: - In 49f01db, `getDefaultValueFromGlobalFilter` was introduced to support `GlobalFilterInput`. - `GlobalFilterInput` no longer relies on this function, so remove the unused function. Task: [6388147](https://www.odoo.com/odoo/project/2328/tasks/6388147) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Original PR description
Description of the issue/feature this PR addresses: - In 49f01db, `getDefaultValueFromGlobalFilter` was introduced to support `GlobalFilterInput`. - `GlobalFilterInput` no longer relies on this function, so remove the unused function. Task: [6388147](https://www.odoo.com/odoo/project/2328/tasks/6388147) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Documentation and clarification updates
Adds Corvanis corporate CLA entry so legal/cla can validate contributions from Corvanis contributors. This change only adds: - doc/cla/corporate/corvanis.md - No functional code changes. Forward-Port-Of: odoo/odoo#276949
Original PR description
Adds Corvanis corporate CLA entry so legal/cla can validate contributions from Corvanis contributors. This change only adds: - doc/cla/corporate/corvanis.md - No functional code changes. Forward-Port-Of: odoo/odoo#276949
Miscellaneous changes
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
Original PR description
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 timesheet percentage now refreshes as soon as timesheets are added, edited, or removed, instead of waiting for a page reload. This keeps sales and project tracking information accurate in real time and reduces confusion for users.
Original PR description
Issue: The percentage is only updated after reloading the page. Cause: The percentage computation is performed inside `loadTimesheets`, which is only called when the timesheets are loaded. Fix: Move the percentage computation into a helper function and invoke it whenever a timesheet is added, updated, or removed. task-6401186 Forward-Port-Of: odoo/enterprise#125224 Forward-Port-Of: odoo/enterprise#125074
This fixes intermittent failures in automated barcode scrap checks that could incorrectly treat a scrap quantity as zero. The change helps keep stock and manufacturing barcode validation more stable, reducing false alarms in quality checks.
Original PR description
These barcode scrap tours randomly trigger "You can only enter positive quantities." on runbot: the quantity set with a raw input.value is dropped when the field re-renders before the scrap is saved, so it scraps 0. Dispatching an input event keeps the typed value. error-238911 Forward-Port-Of: odoo/enterprise#124952
When users open related entries from a confirmed asset, the list now stays focused on the relevant journal items instead of opening an unhelpful detail form. The breadcrumb label is also clearer, using “Related Items” to better describe what users are viewing.
Original PR description
If you create an asset and confirm it, you can see the Related Entries using the smart button Related Entries. The list view that opens is clickable, but it opens a quite useless form view of the Journal Items. - Rename breadcrumb button to Related Items - Make it behave like action_account_moves_all, to not open form view Ticket: [6385260](https://www.odoo.com/odoo/project/967/tasks/6385260) Forward-Port-Of: odoo/enterprise#124672
Audit reports now correctly update the number of invalid records when an audit check is reviewed successfully. This prevents users from seeing outdated anomaly counts after a check no longer finds issues, improving confidence in audit cycle reporting.
Original PR description
Problem: Sometimes after an audit check passes (gets reviewed successfully), the count of invalid records in the audit report is not updated. Steps to reproduce: 1. Add a check for an audit cycle 2. Make sure the check's domain is satisified by at least one record 3. Check the audit report and see the check you added 4. The check status should show an anomaly and the count of invalid records will be greater than 0 5. Now, edit the check so that the domain is not satisfied by any record 6. Check the audit report again and see the check you edited 7. The check status should show "Reviewed" but the count of invalid records will still be greater than 0, which is not correct Cause: When updating the status of an audit check, the count of invalid records is not updated, only the status gets updated. opw-6264177 Forward-Port-Of: odoo/enterprise#123751 Forward-Port-Of: odoo/enterprise#119227
This fixes the French VAT report export so the BA zone is sent using the expected free-text format rather than as a standard value. This helps ensure the generated report matches the required filing structure and reduces the risk of submission errors.
Original PR description
The value inside the BA zone needs to be a "TexteLibre1" and not a value no task id Forward-Port-Of: odoo/enterprise#125335
The SEO autofill powered by AI now uses the website page’s language instead of the editor’s personal language setting. This helps multilingual websites generate page titles and descriptions in the correct language, reducing manual correction and improving consistency for visitors and search engines.
Original PR description
The SEO "Fill with AI" autofill used the user's language for generation. On a website whose language differs from the user's, the generated seo metadata was therefore in the wrong language. This commit fixes this by using the page language instead. Forward-Port-Of: odoo/enterprise#123447
This fix ensures financial reports correctly recognize when no report section has been opened yet. It helps preserve expected report navigation behavior and prevents a small logic issue from affecting how report sections are restored or displayed.
Original PR description
**Root Cause:**
At [1], the condition `this.lastOpenedSectionByReport === {}` always
return `false` because JavaScript compares objects by reference
rather than by value. As a result, the code never detects when
`lastOpenedSectionByReport` is empty.
**Fix:**
This commit ensures the code correctly detects an empty
`lastOpenedSectionByReport` object.
[1]:
https://github.com/odoo/enterprise/blob/ae4b461edb1d6b49c25d4e264380e7ae4b67f10c/account_reports/static/src/components/account_report/controller.js#L50
**No task ID**
Forward-Port-Of: odoo/enterprise#125325
Forward-Port-Of: odoo/enterprise#124223This fix prevents leftover collaboration messaging from one automated test interfering with a Knowledge tour that does not use collaboration. It helps keep automated build checks stable and reduces false failure reports during testing.
Original PR description
This aims to fix Runbot build error #937788 ([1]). A collaboration error was thrown during a tour which makes no use of collaboration. This makes sure the bus from the previous test doesn't persist when running this tour so it doesn't interfere. [1]: https://runbot.odoo.com/odoo/runbot.build.error/937788
The timesheet assistant now expands the description field dynamically so longer entries can be read in full instead of being cut off. This makes it easier for users to review and confirm detailed time entries without losing important context.
Original PR description
- changed the description field to expand dynamically to display long descriptions in full instead of truncating them in the assistant Task-6348575 Forward-Port-Of: odoo/enterprise#123428
The test read the field content for the last urgent save right after resolving modifyImagePromise, without waiting for the DOM to actually reflect the new image src. This raced the async update of the editable content, so beforeUnload sometimes ran before the image src were updated, sending stale content and failing intermittently. Wait for the updated image to appear in the DOM before triggering the last beforeUnload, instead of relying on a fixed animationFrame wait. runbot-243773 ---
Original PR description
The test read the field content for the last urgent save right after resolving modifyImagePromise, without waiting for the DOM to actually reflect the new image src. This raced the async update of the editable content, so beforeUnload sometimes ran before the image src were updated, sending stale content and failing intermittently. Wait for the updated image to appear in the DOM before triggering the last beforeUnload, instead of relying on a fixed animationFrame wait. runbot-243773 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#278032
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- * Create a PO and confirm it * Open the receipt, validate and duplicate it * Go on the duplicated receipt and change its Operation Type * Confirm the duplicated receipt. -> the Received Qty on the Po counted the duplicated and modified transfer. Observation: ------------- When we duplicat
Original PR description
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- *…
On a Purchase Order, if you duplicate the delivery, change its Operation Type and validate it, it will still count towards the received quantity on the po. Steps to reproduce: ------------------- * Create a PO and confirm it * Open the receipt, validate and duplicate it * Go on the duplicated receipt and change its Operation Type * Confirm the duplicated receipt. -> the Received Qty on the Po counted the duplicated and modified transfer. Observation: ------------- When we duplicate a stock.picking, we will call ```copy``` and copy all its ```move_ids``` (stock.move), and in stock.move we will copy the ```purchase_line_id``` : https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5868 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/models.py#L5881-L5892 https://github.com/odoo/odoo/blob/3e6d93bef49bb2718e8aa1756f95c2a6117c8d55/addons/purchase_stock/models/stock_move.py#L13-L15 the ```purchase_line_id``` will keep the link with the pol. The fields are copied since they have ```copy=True``` https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/addons/stock/models/stock_picking.py#L614 https://github.com/odoo/odoo/blob/754898c58fded0e3c3c30702f15258f1dadcfa6c/odoo/fields.py#L304 Because new stock moves are linked directly to the Purchase Order Line (POL), the qty_received calculation aggregates all associated move quantities. https://github.com/odoo/odoo/blob/cfc63060926db4cec773c159b8ecf97dc0b36d1a/addons/purchase_stock/models/purchase_order_line.py#L73-L76 opw-6088239 Forward-Port-Of: odoo/odoo#276250 Forward-Port-Of: odoo/odoo#259570
Problem: Some users with limited access rights cannot access invoices they created, after another user duplicates their sales order and invoices it. Steps to reproduce: 1. Create a user with minimal access rights (only access rights to their own sales orders and invoices). 2. Sign in as that user and create a sales order and confirm it. 3. Create an invoice for that sales order and validate it. 4. Sign in as an administrator and create a duplicate sales order for that sales order, but as
Original PR description
Problem: Some users with limited access rights cannot access invoices they created, after another user duplicates their sales order and invoices it. Steps to reproduce: 1. Create a user with minimal…
Problem: Some users with limited access rights cannot access invoices they created, after another user duplicates their sales order and invoices it. Steps to reproduce: 1. Create a user with minimal access rights (only access rights to their own sales orders and invoices). 2. Sign in as that user and create a sales order and confirm it. 3. Create an invoice for that sales order and validate it. 4. Sign in as an administrator and create a duplicate sales order for that sales order, but assign it to a different user (not the one created in step 1). 5. Confirm the duplicate sales order, create an invoice for it and validate it. 6. Sign in as the user created in step 1 and try to access the invoice created in step 3. 7. Note the access error Cause: When reading an account.move record, the system searches for duplicate moves and adds them to the duplicated_ref_ids field. However, it does not check if the user has read access to those duplicate moves, which leads to access errors when trying to access the main account.move record (which the user has read access to) because the system tries to read the duplicate moves (which the user does not have read access to). opw-6374566 Forward-Port-Of: odoo/odoo#277823 Forward-Port-Of: odoo/odoo#276547
currently the xpaths are targeting a \<strong\> tag. Those are available in the translations, and can be erased depending on language, user preference, default customization. Once removed you can no longer print invoices with the default report. This fix should make it target the first element of the div instead of the strong, avoiding that conflict and allowing the customer to translate however he feels like. opw-6383047 Description of the issue/feature this PR addresses: Current be
Original PR description
currently the xpaths are targeting a \<strong\> tag. Those are available in the translations, and can be erased depending on language, user preference, default customization. Once removed you can no longer print invoices with the default report. This fix should make it target the first element of the div instead of the strong, avoiding that conflict and allowing the customer to translate however he feels like. opw-6383047 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#277581
**Steps to reproduce:** - Create two companies - Create aliases for each company - Receive a bounced email on the alias of the second company - Recipient of the bounce email will be from the first company **Issue:** `self.env.company` is used in `message_route` for catchall mails without checking if it corresponds to the received domain, making it defaults to the 'main' company instead. **Fix:** Try to find the company of the given mail address using the `'mail.alias.domain'` and app
Original PR description
**Steps to reproduce:** - Create two companies - Create aliases for each company - Receive a bounced email on the alias of the second company - Recipient of the bounce email will be from the first company **Issue:** `self.env.company` is used in `message_route` for catchall mails without checking if it corresponds to the received domain, making it defaults to the 'main' company instead. **Fix:** Try to find the company of the given mail address using the `'mail.alias.domain'` and apply it on the body rendering and `_routing_create_bounce_email` function. similar fix in `account` module: https://github.com/odoo/odoo/commit/b7e0d8914d35af12a96593e484889e48c0613078 opw-5180433 Forward-Port-Of: odoo/odoo#244296
Issue: In "l10n standalone" for l10n_ke, .`test_cogs_kit_multi_steps_first_step_validated` failed. Steps to reproduce: - install `l10_ke_edi_oscu_stock` and `sale_mrp` - run `test_cogs_kit_multi_steps_first_step_validated` Cause: `l10_ke_edi_oscu_stock` override the compute for product `invoice_policy`. Product from Kenyan company or withour company are by default set to invoice on delivery. Therefore, setting a two steps delivery require to validate picking then shipping bef
Original PR description
Issue:
In "l10n standalone" for l10n_ke, .`test_cogs_kit_multi_steps_first_step_validated` failed.
Steps to reproduce:
- install `l10_ke_edi_oscu_stock` and `sale_mrp`
- run `test_cogs_kit_multi_steps_first_step_validated`
Cause:
`l10_ke_edi_oscu_stock` override the compute for product `invoice_policy`. Product from
Kenyan company or withour company are by default set to invoice on delivery. Therefore,
setting a two steps delivery require to validate picking then shipping before invoicing.
As products are not required to be invoiced on delivery by any l10n, it is possible to force
test products to have invoice_policy set to 'order' and not to depend on l10n default value.
runbot-940390
Forward-Port-Of: odoo/odoo#277268Current behavior before PR, [1](https://github.com/odoo/odoo/pull/261837) introduced a rule with higher specificity, overriding the animation-delays of the specific dots in the typing indicator. This caused all dots to jump together at the same time. Desired behavior after PR is merged, the different animation-delays are moved inside the specific rule to correctly apply the delay. Before/After, <img width="125" height="160" alt="bug" src="https://github.com/user-attachments/asset
Original PR description
Current behavior before PR, [1](https://github.com/odoo/odoo/pull/261837) introduced a rule with higher specificity, overriding the animation-delays of the specific dots in the typing indicator. This caused all dots to jump together at the same time. Desired behavior after PR is merged, the different animation-delays are moved inside the specific rule to correctly apply the delay. Before/After, <img width="125" height="160" alt="bug" src="https://github.com/user-attachments/assets/8011fe05-6e78-45d6-aee7-a82b7c9bfdd1" /> <img width="125" height="160" alt="expected" src="https://github.com/user-attachments/assets/f367311f-b9a4-4d18-9be1-ae1e7d059a9a" /> --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277944
**Problem:** After partially invoicing a timesheet-delivered sale order line, a second invoice for the remaining delivered quantity can no longer be created. **Steps to reproduce:** 1. Install Sales and Timesheets 2. Sell a service invoiced on delivered timesheets 3. Log a timesheet covering the whole period 4. Create an invoice, reduce its quantity to part of the delivered amount, and post it 5. Create an invoice again for the rest **Current behavior:** "Cannot create an invoice. N
Original PR description
**Problem:** After partially invoicing a timesheet-delivered sale order line, a second invoice for the remaining delivered quantity can no longer be created. **Steps to reproduce:** 1. Install Sales…
**Problem:** After partially invoicing a timesheet-delivered sale order line, a second invoice for the remaining delivered quantity can no longer be created. **Steps to reproduce:** 1. Install Sales and Timesheets 2. Sell a service invoiced on delivered timesheets 3. Log a timesheet covering the whole period 4. Create an invoice, reduce its quantity to part of the delivered amount, and post it 5. Create an invoice again for the rest **Current behavior:** "Cannot create an invoice. No items are available to invoice." is raised, even though qty_delivered - qty_invoiced is still positive. **Expected behavior:** A second invoice is created for the remaining delivered quantity. **Cause of the issue:** Since opw-6001094, `_recompute_qty_to_invoice` runs on every invoice creation, not only when a timesheet period is provided. It re-derives `qty_to_invoice` from un-invoiced timesheets alone. Posting the first invoice already linked every timesheet of the line (the linking ignores the invoiced quantity), so no un-invoiced timesheet is left, and `qty_to_invoice` is forced to 0 — discarding the still-billable remainder. **Fix:** Forcing the quantity to zero is only meaningful when the invoice is restricted to a timesheet period, where a line whose timesheets all fall outside that period genuinely has nothing to invoice. Without a period, the standard delivered-versus-invoiced quantity is the authoritative measure of what remains to bill, so the timesheet-based recomputation must not override it. opw-6295941 Forward-Port-Of: odoo/odoo#274677
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share the project with edit access to a portal user belonging to Company A.4 4. Create a task, switch to Company B, and log a timesheet on the task. 5. Log in as the portal user and try to access the project. Issue: ------- An `Access to unauthorized or invalid companies exception` is raised,
Original PR description
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share…
Steps to reproduce: ------------------------- 1. Install hr_timesheet and create a second company (e.g., Company B). 2. Create a global project (no company assigned) with timesheets enabled. 3. Share the project with edit access to a portal user belonging to Company A.4 4. Create a task, switch to Company B, and log a timesheet on the task. 5. Log in as the portal user and try to access the project. Issue: ------- An `Access to unauthorized or invalid companies exception` is raised, preventing the portal user from accessing a project they are legitimately shared on. Cause: ---------- https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/project/controllers/portal.py#L159-L173 During `_prepare_project_sharing_session_info`, hr_timesheet overrides the company determination logic through `_get_project_sharing_company()`. https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/hr_timesheet/controllers/project.py#L13-L18 For global projects, the company is derived from an existing timesheet if one exists. As a result, creating a timesheet in another company causes that company to be injected into the sharing session as the current company. Since the portal user does not have access to that company, opening the project triggers an access error. Solution: ---------- Remove the `_get_project_sharing_company()` override. The base implementation already falls back to the portal user's own company when the project has no company assigned, ensuring the sharing session only contains companies the portal user is allowed to access. https://github.com/odoo/odoo/blob/b7b3292b6a46c3dbc17aeee0183df0af318bf810/addons/project/controllers/portal.py#L141-L142 This allows portal users from Company A to continue accessing global projects without errors. opw-6253960 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277640 Forward-Port-Of: odoo/odoo#272161
#### Description of the issue this PR addresses: - Tables containing only a `<caption>` (or a `<thead>` without a `<tbody>`) could reach the editor with no `<tbody>`. - Table operations assume every table contains a `<tbody>`, making these tables impossible to manipulate correctly. #### Desired behavior after PR is merged: - Tables without a `<tbody>` are normalized during editor setup and paste. - `<thead>` is converted or merged into `<tbody>`. - A missing `<tbody>` is created when nec
Original PR description
#### Description of the issue this PR addresses: - Tables containing only a `<caption>` (or a `<thead>` without a `<tbody>`) could reach the editor with no `<tbody>`. - Table operations assume every table contains a `<tbody>`, making these tables impossible to manipulate correctly. #### Desired behavior after PR is merged: - Tables without a `<tbody>` are normalized during editor setup and paste. - `<thead>` is converted or merged into `<tbody>`. - A missing `<tbody>` is created when necessary, ensuring every table has the expected structure for editor operations. task-6391354 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277081 Forward-Port-Of: odoo/odoo#276588
Steps to reproduce: - activate location - create a tracked product A - create a PO with qty=10 with product A - receive them (8 in WH/Stock, 2 in WH/Stock/Shelf 1) - In Reporting/stock filter with "wh/stock" Issue: On hand value will be 0 Cause: "wh/stock did not match _rec_names = 'name' -> WH location is different than "stock" location (who's parent is "WH"). We need to match it with _rec_names_search (1) to match the right location. We fall back on _rec_names in case _rec_name
Original PR description
Steps to reproduce: - activate location - create a tracked product A - create a PO with qty=10 with product A - receive them (8 in WH/Stock, 2 in WH/Stock/Shelf 1) - In Reporting/stock filter with "wh/stock" Issue: On hand value will be 0 Cause: "wh/stock did not match _rec_names = 'name' -> WH location is different than "stock" location (who's parent is "WH"). We need to match it with _rec_names_search (1) to match the right location. We fall back on _rec_names in case _rec_names_search would not be defined (not really necessary in here but meh why not be conservative) (1) https://github.com/odoo/odoo/blob/2bb7493b72b400ed76cc6460c94867fb86de9f3a/addons/stock/models/stock_location.py#L19 opw-6312702 Forward-Port-Of: odoo/odoo#271552
Before this commit, validating transfers of several companies at once could assign a lot of one company to the move lines of another one, because the search for existing lots used a variable left over from a previous loop (the last move line iterated) instead of the company of the group of lines being checked. Steps to reproduce: - in a multi-company database, create a product tracked by lots - create a lot with the same name for that product in each company - create one receipt per compan
Original PR description
Before this commit, validating transfers of several companies at once could assign a lot of one company to the move lines of another one, because the search for existing lots used a variable left…
Before this commit, validating transfers of several companies at once could assign a lot of one company to the move lines of another one, because the search for existing lots used a variable left over from a previous loop (the last move line iterated) instead of the company of the group of lines being checked. Steps to reproduce: - in a multi-company database, create a product tracked by lots - create a lot with the same name for that product in each company - create one receipt per company with that lot name typed in the detailed operations, select both receipts in the Transfers list view and validate them together The lines of one company are linked to the lot of the other company and the validation is blocked by "Incompatible companies on records". When the lot only exists in one of the companies, the search misses it and the validation fails on the lot uniqueness constraint while recreating a lot that already exists. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277227 Forward-Port-Of: odoo/odoo#276688
Steps to reproduce 1. Go to Website Settings. 2. Configure the "Contact Us" form to create an Opportunity. 3. Select a "Default Sales Team" (ensure this team has a Team Leader set). 4. Leave the "Default Salesperson" field empty (None). 5. Submit the "Contact Us" form on the website. Current behavior The resulting Opportunity is automatically assigned to the Team Leader. Expected behavior The Opportunity should remain unassigned, respecting the empty "Default Salesperson" configura
Original PR description
Steps to reproduce 1. Go to Website Settings. 2. Configure the "Contact Us" form to create an Opportunity. 3. Select a "Default Sales Team" (ensure this team has a Team Leader set). 4. Leave the…
Steps to reproduce 1. Go to Website Settings. 2. Configure the "Contact Us" form to create an Opportunity. 3. Select a "Default Sales Team" (ensure this team has a Team Leader set). 4. Leave the "Default Salesperson" field empty (None). 5. Submit the "Contact Us" form on the website. Current behavior The resulting Opportunity is automatically assigned to the Team Leader. Expected behavior The Opportunity should remain unassigned, respecting the empty "Default Salesperson" configuration. Issue In https://github.com/odoo-dev/odoo/commit/d136e79d1ea0a4793ba9d447603e6f0e29b40770, a fallback was introduced to explicitly assign the Team Leader (`team_id.user_id`) whenever a team was present but a salesperson was not, provided rule-based assignment was disabled: https://github.com/odoo/odoo/blob/d136e79d1ea0a4793ba9d447603e6f0e29b40770/addons/website_crm/models/crm_lead.py#L55-L56 This incorrectly overrides the intentional configuration in the website settings. Additionally, in https://github.com/odoo-dev/odoo/commit/ba6a5ddc8dec971f8b810dfad3d9934e7b581c91, the website_form_input_filter was made to fall back to request.website.crm_default_team_id and crm_default_user_id when the form did not submit those fields: https://github.com/odoo/odoo/blob/ba6a5ddc8dec971f8b810dfad3d9934e7b581c91/addons/website_crm/models/crm_lead.py#L14-L17 The Contact Us form already passes the configured team and salesperson as hidden inputs. When they are not configured, nothing is submitted for those fields. The fallback to request.website caused leads to be assigned a team even when neither field was intentionally configured, because crm_default_team_id defaults to the first sales team on website creation. opw-6050663 Forward-Port-Of: odoo/odoo#257134
Issue: When an invoice (sales journal) uses "Switzerland" localization and the invoice is issued to a customer outside Switzerland/Liechtenstein, no payment reference is generated. This causes the invoice PDF to hide payment communication and bank account details. Other localizations like Belgian companies, uses Belgian references, the reference is always generated regardless of customer country. Steps to reproduce: - Configure a Swiss company with a QR IBAN bank account - Set the sales
Original PR description
Issue: When an invoice (sales journal) uses "Switzerland" localization and the invoice is issued to a customer outside Switzerland/Liechtenstein, no payment reference is generated. This causes the…
Issue: When an invoice (sales journal) uses "Switzerland" localization and the invoice is issued to a customer outside Switzerland/Liechtenstein, no payment reference is generated. This causes the invoice PDF to hide payment communication and bank account details. Other localizations like Belgian companies, uses Belgian references, the reference is always generated regardless of customer country. Steps to reproduce: - Configure a Swiss company with a QR IBAN bank account - Set the sales journal Communication Standard to Switzerland - Create and confirm an invoice for a non swiss customer (US, BE) - Observe in the pdf and in the other info tab -> no payment reference or payment details Cause: `get_l10n_ch_qrr_number()` was using on `l10n_ch_is_qr_valid()`, which conflicts QR-bill printability (partner country, currency) with payment reference generation. When the customer is outside CH/LI, `l10n_ch_is_qr_valid()` is False and no QRR reference is generated. Solution: Decouple QRR reference generation from QR bill printability. The Swiss communication standard now generates a QRR format reference when a QR-IBAN is configured, regardless of customer's country or currency. opw-6222417 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#272617 Forward-Port-Of: odoo/odoo#266861
There is a flickering when hovering the chart granularity popover. How to reproduce: - open a dashboard with a time-based chart (like the Sales dashboard) - hover it and click on the "Month" button - hover the popover with the granularity suggestions => flickering The issue seems to come from the way Chrome handles the <select> popover as the element is not recognized as a child element of the <select> parent. As such, the pseudo-class `:focus-within` does not work as intended and th
Original PR description
There is a flickering when hovering the chart granularity popover. How to reproduce: - open a dashboard with a time-based chart (like the Sales dashboard) - hover it and click on the "Month" button - hover the popover with the granularity suggestions => flickering The issue seems to come from the way Chrome handles the <select> popover as the element is not recognized as a child element of the <select> parent. As such, the pseudo-class `:focus-within` does not work as intended and the chart menu flickers between a visible/hidden state. As a fix, we rely on another pseudo-class `:open` that applies to the <select> tag, its open state being correctly handled by the browser. Task-6288876 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#274619
Steps to reproduce: 1. Drop the Website Form snippet. 2. Add a checkbox field. 3. Change the label position to Top. > The Default Value option disappears. Cause: The `applyTo` selector relied on the `.col-sm` wrapper, which is only present for left/right label positions. As a result, it did not match checkbox fields with Top or None labels. This commit fix the applyTo selector so the Default Value option is displayed for checkbox fields regardless of the selected label position.
Original PR description
Steps to reproduce: 1. Drop the Website Form snippet. 2. Add a checkbox field. 3. Change the label position to Top. > The Default Value option disappears. Cause: The `applyTo` selector relied on the `.col-sm` wrapper, which is only present for left/right label positions. As a result, it did not match checkbox fields with Top or None labels. This commit fix the applyTo selector so the Default Value option is displayed for checkbox fields regardless of the selected label position. task-6373796 Forward-Port-Of: odoo/odoo#277497 Forward-Port-Of: odoo/odoo#275823
### Description of the issue/feature this PR addresses: - Opening Studio on a form containing a Many2many field using the many2many_tags_email widget crashes with an OWL prop validation error. - **Steps to reproduce:** 1. Open any form view (e.g., Contacts) and enter `Studio`. 2. Create a new `Many2many` custom field on a model such as `res.partner`. 3. Set the field's widget to `many2many_tags_email` and save the customization. 4. Exit Studio and populate the field with one or more
Original PR description
### Description of the issue/feature this PR addresses: - Opening Studio on a form containing a Many2many field using the many2many_tags_email widget crashes with an OWL prop validation error. -…
### Description of the issue/feature this PR addresses: - Opening Studio on a form containing a Many2many field using the many2many_tags_email widget crashes with an OWL prop validation error. - **Steps to reproduce:** 1. Open any form view (e.g., Contacts) and enter `Studio`. 2. Create a new `Many2many` custom field on a model such as `res.partner`. 3. Set the field's widget to `many2many_tags_email` and save the customization. 4. Exit Studio and populate the field with one or more related records. 5. Open Studio again on the same form view. This results in the following error: ```.js Error: Invalid props for component 'RecipientTag': 'onDelete' is undefined (should be a value) ``` ### Current behavior before PR: - When opening Studio on a form containing a `Many2many` field with the `many2many_tags_email` widget, the field is rendered with `onDelete` set to undefined by `Many2ManyTagsField`. Starting from `saas-19.1`, the `many2many_tags_email` widget uses the new [RecipientTag] component, which requires onDelete to be defined. As a result, Owl's prop validation fails when RecipientTag receives `onDelete = undefined`, causing Studio to crash with an I nvalid props for component 'RecipientTag' error. ### Desired behavior after PR is merged: - RecipientTag should allow onDelete to be optional so that it can also be used when the parent field does not provide a delete callback. This prevents the Owl prop validation error when opening Studio, while keeping the existing delete functionality unchanged for editable fields where onDelete is available. opw:6395209 [RecipientTag]: https://github.com/odoo/odoo/blob/saas-19.1/addons/mail/static/src/core/web/recipient_tag.js --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#277934
Reverse charge taxes (Inversione Contabile) should have the translated code ending with 'IC' (the acronym), not 'CI'. Suggested by partner: eLBati task-none Forward-Port-Of: odoo/odoo#277892 Forward-Port-Of: odoo/odoo#276270
Original PR description
Reverse charge taxes (Inversione Contabile) should have the translated code ending with 'IC' (the acronym), not 'CI'. Suggested by partner: eLBati task-none Forward-Port-Of: odoo/odoo#277892 Forward-Port-Of: odoo/odoo#276270
### Issue: When sending an invoice to KSEF, the `AdresL1` field in the XML contains the country name for both buyer and seller The KSEF portal already derives the country name from `KodKraju` (country code), causing it to appear twice on portal documents ### Cause: `_display_address` uses the default PL `address_format` which includes `%(country_name)s` The format is not overridden for the FA3 XML export context, so the country name is always appended to `AdresL1` ### Steps to reproduc
Original PR description
### Issue: When sending an invoice to KSEF, the `AdresL1` field in the XML contains the country name for both buyer and seller The KSEF portal already derives the country name from `KodKraju` (country code), causing it to appear twice on portal documents ### Cause: `_display_address` uses the default PL `address_format` which includes `%(country_name)s` The format is not overridden for the FA3 XML export context, so the country name is always appended to `AdresL1` ### Steps to reproduce: - Install `l10n_pl_edi` - Configure KSEF (see video on the ticket) - Create and send an invoice to KSEF - Check `AdresL1` in the generated XML Before the fix, `AdresL1` includes the country name The KSEF portal also shows the country name twice for both buyer and seller opw-6369708 Forward-Port-Of: odoo/odoo#275922
Steps to reproduce: ==== - Disable `Group Products in POS` on the product's UoM. - Create a sale order containing that product. - Settle the sale order in POS. Issue: ==== - Order lines are grouped even though grouping is disabled for the product's UoM. Cause: ==== - During the refactoring of `pos_stock`, the order line splitting logic was moved to `pos_sale_stock`. As a result, when `pos_sale_stock` is not installed, sale order lines are no longer split when settling a sale order.
Original PR description
Steps to reproduce: ==== - Disable `Group Products in POS` on the product's UoM. - Create a sale order containing that product. - Settle the sale order in POS. Issue: ==== - Order lines are grouped even though grouping is disabled for the product's UoM. Cause: ==== - During the refactoring of `pos_stock`, the order line splitting logic was moved to `pos_sale_stock`. As a result, when `pos_sale_stock` is not installed, sale order lines are no longer split when settling a sale order. Fix: ==== - Move the shared order line splitting logic to `pos_sale` so it is always applied when settling sale orders, regardless of whether `pos_sale_stock` is installed. task-6401619
After [commit](https://github.com/odoo/odoo/commit/b75074f43184a68ebffc2b7833695570966a9bdc) `google_address_autocomplete` fields are readonly true by default. but we need this to readonly=False in preset. we also make the error message more informative for user as the default geolocation service is sometimes inaccurate. So, failing to geolocate can occuer even if you have valid address <img width="1432" height="879" alt="image" src="https://github.com/user-attachments/assets/6e13a
Original PR description
After [commit](https://github.com/odoo/odoo/commit/b75074f43184a68ebffc2b7833695570966a9bdc) `google_address_autocomplete` fields are readonly true by default. but we need this to readonly=False in preset. we also make the error message more informative for user as the default geolocation service is sometimes inaccurate. So, failing to geolocate can occuer even if you have valid address <img width="1432" height="879" alt="image" src="https://github.com/user-attachments/assets/6e13a2fe-6655-436c-8de9-204feba6ee44" /> <img width="737" height="421" alt="image" src="https://github.com/user-attachments/assets/2c3032c2-c3b7-4ab7-8116-7876589a5fa2" /> opw-6377551 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Scenario: - create a website with main language different than en_US - create a website.page with some content - translate that page into English (en_US) - do some change in that page in original language => those changes are saved as delayed translations in en_US - from the backend, do a change in the corresponding view and save Result: the delayed changes in translation are lost and removed from all languages (even from the main website language). Cause: the backend view is displayed and sa
Original PR description
Scenario: - create a website with main language different than en_US - create a website.page with some content - translate that page into English (en_US) - do some change in that page in original language => those changes are saved as delayed translations in en_US - from the backend, do a change in the corresponding view and save Result: the delayed changes in translation are lost and removed from all languages (even from the main website language). Cause: the backend view is displayed and saved in en_US without the delayed changes. So if we modify the view and save, the view without the delayed change will be synced to all other languages which removes the delayed changes. opw-5938871 opw-6360011 Forward-Port-Of: odoo/odoo#278162 Forward-Port-Of: odoo/odoo#277070
`BuilderRange` supported inverted ranges (`props.min > props.max`) to keep the slider direction consistent across options, which was the case for the `Parallax to Bottom` (`min="-0.15" / max="-3"`) with `get min()`/`get max()` normalizing the bounds and `o_we_inverted_range` flipping the direction whenever `props.min > props.max` was detected. For the Bottom case, any value smaller than `-0.15` (e.g. `-1.5`) satisfied `value < props.min` and was clamped back to `-0.15`, making custom intensit
Original PR description
`BuilderRange` supported inverted ranges (`props.min > props.max`) to keep the slider direction consistent across options, which was the case for the `Parallax to Bottom` (`min="-0.15" / max="-3"`) with `get min()`/`get max()` normalizing the bounds and `o_we_inverted_range` flipping the direction whenever `props.min > props.max` was detected. For the Bottom case, any value smaller than `-0.15` (e.g. `-1.5`) satisfied `value < props.min` and was clamped back to `-0.15`, making custom intensities impossible. Since this is the only inverted `BuilderRange` in the codebase, we restored the right order for the min/max, dropped the getters and replaced them with a prop to apply the `o_we_inverted_range` class in this scenario only. task-6058500 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#255252
Because of this PR https://github.com/odoo/odoo/pull/235719 Audit Trail no longer functions as expected: 1) Tracking messages no longer show in the Audit Trail 2) Description is missing from Audit Trail This commit fixes these issues. task-6413110
Original PR description
Because of this PR https://github.com/odoo/odoo/pull/235719 Audit Trail no longer functions as expected: 1) Tracking messages no longer show in the Audit Trail 2) Description is missing from Audit Trail This commit fixes these issues. task-6413110
**PROBLEM** In some cases, third party checks are marked as being "on hand" but they are not. **CAUSE** We retrieve the last operation (accounting.payment) related to the check to determine the current journal of the check. To do this, we order the payment by date, then by write_date, and then by id. If the incoming and outgoing payment are done the same day, the last operation taken into account will be the one with the freshest write_date. If the incoming payment is modified, we wrongly c
Original PR description
**PROBLEM** In some cases, third party checks are marked as being "on hand" but they are not. **CAUSE** We retrieve the last operation (accounting.payment) related to the check to determine the current journal of the check. To do this, we order the payment by date, then by write_date, and then by id. If the incoming and outgoing payment are done the same day, the last operation taken into account will be the one with the freshest write_date. If the incoming payment is modified, we wrongly consider it as the last operation, assigning a journal to the check. **FIX** We check if there is more incoming operations than outgoing operations. If it's not the case, then the check is not on hand, so we remove the current journal. opw-6277377 Forward-Port-Of: odoo/odoo#275866
When selling a product with the Ship Later option the COGS for the product were not recorded properly. Steps to reproduce: ------------------- * Create a product with fifo and real_time valuation * Open PoS and add the product to the order * Validate the order and set the Ship Later option * Go to the backend and validate the picking of the order * Go check the journal entries of the session > Observation: It doesn't contain the COGS line. Why the fix: ------------ Since the stock
Original PR description
When selling a product with the Ship Later option the COGS for the product were not recorded properly. Steps to reproduce: ------------------- * Create a product with fifo and real_time valuation * Open PoS and add the product to the order * Validate the order and set the Ship Later option * Go to the backend and validate the picking of the order * Go check the journal entries of the session > Observation: It doesn't contain the COGS line. Why the fix: ------------ Since the stock_valuation refactoring the COGS are not created anymore when validating the picking of the order. opw-5965021 Forward-Port-Of: odoo/odoo#259714
**Description of the issue/feature this PR addresses:** [FIX] account: prevent access error for branch users When a user restricted to a branch company opens the accounting dashboard, they may encounter an AccessError preventing the app from loading. This occurs because the dashboard logic attempts to read the `fiscalyear_lock_date` from the journal's company. In a branch setup, this configuration often belongs to the parent company, which the user typically does not have read acc
Original PR description
**Description of the issue/feature this PR addresses:** [FIX] account: prevent access error for branch users When a user restricted to a branch company opens the accounting dashboard, they may…
**Description of the issue/feature this PR addresses:** [FIX] account: prevent access error for branch users When a user restricted to a branch company opens the accounting dashboard, they may encounter an AccessError preventing the app from loading. This occurs because the dashboard logic attempts to read the `fiscalyear_lock_date` from the journal's company. In a branch setup, this configuration often belongs to the parent company, which the user typically does not have read access to. The system then blocks the action and gives an AccessError. This commit resolves the issue by adding `.sudo()` when reading the `fiscalyear_lock_date`. This safely bypasses the record rule restriction, allowing the dashboard to fetch the necessary accounting configuration without requiring the user to have broad access to the parent company. **Steps to reproduce:** - As Mitchell Admin: - Settings > Users & Companies > Companies > My Company (San Francisco) > Branches > create a branch - Settings > Users & Companies > Users > Marc Demo > Access Rights > change “Companies” and “Default Company” to only the newly created branch - As Marc Demo: - Attempt to access Accounting app > observe Access Error **Current behavior before PR:** - Users belonging to only a branch company are unable to access the Accounting dashboard **Desired behavior after PR is merged:** - Users belonging to only a branch company are able to access the Accounting dashboard opw-6369616 Forward-Port-Of: odoo/odoo#277877
When an incoming move of an AVCO product is validated with outgoing moves in the same batch, `_set_value()` falls back to a full standard price recomputation through `_run_average_batch(force_recompute=True)`, which searches every valued move of the products since the beginning of the history (or since their last manual valuation). In that method, the line dropship_moves = moves.filtered(lambda m: m.is_dropship) reads `is_dropship` on the whole recordset. Each read prefetches *all*
Original PR description
When an incoming move of an AVCO product is validated with outgoing moves in the same batch, `_set_value()` falls back to a full standard price recomputation through `_run_average_batch(force_recompute=True)`, which searches every valued move of the products since the beginning of the history (or since their last manual valuation).
In that method, the line
dropship_moves = moves.filtered(lambda m: m.is_dropship)
reads `is_dropship` on the whole recordset. Each read prefetches *all* stored fields of `stock.move` for the records, and nothing invalidates the cache between batches. With a large history, this materializes the entire stock.move table slice in memory before ever reaching the carefully batched loop below ("PERF avoid memoryerror").
opw-6393223
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#276884During the _run_average_batch(), we call _get_value() on each dropship move on which an AVCO product is used. In this function, if the following condition is met, we call the function _get_manual_value(): https://github.com/odoo/odoo/blob/12dd03fb678870ddd3f1f8dca66aa3f934aa7985/addons/stock_account/models/stock_move.py#L359-L361 This method's goal is to search product.value records related to the current move. https://github.com/odoo/odoo/blob/12dd03fb678870ddd3f1f8dca66aa3f934aa7985/a
Original PR description
During the _run_average_batch(), we call _get_value() on each dropship move on which an AVCO product is used. In this function, if the following condition is met, we call the function…
During the _run_average_batch(), we call _get_value() on each dropship move on which an AVCO product is used. In this function, if the following condition is met, we call the function _get_manual_value(): https://github.com/odoo/odoo/blob/12dd03fb678870ddd3f1f8dca66aa3f934aa7985/addons/stock_account/models/stock_move.py#L359-L361 This method's goal is to search product.value records related to the current move. https://github.com/odoo/odoo/blob/12dd03fb678870ddd3f1f8dca66aa3f934aa7985/addons/stock_account/models/stock_move.py#L431-L447 This search is performed once per move selected previously even if they are not related to any product.value. We propose to cache the id of every move that is linked to at least one product.value to ensure the search method is only performed for those and potentially reduce the number of calls to the search method. Benchmark ------------ Reducing the execution time with this modification supposes that the majority of stock.move records are not linked to any product.value, which is usually the case. The following benchmark shows the execution times of _run_average_batch() depending on that. | No stock.move | No of moves linked to product.value | Before PR | After PR | |---------------|-------------------------------------|-----------|----------| | 100 | 10 | 1.03 s | 421 ms | | 1000 | 100 | 7.13 s | 1.14 s | | 10000 | 100 | 57.21 s | 1.55 s | | 10000 | 1000 | 60.42 s | 8.98 s | When every stock.move is linked to a product.value, the modification will introduce more operations than needed and slow down the execution. The following benchmark illustrates that. | No stock.move | Before PR | After PR | |---------------|-----------|----------| | 100 | 1.14 s | 1.15 s | | 1000 | 8.21 s | 8.37 s | | 10000 | 80.64 s | 81.51 s | opw-6050007 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#257619