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