Friday, July 18, 2025
34 changes
15 changes
Resolved issues and error corrections
Email Marketing now correctly marks successful mailings as completed even when another mailing in the same queue run fails. This helps prevent campaigns that were already sent from staying in progress and being resent later.
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-pr
Forward-Port-Of: odoo/odoo#219429
Forward-Port-Of: odoo/odoo#214591The website builder now opens the image shape selector immediately instead of waiting for every shape preview to load. Shape previews are loaded together in groups, making the interface feel more responsive while avoiding distracting flicker.
Original PR description
Steps to reproduce: - In the website builder, select an image - Click on "Shape" => It takes several seconds to open, without any feedback to the user. In [commit 1], the `Img` component's…
Steps to reproduce: - In the website builder, select an image - Click on "Shape" => It takes several seconds to open, without any feedback to the user. In [commit 1], the `Img` component's `onWillStart` was wrongly rewritten to await the image load. In this commit, we don't await the `Img` load to avoid a laggy interface. When each `<Img>` in a group appears one at a time, the visual effect is not optimal. In such a case, we can wait for all the images in the group to display them all at once. This commit adds an `ImgGroup` wrapper component to be used in those situations. After the 1st load, images are cached by the browser and should appear immediately. Note that the intent of the `ImgGroup` was initially to also display a placeholder until the images are shown. This was finally scrapped, as the builder images should load fast enough that we don't need to actually show a placeholder. As a matter of fact, if present, those placeholders give a worse impression because they trigger several visual changes on the page in a small time frame. [commit 1]: https://github.com/odoo/odoo/commit/3cc5ff6e96493f2b068090f880987def3787895e#diff-b4107c5542b3089f488c9a60dd38df72710d0702d5c1ee2de36eb80bc884697c task-4367641
Fixes an issue that caused the website editor to crash when creating a new product ribbon in the online shop. The update also restores the expected ribbon styling controls, making product display customization smoother for eCommerce users.
Original PR description
To reproduce the issue introduced in this [commit], - Open website, having eCommerce installed and at least one product set - Go to /shop and start editing - Click on a product - Ribbon option: Click on create a new ribbon => We receive a traceback because "dependencies" aren't set as static. In the 2nd commit, linted the code for readability. 3rd commit sets ribbon text and background color pickers to have only 2 enabled colors, and removes borders from the product option [commit]: https://github.com/odoo/odoo/commit/b4b215325db61fbbe9793545293c8b6fbc99f310
This fixes a website editor issue where newly created text links were not properly marked for translation. Translated pages can now keep link edits, reorder links, and save new translated links without losing changes.
Original PR description
After the initial website builder refactor, new links in text on the website do not contain the class `o_translate_inline`. NOTE: before the refactor it was added only for new links inside paragraph (the bugs described here were present in blocks which are not paragraph) Steps to reproduce: - Open website builder - Select some text and add a link from the toolbar - Again, with some text after in the same text block - Save - Change the website language - Open website builder in translate mode - Bugs: - You cannot change the links - You cannot make it so that the links are in another order - Edit the text to make the translation different - In the edited block, select some text and create a new link - Save - Bug: The edits are lost (the block with the new link is reset) Website refactor: 9fe45e2b7ddbbfd0445ffe25a859e67a316d02b2 task-4367641
This fix recalculates website navigation items when page layout settings are changed. It prevents menus with many links from overflowing after switching to a narrower boxed layout, keeping edited websites visually consistent.
Original PR description
The issue happens when the navbar contains many items and the website page layout is customized to a smaller size, causing the navbar to overflow. Steps to reproduce: - Open website and start editing - Click on the navbar and change content width to "Full" - Go to the theme tab and change the "Page Layout" option from "Full" to "Boxed" => We have an overflow. This commit follows the [html_builder refactoring]. Related to task-4367641 [html_builder refactoring]: https://github.com/odoo/odoo/commit/9fe45e2b7ddb
Fixed an issue where choosing a background image in the website theme editor had no visible effect. This ensures businesses can apply their intended site branding and visual design without needing a workaround.
Original PR description
This commit fixes a bug in the new version of the editor where setting a background image in the website theme would do nothing. Steps to reproduce - open editor - open theme tab - set any image as background => nothing happens After this commit the background image shows correctly.
Basic internal users can now open more Website app screens without being blocked by access-rights warnings. This helps teams view available event, job, and website records more reliably, especially in test and no-demo environments.
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#219356 Forward-Port-Of: odoo/odoo#219128
Point of Sale users without sales document access can now load loyalty programs correctly. This prevents access-right issues from blocking loyalty features at checkout, helping stores continue applying rewards smoothly.
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 Forward-Port-Of: odoo/odoo#219412 Forward-Port-Of: odoo/odoo#217772
Fixed an issue where a PDF opened in a separate pop-out window could keep showing the previous bill when users moved to another bill. This ensures the attachment preview stays in sync with the selected record, reducing confusion during bill review.
Original PR description
Steps: - Install `account_accountant` - Open bills - Create two bills with two different PDF - Go to list view, open first bill - On the pager you have now 2 records (1/2) - Click on the…
Steps:
- Install `account_accountant`
- Open bills
- Create two bills with two different PDF
- Go to list view, open first bill
- On the pager you have now 2 records (1/2)
- Click on the attachment_preview to open PDF in a PopOut
- Click on the next button in the pager
- PopOut is not updated (still with the first PDF)
since https://github.com/odoo/odoo/pull/214726
Before to this commit, the popout service returned an object containing `createManager` (which also contains useful getters such as `.id` and `.externalWindow` used to retrieve the window and communicate with it), and it also contains all createManager's methods using the following code:
```js
return {
createManager,
...createManager(), // ❌ Converts getters to static values
};
```
But all that getters become obsolete as a copy of the object is made at that precise moment and so, for example, `externalWindow` will remain null forever instead of being re-evaluated each time it's accessed.
Since other parts of the code (such those in charge of updating the popout when props are updated) use `externalWindow`, this no longer worked at all, as it never detected an external window.
The solution (in stable) is to use this code instead:
```js
const service = createManager();
service.createManager = createManager;
return service; // ✅ Preserves getters behavior
````
This ensures `externalWindow` getter is properly re-evaluated on each access and returns the current state of the external window.
In master a fix containing breaking changes will be made to improve the service.
opw-4948511
Forward-Port-Of: odoo/odoo#219296This 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. The change keeps exchange return stock movements aligned so the expected delivery cancellation happens correctly, reducing inventory confusion and manual cleanup.
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 Forward-Port-Of: odoo/odoo#218431
This fixes date and date-time default values in the website form builder so they display in the correct format and can be removed after being set. It helps website editors avoid confusing date displays and makes form setup behave as expected.
Original PR description
> [BLSE] After setting a default value for a date in a form, it is not possible to remove it
Editing a posted payment after resetting it to draft no longer clears its journal entry name unless the journal itself is changed. This prevents unnecessary new numbering when users update unrelated details like the amount, reducing confusion and avoiding unexpected gaps in accounting sequences.
Original PR description
Since PR #204507, the move name is reset whenever a payment with a `move_id` is modified, which was intended to allow changing the journal. However, this also resets the journal entry name unnecessarily when unrelated fields (e.g. amount) are updated. This causes confusion for users, especially when the payment is re-posted and a new sequence is generated, leading to gaps in the journal entry numbering without any apparent reason. This fix ensures the journal entry name is only reset when the `journal_id` field is updated. Steps to reproduce: 1. Create a payment and post it 2. Reset it to draft 3. Change the amount 4. Check the journal entry name → it is reset to '/' 4. Repost the payment, and a new sequence is generated Ticket [link](https://www.odoo.com/odoo/project/967/tasks/4886466) opw-4886466 Forward-Port-Of: odoo/odoo#218002 Forward-Port-Of: odoo/odoo#216214
Completed signing certificates are once again downloaded as separate files instead of being combined with the original PDF. People involved in a signing request, including signers and copied recipients, can now access and download the original documents while unrelated users remain excluded.
Original PR description
This PR targets reverting to the previous behavior where certificate of completion is never merged with the original PDF but downloaded separately. It also handles the downloading of completed original documents in the list form/view: - For users who are involved in a sign request (either as a signer or CC'd), the original documents are now available for download. They are now granted read access to the related sign documents. - This ensures that any user who is asked to sign or is CC'd on a sign request can view and download the original documents, without exposing templates or documents to unrelated users. task-id-4886240
Subscriptions with recurring products now require a recurring plan before previewing or starting payment. This prevents customers and sales teams from reaching payment steps that would fail later, making the subscription flow clearer and more reliable.
Original PR description
Reproduce: 1. Create a Subscription with a recurring product but without selecting a recurring plan 2. Click on "Preview" 3. Proceed to confirm and attempt to make a payment. Issue: - The subscription is treated as regular SO, and the make payment then raise Error - When generate a payment link or proceed to payment then raise Error Solution: - Add validation in the `action_preview_sale_order` method to raise `UserError` - Add validation during payment link generation: disable the payment button and display a warning message in the wizard to prevent proceeding task-4925735
Returned check approvals can now only be assigned to users in the Accounting Administrator or Bookkeeper groups. This prevents inappropriate users from being selected as approvers and helps maintain proper financial controls.
Original PR description
Before this commit: - In the account_return_check any user can be set as approver, regardless of the group. After this commit: - Only Accounting Administrator and Bookkeeper groups can be set as approver on the check. task-4934329
4 changes
Resolved issues and error corrections
Subscriptions that include both recurring and one-time products now correctly generate invoices for advance payments covering the next billing period. This prevents missed second-period invoices and helps keep subscription billing accurate.
Original PR description
Steps to Reproduce: 1. create a subscription with a recurring & non-recurring product(select monthly cleaning quatation) 2. Pay for the first period. 3. Now, try to pay the advance payment for the second period. The invoice is not generated for the second duration Issue: - The invoice is not generated for the second period. Cause: - The _get_partial_payment_subscription_transaction method incorrectly compares the sum of authorized, uninvoiced transactions with the total order amount. Solution: - Update the _get_partial_payment_subscription_transaction method to compare the sum of authorized, uninvoiced transaction amounts with the next billing period’s total instead of the full order total task-4780971 Forward-Port-Of: odoo/enterprise#85114
3 changes
Resolved issues and error corrections
When a field service task includes a kit product, its related delivery is now correctly validated when the task is marked done. This ensures delivered quantities update as expected and prevents orders from appearing undelivered despite the work being completed.
Original PR description
12 changes
Resolved issues and error corrections
Italian electronic invoice XML generation now excludes linked accounting documents dated after the document being sent. This prevents SDI rejections caused by references to future invoices or payments in credit note XML files.
Original PR description
In a FatturaElettronica xml document <DatiFattureCollegate> allow us to specify any references to other previously sent documents. However, it is currently possible that the system populate this element with moves dated after the current document, causing the SDI to reject the document. Steps to reproduce: - Create an invoice A and register a full payment via the button - Create a credit note for the invoice, unreconcile the credit note if necessary - Create a new invoice B and add the credit note as payment - Create the XML of the credit note Issue: The XML includes info about invoice B, created after the credit note. If invoice B is dated after the credit note, the SDI will reject the xml Solution: Avoid including reconciled elements with date later than the current document date opw-4795664 Forward-Port-Of: odoo/odoo#219106
When users download an electronic invoice XML from the send and print flow, the related file is now correctly added to Documents even if it is not emailed. This keeps accounting document records complete for Peppol e-invoicing workflows.
Original PR description
Event with the document integration correctly setup, e-invoice xml generated in the send&print wizard will not create an associated document unless the attachment is actually sent via mail Steps to reproduce: - Have a EU Company setup - Enable and configure Peppol Electronic Invoicing - Enable documents integration with accounting - Create an invoice to a Peppol enabled customer, confirm - Open send&print wizard, enable only 'Download' and 'BIS Billing 3.0' Issue: Document related to the xml attachment is not created. This will work as expected when the message is sent to the customer It occurs because, in case of xml attachment, we don't create an associated document until some attachment have been registered on the move, effectively delaying document creation until the mail attachments are created opw-4720588 Forward-Port-Of: odoo/enterprise#89977 Forward-Port-Of: odoo/enterprise#88746
Deferred accounting entries are now created even when the covered period is shorter than one month, such as only a few days within the same month. This helps ensure revenue or costs are allocated accurately for short invoice periods and avoids skipped deferrals.
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
Field service orders that include kit products now correctly validate their related delivery when the task is marked done. This prevents delivered quantities from staying at zero and keeps sales and delivery records aligned for kit-based work.
Original PR description
**Problem:** when the product in the sale order linked to a field service task is a kit and the task is marked as done, the delivery is not validate (as it would for a non kit product) **Steps to…
**Problem:** when the product in the sale order linked to a field service task is a kit and the task is marked as done, the delivery is not validate (as it would for a non kit product) **Steps to reproduce:** - Create a product and set up a Kit-type Bill of Materials for it (with at least two components) - Create a service-type product. - Set the Invoicing Policy to Prepaid/Fixed - set the "create on order" field to Task - assign the Project to Field Service. - Create a Sales Order using the service product. - Confirm the Sales Order. - In the linked task, click on the Products smart button - add the kit-type product from step 1. - Mark the task as done. **Current behavior:** On the sale order, the delivered quantity for the kit product is 0. If you click on the delivery smart button, you'll see that the picking is not validated yet **Expected behavior:** the picking should be validated **Cause of the issue:** https://github.com/odoo/enterprise/blob/d8dc0cabd83a29d0522cb5fd25c6956968d4408b/industry_fsm_stock/models/project_task.py#L23 the orer_line is considered as an exception because the order_line product_uom_qty is smaller than total_qty (the sum of the move_ids' product_uom_qty) But this is normal in the case of a kit opw-4848444 Forward-Port-Of: odoo/enterprise#89616 Forward-Port-Of: odoo/enterprise#88363
**Problem:** when the product in the sale order linked to a field service task is a kit and the task is marked as done, the delivery is not validate (as it would for a non kit product) **Steps to…
**Problem:** when the product in the sale order linked to a field service task is a kit and the task is marked as done, the delivery is not validate (as it would for a non kit product) **Steps to reproduce:** - Create a product and set up a Kit-type Bill of Materials for it (with at least two components) - Create a service-type product. - Set the Invoicing Policy to Prepaid/Fixed - set the "create on order" field to Task - assign the Project to Field Service. - Create a Sales Order using the service product. - Confirm the Sales Order. - In the linked task, click on the Products smart button - add the kit-type product from step 1. - Mark the task as done. **Current behavior:** On the sale order, the delivered quantity for the kit product is 0. If you click on the delivery smart button, you'll see that the picking is not validated yet **Expected behavior:** the picking should be validated **Cause of the issue:** https://github.com/odoo/enterprise/blob/d8dc0cabd83a29d0522cb5fd25c6956968d4408b/industry_fsm_stock/models/project_task.py#L23 the orer_line is considered as an exception because the order_line product_uom_qty is smaller than total_qty (the sum of the move_ids' product_uom_qty) But this is normal in the case of a kit opw-4848444 Forward-Port-Of: odoo/enterprise#89616 Forward-Port-Of: odoo/enterprise#88363
Restaurant bookings now show the number of guests entered during the reservation instead of incorrectly displaying zero or defaulting to table capacity. This helps staff see accurate party sizes and plan seating more reliably.
Original PR description
Currently when making an appointment for x amount of people, inside the restaurant it will show 0 as the number of people who booked. Steps to reproduce: ------------------- * Activate booking on the restaurant * Open the booking preview * Place a reservation for 5 people * In the restaurant and remove default filter > Observation: It shows 0p on the reservation Why the fix: ------------ By having a default value on the field is would not trigger the compute unless a change was made on `resource_ids` after the create was over. After fixing this bug we also aboserve that if we make a reservation for 1 person but all the tables in the restaurant are 4 person seatings, the reservation will show 4p. The reservation should in priority depend on the number entered while booking otherwise we can compute it regarding the resources. opw-4882681 Forward-Port-Of: odoo/enterprise#90277 Forward-Port-Of: odoo/enterprise#88777
Returned check approvals can now only be assigned to users in the Accounting Administrator or Bookkeeper groups. This prevents inappropriate users from being selected as approvers and improves control over accounting approval workflows.
Original PR description
Before this commit: - In the account_return_check any user can be set as approver, regardless of the group. After this commit: - Only Accounting Administrator and Bookkeeper groups can be set as approver on the check. task-4934329 Forward-Port-Of: odoo/enterprise#90159
Project to-do activity counts now use each user's timezone to decide whether items are late, due today, or planned for the future. This prevents mismatches where dashboard counts and the activity list showed different results during certain hours of the day.
Original PR description
User timezone was not being used for activity states and thus the future, today, and late activities would be inaccurate. They were being computed with CURRENT_DATE through SQL which is based on the timezone that the SQL server is in. This would lead to there being a period of some hours based on the user timezone where the actual activities page that you click into and the systray showing different counts of activity states. For example, on our Odoo production database, activities that SF office members create on projects that were for tomorrow would show today after 5pm and when clicking on the today activities there would be nothing until midnight. Using the user timezone in order to compute what today is for them, then using this in the SQL query fixes this issue. This is the same behavior as the compute_state for the state field in mail.activity. opw-4893182
When a project task or subtask is assigned a milestone, it now uses the sales order item linked to that milestone instead of falling back to a parent task or project value. This prevents incorrect invoicing links after users manually clear and reassign milestones on sales-driven project tasks.
Original PR description
**Step to reprocduce :** 1. Install sale_project module 2. Create a product - type: Service - Invoice policy: based on the milestones - Create on order: Project & Task. 3. Create a sale order with…
**Step to reprocduce :**
1. Install sale_project module
2. Create a product
- type: Service
- Invoice policy: based on the milestones
- Create on order: Project & Task.
3. Create a sale order with that product and add two SO lines with different descriptions.
4. Confirm the sale order.
5. Click on the Tasks smart button in the sale order to open the generated tasks.
6. From one of the tasks (e.g., m1)
7. Manually remove the existing milestone and sales order item from the task.
8. Then assign a different milestone (e.g., m2) to the task.
9. The sale order item set different (e.g., m1) instead of the newly set milestone.
**Issue:**
When a task has its `milestone_id` and `sale_line_id` manually cleared, and a new milestone
is later assigned, the task does not get the correct Sales Order Item.
**Cause:**
In the `_compute_sale_line` method, the logic priority the parent task and project when
computing the `sale_line_id`, and only uses the `milestone_id.sale_line_id` as a fallback.
https://github.com/odoo/odoo/blob/259f7eafb15882807640a00cf6939129f27c8fbb/addons/sale_project/models/project_task.py#L109-L113
**Solution :**
To fix this `_compute_sale_line` method to priority the milestone's `sale_line_id`
when a milestone is explicitly set. This ensures that if the task’s milestone
changes, its sale line reflects the one from the milestone, even for subtasks.
opw-4701106Deleting a customer or address will no longer automatically remove related draft or cancelled sales orders. This prevents users from unknowingly losing orders when removing a partner that was only used as a shipping or invoicing address, and lets them review and handle those orders themselves.
Original PR description
On partner deletion, draft & cancelled orders were automatically deleted as well (to ease the deletion of 'unused' partners). Nevertheless, since both the main customer and the shipping and invoicing addresses were considered, the deletion of a partner might lead to the unexpected deletion of an order where the deleted partner was only the invoicing or shipping address. The user might not even be aware of it if they didn't enable the shipping/invoicing addresses setting. We believe it's better to drop this magical deletion and let the user be aware that there are orders related to the customer, so that they can handle it the way they want to, without the program deciding for them. opw-4866778 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
When settling a sales order in Point of Sale, the order lines are now reloaded from the server instead of relying on older cached data. This ensures cashiers see the latest quantities and prices after changes made in Sales or previous partial payments, reducing billing mistakes.
Original PR description
Steps to reproduce ------------------ 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTX is X as expected 4. Return to…
Steps to reproduce ------------------ 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTX is X as expected 4. Return to Sales order (in the sales app) 5. Edit QTY from X to Y and save 6. Go back to PoS 7. Delete the laoded Sales Order and load it again -> Notice that QTY is still X and not the updated Y!! Other Flow in frontend ---------------------- 1. Create a Sales Order, add a product with QTY = X 2. Open PoS 3. Load this same Sales order (by clicking "Settle the order"-> QTY is X as expected 4. Change the quantity manually, to pay for X - 1 5. Validate and pay for the order 6. Load the same Sales order again with "Settle the order" -> The quantity is still X and the price is the unit price times X!! Why the issue ------------- When settling the order, we get its value using _getSaleOrder which basically reads it from the cache. So it will read the old order lines having the old qty, and not the updated one. The fix ------- Instead of reading the lines from the cache, we read them direcly from the backend, to accomodate for cases where the data might have been changed on another device or has not been updated in the cache. opw-4819708 opw-4913397 Co-authored-by: Arthur Nanson <artn@odoo.com>
Odoo now blocks users from archiving a pricelist that is still linked to an active loyalty or promotional program. This prevents coupon codes from being rejected unexpectedly and keeps discount program setup consistent for sales teams.
Original PR description
**Step to Reproduce:** 1. Install `sale_loyalty` and `sale` 2. Enable the `Pricelists` option in the settings. 3. Create a pricelist named demo. 4. Create a Discount & Loyalty named `test program`…
**Step to Reproduce:**
1. Install `sale_loyalty` and `sale`
2. Enable the `Pricelists` option in the settings.
3. Create a pricelist named demo.
4. Create a Discount & Loyalty named `test program` with type `Discount Code`,
5. Assign the demo pricelist to the loyalty program.
6. Copy the discount code from the program’s conditional rules.
7. Archive the demo pricelist.
8. create sale order for any product.
9. Try to apply the copied coupon code.
**Observation:**
- An error is shown: "This code is invalid".
- check loyalty program `test program` pricelist field is empty, that suggesting it's valid for all pricelists, but the coupon still fails.
**Issue:**
- When a linked pricelist is archived, it's hidden in the UI, but the relation still exists in the relational table.
```17_sale=# select id,name,active from product_pricelist;
id | name | active
----+------------------------------------+--------
1 | {"en_US": "Default USD pricelist"} | t
2 | {"en_US": "new"} | f
(2 rows)
17_sale=# select * from loyalty_program_product_pricelist_rel;
loyalty_program_id | product_pricelist_id
--------------------+----------------------
5 | 2
(1 row)
```
- While filtering the domain for coupon, the condition is not satisfied due to the program's pricelist.
https://github.com/odoo/odoo/blob/94d727bd9ba38116d3e14188c730c7566744e9f0/addons/sale_loyalty/models/sale_order.py#L636-L647
**Solution:**
- Display a validation error to the user when trying to archive a pricelist
that is linked to any active promotional programs.
opw-4841678
---
I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Forward-Port-Of: odoo/odoo#214968Reinstalling the Amazon sales integration on databases with past Amazon sales could previously run out of memory. This change reduces the data loaded during setup, making reinstallations much more reliable and lowering peak memory use significantly.
Original PR description
Description ----------- On databases that had `sale_amazon` installed in the past, were used for sales for a certain period, then had the module uninstalled, and later attempted to re-install it, a…
Description ----------- On databases that had `sale_amazon` installed in the past, were used for sales for a certain period, then had the module uninstalled, and later attempted to re-install it, a memory error will occur. The peak memory usage stems from `sale.order.line._compute_is_service`. The reason the compute is triggered is because of the "re-creation" of the master data products `default_product` & `shipping_product`, which writes `type`, which the compute depends on. So the compute will be triggered for all `sale.order.line` records that had those products. This commit avoids the excessive memory usage by explicitly fetching the fields that are needed for the compute, which avoids fetching large fields like the different products' HTML descriptions. Benchmark --------- On a database with 400k+ `sale.order.line` with an amazon related product, installing `sale_amazon` peak memory usage was: | | Peak Mem. | |--------|-----------| | Before | 3.8 GiB | | After | 580 MiB | Reference --------- opw-4915892 --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
French electronic invoices sent through Peppol now use the expected XML identifier field. This prevents Peppol validation errors when companies send BIS Billing 3.0 invoices with French SIRET details.
Original PR description
### Issue: BIS3 XML is not valid for Peppol ### Steps to reproduce: - Install l10n_fr_facturx_chorus_pro and switch to french company - Activate peppol - Create a French customer - Under Sales and…
### Issue: BIS3 XML is not valid for Peppol ### Steps to reproduce: - Install l10n_fr_facturx_chorus_pro and switch to french company - Activate peppol - Create a French customer - Under Sales and Purchase tab, set SIRET to "11000201100044" - Under Accounting tab, set the following: - Invoice sending = Peppol - Einvoice format = BIS Billing 3.0 - peppol_eas = France SIRET - peppol endpoint = 11000201100044 - Use Invoice/Invoiced smart button, then select New to create an invoice for this french customer - Add any non-zero invoice line, then confirm - Send and print, send to peppol - Download the XML. The /PartyIdentification/ID element will have the schemeName attribute set. ### Cause: Previous [commit](https://github.com/odoo/odoo/commit/0f3a9dee5cf15fa978a1857c184413003147c4a6#diff-10c62c279423109c43458eab15a3177ff5592d6570451f890fead74389bc3740) added `schemeName`. But Peppol doesn't want any `schemeName`, see the [doc](https://docs.peppol.eu/poacc/billing/3.0/rules/ubl-tc434/UBL-DT-08/). ### Solution: The correct attribute here seems to be `schemeID`. See an [example from the docs of Peppol](https://docs.peppol.eu/poacc/billing/3.0/bis/#_parties_2). Change `schemeName` to `schemeID`. opw-4934436
This update prevents referral refusal notifications from being sent just because HR opens the refusal wizard. Notifications are now sent only after the refusal is confirmed and are attached to the correct referrer user records, avoiding unnecessary emails and improving email processing performance.
Original PR description
## [PERF] hr_referral: Send refusal notification to referrer's users Description ----------- Following https://github.com/odoo/enterprise/commit/764f9b6f513c90eb79935d9e8469989ea704b61b,…
## [PERF] hr_referral: Send refusal notification to referrer's users Description ----------- Following https://github.com/odoo/enterprise/commit/764f9b6f513c90eb79935d9e8469989ea704b61b, `_send_notification` will not attach the message on the `hr.applicant` itself, so a `model` was provided. But due to a missing `res_id`, `message_notify` will set both `model` & `res_id` to `False` since both are not specified. This leads to the creation of a `mail.message` with no `res_id` and no `model` (as `self` is an empty `mail.thread` recordset). This leads to a performance regression when mail references need to be computed to attach to the notification in `_notify_by_email_get_base_mail_values`, due to the missing `model` and `res_id` of the message. This commit attaches the notification to the referrer's users instead, providing its `model` and `res_id`. Reference --------- opw-4943488 --- ## [FIX] hr_referral: Do not send notif when opening the refuse wizard Description ----------- Currently, when opening the refusal wizard for an applicant, a call to `archive_applicant` is made. However, there is an override of it in `hr_referral` to send a notification for the applicant's refusal, and closing the `referral_state`, even though the applicant may have not been provided a reason for refusal, and the HR can simply close the wizard instead of confirming it. This commit removes the override of `archive_applicant` and moves its logic into `action_refuse_reason_apply` which is called when the wizard is confirmed. Reference --------- opw-4943488 Forward-Port-Of: odoo/enterprise#90309
Fixes an error that could prevent users from reconfirming a loan after cancellation when Accounting Audit Trail is enabled. This ensures loan workflows remain usable even when past posted accounting entries must be preserved for compliance.
Original PR description
Steps: - Activate Audit Trail in Accounting configuration - Create and confirm a loan, having some moves posted in the past - Cancel it, reset it to draft the re-confirm it again -> ValueError: Expected singleton This is because posted moves can not be unlinked when canceling/closing the loan if audit trail is activated. Therefore we try to access the `state` field from a recordset instead of a singleton. With this commit, we filter the generated move to get the newly created one. opw-4834361
This fix prevents the Barcode app from storing invalid empty values while scanning lots during receipt operations. It avoids a crash when users scan multiple lots, helping warehouse teams complete incoming shipments reliably.
Original PR description
## How to reproduce: https://github.com/user-attachments/assets/bf44f9fd-0402-4d70-8b55-5baf192d42e8 - Enable Consignment - On Receipt operation type, enable 'Use existing lots' - Create product P,…
## How to reproduce:
https://github.com/user-attachments/assets/bf44f9fd-0402-4d70-8b55-5baf192d42e8
- Enable Consignment
- On Receipt operation type, enable 'Use existing lots'
- Create product P, tracked by lot
- Create lot SN-001 & SN-002
- Add 1 unit on hand with lot SN-001
- Create Receipt for 10 units of P -> Confirm
- Open receipt on Barcode App
- Scan "SN-002" => 'undefined' value added to 'dbQuantCache'
- Scan "SN-001" => Uncaught Promise > quantsByLocation is not iterable (cannot read property undefined)
---
## Test result without fix:
```
2025-07-18 09:30:33,801 20801 ERROR oes_test_18 odoo.addons.stock_barcode.tests.test_barcode_client_action_picking: FAIL: TestPickingBarcodeClientAction.test_barcode_lazy_cache_scan_two_lots
Traceback (most recent call last):
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/enterprise/stock_barcode/tests/test_barcode_client_action_picking.py", line 3508, in test_barcode_lazy_cache_scan_two_lots
self.start_tour(url, 'test_barcode_lazy_cache_scan_two_lots', login='admin')
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/odoo/odoo/tests/common.py", line 2264, in start_tour
return self.browser_js(url_path=url_path, code=code, ready=ready, timeout=timeout, success_signal="tour succeeded", **kwargs)
File "/home/odoo/projects/odoo-src/multiverse/src/18.0/odoo/odoo/tests/common.py", line 2235, in browser_js
self.fail('%s\n\n%s' % (message, error))
AssertionError: The test code "odoo.startTour('test_barcode_lazy_cache_scan_two_lots', {"stepDelay": 0, "keepWatchBrowser": false, "debug": false, "startUrl": "/odoo/147/action-stock_barcode.stock_barcode_picking_client_action", "delayToCheckUndeterminisms": 0})" failed
TypeError: quantsByLocation is not iterable (cannot read property undefined)
at LazyBarcodeCache.getQuants (http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21482:279)
at BarcodePickingModel._processBarcode (http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21748:631)
at async http://127.0.0.1:8565/web/assets/3d6bda7/web.assets_web.min.js:21661:75
```
OPW-4942192Project profitability now includes relevant budget lines even when a project’s analytic account is linked through a different analytic plan. This prevents missing budget information after upgrades or account-plan mismatches, giving users a more complete view of project finances.
Original PR description
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have…
In version 17.3, the analytic mixin was introduced in budget.line model to allow to link a budget line to multiple analytic accounts belonging to different analytic plans. The issue is that we have not adapted the code in project profitability, to take those changes into account. A problematic situation could be the following: 1. We have a project where the account "X" is set to the main project plan (the first one) "Projects" BUT the account "X" actually belongs to the analytic plan "Departments" (yes, it's possible that there is a mismatch between the project plan and the analytic plan, especially after the 18.0 upgrade where "analytic_account_id" just became "account_id", no matter in which plan it was). 2. We have a budget line linked to the account "X" for the plan "Departments". 3. We want to display the budget lines in project profitability, but this line does not appear. That's because we currently only look for the budget lines belonging to the analytic plan "Projects" aka the main/first plan, that match the account "X" of the project. But as account "X" actually belongs to the analytic plan "Departments", no budget lines are found. task-4901400 version-18.0