From 100ad561119955da4f4ca5652dfd7df38582cdc8 Mon Sep 17 00:00:00 2001 From: "Jacky (trj)" Date: Thu, 8 Sep 2022 14:01:06 +0000 Subject: [PATCH] [ADD] pos_sale_loyalty: link between pos_sale and pos_loyalty This link module corrects some behaviors when both modules are installed and used. The loyalty programs of quotations and sales orders are properly handled by the Sale app and its corresponding loyalty module. Even when it is settled by the Point of Sale app, it is still properly being handled by the Sale loyalty module and it should continue as such. The loyalty programs of Point of Sale is not considering the order lines created by a quotation or sale order. closes odoo/odoo#99756 Signed-off-by: Masereel Pierre --- addons/pos_loyalty/static/src/js/Loyalty.js | 12 ++++++--- addons/pos_sale/models/sale_order.py | 5 +++- addons/pos_sale_loyalty/__init__.py | 4 +++ addons/pos_sale_loyalty/__manifest__.py | 23 ++++++++++++++++ addons/pos_sale_loyalty/models/__init__.py | 4 +++ addons/pos_sale_loyalty/models/sale_order.py | 13 ++++++++++ .../pos_sale_loyalty/static/src/js/models.js | 26 +++++++++++++++++++ 7 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 addons/pos_sale_loyalty/__init__.py create mode 100644 addons/pos_sale_loyalty/__manifest__.py create mode 100644 addons/pos_sale_loyalty/models/__init__.py create mode 100644 addons/pos_sale_loyalty/models/sale_order.py create mode 100644 addons/pos_sale_loyalty/static/src/js/models.js diff --git a/addons/pos_loyalty/static/src/js/Loyalty.js b/addons/pos_loyalty/static/src/js/Loyalty.js index 4a34b2b2ce5..4262c950c94 100644 --- a/addons/pos_loyalty/static/src/js/Loyalty.js +++ b/addons/pos_loyalty/static/src/js/Loyalty.js @@ -230,6 +230,10 @@ const PosLoyaltyOrderline = (Orderline) => class PosLoyaltyOrderline extends Ord } return super.set_quantity(...arguments); } + //to override + ignoreLoyaltyPoints() { + return false; + } } Registries.Model.extend(Orderline, PosLoyaltyOrderline); @@ -753,8 +757,9 @@ const PosLoyaltyOrder = (Order) => class PosLoyaltyOrder extends Order { let orderedProductPaid = 0; for (const line of orderLines) { - if ((!line.reward_product_id && (rule.any_product || rule.valid_product_ids.has(line.get_product().id))) || - (line.reward_product_id && (rule.any_product || rule.valid_product_ids.has(line.reward_product_id)))) { + if (((!line.reward_product_id && (rule.any_product || rule.valid_product_ids.has(line.get_product().id))) || + (line.reward_product_id && (rule.any_product || rule.valid_product_ids.has(line.reward_product_id)))) && + !line.ignoreLoyaltyPoints()){ // We only count reward products from the same program to avoid unwanted feedback loops if (line.reward_product_id) { const reward = this.pos.reward_by_id[line.reward_id]; @@ -781,7 +786,8 @@ const PosLoyaltyOrder = (Order) => class PosLoyaltyOrder extends Order { splitPoints.push(...Array.apply(null, Array(totalProductQty)).map((_) => {return {points: rule.reward_point_amount}})); } else if (rule.reward_point_mode === 'money') { for (const line of orderLines) { - if (line.is_reward_line || !(rule.valid_product_ids.has(line.get_product().id)) || line.get_quantity() <= 0) { + if (line.is_reward_line || !(rule.valid_product_ids.has(line.get_product().id)) || line.get_quantity() <= 0 + || line.ignoreLoyaltyPoints()) { continue; } const pointsPerUnit = round_precision(rule.reward_point_amount * line.get_price_with_tax() / line.get_quantity(), 0.01); diff --git a/addons/pos_sale/models/sale_order.py b/addons/pos_sale/models/sale_order.py index 01b3640ad2d..e4ed57333e1 100644 --- a/addons/pos_sale/models/sale_order.py +++ b/addons/pos_sale/models/sale_order.py @@ -52,8 +52,11 @@ class SaleOrderLine(models.Model): for sale_line in self: sale_line.qty_invoiced += sum([self._convert_qty(sale_line, pos_line.qty, 'p2s') for pos_line in sale_line.pos_order_line_ids], 0) + def _get_sale_order_fields(self): + return ["product_id", "name", "price_unit", "product_uom_qty", "tax_id", "qty_delivered", "qty_invoiced", "discount", "qty_to_invoice", "price_total"] + def read_converted(self): - field_names = ["product_id", "name", "price_unit", "product_uom_qty", "tax_id", "qty_delivered", "qty_invoiced", "discount", "qty_to_invoice", "price_total"] + field_names = self._get_sale_order_fields() results = [] for sale_line in self: if sale_line.product_type: diff --git a/addons/pos_sale_loyalty/__init__.py b/addons/pos_sale_loyalty/__init__.py new file mode 100644 index 00000000000..dc5e6b693d1 --- /dev/null +++ b/addons/pos_sale_loyalty/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/addons/pos_sale_loyalty/__manifest__.py b/addons/pos_sale_loyalty/__manifest__.py new file mode 100644 index 00000000000..071e997c157 --- /dev/null +++ b/addons/pos_sale_loyalty/__manifest__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + + +{ + 'name': 'pos_sale_loyalty', + 'version': '1.0', + 'category': 'Hidden', + 'sequence': 6, + 'summary': 'Link module between pos_sale and pos_loyalty', + 'description': """ +This module correct some behaviors when both module are installed. +""", + 'depends': ['pos_sale', 'pos_loyalty'], + 'installable': True, + 'auto_install': True, + 'assets': { + 'point_of_sale.assets': [ + 'pos_sale_loyalty/static/src/js/**/*.js', + ], + }, + 'license': 'LGPL-3', +} diff --git a/addons/pos_sale_loyalty/models/__init__.py b/addons/pos_sale_loyalty/models/__init__.py new file mode 100644 index 00000000000..00b62d54b4a --- /dev/null +++ b/addons/pos_sale_loyalty/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import sale_order diff --git a/addons/pos_sale_loyalty/models/sale_order.py b/addons/pos_sale_loyalty/models/sale_order.py new file mode 100644 index 00000000000..98641fb71ca --- /dev/null +++ b/addons/pos_sale_loyalty/models/sale_order.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class SaleOrderLine(models.Model): + _inherit = 'sale.order.line' + + def _get_sale_order_fields(self): + field_names = super()._get_sale_order_fields() + field_names.append('reward_id') + return field_names diff --git a/addons/pos_sale_loyalty/static/src/js/models.js b/addons/pos_sale_loyalty/static/src/js/models.js new file mode 100644 index 00000000000..6d823b7e72a --- /dev/null +++ b/addons/pos_sale_loyalty/static/src/js/models.js @@ -0,0 +1,26 @@ +/** @odoo-module alias=pos_sale_loyalty.models **/ + + +import { Orderline } from 'point_of_sale.models'; +import Registries from 'point_of_sale.Registries'; + +export const PosSaleLoyaltyOrderline = (Orderline) => class PosSaleLoyaltyOrderline extends Orderline { + //@override + ignoreLoyaltyPoints() { + if (this.sale_order_origin_id) { + return true; + } + return super.ignoreLoyaltyPoints(...arguments); + } + //@override + setQuantityFromSOL(saleOrderLine) { + // we need to consider reward product such as discount in a quotation + if (saleOrderLine.reward_id) { + this.set_quantity(saleOrderLine.product_uom_qty); + } else { + super.setQuantityFromSOL(...arguments); + } + } +}; + +Registries.Model.extend(Orderline, PosSaleLoyaltyOrderline);