1 # -*- coding: utf-8 -*-
6 from openerp.osv import osv
7 from openerp.addons.web import http
8 from openerp.addons.web.http import request
10 def get_order(order_id=None):
11 order_obj = request.registry.get('sale.order')
12 # check if order allready exists
15 order = order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id)
20 fields = [k for k, v in order_obj._columns.items()]
21 order_value = order_obj.default_get(request.cr, openerp.SUPERUSER_ID, fields)
22 order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id
23 order_value.update(order_obj.onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value'])
24 order_id = order_obj.create(request.cr, openerp.SUPERUSER_ID, order_value)
25 order = order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id)
28 def get_current_order():
29 order = get_order(request.httprequest.session.get('ecommerce_order_id'))
30 if order.state != 'draft':
32 request.httprequest.session['ecommerce_order_id'] = order.id
35 class website(osv.osv):
37 def get_rendering_context(self, additional_values=None):
39 'order': get_current_order(),
40 # 'website_sale_get_current_order': get_current_order, # TODO: replace 'order' key in templates
43 values.update(additional_values)
44 return super(website, self).get_rendering_context(values)
46 class Ecommerce(http.Controller):
48 def get_categories(self):
49 category_obj = request.registry.get('pos.category')
50 category_ids = category_obj.search(request.cr, openerp.SUPERUSER_ID, [('parent_id', '=', False)])
51 categories = category_obj.browse(request.cr, openerp.SUPERUSER_ID, category_ids)
55 def render(self, template, values={}):
56 website = request.registry['website']
58 'categories': self.get_categories(),
60 _values.update(values)
61 return website.render(template, _values)
63 def recommended_product(self, my_pids):
66 product_obj = request.registry.get('product.product')
68 my_pids = str(my_pids)[1:-1]
72 FROM sale_order_line as my
73 LEFT JOIN sale_order_line as sol
74 ON sol.order_id = my.order_id
75 WHERE my.product_id in (%s)
76 AND sol.product_id not in (%s)
77 GROUP BY sol.product_id
78 ORDER BY COUNT(sol.order_id) DESC
80 """ % (my_pids, my_pids)
81 request.cr.execute(query)
82 for p in request.cr.fetchall():
83 product_ids.append(p[0])
85 # search to apply access rules
86 product_ids = product_obj.search(request.cr, request.uid, [("id", "in", product_ids)])
87 return product_obj.browse(request.cr, request.uid, product_ids)
89 @http.route(['/shop', '/shop/category/<cat_id>', '/shop/category/<cat_id>/page/<page>', '/shop/page/<page>'], type='http', auth="public")
90 def category(self, cat_id=0, page=0, **post):
92 website = request.registry['website']
93 product_obj = request.registry.get('product.product')
95 domain = [("sale_ok", "=", True)]
96 if openerp.SUPERUSER_ID != request.uid:
97 domain += [('website_published', '=', True)]
101 domain = [('pos_categ_id.id', 'child_of', cat_id)] + domain
103 product_count = len(product_obj.search(request.cr, request.uid, domain))
104 page_count = int(math.ceil(product_count / 20.0))
106 #if post.get("search"):
107 # domain += ['|', '|', ('name', 'ilike', "%%%s%%" % post.get("search")), ('description', 'ilike', "%%%s%%" % post.get("search")), ('pos_categ_id.name', 'ilike', "%%%s%%" % post.get("search"))]
109 page = max(1,min(int(page),page_count))
110 offset = (page-1) * 20
112 if page_count <= 5 or page <= 3:
114 pmax = min(page_count,5)
115 elif page >= page_count - 2:
116 pmin = page_count - 4
122 pages = range(pmin, pmax+1)
124 product_ids = product_obj.search(request.cr, request.uid, domain, limit=20, offset=offset)
126 values = website.get_rendering_context({
127 'current_category': cat_id,
128 'products': product_obj.browse(request.cr, request.uid, product_ids),
129 'search': post.get("search"),
130 'page_count': page_count,
134 return self.render("website_sale.products", values)
136 @http.route(['/shop/product/<product_id>'], type='http', auth="public")
137 def product(self, cat_id=0, product_id=0):
138 website = request.registry['website']
139 order = get_current_order()
141 product_id = product_id and int(product_id) or 0
142 product_obj = request.registry.get('product.product')
144 line = [line for line in order.order_line if line.product_id.id == product_id]
145 quantity = line and int(line[0].product_uom_qty) or 0
147 values = website.get_rendering_context({
148 'product': product_obj.browse(request.cr, request.uid, product_id),
149 'quantity': quantity,
150 'recommended_products': self.recommended_product([product_id]),
152 return self.render("website_sale.product", values)
154 @http.route(['/shop/mycart'], type='http', auth="public")
155 def mycart(self, **post):
156 website = request.registry['website']
157 order = get_current_order()
160 pricelist_obj = request.registry.get('product.pricelist')
161 pricelist_ids = pricelist_obj.search(request.cr, openerp.SUPERUSER_ID, [('code', '=', post.get('code'))])
163 order.write({'pricelist_id': pricelist_ids[0]})
165 my_pids = [line.product_id.id for line in order.order_line]
166 values = website.get_rendering_context({
167 "recommended_products": self.recommended_product(my_pids),
170 return self.render("website_sale.mycart", values)
172 @http.route(['/shop/add_cart'], type='http', auth="public")
173 def add_cart(self, product_id=0, remove=False):
174 website = request.registry['website']
177 order_line_obj = request.registry.get('sale.order.line')
178 user_obj = request.registry.get('res.users')
180 product_id = product_id and int(product_id) or 0
181 order = get_current_order()
185 # values initialisation
187 order_line_ids = order_line_obj.search(request.cr, openerp.SUPERUSER_ID, [('order_id', '=', order.id), ('product_id', '=', product_id)], context=context)
189 order_line = order_line_obj.read(request.cr, openerp.SUPERUSER_ID, order_line_ids, [], context=context)[0]
190 quantity = order_line['product_uom_qty'] + (remove and -1 or 1)
192 order_line_obj.unlink(request.cr, openerp.SUPERUSER_ID, order_line_ids, context=context)
194 fields = [k for k, v in order_line_obj._columns.items()]
195 values = order_line_obj.default_get(request.cr, openerp.SUPERUSER_ID, fields, context=context)
197 values['product_uom_qty'] = quantity
198 values['product_id'] = product_id
199 values['order_id'] = order.id
201 # change and record value
203 pricelist_id = order.pricelist_id and order.pricelist_id.id or False
204 values.update(order_line_obj.product_id_change(request.cr, openerp.SUPERUSER_ID, [], pricelist_id, product_id,
205 partner_id=user_obj.browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id,
206 context=context)['value'])
208 order_line_obj.write(request.cr, openerp.SUPERUSER_ID, order_line_ids, values, context=context)
210 order_line_id = order_line_obj.create(request.cr, openerp.SUPERUSER_ID, values, context=context)
211 order.write({'order_line': [(4, order_line_id)]}, context=context)
213 values = website.get_rendering_context()
214 html = self.render("website_sale.total", values)
215 return simplejson.dumps({"quantity": quantity, "totalHTML": html})
217 @http.route(['/shop/remove_cart'], type='http', auth="public")
218 def remove_cart(self, product_id=0):
219 return self.add_cart(product_id=product_id, remove=True)
221 @http.route(['/shop/checkout'], type='http', auth="public")
222 def checkout(self, **post):
223 website = request.registry['website']
224 values = website.get_rendering_context({
227 order = get_current_order()
229 if order.state != 'draft':
230 return self.confirmed(**post)
231 if not order.order_line:
232 return self.mycart(**post)
234 partner_obj = request.registry.get('res.partner')
235 user_obj = request.registry.get('res.users')
236 country_obj = request.registry.get('res.country')
237 country_state_obj = request.registry.get('res.country.state')
238 payment_obj = request.registry.get('portal.payment.acquirer')
240 if request.uid != website.get_public_user().id:
241 values['partner'] = user_obj.browse(request.cr, request.uid, request.uid).partner_id
242 shipping_ids = partner_obj.search(request.cr, request.uid, [("parent_id", "=", values['partner'].id), ('type', "=", 'delivery')])
243 values['shipping'] = None
245 values['shipping'] = partner_obj.browse(request.cr, request.uid, shipping_ids[0])
247 values['countries'] = country_obj.browse(request.cr, openerp.SUPERUSER_ID, country_obj.search(request.cr, openerp.SUPERUSER_ID, [(1, "=", 1)]))
248 values['states'] = country_state_obj.browse(request.cr, openerp.SUPERUSER_ID, country_state_obj.search(request.cr, openerp.SUPERUSER_ID, [(1, "=", 1)]))
250 payment_ids = payment_obj.search(request.cr, openerp.SUPERUSER_ID, [('visible', '=', True)])
251 values['payments'] = payment_obj.browse(request.cr, openerp.SUPERUSER_ID, payment_ids)
252 for payment in values['payments']:
253 content = payment_obj.render(request.cr, openerp.SUPERUSER_ID, payment.id, order, order.name, order.pricelist_id.currency_id, order.amount_total)
254 payment._content = content
256 return website.render("website_sale.checkout", values)
258 @http.route(['/shop/confirm_order'], type='http', auth="public")
259 def confirm_order(self, **post):
260 website = request.registry['website']
261 order = get_current_order()
263 json = {'error': [], 'validation': False}
264 partner_obj = request.registry.get('res.partner')
265 user_obj = request.registry.get('res.users')
267 if order.state != 'draft':
268 json['validation'] = True
270 if not order.order_line:
271 json['error'].append("empty_cart")
275 required_field = ['phone', 'zip', 'email', 'street', 'city', 'name', 'country_id']
276 for key in required_field:
277 if not post.get(key):
278 json['error'].append(key)
279 if 'shipping_name' in post and key != 'email' and not post.get("shipping_%s" % key):
280 json['error'].append("shipping_%s" % key)
282 return simplejson.dumps(json)
284 # search or create company
287 company_ids = partner_obj.search(request.cr, openerp.SUPERUSER_ID, [("name", "ilike", post['company']), ('is_company', '=', True)])
288 company_id = company_ids and company_ids[0] or None
290 company_id = partner_obj.create(request.cr, openerp.SUPERUSER_ID, {'name': post['company'], 'is_company': True})
294 'phone': post['phone'],
296 'email': post['email'],
297 'street': post['street'],
298 'city': post['city'],
299 'name': post['name'],
300 'parent_id': company_id,
301 'country_id': post['country_id'],
302 'state_id': post['state_id'],
304 if request.uid != website.get_public_user().id:
305 partner_id = user_obj.browse(request.cr, request.uid, request.uid).partner_id.id
306 partner_obj.write(request.cr, request.uid, [partner_id], partner_value)
308 partner_id = partner_obj.create(request.cr, openerp.SUPERUSER_ID, partner_value)
311 if 'shipping_name' in post:
313 'fax': post['shipping_fax'],
314 'phone': post['shipping_phone'],
315 'zip': post['shipping_zip'],
316 'street': post['shipping_street'],
317 'city': post['shipping_city'],
318 'name': post['shipping_name'],
320 'parent_id': partner_id,
321 'country_id': post['shipping_country_id'],
322 'state_id': post['shipping_state_id'],
324 domain = [(key, '_id' in key and '=' or 'ilike', '_id' in key and int(value) or value)
325 for key, value in shipping_value.items() if key in required_field + ["type", "parent_id"]]
326 shipping_ids = partner_obj.search(request.cr, openerp.SUPERUSER_ID, domain)
328 shipping_id = shipping_ids[0]
329 partner_obj.write(request.cr, openerp.SUPERUSER_ID, [shipping_id], shipping_value)
331 shipping_id = partner_obj.create(request.cr, openerp.SUPERUSER_ID, shipping_value)
335 'partner_id': partner_id,
336 'partner_invoice_id': partner_id,
337 'partner_shipping_id': shipping_id or partner_id
339 order_value.update(request.registry.get('sale.order').onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value'])
340 order.write(order_value)
342 json['validation'] = True
343 return simplejson.dumps(json)
345 @http.route(['/shop/confirmed'], type='http', auth="public")
346 def confirmed(self, **post):
347 website = request.registry['website']
349 if request.httprequest.session.get('ecommerce_order_id'):
350 order = get_current_order()
351 if order.state != 'draft':
352 request.httprequest.session['ecommerce_order_id_old'] = order.id
353 request.httprequest.session['ecommerce_order_id'] = None
355 order_old = get_order(request.httprequest.session.get('ecommerce_order_id_old'))
356 if not order_old.order_line:
357 return self.mycart(**post)
359 values = website.get_rendering_context({
363 return self.render("website_sale.confirmed", values)
365 @http.route(['/shop/publish'], type='http', auth="public")
366 def publish(self, **post):
367 product_id = int(post['id'])
368 product_obj = request.registry['product.product']
370 product = product_obj.browse(request.cr, request.uid, product_id)
371 product_obj.write(request.cr, request.uid, [product_id], {'website_published': not product.website_published})
372 product = product_obj.browse(request.cr, request.uid, product_id)
374 return product.website_published and "1" or "0"
376 # vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: