Daily updates from Odoo
Thursday, July 17, 2025
22 changes · 18.0
Enhancements to existing features
Swiss companies selling goods directly to EU consumers can now more easily configure EU One Stop Shop tax reporting. The update adds tax mappings from Switzerland to EU countries, reducing manual setup and improving discoverability of the OSS workflow.
Original PR description
Make it easy for any Swiss company that wants to operate B2C sales of goods to customers located in the EU to take advantage of the EU One Stop Shop (OSS) Module, aka l10n_eu_oss_reports. We will ease the discoverability and the configuration Adding the Tax Mapping between Switzerland and the rest of the EU countries task-4943589 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Resolved issues and error corrections
Credit notes sent through Spain’s TicketBAI reporting now show negative amounts when using the correction-by-differences method. This helps ensure refunds and tax totals are reported accurately to the tax authority, reducing compliance errors.
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
This fixes an issue where reducing a sales order line to zero after a return for exchange could create an unnecessary receipt instead of canceling the replacement delivery. Businesses get cleaner inventory operations and avoid confusing extra warehouse documents during exchange handling.
Original PR description
When dealing with a "return for exchange" case, some SM won't be merged To reproduce the issue: 1. Confirm a SO with a product 2. Process the delivery 3. Return > Return for exchange 4. Process the…
When dealing with a "return for exchange" case, some SM won't be merged To reproduce the issue: 1. Confirm a SO with a product 2. Process the delivery 3. Return > Return for exchange 4. Process the receipt 5. Set the SOL qty to 0 Error: a receipt is created. The second delivery should actually be canceled This happens because the SM from step 5 is not merged into the SM of the second delivery. When editing a SOL qty, a procurement is ran and its values are based on the SOL: https://github.com/odoo/odoo/blob/66c5d10833af8946ab5d3f887086f9ba08d36ab3/addons/sale_stock/models/sale_order_line.py#L228-L230 https://github.com/odoo/odoo/blob/66c5d10833af8946ab5d3f887086f9ba08d36ab3/addons/sale_stock/models/sale_order_line.py#L378 Where we define a specific `date_deadline` https://github.com/odoo/odoo/blob/66c5d10833af8946ab5d3f887086f9ba08d36ab3/addons/sale_stock/models/sale_order_line.py#L260 However, when we return for exchange, we also run a procurement, but its values are defined differently: https://github.com/odoo/odoo/blob/30e60b55736cfd5f3116ebbc680b49d9113ca419/addons/stock/wizard/stock_picking_return.py#L238 And nothing defines `date_dealine` Since the values of both SM are not the same, they won't be merged, cf https://github.com/odoo/odoo/blob/9f8c364f056c8937409f8ed91b8d1fa436c2d7c0/addons/stock/models/stock_move.py#L1119 Hence the creation of the receipt picking OPW-4688679
This fixes an issue where updating stock quantities for one company while logged into another could use the wrong product cost. Inventory valuation entries and standard prices now remain accurate for the company whose stock is being adjusted, helping prevent incorrect financial reporting.
Original PR description
**Problem:** when updating quantity of a product in company A from a user logged in on company B the svl are created with wrong values and standard price is incorrectly updated **Steps to…
**Problem:** when updating quantity of a product in company A from a user logged in on company B the svl are created with wrong values and standard price is incorrectly updated **Steps to reproduce:** - check two companies on the top right of the screen (comp A and comp B) - create a storable product with a avco category - make sure that the cost method of the category is avco both when logged in with company A and B (the cost method is company dependent) - while logged in with comp A create, confirm, receive and validate a PO for a quantity of 1 and a unit price of 100 - do the same while logged in with comp B but with a unit price of 10 - open the product form (cost should be 100 or 10 depending on the company) - while logged in on comp B click on the 'on hand' smart button - update from 1 to 2 the on hand quantity in the WH of comp A - switch to comp A and come back to prodcut form **Current behavior:** the standard price is 55. additionaly, when opening inventory/reporting/valuation and chossing the product we see that the svl created has a value of 55 **Expected behavior:** standard price should stay at 100 and the svl should be created with a value of 100 **Cause of the issue:** Product_price_udpate_before_done calls get_price_unit to compute the new standard price. https://github.com/odoo/odoo/blob/750265bac921936a7c29cf73f8f9e926eea4a926/addons/stock_account/models/stock_move.py#L345 Inside get_price_unit, because the move has no unit_price we use self.product_id.standard_price which will take the standard price of comp B https://github.com/odoo/odoo/blob/750265bac921936a7c29cf73f8f9e926eea4a926/addons/stock_account/models/stock_move.py#L59 opw-4852096 Forward-Port-Of: odoo/odoo#217524
This fixes a navigation issue where reloading a page after opening embedded project actions could show an incorrect extra task in the breadcrumb trail. Users now get a cleaner breadcrumb path for embedded actions like Planning or Timesheets, though the task list step may no longer appear there and remains available from the top menu.
Original PR description
- Open the Project app. The URL is `/odoo/project`; - Open a project. For example, the project with ID 5. The URL is `/odoo/project/5/tasks`; - Click on an embedded action. For example, 'Planning'.…
- Open the Project app. The URL is `/odoo/project`; - Open a project. For example, the project with ID 5. The URL is `/odoo/project/5/tasks`; - Click on an embedded action. For example, 'Planning'. The URL is `/odoo/project/5/tasks/5/action1574`; - Switch to another embedded action. For exemple, `Timesheet`. The URL is `/odoo/project/5/tasks/5/project-timesheets`. Note that in this case, the last action of the URL has changed. Reload the browser (F5). When reloading the router and the action service will use the URL to reconstruct the breadcrumb. It will decompose the URL as follows: - `/odoo/project` : The list of projects; - `/odoo/project/5` : The form view of the project '5', this is a known limitation; this step was not included the initial flow; - `/odoo/project/5/tasks`: The list of tasks of the project 5; - `/odoo/project/5/tasks/5` : The form view of the task 5. This line is an error, the task 5 should not be included in the breadcrumb. - `/odoo/project/5/tasks/5/project-timesheets` : The `Timesheet` embedded action. The issue occurs because the 'active_id' of the 'Timesheet' embedded action is taken as a 'resId' for the action tasks, which add an error on the breadcrumb. This commit, changes the behaviour to allways replace the last action with the embedded action. This behaviour is already done when changing of embedded action, but not for the first one. If we take our example again : - `/odoo/project`; - `/odoo/project/5/tasks`; - Click on an embedded action: `/odoo/project/5/action1574`; - Switch to another embedded action: `/odoo/project/5/project-timesheets` After reloading, the breadcrumb will be: - `/odoo/project` : The list of projects; - `/odoo/project/5` : The form view of the project '5'; - `/odoo/project/5/project-timesheets` : The `Timesheet` embedded action. However, this commit causes a side effect. The list of tasks will no longer appear in the breadcrumb. Users can still access it via the Top Menu. opw-4889557
Updates Odoo to work reliably with newer Python and Debian platform versions. This helps reduce deployment and upgrade risks for organizations moving to Debian Trixie or Python 3.13 by aligning dependencies and internal compatibility handling.
Original PR description
Forward-Port-Of: odoo/odoo#219270
Fixes an issue where emails scheduled from the chatter could be delayed because the background job placed them back into the general email queue instead of sending them when due. Scheduled messages now respect the selected send time, improving reliability for customer and internal communications.
Original PR description
**Steps to reproduce:** - Go to the chatter of any record - Click on `Send message` - Click on `Full composer` icon on the bottom right - Prepare an email with custom subject / body - Click on `Send…
**Steps to reproduce:**
- Go to the chatter of any record
- Click on `Send message`
- Click on `Full composer` icon on the bottom right
- Prepare an email with custom subject / body
- Click on `Send Later` and set the scheduled time
- Mail is not sent on scheduled time
**Issue:**
For the timing issue, as the mail is sent by a cron job it obtains a context with `mail_notify_force_send` set to `False` due to the function `_get_eval_context` of `ir.actions.server`.
```
""" Override the method giving the evaluation context but also the
context used in all subsequent calls. Add the mail_notify_force_send
key set to False in the context. This way all notification emails linked
to the currently executed action will be set in the queue instead of
sent directly. This will avoid possible break in transactions. """
```
This context override the `force_send` value used when sending emails notifications. Everything is created properly but the mail is not sent directly and goes to the email queue manager (where it needs to wait until the next execution). This means that the time given previously is not explicitly used to send the mail and the mail is delayed (which doesn't seem to be the expected behavior).
```
if force_send := self.env.context.get('mail_notify_force_send', force_send):
force_send_limit = int(self.env['ir.config_parameter'].sudo().get_param('mail.mail.force.send.limit', 100))
force_send = len(emails) < force_send_limit
if force_send and (not self.pool._init or test_mode):
# unless asked specifically, send emails after the transaction to
# avoid side effects due to emails being sent while the transaction fails
if not test_mode and send_after_commit:
emails.send_after_commit()
else:
emails.send()
```
**Fix:**
Overwrite `mail_notify_force_send` value when posting the scheduled message in the cron job.
related: https://github.com/odoo/odoo/commit/df18d5257cef737f3e1d245a8b85769e1fe1a032
opw-4700253
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prSales orders using units such as dozens now carry the correct converted quantity and price into Point of Sale orders. This prevents undercharging or incorrect fulfillment when POS staff import confirmed sales orders with non-standard units of measure.
Original PR description
**Steps to reproduce:** - Install `pos_sale`. - Create a sale order for a POS product with quantity 1 and UoM `Dozens`. - Confirm the order. - Go to Point of Sale → open a session. - Click Actions →…
**Steps to reproduce:** - Install `pos_sale`. - Create a sale order for a POS product with quantity 1 and UoM `Dozens`. - Confirm the order. - Go to Point of Sale → open a session. - Click Actions → Quotation/Order and select the recently created sale order. - Check the POS order line quantity. **Issue:** - The POS order line shows quantity as 1 unit, while the sale order line used 1 Dozen, so it should be 12 units. **Cause:** - The POS order line was directly using the quantity and price from the sale_order_line without applying the proper UoM conversion. https://github.com/odoo/odoo/blob/8f937d4c4a6c4cece698a5e904ba7a0cf2fbb24c/addons/pos_sale/static/src/overrides/models/pos_store.js#L152-L153 Solution: - Updated logic to set quantity and price_unit in the POS order line based on the converted sale order lines after UoM calculations. https://github.com/odoo/odoo/blob/8f937d4c4a6c4cece698a5e904ba7a0cf2fbb24c/addons/pos_sale/static/src/overrides/models/pos_store.js#L84-L86 - Also updated the value assigning of 'has_valued_move_ids' to converted line because quantity calculation is based on 'converted_line'. https://github.com/odoo/odoo/blob/8f937d4c4a6c4cece698a5e904ba7a0cf2fbb24c/addons/pos_sale/static/src/overrides/models/pos_order_line.js#L50-L53 opw-4900767 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Refreshing a project page after using an embedded action button no longer shows unrelated or random breadcrumbs. This improves navigation accuracy, though clicking embedded actions will no longer add an extra breadcrumb back to the default task view.
Original PR description
When using embedded action buttons (in this case in the project app), clicking on a embedded action button besides the default 'task' button and refreshing the page results in erroneous breadcrumbs.…
When using embedded action buttons (in this case in the project app), clicking on a embedded action button besides the default 'task' button and refreshing the page results in erroneous breadcrumbs. Specifically, the breadcrumbs will include a random task that was not clicked on. This is caused by an additional action being registered to the action list for the embedded action button while we are still on the same project. Instead, with the implemented fix, the current action will be replaced by the new embedded action instead of the new action being added to the action list without replacement. With this fix, refreshing the page after clicking an embedded button will not cause errors in the breadcrumbs. However, there are side effects caused by this change. Before the fix, clicking on an embedded action button other than the default 'task' button would create a breadcrumb to go back to the 'task' action. With the fix, this is no longer the case: a breadcrumb is no longer created when clicking on an embedded action. This should not be a big issue as the user will still be on the same page anyways and can easily nagivate back to the 'task' page with the embedded action. To reproduce the error on a blank DB: 1) Download and open the project app 2) Open any project 3) View embedded action buttons by clicking on the button to the left of view selection 4) Enable the 'sale orders' button and click on it 5) Notice the breadcrumbs 6) Refresh the page 7) Notice the erroneous breadcrumbs opw-4889557 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Point of Sale users without sales document access can now load loyalty programs correctly. This prevents access-rights issues from blocking loyalty features during PoS operations.
Original PR description
Before this commit, the loyalty program was not loaded for PoS users who lacked access rights to sale documents. This issue occurred because the system attempted to read the `total_order_count` field, which is computed based on sale orders, causing a failure in loading the loyalty program. opw-4847852 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Basic internal users can now open more Website app screens without running into access-rights warnings. This helps users view available website-related records such as events and pages more reliably, while also improving automated test stability.
Original PR description
*: event, website_event, website_hr_recruitment The functional desire is to be able to access the website app as a basic internal user and see records views that you can see. In practice, there are…
*: event, website_event, website_hr_recruitment The functional desire is to be able to access the website app as a basic internal user and see records views that you can see. In practice, there are quite a few technical issues preventing that (the user easily gets hit with "you don't have the rights to access this" because of internal fields of the main models and screens could maybe be different or the framework should be a bit more smarter about this. This commit adds bandaids on the problem to at least allow some access without warning on some things (by hiding specific fields in the website views, etc). The main reason for this commit is keeping the no-demo runbot tests happy (especially in later versions where it became the standard). In master, this should definitely be reviewed to work more robustly and more well-thought from a functional point of view. Some (all?) examples of issues solved: as an internal user without any access rights (except being an internal user), try to: - Access the kanban view of events in the website app - Group the list view of events by "stage" in the website app - Access the list view or kanban view of jobs in the website app - Go on an event in the website app, try to access the form view with the related top-right button - Go on a job page in the website app, try to access the form view with the related top-right button Note: the publish button also kinda has the same problem for pages. This will be fixed in a dedicated PR after this one. runbot-161791 Forward-Port-Of: odoo/odoo#219128
This fixes incorrect on-hand and forecasted quantities when processing returns for exchanges in Inventory. Businesses can rely on more accurate stock availability after exchange workflows, reducing the risk of overselling or replenishing unnecessarily.
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
This fix ensures email marketing campaigns are correctly marked as completed after messages are sent, even if another campaign in the same processing run fails. It reduces the risk of already-sent campaigns being retried and sending duplicate emails.
Original PR description
**Steps to reproduce:** - Install `Email Marketing` app - Setup mail catcher - Create a first mailing `test_1` - Insert a dynamic field in the body template to trigger an error (easy way is to setup…
**Steps to reproduce:**
- Install `Email Marketing` app
- Setup mail catcher
- Create a first mailing `test_1`
- Insert a dynamic field in the body template to trigger an error (easy way is to setup a dynamic field and then change the `Recipients` type)
- Ensure this mailing has recipients
- Create a second mailing `test_2` with correct template / recipients
- Disable the `Mail Marketing: Process queue` action to prevent automatic processing (optional but could avoid issues)
- For `test_1` and then `test_2`, click on "Send" to trigger the `action_launch()`
- Manually trigger the scheduled action `Mail Marketing: Process queue`
- An error should be raised as expected ('Failed to render QWeb template')
- The mails for `test_2` are properly sent
- However `test_2` remains in `sending` state instead of `done`
**Issue:**
This issue is caused by the transaction rollback when the `test_1` error is raised. When sending the mail, `_action_send_mail` is called with `auto_commit` set to `True` before the mailing state is updated to `done` but after it is set to `sending`.
This means that, when there is an issue later on, the uncommitted changes will be rolled back, which removes the last state modification and the state gets back to `sending` even if the mails were properly sent.
This could lead to unintended behavior such as mailings being retried and resent on next trigger.
**Fix:**
Explicitly called `commit()` after the state update and disabled the `auto_commit` of `_action_send_mail()`.
Could be better to use `post_send_callback` parameter from
`def send(self, auto_commit=False, raise_exception=False, post_send_callback=None):`
but we would need to modify multiple function signatures (which seems bad in stable).
No test was added as the issue require manual committing which is not supported in tests.
opw-4832616
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-prWhen Indian e-invoicing authentication fails, users now see the detailed error message and code returned by the service. This helps businesses understand what went wrong and resolve setup or access issues faster.
Original PR description
Previously, the `UserError` raised on authentication failure did not include the error message returned by the IAP server.
In this commit:
---
- Added logic to extract and include detailed error messages with code from the IAP response in the `UserError` during authentication for e-invoicing.
Related Tickets:
---
opw-4908388
opw-4942744
opw-4946339
opw-4946193
opw-4933833
Forward-Port-Of: odoo/odoo#219277This fix changes how Vietnamese credit notes are submitted to Viettel SInvoice so that total and tax amounts keep the expected credit-note signs, while only the unit price sign is adjusted. This helps businesses using Viettel's validation flow avoid incorrect positive amounts appearing in the SInvoice portal, though setups without that validation step may need extra care.
Original PR description
Description of the issue/feature this PR addresses: - Viettel SInvoice will automatically change the signs of the amount values (except for unit price) we sent for credit notes (on accounts with data…
Description of the issue/feature this PR addresses: - Viettel SInvoice will automatically change the signs of the amount values (except for unit price) we sent for credit notes (on accounts with data validation step). So the "right" values will appear in the portal. Currently (before the commit) the values have the wrong sign in the portal (because they are changed but we sent the right ones already). - We need to retain the original signs of those values when submitting them to SInvoice. Current behavior before PR: - All the amount values, including `itemTotalAmountWithoutTax`, `taxAmount`, `itemTotalAmountAfterDiscount` and `itemTotalAmountWithTax` are sent to Viettel SInvoice in negative values for credit note. Viettel SInvoice changes the sign of these values to positive (which is not correct for credit note). Desired behavior after PR is merged: - Only the sign of `unitPrice` is changed when we send the credit note to SInvoice. **Note:** - The signs will not automatically be changed for accounts with data validation step removed. So this commit will break credit notes for them (since the signs are not automatically adjusted but our values have the wrong signs). --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr Forward-Port-Of: odoo/odoo#201993
Point of Sale users in Belgium will now see clearer messages when the fiscal Blackbox cable is faulty or the device does not return a valid response. This helps staff identify connection problems faster and reduces confusion during checkout operations.
Original PR description
This PR adds some explicit messages to invalid responsed from the Blackbox. We will now log and inform the user when the cable is malfunctioning or the blackbox isn't responding with a valid message
This pull request combines several fixes and updates across accounting, social media, payroll, subscriptions, delivery, WhatsApp, and localization features. It improves reliability for reports, payments, messaging status display, Facebook page connections, DHL shipping integration, and country-specific compliance workflows.
Loan-related journal entries are now posted on the exact dates set in the amortization schedule instead of defaulting to month-end. This improves accounting accuracy and helps finance teams keep loan records aligned with planned repayment timelines.
Original PR description
Before this **PR**: Journal entries were posted at the end of the month, regardless of the dates defined in the amortization schedule. After this **PR**: Journal entries are now posted according to the specific dates in the amortization schedule. **opw**-4745823
Deferred accounting entries are now created even when the covered period is shorter than one month, such as a few days at the end of a month. This improves revenue or expense allocation accuracy for short invoice periods and helps financial reporting match expected accounting treatment.
Original PR description
Previously, `_get_deferred_periods` would return an empty list when the deferral period was contained within a single month and matched the invoice date's month, even if the period spanned multiple days. This caused deferred entries to be skipped for valid short deferral spans (e.g. June 25 to June 30). This fix removes the condition that filters out single-month deferral periods, ensuring that deferred entries are always generated when a valid start and end date are present. This change supports accurate pro-rata allocation even for invoice periods shorter than one month, aligning the accounting behavior with expected financial standards. task-4910854 Forward-Port-Of: odoo/enterprise#89114
Intrastat reports no longer preselect journal filters, so credit notes are less likely to be missed. This helps businesses produce more complete arrivals reporting without needing to manually adjust filters first.
Original PR description
- Before this PR: Customers often miss credit notes in Intrastat arrivals due to filtering on purchase journals only, which results in incomplete reports. - After this PR: Journal filters are now unticked by default in both root and variant Intrastat reports. - Task ID: 4936349
This fix prevents receipt demand quantities from being inflated when users partially process lot-tracked products in the Barcode app and return later to finish the receipt. It keeps inventory receipts accurate by correctly handling remaining backorder quantities when exiting barcode workflows, including batch picking scenarios.
Original PR description
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back…
### Steps to reproduce: - Create a storable product tracked by lot - Create and confirm a receipt for 10 units of that product - Go to the barcode app and regiter 1 unit - Exit the picking - Go back to the picking register the 9 remaining units - Exit the picking and comeback #### > The demand of the receipt has been updated from 10 to 19. ### Cause of the issue: Exiting the picking will launch a call of the `post_barcode_process` in order to keep track of the changes you made without changing the initial demand: https://github.com/odoo/enterprise/blob/c26c21cec14a234021bb13bbc2684334bc64b70b/stock_barcode/models/stock_move.py#L50-L53 THe first time you enter the picking you have a single move with a quantity of 10. The first time you exit, since you have set a qty_done of 1 (and hence have updated the quantity of the associated move to 1), the `split_uncompleted_moves` will then create a move for a quantity of 9 in order to keep 10 units assigned. The second time you enter the picking both moves are grouped in a single line since the product is tracked by lot, however, when you update the qty_done of that grouped line you will actually only update the quantity of the first move line and its related move. Since the `_truncate_overreserved_moves` was not designed to handle these grouped lines, it does not notice that the combined reservation overcomes the actual demand. opw-4731803
Shipping with DHL or USPS now uses the correct package details for each carrier. This prevents incorrect shipment information from being sent when both delivery integrations are installed, improving reliability for order fulfillment.
Original PR description
Forward-Port-Of: odoo/enterprise#89771