_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'),
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'],
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);
+ }
}
}
},
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();
</group>
<separator string="Rules" colspan="4"/>
- <p>Rules change how loyalty points are earned for specific products</p>
+ <p>Rules change how loyalty points are earned for specific products or categories</p>
<field name="rule_ids" colspan="4" nolabel="1">
<tree string="Rules">
<field name="name" />
- <field name="product_id" />
<field name="pp_product" />
<field name="pp_currency" />
<field name="cumulative" />
<h1><field name="name" class="oe_inline"/></h1>
</div>
<group col="4">
- <field name="product_id" />
+ <group col='2'>
+ <field name="type" />
+ </group>
+ <group col='2'>
+ <field name="product_id" attrs="{ 'invisible':[('type','!=','product')], 'required':[('type','==','product')]}" />
+ <field name="category_id" attrs="{ 'invisible':[('type','!=','category')], 'required':[('type','==','category')]}"/>
+ </group>
+ </group>
+ <group col="6">
<field name="pp_product" />
<field name="pp_currency" />
<field name="cumulative" />
<field name="discount_product_id" attrs="{ 'invisible':[('type','!=','discount')], 'required':[('type','==','discount')] }"/>
</group>
<group>
- <field name="minimum_points" />
<field name="point_cost" />
+ <field name="minimum_points" />
</group>
</form>
</field>