d969d2a9211fab97ee4a84ed0473fcdf48bbddbd
[odoo/odoo.git] / addons / website_sale / models / website.py
1 # -*- coding: utf-8 -*-
2 import uuid
3 from openerp.osv import orm, fields
4 from openerp.addons.web.http import request
5 from openerp import SUPERUSER_ID
6
7
8 class Website(orm.Model):
9     _inherit = 'website'
10
11     def _get_pricelist_id(self, cr, uid, ids, field_name, arg, context=None):
12         pricelist_id = self.ecommerce_get_pricelist_id(cr, uid, None, context=context)
13         return dict.fromkeys(ids, pricelist_id)
14
15     _columns = {
16         'pricelist_id': fields.function(
17             _get_pricelist_id, type='many2one', obj='product.pricelist')
18     }
19
20     # ************************************************************
21     # Ecommerce pricelist management
22     # ***********************************************************
23
24     def ecommerce_get_pricelist_id(self, cr, uid, ids, context=None):
25         if not request.httprequest.session.get('ecommerce_pricelist') or request.httprequest.session.get('ecommerce_pricelist_uid') != uid:
26             self._ecommerce_change_pricelist(cr, uid, None, context=context)
27         return request.httprequest.session.get('ecommerce_pricelist')
28
29     def _ecommerce_change_pricelist(self, cr, uid, code=None, context=None):
30         request.httprequest.session.setdefault('ecommerce_pricelist', False)
31
32         pricelist_id = False
33         if code:
34             pricelist_obj = self.pool.get('product.pricelist')
35             pricelist_ids = pricelist_obj.search(cr, SUPERUSER_ID, [('code', '=', code)], context=context)
36             if pricelist_ids:
37                 pricelist_id = pricelist_ids[0]
38
39         if not pricelist_id:
40             partner_id = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context).partner_id.id
41             pricelist_id = self.pool.get('sale.order').onchange_partner_id(cr, SUPERUSER_ID, [], partner_id, context=context)['value']['pricelist_id']
42
43         request.httprequest.session['ecommerce_pricelist'] = pricelist_id
44         request.httprequest.session['ecommerce_pricelist_uid'] = uid
45
46         order = self.ecommerce_get_current_order(cr, uid, context=context)
47         if order:
48             values = {'pricelist_id': pricelist_id}
49             values.update(order.onchange_pricelist_id(pricelist_id, None)['value'])
50             order.write(values)
51             for line in order.order_line:
52                 self._ecommerce_add_product_to_cart(cr, uid, order_line_id=line.id, number=0)
53
54     # ************************************************************
55     # Ecommerce quotation management
56     # ************************************************************
57
58     def _ecommerce_add_product_to_cart(self, cr, uid, product_id=0, order_line_id=0, number=1, set_number=-1, context=None):
59         order = self.ecommerce_get_current_order(cr, uid, context=context)
60         if not order:
61             order = self.ecommerce_get_new_order(cr, uid, context=context)
62
63         order_line_obj = self.pool.get('sale.order.line')
64         order_obj = self.pool.get('sale.order')
65
66         context = dict(context or {}, pricelist=self.ecommerce_get_pricelist_id(cr, uid, None, context=context))
67
68         # set order_line_id and product_id
69         if order_line_id:
70             order_line = None
71             for line in order.order_line:
72                 if line.id == order_line_id:
73                     order_line = line
74                     break
75             if order_line:
76                 product_id = order_line.product_id.id
77             else:
78                 order_line_id = None
79         else:
80             order_line_ids = order_line_obj.search(cr, SUPERUSER_ID,
81                 [('order_id', '=', order.id), ('product_id', '=', product_id)], context=context)
82             if order_line_ids:
83                 order_line_id = order_line_ids[0]
84
85         if not order_line_id and not product_id:
86             return 0
87
88         # values initialisation
89         quantity = 0
90         values = {}
91         order_line_ids = []
92         if order_line_id:
93             order_line_val = order_line_obj.read(cr, SUPERUSER_ID, [order_line_id], [], context=context)[0]
94             if not product_id:
95                 product_id = order_line_val['product_id'][0]
96             if set_number >= 0:
97                 quantity = set_number
98             else:
99                 quantity = order_line_val['product_uom_qty'] + number
100             if quantity < 0:
101                 quantity = 0
102             order_line_ids = [order_line_id]
103         else:
104             fields = [k for k, v in order_line_obj._columns.items()]
105             values = order_line_obj.default_get(cr, SUPERUSER_ID, fields, context=context)
106             quantity = 1
107
108         # change and record value
109         if quantity:
110             vals = order_line_obj._recalculate_product_values(cr, uid, order_line_ids, product_id, fiscal_position=order.fiscal_position.id, context=context)
111             values.update(vals)
112             values['product_uom_qty'] = quantity
113             values['product_id'] = product_id
114             values['order_id'] = order.id
115
116             product = self.pool.get('product.product').browse(cr, uid, product_id, context=context)
117             values['name'] = "%s: %s" % (product.name, product.variants) if product.variants else product.name
118             if values.get('tax_id'):
119                 values['tax_id'] = [(6, 0, values['tax_id'])]
120
121             order_obj.write(cr, SUPERUSER_ID, [order.id], {'order_line': [(1, order_line_id, values) if order_line_id else (0, 0, values)]}, context=context)
122
123         elif order_line_ids:
124             order_line_obj.unlink(cr, SUPERUSER_ID, order_line_ids, context=context)
125
126         order = self.ecommerce_get_current_order(cr, uid, context=context)
127         if not order or not order.order_line:
128             self._ecommerce_change_pricelist(cr, uid, None, context=context)
129
130         return quantity
131
132     def _ecommerce_get_quotation_values(self, cr, uid, context=None):
133         """ Generate the values for a new ecommerce quotation. """
134         SaleOrder = self.pool.get('sale.order')
135         fields = [k for k, v in SaleOrder._columns.items()]
136         values = SaleOrder.default_get(cr, SUPERUSER_ID, fields, context=context)
137         if request.httprequest.session.get('ecommerce_pricelist'):
138             values['pricelist_id'] = request.httprequest.session['ecommerce_pricelist']
139         values['partner_id'] = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id
140         values.update(SaleOrder.onchange_partner_id(cr, SUPERUSER_ID, [], values['partner_id'], context=context)['value'])
141         values['website_session_id'] = request.httprequest.session['website_session_id']
142         return values
143
144     def _ecommerce_create_quotation(self, cr, uid, context=None):
145         """ Create a new quotation used in the ecommerce (event, sale) """
146         SaleOrder = self.pool.get('sale.order')
147         quotation_values = self._ecommerce_get_quotation_values(cr, uid, context=context)
148         quotation_values['user_id'] = False
149         return SaleOrder.create(cr, SUPERUSER_ID, quotation_values, context=context)
150
151     def ecommerce_get_new_order(self, cr, uid, context=None):
152         """ Create a new quotation for the ecommerce and update the session
153         accordingly: website_session_id if not set, ecommerce_order_id """
154         SaleOrder = self.pool.get('sale.order')
155
156         # add website_session_id key for access rules
157         if not request.httprequest.session.get('website_session_id'):
158             request.httprequest.session['website_session_id'] = str(uuid.uuid4())
159
160         order_id = self._ecommerce_create_quotation(cr, uid, context=context)
161         request.httprequest.session['ecommerce_order_id'] = order_id
162         context = dict(context or {}, pricelist=self.ecommerce_get_pricelist_id(cr, uid, None, context=context))
163         return SaleOrder.browse(cr, SUPERUSER_ID, order_id, context=context)
164
165     def ecommerce_get_current_order(self, cr, uid, context=None):
166         SaleOrder = self.pool.get('sale.order')
167         context = dict(context or {}, pricelist=self.ecommerce_get_pricelist_id(cr, uid, None, context=context))
168         order_id = request.httprequest.session.get('ecommerce_order_id')
169         if not order_id:
170             request.httprequest.session['ecommerce_order_id'] = False
171             return False
172         if not order_id in SaleOrder.exists(cr, uid, [order_id], context=context):
173             request.httprequest.session['ecommerce_order_id'] = False
174             return False
175         try:
176             order = SaleOrder.browse(cr, SUPERUSER_ID, order_id, context=context)
177             assert order.website_session_id == request.httprequest.session['website_session_id']
178             return order
179         except:
180             request.httprequest.session['ecommerce_order_id'] = False
181             return False
182
183     # ************************************************************
184     # Ecommerce transaction management
185     # ************************************************************
186
187     def _get_transaction(self, cr, uid, tx_id=None, context=None):
188         transaction_obj = self.pool.get('payment.transaction')
189         if tx_id:
190             tx_ids = transaction_obj.search(cr, uid, [('id', '=', tx_id), ('state', 'not in', ['cancel'])], context=context)
191             if tx_ids:
192                 return transaction_obj.browse(cr, uid, tx_ids[0], context=context)
193         return False
194
195     def ecommerce_get_current_transaction(self, cr, uid, context=None):
196         if request.httprequest.session.get('website_sale_transaction_id'):
197             tx = self._get_transaction(cr, uid, tx_id=request.httprequest.session['website_sale_transaction_id'], context=context)
198             if not tx:
199                 request.httprequest.session['website_sale_transaction_id'] = False
200             return tx
201         return False
202
203     def ecommerce_reset(self, cr, uid, context=None):
204         request.httprequest.session.update({
205             'ecommerce_order_id': False,
206             'ecommerce_pricelist': False,
207             'website_sale_transaction_id': False,
208         })
209         request.context.update({
210             'website_sale_order': False,
211             'website_sale_transaction': False,
212         })
213
214     def preprocess_request(self, cr, uid, ids, request, context=None):
215         request.context.update({
216             'website_sale_order': self.ecommerce_get_current_order(cr, uid, context=context),
217             'website_sale_transaction': self.ecommerce_get_current_transaction(cr, uid, context=context)
218         })
219         return super(Website, self).preprocess_request(cr, uid, ids, request, context=None)
220
221     def ecommerce_get_product_domain(self):
222         return [
223             ("sale_ok", "=", True),
224             # force search on product.product to use the orm (exclude active, acl,..)
225             ("product_variant_ids.id", "!=", False),
226         ]