[IMP] website_sale_options

This commit is contained in:
Christophe Matthieu 2014-06-24 15:11:53 +02:00
parent 1d68662fb9
commit 204a62499a
16 changed files with 300 additions and 193 deletions

View File

@ -62,7 +62,7 @@ class ir_http(orm.AbstractModel):
self.geo_ip_resolver = GeoIP.open('/usr/share/GeoIP/GeoIP.dat', GeoIP.GEOIP_STANDARD)
except ImportError:
self.geo_ip_resolver = False
if self.geo_ip_resolver:
if self.geo_ip_resolver and request.httprequest.remote_addr:
record = self.geo_ip_resolver.record_by_addr(request.httprequest.remote_addr) or {}
request.session['geoip'] = record

View File

@ -98,17 +98,17 @@ class QueryURL(object):
return path
class website_sale(http.Controller):
def get_pricelist():
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
sale_order = context.get('sale_order')
if sale_order:
pricelist = sale_order.pricelist_id
else:
partner = pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id
pricelist = partner.property_product_pricelist
return pricelist
def get_pricelist(self):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
sale_order = context.get('sale_order')
if sale_order:
pricelist = sale_order.pricelist_id
else:
partner = pool['res.users'].browse(cr, SUPERUSER_ID, uid, context=context).partner_id
pricelist = partner.property_product_pricelist
return pricelist
class website_sale(http.Controller):
@http.route(['/shop',
'/shop/page/<int:page>',
@ -215,11 +215,6 @@ class website_sale(http.Controller):
context['pricelist'] = int(self.get_pricelist())
product = template_obj.browse(cr, uid, int(product), context=context)
optional_product_ids = []
for p in product.optional_product_ids:
ctx = dict(context, active_id=p.id)
optional_product_ids.append(template_obj.browse(cr, uid, p.id, context=ctx))
attribute_value_ids = []
if request.website.company_pricelist_id.id != context['pricelist']:
company_currency_id = request.website.company_currency_id.id
@ -240,7 +235,6 @@ class website_sale(http.Controller):
'category_list': category_list,
'main_object': product,
'product': product,
'optional_product_ids': optional_product_ids,
'attribute_value_ids': attribute_value_ids
}
return request.website.render("website_sale.product", values)
@ -282,24 +276,13 @@ class website_sale(http.Controller):
@http.route(['/shop/cart/update'], type='http', auth="public", methods=['POST'], website=True)
def cart_update(self, product_id, add_qty=1, set_qty=0, goto_shop=None, **kw):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
order = request.website.sale_get_order(force_create=1)
prod_obj = pool['product.product']
optional_product_ids = []
for k, v in kw.items():
if "optional-product-" in k and int(kw.get(k.replace("product", "quantity"))):
optional_product_ids.append(int(v))
if add_qty or set_qty:
line_id, quantity, option_ids = order._cart_update(product_id=int(product_id),
add_qty=int(add_qty), set_qty=int(set_qty),
optional_product_ids=optional_product_ids)
# options have all time the same quantity
for option_id in optional_product_ids:
order._cart_update(product_id=option_id, set_qty=quantity, linked_line_id=line_id)
order = request.website.sale_get_order(force_create=1)
line_id, quantity = order._cart_update(product_id=int(product_id), add_qty=int(add_qty), set_qty=int(set_qty))
if goto_shop:
attrib_list = request.httprequest.args.getlist('attrib')
keep = QueryURL('/shop', category=kw.get('category'), search=kw.get('search'), attrib=attrib_list)
return request.redirect( keep() )
return request.redirect("/shop/product/%s" % slug(prod_obj.browse(cr, uid, product_id).product_tmpl_id))
else:
return request.redirect("/shop/cart")

View File

@ -6,58 +6,6 @@
<field name="image" type="base64" file="website/static/description/website_edit.png"/>
</record>
<!-- add Warranty to ipad -->
<record id="product_attribute_1" model="product.attribute">
<field name="name">Duration</field>
<field name="type">hidden</field>
</record>
<record id="product_attribute_value_1" model="product.attribute.value">
<field name="name">1 year</field>
<field name="attribute_id" ref="product_attribute_1"/>
</record>
<record id="product_attribute_value_2" model="product.attribute.value">
<field name="name">2 year</field>
<field name="attribute_id" ref="product_attribute_1"/>
</record>
<record id="product_product_1" model="product.product">
<field name="name">Warranty</field>
<field name="list_price">20.0</field>
<field name="website_sequence">1000</field>
<field name="website_published" eval="True"/>
<field name="type">service</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
<field name="description_sale">Warranty, issued to the purchaser of an article by its manufacturer, promising to repair or replace it if necessary within a specified period of time.</field>
<field name="default_code">W0001</field>
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_1')])]"/>
</record>
<record id="product_product_1b" model="product.product">
<field name="default_code">W0002</field>
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_2')])]"/>
</record>
<record id="product_attribute_line_1" model="product.attribute.line">
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
<field name="attribute_id" ref="product_attribute_1"/>
<field name="value_ids" eval="[(6,0,[ref('product_attribute_value_1'), ref('product_attribute_value_2')])]"/>
</record>
<record id="product_product_1_product_template" model="product.template">
<field name="attribute_line_ids" eval="[(6,0,[ref('product_attribute_line_1')])]"/>
</record>
<record id="product.product_product_4_product_template" model="product.template">
<field name="optional_product_ids" eval="[(6,0,[ref('product_product_1_product_template')])]"/>
</record>
<record id="product_attribute_price_1" model="product.attribute.price">
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
<field name="value_id" ref="product_attribute_value_2"/>
<field name="price_extra">18.00</field>
</record>
<!-- -->
<record id="product.product_attribute_2" model="product.attribute">
<field name="type">color</field>
</record>

View File

@ -51,20 +51,14 @@ class sale_order(osv.Model):
'order': order
}
def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, linked_line_id=None, optional_product_ids=None, context=None):
def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, context=None):
for so in self.browse(cr, uid, ids, context=context):
order_line_id = None
domain = [('order_id', '=', so.id), ('product_id', '=', product_id)]
if line_id:
domain += [('id', '=', line_id)]
domain += linked_line_id and [('linked_line_id', '=', linked_line_id)] or [('linked_line_id', '=', False)]
if not line_id:
if optional_product_ids:
domain += [('option_line_ids.product_id', '=', pid) for pid in optional_product_ids]
else:
domain += [('option_line_ids', '=', False)]
order_line_id = None
order_line_ids = self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
if order_line_ids:
order_line_id = order_line_ids[0]
@ -99,15 +93,11 @@ class sale_order(osv.Model):
quantity = 0
for so in self.browse(cr, uid, ids, context=context):
line_id = so._cart_find_product_line(product_id, line_id, linked_line_id, optional_product_ids, context=context)
line_id = so._cart_find_product_line(product_id, line_id, context=context)
# Create line if no line with product_id can be located
if not line_id:
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, context=context)
if linked_line_id and linked_line_id in map(int,so.order_line):
values["linked_line_id"] = linked_line_id
linked = sol.browse(cr, SUPERUSER_ID, linked_line_id, context=context)
values["name"] = _("%s\nLinked to: %s") % (values["name"], linked.product_id.name_get()[0][1])
line_id = sol.create(cr, SUPERUSER_ID, values, context=context)
if add_qty:
add_qty -= 1
@ -118,23 +108,16 @@ class sale_order(osv.Model):
elif add_qty != None:
quantity = sol.browse(cr, SUPERUSER_ID, line_id, context=context).product_uom_qty + (add_qty or 0)
# select linked product
option_ids = [line.id for line in so.order_line if line.linked_line_id.id == line_id]
# Remove zero of negative lines
if quantity <= 0:
sol.unlink(cr, SUPERUSER_ID, [line_id] + option_ids, context=context)
sol.unlink(cr, SUPERUSER_ID, [line_id], context=context)
else:
# update line
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, line_id, context=context)
values['product_uom_qty'] = quantity
sol.write(cr, SUPERUSER_ID, [line_id], values, context=context)
# change quantity of linked product
if option_ids:
sol.write(cr, SUPERUSER_ID, option_ids, {'product_uom_qty': quantity}, context=context)
return (line_id, quantity, option_ids)
return (line_id, quantity)
def _cart_accessories(self, cr, uid, ids, context=None):
for order in self.browse(cr, uid, ids, context=context):
@ -143,28 +126,6 @@ class sale_order(osv.Model):
product_ids = random.sample(s, min(len(s),3))
return self.pool['product.product'].browse(cr, uid, product_ids, context=context)
def _cart_optional_products(self, cr, uid, ids, context=None):
for order in self.browse(cr, uid, ids, context=context):
products = {}
for l in order.website_order_line:
opt = {}
for o in l.product_id.optional_product_ids:
if not opt.get(o.product_tmpl_id.id):
opt[o.product_tmpl_id.id] = {
'product_tmpl_id': o.product_tmpl_id,
'product_ids': []
}
if o not in opt[o.product_tmpl_id.id]:
opt[o.product_tmpl_id.id]['product_ids'].append(o)
if opt:
products[l.id] = {
'order_line_id': l,
'optional_product_tmpl': opt
}
return products
class website(orm.Model):
_inherit = 'website'

View File

@ -393,13 +393,10 @@
<t t-call="website_sale.product_price"/>
<p t-if="len(product.product_variant_ids) > 1" class="css_not_available_msg bg-danger" style="padding: 15px;">Product not available</p>
<t t-placeholder="button">
<a t-if="not optional_product_ids" class="btn btn-primary btn-lg mt8 a-submit js_check_product">Add to Cart</a>
<a t-if="optional_product_ids" class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
</t>
<a class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
</div>
<div t-if="optional_product_ids" id="modal_optional_products" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div id="modal_optional_products" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
@ -407,7 +404,6 @@
<h4 class="modal-title" id="myModalLabel">Product to add in your shopping cart</h4>
</div>
<div class="modal-body">
<table class="table table-striped table-condensed">
<thead>
<tr>
@ -426,7 +422,7 @@
<strong t-field="product.name"/>
<div class="text-muted">
<div t-field="product.description_sale"/>
<div class="js_attributes"></div>
<div class="js_attributes"/>
</div>
</td>
<td>
@ -461,51 +457,6 @@
</div>
</td>
</tr>
<tr t-if="optional_product_ids"><td colspan="4"><h4>Select Your Options:</h4></td></tr>
<t t-set="option_inc" t-value="0"/>
<tr class="js_product" t-foreach="optional_product_ids" t-as="product">
<td width="100">
<input type="hidden" class="optional_product_id" t-attf-name="optional-product-#{option_inc}" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
<span t-field="product.image_small" t-field-options='{"widget": "image"}'/>
</td>
<td>
<div class="pull-left">
<strong class="media-heading" t-field="product.name"/>
<div class="text-muted" t-field="product.description_sale"/>
</div>
</td>
<td>
<div class="pull-right">
<t t-call="website_sale.variants"/>
</div>
</td>
<td>
<t t-if="(website.compute_curency(product.lst_price) - product.price) &gt; 0.1">
<span class="text-danger" style="text-decoration: line-through; white-space: nowrap;"
t-field="product.lst_price"
t-field-options='{
"widget": "monetary",
"from_currency": "website.company_currency_id",
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
}'/><br/>
</t>
<span class="oe_price" style="white-space: nowrap;"
t-field="product.price"
t-field-options='{
"widget": "monetary",
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
}'/>
<p class="css_not_available_msg bg-danger" style="position:absolute; padding: 15px;">Product not available</p>
</td>
<td>
<input type="hidden" class="js_optional_same_quantity" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
<a href="#" class="js_add"><strong>Add to Cart</strong></a>
<span class="js_remove hidden">
<span class="js_item">1 Item</span><span class="js_items hidden">5 Items</span><br/>
<a href="#" class="js_remove"><small>Remove from cart</small></a>
</span>
</td>
</tr>
</tbody>
</table>
</div>
@ -536,19 +487,8 @@
</t>
</template>
<template id="product_confirmation" inherit_id="website_sale.product" optional="disabled" name="Confirm: Add To Cart">
<xpath expr="//div[@id='modal_optional_products']" position="attributes">
<attribute name="t-if">True</attribute>
</xpath>
<xpath expr="//t[@t-placeholder='button']" position="replace">
<t t-placeholder="button">
<a class="btn btn-primary btn-lg mt8 js_check_product" href="#" data-toggle="modal" data-target="#modal_optional_products">Add to Cart</a>
</t>
</xpath>
</template>
<template id="product_quantity" inherit_id="website_sale.product" optional="enabled" name="Select Quantity">
<xpath expr="//t[@t-placeholder='button']" position="before">
<xpath expr="//a[@data-target='#modal_optional_products']" position="before">
<div class="css_quantity input-group" style="width: 108px;">
<span class="input-group-addon">
<a t-attf-href="#" class="mb8 js_add_cart_json">

View File

@ -26,7 +26,6 @@
<field name="website_published" class="pull-right" widget="website_button"/>
<field name="alternative_product_ids" widget="many2many_tags"/>
<field name="accessory_product_ids" widget="many2many_tags"/>
<field name="optional_product_ids" widget="many2many_tags"/>
<field name="website_style_ids" widget="many2many_tags"/>
<field name="website_sequence"/>
</group>

View File

@ -0,0 +1,2 @@
import controllers
import models

View File

@ -0,0 +1,22 @@
{
'name': 'eCommerce Optional Products',
'category': 'Website',
'version': '1.0',
'description': """
OpenERP E-Commerce
==================
""",
'author': 'OpenERP SA',
'depends': ['website_sale'],
'data': [
'views/views.xml',
'views/templates.xml',
],
'demo': [
'data/demo.xml',
],
'qweb': ['static/src/xml/*.xml'],
'installable': True,
'application': True,
}

View File

@ -0,0 +1 @@
import main

View File

@ -0,0 +1,46 @@
# -*- coding: utf-8 -*-
from openerp import SUPERUSER_ID
from openerp.addons.web import http
from openerp.addons.web.http import request
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 website_sale
class website_sale_options(website_sale):
def product(self, product, category='', search='', **kwargs):
r = super(website_sale_options, self)
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
template_obj = pool['product.template']
optional_product_ids = []
for p in product.optional_product_ids:
ctx = dict(context, active_id=p.id)
optional_product_ids.append(template_obj.browse(cr, uid, p.id, context=ctx))
r.qcontext['optional_product_ids'] = optional_product_ids
return r
def cart_update(self, product_id, add_qty=1, set_qty=0, goto_shop=None, **kw):
cr, uid, context, pool = request.cr, request.uid, request.context, request.registry
order = request.website.sale_get_order(force_create=1)
prod_obj = pool['product.product']
optional_product_ids = []
for k, v in kw.items():
if "optional-product-" in k and int(kw.get(k.replace("product", "quantity"))):
optional_product_ids.append(int(v))
if add_qty or set_qty:
line_id, quantity = order._cart_update(product_id=int(product_id),
add_qty=int(add_qty), set_qty=int(set_qty),
optional_product_ids=optional_product_ids)
# options have all time the same quantity
for option_id in optional_product_ids:
order._cart_update(product_id=option_id, set_qty=value.get('quantity'), linked_line_id=value.get('line_id'))
if goto_shop:
return request.redirect("/shop/product/%s" % slug(prod_obj.browse(cr, uid, product_id).product_tmpl_id))
else:
return request.redirect("/shop/cart")

View File

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<!-- add Warranty to ipad -->
<record id="product_attribute_1" model="product.attribute">
<field name="name">Duration</field>
<field name="type">hidden</field>
</record>
<record id="product_attribute_value_1" model="product.attribute.value">
<field name="name">1 year</field>
<field name="attribute_id" ref="product_attribute_1"/>
</record>
<record id="product_attribute_value_2" model="product.attribute.value">
<field name="name">2 year</field>
<field name="attribute_id" ref="product_attribute_1"/>
</record>
<record id="product_product_1" model="product.product">
<field name="name">Warranty</field>
<field name="list_price">20.0</field>
<field name="website_sequence">-1</field>
<field name="website_published" eval="True"/>
<field name="type">service</field>
<field name="uom_id" ref="product.product_uom_unit"/>
<field name="uom_po_id" ref="product.product_uom_unit"/>
<field name="description_sale">Warranty, issued to the purchaser of an article by its manufacturer, promising to repair or replace it if necessary within a specified period of time.</field>
<field name="default_code">W0001</field>
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_1')])]"/>
</record>
<record id="product_product_1b" model="product.product">
<field name="default_code">W0002</field>
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
<field name="attribute_value_ids" eval="[(6,0,[ref('product_attribute_value_2')])]"/>
</record>
<record id="product_attribute_line_1" model="product.attribute.line">
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
<field name="attribute_id" ref="product_attribute_1"/>
<field name="value_ids" eval="[(6,0,[ref('product_attribute_value_1'), ref('product_attribute_value_2')])]"/>
</record>
<record id="product_product_1_product_template" model="product.template">
<field name="attribute_line_ids" eval="[(6,0,[ref('product_attribute_line_1')])]"/>
</record>
<record id="product.product_product_4_product_template" model="product.template">
<field name="optional_product_ids" eval="[(6,0,[ref('product_product_1_product_template')])]"/>
</record>
<record id="product_attribute_price_1" model="product.attribute.price">
<field name="product_tmpl_id" ref="product_product_1_product_template"/>
<field name="value_id" ref="product_attribute_value_2"/>
<field name="price_extra">18.00</field>
</record>
<!-- -->
</data>
</openerp>

View File

@ -0,0 +1 @@
import sale_order

View File

@ -0,0 +1,72 @@
# -*- coding: utf-8 -*-
from openerp import SUPERUSER_ID
from openerp.osv import osv, orm, fields
from openerp.addons.web.http import request
from openerp.tools.translate import _
class sale_order(osv.Model):
_inherit = "sale.order"
def _cart_find_product_line(self, cr, uid, ids, product_id=None, line_id=None, linked_line_id=None, optional_product_ids=None, context=None):
for so in self.browse(cr, uid, ids, context=context):
domain = [('order_id', '=', so.id), ('product_id', '=', product_id)]
if line_id:
domain += [('id', '=', line_id)]
domain += linked_line_id and [('linked_line_id', '=', linked_line_id)] or [('linked_line_id', '=', False)]
if not line_id:
if optional_product_ids:
domain += [('option_line_ids.product_id', '=', pid) for pid in optional_product_ids]
else:
domain += [('option_line_ids', '=', False)]
order_line_id = None
order_line_ids = self.pool.get('sale.order.line').search(cr, SUPERUSER_ID, domain, context=context)
if order_line_ids:
order_line_id = order_line_ids[0]
return order_line_id
def _cart_update(self, cr, uid, ids, product_id=None, line_id=None, add_qty=0, set_qty=0, linked_line_id=None, optional_product_ids=None, context=None):
""" Add or set product quantity, add_qty can be negative """
sol = self.pool.get('sale.order.line')
quantity = 0
for so in self.browse(cr, uid, ids, context=context):
line_id = so._cart_find_product_line(product_id, line_id, linked_line_id, optional_product_ids, context=context)
# Create line if no line with product_id can be located
if not line_id:
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, context=context)
if linked_line_id and linked_line_id in map(int,so.order_line):
values["linked_line_id"] = linked_line_id
linked = sol.browse(cr, SUPERUSER_ID, linked_line_id, context=context)
values["name"] = _("%s\nLinked to: %s") % (values["name"], linked.product_id.name_get()[0][1])
line_id = sol.create(cr, SUPERUSER_ID, values, context=context)
if add_qty:
add_qty -= 1
# compute new quantity
if set_qty:
quantity = set_qty
elif add_qty != None:
quantity = sol.browse(cr, SUPERUSER_ID, line_id, context=context).product_uom_qty + (add_qty or 0)
# select linked product
option_ids = [line.id for line in so.order_line if line.linked_line_id.id == line_id]
# Remove zero of negative lines
if quantity <= 0:
sol.unlink(cr, SUPERUSER_ID, [line_id] + option_ids, context=context)
else:
# update line
values = self._website_product_id_change(cr, uid, ids, so.id, product_id, line_id, context=context)
values['product_uom_qty'] = quantity
sol.write(cr, SUPERUSER_ID, [line_id], values, context=context)
# change quantity of linked product
if option_ids:
sol.write(cr, SUPERUSER_ID, option_ids, {'product_uom_qty': quantity}, context=context)
return (line_id, quantity)

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<template id="optional_products" inherit_id="website_sale.product" name="Optional Products">
<xpath expr="//tr[@id='product_confirmation']" position="after">
<tr t-if="optional_product_ids"><td colspan="4"><h4>Select Your Options:</h4></td></tr>
<t t-set="option_inc" t-value="0"/>
<tr class="js_product" t-foreach="optional_product_ids" t-as="product">
<td width="100">
<input type="hidden" class="optional_product_id" t-attf-name="optional-product-#{option_inc}" t-att-value="int(product.product_variant_ids[0]) if len(product.product_variant_ids) == 1 else '0'"/>
<span t-field="product.image_small" t-field-options='{"widget": "image"}'/>
</td>
<td>
<div class="pull-left">
<strong class="media-heading" t-field="product.name"/>
<div class="text-muted" t-field="product.description_sale"/>
</div>
</td>
<td>
<div class="pull-right">
<t t-call="website_sale.variants"/>
</div>
</td>
<td>
<t t-if="(website.compute_curency(product.lst_price) - product.price) &gt; 0.1">
<span class="text-danger" style="text-decoration: line-through; white-space: nowrap;"
t-field="product.lst_price"
t-field-options='{
"widget": "monetary",
"from_currency": "website.company_currency_id",
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
}'/><br/>
</t>
<span class="oe_price" style="white-space: nowrap;"
t-field="product.price"
t-field-options='{
"widget": "monetary",
"display_currency": "user_id.partner_id.property_product_pricelist.currency_id"
}'/>
<p class="css_not_available_msg bg-danger" style="position:absolute; padding: 15px;">Product not available</p>
</td>
<td>
<input type="hidden" class="js_optional_same_quantity" t-attf-name="optional-quantity-#{option_inc}" value="0"/>
<a href="#" class="js_add"><strong>Add to Cart</strong></a>
<span class="js_remove hidden">
<span class="js_item">1 Item</span><span class="js_items hidden">5 Items</span><br/>
<a href="#" class="js_remove"><small>Remove from cart</small></a>
</span>
</td>
</tr>
</xpath>
</template>
</data>
</openerp>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record model="ir.ui.view" id="product_template_form_view">
<field name="name">product.template.product.website.form</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="website_sale.product_template_form_view"/>
<field name="arch" type="xml">
<field name="accessory_product_ids" position="after">
<field name="optional_product_ids" widget="many2many_tags"/>
</field>
</field>
</record>
</data>
</openerp>