From 52d7b2da2e1bff106636c76f82969c5a0e51cc6c Mon Sep 17 00:00:00 2001 From: Ethan Vincent Date: Thu, 22 Feb 2024 08:44:12 +0100 Subject: [PATCH] [FIX] loyalty: prevent product id overwriting **Current behavior:** Creating a promo type loyalty program and editing the 'products' field in the 'Among' section of the rule created by default at the bottom of the form view before saving the program will cause the products selected in this field to be cleared upon saving the program. **Expected behavior:** Filling out this field of the default rule before saving the overarching loyalty program should result in the same behavior as doing so after saving the program. That is, the field should save the user's input. **Steps to reproduce:** 1. Create a new loyalty program in the Discount & Loyalty tab 2. Give it a name and, before saving the program, edit the 'Products' field of the default rule that is created at the bottom of the form to have at least one value 3. Now save the program and observe that the 'Products' field has been cleared of the previously selected values **Cause of the issue:** In the form view for the loyalty.program there are two instances of the field trigger_product_ids which are set to be invisible unless creating a specific program type. This field is set to be related to rule_ids.product_ids in its definition within the loyalty.program class definition. Thus, when the user saves the program and rule concurrently, the empty trigger_product_ids field overwrites the product_ids field and whatever the user had populated it with is cleared. The reason it only happens to the default rule and not ones which are manually added before saving the program is because in the traverse_related() method in fields.py, only the first record of the related field is returned to be modified. In this case, it means only the first rule's product_ids field is overwritten. **Fix:** Overwrite the create() method in program.loyalty and check if the program being created is of type 'gift_card' or 'ewallet' then, if so, delete the trigger_product_ids key,val from the dictionary so it will not later override the products specified in the loyalty rule. opw-3669953 closes odoo/odoo#155093 X-original-commit: 7ed0a773b6e0711b127f236ce665c35202d973bc Signed-off-by: Vincent Ethan --- addons/loyalty/models/loyalty_program.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/addons/loyalty/models/loyalty_program.py b/addons/loyalty/models/loyalty_program.py index c3e414a9681..c4bdaeff2bd 100644 --- a/addons/loyalty/models/loyalty_program.py +++ b/addons/loyalty/models/loyalty_program.py @@ -598,3 +598,15 @@ class LoyaltyProgram(models.Model): })] }, } + + @api.model_create_multi + def create(self, vals_list): + """ + trigger_product_ids will overwrite product ids defined in a loyalty rule in certain instances. Thus, it should + be explicitly removed from an incoming vals dict unless, of course, it was actually a visible field. + """ + for vals in vals_list: + if 'trigger_product_ids' in vals and vals['program_type'] not in ['gift_card', 'ewallet']: + del vals['trigger_product_ids'] + + return super().create(vals_list)