02fab32e17703e6d357c32d2d999765cae72c56f
[odoo/odoo.git] / addons / website_sale / controllers / main.py
1 # -*- coding: utf-8 -*-
2
3 from openerp import SUPERUSER_ID
4 from openerp.osv import osv
5 from openerp.addons.web import http
6 from openerp.addons.web.http import request
7 from openerp.addons.website.models import website
8 import random
9 import uuid
10
11 def get_order(order_id=None):
12     order_obj = request.registry.get('sale.order')
13     # check if order allready exists and have access
14     if order_id:
15         try:
16             order = order_obj.browse(request.cr, request.uid, order_id, context=request.context)
17             order.pricelist_id
18             if order:
19                 return order
20         except:
21             return False
22
23     fields = [k for k, v in order_obj._columns.items()]
24     order_value = order_obj.default_get(request.cr, SUPERUSER_ID, fields, context=request.context)
25     if request.httprequest.session.get('ecommerce_pricelist'):
26         order_value['pricelist_id'] = request.httprequest.session['ecommerce_pricelist']
27     order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, SUPERUSER_ID, request.uid, context=request.context).partner_id.id
28     order_value.update(order_obj.onchange_partner_id(request.cr, SUPERUSER_ID, [], order_value['partner_id'], context=request.context)['value'])
29     
30     # add website_session_id key for access rules
31     if not request.httprequest.session.get('website_session_id'):
32         request.httprequest.session['website_session_id'] = str(uuid.uuid4())
33
34     order_value["website_session_id"] = request.httprequest.session['website_session_id']
35     order_id = order_obj.create(request.cr, SUPERUSER_ID, order_value, context=request.context)
36     order = order_obj.browse(request.cr, SUPERUSER_ID, order_id, context=request.context)
37     request.httprequest.session['ecommerce_order_id'] = order.id
38
39     return order_obj.browse(request.cr, request.uid, order_id,
40                             context=dict(request.context, pricelist=order.pricelist_id.id))
41
42 def get_current_order():
43     if request.httprequest.session.get('ecommerce_order_id'):
44         order = get_order(request.httprequest.session.get('ecommerce_order_id'))
45         if not order:
46             request.httprequest.session['ecommerce_order_id'] = False
47         return order
48     else:
49         return False
50
51 class Website(osv.osv):
52     _inherit = "website"
53     def preprocess_request(self, cr, uid, ids, *args, **kwargs):
54         request.context.update({
55             'website_sale_order': get_current_order(),
56         })
57         return super(Website, self).preprocess_request(cr, uid, ids, *args, **kwargs)
58
59 class Ecommerce(http.Controller):
60
61     _order = 'website_sequence desc, website_published desc'
62
63     def get_categories(self):
64         domain = [('parent_id', '=', False)]
65
66         category_obj = request.registry.get('product.public.category')
67         category_ids = category_obj.search(request.cr, SUPERUSER_ID, domain, context=request.context)
68         categories = category_obj.browse(request.cr, SUPERUSER_ID, category_ids, context=request.context)
69
70         product_obj = request.registry.get('product.product')
71         groups = product_obj.read_group(request.cr, SUPERUSER_ID, [("sale_ok", "=", True), ('website_published', '=', True)], ['public_categ_id'], 'public_categ_id', context=request.context)
72         full_category_ids = [group['public_categ_id'][0] for group in groups if group['public_categ_id']]
73
74         for cat_id in category_obj.browse(request.cr, SUPERUSER_ID, full_category_ids, context=request.context):
75             while cat_id.parent_id:
76                 cat_id = cat_id.parent_id
77                 full_category_ids.append(cat_id.id)
78         full_category_ids.append(1)
79
80         return (categories, full_category_ids)
81
82     def get_bin_packing_products(self, product_ids, fill_hole, col_number=4):
83         """
84         Packing all products of the search into a table of #col_number columns in function of the product sizes
85         The website_size_x, website_size_y is use for fill table (default 1x1)
86         The website_style_ids datas are concatenate in a html class
87
88         @values:
89
90         product_ids: list of product template
91         fill_hole: list of extra product template use to fill the holes
92         col_number: number of columns
93
94         @return:
95
96         table (list of list of #col_number items)
97         items: {
98             'product': browse of product template,
99             'x': size x,
100             'y': size y,
101             'class': html class
102         }
103         """
104         product_obj = request.registry.get('product.template')
105         style_obj = request.registry.get('website.product.style')
106         request.context['pricelist'] = self.get_pricelist()
107
108         # search for checking of access rules and keep order
109         product_ids = [id for id in product_ids if id in product_obj.search(request.cr, request.uid, [("id", 'in', product_ids)], context=request.context)]
110
111         size_ids = {}
112         style_ids = style_obj.search(request.cr, SUPERUSER_ID, [('html_class', 'like', 'size_%')], context=request.context)
113         for style in style_obj.browse(request.cr, SUPERUSER_ID, style_ids, context=request.context):
114             size_ids[style.id] = [int(style.html_class[-3]), int(style.html_class[-1])]
115
116         product_list = []
117         bin_packing = {}
118         bin_packing[0] = {}
119
120         for product in product_obj.browse(request.cr, SUPERUSER_ID, product_ids, context=request.context):
121             index = len(product_list)
122
123             # get size and all html classes
124             x = product.website_size_x or 1
125             y = product.website_size_y or 1
126             html_class = " ".join([str(style_id.html_class) for style_id in product.website_style_ids])
127
128             product_list.append({'product': product, 'x': x, 'y': y, 'class': html_class })
129
130             # bin packing products
131             insert = False
132             line = 0
133             while not insert:
134                 # if not full column get next line
135                 if len(bin_packing.setdefault(line, {})) >= col_number:
136                     line += 1
137                     continue
138
139                 col = 0
140                 while col < col_number:
141                     if bin_packing[line].get(col, None) != None:
142                         col += 1
143                         continue
144
145                     insert = True
146
147                     # check if the box can be inserted
148                     copy_line = line
149                     copy_y = y
150                     while copy_y > 0:
151                         copy_col = col
152                         copy_x = x
153                         while copy_x > 0:
154                             if copy_col >= col_number or bin_packing.setdefault(copy_line, {}).get(copy_col, None) != None:
155                                 insert = False
156                                 break
157                             copy_col += 1
158                             copy_x -= 1
159                         if not insert:
160                             break
161                         copy_line += 1
162                         copy_y -= 1
163
164                     if not insert:
165                         col += 1
166                         continue
167
168                     # insert the box
169                     copy_y = y
170                     while copy_y > 0:
171                         copy_y -= 1
172                         copy_x = x
173                         while copy_x > 0:
174                             copy_x -= 1
175                             bin_packing[line + copy_y][col + copy_x] = False
176                     bin_packing[line + copy_y][col + copy_x] = product_list[index]
177                     break
178             
179                 if not insert:
180                     line += 1
181                 else:
182                     break
183
184         length = len(bin_packing)
185
186         # browse product to fill the holes
187         if fill_hole:
188             fill_hole_products = []
189             # search for checking of access rules and keep order
190             fill_hole = [id for id in fill_hole if id in product_obj.search(request.cr, request.uid, [("id", 'in', fill_hole)], context=request.context)]
191             for product in product_obj.browse(request.cr, request.uid, fill_hole, context=request.context):
192                 fill_hole_products.append(product)
193             fill_hole_products.reverse()
194
195         # packaging in list (from dict)
196         bin_packing_list = []
197         line = 0
198         while line < length:
199             bin_packing_list.append([])
200             col = 0
201             while col < col_number:
202                 if fill_hole and fill_hole_products and bin_packing[line].get(col) == None:
203                     bin_packing[line][col] = {'product': fill_hole_products.pop(), 'x': 1, 'y': 1, 'class': "" }
204                 bin_packing_list[line].append(bin_packing[line].get(col))
205                 col += 1
206             line += 1
207
208         return bin_packing_list
209
210     def get_products(self, product_ids):
211         product_obj = request.registry.get('product.template')
212         request.context['pricelist'] = self.get_pricelist()
213         # search for checking of access rules and keep order
214         product_ids = [id for id in product_ids if id in product_obj.search(request.cr, request.uid, [("id", 'in', product_ids)], context=request.context)]
215         return product_obj.browse(request.cr, request.uid, product_ids, context=request.context)
216
217     @website.route(['/shop/', '/shop/category/<cat_id>/', '/shop/category/<cat_id>/page/<int:page>/', '/shop/page/<int:page>/'], type='http', auth="public", multilang=True)
218     def category(self, cat_id=0, page=0, **post):
219
220         if 'promo' in post:
221             self.change_pricelist(post.get('promo'))
222         product_obj = request.registry.get('product.template')
223
224         domain = [("sale_ok", "=", True)]
225         #domain += [('website_published', '=', True)]
226
227         if post.get("search"):
228             domain += ['|', '|', '|',
229                 ('name', 'ilike', "%%%s%%" % post.get("search")), 
230                 ('description', 'ilike', "%%%s%%" % post.get("search")),
231                 ('website_description', 'ilike', "%%%s%%" % post.get("search")),
232                 ('product_variant_ids.public_categ_id.name', 'ilike', "%%%s%%" % post.get("search"))]
233         if cat_id:
234             cat_id = int(cat_id)
235             domain += [('product_variant_ids.public_categ_id.id', 'child_of', cat_id)] + domain
236
237         step = 20
238         product_count = len(product_obj.search(request.cr, request.uid, domain, context=request.context))
239         pager = request.website.pager(url="/shop/category/%s/" % cat_id, total=product_count, page=page, step=step, scope=7, url_args=post)
240
241         request.context['pricelist'] = self.get_pricelist()
242
243         product_ids = product_obj.search(request.cr, request.uid, domain, limit=step, offset=pager['offset'], order=self._order, context=request.context)
244         fill_hole = product_obj.search(request.cr, request.uid, domain, limit=step, offset=pager['offset']+step, order=self._order, context=request.context)
245
246         styles = []
247         if not request.context['is_public_user']:
248             style_obj = request.registry.get('website.product.style')
249             style_ids = style_obj.search(request.cr, request.uid, [(1, '=', 1)], context=request.context)
250             styles = style_obj.browse(request.cr, request.uid, style_ids, context=request.context)
251
252         values = {
253             'get_categories': self.get_categories,
254             'category_id': cat_id,
255             'product_ids': product_ids,
256             'product_ids_for_holes': fill_hole,
257             'get_bin_packing_products': self.get_bin_packing_products,
258             'get_products': self.get_products,
259             'search': post.get("search"),
260             'pager': pager,
261             'styles': styles,
262             'style_in_product': lambda style, product: style.id in [s.id for s in product.website_style_ids]
263         }
264         return request.website.render("website_sale.products", values)
265
266     @website.route(['/shop/product/<int:product_id>/'], type='http', auth="public", multilang=True)
267     def product(self, cat_id=0, product_id=0, **post):
268
269         if 'promo' in post:
270             self.change_pricelist(post.get('promo'))
271
272         product_obj = request.registry.get('product.template')
273         category_obj = request.registry.get('product.public.category')
274
275         category_ids = category_obj.search(request.cr, request.uid, [(1, '=', 1)], context=request.context)
276         category_list = category_obj.name_get(request.cr, request.uid, category_ids, context=request.context)
277         category_list = sorted(category_list, key=lambda category: category[1])
278
279         category = None
280         if post.get('category_id') and int(post.get('category_id')):
281             category = category_obj.browse(request.cr, request.uid, int(post.get('category_id')), context=request.context)
282
283         request.context['pricelist'] = self.get_pricelist()
284         product = product_obj.browse(request.cr, request.uid, product_id, context=request.context)
285
286         values = {
287             'category_id': post.get('category_id') and int(post.get('category_id')) or None,
288             'category': category,
289             'search': post.get("search"),
290             'get_categories': self.get_categories,
291             'category_list': category_list,
292             'main_object': product,
293             'product': product,
294         }
295         return request.website.render("website_sale.product", values)
296
297     @website.route(['/shop/add_product/', '/shop/category/<int:cat_id>/add_product/'], type='http', auth="public", multilang=True)
298     def add_product(self, cat_id=0, **post):
299         product_id = request.registry.get('product.product').create(request.cr, request.uid, 
300             {'name': 'New Product', 'public_categ_id': cat_id}, request.context)
301         return request.redirect("/shop/product/%s/?unable_editor=1" % product_id)
302
303     def get_pricelist(self):
304         if not request.httprequest.session.get('ecommerce_pricelist'):
305             self.change_pricelist(None)
306         return request.httprequest.session.get('ecommerce_pricelist')
307
308     def change_pricelist(self, code):
309         request.httprequest.session.setdefault('ecommerce_pricelist', False)
310
311         pricelist_id = False
312         if code:
313             pricelist_obj = request.registry.get('product.pricelist')
314             pricelist_ids = pricelist_obj.search(request.cr, SUPERUSER_ID, [('code', '=', code)], context=request.context)
315             if pricelist_ids:
316                 pricelist_id = pricelist_ids[0]
317
318         if not pricelist_id:
319             partner_id = request.registry.get('res.users').browse(request.cr, SUPERUSER_ID, request.uid, request.context).partner_id.id
320             pricelist_id = request.registry['sale.order'].onchange_partner_id(request.cr, SUPERUSER_ID, [], partner_id, context=request.context)['value']['pricelist_id']
321         
322         request.httprequest.session['ecommerce_pricelist'] = pricelist_id
323
324         order = get_current_order()
325         if order:
326             values = {'pricelist_id': pricelist_id}
327             values.update(order.onchange_pricelist_id(pricelist_id, None)['value'])
328             order.write(values)
329             for line in order.order_line:
330                 self.add_product_to_cart(order_line_id=line.id, number=0)
331
332     def add_product_to_cart(self, product_id=0, order_line_id=0, number=1, set_number=-1):
333         order_line_obj = request.registry.get('sale.order.line')
334         order_obj = request.registry.get('sale.order')
335
336         order = get_current_order()
337         if not order:
338             order = get_order()
339
340         request.context = dict(request.context, pricelist=self.get_pricelist())
341
342         quantity = 0
343
344         # values initialisation
345         values = {}
346
347         domain = [('order_id', '=', order.id)]
348         if order_line_id:
349             domain += [('id', '=', order_line_id)]
350         else:
351             domain += [('product_id', '=', product_id)]
352
353         order_line_ids = order_line_obj.search(request.cr, SUPERUSER_ID, domain, context=request.context)
354         if order_line_ids:
355             order_line = order_line_obj.read(request.cr, SUPERUSER_ID, order_line_ids, [], context=request.context)[0]
356             if not product_id:
357                 product_id = order_line['product_id'][0]
358             if set_number >= 0:
359                 quantity = set_number
360             else:
361                 quantity = order_line['product_uom_qty'] + number
362             if quantity < 0:
363                 quantity = 0
364         else:
365             fields = [k for k, v in order_line_obj._columns.items()]
366             values = order_line_obj.default_get(request.cr, SUPERUSER_ID, fields, context=request.context)
367             quantity = 1
368
369         # change and record value
370         vals = order_line_obj._recalculate_product_values(request.cr, request.uid, order_line_ids, product_id, context=request.context)
371         values.update(vals)
372
373         values['product_uom_qty'] = quantity
374         values['product_id'] = product_id
375         values['order_id'] = order.id
376
377         if order_line_ids:
378             order_line_obj.write(request.cr, SUPERUSER_ID, order_line_ids, values, context=request.context)
379             if not quantity:
380                 order_line_obj.unlink(request.cr, SUPERUSER_ID, order_line_ids, context=request.context)
381         else:
382             order_line_id = order_line_obj.create(request.cr, SUPERUSER_ID, values, context=request.context)
383             order_obj.write(request.cr, SUPERUSER_ID, [order.id], {'order_line': [(4, order_line_id)]}, context=request.context)
384
385         return [quantity, order.get_total_quantity()]
386
387     @website.route(['/shop/mycart/'], type='http', auth="public", multilang=True)
388     def mycart(self, **post):
389         order = get_current_order()
390         prod_obj = request.registry.get('product.product')
391
392         if 'promo' in post:
393             self.change_pricelist(post.get('promo'))
394
395         suggested_ids = []
396         product_ids = []
397         if order:
398             for line in order.order_line:
399                 suggested_ids += [p.id for p in line.product_id and line.product_id.suggested_product_ids or [] for line in order.order_line]
400                 product_ids.append(line.product_id.id)
401         suggested_ids = list(set(suggested_ids) - set(product_ids))
402         if suggested_ids:
403             suggested_ids = prod_obj.search(request.cr, request.uid, [('id', 'in', suggested_ids)], context=request.context)
404
405         # select 3 random products
406         suggested_products = []
407         while len(suggested_products) < 3 and suggested_ids:
408             index = random.randrange(0, len(suggested_ids))
409             suggested_products.append(suggested_ids.pop(index))
410
411         values = {
412             'int': int,
413             'get_categories': self.get_categories,
414             'suggested_products': prod_obj.browse(request.cr, request.uid, suggested_products, request.context),
415         }
416         return request.website.render("website_sale.mycart", values)
417
418     @website.route(['/shop/<path:path>/add_cart/', '/shop/add_cart/'], type='http', auth="public", multilang=True)
419     def add_cart(self, path=None, product_id=None, order_line_id=None, remove=None, **kw):
420         self.add_product_to_cart(product_id=product_id and int(product_id), order_line_id=order_line_id and int(order_line_id), number=(remove and -1 or 1))
421         return request.redirect("/shop/mycart/")
422
423     @website.route(['/shop/add_cart_json/'], type='json', auth="public")
424     def add_cart_json(self, product_id=None, order_line_id=None, remove=None):
425         return self.add_product_to_cart(product_id=product_id, order_line_id=order_line_id, number=(remove and -1 or 1))
426
427     @website.route(['/shop/set_cart_json/'], type='json', auth="public")
428     def set_cart_json(self, path=None, product_id=None, order_line_id=None, set_number=0, json=None):
429         return self.add_product_to_cart(product_id=product_id, order_line_id=order_line_id, set_number=set_number)
430
431     @website.route(['/shop/checkout/'], type='http', auth="public", multilang=True)
432     def checkout(self, **post):
433         classic_fields = ["name", "phone", "email", "street", "city", "state_id", "zip"]
434         rel_fields = ['country_id', 'state_id']
435
436         order = get_current_order()
437
438         if not order or order.state != 'draft' or not order.order_line:
439             return self.mycart(**post)
440
441         partner_obj = request.registry.get('res.partner')
442         user_obj = request.registry.get('res.users')
443         country_obj = request.registry.get('res.country')
444         country_state_obj = request.registry.get('res.country.state')
445
446         values = {
447             'shipping': post.get("shipping"),
448             'error': post.get("error") and dict.fromkeys(post.get("error").split(","), 'error') or {}
449         }
450
451         checkout = dict((field_name, '') for field_name in classic_fields + rel_fields)
452         if not request.context['is_public_user']:
453             partner = user_obj.browse(request.cr, request.uid, request.uid, request.context).partner_id
454             checkout.update(dict((field_name, getattr(partner, field_name)) for field_name in classic_fields if getattr(partner, field_name)))
455             checkout['state_id'] = partner.state_id and partner.state_id.id or ''
456             checkout['country_id'] = partner.country_id and partner.country_id.id or ''
457             checkout['company'] = partner.parent_id and partner.parent_id.name or ''
458
459             shipping_ids = partner_obj.search(request.cr, request.uid, [("parent_id", "=", partner.id), ('type', "=", 'delivery')], context=request.context)
460             if shipping_ids:
461                 for k, v in partner_obj.read(request.cr, request.uid, shipping_ids[0], request.context).items():
462                     checkout['shipping_'+k] = v or ''
463
464         values['checkout'] = checkout
465         countries_ids = country_obj.search(request.cr, SUPERUSER_ID, [(1, "=", 1)], context=request.context)
466         values['countries'] = country_obj.browse(request.cr, SUPERUSER_ID, countries_ids, request.context)
467         states_ids = country_state_obj.search(request.cr, SUPERUSER_ID, [(1, "=", 1)], context=request.context)
468         values['states'] = country_state_obj.browse(request.cr, SUPERUSER_ID, states_ids, request.context)
469
470         return request.website.render("website_sale.checkout", values)
471
472     @website.route(['/shop/confirm_order/'], type='http', auth="public", multilang=True)
473     def confirm_order(self, **post):
474         order = get_current_order()
475
476         error = []
477         partner_obj = request.registry.get('res.partner')
478         user_obj = request.registry.get('res.users')
479
480         if order.state != 'draft':
481             return request.redirect("/shop/checkout/")
482         if not order.order_line:
483             error.append("empty_cart")
484             return request.redirect("/shop/checkout/")
485
486         # check values
487         request.session['checkout'] = post
488         required_field = ['phone', 'zip', 'email', 'street', 'city', 'name', 'country_id']
489         for key in required_field:
490             if not post.get(key):
491                 error.append(key)
492             if post.get('shipping_different') and key != 'email' and not post.get("shipping_%s" % key):
493                 error.append("shipping_%s" % key)
494         if error:
495             return request.redirect("/shop/checkout/?error=%s&shipping=%s" % (",".join(error), post.get('shipping_different') and 'on' or ''))
496
497         # search or create company
498         company_id = None
499         if post['company']:
500             company_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("name", "ilike", post['company']), ('is_company', '=', True)], context=request.context)
501             company_id = company_ids and company_ids[0] or None
502             if not company_id:
503                 company_id = partner_obj.create(request.cr, SUPERUSER_ID, {'name': post['company'], 'is_company': True}, request.context)
504
505         partner_value = {
506             'phone': post['phone'],
507             'zip': post['zip'],
508             'email': post['email'],
509             'street': post['street'],
510             'city': post['city'],
511             'name': post['name'],
512             'parent_id': company_id,
513             'country_id': post['country_id'],
514             'state_id': post['state_id'],
515         }
516         if not request.context['is_public_user']:
517             partner_id = user_obj.browse(request.cr, request.uid, request.uid, context=request.context).partner_id.id
518             partner_obj.write(request.cr, request.uid, [partner_id], partner_value, context=request.context)
519         else:
520             partner_id = partner_obj.create(request.cr, SUPERUSER_ID, partner_value, context=request.context)
521
522
523         shipping_id = None
524         if post.get('shipping_different'):
525             shipping_value = {
526                 'phone': post['shipping_phone'],
527                 'zip': post['shipping_zip'],
528                 'street': post['shipping_street'],
529                 'city': post['shipping_city'],
530                 'name': post['shipping_name'],
531                 'type': 'delivery',
532                 'parent_id': partner_id,
533                 'country_id': post['shipping_country_id'],
534                 'state_id': post['shipping_state_id'],
535             }
536             domain = [(key, '_id' in key and '=' or 'ilike', '_id' in key and value and int(value) or False)
537                 for key, value in shipping_value.items() if key in required_field + ["type", "parent_id"]]
538
539             shipping_ids = partner_obj.search(request.cr, SUPERUSER_ID, domain, context=request.context)
540             if shipping_ids:
541                 shipping_id = shipping_ids[0]
542                 partner_obj.write(request.cr, SUPERUSER_ID, [shipping_id], shipping_value, request.context)
543             else:
544                 shipping_id = partner_obj.create(request.cr, SUPERUSER_ID, shipping_value, request.context)
545
546         order_value = {
547             'partner_id': partner_id,
548             'message_follower_ids': [(4, partner_id)],
549             'partner_invoice_id': partner_id,
550             'partner_shipping_id': shipping_id or partner_id
551         }
552         order_value.update(request.registry.get('sale.order').onchange_partner_id(request.cr, SUPERUSER_ID, [], order.partner_id.id, context=request.context)['value'])
553         order.write(order_value)
554
555         return request.redirect("/shop/payment/")
556
557     @website.route(['/shop/payment/'], type='http', auth="public", multilang=True)
558     def payment(self, **post):
559         order = get_current_order()
560
561         if not order or not order.order_line:
562             return self.mycart(**post)
563
564         values = {
565             'partner': False,
566             'order': order
567         }
568
569         payment_obj = request.registry.get('portal.payment.acquirer')
570         payment_ids = payment_obj.search(request.cr, SUPERUSER_ID, [('visible', '=', True)], context=request.context)
571         values['payments'] = payment_obj.browse(request.cr, SUPERUSER_ID, payment_ids, request.context)
572         for payment in values['payments']:
573             content = payment_obj.render(request.cr, SUPERUSER_ID, payment.id, order, order.name, order.pricelist_id.currency_id, order.amount_total)
574             payment._content = content
575
576         return request.website.render("website_sale.payment", values)
577
578     @website.route(['/shop/payment_validate/'], type='http', auth="public", multilang=True)
579     def payment_validate(self, **post):
580         request.httprequest.session['ecommerce_order_id'] = False
581         request.httprequest.session['ecommerce_pricelist'] = False
582         return request.redirect("/shop/")
583
584     @website.route(['/shop/change_sequence/'], type='json', auth="public")
585     def change_sequence(self, id, top):
586         product_obj = request.registry.get('product.template')
587         if top:
588             product_obj.set_sequence_top(request.cr, request.uid, [id], context=request.context)
589         else:
590             product_obj.set_sequence_bottom(request.cr, request.uid, [id], context=request.context)
591
592     @website.route(['/shop/change_styles/'], type='json', auth="public")
593     def change_styles(self, id, style_id):
594         product_obj = request.registry.get('product.template')
595         product = product_obj.browse(request.cr, request.uid, id, context=request.context)
596
597         remove = []
598         active = False
599         for style in product.website_style_ids:
600             if style.id == style_id:
601                 remove.append(style.id)
602                 active = True
603                 break
604
605         style = request.registry.get('website.product.style').browse(request.cr, request.uid, style_id, context=request.context)
606
607         if remove:
608             product.write({'website_style_ids': [(3, rid) for rid in remove]})
609         if not active:
610             product.write({'website_style_ids': [(4, style.id)]})
611
612         return not active
613
614     @website.route(['/shop/change_size/'], type='json', auth="public")
615     def change_size(self, id, x, y):
616         product_obj = request.registry.get('product.template')
617         product = product_obj.browse(request.cr, request.uid, id, context=request.context)
618         return product.write({'website_size_x': x, 'website_size_y': y})
619
620 # vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: