[IMP] product: only template child / multiple template childs form view improvements

- added a is_only_child field on product.product, telling whether the
product is the only child of the product.template
- improved the product form view, to set readonly all fields coming fgrom
the template when the product is not the only child. This way, the user
is more aware that changing a value in the template changes the value
for all child products. He will have to do those changes on the template
form. A link to the template has been added in the product form view.

bzr revid: tde@openerp.com-20140122095826-8k0wl7af57iiyify
This commit is contained in:
Thibault Delavallée 2014-01-22 10:58:26 +01:00
parent 14bdf21b17
commit 38d64147d5
8 changed files with 92 additions and 46 deletions

View File

@ -11,12 +11,16 @@
<page string="Accounting" groups="account.group_account_invoice">
<group name="properties">
<group>
<field name="property_account_income" domain="[('type','=','other')]" groups="account.group_account_user"/>
<field name="taxes_id" colspan="2" attrs="{'readonly':[('sale_ok','=',0)]}" widget="many2many_tags"/>
<field name="property_account_income" domain="[('type','=','other')]" groups="account.group_account_user"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="taxes_id" colspan="2" widget="many2many_tags"
attrs="{'readonly':[ '|', ('sale_ok','=',0), ('is_only_child', '=', False)]}"/>
</group>
<group>
<field name="property_account_expense" domain="[('type','=','other')]" groups="account.group_account_user"/>
<field name="supplier_taxes_id" colspan="2" widget="many2many_tags"/>
<field name="property_account_expense" domain="[('type','=','other')]" groups="account.group_account_user"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="supplier_taxes_id" colspan="2" widget="many2many_tags"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</group>
</group>
</page>

View File

@ -8,10 +8,11 @@
<field name="arch" type="xml">
<div name="options" position="inside">
<field name="event_ok" on_change="onchange_event_ok(type, event_ok, context)"/>
<label for="event_ok"/>
<label for="event_ok"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</div>
<div name='ean' position="after">
<field name="event_type_id" attrs="{'readonly': [('event_ok', '=', False)]}"/>
<field name="event_type_id" attrs="{'readonly': ['|', ('event_ok', '=', False), ('is_only_child', '=', False)]}"/>
</div>
</field>
</record>

View File

@ -292,7 +292,7 @@
</record>
<record id="product_template_search_view_procurment" model="ir.ui.view">
<field name="name">product.template.search.procurment</field>
<field name="name">product.template.search.procurement</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_search_view"/>
<field name="arch" type="xml">
@ -313,12 +313,12 @@
</xpath>
<xpath expr="//group[@name='general']" position="after" >
<group name="procurement_help" class="oe_grey" col="1" groups="base.group_user">
<p attrs="{'invisible': ['|','|',('type','&lt;&gt;','service'),('procure_method','&lt;&gt;','make_to_stock')]}">
<p attrs="{'invisible': ['|', '|', ('type', '!=', 'service'), ('procure_method', '!=', 'make_to_stock')]}">
When you sell this service, nothing special will be triggered
to deliver the customer, as you set the procurement method as
'Make to Stock'.
</p>
<p attrs="{'invisible': ['|','|',('type','&lt;&gt;','product'),('procure_method','&lt;&gt;','make_to_stock')]}">
<p attrs="{'invisible': ['|', '|', ('type', '!=', 'product'), ('procure_method', '!=', 'make_to_stock')]}">
When you sell this product, OpenERP will <b>use the available
inventory</b> for the delivery order.
<br/><br/>
@ -326,7 +326,7 @@
will wait for new products. To fulfill the inventory, you should
create others rules like orderpoints.
</p>
<p attrs="{'invisible': ['|','|',('type','&lt;&gt;','consu'),('procure_method','&lt;&gt;','make_to_stock')]}">
<p attrs="{'invisible': ['|', '|', ('type', '!=', 'consu'), ('procure_method', '!=', 'make_to_stock')]}">
When you sell this product, a delivery order will be created.
OpenERP will consider that the <b>required quantities are always
available</b> as it's a consumable (as a result of this, the quantity
@ -360,8 +360,10 @@
<button string="Orderpoints" name="%(product_open_orderpoint)d" type="action" attrs="{'invisible':[('type', '=', 'service')]}"/>
</xpath>
<xpath expr="//field[@name='cost_method']" position="before">
<field name="procure_method" groups="base.group_user"/>
<field name="supply_method" groups="base.group_user"/>
<field name="procure_method" groups="base.group_user"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="supply_method" groups="base.group_user"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</xpath>
<xpath expr="//group[@name='general']" position="after" >
<group name="procurement_help" class="oe_grey" col="1" groups="base.group_user">

View File

@ -615,6 +615,12 @@ class product_product(osv.osv):
(data['name'] or '') + (data['variants'] and (' - '+data['variants']) or '')
return res
def _is_only_child(self, cr, uid, ids, name, arg, context=None):
res = dict.fromkeys(ids, True)
for product in self.browse(cr, uid, ids, context=context):
if product.product_tmpl_id and len(product.product_tmpl_id.product_variant_ids) > 1:
res[product.id] = False
return res
def _get_main_product_supplier(self, cr, uid, product, context=None):
"""Determines the main (best) product supplier for ``product``,
@ -676,6 +682,8 @@ class product_product(osv.osv):
'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the product without removing it."),
'variants': fields.char('Variants', size=64, translate=True),
'product_tmpl_id': fields.many2one('product.template', 'Product Template', required=True, ondelete="cascade", select=True),
'is_only_child': fields.function(
_is_only_child, type='boolean', string='Sole child of the parent template'),
'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'), help="Price Extra: Extra price for the variant on sale price. eg. 200 price extra, 1000 + 200 = 1200."),

View File

@ -60,30 +60,35 @@
<field name="arch" type="xml">
<form string="Product" version="7.0">
<sheet>
<field name="is_only_child" invisible="0"/>
<field name="image_medium" widget="image" class="oe_avatar oe_left"/>
<div class="oe_title">
<div class="oe_edit_only">
<label for="name" name='label_name' string="Product Name"
groups="product.group_product_mono"/>
attrs="{'invisible': [('is_only_child', '=', False)]}"/>
<label for="name" name='label_name' string="Product Template"
groups="product.gorup_product_variant"/>
attrs="{'invisible': [('is_only_child', '=', True)]}"/>
</div>
<h1>
<field name="name" class="oe_inline"
required="0"
groups="product.group_product_mono"/>
attrs="{'required': [('is_only_child', '=', True)],
'invisible': [('is_only_child', '=', False)]}"/>
<field name="product_tmpl_id" class="oe_inline"
groups="product.group_product_variant"
attrs="{'required': [('is_only_child', '=', False)],
'invisible': [('is_only_child', '=', True)]}"
on_change="onchange_product_tmpl_id(product_tmpl_id)"/>
<span attrs="{'invisible':[('variants','=',False)]}" groups="product.group_product_variant"> - </span>
<field name="variants" placeholder="Variant Name"
readonly="0"
groups="product.group_product_variant" class="oe_inline"/>
</h1>
<span attrs="{'invisible': [('is_only_child', '=', True)]}">
Manage some of the product attributes on the
<a>template form</a>
</span>
<label for="categ_id" class="oe_edit_only"/>
<h2><field name="categ_id"/></h2>
<h2><field name="categ_id" attrs="{'readonly': [('is_only_child', '=', False)]}"/></h2>
<label for="public_categ_id" class="oe_edit_only"/>
<h3><field name="public_categ_id"/></h3>
<h3><field name="public_categ_id" attrs="{'readonly': [('is_only_child', '=', False)]}"/></h3>
<div name="options" groups="base.group_user">
<field name="sale_ok"/>
<label for="sale_ok"/>
@ -95,9 +100,14 @@
<page string="Information">
<group>
<group>
<field name="type"/>
<field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"/>
<field name="lst_price" string="Public Sale Price"/>
<field name="type"
attrs="{'invisible': [('is_only_child', '=', False)]}"/>
<field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"
attrs="{'invisible': [('is_only_child', '=', False)]}"/>
<field name="lst_price" string="Public Sale Price"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="price_extra"
attrs="{'invisible': [('is_only_child', '=', True)]}"/>
</group>
<group>
<field name="default_code"/>
@ -105,19 +115,24 @@
<div name="ean">
<field name="ean13" placeholder="e.g. 5901234123457"/>
</div>
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
<field name="company_id" groups="base.group_multi_company" widget="selection"
attrs="{'invisible': [('is_only_child', '=', False)]}"/>
</group>
</group>
<field name="description" placeholder="describe the product characteristics..."/>
<field name="description" placeholder="describe the product characteristics..."
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</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" groups="product.group_costing_method"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="standard_price"
attrs="{'readonly': ['|', ('cost_method','=','average'), ('is_only_child', '=', False)]}"/>
</group>
<group name="procurement_uom" groups="product.group_uom" string="Purchase">
<field name="uom_po_id"/>
<field name="uom_po_id"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</group>
</group>
<separator string="Description for Suppliers"/>
@ -126,14 +141,19 @@
<page string="Inventory" groups="base.group_user">
<group name="inventory">
<group name="status" string="Status">
<field name="state"/>
<field name="state"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="product_manager"
context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_manager']}"/>
attrs="{'readonly': [('is_only_child', '=', False)]}"
context="{'default_groups_ref': ['base.group_user', 'base.group_partner_manager', 'base.group_sale_manager']}"/>
</group>
<group name="Weights" groups="product.group_stock_packaging" string="Weights">
<field digits="(14, 3)" name="volume" attrs="{'readonly':[('type','=','service')]}"/>
<field name="weight" attrs="{'readonly':[('type','=','service')]}"/>
<field name="weight_net" attrs="{'readonly':[('type','=','service')]}"/>
<field digits="(14, 3)" name="volume"
attrs="{'readonly': ['|', ('type','=','service'), ('is_only_child', '=', False)]}"/>
<field name="weight"
attrs="{'readonly': ['|', ('type','=','service'), ('is_only_child', '=', False)]}"/>
<field name="weight_net"
attrs="{'readonly': ['|', ('type','=','service'), ('is_only_child', '=', False)]}"/>
</group>
</group>
</page>
@ -141,17 +161,21 @@
<group name="sale">
<group string="Sale Conditions">
<label for="warranty"/>
<div>
<div attrs="{'readonly': [('is_only_child', '=', False)]}">
<field name="warranty" class="oe_inline"/> months
</div>
</group>
<group groups="product.group_uos" string="Unit of Measure">
<field name="uos_id"/>
<field name="uos_coeff"/>
<field name="mes_type"/>
<field name="uos_id"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="uos_coeff"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
<field name="mes_type"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</group>
</group>
<field name="packaging" groups="product.group_stock_packaging">
<field name="packaging" groups="product.group_stock_packaging"
attrs="{'readonly': [('is_only_child', '=', False)]}">
<form string="Packaging" version="7.0">
<group col="4">
<field name="ean"/>
@ -174,7 +198,8 @@
</form>
</field>
<separator string="Description for Quotations"/>
<field name="description_sale" placeholder="note to be displayed on quotations..."/>
<field name="description_sale" placeholder="note to be displayed on quotations..."
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</page>
</notebook>
</sheet>

View File

@ -552,7 +552,8 @@
<field name="arch" type="xml">
<div name="options" position="inside">
<field name="purchase_ok"/>
<label for="purchase_ok"/>
<label for="purchase_ok"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</div>
<group name="procurement" position="after">
<separator string="Suppliers"/>

View File

@ -31,7 +31,8 @@
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<field name="product_manager" position="after">
<field name="intrastat_id"/>
<field name="intrastat_id"
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
</field>
</field>
</record>

View File

@ -122,9 +122,9 @@
</group>
<group name="Weights" position="after">
<group name="store" groups="stock.group_locations" string="Counter-Part Locations Properties">
<field name="property_stock_procurement" attrs="{'readonly':[('type','=','service')]}" domain="[('usage','=','procurement')]"/>
<field name="property_stock_production" attrs="{'readonly':[('type','=','service')]}" domain="[('usage','=','production')]"/>
<field name="property_stock_inventory" attrs="{'readonly':[('type','=','service')]}" domain="[('usage','=','inventory')]"/>
<field name="property_stock_procurement" attrs="{'readonly':['|', '|', ('type','=','service'), ('is_only_child', '=', False), ('is_only_child', '=', False)]}" domain="[('usage','=','procurement')]"/>
<field name="property_stock_production" attrs="{'readonly':['|', '|', ('type','=','service'), ('is_only_child', '=', False), ('is_only_child', '=', False)]}" domain="[('usage','=','production')]"/>
<field name="property_stock_inventory" attrs="{'readonly':['|', '|', ('type','=','service'), ('is_only_child', '=', False), ('is_only_child', '=', False)]}" domain="[('usage','=','inventory')]"/>
</group>
</group>
<field name="product_manager" position="attributes" version="7.0">
@ -163,9 +163,13 @@
<field name="valuation" attrs="{'readonly':[('type', '=', 'service')]}"/>
</group>
<group colspan="2" col="2">
<field name="property_stock_account_input" attrs="{'invisible':[('valuation', '!=', 'real_time')]}"
<field name="property_stock_account_input"
attrs="{'invisible':[('valuation', '!=', 'real_time')],
'readonly': [('is_only_child', '=', False)]}"
domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
<field name="property_stock_account_output" attrs="{'invisible':[('valuation', '!=', 'real_time')]}"
<field name="property_stock_account_output"
attrs="{'invisible':[('valuation', '!=', 'real_time')],
'readonly': [('is_only_child', '=', False)]}"
domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation')]"/>
</group>
</group>