[MERGE] [IMP] product: product and product template management
product - added a is_only_child field, telling whether the product is the only child of its template - form view: fields coming from the template are now readonly when there are several products (variants) for the template; added a link to the template on the product form view - renamed Products menu into All Products - some improvements in search view, notably groupby product.template - improved form view to look more similar to the product one - added Product Template menus when using variants website_sale: do not fetch templates without products bzr revid: tde@openerp.com-20140122183759-s9lfvfeo8f6ytm34
This commit is contained in:
@@ -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>
|
||||
@@ -31,12 +35,16 @@
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="Accounting">
|
||||
<separator string="Sales Properties" colspan="2"/>
|
||||
<separator string="Purchase Properties" colspan="2"/>
|
||||
<field name="property_account_income" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
<field name="property_account_expense" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
<field name="taxes_id"/>
|
||||
<field name="supplier_taxes_id"/>
|
||||
<group name="properties">
|
||||
<group>
|
||||
<field name="property_account_income" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
<field name="taxes_id" colspan="2" widget="many2many_tags"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="property_account_expense" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
<field name="supplier_taxes_id" colspan="2" widget="many2many_tags"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -291,15 +291,49 @@
|
||||
<field name="res_model">stock.warehouse.orderpoint</field>
|
||||
</record>
|
||||
|
||||
<record id="product_template_search_view_procurment" model="ir.ui.view">
|
||||
<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">
|
||||
<filter name="consumable" position="before">
|
||||
<filter string="Products" icon="terp-accessories-archiver" domain="[('type','=','product')]" help="Stockable products"/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_template_form_view_procurement">
|
||||
<field name="name">product.template.procurement</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='type']" position="after">
|
||||
<xpath expr="//field[@name='cost_method']" position="before">
|
||||
<field name="procure_method"/>
|
||||
<field name="supply_method"/>
|
||||
</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', '!=', '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', '!=', '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/>
|
||||
If there are not enough quantities available, the delivery order
|
||||
will wait for new products. To fulfill the inventory, you should
|
||||
create others rules like orderpoints.
|
||||
</p>
|
||||
<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
|
||||
on hand may become negative).
|
||||
</p>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -326,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">
|
||||
|
||||
+57
-27
@@ -23,10 +23,10 @@ import math
|
||||
import re
|
||||
|
||||
from _common import rounding
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp import tools
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.osv import osv, orm, fields
|
||||
from openerp.tools.translate import _
|
||||
|
||||
import openerp.addons.decimal_precision as dp
|
||||
@@ -391,7 +391,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 +468,13 @@ 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 = {}
|
||||
template = self.browse(cr, uid, id, context=context)
|
||||
default['name'] = _("%s (copy)") % (template['name'])
|
||||
return super(product_template, self).copy(cr, uid, id, default=default, context=context)
|
||||
|
||||
_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,
|
||||
@@ -510,6 +517,13 @@ class product_template(osv.osv):
|
||||
|
||||
|
||||
class product_product(osv.osv):
|
||||
_name = "product.product"
|
||||
_description = "Product"
|
||||
_table = "product_product"
|
||||
_inherits = {'product.template': 'product_tmpl_id'}
|
||||
_inherit = ['mail.thread']
|
||||
_order = 'default_code,name_template'
|
||||
|
||||
def view_header_get(self, cr, uid, view_id, view_type, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
@@ -583,6 +597,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:
|
||||
@@ -614,6 +629,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``,
|
||||
@@ -641,7 +662,6 @@ class product_product(osv.osv):
|
||||
}
|
||||
return result
|
||||
|
||||
|
||||
def _get_name_template_ids(self, cr, uid, ids, context=None):
|
||||
result = set()
|
||||
template_ids = self.pool.get('product.product').search(cr, uid, [('product_tmpl_id', 'in', ids)])
|
||||
@@ -649,19 +669,6 @@ class product_product(osv.osv):
|
||||
result.add(el)
|
||||
return list(result)
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
'price_extra': lambda *a: 0.0,
|
||||
'price_margin': lambda *a: 1.0,
|
||||
'color': 0,
|
||||
}
|
||||
|
||||
_name = "product.product"
|
||||
_description = "Product"
|
||||
_table = "product_product"
|
||||
_inherits = {'product.template': 'product_tmpl_id'}
|
||||
_inherit = ['mail.thread']
|
||||
_order = 'default_code,name_template'
|
||||
_columns = {
|
||||
'qty_available': fields.function(_product_qty_available, type='float', string='Quantity On Hand'),
|
||||
'virtual_available': fields.function(_product_virtual_available, type='float', string='Quantity Available'),
|
||||
@@ -673,24 +680,34 @@ 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),
|
||||
'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')),
|
||||
'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),
|
||||
'product.product': (lambda self, cr, uid, ids, c=None: ids, [], 10),
|
||||
|
||||
}, select=True),
|
||||
}, select=True),
|
||||
'color': fields.integer('Color Index'),
|
||||
'seller_info_id': fields.function(_calc_seller, type='many2one', relation="product.supplierinfo", string="Supplier Info", multi="seller_info"),
|
||||
'seller_delay': fields.function(_calc_seller, type='integer', string='Supplier Lead Time', multi="seller_info", help="This is the average delay in days between the purchase order confirmation and the reception of goods for this product and for the default supplier. It is used by the scheduler to order requests based on reordering delays."),
|
||||
'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"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'active': lambda *a: 1,
|
||||
'price_extra': lambda *a: 0.0,
|
||||
'price_margin': lambda *a: 1.0,
|
||||
'color': 0,
|
||||
'is_only_child': True,
|
||||
}
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
unlink_ids = []
|
||||
unlink_product_tmpl_ids = []
|
||||
@@ -721,7 +738,6 @@ class product_product(osv.osv):
|
||||
res = check_ean(product['ean13'])
|
||||
return res
|
||||
|
||||
|
||||
_constraints = [(_check_ean_key, 'You provided an invalid "EAN13 Barcode" reference. You may use the "Internal Reference" field instead.', ['ean13'])]
|
||||
|
||||
def on_order(self, cr, uid, ids, orderline, quantity):
|
||||
@@ -785,7 +801,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))
|
||||
@@ -847,9 +863,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',
|
||||
@@ -867,10 +886,21 @@ 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)
|
||||
|
||||
def open_product_template(self, cr, uid, ids, context=None):
|
||||
""" Utility method used to add an "Open Template" button in product views """
|
||||
product = self.browse(cr, uid, ids[0], context=context)
|
||||
return {'type': 'ir.actions.act_window',
|
||||
'res_model': 'product.template',
|
||||
'view_mode': 'form',
|
||||
'res_id': product.product_tmpl_id.id,
|
||||
'target': 'new'}
|
||||
|
||||
|
||||
class product_packaging(osv.osv):
|
||||
_name = "product.packaging"
|
||||
|
||||
+206
-96
@@ -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<0;blue:virtual_available>=0 and state in ('draft', 'end', 'obsolete');black:virtual_available>=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>
|
||||
@@ -57,18 +60,35 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Product" version="7.0">
|
||||
<sheet>
|
||||
<field name="image_medium" widget="image" class="oe_avatar oe_left"/>
|
||||
<field name="is_only_child" invisible="1"/>
|
||||
<field name="image_medium" widget="image" class="oe_avatar oe_left"
|
||||
attrs="{'readonly': [('is_only_child', '=', False)]}"/>
|
||||
<div class="oe_title">
|
||||
<div class="oe_edit_only">
|
||||
<label for="name" string="Product Name"/>
|
||||
<label for="name" name='label_name' string="Product Name"
|
||||
attrs="{'invisible': [('is_only_child', '=', False)]}"/>
|
||||
<label for="name" name='label_name' string="Product Template"
|
||||
attrs="{'invisible': [('is_only_child', '=', True)]}"/>
|
||||
</div>
|
||||
<h1>
|
||||
<field name="name"/>
|
||||
<field name="name" class="oe_inline"
|
||||
attrs="{'required': [('is_only_child', '=', True)],
|
||||
'invisible': [('is_only_child', '=', False)]}"/>
|
||||
<field name="product_tmpl_id" class="oe_inline" readonly="1" required="0"
|
||||
attrs="{'invisible': [('is_only_child', '=', True)]}"/>
|
||||
<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"/>
|
||||
</h1>
|
||||
<span attrs="{'invisible': [('is_only_child', '=', True)]}">
|
||||
<p>Generic product settings are managed on
|
||||
<button name="open_product_template" type="object" string="the template" class="oe_link"/>
|
||||
</p>
|
||||
</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"/>
|
||||
@@ -80,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="list_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"/>
|
||||
@@ -90,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"/>
|
||||
@@ -111,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>
|
||||
@@ -126,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"/>
|
||||
@@ -159,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>
|
||||
@@ -189,7 +229,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 +262,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 +404,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 +618,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 +708,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 +757,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','<>', 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 +781,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 +814,7 @@
|
||||
<field name="categ_id"/>
|
||||
<field name="type"/>
|
||||
<field name="state"/>
|
||||
<field name="uom_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
@@ -762,81 +837,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"/>
|
||||
<field name="standard_price" attrs="{'readonly':[('cost_method','=','average')]}"/>
|
||||
<field name="cost_method"/>
|
||||
</group>
|
||||
|
||||
<group string="Weights">
|
||||
<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')]}"/>
|
||||
</group>
|
||||
<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="procurement_uom" groups="product.group_uom" string="Purchase">
|
||||
<field name="uom_po_id"/>
|
||||
</group>
|
||||
</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 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 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>
|
||||
|
||||
<group name="uom" string="Unit of Measure">
|
||||
<field name="uom_id" on_change="onchange_uom(uom_id,uom_po_id)" groups="product.group_uom"/>
|
||||
<field name="uom_po_id"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Sales" attrs="{'invisible':[('sale_ok','=',False)]}">
|
||||
<group name="sale">
|
||||
<group name="sale_condition" string="Sale Conditions">
|
||||
<label for="warranty"/>
|
||||
<div>
|
||||
<field name="warranty" class="oe_inline" style="vertical-align:baseline"/> months
|
||||
</div>
|
||||
</group>
|
||||
|
||||
<group name="uos" groups="product.group_uom" string="Second Unit of Measure">
|
||||
<group groups="product.group_uos" string="Unit of Measure">
|
||||
<field name="uos_id"/>
|
||||
<field name="uos_coeff"/>
|
||||
<field name="mes_type"/>
|
||||
</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>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Procurement & Locations">
|
||||
<group>
|
||||
<group name="delay" string="Delays">
|
||||
<label for="produce_delay"/>
|
||||
<div>
|
||||
<field name="produce_delay" class="oe_inline"/> days
|
||||
</div>
|
||||
<field name="warranty"/>
|
||||
</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 +927,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>
|
||||
|
||||
@@ -5,10 +5,18 @@
|
||||
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>
|
||||
|
||||
<record id="group_product_mono" model="res.groups">
|
||||
<field name="name">Do Not Manage Product Variants</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
</record>
|
||||
<record id="base.group_user" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('product.group_product_mono'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="group_sale_pricelist" model="res.groups">
|
||||
<field name="name">Sales Pricelists</field>
|
||||
<field name="category_id" ref="base.module_category_hidden"/>
|
||||
|
||||
@@ -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"/>
|
||||
@@ -597,14 +598,26 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="product_template_search_view_purchase" model="ir.ui.view">
|
||||
<field name="name">product.template.search.purchase</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_search_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<filter name="filter_to_sell" position="after">
|
||||
<filter name="filter_to_purchase" string="Can be Purchased" icon="terp-accessories-archiver+" domain="[('purchase_ok', '=', 1)]"/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_template_purchase_ok_form" model="ir.ui.view">
|
||||
<field name="name">product.template.purchase.ok.form.inherit</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="sale_ok" position="after">
|
||||
<div name="options" position="inside">
|
||||
<field name="purchase_ok"/>
|
||||
</field>
|
||||
<label for="purchase_ok"/>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_purchase_line_product_tree">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -26,9 +26,37 @@ from openerp.tools.translate import _
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
class sale_configuration(osv.osv_memory):
|
||||
|
||||
class sale_configuration(osv.TransientModel):
|
||||
_inherit = 'sale.config.settings'
|
||||
|
||||
def set_group_product_variant(self, cr, uid, ids, context=None):
|
||||
""" This method is automatically called by res_config as it begins
|
||||
with set. It is used to implement the 'one group or another'
|
||||
behavior. We have to perform some group manipulation by hand
|
||||
because in res_config.execute(), set_* methods are called
|
||||
after group_*; therefore writing on an hidden res_config file
|
||||
could not work.
|
||||
If group_product_variant is checked: remove group_product_mono
|
||||
from group_user, remove the users. Otherwise, just add
|
||||
group_product_mono in group_user.
|
||||
The inverse logic about group_product_variant is managed by the
|
||||
normal behavior of 'group_product_variant' field.
|
||||
"""
|
||||
def ref(xml_id):
|
||||
mod, xml = xml_id.split('.', 1)
|
||||
return self.pool['ir.model.data'].get_object(cr, uid, mod, xml, context)
|
||||
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
config_group = ref('product.group_product_mono')
|
||||
base_group = ref('base.group_user')
|
||||
if obj.group_product_variant:
|
||||
base_group.write({'implied_ids': [(3, config_group.id)]})
|
||||
config_group.write({'users': [(3, u.id) for u in base_group.users]})
|
||||
else:
|
||||
base_group.write({'implied_ids': [(4, config_group.id)]})
|
||||
return True
|
||||
|
||||
_columns = {
|
||||
'group_invoice_so_lines': fields.boolean('Generate invoices based on the sales order lines',
|
||||
implied_group='sale.group_invoice_so_lines',
|
||||
|
||||
@@ -37,29 +37,30 @@
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="delay" position="inside">
|
||||
<field name="sale_delay" attrs="{'readonly':[('sale_ok','=',False)]}"/>
|
||||
</group>
|
||||
<group name="delay" position="after">
|
||||
<group name="store" string="Storage Location">
|
||||
<xpath expr="//group[@name='sale_condition']" position="inside">
|
||||
<label for="sale_delay"/>
|
||||
<div>
|
||||
<field name="sale_delay" attrs="{'readonly':[('sale_ok','=',False)]}" class="oe_inline" style="vertical-align:baseline"/> days
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//group[@name='status']" position="after">
|
||||
<group name="store" string="Storage Location">
|
||||
<field name="loc_rack"/>
|
||||
<field name="loc_row"/>
|
||||
<field name="loc_case"/>
|
||||
</group>
|
||||
</group>
|
||||
<page position="after" string="Information">
|
||||
<page string="Properties">
|
||||
<group string="Counter-Part Locations Properties" groups="stock.group_locations">
|
||||
<field name="property_stock_procurement" domain="[('usage','=','procurement')]"/>
|
||||
<field name="property_stock_production" domain="[('usage','=','production')]"/>
|
||||
<field name="property_stock_inventory" domain="[('usage','=','inventory')]"/>
|
||||
</group>
|
||||
<group string="Accounting Entries">
|
||||
<field name="property_stock_account_input" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
<field name="property_stock_account_output" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
</group>
|
||||
</page>
|
||||
</page>
|
||||
<field name="loc_case"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<xpath expr="//group[@name='weight']" position="after">
|
||||
<group string="Accounting Entries">
|
||||
<field name="property_stock_account_input" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
<field name="property_stock_account_output" domain="[('type','<>','view'),('type','<>','consolidation')]"/>
|
||||
</group>
|
||||
<group string="Counter-Part Locations Properties" groups="stock.group_locations">
|
||||
<field name="property_stock_procurement" domain="[('usage','=','procurement')]"/>
|
||||
<field name="property_stock_production" domain="[('usage','=','production')]"/>
|
||||
<field name="property_stock_inventory" domain="[('usage','=','inventory')]"/>
|
||||
</group>
|
||||
</xpath>
|
||||
<field name="product_manager" position="attributes" version="7.0">
|
||||
<attribute name="context">{'default_groups_ref': ['base.group_user', 'base.group_sale_manager', 'stock.group_stock_manager']}</attribute>
|
||||
</field>
|
||||
@@ -121,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">
|
||||
@@ -138,7 +139,7 @@
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="standard_price" position="replace" version="7.0">
|
||||
<label string="Cost Price" for="standard_price" align="1.0" groups="base.group_user"/>
|
||||
<label for="standard_price" align="1.0" groups="base.group_user"/>
|
||||
<div groups="base.group_user">
|
||||
<field name="standard_price" attrs="{'readonly':[('cost_method','=','average')]}" nolabel="1"/>
|
||||
<button name="%(action_view_change_standard_price)d" string="- update"
|
||||
@@ -162,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','<>','view'),('type','<>','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','<>','view'),('type','<>','consolidation')]"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
@@ -23,9 +23,15 @@
|
||||
<menuitem
|
||||
action="product.product_category_action_form" id="menu_product_category_config_stock"
|
||||
parent="stock.menu_product_in_config_stock" sequence="0"/>
|
||||
<menuitem
|
||||
action="product.product_variant_action" id="menu_product_variant_config_stock"
|
||||
parent="stock.menu_product_in_config_stock" groups="product.group_product_variant" sequence="2"/>
|
||||
<menuitem
|
||||
action="product.product_template_action" id="menu_product_template_config_stock"
|
||||
parent="stock.menu_product_in_config_stock" groups="product.group_product_variant" sequence="1"/>
|
||||
<menuitem
|
||||
action="product.product_ul_form_action" groups="product.group_stock_packaging"
|
||||
id="menu_product_packaging_stock_action" parent="stock.menu_product_in_config_stock" sequence="1"/>
|
||||
id="menu_product_packaging_stock_action" parent="stock.menu_product_in_config_stock" sequence="3"/>
|
||||
<menuitem
|
||||
id="menu_stock_unit_measure_stock" name="Units of Measure"
|
||||
parent="stock.menu_product_in_config_stock" sequence="35" groups="product.group_uom"/>
|
||||
|
||||
@@ -138,8 +138,8 @@ class product_product(osv.Model):
|
||||
def _website_url(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
|
||||
for id in ids:
|
||||
res[id] = "%s/shop/product/%s/" % (base_url, id)
|
||||
for product in self.browse(cr, uid, ids, context=context):
|
||||
res[product.id] = "%s/shop/product/%s/" % (base_url, product.product_tmpl_id.id)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
|
||||
@@ -216,4 +216,4 @@ class Website(orm.Model):
|
||||
return super(Website, self).preprocess_request(cr, uid, ids, request, context=None)
|
||||
|
||||
def ecommerce_get_product_domain(self):
|
||||
return [("sale_ok", "=", True)]
|
||||
return [("sale_ok", "=", True),("product_variant_ids","!=",False)]
|
||||
|
||||
@@ -53,11 +53,12 @@
|
||||
<field name="inherit_id" ref="product.product_template_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<!-- add state field in header -->
|
||||
|
||||
<xpath expr="//sheet/div" position="before">
|
||||
<field name="website_url" invisible="1"/>
|
||||
<field name="website_published" class="pull-right" widget="website_button"/>
|
||||
</xpath>
|
||||
<xpath expr="//page[@string='Information']" position="inside">
|
||||
<xpath expr="//field[@name='description']" position="before">
|
||||
<group colspan="4" string="Website Options">
|
||||
<field name="suggested_product_ids" widget="many2many_tags"/>
|
||||
<field name="website_style_ids" widget="many2many_tags"/>
|
||||
|
||||
Reference in New Issue
Block a user