[WIP] website_sale: refactoring and use inherit_option_id

bzr revid: chm@openerp.com-20130812163123-3ako1rggjnszzi2h
This commit is contained in:
Christophe Matthieu 2013-08-12 18:31:23 +02:00
parent ed5ad1c91d
commit 59ba4e7561
5 changed files with 143 additions and 106 deletions

View File

@ -27,6 +27,7 @@ def urlplus(url, params):
url += "%s=%s&" % (k, urllib.quote_plus(v))
return url
class website(osv.osv):
_name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco
_description = "Website"
@ -93,4 +94,25 @@ class website(osv.osv):
for page in range(pmin, pmax+1):
d["pages"].append({'url': "%spage/%s/" % (url, page), 'num': page})
return d
return d
class res_partner(osv.osv):
_inherit = "res.partner"
def google_map_img(self, cr, uid, ids, zoom=8, width=298, height=298, context=None):
partner = self.browse(cr, uid, ids[0], context=context)
params = {
'center': '%s, %s %s, %s' % (partner.street, partner.city, partner.zip, partner.country_id and partner.country_id.name_get()[0][1] or ''),
'size': "%sx%s" % (height, width),
'zoom': zoom,
'sensor': 'false',
}
return urlplus('http://maps.googleapis.com/maps/api/staticmap' , params)
def google_map_link(self, cr, uid, ids, zoom=8, context=None):
partner = self.browse(cr, uid, ids[0], context=context)
params = {
'q': '%s, %s %s, %s' % (partner.street, partner.city, partner.zip, partner.country_id and partner.country_id.name_get()[0][1] or ''),
}
return urlplus('https://maps.google.be/maps' , params)

View File

@ -1,3 +1,2 @@
import controllers
import pricelist
import product
import website_sale

View File

@ -50,40 +50,6 @@ class Ecommerce(http.Controller):
categories = category_obj.browse(request.cr, openerp.SUPERUSER_ID, category_ids)
return categories
def render(self, template, values={}):
website = request.registry['website']
_values = {
'categories': self.get_categories(),
}
_values.update(values)
return website.render(template, _values)
def recommended_product(self, my_pids):
if not my_pids:
return []
product_obj = request.registry.get('product.product')
my_pids = str(my_pids)[1:-1]
product_ids = []
query = """
SELECT sol.product_id
FROM sale_order_line as my
LEFT JOIN sale_order_line as sol
ON sol.order_id = my.order_id
WHERE my.product_id in (%s)
AND sol.product_id not in (%s)
GROUP BY sol.product_id
ORDER BY COUNT(sol.order_id) DESC
LIMIT 8
""" % (my_pids, my_pids)
request.cr.execute(query)
for p in request.cr.fetchall():
product_ids.append(p[0])
# search to apply access rules
product_ids = product_obj.search(request.cr, request.uid, [("id", "in", product_ids)])
return product_obj.browse(request.cr, request.uid, product_ids)
@http.route(['/shop/', '/shop/category/<cat_id>/', '/shop/category/<cat_id>/page/<int:page>/', '/shop/page/<int:page>/'], type='http', auth="public")
def category(self, cat_id=0, page=0, **post):
@ -105,12 +71,13 @@ class Ecommerce(http.Controller):
product_ids = product_obj.search(request.cr, request.uid, domain, limit=step, offset=pager['offset'])
values = website.get_rendering_context({
'categories': self.get_categories(),
'current_category': cat_id,
'products': product_obj.browse(request.cr, request.uid, product_ids),
'search': post.get("search"),
'pager': pager,
})
return self.render("website_sale.products", values)
return website.render("website_sale.products", values)
@http.route(['/shop/product/<product_id>/'], type='http', auth="public")
def product(self, cat_id=0, product_id=0):
@ -121,32 +88,28 @@ class Ecommerce(http.Controller):
product_obj = request.registry.get('product.product')
line = [line for line in order.order_line if line.product_id.id == product_id]
quantity = line and int(line[0].product_uom_qty) or 0
values = website.get_rendering_context({
'categories': self.get_categories(),
'product': product_obj.browse(request.cr, request.uid, product_id),
'quantity': quantity,
'recommended_products': self.recommended_product([product_id]),
})
return self.render("website_sale.product", values)
return website.render("website_sale.product", values)
@http.route(['/shop/mycart/'], type='http', auth="public")
def mycart(self, **post):
website = request.registry['website']
order = get_current_order()
website = request.registry['website']
if post.get('code'):
pricelist_obj = request.registry.get('product.pricelist')
pricelist_ids = pricelist_obj.search(request.cr, openerp.SUPERUSER_ID, [('code', '=', post.get('code'))])
if pricelist_ids:
order.write({'pricelist_id': pricelist_ids[0]})
my_pids = [line.product_id.id for line in order.order_line]
values = website.get_rendering_context({
"recommended_products": self.recommended_product(my_pids),
'categories': self.get_categories(),
})
return self.render("website_sale.mycart", values)
return website.render("website_sale.mycart", values)
def add_product_to_cart(self, product_id=0, number=1):
context = {}

View File

@ -22,8 +22,7 @@
<a href="/shop/mycart/">
<i class="icon-shopping-cart"></i>
My cart
<!-- FIXME: logic to obtain the shopping cart numer of items shall not be in the template. Move it in models or in controllers -->
<!-- <span class="badge badge-success" t-if="order.order_line" t-esc="int(sum([l.product_uom_qty for l in order.order_line]))"/> -->
<span class="badge badge-success" t-if="order.get_total_quantity()" t-esc="order.get_total_quantity()"/>
</a>
</li>
</xpath>
@ -44,7 +43,7 @@
<!-- Page Shop -->
<template id="page">
<template id="layout_categories">
<t t-call="website.layout">
<t t-set="head">
<script type="text/javascript" src="/website_sale/static/src/js/website_sale.js"></script>
@ -54,25 +53,21 @@
<t t-set="title">Shop - <t t-raw="title">Categories</t></t>
<div class="container mt48 oe_ecommerce">
<div class="row">
<t t-call='website_sale.categories' />
<div class="span4">
<ul class="nav nav-list">
<li t-att-class=" '' if current_category else 'active' " class='active'><a href='/shop/'>All Products</a></li>
<t t-foreach="categories" t-as="category">
<t t-call="website_sale.categories_recursive"/>
</t>
</ul>
</div>
<t t-raw="shop_content" />
</div>
</div>
</t>
</template>
<!-- List of categories -->
<template id="categories">
<div class="span4">
<ul class="nav nav-list">
<li t-att-class=" '' if current_category else 'active' " class='active'><a href='/shop/'>All Products</a></li>
<t t-foreach="categories" t-as="category">
<t t-call="website_sale.categories_recursive"/>
</t>
</ul>
</div>
</template>
<!-- List of categories -->
<template id="categories_recursive">
<li t-att-class="category.id == current_category and 'active' or ''">
@ -88,7 +83,7 @@
<!-- Product list -->
<template id="products">
<t t-call="website_sale.page">
<t t-call="website_sale.layout_categories">
<t t-set="title">Product</t>
<t t-set="shop_content">
<div class='span8 navbar navbar-inverse'>
@ -105,8 +100,6 @@
<div class='row grid grid-align-top'>
<t t-foreach="products" t-as="product">
<t t-set="quantity" t-value="1"/>
<!-- FIXME: logic to obtain a specific product count in the shopping cart shall not be in the template. Move it in models or in controllers -->
<!-- <t t-set="quantity" t-value="([int(line.product_uom_qty) for line in (order.order_line or []) if line.product_id.id == product.id] + [0])[0]"/> -->
<t t-call="website_sale.product_card"/>
</t>
</div>
@ -130,38 +123,19 @@
<div t-field="product.description_sale"></div>
<div><span t-field="product.list_price"></span></div>
<div class="mb8 mt8">
<a t-if="quantity" t-att-href="'./remove_cart/%s/' % product.id" class="btn mb8 btn-small btn-inverse">Remove one</a>
<a t-att-href="'./add_cart/%s/' % product.id" class="btn btn-small btn-success">Add to cart <t t-if="quantity">(<t t-esc="quantity"/>)</t></a>
<a t-att-href="'./add_cart/%s/' % product.id" class="btn btn-small btn-success">Add to cart</a>
</div>
</div>
</div>
</template>
<template id="product_recommended">
<div class="well mt32" t-if="recommended_products">
<h4>Customers who have bought this item also bought</h4>
<div class='row mt16'>
<t t-foreach="recommended_products or []" t-as="product">
<div class='span2 thumbnail'>
<a t-att-href="'/shop/product/%%s/' %% product.id">
<div class='mt16 text-center'>
<img t-att-src="'data:image/png;base64,' + product.image"/>
<h5 t-field='product.name'></h5>
</div>
</a>
</div>
</t>
</div>
</div>
</template>
<!-- product -->
<template id="product">
<t t-call="website_sale.page">
<template id="product" name="Product">
<t t-call="website_sale.layout_categories">
<t t-set="title">Product</t>
<t t-set="shop_content">
<div class="oe_product_detail span8">
<div class="oe_product_detail span8" id="product_detail">
<a href="#" t-att-data-id="product.id" class="pull-right" t-if="editable">
<span t-att-class="'label label-success js_unpublish %%s' %% (not product.website_published and 'hidden' or '')">Click to Unpublish</span>
<span t-att-class="'label label-important js_publish %%s' %% (product.website_published and 'hidden' or '')">Click to Publish</span>
@ -169,41 +143,88 @@
<h2 t-field="product.name"></h2>
<div class="oe_button_cart">
<a t-if="quantity" t-att-href="'./remove_cart/%s/' % product.id" class="btn btn-small btn-inverse">Remove one</a>
<a t-att-href="'./add_cart/%s/' % product.id" class="btn btn-small btn-success">Add to cart <t t-if="quantity">(<t t-esc="quantity"/>)</t></a>
<a t-att-href="'./add_cart/%s/' % product.id" class="btn btn-small btn-success">Add to cart</a>
</div>
<img class="media-object" t-att-src="'data:image/png;base64,' + product.image"/>
<div t-field="product.description_website"></div>
<div class="oe_ecommerce_price"><t t-field="product.list_price" /></div>
<t t-call="website_sale.product_recommended"/>
</div>
</t>
</t>
</template>
<template id="recommended_products" inherit_id="website_sale.product" inherit_option_id="website_sale.product" name="Recommended Products">
<xpath expr="//div[@id='product_detail']" position="inside">
<div class="well mt32" t-if="product.recommended_products()">
<h4>Customers who have bought this item also bought</h4>
<div class='row mt16'>
<t t-foreach="product.recommended_products()" t-as="product">
<div class='span2 thumbnail'>
<a t-att-href="'/shop/product/%%s/' %% product.id">
<div class='mt16 text-center'>
<img t-att-src="'data:image/png;base64,' + product.image"/>
<h5 t-field='product.name'></h5>
</div>
</a>
</div>
</t>
</div>
</div>
</xpath>
</template>
<!-- Page Shop my cart -->
<template id="mycart">
<t t-call="website_sale.page">
<t t-call="website_sale.layout_categories">
<t t-set="title">My cart</t>
<t t-set="shop_content">
<div class="span8 oe_mycart">
<h2>My Shopping Cart</h2>
<h3 t-if="not order.order_line">Your cart is empty</h3>
<div class='row mt32 grid grid-align-top'>
<t t-foreach="order.order_line or []" t-as="line">
<t t-set="product" t-value="line.product_id"/>
<t t-set="quantity" t-value="int(line.product_uom_qty)"/>
<t t-call="website_sale.product_card"/>
</t>
</div>
<t t-call="website_sale.total"/>
<table class='table-equalized' t-if="order.order_line">
<thead>
<tr><th>Product</th><th>Qty.</th><th>Price</th></tr>
</thead>
<tbody>
<t t-foreach="order.order_line" t-as="line">
<tr>
<td>
<a t-att-href="line.product_id"><span t-field="line.product_id.name"/></a>
</td>
<td>
<a t-att-href="line.product_id"><img class="img-rounded" t-att-src="'data:image/png;base64,' + line.product_id.image"/></a>
</td>
<td>
<span t-field="line.product_id.list_price"></span>
</td>
<td>
<div class="mb8 mt8">
<input type="text" t-att-value="line.product_uom_qty"/>
<a t-attf-href="./remove_cart/#{ line.product_id.id }/" class="btn mb8 btn-small btn-inverse">-</a>
<a t-attf-href="./add_cart/#{ line.product_id.id }/" class="btn mb8 btn-small btn-success">+</a>
</div>
</td>
</tr>
<tr>
<td> </td>
<td colspan="2">
<small t-field="line.product_id.description_sale"/>
</td>
</tr>
</t>
</tbody>
<tfoot>
<tr> <td>Subtotal </td> <td><t t-esc="order.amount_untaxed"/></td></tr>
<tr> <td>Taxes </td> <td><t t-esc="order.amount_tax"/></td></tr>
<tr> <td><h4>Total</h4></td> <td><h4><t t-esc="order.amount_total"/></h4></td></tr>
</tfoot>
</table>
<form t-if="order.order_line" class="well form-search" action="/shop/mycart/" method="post">
<input name="code" class='input' type="text" placeholder="Reduction Code..."/>
<button class="btn">Apply Code</button>
</form>
<a t-if="order.order_line" href="/shop/checkout/"><button class="btn btn-success">Proceed To Payment</button></a>
<t t-call="website_sale.product_recommended"/>
</div>
</t>
</t>

View File

@ -2,11 +2,11 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# Copyright (C)-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# published by the Free Software Foundation, either version of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
@ -33,4 +33,36 @@ class product_product(osv.osv):
_columns = {
'website_published': fields.boolean('Available in the website'),
'description_website': fields.html('Description for the website'),
}
}
def recommended_products(self, cr, uid, ids, context=None):
id = ids[0]
product_ids = []
query = """
SELECT sol.product_id
FROM sale_order_line as my
LEFT JOIN sale_order_line as sol
ON sol.order_id = my.order_id
WHERE my.product_id in (%s)
AND sol.product_id not in (%s)
GROUP BY sol.product_id
ORDER BY COUNT(sol.order_id) DESC
LIMIT 8
""" % (id, id)
cr.execute(query)
for p in cr.fetchall():
product_ids.append(p[0])
# search to apply access rules
product_ids = self.search(cr, uid, [("id", "in", product_ids)])
return self.browse(cr, uid, product_ids)
class sale_order(osv.osv):
_inherit = "sale.order"
def get_total_quantity(self, cr, uid, ids, context=None):
order = self.browse(cr, uid, ids[0], context=context)
if order.order_line:
result = sum([l.product_uom_qty for l in order.order_line])
return result