Skip to content

Commit

Permalink
[FIX] pos_restaurant: Grant loyalty points for products only
Browse files Browse the repository at this point in the history
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

closes #162268

X-original-commit: 6336e45
Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
Signed-off-by: Ali Hassan Youssef (alhy) <alhy@odoo.com>
  • Loading branch information
AH-Yussef committed May 16, 2024
1 parent 93a3f02 commit 7b147e9
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
2 changes: 1 addition & 1 deletion addons/pos_loyalty/static/src/js/Loyalty.js
Original file line number Diff line number Diff line change
Expand Up @@ -988,7 +988,6 @@ patch(Order.prototype, "pos_loyalty.Order", {
const lineQty = line.reward_product_id
? -line.get_quantity()
: line.get_quantity();
totalProductQty += lineQty;
if (qtyPerProduct[line.reward_product_id || line.get_product().id]) {
qtyPerProduct[line.reward_product_id || line.get_product().id] +=
lineQty;
Expand All @@ -998,6 +997,7 @@ patch(Order.prototype, "pos_loyalty.Order", {
}
if (!line.is_reward_line) {
orderedProductPaid += line.get_price_with_tax();
totalProductQty += lineQty;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { PosLoyalty } from "@pos_loyalty/tours/PosLoyaltyTourMethods";
import { ProductScreen } from "@point_of_sale/../tests/tours/helpers/ProductScreenTourMethods";
import { SelectionPopup } from "@point_of_sale/../tests/tours/helpers/SelectionPopupTourMethods";
import { getSteps, startSteps } from "@point_of_sale/../tests/tours/helpers/utils";
import { registry } from "@web/core/registry";

Expand Down Expand Up @@ -173,3 +174,33 @@ ProductScreen.exec.addOrderline('Test Product 1', '1.00', '100');
ProductScreen.check.totalAmountIs('80.00');

registry.category("web_tour.tours").add("PosLoyaltyPromotion", { test: true, url: "/pos/web", steps: getSteps() });

startSteps();

ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickHomeCategory();

// Generates 10.2 points and use points to get the reward product with zero sale price
ProductScreen.exec.addOrderline('Desk Organizer', '3');
PosLoyalty.exec.finalizeOrder('Cash', '15.3');

registry.category("web_tour.tours").add('PosLoyaltyNextOrderCouponExpirationDate', { test: true, url: '/pos/web', steps: getSteps() });

startSteps();

ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickHomeCategory();

ProductScreen.do.clickPartnerButton();
ProductScreen.do.clickCustomer('Test Partner');

ProductScreen.exec.addOrderline('Desk Organizer', '1');
ProductScreen.exec.addOrderline('Whiteboard Pen', '1');

PosLoyalty.do.clickRewardButton();
SelectionPopup.do.clickItem("100% on the cheapest product");

PosLoyalty.check.orderTotalIs('5.10');
PosLoyalty.exec.finalizeOrder('Cash', '5.10');

registry.category("web_tour.tours").add('PosLoyaltyDontGrantPointsForRewardOrderLines', { test: true, url: '/pos/web', steps: getSteps() });
46 changes: 46 additions & 0 deletions addons/pos_loyalty/tests/test_frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -1671,3 +1671,49 @@ def test_promotion_with_min_amount_and_specific_product_rule(self):
'PosLoyaltyMinAmountAndSpecificProductTour',
login='pos_user',
)

def test_dont_grant_points_reward_order_lines(self):
"""
Make sure that points granted per unit are only given
for the product -non reward- lines!
"""
self.env['loyalty.program'].search([]).write({'active': False})

loyalty_program = self.env['loyalty.program'].create({
'name': 'Loyalty Program',
'program_type': 'loyalty',
'applies_on': 'both',
'trigger': 'auto',
'rule_ids': [(0, 0, {
'reward_point_amount': 1,
'reward_point_mode': 'unit',
'minimum_qty': 2,
})],
'reward_ids': [(0, 0, {
'reward_type': 'discount',
'discount': 100,
'discount_mode': 'percent',
'discount_applicability': 'cheapest',
'required_points': 2,
})],
})

partner = self.env['res.partner'].create({'name': 'Test Partner'})

self.pos_user.write({
'groups_id': [
(4, self.env.ref('stock.group_stock_user').id),
]
})

self.main_pos_config.open_ui()
self.start_tour(
"/pos/web?config_id=%d" % self.main_pos_config.id,
"PosLoyaltyDontGrantPointsForRewardOrderLines",
login="pos_user",
)

loyalty_card = loyalty_program.coupon_ids.filtered(lambda coupon: coupon.partner_id.id == partner.id)

self.assertTrue(loyalty_card)
self.assertFalse(loyalty_card.points)

0 comments on commit 7b147e9

Please sign in to comment.