# -*- coding: utf-8 -*-
# Part of BiztechCS. See LICENSE file for full copyright and licensing details.
import werkzeug
from openerp import http
from openerp.http import request
from openerp import SUPERUSER_ID
from openerp.tools.translate import _
from openerp.addons.website.models.website import slug
from openerp.addons.website_sale.controllers.main import QueryURL
from openerp.addons.website_sale.controllers.main import get_pricelist
from openerp.addons.web.controllers.main import login_and_redirect
from openerp.addons.website_sale.controllers.main import website_sale
import re
PPG = 12 # Products Per Page
PPR = 3 # Products Per Row
class table_compute(object):
def __init__(self):
self.table = {}
def _check_place(self, posx, posy, sizex, sizey):
res = True
for y in range(sizey):
for x in range(sizex):
if posx + x >= PPR:
res = False
break
row = self.table.setdefault(posy + y, {})
if row.setdefault(posx + x) is not None:
res = False
break
for x in range(PPR):
self.table[posy + y].setdefault(x, None)
return res
def process(self, products):
# Compute products positions on the grid
minpos = 0
index = 0
maxy = 0
for p in products:
x = min(max(p.website_size_x, 1), PPR)
y = min(max(p.website_size_y, 1), PPR)
if index >= PPG:
x = y = 1
pos = minpos
while not self._check_place(pos % PPR, pos / PPR, x, y):
pos += 1
# if 21st products (index 20) and the last line is full (PPR products in it), break
# (pos + 1.0) / PPR is the line where the product would be inserted
# maxy is the number of existing lines
# + 1.0 is because pos begins at 0, thus pos 20 is actually the 21st block
# and to force python to not round the division operation
if index >= PPG and ((pos + 1.0) / PPR) > maxy:
break
if x == 1 and y == 1: # simple heuristic for CPU optimization
minpos = pos / PPR
for y2 in range(y):
for x2 in range(x):
self.table[(pos / PPR) + y2][(pos % PPR) + x2] = False
self.table[pos / PPR][pos % PPR] = {
'product': p, 'x': x, 'y': y,
'class': " ".join(map(lambda x: x.html_class or '', p.website_style_ids))
}
if index <= PPG:
maxy = max(maxy, y + (pos / PPR))
index += 1
# Format table according to HTML needs
rows = self.table.items()
rows.sort()
rows = map(lambda x: x[1], rows)
for col in range(len(rows)):
cols = rows[col].items()
cols.sort()
x += len(cols)
rows[col] = [c for c in map(lambda x: x[1], cols) if c != False]
return rows
# TODO keep with input type hidden
class biztech_theme(http.Controller):
@http.route(['/home/contact_info'
], type='http', auth="public", website=True)
def contacts(self, **post):
partner = request.env.user.partner_id
super_email = request.env.user.email
name = post.pop('full_name', '')
email = post.pop('emp_email', '')
subject = post.pop('email_subject', '')
msg = post.pop('message', '')
contact = {'full_name': name, 'emp_email': email,
'email_subject': subject, 'message': msg}
values = {'error': {}, 'contact': contact}
if not name:
values['error'].update({'full_name': True})
if not email:
values['error'].update({'emp_email': True})
if email:
if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", email) != None:
pass
else:
values['error'].update({'emp_email': 'invalid'})
if values and values.has_key('error') and values['error']:
return request.website.render("website.contactus", values)
if super_email:
body = "
Hello,Admin
Name: " + name + "
Email Address: " + email + \
"
Subject: " + subject + \
"
Message:" + msg + "
Thanks"
temp_id = request.env.ref('kingfisher.contact_info_email')
request.registry['mail.template'].browse(temp_id.id).write({
'email_to': super_email, 'subject': subject, 'body_html': body or ''})
request.registry['mail.template'].send_mail(
temp_id.id, partner.id, True)
return request.website.render("website.contactus", {'successmsg': 'Your message has been sent successfully.'})
return request.website.render("website.contactus", {'failmsg': 'Your message has not been sent.'})
def get_pricelist(self):
return get_pricelist()
@http.route(['/shop',
'/shop/page/',
'/shop/category/',
'/shop/category//page/'
], type='http', auth="public", website=True)
def shop(self, page=0, category=None, search='', **post):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
domain = request.website.sale_product_domain()
if search:
for srch in search.split(" "):
domain += ['|', '|', '|', ('name', 'ilike', srch), ('description', 'ilike', srch),
('description_sale', 'ilike', srch), ('product_variant_ids.default_code', 'ilike', srch)]
if category:
domain += [('public_categ_ids', 'child_of', int(category))]
attrib_list = request.httprequest.args.getlist('attrib')
attrib_values = [map(int, v.split("-")) for v in attrib_list if v]
attrib_set = set([v[1] for v in attrib_values])
if attrib_values:
attrib = None
ids = []
for value in attrib_values:
if not attrib:
attrib = value[0]
ids.append(value[1])
elif value[0] == attrib:
ids.append(value[1])
else:
domain += [('attribute_line_ids.value_ids', 'in', ids)]
attrib = value[0]
ids = [value[1]]
if attrib:
domain += [('attribute_line_ids.value_ids', 'in', ids)]
keep = QueryURL(
'/shop', category=category and int(category), search=search, attrib=attrib_list)
if not context.get('pricelist'):
pricelist = self.get_pricelist()
context['pricelist'] = int(pricelist)
else:
pricelist = pool.get('product.pricelist').browse(
cr, uid, context['pricelist'], context)
product_obj = pool.get('product.template')
parent_category_ids = []
if category:
parent_category_ids = [category.id]
current_category = category
while current_category.parent_id:
parent_category_ids.append(current_category.parent_id.id)
current_category = current_category.parent_id
url = "/shop"
product_count = product_obj.search_count(cr, uid, domain, context=context)
if search:
post["search"] = search
if category:
category = pool['product.public.category'].browse(
cr, uid, int(category), context=context)
url = "/shop/category/%s" % slug(category)
if attrib_list:
post['attrib'] = attrib_list
pager = request.website.pager(
url=url, total=product_count, page=page, step=PPG, scope=7, url_args=post)
product_ids = product_obj.search(cr, uid, domain, limit=PPG, offset=pager[
'offset'], order='website_published desc, website_sequence desc', context=context)
products = product_obj.browse(cr, uid, product_ids, context=context)
style_obj = pool['product.style']
style_ids = style_obj.search(cr, uid, [], context=context)
styles = style_obj.browse(cr, uid, style_ids, context=context)
category_obj = pool['product.public.category']
category_ids = category_obj.search(cr, uid, [('parent_id', '=', False)], context=context)
categs = category_obj.browse(cr, uid, category_ids, context=context)
attributes_obj = request.registry['product.attribute']
attributes_ids = attributes_obj.search(cr, uid, [], context=context)
attributes = attributes_obj.browse(cr, uid, attributes_ids, context=context)
#from_currency = pool.get('product.price.type')._get_field_currency(cr, uid, 'list_price', context)
from_currency = pool['res.users'].browse(cr, uid, uid, context=context).company_id.currency_id
to_currency = pricelist.currency_id
compute_currency = lambda price: pool['res.currency']._compute(
cr, uid, from_currency, to_currency, price, context=context)
values = {
'search': search,
'category': category,
'attrib_values': attrib_values,
'attrib_set': attrib_set,
'pager': pager,
'pricelist': pricelist,
'products': products,
'bins': table_compute().process(products),
'rows': PPR,
'styles': styles,
'categories': categs,
'attributes': attributes,
'compute_currency': compute_currency,
'keep': keep,
'parent_category_ids': parent_category_ids,
'style_in_product': lambda style, product: style.id in [s.id for s in product.website_style_ids],
'attrib_encode': lambda attribs: werkzeug.url_encode([('attrib', i) for i in attribs]),
}
return request.website.render("website_sale.products", values)
@http.route(['/shop/get_products_slider'], type='http', auth='public', website=True)
def get_slider_product(self, **post):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
value = {'products': False, 'header': False}
if not context.get('pricelist'):
pricelist = self.get_pricelist()
context['pricelist'] = int(pricelist)
else:
pricelist = pool.get('product.pricelist').browse(
cr, uid, context['pricelist'], context)
from_currency = pool['res.users'].browse(
cr, uid, uid, context=context).company_id.currency_id
to_currency = pricelist.currency_id
compute_currency = lambda price: pool['res.currency']._compute(
cr, uid, from_currency, to_currency, price, context=context)
value.update({'compute_currency': compute_currency})
if post.get('product_count') and post.get('slider_type'):
prod_ids = request.registry['product.template'].search(cr, uid, [(post.get(
'slider_type'), '=', 'True'), ("sale_ok", "=", True)], limit=int(post.get('product_count')), context=context)
price_list = request.registry['website'].price_list_get()
product_data = request.registry['product.template'].browse(
cr, uid, prod_ids, context)
if product_data:
value['products'] = product_data
if post.get('slider_type') == 'is_arrival':
if post.get('product_label'):
value['header'] = post.get('product_label')
else:
value['default_header'] = 'is_arrival'
if post.get('slider_type') == 'is_features':
if post.get('product_label'):
value['header'] = post.get('product_label')
else:
value['default_header'] = 'is_features'
if post.get('product_label'):
value['header'] = post.get('product_label')
if not post.get('product_label') and post.get('slider_type') == 'is_arrival':
value['default_header'] = 'is_arrival'
if not post.get('product_label') and post.get('slider_type') == 'is_features':
value['default_header'] = 'is_features'
return request.website.render("kingfisher.product_snippet", value)
@http.route(['/shop/get_brand_slider'], type='http', auth='public', website=True)
def get_brand_slider(self, **post):
value = {'brand_header': False}
if post.get('product_label'):
value['brand_header'] = post.get('product_label')
return request.website.render("kingfisher.our_brand_slider", value)
class product_zoom_config(website_sale):
@http.route(['/product/zoom_type'], type='json', auth="public", website=True)
def get_zoom_type(self, type_id=None):
result = False
result = request.website.inner_zoom
return result