[MERGE] from master
[odoo/odoo.git] / addons / pos_loyalty / loyalty.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 import logging
23
24 import openerp
25
26 from openerp import tools
27 from openerp.osv import fields, osv
28 from openerp.tools.translate import _
29
30 _logger = logging.getLogger(__name__)
31
32 class loyalty_program(osv.osv):
33     _name = 'loyalty.program'
34     _columns = {
35         'name' :        fields.char('Loyalty Program Name', size=32, select=1,
36              required=True, help="An internal identification for the loyalty program configuration"),
37         'pp_currency':  fields.float('Points per currency',help="How many loyalty points are given to the customer by sold currency"),
38         'pp_product':   fields.float('Points per product',help="How many loyalty points are given to the customer by product sold"),
39         'pp_order':     fields.float('Points per order',help="How many loyalty points are given to the customer for each sale or order"),
40         'rounding':     fields.float('Points Rounding', help="The loyalty point amounts are rounded to multiples of this value."),
41         'rule_ids':     fields.one2many('loyalty.rule','loyalty_program_id','Rules'),
42         'reward_ids':   fields.one2many('loyalty.reward','loyalty_program_id','Rewards'),
43         
44     }
45     _defaults = {
46         'rounding': 1,
47     }
48
49 class loyalty_rule(osv.osv):
50     _name = 'loyalty.rule'
51     _columns = {
52         'name':                 fields.char('Name', size=32, select=1, required=True, help="An internal identification for this loyalty program rule"),
53         'loyalty_program_id':   fields.many2one('loyalty.program', 'Loyalty Program', help='The Loyalty Program this exception belongs to'),
54         'type':                 fields.selection((('product','Product'),('category','Category')), 'Type', required=True, help='Does this rule affects products, or a category of products ?'),
55         'product_id':           fields.many2one('product.product','Target Product',  help='The product affected by the rule'),
56         'category_id':          fields.many2one('pos.category',   'Target Category', help='The category affected by the rule'),
57         'cumulative':           fields.boolean('Cumulative',        help='The points won from this rule will be won in addition to other rules'),
58         'pp_product':           fields.float('Points per product',  help='How many points the product will earn per product ordered'),
59         'pp_currency':          fields.float('Points per currency', help='How many points the product will earn per value sold'),
60     }
61     _defaults = {
62         'type':'product',
63     }
64
65
66 class loyalty_reward(osv.osv):
67     _name = 'loyalty.reward'
68     _columns = {
69         'name':                 fields.char('Name', size=32, select=1, required=True, help='An internal identification for this loyalty reward'),
70         'loyalty_program_id':   fields.many2one('loyalty.program', 'Loyalty Program', help='The Loyalty Program this reward belongs to'),
71         'minimum_points':       fields.float('Minimum Points', help='The minimum amount of points the customer must have to qualify for this reward'),
72         'type':                 fields.selection((('gift','Gift'),('discount','Discount'),('resale','Resale')), 'Type', required=True, help='The type of the reward'),
73         'gift_product_id':           fields.many2one('product.product','Gift Product', help='The product given as a reward'),
74         'point_cost':           fields.float('Point Cost', help='The cost of the reward'),
75         'discount_product_id':  fields.many2one('product.product','Discount Product', help='The product used to apply discounts'),
76         'discount':             fields.float('Discount',help='The discount percentage'),
77         'point_product_id':    fields.many2one('product.product', 'Point Product', help='The product that represents a point that is sold by the customer'),
78     }
79
80     def _check_gift_product(self, cr, uid, ids, context=None):
81         for reward in self.browse(cr, uid, ids, context=context):
82             if reward.type == 'gift':
83                 return bool(reward.gift_product_id)
84             else:
85                 return True
86
87     def _check_discount_product(self, cr, uid, ids, context=None):
88         for reward in self.browse(cr, uid, ids, context=context):
89             if reward.type == 'discount':
90                 return bool(reward.discount_product_id)
91             else:
92                 return True
93
94     def _check_point_product(self, cr, uid, ids, context=None):
95         for reward in self.browse(cr, uid, ids, context=context):
96             if reward.type == 'resale':
97                 return bool(reward.point_product_id)
98             else:
99                 return True
100
101     _constraints = [
102         (_check_gift_product,     "The gift product field is mandatory for gift rewards",         ["type","gift_product_id"]),
103         (_check_discount_product, "The discount product field is mandatory for discount rewards", ["type","discount_product_id"]),
104         (_check_point_product,    "The point product field is mandatory for point resale rewards", ["type","discount_product_id"]),
105     ]
106
107 class pos_config(osv.osv):
108     _inherit = 'pos.config' 
109     _columns = {
110         'loyalty_id': fields.many2one('loyalty.program','Loyalty Program', help='The loyalty program used by this point_of_sale'),
111         
112     }
113
114 class res_partner(osv.osv):
115     _inherit = 'res.partner'
116     _columns = {
117         'loyalty_points': fields.float('Loyalty Points', help='The loyalty points the user won as part of a Loyalty Program')
118     }
119
120 class pos_order(osv.osv):
121     _inherit = 'pos.order'
122
123     _columns = {
124         'loyalty_points': fields.float('Loyalty Points', help='The amount of Loyalty points the customer won or lost with this order'),
125     }
126
127     def _order_fields(self, cr, uid, ui_order, context=None):
128         fields = super(pos_order,self)._order_fields(cr,uid,ui_order,context)
129         fields['loyalty_points'] = ui_order.get('loyalty_points',0)
130         return fields
131
132     def create_from_ui(self, cr, uid, orders, context=None):
133         ids = super(pos_order,self).create_from_ui(cr,uid,orders,context=context)
134         for order in orders:
135             if order['data']['loyalty_points'] != 0 and order['data']['partner_id']:
136                 partner = self.pool.get('res.partner').browse(cr,uid,order['data']['partner_id'], context=context)
137                 partner.write({'loyalty_points': partner['loyalty_points'] + order['data']['loyalty_points']})
138
139         return ids
140             
141              
142     
143
144
145