[IMP] product: only template child / multiple template childs form view improvements
authorThibault Delavallée <tde@openerp.com>
Wed, 22 Jan 2014 09:58:26 +0000 (10:58 +0100)
committerThibault Delavallée <tde@openerp.com>
Wed, 22 Jan 2014 09:58:26 +0000 (10:58 +0100)
- 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

addons/account/product_view.xml
addons/event_sale/event_sale_view.xml
addons/procurement/procurement_view.xml
addons/product/product.py
addons/product/product_view.xml
addons/purchase/purchase_view.xml
addons/report_intrastat/report_intrastat_view.xml
addons/stock/product_view.xml

index d5fb3fe..73b31bb 100644 (file)
                     <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>
index 33bd7d7..c7b5071 100644 (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>
index 5f0a0f8..e0f3459 100644 (file)
         </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">
                 </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/>
                             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
                     <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">
index 951b6d6..b553894 100644 (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."),
index c14c773..0248d51 100644 (file)
             <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"/>
                             <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"/>
                                         <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"/>
                             <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>
                                 <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"/>
                                     </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>
index fca1ee3..9ff9c77 100644 (file)
             <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"/>
index bcbd19d..17ce939 100644 (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>
index cff43b8..5821497 100644 (file)
                 </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">
                             <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>