summaryrefslogtreecommitdiff
path: root/addons/product
diff options
context:
space:
mode:
authorThibault Delavallée <tde@openerp.com>2014-01-21 10:38:32 +0100
committerThibault Delavallée <tde@openerp.com>2014-01-21 10:38:32 +0100
commit28eaa636f0bfbf497e616edcfbc64d8a720e788d (patch)
tree7898a40b6f11d96f64f973347619b2442f6e62f2 /addons/product
parent3b1fec32208879a4655a37180e2ea4296728e6ed (diff)
parent9ce241349f3f35b6c75a2aaf9cf7c1ce0006cd7e (diff)
[MERGE] Merged DKA's branch about product variants in the CMS. Review is coming.
bzr revid: tde@openerp.com-20140121093832-yp3jl36nsuho74vk
Diffstat (limited to 'addons/product')
-rw-r--r--addons/product/product.py81
-rw-r--r--addons/product/product_view.xml222
-rw-r--r--addons/product/security/product_security.xml2
3 files changed, 208 insertions, 97 deletions
diff --git a/addons/product/product.py b/addons/product/product.py
index 163785459b4..2e7eb3c499d 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -23,8 +23,10 @@ import math
import re
from _common import rounding
-from openerp import SUPERUSER_ID
+from lxml import etree
+from openerp.osv.orm import setup_modifiers
+from openerp import SUPERUSER_ID
from openerp import tools
from openerp.osv import osv, fields
from openerp.tools.translate import _
@@ -391,7 +393,7 @@ class product_template(osv.osv):
'categ_id': fields.many2one('product.category','Category', required=True, change_default=True, domain="[('type','=','normal')]" ,help="Select category for the current product"),
'public_categ_id': fields.many2one('product.public.category','Public Category', help="Those categories are used to group similar products for public sales (eg.: point of sale, e-commerce)."),
'list_price': fields.float('Sale Price', digits_compute=dp.get_precision('Product Price'), help="Base price to compute the customer price. Sometimes called the catalog price."),
- 'standard_price': fields.float('Cost', digits_compute=dp.get_precision('Product Price'), help="Cost price of the product used for standard stock valuation in accounting and used as a base price on purchase orders.", groups="base.group_user"),
+ 'standard_price': fields.float('Cost Price', digits_compute=dp.get_precision('Product Price'), help="Cost price of the product template used for standard stock valuation in accounting and used as a base price on purchase orders.", groups="base.group_user"),
'volume': fields.float('Volume', help="The volume in m3."),
'weight': fields.float('Gross Weight', digits_compute=dp.get_precision('Stock Weight'), help="The gross weight in Kg."),
'weight_net': fields.float('Net Weight', digits_compute=dp.get_precision('Stock Weight'), help="The net weight in Kg."),
@@ -468,6 +470,15 @@ class product_template(osv.osv):
raise osv.except_osv(_('Unit of Measure categories Mismatch!'), _("New Unit of Measure '%s' must belong to same Unit of Measure category '%s' as of old Unit of Measure '%s'. If you need to change the unit of measure, you may deactivate this product from the 'Procurements' tab and create a new one.") % (new_uom.name, old_uom.category_id.name, old_uom.name,))
return super(product_template, self).write(cr, uid, ids, vals, context=context)
+ def copy(self, cr, uid, id, default=None, context=None):
+ if default is None:
+ default = {}
+ #TOFIX: it should be pass default={'name': _("%s (copy)") % (template['name'])}.
+ template = self.read(cr, uid, id, ['name'], context=context)
+ res = super(product_template, self).copy(cr, uid, id, default=default, context=context)
+ self.write(cr, uid, res, {'name': _("%s (copy)") % (template['name'])}, context=context)
+ return res
+
_defaults = {
'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'product.template', context=c),
'list_price': 1,
@@ -574,6 +585,7 @@ class product_product(osv.osv):
list_price = (field_value - product.price_extra) / (product.price_margin or 1.0)
return self.write(cr, uid, [product_id], {'list_price': list_price}, context=context)
+
def _get_partner_code_name(self, cr, uid, ids, product, partner_id, context=None):
for supinfo in product.seller_ids:
if supinfo.name.id == partner_id:
@@ -664,12 +676,12 @@ class product_product(osv.osv):
'partner_ref' : fields.function(_product_partner_ref, type='char', string='Customer ref'),
'default_code' : fields.char('Internal Reference', size=64, select=True),
'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the product without removing it."),
- 'variants': fields.char('Variants', size=64),
+ 'variants': fields.char('Variants', size=64, translate=True),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete="cascade", select=True),
'ean13': fields.char('EAN13 Barcode', size=13, help="International Article Number used for product identification."),
'packaging' : fields.one2many('product.packaging', 'product_id', 'Logistical Units', help="Gives the different ways to package the same product. This has no impact on the picking order and is mainly used if you use the EDI module."),
- 'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Product Price')),
- 'price_margin': fields.float('Variant Price Margin', digits_compute=dp.get_precision('Product Price')),
+ 'price_extra': fields.float('Variant Price Extra', digits_compute=dp.get_precision('Product Price'), help="Price Extra: Extra price for the variant on sale price. eg. 200 price extra, 1000 + 200 = 1200."),
+ 'price_margin': fields.float('Variant Price Margin', digits_compute=dp.get_precision('Product Price'), help="Price Margin: Margin in percentage amount on sale price for the variant. eg. 10 price margin, 1000 * 1.1 = 1100."),
'pricelist_id': fields.dummy(string='Pricelist', relation='product.pricelist', type='many2one'),
'name_template': fields.related('product_tmpl_id', 'name', string="Template Name", type='char', size=128, store={
'product.template': (_get_name_template_ids, ['name'], 10),
@@ -682,20 +694,28 @@ class product_product(osv.osv):
'seller_qty': fields.function(_calc_seller, type='float', string='Supplier Quantity', multi="seller_info", help="This is minimum quantity to purchase from Main Supplier."),
'seller_id': fields.function(_calc_seller, type='many2one', relation="res.partner", string='Main Supplier', help="Main Supplier who has highest priority in Supplier List.", multi="seller_info"),
}
- def unlink(self, cr, uid, ids, context=None):
- unlink_ids = []
- unlink_product_tmpl_ids = []
- for product in self.browse(cr, uid, ids, context=context):
- tmpl_id = product.product_tmpl_id.id
- # Check if the product is last product of this template
- other_product_ids = self.search(cr, uid, [('product_tmpl_id', '=', tmpl_id), ('id', '!=', product.id)], context=context)
- if not other_product_ids:
- unlink_product_tmpl_ids.append(tmpl_id)
- unlink_ids.append(product.id)
- res = super(product_product, self).unlink(cr, uid, unlink_ids, context=context)
- # delete templates after calling super, as deleting template could lead to deleting
- # products due to ondelete='cascade'
- self.pool.get('product.template').unlink(cr, uid, unlink_product_tmpl_ids, context=context)
+
+
+ def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
+ #override of fields_view_get in order to replace the name field to product template
+ if context is None:
+ context = {}
+ res = super(product_product, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu)
+ #check the current user in group_product_variant
+ if view_type == 'form':
+ doc = etree.XML(res['arch'])
+ if self.pool['res.users'].has_group(cr, uid, 'product.group_product_variant'):
+ for node in doc.xpath("//field[@name='name']"):
+ node.set('invisible', '1')
+ node.set('required', '0')
+ setup_modifiers(node, res['fields']['name'])
+ for node in doc.xpath("//label[@name='label_name']"):
+ node.set('string','Product Template')
+ else:
+ for node in doc.xpath("//field[@name='product_tmpl_id']"):
+ node.set('required', '0')
+ setup_modifiers(node, res['fields']['name'])
+ res['arch'] = etree.tostring(doc)
return res
def onchange_uom(self, cursor, user, ids, uom_id, uom_po_id):
@@ -707,6 +727,16 @@ class product_product(osv.osv):
return {'value': {'uom_po_id': uom_id}}
return False
+ def onchange_product_tmpl_id(self, cr, uid, ids, template_id, context=None):
+ res = {}
+ if template_id:
+ template = self.pool.get('product.template').browse(cr, uid, template_id, context=context)
+ res['value'] = {
+ 'name': template.name,
+ 'lst_price': template.list_price,
+ }
+ return res
+
def _check_ean_key(self, cr, uid, ids, context=None):
for product in self.read(cr, uid, ids, ['ean13'], context=context):
res = check_ean(product['ean13'])
@@ -776,7 +806,7 @@ class product_product(osv.osv):
# OR operator (and given the fact that the 'name' lookup results come from the ir.translation table
# Performing a quick memory merge of ids in Python will give much better performance
ids = set()
- ids.update(self.search(cr, user, args + [('default_code',operator,name)], limit=limit, context=context))
+ ids.update(self.search(cr, user, args + ['|',('default_code',operator,name),('variants',operator,name)], limit=limit, context=context))
if not limit or len(ids) < limit:
# we may underrun the limit because of dupes in the results, that's fine
ids.update(self.search(cr, user, args + [('name',operator,name)], limit=(limit and (limit-len(ids)) or False) , context=context))
@@ -838,9 +868,12 @@ class product_product(osv.osv):
# will do the other languages).
context_wo_lang = context.copy()
context_wo_lang.pop('lang', None)
- product = self.read(cr, uid, id, ['name'], context=context_wo_lang)
+ product = self.read(cr, uid, id, ['name', 'list_price', 'standard_price', 'categ_id', 'variants', 'product_tmpl_id'], context=context_wo_lang)
default = default.copy()
- default.update(name=_("%s (copy)") % (product['name']))
+ if product['variants']:
+ default.update(variants=_("%s (copy)") % (product['variants']), product_tmpl_id=product['product_tmpl_id'][0])
+ else:
+ default.update(name=_("%s (copy)") % (product['name']), list_price=product['list_price'], standard_price=product['standard_price'], categ_id=product['categ_id'][0], product_tmpl_id=None)
if context.get('variant',False):
fields = ['product_tmpl_id', 'active', 'variants', 'default_code',
@@ -858,7 +891,9 @@ class product_product(osv.osv):
context=context)
def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
- if context and context.get('search_default_categ_id'):
+ if context is None:
+ context = {}
+ if context.get('search_default_categ_id'):
args.append((('categ_id', 'child_of', context['search_default_categ_id'])))
return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
diff --git a/addons/product/product_view.xml b/addons/product/product_view.xml
index 1ea85cc96d4..4c315dfe221 100644
--- a/addons/product/product_view.xml
+++ b/addons/product/product_view.xml
@@ -8,7 +8,7 @@
<field name="model">product.product</field>
<field name="arch" type="xml">
<search string="Product">
- <field name="name" string="Product" filter_domain="['|',('name','ilike',self),('default_code','ilike',self)]"/>
+ <field name="name" string="Product" filter_domain="['|','|',('name','ilike',self),('default_code','ilike',self),('variants','ilike',self)]"/>
<filter string="Services" icon="terp-accessories-archiver" domain="[('type','=','service')]"/>
<filter string="Consumable" name="consumable" icon="terp-accessories-archiver" domain="[('type','=','consu')]" help="Consumable products"/>
<separator/>
@@ -23,6 +23,7 @@
<filter string='Default Unit of Measure' icon="terp-mrp" domain="[]" context="{'group_by' : 'uom_id'}"/>
<filter string='Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}"/>
<filter string='Company' icon="terp-go-home" domain="[]" context="{'group_by' : 'company_id'}" groups="base.group_multi_company"/>
+ <filter string='Template' name="template_id" domain="[]" context="{'group_by' : 'product_tmpl_id'}" groups="product.group_product_variant"/>
</group>
</search>
</field>
@@ -36,6 +37,7 @@
<tree colors="red:virtual_available&lt;0;blue:virtual_available&gt;=0 and state in ('draft', 'end', 'obsolete');black:virtual_available&gt;=0 and state not in ('draft', 'end', 'obsolete')" string="Products">
<field name="default_code"/>
<field name="name"/>
+ <field name="variants" groups="product.group_product_variant"/>
<field name="categ_id" invisible="1"/>
<field name="type" invisible="1"/>
<field name="uom_id" string="Unit of Measure" groups="product.group_uom"/>
@@ -46,6 +48,7 @@
<field name="standard_price" invisible="1"/>
<field name="state"/>
<field name="company_id" groups="base.group_multi_company" invisible="1"/>
+ <field name="product_tmpl_id" invisible="1"/>
</tree>
</field>
</record>
@@ -60,10 +63,13 @@
<field name="image_medium" widget="image" class="oe_avatar oe_left"/>
<div class="oe_title">
<div class="oe_edit_only">
- <label for="name" string="Product Name"/>
+ <label for="name" name='label_name' string="Product Name"/>
</div>
<h1>
- <field name="name"/>
+ <field name="name" class="oe_inline"/>
+ <field name="product_tmpl_id" groups="product.group_product_variant" on_change="onchange_product_tmpl_id(product_tmpl_id)" class="oe_inline"/>
+ <span attrs="{'invisible':[('variants','=',False)]}" groups="product.group_product_variant"> - </span>
+ <field name="variants" placeholder="Variant Name" groups="product.group_product_variant" class="oe_inline" readonly="0"/>
</h1>
<label for="categ_id" class="oe_edit_only"/>
<h2><field name="categ_id"/></h2>
@@ -82,7 +88,7 @@
<group>
<field name="type"/>
<field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"/>
- <field name="list_price"/>
+ <field name="lst_price" string="Public Sale Price"/>
</group>
<group>
<field name="default_code"/>
@@ -189,7 +195,7 @@
<div class="oe_kanban_details">
<h4>
<a type="open">
- <t t-if="record.code.raw_value">[<field name="code"/>]</t> <field name="name"/>
+ <t t-if="record.code.raw_value">[<field name="code"/>]</t> <field name="name"/> <t t-if="record.variants.raw_value">(<field name="variants"/>)</t>
</a>
</h4>
<div name="tags"/>
@@ -222,7 +228,7 @@
</field>
</record>
<record id="product_normal_action_sell" model="ir.actions.act_window">
- <field name="name">Products</field>
+ <field name="name">All Products</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.product</field>
<field name="view_mode">kanban,tree,form</field>
@@ -364,7 +370,7 @@
action="product_category_action"
id="product.menu_products_category"
parent="base.menu_product"
- sequence="0" groups="base.group_no_one"/>
+ sequence="2" groups="base.group_no_one"/>
<record id="product_category_action_form" model="ir.actions.act_window">
<field name="name">Product Categories</field>
<field name="type">ir.actions.act_window</field>
@@ -578,7 +584,7 @@
</field>
</record>
<menuitem
- action="product_ul_form_action" groups="product.group_stock_packaging" id="menu_product_ul_form_action" parent="prod_config_main" sequence="3"/>
+ action="product_ul_form_action" groups="product.group_stock_packaging" id="menu_product_ul_form_action" parent="prod_config_main" sequence="5"/>
<record id="product_packaging_tree_view" model="ir.ui.view">
<field name="name">product.packaging.tree.view</field>
@@ -668,6 +674,19 @@
</record>
<!-- Variants -->
+ <record id="product_variant_search_form_view" model="ir.ui.view">
+ <field name="name">product.variant.search.form</field>
+ <field name="model">product.product</field>
+ <field name="arch" type="xml">
+ <search string="Product Variant">
+ <field name="product_tmpl_id"/>
+ <field name="name" string="Product" filter_domain="['|','|',('name','ilike',self),('default_code','ilike',self),('variants','ilike',self)]"/>
+ <group expand='0' string='Group by...'>
+ <filter string='Template' name="template_id" domain="[]" context="{'group_by' : 'product_tmpl_id'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
<record id="product_variant_form_view" model="ir.ui.view">
<field name="name">product.variant.form</field>
<field name="model">product.product</field>
@@ -704,12 +723,12 @@
<record id="product_variant_action" model="ir.actions.act_window">
<field name="name">Product Variants</field>
<field name="type">ir.actions.act_window</field>
- <!--<field name="domain">[('variants','&lt;&gt;', False)]</field>-->
+ <field name="domain">[('variants','!=', '')]</field>
<field name="res_model">product.product</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,kanban</field>
<field name="view_id" ref="product_variant_tree_view"/>
- <field name="search_view_id" ref="product_search_form_view"/>
+ <field name="search_view_id" ref="product_variant_search_form_view"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
Click to define a new variant of product.
@@ -728,9 +747,30 @@
<field name="view_id" ref="product_variant_form_view"/>
<field name="act_window_id" ref="product_variant_action"/>
</record>
- <menuitem action="product.product_variant_action" id="product.menu_variant_product" parent="base.menu_product" sequence="100" groups="product.group_product_variant"/>
+ <menuitem action="product.product_variant_action" id="product.menu_variant_product" parent="prod_config_main" sequence="4" groups="product.group_product_variant"/>
<!-- templates -->
+
+ <record id="product_template_search_view" model="ir.ui.view">
+ <field name="name">product.template.search</field>
+ <field name="model">product.template</field>
+ <field name="arch" type="xml">
+ <search string="Product Template">
+ <field name="name" string="Product"/>
+ <filter string="Services" icon="terp-accessories-archiver" domain="[('type','=','service')]"/>
+ <filter string="Consumable" name="consumable" icon="terp-accessories-archiver" domain="[('type','=','consu')]" help="Consumable products"/>
+ <separator/>
+ <filter string="Can be Sold" name="filter_to_sell" icon="terp-accessories-archiver-minus" domain="[('sale_ok','=',1)]"/>
+ <field name="categ_id"/>
+ <group expand='0' string='Group by...'>
+ <filter string='Category' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'categ_id'}"/>
+ <filter string='Default Unit of Measure' icon="terp-mrp" domain="[]" context="{'group_by' : 'uom_id'}"/>
+ <filter string='Type' icon="terp-stock_symbol-selection" domain="[]" context="{'group_by' : 'type'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
<record id="product_template_tree_view" model="ir.ui.view">
<field name="name">product.template.product.tree</field>
<field name="model">product.template</field>
@@ -740,6 +780,7 @@
<field name="categ_id"/>
<field name="type"/>
<field name="state"/>
+ <field name="uom_id" invisible="1"/>
</tree>
</field>
</record>
@@ -762,81 +803,85 @@
<h2><field name="categ_id"/></h2>
<label for="public_categ_id" class="oe_edit_only"/>
<h3><field name="public_categ_id"/></h3>
+ <div name="options" groups="base.group_user">
+ <field name="sale_ok"/>
+ <label for="sale_ok"/>
+ </div>
</div>
<notebook>
<page string="Information">
- <group>
- <group string="Product Type">
- <field name="sale_ok"/>
- </group>
- <group string="Procurement">
+ <group colspan="4">
+ <group>
<field name="type"/>
- </group>
-
- <group string="Base Prices">
+ <field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"/>
<field name="list_price"/>
+ </group>
+ <group>
+ <field name="company_id" groups="base.group_multi_company" widget="selection"/>
+ </group>
+ </group>
+ <group colspan="4" string="Product Variants" groups="product.group_product_variant">
+ <field colspan="4" name="product_variant_ids" nolabel="1" >
+ <tree string="Product Variants" editable="bottom">
+ <field name="variants" required="1"/>
+ <field name="price_margin" string="Variant Price Margin"/>
+ <field name="price_extra"/>
+ <field name="lst_price" string="Sale Price" readonly="1"/>
+ </tree>
+ </field>
+ </group>
+ <field name="description" placeholder="describe the product characteristics..."/>
+ </page>
+ <page string="Procurements" groups="base.group_user">
+ <group name="procurement">
+ <group name="general">
+ <field name="cost_method" groups="product.group_costing_method"/>
<field name="standard_price" attrs="{'readonly':[('cost_method','=','average')]}"/>
- <field name="cost_method"/>
</group>
-
- <group string="Weights">
- <field digits="(14, 3)" name="volume" attrs="{'readonly':[('type','=','service')]}"/>
- <field digits="(14, 3)" name="weight" attrs="{'readonly':[('type','=','service')]}"/>
- <field digits="(14, 3)" name="weight_net" attrs="{'readonly':[('type','=','service')]}"/>
- </group>
-
- <group name="status" string="Status">
- <field name="categ_id"/>
- <field name="state"/>
- <field name="product_manager" context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_manager']}"/>
+ <group name="delay" string="Delays">
+ <label for="produce_delay"/>
+ <div>
+ <field name="produce_delay" class="oe_inline" style="vertical-align:baseline"/> days
+ </div>
</group>
-
- <group name="uom" string="Unit of Measure">
- <field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"/>
+ <group name="procurement_uom" groups="product.group_uom" string="Purchase">
<field name="uom_po_id"/>
</group>
-
- <group name="uos" groups="product.group_uom" string="Second Unit of Measure">
- <field name="uos_id"/>
- <field name="uos_coeff"/>
- <field name="mes_type"/>
+ </group>
+ <separator string="Suppliers"/>
+ <field name="seller_ids"/>
+ <separator string="Description for Suppliers"/>
+ <field name="description_purchase" placeholder="This note will be displayed on requests for quotation..."/>
+ </page>
+ <page string="Inventory">
+ <group name="inventory">
+ <group name="status" string="Status">
+ <field name="state"/>
+ <field name="product_manager"/>
</group>
-
- <group colspan="4" string="Product Variants" groups="product.group_product_variant">
- <field colspan="4" name="product_variant_ids" nolabel="1">
- <tree string="Product Variants" editable="bottom">
- <field name="active"/>
- <field name="variants" required="1"/>
- <field name="default_code"/>
- <field name="price_margin"/>
- <field name="price_extra"/>
- </tree>
- </field>
+ <group name ="weight" string="Weights">
+ <field digits="(14, 3)" name="volume" attrs="{'readonly':[('type','=','service')]}"/>
+ <field digits="(14, 3)" name="weight" attrs="{'readonly':[('type','=','service')]}"/>
+ <field digits="(14, 3)" name="weight_net" attrs="{'readonly':[('type','=','service')]}"/>
</group>
</group>
</page>
- <page string="Procurement &amp; Locations">
- <group>
- <group name="delay" string="Delays">
- <label for="produce_delay"/>
+ <page string="Sales" attrs="{'invisible':[('sale_ok','=',False)]}">
+ <group name="sale">
+ <group name="sale_condition" string="Sale Conditions">
+ <label for="warranty"/>
<div>
- <field name="produce_delay" class="oe_inline"/> days
+ <field name="warranty" class="oe_inline" style="vertical-align:baseline"/> months
</div>
- <field name="warranty"/>
+ </group>
+ <group groups="product.group_uos" string="Unit of Measure">
+ <field name="uos_id"/>
+ <field name="uos_coeff"/>
+ <field name="mes_type"/>
</group>
</group>
-
- </page>
- <page string="Suppliers">
- <field name="seller_ids"/>
- </page>
- <page string="Descriptions">
- <separator string="Internal Description"/>
- <field name="description"/>
- <separator string="Sale Description"/>
- <field name="description_sale"/>
- <separator string="Purchase Description"/>
- <field name="description_purchase"/>
+ <separator string="Description for Quotations"/>
+ <field name="description_sale" placeholder="note to be displayed on quotations..."/>
</page>
</notebook>
</sheet>
@@ -848,17 +893,48 @@
</field>
</record>
- <record id="product_template_action_tree" model="ir.actions.act_window">
+ <record model="ir.ui.view" id="product_template_kanban_view">
+ <field name="name">Product Template Kanban</field>
+ <field name="model">product.template</field>
+ <field name="arch" type="xml">
+ <kanban>
+ <field name="image_small"/>
+ <field name="list_price"/>
+ <templates>
+ <t t-name="kanban-box">
+ <div class="oe_kanban_vignette oe_semantic_html_override">
+ <a type="open"><img t-att-src="kanban_image('product.template', 'image_small', record.id.value)" class="oe_kanban_image"/></a>
+ <div class="oe_kanban_details">
+ <h4>
+ <a type="open">
+ <field name="name"/>
+ </a>
+ </h4>
+ <div name="tags"/>
+ <ul>
+ <li>Price: <field name="list_price"></field></li>
+ </ul>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record id="product_template_action" model="ir.actions.act_window">
<field name="name">Product Templates</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">product.template</field>
+ <field name="view_mode">kanban,tree,form</field>
<field name="view_type">form</field>
- <field name="view_id" ref="product_template_tree_view"/>
+ <field name="view_id" ref="product_template_kanban_view"/>
</record>
- <menuitem id="product_template_menu"
- parent="base.menu_product" sequence="25"
- action="product_template_action_tree"/>
+ <menuitem action="product_template_action"
+ id="menu_product_template_action"
+ parent="base.menu_product" sequence="0"
+ groups="product.group_product_variant"/>
</data>
</openerp>
diff --git a/addons/product/security/product_security.xml b/addons/product/security/product_security.xml
index 11b6319329a..81a32967d59 100644
--- a/addons/product/security/product_security.xml
+++ b/addons/product/security/product_security.xml
@@ -5,7 +5,7 @@
DO NOT CHANGE IT IN TRUNK -->
<record id="group_product_variant" model="res.groups">
- <field name="name">Product Variant (not supported)</field>
+ <field name="name">Manage Product Variants</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>