Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][IMP] sale_loyalty_order_suggestion: Add hook method #205

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions sale_loyalty_order_suggestion/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,28 @@ def _get_available_programs(self):
]
return programs.filtered(lambda p: p.id not in programs_to_delete)

def _available_programs(self):
self.ensure_one()
def _filter_programs_by_rules_with_products(self):
"""Hook method. The objective of this method is to filter by rules that establish
products as criteria in a loyalty program and then in other methods make the
filtering that corresponds to each functionality."""
valid_programs = self._get_available_programs()
# Filters programs that have rules with minimum_qty > 0
programs_with_minimum_qty = valid_programs.filtered(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this module includes this minimum quantity criteria?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of this module is to suggest promotions on order lines whose product is part of the rules of a promotion.

When the suggestion is made, it shows a gift icon which, when clicked, allows us to configure what is necessary for the promotion to be applicable (products and quantity to be added to the sales order).

By default, promotions in their rules consider the domain [ ] for the allowed products if a specific product is not set in their rules.

The rules of a promotion are not restrictive to each other but as soon as one is fulfilled, the promotion is applicable.

For this reason, and following the example of the DEMO promotion "Buy 3 large cabinets, get one for free" of the type "Buy X get Y", for a promotion to have its rules based on products, it is necessary to establish a quantity as the main criterion.

image

The rest of the types of promotions can also base their rules on products and that is why in this logic they are filtered by product quantity.

It should be clarified that the different types of promotions facilitate a more direct configuration (giving the configuration practically done) of the rules, but in reality we can configure anything as we need.

lambda x: any(rule.minimum_qty > 0 for rule in x.rule_ids)
)
return programs_with_minimum_qty

def _available_programs(self):
self.ensure_one()
filtered_programs = self._filter_programs_by_rules_with_products()
programs = self.env["loyalty.program"]
if programs_with_minimum_qty:
if filtered_programs:
product_id = self.env.context.get("product_id")
programs += programs_with_minimum_qty.filtered(
programs += filtered_programs.filtered(
lambda x: any(
product_id in rule._get_valid_products().ids for rule in x.rule_ids
product_id in rule._get_valid_products().ids
and rule.minimum_qty > 0
for rule in x.rule_ids
)
)
return programs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,15 @@ export class SuggestPromotionWidget extends Component {
}

async viewPromotionsWizard() {
const productId = this.props.record.data.product_id[0];
const SuggestedPromotions = this.getSuggestedPromotions();
const record = this.__owl__.parent.parent.parent.props.record;
await record.save();
this.actionService.doAction("sale_loyalty.sale_loyalty_reward_wizard_action", {
additionalContext: {
default_active_id: record.data.id,
default_order_id: record.data.id,
default_product_id: productId,
default_reward_ids: SuggestedPromotions,
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ class SaleLoyaltyRewardWizard(models.TransientModel):
_inherit = "sale.loyalty.reward.wizard"
_description = "Sale Loyalty - Reward Selection Wizard"

product_id = fields.Many2one("product.product")
# To ensure whether the selected promotion satisfies your rules and is directly
# applicable or needs to satisfy your rules to be applied.
applicable_program = fields.Boolean(
Expand Down Expand Up @@ -34,6 +35,7 @@ def _compute_applicable_promotion(self):

@api.depends("selected_reward_id")
def _compute_loyalty_rule_line_ids(self):
self.loyalty_rule_line_ids = None
units_required = min(
self.selected_reward_id.program_id.rule_ids.mapped("minimum_qty"), default=0
)
Expand Down Expand Up @@ -65,8 +67,6 @@ def _compute_loyalty_rule_line_ids(self):
)
)
self.loyalty_rule_line_ids = lines_vals
else:
self.loyalty_rule_line_ids = None

@api.depends_context("lang")
@api.depends("selected_reward_id")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/>
<field name="arch" type="xml">
<field name="selected_product_id" position="after">
<field name="product_id" invisible="1" />
<field name="applicable_program" invisible="1" />
<field
name="loyalty_rule_line_description"
Expand Down
Loading