summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Matthieu <chm@openerp.com>2014-01-15 12:05:47 +0100
committerChristophe Matthieu <chm@openerp.com>2014-01-15 12:05:47 +0100
commit320a0bc28ce16646e5dba3ff820aa76f89e9efcc (patch)
tree5b1c5a05e5880d15047199e206748e01454e2cc4
parent8d8c382582f996f2eba85f78e12dfd6ce977adc3 (diff)
[IMP] website/website_sale: Use group to display shipping address in frontend like the backend. Use group for product facet caracteristique (backend/frontend). Customize templates is displayed function of groups of ir.ui.view templates.
bzr revid: chm@openerp.com-20140115110547-v0nllq0f800tlhpg
-rw-r--r--addons/sale/res_config.py3
-rw-r--r--addons/sale/res_config_view.xml7
-rw-r--r--addons/sale_stock/res_config.py3
-rw-r--r--addons/sale_stock/res_config_view.xml6
-rw-r--r--addons/website/controllers/main.py5
-rw-r--r--addons/website_sale/controllers/main.py24
-rw-r--r--addons/website_sale/data/website_sale_data.xml5
-rw-r--r--addons/website_sale/models/__init__.py3
-rw-r--r--addons/website_sale/models/product_attributes.py87
-rw-r--r--addons/website_sale/models/product_characteristics.py87
-rw-r--r--addons/website_sale/models/res_config.py11
-rw-r--r--addons/website_sale/security/ir.model.access.csv6
-rw-r--r--addons/website_sale/views/website_sale.xml280
-rw-r--r--addons/website_sale/views/website_sale_backend.xml31
14 files changed, 295 insertions, 263 deletions
diff --git a/addons/sale/res_config.py b/addons/sale/res_config.py
index 70ef3371d41..4295f7727e9 100644
--- a/addons/sale/res_config.py
+++ b/addons/sale/res_config.py
@@ -78,6 +78,9 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""),
'module_sale_stock': fields.boolean("Trigger delivery orders automatically from sales orders",
help='Allows you to Make Quotation, Sale Order using different Order policy and Manage Related Stock.\n'
'-This installs the module sale_stock.'),
+ 'group_sale_delivery_address': fields.boolean("Allow a different address for delivery and invoicing ",
+ implied_group='sale.group_delivery_invoice_address',
+ help="Allows you to specify different delivery and invoice addresses on a sales order."),
}
def default_get(self, cr, uid, fields, context=None):
diff --git a/addons/sale/res_config_view.xml b/addons/sale/res_config_view.xml
index 9d5b5d071fc..44d9888212e 100644
--- a/addons/sale/res_config_view.xml
+++ b/addons/sale/res_config_view.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
-
<record id="view_sales_config" model="ir.ui.view">
<field name="name">sale settings</field>
<field name="model">sale.config.settings</field>
@@ -41,6 +40,10 @@
<field name="module_warning" class="oe_inline"/>
<label for="module_warning"/>
</div>
+ <div>
+ <field name="group_sale_delivery_address" class="oe_inline"/>
+ <label for="group_sale_delivery_address"/>
+ </div>
</div>
<group name="Sale" position="before">
<group>
@@ -58,7 +61,7 @@
</group>
</group>
<group name="Sale" position="before">
- <group>
+ <group name="Product Features">
<label for="id" string="Product Features"/>
<div>
<div>
diff --git a/addons/sale_stock/res_config.py b/addons/sale_stock/res_config.py
index 5023d3b8eea..16af83dd5ac 100644
--- a/addons/sale_stock/res_config.py
+++ b/addons/sale_stock/res_config.py
@@ -28,9 +28,6 @@ class sale_configuration(osv.osv_memory):
_inherit = 'sale.config.settings'
_columns = {
- 'group_sale_delivery_address': fields.boolean("Allow a different address for delivery and invoicing ",
- implied_group='sale.group_delivery_invoice_address',
- help="Allows you to specify different delivery and invoice addresses on a sales order."),
'group_invoice_deli_orders': fields.boolean('Generate invoices after and based on delivery orders',
implied_group='sale_stock.group_invoice_deli_orders',
help="To allow your salesman to make invoices for Delivery Orders using the menu 'Deliveries to Invoice'."),
diff --git a/addons/sale_stock/res_config_view.xml b/addons/sale_stock/res_config_view.xml
index 93bc8e5980e..b039251d827 100644
--- a/addons/sale_stock/res_config_view.xml
+++ b/addons/sale_stock/res_config_view.xml
@@ -8,12 +8,6 @@
<field name="inherit_id" ref="sale.view_sales_config"/>
<field name="arch" type="xml">
<data>
- <xpath expr="//div[@name='Customer Features']" position="inside">
- <div>
- <field name="group_sale_delivery_address" class="oe_inline"/>
- <label for="group_sale_delivery_address"/>
- </div>
- </xpath>
<xpath expr="//div[@name='group_invoice_so_lines']" position="replace">
<div>
<field name="group_invoice_so_lines" on_change="onchange_invoice_methods(group_invoice_so_lines, group_invoice_deli_orders)" class="oe_inline"/>
diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py
index 01acd1f6ba7..2ebdc2ba163 100644
--- a/addons/website/controllers/main.py
+++ b/addons/website/controllers/main.py
@@ -135,11 +135,16 @@ class Website(openerp.addons.web.controllers.main.Home):
view_model, view_theme_id = imd.get_object_reference(
request.cr, request.uid, 'website', 'theme')
+ user = request.registry['res.users'].browse(request.cr, request.uid, request.uid, request.context)
+ group_ids = [g.id for g in user.groups_id]
+
view = request.registry.get("ir.ui.view")
views = view._views_get(request.cr, request.uid, xml_id, request.context)
done = {}
result = []
for v in views:
+ if v.groups_id and [g for g in v.groups_id if g.id not in group_ids]:
+ continue
if v.inherit_option_id and v.inherit_option_id.id != view_theme_id or not optional:
if v.inherit_option_id.id not in done:
result.append({
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index 7696d01a49d..88f7f69d7a1 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -114,10 +114,10 @@ class Ecommerce(http.Controller):
_order = 'website_published desc, website_sequence desc'
- def get_attribute_ids(self):
- attributes_obj = request.registry['product.attribute']
- attributes_ids = attributes_obj.search(request.cr, request.uid, [], context=request.context)
- return attributes_obj.browse(request.cr, request.uid, attributes_ids, context=request.context)
+ def get_characteristic_ids(self):
+ characteristics_obj = request.registry['product.characteristic']
+ characteristics_ids = characteristics_obj.search(request.cr, request.uid, [], context=request.context)
+ return characteristics_obj.browse(request.cr, request.uid, characteristics_ids, context=request.context)
def get_pricelist(self):
""" Shortcut to get the pricelist from the website model """
@@ -134,13 +134,13 @@ class Ecommerce(http.Controller):
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)]
return product_obj.browse(request.cr, request.uid, product_ids, context=request.context)
- def has_search_filter(self, attribute_id, value_id=None):
+ def has_search_filter(self, characteristic_id, value_id=None):
if request.httprequest.args.get('filters'):
filters = simplejson.loads(request.httprequest.args['filters'])
else:
filters = []
for key_val in filters:
- if key_val[0] == attribute_id and (not value_id or value_id in key_val[1:]):
+ if key_val[0] == characteristic_id and (not value_id or value_id in key_val[1:]):
return key_val
return False
@@ -176,11 +176,11 @@ class Ecommerce(http.Controller):
post.get("category") and ("&category=%s" % post.get("category")) or ""
))
- def attributes_to_ids(self, attributes):
- obj = request.registry.get('product.attribute.product')
+ def characteristics_to_ids(self, characteristics):
+ obj = request.registry.get('product.characteristic.product')
domain = []
- for key_val in attributes:
- domain.append(("attribute_id", "=", key_val[0]))
+ for key_val in characteristics:
+ domain.append(("characteristic_id", "=", key_val[0]))
if isinstance(key_val[1], list):
domain.append(("value", ">=", key_val[1][0]))
domain.append(("value", "<=", key_val[1][1]))
@@ -215,7 +215,7 @@ class Ecommerce(http.Controller):
if filters:
filters = simplejson.loads(filters)
if filters:
- ids = self.attributes_to_ids(filters)
+ ids = self.characteristics_to_ids(filters)
domain.append(('id', 'in', ids or [0]))
product_count = product_obj.search_count(cr, uid, domain, context=context)
@@ -549,7 +549,7 @@ class Ecommerce(http.Controller):
company_ids = orm_parter.search(cr, SUPERUSER_ID, [("name", "ilike", company_name), ('is_company', '=', True)], context=context)
company_id = (company_ids and company_ids[0]) or orm_parter.create(cr, SUPERUSER_ID, {'name': company_name, 'is_company': True}, context)
- billing_info = dict(checkout)
+ billing_info = dict((k, v) for k,v in checkout.items() if "shipping_" not in k and k != "company")
billing_info['parent_id'] = company_id
if request.uid != request.registry['website'].get_public_user(cr, uid, context):
diff --git a/addons/website_sale/data/website_sale_data.xml b/addons/website_sale/data/website_sale_data.xml
index 5d9f8be57ce..4d0fae19f67 100644
--- a/addons/website_sale/data/website_sale_data.xml
+++ b/addons/website_sale/data/website_sale_data.xml
@@ -2,6 +2,11 @@
<openerp>
<data noupdate="1">
+ <record id="product.group_product_characteristics" model="res.groups">
+ <field name="name">Product Characteristic (not supported)</field>
+ <field name="category_id" ref="base.module_category_hidden"/>
+ </record>
+
<record id="menu_shop" model="website.menu">
<field name="name">Shop</field>
<field name="url">/shop</field>
diff --git a/addons/website_sale/models/__init__.py b/addons/website_sale/models/__init__.py
index 07bad24c72e..2dbf56cee88 100644
--- a/addons/website_sale/models/__init__.py
+++ b/addons/website_sale/models/__init__.py
@@ -1,6 +1,7 @@
import website_styles
import payment_transaction
import product
-import product_attributes
+import product_characteristics
+import res_config
import sale_order
import website
diff --git a/addons/website_sale/models/product_attributes.py b/addons/website_sale/models/product_attributes.py
deleted file mode 100644
index 6efa13905fb..00000000000
--- a/addons/website_sale/models/product_attributes.py
+++ /dev/null
@@ -1,87 +0,0 @@
-
-from openerp.osv import osv, fields
-
-
-class attributes(osv.Model):
- _name = "product.attribute"
-
- def _get_float_max(self, cr, uid, ids, field_name, arg, context=None):
- result = dict.fromkeys(ids, 0)
- if ids:
- cr.execute("""
- SELECT attribute_id, MAX(value)
- FROM product_attribute_product
- WHERE attribute_id in (%s)
- GROUP BY attribute_id
- """ % ",".join(map(str, ids)))
- result.update(dict(cr.fetchall()))
- return result
-
- def _get_float_min(self, cr, uid, ids, field_name, arg, context=None):
- result = dict.fromkeys(ids, 0)
- if ids:
- cr.execute("""
- SELECT attribute_id, MIN(value)
- FROM product_attribute_product
- WHERE attribute_id in (%s)
- GROUP BY attribute_id
- """ % ",".join(map(str, ids)))
- result.update(dict(cr.fetchall()))
- return result
-
- def _get_min_max(self, cr, uid, ids, context=None):
- result = {}
- for value in self.pool.get('product.attribute.product').browse(cr, uid, ids, context=context):
- if value.type == 'float':
- result[value.attribute_id.id] = True
- return result.keys()
-
- _columns = {
- 'name': fields.char('Name', size=64, translate=True, required=True),
- 'type': fields.selection([('distinct', 'Textual Value'), ('float', 'Numeric Value')], "Type", required=True),
- 'value_ids': fields.one2many('product.attribute.value', 'attribute_id', 'Values'),
- 'attr_product_ids': fields.one2many('product.attribute.product', 'attribute_id', 'Products'),
-
- 'float_max': fields.function(_get_float_max, type='float', string="Max", store={
- 'product.attribute.product': (_get_min_max, ['value','attribute_id'], 20),
- }),
- 'float_min': fields.function(_get_float_min, type='float', string="Min", store={
- 'product.attribute.product': (_get_min_max, ['value','attribute_id'], 20),
- }),
- 'visible': fields.boolean('Display Filter on Website'),
- }
- _defaults = {
- 'type': 'distinct',
- 'visible': True,
- }
-
-class attributes_value(osv.Model):
- _name = "product.attribute.value"
- _columns = {
- 'name': fields.char('Value', size=64, translate=True, required=True),
- 'attribute_id': fields.many2one('product.attribute', 'Attribute', required=True),
- 'atr_product_ids': fields.one2many('product.attribute.product', 'value_id', 'Products'),
- }
-
-class attributes_product(osv.Model):
- _name = "product.attribute.product"
- _order = 'attribute_id, value_id, value'
- _columns = {
- 'value': fields.float('Numeric Value'),
- 'value_id': fields.many2one('product.attribute.value', 'Textual Value'),
- 'attribute_id': fields.many2one('product.attribute', 'Attribute', required=True),
- 'product_tmpl_id': fields.many2one('product.template', 'Product', required=True),
-
- 'type': fields.related('attribute_id', 'type', type='selection',
- selection=[('distinct', 'Distinct'), ('float', 'Float')], string='Type'),
- }
-
- def onchange_attribute_id(self, cr, uid, ids, attribute_id, context=None):
- attribute = self.pool.get('product.attribute').browse(cr, uid, attribute_id, context=context)
- return {'value': {'type': attribute.type, 'value_id': False, 'value': ''}}
-
-class product_template(osv.Model):
- _inherit = "product.template"
- _columns = {
- 'website_attribute_ids': fields.one2many('product.attribute.product', 'product_tmpl_id', 'Product Attributes'),
- }
diff --git a/addons/website_sale/models/product_characteristics.py b/addons/website_sale/models/product_characteristics.py
new file mode 100644
index 00000000000..fff6846da65
--- /dev/null
+++ b/addons/website_sale/models/product_characteristics.py
@@ -0,0 +1,87 @@
+
+from openerp.osv import osv, fields
+
+
+class characteristics(osv.Model):
+ _name = "product.characteristic"
+
+ def _get_float_max(self, cr, uid, ids, field_name, arg, context=None):
+ result = dict.fromkeys(ids, 0)
+ if ids:
+ cr.execute("""
+ SELECT characteristic_id, MAX(value)
+ FROM product_characteristic_product
+ WHERE characteristic_id in (%s)
+ GROUP BY characteristic_id
+ """ % ",".join(map(str, ids)))
+ result.update(dict(cr.fetchall()))
+ return result
+
+ def _get_float_min(self, cr, uid, ids, field_name, arg, context=None):
+ result = dict.fromkeys(ids, 0)
+ if ids:
+ cr.execute("""
+ SELECT characteristic_id, MIN(value)
+ FROM product_characteristic_product
+ WHERE characteristic_id in (%s)
+ GROUP BY characteristic_id
+ """ % ",".join(map(str, ids)))
+ result.update(dict(cr.fetchall()))
+ return result
+
+ def _get_min_max(self, cr, uid, ids, context=None):
+ result = {}
+ for value in self.pool.get('product.characteristic.product').browse(cr, uid, ids, context=context):
+ if value.type == 'float':
+ result[value.characteristic_id.id] = True
+ return result.keys()
+
+ _columns = {
+ 'name': fields.char('Name', size=64, translate=True, required=True),
+ 'type': fields.selection([('distinct', 'Textual Value'), ('float', 'Numeric Value')], "Type", required=True),
+ 'value_ids': fields.one2many('product.characteristic.value', 'characteristic_id', 'Values'),
+ 'attr_product_ids': fields.one2many('product.characteristic.product', 'characteristic_id', 'Products'),
+
+ 'float_max': fields.function(_get_float_max, type='float', string="Max", store={
+ 'product.characteristic.product': (_get_min_max, ['value','characteristic_id'], 20),
+ }),
+ 'float_min': fields.function(_get_float_min, type='float', string="Min", store={
+ 'product.characteristic.product': (_get_min_max, ['value','characteristic_id'], 20),
+ }),
+ 'visible': fields.boolean('Display Filter on Website'),
+ }
+ _defaults = {
+ 'type': 'distinct',
+ 'visible': True,
+ }
+
+class characteristics_value(osv.Model):
+ _name = "product.characteristic.value"
+ _columns = {
+ 'name': fields.char('Value', size=64, translate=True, required=True),
+ 'characteristic_id': fields.many2one('product.characteristic', 'Characteristic', required=True),
+ 'atr_product_ids': fields.one2many('product.characteristic.product', 'value_id', 'Products'),
+ }
+
+class characteristics_product(osv.Model):
+ _name = "product.characteristic.product"
+ _order = 'characteristic_id, value_id, value'
+ _columns = {
+ 'value': fields.float('Numeric Value'),
+ 'value_id': fields.many2one('product.characteristic.value', 'Textual Value'),
+ 'characteristic_id': fields.many2one('product.characteristic', 'Characteristic', required=True),
+ 'product_tmpl_id': fields.many2one('product.template', 'Product', required=True),
+
+ 'type': fields.related('characteristic_id', 'type', type='selection',
+ selection=[('distinct', 'Distinct'), ('float', 'Float')], string='Type'),
+ }
+
+ def onchange_characteristic_id(self, cr, uid, ids, characteristic_id, context=None):
+ characteristic = self.pool.get('product.characteristic').browse(cr, uid, characteristic_id, context=context)
+ return {'value': {'type': characteristic.type, 'value_id': False, 'value': ''}}
+
+class product_template(osv.Model):
+ _inherit = "product.template"
+ _columns = {
+ 'website_characteristic_ids': fields.one2many('product.characteristic.product', 'product_tmpl_id', 'Product Characteristics'),
+ }
diff --git a/addons/website_sale/models/res_config.py b/addons/website_sale/models/res_config.py
new file mode 100644
index 00000000000..0c2663732dd
--- /dev/null
+++ b/addons/website_sale/models/res_config.py
@@ -0,0 +1,11 @@
+
+from openerp.osv import osv, fields
+
+class sale_configuration(osv.osv_memory):
+ _inherit = 'sale.config.settings'
+
+ _columns = {
+ 'group_product_characteristics': fields.boolean("Support multiple characteristics per products ",
+ implied_group='product.group_product_characteristics',
+ help="""Allow to manage several characteristics per product. This characteristics are used for filter and compare your products. As an example, if you sell all in one computers, you may have characteristics like RAM, Processor Speed, Manufacturing, to compare products"""),
+ }
diff --git a/addons/website_sale/security/ir.model.access.csv b/addons/website_sale/security/ir.model.access.csv
index 8b3318af094..0a16d3bd4cf 100644
--- a/addons/website_sale/security/ir.model.access.csv
+++ b/addons/website_sale/security/ir.model.access.csv
@@ -7,8 +7,8 @@ access_product_pricelist_version_public,product.pricelist.version.public,product
access_product_pricelist_public,product.pricelist.public,product.model_product_pricelist,base.group_public,1,0,0,0
access_product_pricelist_item_public,product.pricelist.item.public,product.model_product_pricelist_item,base.group_public,1,0,0,0
access_product_product_price_type_public,product.price.type.public,product.model_product_price_type,base.group_public,1,0,0,0
-access_product_attribute,product.attribute.public,website_sale.model_product_attribute,,1,0,0,0
-access_product_attribute_value,product.attribute.value.public,website_sale.model_product_attribute_value,,1,0,0,0
-access_product_attribute_product,product.attribute.product.public,website_sale.model_product_attribute_product,,1,0,0,0
+access_product_characteristic,product.characteristic.public,website_sale.model_product_characteristic,,1,0,0,0
+access_product_characteristic_value,product.characteristic.value.public,website_sale.model_product_characteristic_value,,1,0,0,0
+access_product_characteristic_product,product.characteristic.product.public,website_sale.model_product_characteristic_product,,1,0,0,0
access_website_product_style,website.product.style.public,website_sale.model_website_product_style,,1,0,0,0
access_product_supplierinfo,product.supplierinfo.public,product.model_product_supplierinfo,base.group_public,1,0,0,0
diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml
index 78c360bc296..99873e57de7 100644
--- a/addons/website_sale/views/website_sale.xml
+++ b/addons/website_sale/views/website_sale.xml
@@ -371,13 +371,13 @@
</xpath>
</template>
-<!-- Product option: attributes -->
-<template id="product_attributes" inherit_option_id="website_sale.product" name="Product Attributes">
+<!-- Product option: characteristics -->
+<template id="product_characteristics" inherit_id="website_sale.product" inherit_option_id="website_sale.product" name="Product Characteristics" groups="product.group_product_characteristics">
<xpath expr="//p[@t-field='product.description_sale']" position="after">
- <hr t-if="product.website_attribute_ids"/>
+ <hr t-if="product.website_characteristic_ids"/>
<p class="text-muted">
<t t-set="attr" t-value="None"/>
- <t t-foreach="product.website_attribute_ids" t-as="attribute"><br t-if="attr and attribute.attribute_id.id != attr"/><t t-if="attribute.attribute_id.id != attr"><span t-field="attribute.attribute_id"/>: </t><t t-if="attribute.attribute_id.id == attr">, </t><t t-if="attribute.attribute_id.type == 'distinct'"><span t-field="attribute.value_id"/></t><t t-if="attribute.attribute_id.type == 'float'"><span t-field="attribute.value"/></t><t t-set="attr" t-value="attribute.attribute_id.id"/></t>
+ <t t-foreach="product.website_characteristic_ids" t-as="characteristic"><br t-if="attr and characteristic.characteristic_id.id != attr"/><t t-if="characteristic.characteristic_id.id != attr"><span t-field="characteristic.characteristic_id"/>: </t><t t-if="characteristic.characteristic_id.id == attr">, </t><t t-if="characteristic.characteristic_id.type == 'distinct'"><span t-field="characteristic.value_id"/></t><t t-if="characteristic.characteristic_id.type == 'float'"><span t-field="characteristic.value"/></t><t t-set="attr" t-value="characteristic.characteristic_id.id"/></t>
</p>
</xpath>
</template>
@@ -595,36 +595,36 @@
</xpath>
</template>
-<template id="products_attributes" inherit_option_id="website_sale.products" name="Product Filters and Attributes">
+<template id="products_characteristics" inherit_id="website_sale.products" inherit_option_id="website_sale.products" name="Product Characteristic's Filters" groups="product.group_product_characteristics">
<xpath expr="//div[@id='products_grid_before']" position="inside">
<form t-action="/shop/filters/" method="post" t-keep-query="category,search">
<ul class="nav nav-pills nav-stacked mt16">
- <t t-set="attribute_ids" t-value="Ecommerce.get_attribute_ids()"/>
- <t t-foreach="attribute_ids" t-as="attribute_id">
- <t t-if="attribute_id.visible">
- <li t-if="attribute_id.value_ids and attribute_id.type == 'distinct'">
- <div t-field="attribute_id.name"/>
+ <t t-set="characteristic_ids" t-value="Ecommerce.get_characteristic_ids()"/>
+ <t t-foreach="characteristic_ids" t-as="characteristic_id">
+ <t t-if="characteristic_id.visible">
+ <li t-if="characteristic_id.value_ids and characteristic_id.type == 'distinct'">
+ <div t-field="characteristic_id.name"/>
<ul class="nav nav-pills nav-stacked">
- <t t-foreach="attribute_id.value_ids" t-as="value_id">
- <li t-att-class="Ecommerce.has_search_filter(attribute_id.id, value_id.id) and 'active' or ''">
+ <t t-foreach="characteristic_id.value_ids" t-as="value_id">
+ <li t-att-class="Ecommerce.has_search_filter(characteristic_id.id, value_id.id) and 'active' or ''">
<label style="margin: 0 20px;">
- <input type="checkbox" t-att-name="'att-%s-%s' % (attribute_id.id, value_id.id)"
- t-att-checked="Ecommerce.has_search_filter(attribute_id.id, value_id.id) and 'checked' or ''"/>
+ <input type="checkbox" t-att-name="'att-%s-%s' % (characteristic_id.id, value_id.id)"
+ t-att-checked="Ecommerce.has_search_filter(characteristic_id.id, value_id.id) and 'checked' or ''"/>
<span style="font-weight: normal" t-field="value_id.name"/>
</label>
</li>
</t>
</ul>
</li>
- <li t-if="attribute_id.type == 'float' and attribute_id.float_min != attribute_id.float_max">
- <div t-field="attribute_id.name"/>
- <t t-set="attribute" t-value="Ecommerce.has_search_filter(attribute_id.id)"/>
+ <li t-if="characteristic_id.type == 'float' and characteristic_id.float_min != characteristic_id.float_max">
+ <div t-field="characteristic_id.name"/>
+ <t t-set="characteristic" t-value="Ecommerce.has_search_filter(characteristic_id.id)"/>
<div style="margin: 0 20px;" class="js_slider"
- t-att-data-id="attribute_id.id"
- t-att-data-value-min="attribute and attribute[1][0] or attribute_id.float_min"
- t-att-data-value-max="attribute and attribute[1][1] or attribute_id.float_max"
- t-att-data-min="attribute_id.float_min"
- t-att-data-max="attribute_id.float_max"></div>
+ t-att-data-id="characteristic_id.id"
+ t-att-data-value-min="characteristic and characteristic[1][0] or characteristic_id.float_min"
+ t-att-data-value-max="characteristic and characteristic[1][1] or characteristic_id.float_max"
+ t-att-data-min="characteristic_id.float_min"
+ t-att-data-max="characteristic_id.float_max"></div>
</li>
</t>
</t>
@@ -733,112 +733,110 @@
<a t-if="not partner" t-attf-href="/web#action=redirect&amp;url=#{ request.httprequest.url }">sign in</a>
</small>
</h3>
- <div class="row">
- <div t-attf-class="form-group #{error.get('name') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Your Name</label>
- <input type="text" name="name" class="form-control" t-att-value="checkout.get('name')"/>
- </div>
- <div t-attf-class="form-group #{error.get('company') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="company" style="font-weight: normal">Your Company</label>
- <input type="text" name="company" class="form-control" t-att-value="checkout.get('company')"/>
- </div>
- <div t-attf-class="form-group #{error.get('email') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Email</label>
- <input type="email" name="email" class="form-control" t-att-value="checkout.get('email')"/>
- </div>
- <div t-attf-class="form-group #{ error.get('phone') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="phone">Phone</label>
- <input type="tel" name="phone" class="form-control" t-att-value="checkout.get('phone')"/>
- </div>
+ <div class="row">
+ <div t-attf-class="form-group #{error.get('name') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Your Name</label>
+ <input type="text" name="name" class="form-control" t-att-value="checkout.get('name')"/>
+ </div>
+ <div t-attf-class="form-group #{error.get('company') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="company" style="font-weight: normal">Your Company</label>
+ <input type="text" name="company" class="form-control" t-att-value="checkout.get('company')"/>
+ </div>
+ <div t-attf-class="form-group #{error.get('email') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Email</label>
+ <input type="email" name="email" class="form-control" t-att-value="checkout.get('email')"/>
+ </div>
+ <div t-attf-class="form-group #{ error.get('phone') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="phone">Phone</label>
+ <input type="tel" name="phone" class="form-control" t-att-value="checkout.get('phone')"/>
+ </div>
- <div t-attf-class="form-group #{error.get('street') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="street">Street</label>
- <input type="text" name="street" class="form-control" t-att-value="checkout.get('street')"/>
- </div>
- <div class="clearfix"/>
+ <div t-attf-class="form-group #{error.get('street') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="street">Street</label>
+ <input type="text" name="street" class="form-control" t-att-value="checkout.get('street')"/>
+ </div>
+ <div class="clearfix"/>
- <div t-attf-class="form-group #{error.get('city') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="city">City</label>
- <input type="text" name="city" class="form-control" t-att-value="checkout.get('city')"/>
- </div>
- <div t-attf-class="form-group #{error.get('zip') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="zip">Zip / Postal Code</label>
- <input type="text" name="zip" class="form-control" t-att-value="checkout.get('zip')"/>
- </div>
- <div t-attf-class="form-group #{error.get('state_id') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="state_id" style="font-weight: normal">State / Province</label>
- <select name="state_id" class="form-control">
- <option value="">select...</option>
- <t t-foreach="states or []" t-as="state">
- <option t-att-value="state.id" t-att-selected="state.id == checkout.get('state_id')"><t t-esc="state.name"/></option>
- </t>
- </select>
- </div>
- <div t-attf-class="form-group #{error.get('country_id') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Country</label>
- <select name="country_id" class="form-control">
- <option value="">Country...</option>
- <t t-foreach="countries or []" t-as="country">
- <option t-att-value="country.id" t-att-selected="country.id == checkout.get('country_id')"><t t-esc="country.name"/></option>
- </t>
- </select>
- </div>
+ <div t-attf-class="form-group #{error.get('city') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="city">City</label>
+ <input type="text" name="city" class="form-control" t-att-value="checkout.get('city')"/>
+ </div>
+ <div t-attf-class="form-group #{error.get('zip') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="zip">Zip / Postal Code</label>
+ <input type="text" name="zip" class="form-control" t-att-value="checkout.get('zip')"/>
+ </div>
+ <div t-attf-class="form-group #{error.get('state_id') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="state_id" style="font-weight: normal">State / Province</label>
+ <select name="state_id" class="form-control">
+ <option value="">select...</option>
+ <t t-foreach="states or []" t-as="state">
+ <option t-att-value="state.id" t-att-selected="state.id == checkout.get('state_id')"><t t-esc="state.name"/></option>
+ </t>
+ </select>
+ </div>
+ <div t-attf-class="form-group #{error.get('country_id') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Country</label>
+ <select name="country_id" class="form-control">
+ <option value="">Country...</option>
+ <t t-foreach="countries or []" t-as="country">
+ <option t-att-value="country.id" t-att-selected="country.id == checkout.get('country_id')"><t t-esc="country.name"/></option>
+ </t>
+ </select>
+ </div>
- <div class="clearfix"/>
+ <div class="clearfix"/>
- <div class="form-group col-lg-6">
- <label>
- <input t-if="not shipping" type="checkbox" name="shipping_different"/>
- <input t-if="shipping" type="checkbox" name="shipping_different" checked="1"/>
- Ship to a different address
- </label>
- </div>
+ <div class="form-group col-lg-6" groups="sale.group_delivery_invoice_address">
+ <label>
+ <input type="checkbox" name="shipping_different" t-att-checked="shipping"/>
+ Ship to a different address
+ </label>
</div>
+ </div>
+ <div class="js_shipping row mb16" t-att-style="not shipping and 'display:none' or ''" groups="sale.group_delivery_invoice_address">
+ <h3 class="oe_shipping col-lg-12 mt16">Shipping Information</h3>
- <div class="js_shipping row mb16" t-att-style="not shipping and 'display:none' or ''">
- <h3 class="oe_shipping col-lg-12 mt16">Shipping Information</h3>
-
- <div t-attf-class="form-group #{error.get('shipping_name') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Name (Shipping)</label>
- <input type="text" name="shipping_name" class="form-control" t-att-value="checkout.get('shipping_name', '')"/>
- </div>
- <div t-attf-class="form-group #{error.get('shipping_phone') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Phone</label>
- <input type="tel" name="shipping_phone" class="form-control" t-att-value="checkout.get('shipping_phone', '')"/>
- </div>
- <div t-attf-class="form-group #{error.get('shipping_street') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Street</label>
- <input type="text" name="shipping_street" class="form-control" t-att-value="checkout.get('shipping_street', '')"/>
- </div>
- <div class="clearfix"/>
- <div t-attf-class="form-group #{error.get('shipping_city') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">City</label>
- <input type="text" name="shipping_city" class="form-control" t-att-value="checkout.get('shipping_city', '')"/>
- </div>
- <div t-attf-class="form-group #{error.get('shipping_zip') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Zip / Postal Code</label>
- <input type="text" name="shipping_zip" class="form-control" t-att-value="checkout.get('shipping_zip', '')"/>
- </div>
- <div t-attf-class="form-group #{error.get('shipping_state_id') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name" style="font-weight: normal">State / Province</label>
- <select name="shipping_state_id" class="form-control">
- <option value="">State / Province...</option>
- <t t-foreach="states or []" t-as="state">
- <option t-att-value="state.id" t-att-selected="state.id == checkout.get('shipping_state_id')"><t t-esc="state.name"/></option>
- </t>
- </select>
- </div>
- <div t-attf-class="form-group #{error.get('shipping_country_id') and 'has-error' or ''} col-lg-6">
- <label class="control-label" for="contact_name">Country</label>
- <select name="shipping_country_id" class="form-control">
- <option value="">Country...</option>
- <t t-foreach="countries or []" t-as="country">
- <option t-att-value="country.id" t-att-selected="country.id == checkout.get('shipping_country_id')"><t t-esc="country.name"/></option>
- </t>
- </select>
- </div>
+ <div t-attf-class="form-group #{error.get('shipping_name') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Name (Shipping)</label>
+ <input type="text" name="shipping_name" class="form-control" t-att-value="checkout.get('shipping_name', '')"/>
+ </div>
+ <div t-attf-class="form-group #{error.get('shipping_phone') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Phone</label>
+ <input type="tel" name="shipping_phone" class="form-control" t-att-value="checkout.get('shipping_phone', '')"/>
</div>
- <button type="submit" class="btn btn-default btn-primary pull-right mb32">Confirm <span class="fa fa-long-arrow-right"/></button>
+ <div t-attf-class="form-group #{error.get('shipping_street') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Street</label>
+ <input type="text" name="shipping_street" class="form-control" t-att-value="checkout.get('shipping_street', '')"/>
+ </div>
+ <div class="clearfix"/>
+ <div t-attf-class="form-group #{error.get('shipping_city') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">City</label>
+ <input type="text" name="shipping_city" class="form-control" t-att-value="checkout.get('shipping_city', '')"/>
+ </div>
+ <div t-attf-class="form-group #{error.get('shipping_zip') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Zip / Postal Code</label>
+ <input type="text" name="shipping_zip" class="form-control" t-att-value="checkout.get('shipping_zip', '')"/>
+ </div>
+ <div t-attf-class="form-group #{error.get('shipping_state_id') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name" style="font-weight: normal">State / Province</label>
+ <select name="shipping_state_id" class="form-control">
+ <option value="">State / Province...</option>
+ <t t-foreach="states or []" t-as="state">
+ <option t-att-value="state.id" t-att-selected="state.id == checkout.get('shipping_state_id')"><t t-esc="state.name"/></option>
+ </t>
+ </select>
+ </div>
+ <div t-attf-class="form-group #{error.get('shipping_country_id') and 'has-error' or ''} col-lg-6">
+ <label class="control-label" for="contact_name">Country</label>
+ <select name="shipping_country_id" class="form-control">
+ <option value="">Country...</option>
+ <t t-foreach="countries or []" t-as="country">
+ <option t-att-value="country.id" t-att-selected="country.id == checkout.get('shipping_country_id')"><t t-esc="country.name"/></option>
+ </t>
+ </select>
+ </div>
+ </div>
+ <button type="submit" class="btn btn-default btn-primary pull-right mb32">Confirm <span class="fa fa-long-arrow-right"/></button>
</div>
<div class="col-lg-offset-1 col-lg-3 text-muted">
<h3 class="page-header mt16">Your Order <small><a href="/shop/mycart"><span class="fa fa-arrow-right"/> change</a></small></h3>
@@ -962,19 +960,19 @@
<div>
<a href="/shop/checkout"><span class="fa fa-arrow-right"/> Change Address</a>
</div>
-
- <h4 class="mt32">Ship To:</h4>
- <t t-if="website_sale_order.partner_shipping_id and website_sale_order.partner_shipping_id.id != website_sale_order.partner_invoice_id.id">
- <div t-field="order.partner_shipping_id" t-field-options='{
- "widget": "contact",
- "fields": ["address", "name", "phone"]
- }'/>
+ <t groups="sale.group_delivery_invoice_address">
+ <h4 class="mt32">Ship To:</h4>
+ <t t-if="website_sale_order.partner_shipping_id and website_sale_order.partner_shipping_id.id != website_sale_order.partner_invoice_id.id">
+ <div t-field="order.partner_shipping_id" t-field-options='{
+ "widget": "contact",
+ "fields": ["address", "name", "phone"]
+ }'/>
+ </t>
+ <address t-if="website_sale_order.partner_shipping_id.id == website_sale_order.partner_invoice_id.id">Ship to the same address</address>
+ <div class="mb32">
+ <a href="/shop/checkout"><span class="fa fa-arrow-right"/> Change Address</a>
+ </div>
</t>
- <address t-if="website_sale_order.partner_shipping_id.id == website_sale_order.partner_invoice_id.id">Ship to the same address</address>
- <div class="mb32">
- <a href="/shop/checkout"><span class="fa fa-arrow-right"/> Change Address</a>
- </div>
-
</div>
</div>
@@ -1036,14 +1034,16 @@
"widget": "contact",
"fields": ["address", "name", "phone", "email"]
}'/>
- <h4 class="mt32">Ship To:</h4>
- <t t-if="order.partner_shipping_id and order.partner_shipping_id.id != order.partner_invoice_id.id">
- <div t-field="order.partner_shipping_id" t-field-options='{
- "widget": "contact",
- "fields": ["address", "name", "phone"]
- }'/>
+ <t groups="sale.group_delivery_invoice_address">
+ <h4 class="mt32">Ship To:</h4>
+ <t t-if="order.partner_shipping_id and order.partner_shipping_id.id != order.partner_invoice_id.id">
+ <div t-field="order.partner_shipping_id" t-field-options='{
+ "widget": "contact",
+ "fields": ["address", "name", "phone"]
+ }'/>
+ </t>
+ <address t-if="order.partner_shipping_id.id == order.partner_invoice_id.id">Ship to the same address</address>
</t>
- <address t-if="order.partner_shipping_id.id == order.partner_invoice_id.id">Ship to the same address</address>
</div>
</div>
diff --git a/addons/website_sale/views/website_sale_backend.xml b/addons/website_sale/views/website_sale_backend.xml
index e12c5d40a10..a2e18f552c1 100644
--- a/addons/website_sale/views/website_sale_backend.xml
+++ b/addons/website_sale/views/website_sale_backend.xml
@@ -2,6 +2,19 @@
<openerp>
<data>
+ <record id="view_sales_config_website_sale" model="ir.ui.view">
+ <field name="name">sale settings</field>
+ <field name="model">sale.config.settings</field>
+ <field name="inherit_id" ref="sale.view_sales_config"/>
+ <field name="arch" type="xml">
+ <xpath expr="//group[@name='Product Features']/div" position="inside">
+ <div>
+ <field name="group_product_characteristics" class="oe_inline"/>
+ <label for="group_product_characteristics"/>
+ </div>
+ </xpath>
+ </field>
+ </record>
<record id="product_normal_form_view" model="ir.ui.view">
<field name="name">product.normal.form.inherit</field>
@@ -48,15 +61,15 @@
<group colspan="4" string="Website Options">
<field name="suggested_product_ids" widget="many2many_tags"/>
<field name="website_style_ids" widget="many2many_tags"/>
- <field colspan="4" name="website_attribute_ids" nolabel="1">
- <tree string="Product Attributes" editable="bottom">
- <field name="attribute_id" on_change="onchange_attribute_id(attribute_id)"/>
+ <field colspan="4" name="website_characteristic_ids" nolabel="1" groups="product.group_product_characteristics">
+ <tree string="Product Characteristics" editable="bottom">
+ <field name="characteristic_id" on_change="onchange_characteristic_id(characteristic_id)"/>
<field name="type" invisible="1"/>
<field name="value" attrs="{'required': [('type','=','float')]}"/>
<field name="value_id"
attrs="{'required': [('type','=','distinct')]}"
- context="{'default_attribute_id': attribute_id}"
- domain="[('attribute_id', '=', attribute_id)]"/>
+ context="{'default_characteristic_id': characteristic_id}"
+ domain="[('characteristic_id', '=', characteristic_id)]"/>
</tree>
</field>
</group>
@@ -65,11 +78,11 @@
</field>
</record>
- <record model="ir.ui.view" id="view_product_attribute_form">
- <field name="name">product.attribute.form</field>
- <field name="model">product.attribute</field>
+ <record model="ir.ui.view" id="view_product_characteristic_form">
+ <field name="name">product.characteristic.form</field>
+ <field name="model">product.characteristic</field>
<field name="arch" type="xml">
- <form string="Product Attributes" version="7.0">
+ <form string="Product Characteristics" version="7.0">
<group>
<field name="name"/>
<field name="type"/>