Wednesday, September 2, 2026
38 changes · saas-19.2
Resolved issues and error corrections
Users adding a certificate key file without entering a password will no longer see an immediate error suggesting the password is wrong. The warning now appears only when a password was actually provided and is incorrect, making the certificate setup experience clearer and less confusing.
Original PR description
When adding a key file without entering a password, an error banner is immediately displayed, incorrectly suggesting that the password may be invalid. Only show the error banner when a password was provided and is incorrect. Also refactored the compute function to avoid repeated try-except blocks. task-6299175 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285744 Forward-Port-Of: odoo/odoo#283589
Refunds in Italian point of sale now take users to the payment page for the refund order, not the original sale or product screen. This prevents cashier confusion and helps complete fiscal-printer refund flows correctly.
Original PR description
**Issue**: 1. From versions 18.4 to 19.1 inclusive, the system redirects to the product screen; 2. From version 19.2 onward, the redirection targets the payment page of the original order instead of the refund order. **Expected behavior**: The system navigates to the payment page for the refund order. **Steps to reproduce**: - Set up an Italian fiscal printer; - Open a POS session and process an order; - Create a refund for the order. [Ticket link](https://www.odoo.com/odoo/project/49/tasks/6499079) opw-6499079 Forward-Port-Of: odoo/enterprise#129758
This update re-enables accounting valuation tests across inventory, purchasing, manufacturing, repairs, point of sale, and related project flows after a prior valuation refactoring. It also fixes two issues found by those tests, improving reliability of product costing and analytic accounting in affected business processes.
This fix stops Odoo from showing a false consumption warning when a serial-tracked component is bought on demand and received after the finished product serial number was assigned. Manufacturing orders can now be completed without confusing users when the correct component quantity was reserved and consumed.
Original PR description
Steps to reproduce the bug: - Warehouse configured for 2-Step Manufacturing - Component "C1": - Routes: MTO + Buy - Tracking: By Unique Serial Number - Create a Finished product: - Route: Manufacture…
Steps to reproduce the bug:
- Warehouse configured for 2-Step Manufacturing
- Component "C1":
- Routes: MTO + Buy
- Tracking: By Unique Serial Number
- Create a Finished product:
- Route: Manufacture
- Tracking: By Unique Serial Number
- BoM:
- component "C1": 1 unit
- Create and confirm the Manufacturing Order
- Generate/assign the serial number for the finished product immediately, before the related purchase order is even confirmed
- Confirm the Purchase Order
- Receive the component
- Transfer the component to WH/Pre-Production
- Click Produce All
Problem:
A Consumption Warning was displayed stating that the consumed quantity differs from the expected quantity, even though the consumed quantity was exactly equal to the BoM quantity and no manual quantity change was performed. Clicking "Set Quantities & Validate" completed the MO successfully, hiding the inconsistency.
`_get_consumption_issues()` only counts a raw move's quantity as "consumed" when `move.picked` is `True`
[(odoo/addons/mrp/models/mrp_production.py#L1791)](https://github.com/odoo/odoo/blob/19.0/addons/mrp/models/mrp_production.py#L1791).
Generating the finished product's serial number calls `_set_qty_producing()`
[(odoo/addons/mrp/models/mrp_production.py#L1402)](https://github.com/odoo/odoo/blob/19.0/addons/mrp/models/mrp_production.py#L1402).
, which itself only sets `move.picked = True` when `move.quantity` is truthy
[(odoo/addons/mrp/models/mrp_production.py#L1443)](https://github.com/odoo/odoo/blob/19.0/addons/mrp/models/mrp_production.py#L1443).
At that point the MTO component had not been received yet, so `move.quantity` was still 0 and `picked` was never set. Once the component was later received and transferred to Pre-Production, `_action_assign()` correctly reserved the raw move (`quantity` became correct), but nothing ever went back to flip `picked` to `True`, since `_set_quantities()`
[(odoo/addons/mrp/models/mrp_production.py#L2932)](https://github.com/odoo/odoo/blob/19.0/addons/mrp/models/mrp_production.py#L2932).
only calls `_set_qty_producing()` again when `qty_producing` is still falsy, which was no longer the case. `_get_consumption_issues()` therefore still counted the consumed quantity as 0 against the expected BoM quantity.
Solution:
In `pre_button_mark_done()`, for auto productions (single unit being produced), after `_set_quantities()` runs, also mark as `picked` any non-manual-consumption raw move that is not yet `picked` but whose reserved `quantity` already exactly matches its own `product_uom_qty`. This is scoped to auto productions only, since on a multi-unit production a raw move's aggregate `quantity` can equal its `product_uom_qty` by coincidence (reservation for future backorder steps) even though only part of it is meant to be consumed for the current step.
opw-6421531
Forward-Port-Of: odoo/odoo#281258This fix makes an automated website test step more stable by reusing a proven change from a newer version. It reduces random test failures, helping releases and maintenance checks run more smoothly without affecting end users directly.
Original PR description
This is just a backport of the step from 19.3 where the tour is never failing randomly. https://github.com/odoo/odoo/commit/c5d7a6a90be4730e18070826a9394ab10dfc6be8#diff-c7720501ec33f5f92c907d8bb41de50edd832a4564317073e801a6915796a6bdR260-R261 runbot-237566 Forward-Port-Of: odoo/odoo#284689
This fix makes Odoo's PDF tools expose a common PDF page object consistently across supported PDF library versions. It helps prevent version-specific test failures and improves internal reliability without changing user-facing behavior.
Original PR description
Prior to this commit, `PageObject` was not re-exported by `odoo.tools.pdf`, forcing tests to patch internal module paths like `PyPDF2._page.PageObject`. This resulted in test failures depending on the installed PDF library version: - `pypdf` (>= 3.0.0): `PyPDF2` submodules no longer exist. - `PyPDF2` 1.x: `PageObject` resides in `PyPDF2.pdf` rather than `PyPDF2._page`. To resolve this, this commit re-exports `PageObject` through `odoo.tools.pdf` across all backend wrappers. runbot-946795 Forward-Port-Of: odoo/odoo#285978
One-time purchases of products that can also be sold by subscription are now treated correctly in stock forecasts. This prevents standard sales from creating endless future demand, improving inventory planning and replenishment accuracy.
Original PR description
When a recurring product (with `allow_one_time_sale = True`) is sold as a one-time purchase (no subscription plan), the stock forecast report and replenishment logic incorrectly treat it as an active…
When a recurring product (with `allow_one_time_sale = True`) is sold as a one-time purchase (no subscription plan), the stock forecast report and replenishment logic incorrectly treat it as an active subscription. This results in infinite projected future outgoing moves for standard sales. This occurs because the logic only checks if `recurring_invoice` is True on the product, ignoring whether the parent order actually has a `plan_id`. This commit fixes the issue by: 1. Updating `_get_stock_subscription_lines` in `sale.order.line` to filter out lines using `_subscription_is_one_time_sale()`. 2. Updating the domains in `stock.forecasted_product_product` to require `order_id.plan_id != False` for subscription forecasts, while correctly routing one-time sales (`order_id.plan_id == False`) back to the standard sale domain. 3. Adapting existing tests to verify that one-time sales do not generate future subscription stock forecasts. Task-6193648 Forward-Port-Of: odoo/enterprise#116889
This fix makes Sign app tests work consistently with different supported PDF library versions. It reduces the risk of false test failures during upgrades or maintenance, helping keep Sign-related releases smoother without changing user-facing features.
Original PR description
Prior to this commit, `PageObject` was not re-exported by `odoo.tools.pdf`, forcing tests (such as `test_origin_offset_translation` in `sign`) to patch internal module paths like `PyPDF2._page.PageObject`. This resulted in test failures depending on the installed PDF library version: - `pypdf` (>= 3.0.0): `PyPDF2` submodules no longer exist. - `PyPDF2` 1.x: `PageObject` resides in `PyPDF2.pdf` rather than `PyPDF2._page`. To resolve this: - `PageObject` has been re-exported through `odoo.tools.pdf`. - Update `test_origin_offset_translation` to import `PageObject` via `odoo.tools.pdf` and use `patch.object` with standard attribute names (`cropbox`, `add_transformation`). runbot-946795 Forward-Port-Of: odoo/enterprise#130017
The website editor now keeps resize handles visible when editing animated content near the sidebar. This prevents the sidebar from covering part of the editing overlay, making it easier for users to resize and understand the position of animated page elements.
Original PR description
Steps to reproduce: - Drop a few snippets to make the page scrollable - At the bottom, drop the `s_three_columns` snippet - Click on the last Card - Add an animation "onScroll" (Effect - Slide, Intensity - 100) - Scroll top slightly to hide a part of the card behind the sidebar => The resize overlay is partially hidden The elements `.hb-row` have a z-index of 2, so they appear in front of the overlay which has a z-index of 1. It was decided to fully show the overlay to allow resizing. Keeping the overlay visible in front of the sidebar also allow the user to see where animated element is. task-6476269 Forward-Port-Of: odoo/odoo#283842 Forward-Port-Of: odoo/odoo#282796
The Peru POS receipt now hides extra electronic invoicing details, such as the amount in words and QR-related data, when the basic receipt option is used. This keeps simplified receipts concise while preserving the full information on standard receipts.
Original PR description
Step to reproduce - install l10n_pe_edi_pos with demo and switch to PE company - from settings> "Signature Provider" set it to SUNAT - create a pos, enable "Basic Receipt" from settings - open pos…
Step to reproduce - install l10n_pe_edi_pos with demo and switch to PE company - from settings> "Signature Provider" set it to SUNAT - create a pos, enable "Basic Receipt" from settings - open pos and fulfill a order - from feedback screen, print > print basic recipt Observation: - `Amount In Word` is visible in basic receipt, we should not show such info in basic receipt Cause: - commit [1] introduces the template `l10n_pe_edi_pos.pos_order_receipt`, which adds the info block to the receipt using xpath `<xpath expr="//div[contains(@t-if, 'use_self_invoicing')]" position="before">` - this inserts the block before the [target div](https://github.com/odoo/odoo/blob/1ace23afe8a937fc1dc53879f33ca591fd5d25b8/addons/point_of_sale/receipt/pos_order_receipt.xml#L70-L86), which is independent of the `basic_receipt` flag, causing the block to always be visible [1] https://github.com/odoo/enterprise/commit/a0c4f841cde0fcfda0a0c57f865f0eff6b6d6afe Fix: - place the block so it is shown only when `basic_receipt` is false - update the xpath expression to `prices` div ( here `basic_receipt` is false `//div[@name='prices']` with `position="inside"` After fix (for full receipt) <img width="257" height="349" alt="image" src="https://github.com/user-attachments/assets/3932cae1-3ceb-42ad-9ce4-16a9bd4fea7d" /> opw-6383358
Vendor bills created from incoming emails will no longer use the saved copy of the email as the main invoice attachment. This ensures the invoice preview points to the actual PDF or image document when one is extracted from the email, avoiding broken previews for accounting users.
Original PR description
When an incoming mail server has the "Keep Original" option enabled, a copy of every incoming mail is stored as original_email.eml. Because it is not a document of the invoice, the system unattaches…
When an incoming mail server has the "Keep Original" option enabled, a copy of every incoming mail is stored as original_email.eml. Because it is not a document of the invoice, the system unattaches it, however it may still be used as main attachment in case no other PDF or image was attached to the message. Steps to reproduce: - Configure an incoming mail server with "Keep Original" enabled, using an alias pointing to a vendor bill journal. - Send a mail to that alias containing an xml embedding a PDF. - Open that bill Issue: The invoice's main attachment points to the .eml file. This occurs because it is set before the PDF is extracted from the xml. Then, when import extracts the PDF, it is added as attachment on the invoice, but we already have a main attachment that won't be overwritten. However, once a pdf or image is added as attachment, the system will show the (broken) preview. opw-6431726 Forward-Port-Of: odoo/odoo#285409 Forward-Port-Of: odoo/odoo#280318
Forum information links now appear as regular links in the website editor instead of being treated like buttons. This prevents irrelevant button styling controls from appearing, making forum page editing clearer and less confusing.
Original PR description
Steps to reproduce: - Go to a forum page. - Open the website editor. - Select the "About this forum" link in the sidebar. => Button styling options are shown for a regular link. Before this commit, forum information links used button classes, which made the editor expose button styling options for them. After this commit, the `btn`, `btn-sm`, and `btn-link` classes are replaced with `small` so the editor treats these elements as regular links on desktop and mobile. task-6259086
This update fixes typos and wording inconsistencies in the Point of Sale LNA checklist. It improves the clarity and professionalism of the checklist without changing any business process or functionality.
Original PR description
Fixed some typos and inconsistencies on the LNA checklist document Task-[6330795](https://www.odoo.com/odoo/project/1737/tasks/6330795) 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#281950
Swiss payroll employee records will no longer show repeated, low-value history messages when pension-related records are refreshed. This keeps the employee chatter clearer and makes important updates easier to find, especially where automated hourly updates run often.
Original PR description
Calling `_create_or_update_snapshot` after writing on an employee recomputes `lpp_mutations`, deleting and recreating the linked records. Because `lpp_mutations` was tracked, every `write` on an employee generated unhelpful chatter entries, cluttering important history. This was especially noisy during frequent writes in hourly crons. Disable field tracking on `lpp_mutations` to improve chatter clarity and overall user experience. opw-6285407 --- Forward-Port-Of: odoo/enterprise#129628 Forward-Port-Of: odoo/enterprise#128033
This fixes an issue where manufacturing subcontracting receipts could create related accounting lines in an unpredictable order. The change makes processing consistent, improving reliability for automated tests and reducing the chance of inconsistent accounting display or matching behavior.
Original PR description
The search order on account move line depends on date, move name and id. This search result order can be non deterministic because, when creating account move line from stock valuation, it depends on…
The search order on account move line depends on date, move name and id. This search result order can be non deterministic because, when creating account move line from stock valuation, it depends on the order from a set, but sets are unordered. **Step to reproduce** Run [test_subcontracting_purchase_bill](https://github.com/odoo/odoo/blob/13b2781978b0edad0df0800404276919b767e32b/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py#L268) in: Single app, community, with demo data. **Observation** * The search: When doing the search since we didn't specify any order, the search from account.move.line will ordered by: https://github.com/odoo/odoo/blob/3dd41395e2e4205fa477eb474d4a4dba0a976154/addons/account/models/account_move_line.py#L23 https://github.com/odoo/odoo/blob/3dd41395e2e4205fa477eb474d4a4dba0a976154/addons/account/models/account_move_line.py#L1664 Since, for the components the date and move name are the same it will only depend on the aml ids: * `Account.move.line` creation: When it validate the receipt (`button_validate`) https://github.com/odoo/odoo/blob/869c750f978b1b00a4a04bd61226f0e20d2e7729/addons/mrp_subcontracting_purchase/tests/test_mrp_subcontracting_purchase.py#L296 It will mark as done the picking (`_action_done`) and the productions (`button_mark_done`) linked to this picking. https://github.com/odoo/odoo/blob/869c750f978b1b00a4a04bd61226f0e20d2e7729/addons/stock/models/stock_picking.py#L1429 https://github.com/odoo/odoo/blob/869c750f978b1b00a4a04bd61226f0e20d2e7729/addons/mrp_subcontracting/models/stock_picking.py#L49 Modify the inventory accordingly (`_post_inventory`) https://github.com/odoo/odoo/blob/869c750f978b1b00a4a04bd61226f0e20d2e7729/addons/mrp/models/mrp_production.py#L2231 while inside of `_post_inventory`, it will process all the production moves, for this it will divided them in set to process them by batch: https://github.com/odoo/odoo/blob/f0e58b9324af18d0cf0264aec2886d098e997f03/addons/mrp/models/mrp_production.py#L1904-L1911 From this set, it will create the `account.move.line`: It retrieve the actual stock move with the browse, and call `_action_done`, from where the stock valuation layer will create the `account.move.line`. https://github.com/odoo/odoo/blob/f0e58b9324af18d0cf0264aec2886d098e997f03/addons/mrp/models/mrp_production.py#L1913 https://github.com/odoo/odoo/blob/f0e58b9324af18d0cf0264aec2886d098e997f03/addons/stock_account/models/stock_move.py#L187 The issue arise because a set read order is non deterministic. runbot-939794 Forward-Port-Of: odoo/odoo#279396
Fixed an issue where spreadsheets containing inserted images could not be downloaded as Excel files. The export process now uses the required image access information, so users can reliably export spreadsheets with images included.
Original PR description
Since https://github.com/odoo/enterprise/pull/97488, the images are shared across spreadsheets and the attachments are no longer related to a specific record. Due to the management of the…
Since https://github.com/odoo/enterprise/pull/97488, the images are shared across spreadsheets and the attachments are no longer related to a specific record. Due to the management of the IrAttachment access rights, it means that those attachments are not accessible by anyone by default and we rely on the access_token to display them in the webclient. However, the method that builds the final xlsx file fetches the images from the server and did not use the access token, meaning that it could never access the attachment. Such situation raised a UserError that was caught by the webclient. How to reproduce: - As admin, create a spreadsheet and insert an image inside of it - try to download the spreadsheet as an xlsx file counterpart of https://github.com/odoo/enterprise/pull/126384 Task-6432724 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#279788
Adds test coverage to ensure spreadsheets shared or edited in Odoo can be exported to Excel correctly when they contain images. This helps prevent regressions that could affect users relying on spreadsheet exports with embedded visuals.
Original PR description
Counterpart of https://github.com/odoo/odoo/pull/279788 Task-6432724 Forward-Port-Of: odoo/enterprise#126384
This fixes an error that could appear when users reordered a long list of order lines spanning multiple pages and then chose to discard their changes. Users can now safely cancel those edits without being blocked by a technical validation error.
Original PR description
**Steps to reproduce:** - Create a quotation - Add order lines until reaching 200 (duplicating helps), save and ensure that the pager appeared (1-200/201) - Drag one of the lines with the handle to…
**Steps to reproduce:** - Create a quotation - Add order lines until reaching 200 (duplicating helps), save and ensure that the pager appeared (1-200/201) - Drag one of the lines with the handle to reorder them - Discard all changes (X shaped button) You will have an evaluation error **Behavior:** When loading a list of records exceeding the limit, only parts of the records are saved in `_cache`. When triggering a reordering of said list, all records need to be loaded including the ones on other pages: https://github.com/odoo/odoo/blob/d4eff7b14d37a9b59c95d304542a5a12629bc90b/addons/web/static/src/model/relational_model/static_list.js#L1139-L1149 `_getResIdsToLoad()` gets all Ids missing from the cache, these are then passed through `._createRecordDatapoint` and will then be stored in `_cache`. The issue is that the Datapoints are getting created with only `activeFields` as data, which in our case are `id` and `sequence` When discarding the changes `._checkValidity()`is called on each Datapoint: https://github.com/odoo/odoo/blob/d4eff7b14d37a9b59c95d304542a5a12629bc90b/addons/web/static/src/model/relational_model/record.js#L423-L429 And then `._isInvisible()` is called. This is where the issue happens, since only `sequence` and `id` are stored, when we try evaluate `combo_item_id`, which is the condition to see if sequence is invisible, `combo_item_id` is not found and we get an Evaluation Error. This commit prevents going into `._checkValidity()` by adding `this.isInEdition` to the check leading to it, requiring that the record is in 'edit' mode which is not the case for records created with `_createRecordDatapoint()` opw-6399024 Forward-Port-Of: odoo/odoo#281018
Mobile users can now drag and drop table cells in the HTML editor without the action being interrupted by browser touch behavior. This improves editing reliability when working with tables inside Todo items on phones or tablets.
Original PR description
Steps to Reproduce - Insert a table inside a Todo item. - Long-press the table menu to open the drag-and-drop overlay. - Try to drag and drop table cells. Issue: - Table cells cannot be dragged and dropped on mobile devices. Cause: - On mobile devices, the browser fires `pointercancel`/`pointerleave` during a drag operation, which ends the drag operation prematurely. As a result, subsequent `pointermove` events are not triggered causing the drag-and-drop operation to fail. Solution: - Add `touch-action: none` to the table menu element. This prevents the browser default touch handling from interfering with the drag operation, allowing `pointermove` events to continue and drag-and-drop to work correctly on mobile devices. task-6201176 Forward-Port-Of: odoo/odoo#267680
French e-invoicing now ignores PDP response records that do not include a valid tracking identifier. This prevents scheduled PEPPOL status updates from failing and helps invoices and vendor bills continue processing reliably.
Original PR description
Steps to reproduce: - Install `l10n_fr_pdp` and `l10n_be` module - Activate `French e-invoicing` (you need to put your DB in test mode) (i.e: `account_peppol.edi.mode = 'test'` in system parameter)…
Steps to reproduce:
- Install `l10n_fr_pdp` and `l10n_be` module
- Activate `French e-invoicing` (you need to put your DB in test mode)
(i.e: `account_peppol.edi.mode = 'test'` in system parameter) Refer this Documentation https://www.odoo.com/documentation/19.0/applications/finance/fiscal_localizations/france.html?highlight=e%20invoicing#localizations-france-e-invoicing-fac-elec-config
- Create a Invoice and Sent with `E-invoicing`
- Run `PEPPOL: retrieve new documents` Cron
- In Invoice Other Info > `E-Invoicing Status` should be in `Done` state
- Now Vendor Bill is created for that invoice > Cancel that bill with reason > Check `E-Invoicing Status` response for bill(one response will be without UUID)
- Go to schedule actions > `PEPPOL: update message status`
- Run it and get the traceback: `KeyError: 'false'`
Issue:
When sending a lifecycle response to the French PDP, `_pdp_send_response` calls the `/api/pdp/1/send_response` endpoint and expects IAP to return a `message_uuid` for each response.
However, IAP return a response without a message UUID, for example: ` {'messages': [{'message_uuid': False}]}` `_pdp_send_response` currently assumes that every returned message has a valid UUID and creates an `account.peppol.response` with:
```
'peppol_message_uuid': False
'peppol_state': 'processing'
```
This leaves an `account.peppol.response` in `processing` state without a UUID that can be used to track it.
During the next execution of `_cron_peppol_get_message_status`, `_peppol_get_message_status` retrieves this response through `_peppol_get_documents_for_status` and builds `uuid_to_record` using `peppol_message_uuid` as the key. The resulting mapping contains the Python value `False` as a key.
The cron then calls the PDP `1/get_document` endpoint with this invalid UUID. IAP returns it as the string `'false'`, which is passed to `_peppol_process_messages_status`. The French PDP implementation tries to retrieve the corresponding record with: `uuid_to_record[uid]`
Since the mapping contains `False` while `uid` is `'false'`, this raises: `KeyError: 'false'`
This failure prevents the status cron from completing the processing of the messages.
Solution:
Avoid creating the `account.peppol.response` when IAP does not return a `message_uuid`. A response without a UUID cannot be tracked through the PDP status flow, so creating it in `processing` state only leaves an
invalid record that will later cause the status processing to fail.
opw-6453133
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#281691This fix ensures project forecasting can automatically plan work correctly when several roles are involved. It helps teams get more reliable planning results and reduces manual corrections in resource scheduling.
Original PR description
task-6484707 Forward-Port-Of: odoo/enterprise#128541
This fix stops users from creating order boxes directly from printer settings. Order boxes must be paired with a real physical device, helping avoid incorrect setup and operational issues in self-ordering flows.
Original PR description
We prevent users from creating oboxes from pos.printer model, as oboxes should be paired with an actual device. Forward-Port-Of: odoo/enterprise#129960
This fix connects the Greek electronic invoicing module to the translation system. It ensures the module can be translated through Odoo’s standard process, improving language coverage for Greek localization users.
Original PR description
Commit https://github.com/odoo/odoo/commit/45bd522dde7a67194e14a40d66944a2e34d1f79d introudced a new module without it's related `weblate.json` entry. This commit fixes this omission. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285570
This fix prevents Helpdesk from using outdated email alias information when opening tickets from a team record. Users can now navigate from an alias to its related Helpdesk Team and open the Tickets view without encountering an error.
Original PR description
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe…
### Steps to Reproduce: 1. In Debug mode, go to Aliases 2. Click on any active Alias, ex. customer-care 3. Click on "Open Parent Document" smart button 4. Click on "Tickets" smart button and observe error ### Description of the issue/feature this PR addresses: **Issue:** When navigating from an email alias to its parent document (e.g., a Helpdesk Team), the web client incorrectly retains the `active_id` and `active_model` of the alias in the context. **Solution:** We updated the `action_view_ticket` method in `helpdesk.team` to explicitly inject the correct `active_model` and `active_id` into the context before calling `_for_xml_id`. This overwrites the polluted Alias data before the window action is evaluated. ### Current behavior before PR: Clicking the "Tickets" smart button passes the old alias context into the action. This bad data flows into the ticket view, which attempts to look up a Helpdesk Team using the Alias's ID to generate the empty list help message, resulting in a `MissingError`. ### Desired behavior after PR: The Python action sanitizes the context at the source, ensuring that the XML action and subsequent view evaluations receive the correct Helpdesk Team ID. Ultimately, the view will load normally without crashing. opw-6395638 Forward-Port-Of: odoo/enterprise#129939 Forward-Port-Of: odoo/enterprise#125232
This fix prevents certain make-to-order manufacturing orders from producing or valuing finished goods incorrectly after quantities are changed following split and merge operations. It ensures production quantities are divided correctly across related finished-goods records and avoids validation errors for average or FIFO-valued products.
Original PR description
When the quantity of a make-to-order manufacturing order is changed, its finished move is copied to propagate the extra quantity downstream. In some cases (after splitting then merging back…
When the quantity of a make-to-order manufacturing order is changed, its finished move is copied to propagate the extra quantity downstream. In some cases (after splitting then merging back productions) that copy is not merged back, so the order ends up with two finished moves for the same product. On validation, two things then go wrong: - _post_inventory writes the produced quantity on each finished move, so both get the full quantity and the production is doubled - mrp_account._cal_price prices the finished move and calls ensure_one(), which raises "Expected singleton" for an average/fifo product, so "Produce All" fails Split the produced quantity across the finished moves with unit_factor (like _set_qty_producing already does), and price them as a whole instead of expecting a single finished move. Steps to reproduce: - Create a BoM for product A with the MTO route, and a component B - Create a Sale Order for 30 units of A, confirm it - Split the MO into 3 productions of 10, merge two of them - On the third, Update Quantity 10 -> 15, then Produce All - The product should be produced once (15, not 30), with A valued in average/fifo it instead of an error. opw-6242504 opw-6310972 opw-6307025 opw-6354739 Forward-Port-Of: odoo/odoo#282596 Forward-Port-Of: odoo/odoo#269254
This update ensures the Indian stock localization installs the required accounting-related stock component so related forms work correctly in isolated app tests. It prevents setup or test failures caused by a missing field dependency, with no expected change to normal business workflows.
Original PR description
The view 'l10n_in_ewaybill_stock.view_picking_form_inherit_ewaybill' is broken in single-app tests because it depends on stock.picking:country_code. That field is provided by module 'stock_account' through auto_install relationship. 'stock_account' auto_installs with 'stock' and 'account' installed. This condition exists on stable so it's safe to add this dependency. The dependency is added to l10n_in_stock because it seemed like the logical place where 'account' and 'stock' functionality comes together. [l10n_in_ewaybill_stock] ──[depends]──> [l10n_in_stock] [l10n_in_stock] ──[depends]──> [stock] [l10n_in_stock] ──[depends]──> [l10n_in] ──[depends]──> [account_tax_python] ──[depends]──> [account] REF Runbot: https://runbot.odoo.com/odoo/error/945482 Forward-Port-Of: odoo/odoo#284990
When users paste a new URL over a fully selected link whose visible text matches its address, the editor now replaces both the destination and the displayed text. This prevents documents from showing an outdated URL label while pointing to a different address.
Original PR description
**Current behavior before PR:** Steps to reproduce the issue: - Create a link via typing a valid URL + space. - Copy/Paste a different URL from the browser. - Select the entire link you just created. - Paste the copied URL on top of it. Notice that the label is still the old URL even though the URL actually changed. This happens because after commit [1] When pasting a URL over an active text selection, selected content is converted into a link pointing to the pasted URL. This should not be the case if selected content is a link with same label and URL. **Desired behavior after PR is merged:** If a link is entirely selected and its label is the same as URL then it should replace the existing link label with new URL. [1]: https://github.com/odoo/odoo/commit/d356043a67e1d7291bd1302b1e90a2d9a07718da task-6456004 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#281700
Applying text color in the HTML editor now affects only the exact selected text, even when the selection crosses bold or other inline formatting. This prevents unintended coloring of nearby text and keeps edited content formatting accurate.
Original PR description
Problem: When applying color on a selection that spans across partially selected inline elements (e.g. `<p><b>a[b</b>c]d</p>`), container elements whose contents are not fully selected (such as…
Problem: When applying color on a selection that spans across partially selected inline elements (e.g. `<p><b>a[b</b>c]d</p>`), container elements whose contents are not fully selected (such as `<b>`) were included in `targetedNodes`. This caused improper color formatting/nesting on partially selected elements. Cause: In `ColorPlugin._applyColor()`, `targetedNodes` were filtered by checking `isNodeEditable(node)` and `nodeName !== "T"`, but did not check whether the contents of `node` were fully selected (`areNodeContentsFullySelected(node)`). As a result, partially selected ancestor elements were included in `targetedNodes`. Solution: Filter `targetedNodes` in `_applyColor()` using `this.dependencies.selection.areNodeContentsFullySelected(node)` to ensure only fully selected nodes are targeted when applying colors. Steps to reproduce: 1. Open html_editor. 2. Insert content: `<p><b>ab</b>cd</p>`. 3. Select `b` inside `<b>` and `c` inside `<p>` (`<p><b>a[b</b>c]d</p>`). 4. Apply text color (e.g. red). 5. Observe "ab" and "c" was colored instead of just "b" and "c". task-6456443 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#285658 Forward-Port-Of: odoo/odoo#281462
The point of sale now hides quotations that have already been settled, preventing staff from accidentally selecting and paying the same quotation twice. This reduces duplicate settlement errors and keeps sales records cleaner.
Original PR description
Once a quotation is settled, opening the quotation list should not allow selecting it again. This commits updates the domain to prevent it. task-6479356 Forward-Port-Of: odoo/odoo#284768
Users can now open WhatsApp Business account settings when using translated languages such as French (Belgium). The fix prevents a language-related page error, helping administrators manage WhatsApp configuration reliably across locales.
Original PR description
Currently, an error occurs when a user tries to view the WhatsApp Business account. **Steps to Reproduce:** - Install the `whatsapp_oauth` module. - Go to `Settings` > `Languages` and add `French…
Currently, an error occurs when a user tries to view the WhatsApp Business account. **Steps to Reproduce:** - Install the `whatsapp_oauth` module. - Go to `Settings` > `Languages` and add `French (BE)`, then `switch to it`. - Go to `WhatsApp` > `Configuration` > `WhatsApp Business Accounts (Comptes Whatsapp Business)`. `ValueError: L'élément '<xpath expr="//div[contains(normalize-space(.), 'Receiving Messages')]">' ne peut être localisé dans la vue parente` When the user changes the language, the text in the view is translated [1]. Since the WhatsApp account view tries to locate the div using the plain text Receiving Messages [2]. Since the text has been translated in the parent view, the XPath can no longer locate the element and raise the error. This commit ensures that the XPath uses the name attribute to identify the element, which is language-independent. We cannot use the class attribute because the same class is used by other div elements. [1]- https://github.com/odoo/enterprise/blob/a3db72899cb97612505aebbd5450aeb65205db73/whatsapp/views/whatsapp_account_views.xml#L81-L84 [2]- https://github.com/odoo/enterprise/blob/a3db72899cb97612505aebbd5450aeb65205db73/whatsapp_oauth/views/whatsapp_account_views.xml#L61-L63 7534862409 Forward-Port-Of: odoo/enterprise#130003
Fixes an issue where expanding a newly created calendar event opened a blank form instead of the event just created. This prevents users from accidentally creating duplicate events for the same time slot.
Original PR description
Problem: In Calendar, dragging a slot opens the quick create dialog. Typing a subject and clicking the expand button in the dialog header creates the event, but the form that opens is empty, and…
Problem: In Calendar, dragging a slot opens the quick create dialog. Typing a subject and clicking the expand button in the dialog header creates the event, but the form that opens is empty, and saving it creates a second event for the same slot. Cause: `FormViewDialog` stores the id of the record it saved in `currentResId`, which `onExpand` passes as `res_id`. `saveRecord` sets it only in the branch that runs when no `onRecordSave` prop is given. `AttendeeCalendarController` passes one since 30478fe855cd (odoo/odoo#239435), so `currentResId` stays false and the action opens a new record. Solution: Set `currentResId` in the shared branch of `saveRecord`. It is private to `FormViewDialog`, so a consumer passing `onRecordSave` cannot set it. Steps to reproduce: - Open Calendar. - Drag a slot in the week view to open the quick create dialog. - Type a meeting subject. - Click the expand button in the dialog header. - Observe that the form opens on a new record while the event is created. Ticket [link](https://www.odoo.com/odoo/project/49/tasks/6476930) opw-6476930 Forward-Port-Of: odoo/odoo#285899
The link popover no longer shows a non-working wand icon when an image has a link. This removes a confusing control and makes editing linked images clearer for users.
Original PR description
**Current behavior before PR:** Steps to reproduce the issue: - Add an image - Add a link to the image - Put cursor just right after the image link so that link popover is opened - Notice that there is a wand icon in link popover to replace title, clicking on it does nothing **Desired behavior after PR:** There should be no replace title icon in popover for image-link. task-6420902 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#279076
Fixed a problem that could block users from sending certain Peruvian invoices to SUNAT when the document type was not supported. Instead of showing a confusing system error, Odoo now presents the appropriate validation message so users can correct the invoice.
Original PR description
Currently, an exception is raised when a user attempts to send an invoice to SUNAT using the `Send to SUNAT` option and the invoice is not a valid LATAM document code. Error: `XMLSyntaxError Start…
Currently, an exception is raised when a user attempts to send an invoice to SUNAT using the `Send to SUNAT` option and the invoice is not a valid LATAM document code. Error: `XMLSyntaxError Start tag expected, '<' not found, line 1, column 1 (<strin...` This issue originates from the recent refactoring in [1]. When the LATAM document type is unsupported, or when invoice export fails, `_l10n_pe_edi_generate_invoice_bstr()` returns an error message instead of valid XML (see [2]). The result is subsequently passed to `objectify.fromstring()`(see code ref [3]), which expects a valid XML payload. As a consequence, XML parsing fails and an exception is raised. This commit fixes the issue by updating `_l10n_pe_edi_generate_invoice_bstr()` to return the generated XML content and any associated errors separately, instead of returning an error message as the XML payload. This prevents error messages from being processed as XML and allows them to be properly surfaced to the user as validation errors, rather than causing an exception during XML parsing (see [4]). [1]: https://github.com/odoo/enterprise/commit/ec7160d3d0871794ed592354fff00fd64797e302#diff-832d0127b086c66c0d5800028ee92f007e33f6c1052c6f16a1709f29da1186f9 [2]: https://github.com/odoo/enterprise/blob/5ddef3263d4d9788b894ea465fb183e53d4c9e89/l10n_pe_edi/models/account_move.py#L1092-L1104 [3]: https://github.com/odoo/enterprise/blob/db85dcfcf2afb584bc40d3a4fb94c4838bd355c9/l10n_pe_edi/models/account_move.py#L535 [4]: https://github.com/odoo/enterprise/blob/5ddef3263d4d9788b894ea465fb183e53d4c9e89/l10n_pe_edi/models/account_move_send.py#L80-L84 sentry-7554239976
Accountants without company access-rights permissions can now generate BOE files for Spanish Modelo tax reports without seeing an access error. This removes an unnecessary permission requirement, helping accounting teams complete tax filing exports without administrator intervention.
Original PR description
Users who only have accounting rights (not the Settings > Users Companies > Access Rights group) get an access error on the Companies model when generating the BOE file for the Modelo 115 tax…
Users who only have accounting rights (not the Settings > Users Companies > Access Rights group) get an access error on the Companies model when generating the BOE file for the Modelo 115 tax reports, even though exporting a BOE file has nothing to do with editing company configuration and should be available to any accountant. Steps to reproduce: ------------------- * Log in as a user with accounting rights only (not part of the Companies > Access Rights group) * Go to Accounting > Reporting > Tax Return, open the Mod 115 report * Click the gear icon > BOE > Generate BOE > Observation: An AccessError is raised: "You are not allowed to modify 'Companies' (res.company) ... This operation is allowed for the following groups: Access Rights", even though the user is not trying to edit the company. Why the fix: ------------ The BOE wizard shared by Mod 111/115/303 declares a `company_partner_id` field, related to `company_id.partner_id`, with `readonly=False`. That field is invisible in every view and only exists to compute the domain of `partner_bank_id`; it was never meant to be edited by the user. Because it is declared writable, the ORM attaches an inverse to the related field, so saving the wizard (which happens when generating the BOE, since the field, though invisible, is still part of the view and thus of the saved values) writes `company.partner_id` back onto `res.company`, even though the value never actually changes. That implicit write requires write access on res.company, which is only granted to the Access Rights group, causing the error for regular accountants. Dropping `readonly=False` keeps the field as a plain readonly related field, still usable for the bank account domain, without ever triggering that spurious write. opw-6388869 Forward-Port-Of: odoo/enterprise#129924 Forward-Port-Of: odoo/enterprise#126661
This fix prevents an error when users customize worksheet templates in Studio after company-specific template data is migrated from older versions. It ensures the correct worksheet template is selected, so businesses with multiple companies can continue editing templates without crashes.
Original PR description
Since `company_id` on `worksheet.template` changed due to this a973d7d from a Many2many to a Many2one field. For example, in v17, a single worksheet template linked to 3 companies via the m2m field…
Since `company_id` on `worksheet.template` changed due to this a973d7d from a Many2many to a Many2one field.
For example, in v17, a single worksheet template linked to 3 companies via the m2m field was returned as 1 record when opening Design Template. After the upgrade in v18, company_id became m2o, and the same data is split into 3 separate records (one per company).
When trying to add a customization via Studio, the search [fetches](https://github.com/odoo/enterprise/blob/18.0/worksheet/controllers/main.py#L12) records based on the model set on the worksheet. In the new version, Studio
[creates](https://github.com/odoo/enterprise/blob/18.0/worksheet/models/worksheet_template.py#L112)
a new model, but for existing records the
model is the same across the 3 worksheet records tied to the same template. This causes the search to match all 3 records and raise a SingletonError.
```py
Traceback (most recent call last):
File "/home/odoo/src/odoo/19.0/odoo/http.py", line 2856, in __call__
response = request._serve_db()
File "/home/odoo/src/odoo/19.0/odoo/http.py", line 2331, in _serve_db
raise self._update_served_exception(exc)
File "/home/odoo/src/odoo/19.0/odoo/http.py", line 2329, in _serve_db
return service_model.retrying(serve_func, env=self.env)
File "/home/odoo/src/odoo/19.0/odoo/service/model.py", line 188, in retrying
result = func()
File "/home/odoo/src/odoo/19.0/odoo/http.py", line 2384, in _serve_ir_http
response = self.dispatcher.dispatch(rule.endpoint, args)
File "/home/odoo/src/odoo/19.0/odoo/http.py", line 2599, in dispatch
result = self.request.registry['ir.http']._dispatch(endpoint)
File "/home/odoo/src/odoo/19.0/odoo/addons/base/models/ir_http.py", line 353, in _dispatch
result = endpoint(**request.params)
File "/home/odoo/src/odoo/19.0/odoo/http.py", line 838, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/odoo/src/enterprise/19.0/industry_fsm_report/controllers/main.py", line 9, in edit_view
action = super().edit_view(view_id, studio_view_arch, operations, model, context)
File "/home/odoo/src/odoo/19.0/odoo/http.py", line 838, in route_wrapper
result = endpoint(self, *args, **params_ok)
File "/home/odoo/src/enterprise/19.0/worksheet/controllers/main.py", line 17, in edit_view
worksheet_template_to_change._generate_qweb_report_template()
File "/home/odoo/src/enterprise/19.0/worksheet/models/worksheet_template.py", line 490, in _generate_qweb_report_template
new_arch = self._get_qweb_arch(worksheet_template.model_id, report_name, form_view_id)
File "/home/odoo/src/enterprise/19.0/worksheet/models/worksheet_template.py", line 460, in _get_qweb_arch
if 'name' in row_node.attrib and row_node.attrib['name'] not in self._get_qweb_arch_omitted_fields() and row_node.attrib['name'] in form_view_fields:
File "/home/odoo/src/enterprise/19.0/worksheet/models/worksheet_template.py", line 378, in _get_qweb_arch_omitted_fields
'x_%s_id' % self.res_model.replace('.', '_'), 'x_name', # redundant
File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 1657, in __get__
record.ensure_one()
File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5942, in ensure_one
raise ValueError("Expected singleton: %s" % self)
ValueError: Expected singleton: worksheet.template(3, 14, 18)
```
OPW: 6389190
Forward-Port-Of: odoo/enterprise#127463
Forward-Port-Of: odoo/enterprise#126773Fixes an issue where pressing Enter in a bulleted list item containing a table would not split the bullet as expected. Users can now edit text before or after embedded tables in lists more naturally, while empty list items are handled more safely.
Original PR description
### Steps to reproduce: - Insert a bullet list - Inside of the list, insert a table - Write before and/or after the table (in the same list item) - Press enter before and/or after the inserted text - Notice that the bullet is not split like in a normal list ### Root Cause: - On Enter, list plugin checked whether the list item contained unsplittable element. Since the table was inside the list item, it always treated the list item as unsplittable, even when the cursor was outside the table. As a result, the list item could never be split. ### Solution: - Instead of checking the whole list item, walk up from the split target to the list item and look for an unsplittable element along the way. This allows the list item to split normally when the cursor is outside the unsplittable. task-6449843 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#284711 Forward-Port-Of: odoo/odoo#280903
Project profitability reports now include the cost of goods sold for delivered products when Anglo-Saxon accounting and analytic accounting are enabled. This gives users a more accurate view of project margins by preventing matching accounting entries from hiding the actual product cost.
Original PR description
**Problem:** Since this PR https://github.com/odoo/odoo/pull/261798, both cogs lines have an analytic account, which causes the cogs to not appear on the project profitability report because cogs…
**Problem:** Since this PR https://github.com/odoo/odoo/pull/261798, both cogs lines have an analytic account, which causes the cogs to not appear on the project profitability report because cogs lines balance each other **Steps to reproduce:** - enable 'anglo saxon accounting' and 'analytic accounting' settings - create a storable product with automated std category, a cost of 10 and on hand quantity - create a service product and set the 'create on order' field to 'project' - confirm a SO for 1 unit of the product and 1 unit of the service - validate the delivery and create and confirm invoice - from the sale order, click on the project smart button - from the project click on the dashboard smart button **Current behavior:** the cogs section don't appear in the profitability report **Expected behavior:** it should appear with a line with a value of -10 **Cause of the issue:** since this PR https://github.com/odoo/odoo/pull/261798, both cogs line are linked to the analytic account. That's the expected behaviour but in the case of the project profitability reports, it prevents the user the see the cost of the product in the cogs section. That's because, inside the _get_revenues_items_from_invoices() method, bot cogs_line are added to the cogs_line list. https://github.com/odoo/odoo/blob/141cb292dc5e456161119e19f7a91665feaa0198/addons/sale_project/models/project_project.py#L699-L700 So when computing the amount_to_invoice for the costs ml_type, the balance of the lines will zero out each other and amount_to_invoice will be 0. https://github.com/odoo/odoo/blob/141cb292dc5e456161119e19f7a91665feaa0198/addons/sale_project/models/project_project.py#L703-L716 As a consequence, the cost of goods sold section won't be created https://github.com/odoo/odoo/blob/141cb292dc5e456161119e19f7a91665feaa0198/addons/sale_project/models/project_project.py#L718-L719 **fix:** only the line with an account of internal type 'expense' reflects the actual cost of the product sold in the context of the project. So when computing the profitability report that's the only line we should consider **test:** test_report_invoice_items_anglo_saxon_automatic_valuation checks that the cogs section is well displayed in the project profitability report. In the PR (mentionned above) which sets the analytic account on the stock cogs line, lines were added in the test to manually remove the analytic account on the stock cogs line to make the test pass. With the fix of this PR we can remove those additional lines in the test and it will check our use case well again. opw-6412409 Forward-Port-Of: odoo/odoo#284270 Forward-Port-Of: odoo/odoo#283144
This fixes an unreliable automated test for the ReferenceField autocomplete in the web module. It helps prevent false build failures caused by timing delays, improving confidence in release validation without changing user-facing behavior.
Original PR description
The test is non-deterministic and fails with the runbot error:
found 0 elements instead of 1:
0 matching ".ui-autocomplete .ui-menu-item:nth-child(2)"
if there is even a 100ms network delay. clear() dispatches input events, but without flushing the timers, the dropdown state at the time of click(".o_field_reference input") can be out of sync causing no menu items to render and failing the test.
This change makes the sequence deterministic without changing the assertions:
1. runAllTimers() clears the timers and allows the clear of the input to fully go through.
2. click(".o_form_view") unfocus the input so the next click of the input refocuses and triggers the menu opening.
3. checking contains on the dropdown children ensures the menu items can render before click.
runbot error: 940222Original PR description
*: stock_landed_costs, purchase_{stock,mrp}, stock_dropshipping, sale_mrp, pos_mrp, repair, mrp_landed_costs, mrp_subcontracting_{dropshipping,landed_costs}, point_of_sale, {project_,}stock_account…
*: stock_landed_costs, purchase_{stock,mrp}, stock_dropshipping, sale_mrp, pos_mrp, repair, mrp_landed_costs, mrp_subcontracting_{dropshipping,landed_costs}, point_of_sale, {project_,}stock_account
Adapts the test skipped to fast merge the valuation refactoring made in https://github.com/odoo/odoo/commit/08b62a4bbcc6f9a391b2cc00a621ef4c76100229.
<img width="482" height="297" alt="table" src="https://github.com/user-attachments/assets/ba57f350-2a9e-4a51-990d-fabe14f5a56a" />
(*) Includes the one sale_project_stock_account test re-enabled through the TestAnalytics subclass.
It is organised as one commit per module. Two of the re-enabled tests surfaced genuine bugs in the new valuation model; those commits also carry the related fixes: purchase_mrp, project_stock_account Every other commit changes tests-only.
Only one skipped test remains: point_of_sale TestUi.test_05_ticket_screen, a browser tour with no stock-valuation content that was swept into the mass skip by mistake and fails for an unrelated reason (it is left to a separate point-of-sale tour investigation).
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#277339
Forward-Port-Of: odoo/odoo#275246