[FIX] pos_loyalty: zero division when reward product has zero price
The issue occurred when a loyalty program's rule was set to be based on money spent, and the reward was a free product with a sale price of zero. This caused a zero division error in the code, resulting in the remaining points becoming NaN after the reward was obtained in the point of sale. opw-3253366 closes odoo/odoo#123123 X-original-commit: 1eaca074741157e42c12da22e945a1817e7ceec3 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com> Signed-off-by: Pedram Bi Ria (pebr) <pebr@odoo.com>
This commit is contained in:
@@ -1516,14 +1516,20 @@ patch(Order.prototype, "pos_loyalty.Order", {
|
||||
}
|
||||
return result;
|
||||
}, 0);
|
||||
const correction = shouldCorrectRemainingPoints
|
||||
? this._getPointsCorrection(reward.program_id)
|
||||
: 0;
|
||||
freeQty = computeFreeQuantity(
|
||||
(remainingPoints - correction) / factor,
|
||||
reward.required_points / factor,
|
||||
reward.reward_product_qty
|
||||
);
|
||||
if (factor === 0) {
|
||||
freeQty = Math.floor(
|
||||
(remainingPoints / reward.required_points) * reward.reward_product_qty
|
||||
);
|
||||
} else {
|
||||
const correction = shouldCorrectRemainingPoints
|
||||
? this._getPointsCorrection(reward.program_id)
|
||||
: 0;
|
||||
freeQty = computeFreeQuantity(
|
||||
(remainingPoints - correction) / factor,
|
||||
reward.required_points / factor,
|
||||
reward.reward_product_qty
|
||||
);
|
||||
}
|
||||
} else {
|
||||
freeQty = Math.floor(
|
||||
(remainingPoints / reward.required_points) * reward.reward_product_qty
|
||||
|
||||
@@ -140,3 +140,24 @@ PosLoyalty.check.orderTotalIs("6.40");
|
||||
PosLoyalty.exec.finalizeOrder("Cash", "10");
|
||||
|
||||
registry.category("web_tour.tours").add("PosLoyaltyLoyaltyProgram2", { 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', '2');
|
||||
ProductScreen.do.clickPartnerButton();
|
||||
ProductScreen.do.clickCustomer('Test Partner AAA');
|
||||
|
||||
// At this point, the free_product program is triggered.
|
||||
// The reward button should be highlighted.
|
||||
PosLoyalty.check.isRewardButtonHighlighted(true);
|
||||
PosLoyalty.do.claimReward("Free Product - Whiteboard Pen");
|
||||
PosLoyalty.check.hasRewardLine('Free Product - Whiteboard Pen', '0.0', '1.00');
|
||||
|
||||
PosLoyalty.check.orderTotalIs('10.2');
|
||||
PosLoyalty.exec.finalizeOrder('Cash', '10.2');
|
||||
|
||||
registry.category("web_tour.tours").add("PosLoyaltyLoyaltyProgram3", { test: true, url: "/pos/web", steps: getSteps() });
|
||||
|
||||
@@ -377,6 +377,50 @@ class TestUi(TestPointOfSaleHttpCommon):
|
||||
reward_orderline = self.main_pos_config.current_session_id.order_ids[-1].lines.filtered(lambda line: line.is_reward_line)
|
||||
self.assertEqual(len(reward_orderline.ids), 0, msg='Reference: Order4_no_reward. Last order should have no reward line.')
|
||||
|
||||
def test_loyalty_free_product_zero_sale_price_loyalty_program(self):
|
||||
# In this program, each $ spent gives 1 point.
|
||||
# 5 points can be used to get a free whiteboard pen.
|
||||
# and the whiteboard pen sale price is zero
|
||||
self.pos_user.write({
|
||||
'groups_id': [
|
||||
(4, self.env.ref('stock.group_stock_user').id),
|
||||
]
|
||||
})
|
||||
self.whiteboard_pen.write({'lst_price': 0})
|
||||
|
||||
loyalty_program = self.env['loyalty.program'].create({
|
||||
'name': 'Loyalty Program',
|
||||
'program_type': 'loyalty',
|
||||
'trigger': 'auto',
|
||||
'applies_on': 'both',
|
||||
'rule_ids': [(0, 0, {
|
||||
'reward_point_amount': 1,
|
||||
'reward_point_mode': 'money',
|
||||
'minimum_qty': 1,
|
||||
})],
|
||||
'reward_ids': [(0, 0, {
|
||||
'reward_type': 'product',
|
||||
'reward_product_id': self.whiteboard_pen.id,
|
||||
'reward_product_qty': 1,
|
||||
'required_points': 5,
|
||||
})],
|
||||
})
|
||||
|
||||
(self.promo_programs | self.coupon_program).write({'active': False})
|
||||
|
||||
partner_aaa = self.env['res.partner'].create({'name': 'Test Partner AAA'})
|
||||
|
||||
self.start_tour(
|
||||
"/pos/web?config_id=%d" % self.main_pos_config.id,
|
||||
"PosLoyaltyLoyaltyProgram3",
|
||||
login="pos_user",
|
||||
)
|
||||
|
||||
aaa_loyalty_card = loyalty_program.coupon_ids.filtered(lambda coupon: coupon.partner_id.id == partner_aaa.id)
|
||||
|
||||
self.assertEqual(loyalty_program.pos_order_count, 1)
|
||||
self.assertAlmostEqual(aaa_loyalty_card.points, 5.2)
|
||||
|
||||
def test_pos_loyalty_tour_max_amount(self):
|
||||
"""Test the loyalty program with a maximum amount and product with different taxe."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user