Daily updates from Odoo
Monday, August 11, 2025
26 changes · saas-18.4
Resolved issues and error corrections
Purchase orders created outside the standard purchase screen now correctly use the supplier’s preferred currency instead of defaulting to the company currency. This prevents incorrect currency selection when purchase orders are generated from workflows such as approvals.
Original PR description
Steps to reproduce: - Go to Invoicing > Configuration > Accounting > Currencies: - Enable the Euro currency - Set company currency to USD - Go to any partner form (e.g. Azure Interior): - In Sales &…
Steps to reproduce:
- Go to Invoicing > Configuration > Accounting > Currencies:
- Enable the Euro currency
- Set company currency to USD
- Go to any partner form (e.g. Azure Interior):
- In Sales & Purchase tab: - Set Supplier Currency to Euro
- Create a purchase order from the UI:
- Select Azure Interior → Currency is correctly updated to Euro (via onchange)
- Install the Approvals module
- Create a storable product "P1":
- Under Purchase tab: - Vendor: Azure Interior - Price unit: 5 EUR
- Create an approval request:
- Request Owner: Marc Demo
- Product: P1
- Approver: Mitchel Admin
- Submit and approve the request
- Click on "Create Purchase Order"
Issue:
The purchase order is created with the correct partner and product. But the currency is incorrectly set to the company currency (USD), instead of the supplier's currency (Euro).
Cause:
The currency was updated via an `@onchange`, which is only triggered in the UI.
When creating a PO programmatically (e.g. via approvals or in a test), the onchange is not executed and the currency falls back to the company default.
Solution:
Replace the `@onchange` logic for `currency_id` with a stored compute field.
This ensures that the correct currency is always computed, regardless of how the purchase order is created.
opw-4938390
Forward-Port-Of: odoo/odoo#222235
Forward-Port-Of: odoo/odoo#221907This change reverts a previous adjustment to editor avatars because it caused an unexpected horizontal scroll area in forms. Reverting it restores the expected form layout while the team prepares a better solution for the original avatar overlap issue.
Original PR description
This reverts commit 72acbe0 because of unexpected horizontal inner scroll on `o_form_sheet_bg` element. A better fix will be found in the futur. Forward-Port-Of: odoo/odoo#222162
This fixes an issue where sales order line prices could stay unchanged after increasing the quantity, even when a pricelist rule should apply a lower price. Businesses using quantity-based pricelists can now rely on accurate pricing without manually switching pricelists or forcing an update.
Original PR description
**Steps to reproduce**: 1. Install the `sale` module. 2. Enable `Pricelists` under `Settings > Sales > Pricing > Pricelists`. 3. Create two pricelists: - Pricelist A with two fixed-price rules: -…
**Steps to reproduce**:
1. Install the `sale` module.
2. Enable `Pricelists` under `Settings > Sales > Pricing > Pricelists`.
3. Create two pricelists:
- Pricelist A with two fixed-price rules:
- `0.75` for quantity ≥ 0
- `0.50` for quantity ≥ 1000
- Pricelist B with a `-10%` discount applied to Pricelist A.
4. Create a Sales Order using Pricelist B.
5. Add a product to the order line.
6. Increase the quantity to 1000.
**Observed behavior**:
- The unit price does not update according to the pricelist rule for quantity ≥ 1000.
- If you switch the pricelist to another and then back again, the `Update prices` button appears and correctly updates the price.
**Root cause**:
- The price is not recomputed when the quantity changes because the `price_unit` is not updated because it does not match the `technical_price_unit`.
- Since PR [#21392](https://github.com/odoo/odoo/pull/213912), `price_unit` is rounded (2 decimals), but `technical_price_unit` is not. This causes a mismatch in comparison logic due to rounding differences.
**Solution**:
- Replace direct float comparison with `currency_id.compare_amounts()` to ensure proper comparison with rounding precision.
opw-4944644
Forward-Port-Of: odoo/odoo#221389This update removes an internal dependency in the HTML builder's drag-and-drop behavior so it can work cleanly with upcoming email marketing changes. It preserves the existing protection against unintended edits being marked for saving while making the editor easier to reuse across modules.
Original PR description
In commit [1], in order to prevent the drag and drop from marking unwanted elements as dirty, a dependency to the `savePlugin` was added to use its `ignoreDirty` shared function. However, this dependency is problematic for the upcoming `mass_mailing` refactoring, as it will not use this plugin. This commit uses the `on_prepare_drag_handlers` resource instead, to remove that dependency. [1]: 6fdf188fdf5cfdc11e5e1a8429d0a652054344de task-4367641 Co-authored-by: Damien Abeloos <abd@odoo.com>
This fixes Belgian POS reporting so credit notes show as negative amounts while invoices remain positive, making sales details clearer and consistent with totals. It also prevents the POS from accidentally removing two order lines when decreasing an unsaved item quantity.
Original PR description
- Fix issue on the POS sale details report, where the amount of credit notes was displayed as a positive amount along invoices while the total was correctly computed. Now we displayed the signed amount (negative amount for credit note, and positive ones for invoices). - Fix issue in `handleDecreaseUnsavedLine` which was leading to removing two orderlines instead of one in the current order. This issue appeared since this commit (1aaa600801d9ecf23d9c460690587ec4e4d9b423). Since we already set the line qty to 0 (or remove it) inside `updateSelectedOrderline` after calling `_showDecreaseQuantityPopup`, we don't need to call `removeOrderLine` inside `handleDecreaseUnsavedLine`. task-id: 4901299 enterprise PR: https://github.com/odoo/enterprise/pull/92070 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Changing a website color palette no longer shows a warning about losing custom colors when no custom colors were set. This prevents confusion for website editors and keeps the theme selection flow smoother.
Original PR description
Since `html_builder`, when changing the color palette, the warning about losing color customizations is displayed even when there were no such customization to lose. This commit restores the condition around this warning. Steps to reproduce: - Go to "Theme" tab - Pick a color palette => A confirmation warning was displayed even though no color customization could be lost. task-4367641
This fix prevents an error when users click the 'From WH' button on a project task in the community version. The unavailable map view is removed there, so the button behaves correctly while leaving room for enterprise-specific map support.
Original PR description
* STEP TO REPRODUCE: go to task of a project, enable 'From WH' in top bar button. Click on it -> error because no map view * SOLUTION: in community version we should remove map view then in enterprise we can overide to add it 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#222003
The website editor now loads the same style foundations used by the live website, so theme colors and other design settings are available while editing. This reduces visual mismatches and makes product page previews and customization controls more reliable for website builders.
Original PR description
The `html_builder.inside_editor_style` bundle provides style assets that are loaded exclusively inside the editor's iframe during edition. We want to use scss variables that are sometimes overriden in various ways such as the theme tab of the website builder, website settings or website themes. The inheritance currently does not work and some variables are straight up not available. To resolve this, this commit inherits the `web.assets_frontend` which provides all those variables and is overriden by all said mechanisms.
Fixed an issue where clicking too quickly on a newly dropped building block could fail to select the intended field. This makes the website/page editing experience more reliable immediately after adding dynamic content.
Original PR description
[1] introduced a click redispatching in case a newly dropped element is being clicked upon too early. It just forwarded the click under the loading glasspane, but this is not ok in case elements of the block get redrawn before the click happens, as they will not be inside the DOM anymore. This commit fixes this by clicking on the topmost remaining element of the initially clicked elements. Steps to reproduce: - Drop a "Form Info" block - Very quickly click on a field => The field was not selected. [1]: https://github.com/odoo/odoo/commit/0884b2c716366c872a977f84f8bbdb33ce13468d task-4367641
Receipts that include stock moves linked to different partners can now be opened without triggering an error. This prevents a crash in Inventory operations and allows users to view imported receipt records normally.
Original PR description
When opening a Receipt containing stock moves linked to different partners, A traceback will appear. Steps to reproduce the error: - Install ``stock`` module with demo data - Go to Inventory > Operations > Receipts - Import this [file](https://docs.google.com/spreadsheets/d/1LkplPQqWdUGOUHaTuJ1khXdvB6kGDVwb/edit?usp=sharing&ouid=106663959141116380430&rtpof=true&sd=true) - Open the imported record Traceback: ``ValueError: Expected singleton: res.partner(1, 2)`` https://github.com/odoo/odoo/blob/ac2b182f55a632f4e8a869cbf61613ebc93d8ae2/addons/stock/models/stock_move.py#L710 Here, ``_get_lang`` method is called on self containing multiple stock moves. So, it will give the traceback from below line because it will have multiple partners. https://github.com/odoo/odoo/blob/ac2b182f55a632f4e8a869cbf61613ebc93d8ae2/addons/stock/models/stock_move.py#L2214-L2216 sentry-6798363441 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Accounting administrators without expense permissions can now create expenses without running into a misleading validation error. To prevent incorrect employee selection, these users can only create expenses for their own employee record.
Original PR description
- Create a user and its related employee without any expense access rights but with accounting admin rights. - With that user create a new expense. - On the employee field select a different employee…
- Create a user and its related employee without any expense access rights but with accounting admin rights. - With that user create a new expense. - On the employee field select a different employee and save. - The following error appears: Validation Error The operation cannot be completed: Missing required value for the field 'Description' (name). Model: 'Expense' (hr.expense) - create/update: a mandatory field is not set - delete: another model requires the record being deleted, you can archive it instead Since b1ac6f52d37cd59fdb973ce87f93d1d0a69dd204, the field employee_id is no longer invisible for users without hr_expense rights. However, in the method _search_filter_for_expense, users without hr_expense rights but with account rights are able to select every employee (commit 87cca4a9ee64c890ccbd24e2d6766f9f8799a0c0). But in hr_expense, the method _compute_is_editable only considered hr_expense rights, which meant that users trying to create a new expense with only accounting rights would get an error if they were not the approver of the employee they tried to create the expense for. After this commit: If the user has no hr_expense rights but has account rights, they will only be able to create expenses for themselves. opw-4780218 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#222253 Forward-Port-Of: odoo/odoo#215452
Product images shown on shared purchase portal pages are now constrained to an appropriate small size instead of appearing at their original dimensions. This keeps purchase documents easier to read and prevents large product photos from disrupting the portal layout.
Original PR description
Issue ----- Images on the purchase portal are displayed in their original size instead, making it a visual mess. Steps to reproduce ----- - Create a product with a large image - Create a purchase for…
Issue ----- Images on the purchase portal are displayed in their original size instead, making it a visual mess. Steps to reproduce ----- - Create a product with a large image - Create a purchase for the product - Click the cog wheel > Share - Open the link in a new tab (with no active session, eg private window) --> The image is way too big Cause ----- Images are now converted to Webp: https://github.com/odoo/odoo/commit/1a978183001e0503104285f4bd5bed983beb0efb The problem is that Webp images cannot be resized through the Python backend: https://github.com/odoo/odoo/blob/0c6622294b7117ec5eb1cbf8a9270636b2dd807f/odoo/tools/image.py#L81-L83 However, the product model has multiple sizes for the image: https://github.com/odoo/odoo/blob/3ddf2bcdf16b5b43db4c4abe2cdbc4384cf683cc/addons/product/models/product_product.py#L91-L94 What we can do is load the smallest possible image and then use styling to limit the display size. The 48px comes from the hardcoded values in https://github.com/odoo/odoo/blob/0c6622294b7117ec5eb1cbf8a9270636b2dd807f/addons/purchase/controllers/portal.py#L99 This fix will no longer be needed when (if) Webp images get resized in backend. Comparison ----- Left is before, right is after fix.  Image used -----  ----- Ticket: opw-4625113 Forward-Port-Of: odoo/odoo#221139 Forward-Port-Of: odoo/odoo#217990
The website editor sidebar now shows the layout option before the background option. This makes an important design setting easier to find and restores the previous ordering.
Original PR description
The layout option was placed after the background option in the sidebar while it was the other way before. Since layout is more important, it should be placed at the start of the block. This commit moves the layout option before the background option. task-4367641
This update changes how the website editor handles drag-and-drop actions so it no longer depends on a specific saving component. This supports future email marketing editor work where content may be saved through a different flow, reducing integration risk without changing the visible editing experience.
Original PR description
[Commit] introduced a way to prevent mutations from being saved when a change was caused by a `dragAndDrop` operation. However it did so by adding a dependency to `savePlugin`, which is not desirable for the upcoming `mass_mailing` refactoring, which will use the `html_builder` in coordination with a Form View, which has its independent way of saving user content. This commit introduces a resource in order to remove that dependency. [Commit]: https://github.com/odoo/odoo/commit/6fdf188fdf5cfdc11e5e1a8429d0a652054344de task-4367641
Cancelling a product import before uploading a file no longer causes Odoo to crash. The import flow now avoids opening the product list with invalid filter data, improving reliability for users who back out of imports.
Original PR description
Steps to reproduce: - Go to Inventory > Products - Click "Import" - Cancel the import wizard before uploading any file - Odoo crashes with `InvalidDomainError` due to domain [['id', 'in', undefined]] This commit ensures that the domain is only set when resIds is valid. --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Website table of contents links now update when headings are translated, so visitors see navigation labels that match the selected language. The change also prevents editors from directly changing generated navigation items, reducing inconsistent content in multilingual pages.
Original PR description
When we translate headings in the Table of Content snippet, the snippet's navbar items aren't responsive, they stay connected to the original language headings. Steps to reproduce the problem: - Add a second language to your website - Open Website and start editing - Drop the table of content snippet - Save, switch to your secondary language and start translating - Modify the table's heading => Navbar headings aren't updated. This commit also fixes the possibility of editing a navbar item directly, which shouldn't be the case. This commit follows the [html_builder refactoring]. Related to task-4367641 [html_builder refactoring]: https://github.com/odoo/odoo/commit/9fe45e2b7ddb
This fix prevents an error when users create a new work entry from the list view in French payroll. It adds checks for missing start or end dates so the entry form can open normally instead of blocking the user with a traceback.
Original PR description
Currently, a traceback occurs when a user attempts to create a work entry in the list view. **To reproduce this issue:** 1) Install the `l10n_fr_hr_work_entry_holidays` module. 2) Switch to the `French` company and open the payroll. 3) Open the work entries in list view and try to create a new record. **Error:** ``` AttributeError: 'int' object has no attribute 'seconds' ``` **Cause:** By default, when creating a work entry through the list view, no `start` or `end` date is provided. This leads to the traceback originating from the following line when computing the duration. https://github.com/odoo/odoo/blob/84b15dc1f866e27d5c8a5fe3e457c2f982bcb133/addons/l10n_fr_hr_work_entry_holidays/models/hr_work_entry.py#L28-L32 **Solution:** Adding an extra check of the `start` and `end` date would resolve this issue. opw-4943104 Forward-Port-Of: odoo/odoo#221442 Forward-Port-Of: odoo/odoo#220127
The point of sale now calculates prices correctly when products have dynamic or configurable variants with extra charges. This prevents customers from being charged duplicated or incorrect variant surcharges, improving checkout accuracy.
Original PR description
When you have product with dynamic variants using extra price, the price added to the cart is not correctly computed. Steps to reproduce: ------------------- * Create a product with a dynamic variant…
When you have product with dynamic variants using extra price, the price added to the cart is not correctly computed. Steps to reproduce: ------------------- * Create a product with a dynamic variant (2 values), price 1 * Add an extra price for each value, ex 10, 20, 100 * Make a sale order with the first two variant value * Open shop * Add the product to the order 3 times, 1 for each value > Observation: Prices are respectively: 21, 41, 111 Why the fix: ------------ In the shop only `product.product` are shown. When selecting the product with variant, the product has a `lst_price` of 11 which corresponds to the price of the `product_template` plus the extra price. This value is normal but cannot be used in the computation of `get_price` as we also provide the value for `extra_price`. We can use `list_price` instead of `lst_price` as it does not include the information related to variants. Why do we see 2 different behaviors before this fix? When selecting a variant option, if the product with this variant already exist, the lst_price already contains the information about the selected variant. Which explains why, in the end, the price has twice the extra price of the variant selected. When the product with the variant does not exist, the price has one time the price of the selected variant plus one time the price of the first product with variant the is created. Configurable products were also having issues when mixing multiple variants, especially when one of them had creation mode set to "always". When exiting the configuration popup the payload does not include the extra price coming from "always" attributes. depending on what the other choices were we would have an extra price, meaning we would compute the price with `list_price` but the extra price did not include the information about the "always" variant if it had one. Using `list_price` is enough for the initial problem but only when the selected DYNAMIC variant has an extra price otherwise the code does not pass through the condition asking for extra price. In such case there is no extra price from the payload and it's still computing the price with `lst_price`, which includes information about the extra price of the variant that was already sold previously. Thus we make sure that we compute with `list_price` whenever a configurable product is added. opw-4815555 Forward-Port-Of: odoo/odoo#220091 Forward-Port-Of: odoo/odoo#216649
This fixes an internal accounting test that was tied to the year 2025 and would start failing in 2026. The change helps keep automated quality checks reliable over time without affecting day-to-day user workflows.
Original PR description
The test test_resequence_change_payment_name had hardcoded 2025 in the sequence name, meaning that the test will fail in 2026. opw-4437481 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#222220
Fixes a point of sale issue where completing a payment with automatic receipt printing could create two new draft orders instead of one. This helps keep cashier workflows cleaner and avoids unnecessary empty orders after a sale.
Original PR description
Steps to reproduce: ------------------------- - Open a session with automatic receipt printing enabled. - Pay an order when only one open order is present. Issue: ------- - Two new draft orders are created instead of one. Cause: --------- - `this.pos.defaultPage` is a getter that creates a new draft order if none exists. Later, `selectNextOrder()` was also triggering a new order creation when automatic receipt printing was enabled, causing the creation of two draft orders. FIX: ----- - Removed the redundant order creation logic from `selectNextOrder()`, as the new order is already created through the default page getter also moved that function logic to pos store. Task: 4925669
This fix ensures products that are not marked for sale cannot be selected on standard quotations when the rental app is installed. It prevents accidental quotation of unavailable products and keeps sales options aligned with product settings.
Original PR description
Versions
--------
- saas-18.3
Steps
-----
1. Have a product that's neither salable not rentable;
2. open a quotation;
3. click "Add a product".
Issue
-----
It's possible to select the unsalable product.
Cause
-----
Commit d5f72c201bf0 added a `_domain_product_id` override to `sale_renting` which includes `('rent_ok', '=', order_is_rental)`. As a consequence, whenever you have a quotation that isn't a rental, this domain will retrieve *any* product that isn't rental either.
Solution
--------
Add a `('rent_ok', '=', True)` condition to ensure the override only affects rental orders, and that non-rental orders won't retrieve all non-rental products.
opw-4983348
Forward-Port-Of: odoo/enterprise#91701Project profitability now continues to include invoices from subscriptions that were renewed. This prevents previously invoiced revenue from disappearing after renewal, giving businesses a more accurate view of project profitability.
Original PR description
To reproduce: ============= - create a subscription with a service and link it to a project - confirm the subscription and invoice it - check the profitability of the project, everything is fine - renew the subscription and invoice it - check the profitability of the project, the invoiced amount is not taking into account the previous invoiced amount Problem: ======== renewed subscriptions are excluded from the profitability computation because they are closed by the renewal and not bringing any profitability, but with that we loose the profitability of the previous invoiced amount. Solution: ========= keep renewed subscriptions in computing `Invoiced` amount. opw-4755016 Forward-Port-Of: odoo/enterprise#92052 Forward-Port-Of: odoo/enterprise#91437
This fixes a point-of-sale issue where printing another bill for an already-synced order could fail when no new changes were present. Staff can now reprint or create multiple bills from the same order reliably, reducing checkout friction.
Original PR description
Before this commit an issue was appearing when we try to make multiple bill on the same order. If the order was already synced and didn't get any changes, clicking `Print bill` with `pos_blackbox_be` wouldn't do anything. Now we print the bill after syncing the order, even if the order don't have any new changes to sync. task-id: 4901299 community PR: https://github.com/odoo/odoo/pull/222424
The Czech VIES summary report now counts supplies by invoice instead of invoiced quantity, groups data by journal entry, and rounds total values correctly to whole Czech crowns. This helps businesses submit more accurate VAT reporting in line with Czech tax authority requirements.
Original PR description
There are some errors in the VIES summary report fixed here:
1. The supply number is not the quantity invoiced, it is the
number of invoices
2. There was some confusion between the terms "supply transaction"
and "supply code", with "supply code" not being used
in this report (but still in Python code to avoid breaking stable versions)
3. We were considering journal items, whereas it is preferable
to group them by journal entry
4. The total value is rounded up to the nearest whole crown (Czech currency)
Here is a link to the documentation:
adisspr.mfcr.cz/dpr/adis/idpr_pub/epo2_info/popis_struktury_detail.faces?zkratka=DPHSHV
where pln_hodnota is the total value; pln_pocet is the supply number; and k_pln_eu is the supply transaction.
opw-4688616
Forward-Port-Of: odoo/enterprise#91891
Forward-Port-Of: odoo/enterprise#88279The Swedish SIE4 import now skips accounting entries that contain no usable transaction lines. This prevents empty journal entries from being created in Odoo, keeping imported accounting data cleaner and more reliable.
Original PR description
The aim of this commit is making sure that we don't import move without transaction in it. In SIE4, we can have moves with BTRANS and RTRANS tags that we are ignoring. It means that we could have move without any move lines. It's not an expected behavior in Odoo. This commit checks that the move data are created only if we have lines for that move. no task id Forward-Port-Of: odoo/enterprise#91783
This fix ensures Colombian electronic invoices send document type codes in the exact two-character format required by DIAN. It helps prevent invoice submissions from being rejected because of incorrectly formatted EDI types.
Original PR description
The DIAN endpoint only accepts Electronic Invoice types with a length of 2 characters. This fix adds zero-padding to the problematic edi types. task: 4882683 Forward-Port-Of: odoo/enterprise#89925