[IMP] stock: configurable product's weight UOM
This commit adds the possibility to chose between pounds and kilograms to express the weight field on the product. This is done so that companies that worked internally in pounds do not have to convert their weights back to kilograms for a consistent computation of the rates in delivery. We complete the general settings with the selection of the weight's uom. Validating the setting will create an ir.config.parameter. A static method defined on product template will return the chosen UOM. We display "weight_uom_name" on the form view so that the UOM is not clickable/editable because we fear user would want to edit the UOM instead of changing it in the res config. We move the view definition allowing to fill the product's weight from stock to product to help the generation of the intrastat report without installing inventory.
This commit is contained in:
committed by
Simon Lejeune
parent
951cb8bf40
commit
52a85e57b9
@@ -79,40 +79,42 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<h2>Multi-company</h2>
|
||||
<div class="row mt16 o_settings_container" name="multi_company">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_multi_company"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Multi-company" for="group_multi_company"/>
|
||||
<div class="text-muted">
|
||||
Manage multiple legal entities with separate accounting
|
||||
<div id="multi_company">
|
||||
<field name="company_id" invisible="1"/>
|
||||
<h2>Multi-company</h2>
|
||||
<div class="row mt16 o_settings_container" name="multi_company">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="group_multi_company"/>
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('group_multi_company','=',False)]}">
|
||||
<div class="mt16">
|
||||
<button name="%(base.action_res_company_form)d" icon="fa-arrow-right" type="action" string="Companies" class="btn-link"/>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Multi-company" for="group_multi_company"/>
|
||||
<div class="text-muted">
|
||||
Manage multiple legal entities with separate accounting
|
||||
</div>
|
||||
<div id="company_share_partner">
|
||||
<field name="company_share_partner"/>
|
||||
<label string="Common Contact Book" class="o_light_label" for="company_share_partner"/>
|
||||
<div class="content-group" attrs="{'invisible': [('group_multi_company','=',False)]}">
|
||||
<div class="mt16">
|
||||
<button name="%(base.action_res_company_form)d" icon="fa-arrow-right" type="action" string="Companies" class="btn-link"/>
|
||||
</div>
|
||||
<div id="company_share_partner">
|
||||
<field name="company_share_partner"/>
|
||||
<label string="Common Contact Book" class="o_light_label" for="company_share_partner"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" title="Configure company rules to automatically create SO/PO when one of your company sells/buys to another of your company." attrs="{'invisible': [('group_multi_company', '=', False)]}" id="inter_company">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_inter_company_rules" widget="upgrade_boolean"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Inter-Company Transactions" for="module_inter_company_rules"/>
|
||||
<div class="text-muted">
|
||||
Automate inter-company transactions
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" title="Configure company rules to automatically create SO/PO when one of your company sells/buys to another of your company." attrs="{'invisible': [('group_multi_company', '=', False)]}" id="inter_company">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="module_inter_company_rules" widget="upgrade_boolean"/>
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('module_inter_company_rules','=',False)]}" id="inter_companies_rules">
|
||||
<div class="mt16 text-warning"><strong>Save</strong> this page and come back here to set up the feature.</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Inter-Company Transactions" for="module_inter_company_rules"/>
|
||||
<div class="text-muted">
|
||||
Automate inter-company transactions
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('module_inter_company_rules','=',False)]}" id="inter_companies_rules">
|
||||
<div class="mt16 text-warning"><strong>Save</strong> this page and come back here to set up the feature.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -51,12 +51,6 @@ class StockMoveLine(models.Model):
|
||||
class StockPicking(models.Model):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
def _default_uom(self):
|
||||
weight_uom_id = self.env.ref('product.product_uom_kgm', raise_if_not_found=False)
|
||||
if not weight_uom_id:
|
||||
uom_categ_id = self.env.ref('product.product_uom_categ_kgm').id
|
||||
weight_uom_id = self.env['product.uom'].search([('category_id', '=', uom_categ_id), ('factor', '=', 1)], limit=1)
|
||||
return weight_uom_id
|
||||
|
||||
@api.one
|
||||
@api.depends('move_line_ids')
|
||||
@@ -89,7 +83,7 @@ class StockPicking(models.Model):
|
||||
weight = fields.Float(compute='_cal_weight', digits=dp.get_precision('Stock Weight'), store=True)
|
||||
carrier_tracking_ref = fields.Char(string='Tracking Reference', copy=False)
|
||||
carrier_tracking_url = fields.Char(string='Tracking URL', compute='_compute_carrier_tracking_url')
|
||||
weight_uom_id = fields.Many2one('product.uom', string='Unit of Measure', required=True, readonly="1", help="Unit of measurement for Weight", default=_default_uom)
|
||||
weight_uom_id = fields.Many2one('product.uom', string='Unit of Measure', compute='_compute_weight_uom_id', help="Unit of measurement for Weight")
|
||||
package_ids = fields.Many2many('stock.quant.package', compute='_compute_packages', string='Packages')
|
||||
weight_bulk = fields.Float('Bulk Weight', compute='_compute_bulk_weight')
|
||||
shipping_weight = fields.Float("Weight for Shipping", compute='_compute_shipping_weight')
|
||||
@@ -99,6 +93,11 @@ class StockPicking(models.Model):
|
||||
for picking in self:
|
||||
picking.carrier_tracking_url = picking.carrier_id.get_tracking_link(picking) if picking.carrier_id and picking.carrier_tracking_ref else False
|
||||
|
||||
def _compute_weight_uom_id(self):
|
||||
weight_uom_id = self.env['product.template']._get_weight_uom_id_from_ir_config_parameter()
|
||||
for picking in self:
|
||||
picking.weight_uom_id = weight_uom_id
|
||||
|
||||
@api.depends('move_lines')
|
||||
def _cal_weight(self):
|
||||
for picking in self:
|
||||
|
||||
@@ -136,7 +136,7 @@ class ProductProduct(models.Model):
|
||||
volume = fields.Float('Volume', help="The volume in m3.")
|
||||
weight = fields.Float(
|
||||
'Weight', digits=dp.get_precision('Stock Weight'),
|
||||
help="The weight of the contents in Kg, not including any packaging, etc.")
|
||||
help="Weight of the product, packaging not included. The unit of measure can be changed in the general settings")
|
||||
|
||||
pricelist_item_ids = fields.Many2many(
|
||||
'product.pricelist.item', 'Pricelist Items', compute='_get_pricelist_items')
|
||||
|
||||
@@ -89,6 +89,8 @@ class ProductTemplate(models.Model):
|
||||
'Weight', compute='_compute_weight', digits=dp.get_precision('Stock Weight'),
|
||||
inverse='_set_weight', store=True,
|
||||
help="The weight of the contents in Kg, not including any packaging, etc.")
|
||||
weight_uom_id = fields.Many2one('product.uom', string='Weight Unit of Measure', compute='_compute_weight_uom_id')
|
||||
weight_uom_name = fields.Char(string='Weight unit of measure label', related='weight_uom_id.name', readonly=True)
|
||||
|
||||
sale_ok = fields.Boolean(
|
||||
'Can be Sold', default=True,
|
||||
@@ -234,6 +236,25 @@ class ProductTemplate(models.Model):
|
||||
for template in (self - unique_variants):
|
||||
template.weight = 0.0
|
||||
|
||||
@api.model
|
||||
def _get_weight_uom_id_from_ir_config_parameter(self):
|
||||
""" Get the unit of measure to interpret the `weight` field. By default, we considerer
|
||||
that weights are expressed in kilograms. Users can configure to express them in pounds
|
||||
by adding an ir.config_parameter record with "product.product_weight_in_lbs" as key
|
||||
and "1" as value.
|
||||
"""
|
||||
get_param = self.env['ir.config_parameter'].sudo().get_param
|
||||
product_weight_in_lbs_param = get_param('product.weight_in_lbs')
|
||||
if product_weight_in_lbs_param == '1':
|
||||
return self.env.ref('product.product_uom_lb')
|
||||
else:
|
||||
return self.env.ref('product.product_uom_kgm')
|
||||
|
||||
def _compute_weight_uom_id(self):
|
||||
weight_uom_id = self._get_weight_uom_id_from_ir_config_parameter()
|
||||
for product_template in self:
|
||||
product_template.weight_uom_id = weight_uom_id
|
||||
|
||||
@api.one
|
||||
def _set_weight(self):
|
||||
if len(self.product_variant_ids) == 1:
|
||||
|
||||
@@ -24,6 +24,10 @@ class ResConfigSettings(models.TransientModel):
|
||||
implied_group='product.group_product_pricelist')
|
||||
group_pricelist_item = fields.Boolean("Show pricelists to customers",
|
||||
implied_group='product.group_pricelist_item')
|
||||
product_weight_in_lbs = fields.Selection([
|
||||
('0', 'Kilogram'),
|
||||
('1', 'Pound'),
|
||||
], 'Weight unit of measure', config_parameter='product.weight_in_lbs', default='0')
|
||||
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -55,6 +55,18 @@
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="product_variant_id" invisible="1"/>
|
||||
</group>
|
||||
<group name="group_lots_and_weight" attrs="{'invisible':[('type', 'not in', ['product', 'consu'])]}">
|
||||
<label for="weight"/>
|
||||
<div class="o_row" name="weight">
|
||||
<field name="weight"/>
|
||||
<span><field name="weight_uom_name"/></span>
|
||||
</div>
|
||||
<label for="volume"/>
|
||||
<div class="o_row" name="volume">
|
||||
<field name="volume" string="Volume"/>
|
||||
<span>m³</span>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Sales" attrs="{'invisible':[('sale_ok','=',False)]}" name="sales">
|
||||
|
||||
@@ -9,6 +9,26 @@
|
||||
<field name="company_share_product"/>
|
||||
<label string="Common Product Catalog" class="o_light_label" for="company_share_product"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@id='multi_company']" position="before">
|
||||
<h2>Products</h2>
|
||||
<div class="row mt16 o_settings_container" id="product_general_settings">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||
<div class="o_setting_left_pane">
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="product_weight_in_lbs"/>
|
||||
<div class="text-muted">
|
||||
In which unit of measure do you manage your weights
|
||||
</div>
|
||||
<div class="content-group">
|
||||
<div class="mt16">
|
||||
<field name="product_weight_in_lbs" class="o_light_label" widget="radio"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -97,18 +97,6 @@
|
||||
</group>
|
||||
</group>
|
||||
<group name="inventory_valuation" position="after">
|
||||
<group string="Logistics" name="group_lots_and_weight" attrs="{'invisible':[('type', 'not in', ['product', 'consu'])]}">
|
||||
<label for="weight"/>
|
||||
<div class="o_row" name="weight">
|
||||
<field name="weight"/>
|
||||
<span>kg</span>
|
||||
</div>
|
||||
<label for="volume"/>
|
||||
<div class="o_row" name="volume">
|
||||
<field name="volume" string="Volume"/>
|
||||
<span>m³</span>
|
||||
</div>
|
||||
</group>
|
||||
<group string="Counterpart Locations" name="stock_property" groups="base.group_no_one">
|
||||
<field name="property_stock_production" domain="[('usage','=','production')]"/>
|
||||
<field name="property_stock_inventory" domain="[('usage','=','inventory')]"/>
|
||||
|
||||
Reference in New Issue
Block a user