Friday, July 25, 2025
4 changes · saas-18.1
Resolved issues and error corrections
Chart interactions in spreadsheets and dashboards now distinguish between clicks on the legend, chart elements, and the chart area itself. This prevents unintended dashboard actions when users only meant to interact with a chart legend, making chart use more reliable.
Original PR description
### [FIX] charts: avoid conflicting click listeners We have several click listeners on charts: one on the legend, one on all odoo chart elements, and one on the chart itself in dashboard. The first two are handled in ChartJS, and the last one is handled in a t-on-click. The problem is that the t-on-click was called for every click on the chart, even if the click was on the legend. This is because ChartJS handles events at the next animation frame, so the t-on-click was always called before the ChartJS click listener. To fix this, we also handle the click on the chart inside ChartJS. Task: [4636147](https://www.odoo.com/web#id=4636147&cids=1&menu_id=4720&action=333&active_id=2328&model=project.task&view_type=form) --- I confirm I have signed the CLA and read the PR guidelines at www.odoo.com/submit-pr
Tasks and subtasks linked to milestone-based services now keep the sales order item that matches the selected milestone. This prevents billing or tracking from being associated with the wrong sales order line after users manually change a task's milestone.
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-4701106
Forward-Port-Of: odoo/odoo#215213Odoo now blocks users from archiving a pricelist when it is still linked to an active discount or loyalty program. This prevents confusing situations where a coupon appears invalid even though the related program looks available, helping sales teams avoid broken promotions.
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#214968Archived or unpublished products are now automatically removed from shopping carts before customers can complete checkout. This prevents sales of products that are no longer available and keeps online orders aligned with the current catalog.
Original PR description
Fix issue where customers could complete purchases of products that where archived or unpublished after being added to cart but before checkout completion. => Step to reproduce bug : - Install website_sale. - Add a product to the cart. - (In an other window) archive the product. - finish the buy from the cart. (don't reload the cart or the product will be gone) => Cause: The bug originate from: https://github.com/odoo/odoo/blob/2d7bb960b00bfeae3e6ab8c0367237f3b08271cb/addons/website_sale/controllers/main.py#L1781-L1793 There is no check up during the last part of the transaction to verify if the product is still available. => Fix: Erase from the product from all cart when it's archived opw-4829872 Forward-Port-Of: odoo/odoo#213656