[FIX] pos_loyalty:reward should not affect point rewarded

Current behavior:
When creating a loyalty program, with a rules that award points for each
dollar spent, the value of the point was inconsistent because it was
taking the rewards into account.

Steps to reproduce:
- Create a loyalty program with a rule that award 0.1 point for each
  dollar spent, and a reward that gives 1$ per points.
- Create a product with a price of 265$.
- Open the PoS and create a new order for 1000$.
- Select a customer and pay the order.(The customer now have 100 points)
- Create a new order with the product created earlier, and apply the
  reward.
- The value of the reward shoudl be 126.5$ (100 points + 26.5 points
  from the current order) but it is not.

opw-3275585

closes odoo/odoo#129963

X-original-commit: 70256e5cf8359a09687acc3e2d4f8792ef4f9801
Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
Signed-off-by: Robin Engels (roen) <roen@odoo.com>
This commit is contained in:
roen-odoo
2023-07-28 00:27:54 +02:00
parent d032664770
commit 03145907b8
3 changed files with 117 additions and 48 deletions
@@ -803,7 +803,9 @@ patch(Order.prototype, "pos_loyalty.Order", {
qtyPerProduct[line.reward_product_id || line.get_product().id] =
lineQty;
}
orderedProductPaid += line.get_price_with_tax();
if (!line.is_reward_line) {
orderedProductPaid += line.get_price_with_tax();
}
}
}
if (totalProductQty < rule.minimum_qty) {
@@ -2,23 +2,24 @@
import { PosLoyalty } from "@pos_loyalty/../tests/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";
registry
.category("web_tour.tours")
.add("PosLoyaltyTour1", {
test: true,
url: "/pos/web",
.add("PosLoyaltyTour1", {
test: true,
url: "/pos/web",
steps: () => {
// --- PoS Loyalty Tour Basic Part 1 ---
// Generate coupons for PosLoyaltyTour2.
startSteps();
ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickHomeCategory();
// basic order
// just accept the automatically applied promo program
// applied programs:
@@ -28,7 +29,7 @@ registry
PosLoyalty.do.selectRewardLine("on the cheapest product");
PosLoyalty.check.orderTotalIs("13.12");
PosLoyalty.exec.finalizeOrder("Cash", "20");
// remove the reward from auto promo program
// no applied programs
ProductScreen.exec.addOrderline("Whiteboard Pen", "6");
@@ -37,7 +38,7 @@ registry
PosLoyalty.exec.removeRewardLine("90% on the cheapest product");
PosLoyalty.check.orderTotalIs("19.2");
PosLoyalty.exec.finalizeOrder("Cash", "20");
// order with coupon code from coupon program
// applied programs:
// - coupon program
@@ -50,7 +51,7 @@ registry
PosLoyalty.do.enterCode("1234");
PosLoyalty.check.hasRewardLine("Free Product - Desk Organizer", "-15.30");
PosLoyalty.exec.finalizeOrder("Cash", "50");
// Use coupon but eventually remove the reward
// applied programs:
// - on cheapest product
@@ -64,7 +65,7 @@ registry
PosLoyalty.exec.removeRewardLine("Free Product");
PosLoyalty.check.orderTotalIs("62.27");
PosLoyalty.exec.finalizeOrder("Cash", "90");
// specific product discount
// applied programs:
// - on cheapest product
@@ -78,23 +79,23 @@ registry
PosLoyalty.check.hasRewardLine("50% on specific products", "-16.66"); // 17.55 - 1.78*0.5
PosLoyalty.check.orderTotalIs("37.78");
PosLoyalty.exec.finalizeOrder("Cash", "50");
return getSteps();
}
return getSteps();
}
});
registry
.category("web_tour.tours")
.add("PosLoyaltyTour2", {
test: true,
url: "/pos/web",
.add("PosLoyaltyTour2", {
test: true,
url: "/pos/web",
steps: () => {
// --- PoS Loyalty Tour Basic Part 2 ---
// Using the coupons generated from PosLoyaltyTour1.
startSteps();
ProductScreen.do.clickHomeCategory();
// Test that global discount and cheapest product discounts can be accumulated.
// Applied programs:
// - global discount
@@ -108,7 +109,7 @@ registry
PosLoyalty.check.hasRewardLine("10% on your order", "-1.64");
PosLoyalty.check.orderTotalIs("60.63"); //SUBTOTAL
PosLoyalty.exec.finalizeOrder("Cash", "70");
// Scanning coupon twice.
// Also apply global discount on top of free product to check if the
// calculated discount is correct.
@@ -137,7 +138,7 @@ registry
PosLoyalty.do.enterCode("5678");
PosLoyalty.check.orderTotalIs("60.13");
PosLoyalty.exec.finalizeOrder("Cash", "65");
// Specific products discount (with promocode) and free product (1357)
// Applied programs:
// - discount on specific products
@@ -152,7 +153,7 @@ registry
PosLoyalty.check.hasRewardLine("50% on specific products", "-10.20");
PosLoyalty.check.orderTotalIs("10.20");
PosLoyalty.exec.finalizeOrder("Cash", "20");
// Check reset program
// Enter two codes and reset the programs.
// The codes should be checked afterwards. They should return to new.
@@ -170,23 +171,23 @@ registry
PosLoyalty.check.hasRewardLine("90% on the cheapest product", "-2.87");
PosLoyalty.check.orderTotalIs("16.27");
PosLoyalty.exec.finalizeOrder("Cash", "20");
return getSteps();
}
return getSteps();
}
});
registry
.category("web_tour.tours")
.add("PosLoyaltyTour3", {
test: true,
url: "/pos/web",
.add("PosLoyaltyTour3", {
test: true,
url: "/pos/web",
steps: () => {
// --- PoS Loyalty Tour Basic Part 3 ---
startSteps();
ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickHomeCategory();
ProductScreen.do.clickDisplayedProduct("Promo Product");
PosLoyalty.check.orderTotalIs("34.50");
ProductScreen.do.clickDisplayedProduct("Product B");
@@ -198,22 +199,22 @@ registry
PosLoyalty.check.hasRewardLine("100% on specific products", "21.82");
PosLoyalty.check.hasRewardLine("100% on specific products", "18.18");
PosLoyalty.check.orderTotalIs("49.50");
return getSteps();
}
return getSteps();
}
});
registry
.category("web_tour.tours")
.add("PosLoyaltyTour4", {
test: true,
url: "/pos/web",
.add("PosLoyaltyTour4", {
test: true,
url: "/pos/web",
steps: () => {
startSteps();
ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickHomeCategory();
ProductScreen.exec.addOrderline("Test Product 1", "1");
ProductScreen.exec.addOrderline("Test Product 2", "1");
ProductScreen.do.selectPriceList("Public Pricelist");
@@ -221,24 +222,44 @@ registry
PosLoyalty.check.orderTotalIs("0.00");
ProductScreen.do.selectPriceList("Test multi-currency");
PosLoyalty.check.orderTotalIs("0.00");
return getSteps();
}
return getSteps();
}
});
registry
.category("web_tour.tours")
.add("PosCouponTour5", {
test: true,
url: "/pos/web",
.add("PosCouponTour5", {
test: true,
url: "/pos/web",
steps: () => {
startSteps();
ProductScreen.do.clickHomeCategory();
ProductScreen.exec.addOrderline("Test Product 1", "1.00", "100");
PosLoyalty.do.clickDiscountButton();
PosLoyalty.do.clickConfirmButton();
ProductScreen.check.totalAmountIs("92.00");
return getSteps();
}
return getSteps();
}
});
//transform the last tour to match the new format
registry
.category("web_tour.tours")
.add("PosLoyaltyTour6", {
test: true,
url: "/pos/web",
steps: () => {
ProductScreen.do.confirmOpeningPopup();
ProductScreen.do.clickHomeCategory();
ProductScreen.do.clickPartnerButton();
ProductScreen.do.clickCustomer('AAA Partner');
ProductScreen.do.clickDisplayedProduct('Test Product A');
PosLoyalty.do.clickRewardButton();
SelectionPopup.do.clickItem("$ 1 per point on your order");
ProductScreen.check.totalAmountIs('138.50');
return getSteps();
}
});
+46
View File
@@ -1034,3 +1034,49 @@ class TestUi(TestPointOfSaleHttpCommon):
self.main_pos_config.open_ui()
self.start_tour('/pos/web?config_id=%d' % self.main_pos_config.id, 'PosLoyaltySpecificDiscountWithFreeProductTour', login='pos_user')
def test_point_per_money_spent(self):
"""Test the point per $ spent feature"""
LoyaltyProgram = self.env['loyalty.program']
(LoyaltyProgram.search([])).write({'pos_ok': False})
self.loyalty_program = self.env['loyalty.program'].create({
'name': 'Loyalty Program Test',
'program_type': 'loyalty',
'trigger': 'auto',
'applies_on': 'both',
'pos_ok': True,
'pos_config_ids': [Command.link(self.main_pos_config.id)],
'rule_ids': [(0, 0, {
'reward_point_mode': 'money',
'reward_point_amount': 0.1,
'minimum_amount': 1,
})],
'reward_ids': [(0, 0, {
'reward_type': 'discount',
'required_points': 1,
'discount': 1,
'discount_mode': 'per_point',
})],
})
self.product_a = self.env["product.product"].create({
"name": "Test Product A",
"type": "product",
"list_price": 265,
"available_in_pos": True,
"taxes_id": False,
})
partner_aaa = self.env['res.partner'].create({'name': 'AAA Partner'})
self.env['loyalty.card'].create({
'partner_id': partner_aaa.id,
'program_id': self.loyalty_program.id,
'points': 100,
})
self.main_pos_config.open_ui()
self.start_tour(
"/pos/web?config_id=%d" % self.main_pos_config.id,
"PosLoyaltyTour6",
login="pos_user",
)