Sunday, May 19, 2024
2 changes · 17.0
Resolved issues and error corrections
This fix corrects a bug in the POS loyalty program where loyalty points were being incorrectly calculated when applying discounts. Previously, discount lines were being counted as products, causing customers to earn extra loyalty points they shouldn't receive. Now, loyalty points are only granted for actual products purchased, not for discount rewards applied to the order.
Original PR description
### Steps to reproduce: - Install **POS** app. - Go to **POS** > **Products** > **Discount & Loyalty** - Create a New program with: - **Program Type:** Loyalty Cards - Conditional rules: - **Minimum…
### Steps to reproduce:
- Install **POS** app.
- Go to **POS** > **Products** > **Discount & Loyalty**
- Create a New program with:
- **Program Type:** Loyalty Cards
- Conditional rules:
- **Minimum Quantity:** 2
- **Grant:** 1 Loyalty Points per unit paid
- Rewards:
- **Reward Type:** Discount
- **Discount:** 100 % one Cheapest Product
- **In exchange of:** 2 Loyalty Points
- Start a new POS session
- Select a Customer
- Add two different products.
- Notice the Loyalty Points of **+2** shown. This is _Correct_
- Click on the **Reward** button
- Notice how the Loyalty Points are now **+3** which is obviously _wrong_ given we only have two products. Basically it's as if the reward line (100% discount) is taken into consideration as the cheapest product.
### Investigation:
- Inside `_updatePrograms`, `pointsForPrograms()` are calculated.
- we sum the lines quantities regardless of whether it's a reward line or not https://github.com/odoo/odoo/blob/e5c3ba58964f47cfd41d337e39e1bf25eaa25379/addons/pos_loyalty/static/src/js/Loyalty.js#L906
- By doing so, the reward lines are taken into consideration and the rule is triggerd by skipping this if clause https://github.com/odoo/odoo/blob/e5c3ba58964f47cfd41d337e39e1bf25eaa25379/addons/pos_loyalty/static/src/js/Loyalty.js#L917-L921
opw-3855323
Forward-Port-Of: odoo/odoo#165770
Forward-Port-Of: odoo/odoo#161503This fix optimizes how Odoo handles memory when updating large numbers of records, reducing memory consumption by approximately 95%. The improvement prevents MemoryError exceptions that commonly occur during system upgrades when processing thousands of records simultaneously, making upgrades more stable and reliable.
Original PR description
This is re-targeting https://github.com/odoo/odoo/pull/162442 to 16.0 Motivation: MemoryError exceptions when a large number of records on the same model have dirty fields. Such often happens during…
This is re-targeting https://github.com/odoo/odoo/pull/162442 to 16.0 Motivation: MemoryError exceptions when a large number of records on the same model have dirty fields. Such often happens during upgrades. In the current implementation, the cached data is re-arranged in multiple steps using local data structures. The most problematic is `id_vals[record.id][field.name]`, because it creates a dictionary with a potentially long field name (think studio fields) as key for each dirty record. For thousands of records, this quickly accumulates to 10s or even 100s of MiB in RAM. The idea of this patch is: 1. collect all dirty ids for all dirty fields on the model. This does not cost additional memory, since the ist of ids per field will be pop()'ed from the cache. 2. Walk over fields and ids collecting all fields and values of each id in the same loop, carefully consuming objects, while directly building the `updates` dictionary, without creating the intermediate data structures. This way, the _flush method only consumes a marginal amount of memory compared to the memory already consumed by the cache. Careful profiling (using `memray` for memory profiling, the odoo profiler for runtime profiling) of a testcase that flushes 80k records in 8 writes has shown this new version to consume roughly 95% less memory while running slightly faster. Forward-Port-Of: odoo/odoo#165393