diff --git a/addons/pos_loyalty/loyalty.py b/addons/pos_loyalty/loyalty.py index e6b059d9e84..ef3d5d4d924 100644 --- a/addons/pos_loyalty/loyalty.py +++ b/addons/pos_loyalty/loyalty.py @@ -51,18 +51,24 @@ class loyalty_rule(osv.osv): _columns = { 'name': fields.char('Name', size=32, select=1, required=True, help="An internal identification for this loyalty program rule"), 'loyalty_program_id': fields.many2one('loyalty.program', 'Loyalty Program', help='The Loyalty Program this exception belongs to'), - 'product_id': fields.many2one('product.product','Target Product', help='The product affected by the rule'), - 'cumulative': fields.boolean('Cumulative', help='The points won from this rule will be won in addition to other rules'), + 'type': fields.selection((('product','Product'),('category','Category')), 'Type', required=True, help='Does this rule affects products, or a category of products ?'), + 'product_id': fields.many2one('product.product','Target Product', help='The product affected by the rule'), + 'category_id': fields.many2one('pos.category', 'Target Category', help='The category affected by the rule'), + 'cumulative': fields.boolean('Cumulative', help='The points won from this rule will be won in addition to other rules'), 'pp_product': fields.float('Points per product', help='How many points the product will earn per product ordered'), 'pp_currency': fields.float('Points per currency', help='How many points the product will earn per value sold'), } + _defaults = { + 'type':'product', + } + class loyalty_reward(osv.osv): _name = 'loyalty.reward' _columns = { 'name': fields.char('Name', size=32, select=1, required=True, help='An internal identification for this loyalty reward'), 'loyalty_program_id': fields.many2one('loyalty.program', 'Loyalty Program', help='The Loyalty Program this reward belongs to'), - 'minimum_points': fields.float('Minimum Points', help='The minimum amount of points the customer must have to be eligible for this reward'), + 'minimum_points': fields.float('Minimum Points', help='The minimum amount of points the customer must have to qualify for this reward'), 'type': fields.selection((('gift','Gift'),('discount','Discount')), 'Type', required=True, help='The type of the reward'), 'gift_product_id': fields.many2one('product.product','Gift Product', help='The product given as a reward'), 'point_cost': fields.float('Point Cost', help='The cost of the reward'), diff --git a/addons/pos_loyalty/static/src/js/loyalty.js b/addons/pos_loyalty/static/src/js/loyalty.js index 766a5d3efc6..4b1c1f3a64d 100644 --- a/addons/pos_loyalty/static/src/js/loyalty.js +++ b/addons/pos_loyalty/static/src/js/loyalty.js @@ -9,9 +9,9 @@ openerp.pos_loyalty = function(instance){ var model = models[i]; if (model.model === 'res.partner') { model.fields.push('loyalty_points'); - } else if (model.model === 'pos.config') { - // load loyalty after pos.config - models.splice(i+1,0,{ + } else if (model.model === 'product.product') { + // load loyalty after products + models.push(i+1,0,{ model: 'loyalty.program', condition: function(self){ return !!self.config.loyalty_id[0]; }, fields: ['name','pp_currency','pp_product','pp_order','rounding'], @@ -26,15 +26,27 @@ openerp.pos_loyalty = function(instance){ self.loyalty.rules = rules; self.loyalty.rules_by_product_id = {}; + self.loyalty.rules_by_category_id = {}; for (var i = 0; i < rules.length; i++){ var rule = rules[i]; - if (!self.loyalty.rules_by_product_id[rule.product_id[0]]) { - self.loyalty.rules_by_product_id[rule.product_id[0]] = [rule]; - } else if (rule.cumulative) { - self.loyalty.rules_by_product_id[rule.product_id[0]].unshift(rule); - } else { - self.loyalty.rules_by_product_id[rule.product_id[0]].push(rule); + if (rule.type === 'product') { + if (!self.loyalty.rules_by_product_id[rule.product_id[0]]) { + self.loyalty.rules_by_product_id[rule.product_id[0]] = [rule]; + } else if (rule.cumulative) { + self.loyalty.rules_by_product_id[rule.product_id[0]].unshift(rule); + } else { + self.loyalty.rules_by_product_id[rule.product_id[0]].push(rule); + } + } else if (rule.type === 'category') { + var category = self.db.get_category_by_id(rule.category_id[0]); + if (!self.loyalty.rules_by_category_id[category.id]) { + self.loyalty.rules_by_category_id[category.id] = [rule]; + } else if (rule.cumulative) { + self.loyalty.rules_by_category_id[category.id].unshift(rule); + } else { + self.loyalty.rules_by_category_id[category.id].push(rule); + } } } }, @@ -80,12 +92,32 @@ openerp.pos_loyalty = function(instance){ var rule = rules[j]; total_points += round_pr(line.get_quantity() * rule.pp_product, rounding); total_points += round_pr(line.get_price_with_tax() * rule.pp_currency, rounding); - if (!rule.cumulative) { + // if affected by a non cumulative rule, skip the others. (non cumulative rules are put + // at the beginning of the list when they are loaded ) + if (!rule.cumulative) { overriden = true; break; } } + // Test the category rules + if ( product.pos_categ_id ) { + var category = this.pos.db.get_category_by_id(product.pos_categ_id[0]); + while (category && !overriden) { + var rules = this.pos.loyalty.rules_by_category_id[category.id] || []; + for (var j = 0; j < rules.length; j++) { + var rule = rules[j]; + total_points += round_pr(line.get_quantity() * rule.pp_product, rounding); + total_points += round_pr(line.get_price_with_tax() * rule.pp_currency, rounding); + if (!rule.cumulative) { + overriden = true; + break; + } + } + category = this.pos.db.get_category_by_id(this.pos.db.get_category_parent_id(category.id)); + } + } + if (!overriden) { product_sold += line.get_quantity(); total_sold += line.get_price_with_tax(); diff --git a/addons/pos_loyalty/views/views.xml b/addons/pos_loyalty/views/views.xml index 231c22eed92..9af7ebb3706 100644 --- a/addons/pos_loyalty/views/views.xml +++ b/addons/pos_loyalty/views/views.xml @@ -61,11 +61,10 @@ -

Rules change how loyalty points are earned for specific products

+

Rules change how loyalty points are earned for specific products or categories

- @@ -96,7 +95,15 @@

- + + + + + + + + + @@ -123,8 +130,8 @@ - +