main.py~ 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. # -*- coding: utf-8 -*-
  2. import werkzeug
  3. from openerp import http
  4. from openerp.http import request
  5. from openerp import SUPERUSER_ID
  6. from openerp.addons.website.models.website import slug
  7. from openerp.addons.website_sale.controllers.main import QueryURL
  8. from openerp.addons.website_sale.controllers.main import get_pricelist
  9. from openerp.addons.web.controllers.main import login_redirect
  10. from openerp.addons.website_sale.controllers.main import website_sale
  11. import re
  12. PPG = 12 # Products Per Page
  13. PPR = 3 # Products Per Row
  14. class table_compute(object):
  15. def __init__(self):
  16. self.table = {}
  17. def _check_place(self, posx, posy, sizex, sizey):
  18. res = True
  19. for y in range(sizey):
  20. for x in range(sizex):
  21. if posx+x>=PPR:
  22. res = False
  23. break
  24. row = self.table.setdefault(posy+y, {})
  25. if row.setdefault(posx+x) is not None:
  26. res = False
  27. break
  28. for x in range(PPR):
  29. self.table[posy+y].setdefault(x, None)
  30. return res
  31. def process(self, products):
  32. # Compute products positions on the grid
  33. minpos = 0
  34. index = 0
  35. maxy = 0
  36. for p in products:
  37. x = min(max(p.website_size_x, 1), PPR)
  38. y = min(max(p.website_size_y, 1), PPR)
  39. if index>=PPG:
  40. x = y = 1
  41. pos = minpos
  42. while not self._check_place(pos%PPR, pos/PPR, x, y):
  43. pos += 1
  44. # if 21st products (index 20) and the last line is full (PPR products in it), break
  45. # (pos + 1.0) / PPR is the line where the product would be inserted
  46. # maxy is the number of existing lines
  47. # + 1.0 is because pos begins at 0, thus pos 20 is actually the 21st block
  48. # and to force python to not round the division operation
  49. if index >= PPG and ((pos + 1.0) / PPR) > maxy:
  50. break
  51. if x==1 and y==1: # simple heuristic for CPU optimization
  52. minpos = pos/PPR
  53. for y2 in range(y):
  54. for x2 in range(x):
  55. self.table[(pos/PPR)+y2][(pos%PPR)+x2] = False
  56. self.table[pos/PPR][pos%PPR] = {
  57. 'product': p, 'x':x, 'y': y,
  58. 'class': " ".join(map(lambda x: x.html_class or '', p.website_style_ids))
  59. }
  60. if index<=PPG:
  61. maxy=max(maxy,y+(pos/PPR))
  62. index += 1
  63. # Format table according to HTML needs
  64. rows = self.table.items()
  65. rows.sort()
  66. rows = map(lambda x: x[1], rows)
  67. for col in range(len(rows)):
  68. cols = rows[col].items()
  69. cols.sort()
  70. x += len(cols)
  71. rows[col] = [c for c in map(lambda x: x[1], cols) if c != False]
  72. return rows
  73. # TODO keep with input type hidden
  74. class biztech_theme(http.Controller):
  75. @http.route(['/home/subscribe'
  76. ], type='http', auth="public", website=True)
  77. def subscribe(self, **post):
  78. email=post.pop('email')
  79. values={'sub_error':{},'subscribe':{'email':email}}
  80. if not email:
  81. values = {'sub_error':{'email':True},'subscribe':{'email':email}}
  82. return request.website.render("website.homepage",values)
  83. if email:
  84. if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", email) != None:
  85. pass
  86. else:
  87. values['sub_error'].update({'email': 'invalid'})
  88. return request.website.render("website.homepage",values)
  89. cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
  90. model_id=pool.get('ir.model').search(cr,uid,[('model','=','res.partner')])
  91. mass_mail = pool.get('distribution.list').search(cr,uid,[('name','=','Subscribe')])
  92. if not mass_mail:
  93. mass_mail=pool.get('distribution.list').create(cr,uid,{
  94. 'name':'Subscribe',
  95. 'dst_model_id': model_id[0],
  96. 'bridge_field':'id',
  97. 'partner_path':'id',
  98. 'to_include_distribution_list_line_ids':[[0,False,
  99. {'name':'Subscribe',
  100. 'src_model_id':model_id[0],
  101. 'domain':"[['subscribe', '=', True]]"}
  102. ]]},context)
  103. email_id=email
  104. success_msg=False
  105. already_sub_msg=False
  106. if email_id:
  107. uid=SUPERUSER_ID
  108. partner=pool.get('res.partner').search(cr,uid,[('email','=',email_id),('subscribe','=',True)])
  109. if not partner:
  110. pool.get('res.partner').create(cr,uid,{'name':email_id.split('@')[0],'email':email_id,
  111. 'customer':True,'subscribe':True},context)
  112. success_msg='You have been subscribed successfully.'
  113. else:
  114. already_sub_msg='You are already subscribed.'
  115. return request.website.render("website.homepage", {'successmsg':success_msg,'already_sub_msg':already_sub_msg})
  116. @http.route(['/home/contact_info'
  117. ], type='http', auth="public", website=True)
  118. def contacts(self,**post):
  119. cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
  120. uid=SUPERUSER_ID
  121. partner = pool.get('res.users').browse(cr, SUPERUSER_ID, request.uid, context).partner_id
  122. super_email=pool.get('res.users').browse(cr, SUPERUSER_ID, SUPERUSER_ID, context).email
  123. name=post.pop('full_name', '')
  124. email=post.pop('emp_email', '')
  125. subject=post.pop('email_subject', '')
  126. msg=post.pop('message', '')
  127. contact={'full_name':name,'emp_email':email,'email_subject':subject,'message':msg}
  128. values={'error':{},'contact':contact}
  129. if not name:
  130. values['error'].update({'full_name': True})
  131. if not email:
  132. values['error'].update({'emp_email': True})
  133. if email:
  134. if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", email) != None:
  135. pass
  136. else:
  137. values['error'].update({'emp_email': 'invalid'})
  138. if values and values.has_key('error') and values['error']:
  139. return request.website.render("website.contactus", values)
  140. if super_email:
  141. body="<p>Hello,Admin<br/><br/> Name: "+name+" <br/><br/>Email Address: "+email+ " <br/><br/> Subject: "+subject+" <br/><br/> Message:"+msg+"<br/><br/> Thanks"
  142. temp_id= pool.get('ir.model.data').get_object(cr, uid, 'kingfisher', 'contact_info_email')
  143. pool.get('email.template').write(cr, uid, temp_id.id, {'email_to': super_email,'subject' : subject,'body_html':body or ''}, context=context)
  144. pool.get('email.template').send_mail(cr, uid, temp_id.id,partner.id,True, context=context)
  145. return request.website.render("website.contactus", {'successmsg':'Your message has been sent successfully.'})
  146. return request.website.render("website.contactus", {'failmsg':'Your message has not been sent.'})
  147. #return request.redirect("/page/contactus")
  148. def get_pricelist(self):
  149. return get_pricelist()
  150. @http.route(['/shop/product/comment/<int:product_template_id>'], type='http', auth="public", methods=['GET','POST'], website=True)
  151. def product_comment(self, product_template_id, **post):
  152. if not request.session.uid:
  153. request.session.update({'comments':post.get('comment')})
  154. return login_redirect()
  155. cr, uid, context = request.cr, request.uid, request.context
  156. if post.get('comment') or request.session.has_key('comments') and request.session.comments!=None:
  157. request.registry['product.template'].message_post(
  158. cr, uid, product_template_id,
  159. body=post.get('comment') or request.session.comments,
  160. type='comment',
  161. subtype='mt_comment',
  162. context=dict(context, mail_create_nosubscribe=True))
  163. if request.session.has_key('comments') and request.session.comments!=None:
  164. request.session.update({'comments':None})
  165. return werkzeug.utils.redirect('/shop/product/' +str(product_template_id)+ "#comments")
  166. return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
  167. @http.route(['/shop',
  168. '/shop/page/<int:page>',
  169. '/shop/category/<model("product.public.category"):category>',
  170. '/shop/category/<model("product.public.category"):category>/page/<int:page>'
  171. ], type='http', auth="public", website=True)
  172. def shop(self, page=0, category=None, search='', **post):
  173. cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
  174. domain = request.website.sale_product_domain()
  175. if search:
  176. for srch in search.split(" "):
  177. domain += ['|', '|', '|', ('name', 'ilike', srch), ('description', 'ilike', srch),
  178. ('description_sale', 'ilike', srch), ('product_variant_ids.default_code', 'ilike', srch)]
  179. if category:
  180. domain += [('public_categ_ids', 'child_of', int(category))]
  181. attrib_list = request.httprequest.args.getlist('attrib')
  182. attrib_values = [map(int,v.split("-")) for v in attrib_list if v]
  183. attrib_set = set([v[1] for v in attrib_values])
  184. if attrib_values:
  185. attrib = None
  186. ids = []
  187. for value in attrib_values:
  188. if not attrib:
  189. attrib = value[0]
  190. ids.append(value[1])
  191. elif value[0] == attrib:
  192. ids.append(value[1])
  193. else:
  194. domain += [('attribute_line_ids.value_ids', 'in', ids)]
  195. attrib = value[0]
  196. ids = [value[1]]
  197. if attrib:
  198. domain += [('attribute_line_ids.value_ids', 'in', ids)]
  199. keep = QueryURL('/shop', category=category and int(category), search=search, attrib=attrib_list)
  200. if not context.get('pricelist'):
  201. pricelist = self.get_pricelist()
  202. context['pricelist'] = int(pricelist)
  203. else:
  204. pricelist = pool.get('product.pricelist').browse(cr, uid, context['pricelist'], context)
  205. product_obj = pool.get('product.template')
  206. url = "/shop"
  207. product_count = product_obj.search_count(cr, uid, domain, context=context)
  208. if search:
  209. post["search"] = search
  210. if category:
  211. category = pool['product.public.category'].browse(cr, uid, int(category), context=context)
  212. url = "/shop/category/%s" % slug(category)
  213. if attrib_list:
  214. post['attrib'] = attrib_list
  215. pager = request.website.pager(url=url, total=product_count, page=page, step=PPG, scope=7, url_args=post)
  216. product_ids = product_obj.search(cr, uid, domain, limit=PPG, offset=pager['offset'], order='website_published desc, website_sequence desc', context=context)
  217. products = product_obj.browse(cr, uid, product_ids, context=context)
  218. style_obj = pool['product.style']
  219. style_ids = style_obj.search(cr, uid, [], context=context)
  220. styles = style_obj.browse(cr, uid, style_ids, context=context)
  221. category_obj = pool['product.public.category']
  222. category_ids = category_obj.search(cr, uid, [('parent_id', '=', False)], context=context)
  223. categs = category_obj.browse(cr, uid, category_ids, context=context)
  224. attributes_obj = request.registry['product.attribute']
  225. attributes_ids = attributes_obj.search(cr, uid, [], context=context)
  226. attributes = attributes_obj.browse(cr, uid, attributes_ids, context=context)
  227. from_currency = pool.get('product.price.type')._get_field_currency(cr, uid, 'list_price', context)
  228. to_currency = pricelist.currency_id
  229. compute_currency = lambda price: pool['res.currency']._compute(cr, uid, from_currency, to_currency, price, context=context)
  230. values = {
  231. 'search': search,
  232. 'category': category,
  233. 'attrib_values': attrib_values,
  234. 'attrib_set': attrib_set,
  235. 'pager': pager,
  236. 'pricelist': pricelist,
  237. 'products': products,
  238. 'bins': table_compute().process(products),
  239. 'rows': PPR,
  240. 'styles': styles,
  241. 'categories': categs,
  242. 'attributes': attributes,
  243. 'compute_currency': compute_currency,
  244. 'keep': keep,
  245. 'style_in_product': lambda style, product: style.id in [s.id for s in product.website_style_ids],
  246. 'attrib_encode': lambda attribs: werkzeug.url_encode([('attrib',i) for i in attribs]),
  247. }
  248. return request.website.render("website_sale.products", values)
  249. @http.route(['/shop/get_products_slider'], type='http', auth='public', website=True)
  250. def get_slider_product(self, **post):
  251. cr, uid, context = request.cr, request.uid, request.context
  252. value = {'products': False, 'header': False}
  253. if post.get('product_count') and post.get('slider_type'):
  254. prod_ids = request.registry['product.template'].search(cr, uid, [(post.get(
  255. 'slider_type'), '=', 'True'), ("sale_ok", "=", True)], limit=int(post.get('product_count')), context=context)
  256. price_list = request.registry[
  257. 'website'].price_list_get(cr, uid, context)
  258. product_data = request.registry['product.template'].browse(
  259. cr, uid, prod_ids, {'pricelist': int(price_list)})
  260. if product_data:
  261. value['products'] = product_data
  262. if post.get('slider_type') == 'is_arrival':
  263. if post.get('product_label'):
  264. value['header'] = post.get('product_label')
  265. else:
  266. value['header'] = "LANZAMIENTOS"
  267. if post.get('slider_type') == 'is_features':
  268. if post.get('product_label'):
  269. value['header'] = post.get('product_label')
  270. else:
  271. value['header'] = "FEATURES PRODUCT"
  272. if post.get('product_label'):
  273. value['header'] = post.get('product_label')
  274. return request.website.render("kingfisher.product_snippet", value)
  275. @http.route(['/shop/get_brand_slider'], type='http', auth='public', website=True)
  276. def get_brand_slider(self, **post):
  277. cr, uid, context = request.cr, request.uid, request.context
  278. value = {'brand_header': False}
  279. if post.get('product_label'):
  280. value['brand_header'] = post.get('product_label')
  281. return request.website.render("kingfisher.our_brand_slider", value)
  282. class product_zoom_config(website_sale):
  283. @http.route(['/product/zoom_type'], type='json', auth="public", website=True)
  284. def get_zoom_type(self, type_id=None):
  285. cr, uid, context = request.cr, request.uid, request.context
  286. result=False
  287. result=request.website.inner_zoom
  288. return result
  289. # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: