From 2ff3749064c423dd17a767c120961733aec10a2c Mon Sep 17 00:00:00 2001 From: Martin Geubelle Date: Tue, 8 Dec 2015 14:17:23 +0100 Subject: [PATCH] [ADD] delivery: package editable after put in pack * It is sometime useful to be able to set the package type and the package weight during the delivery * These fields can be edited during the 'put in pack' operation or after, with a button in the view * As the weight is computed, a new field 'shipping_weight' has been added * These fields (package type and weight) will be used in the delivery carrier for the shipping * Packaging types are now handled in a centralized way for all shippers --- addons/delivery/__openerp__.py | 1 + addons/delivery/models/__init__.py | 1 + addons/delivery/models/product_packaging.py | 21 +++++++ addons/delivery/models/stock_picking.py | 63 +++++++++++++++++++ addons/delivery/views/delivery_view.xml | 25 ++++++++ .../delivery/views/product_packaging_view.xml | 38 +++++++++++ addons/product/product_view.xml | 4 +- addons/stock/stock.py | 2 +- addons/stock/stock_view.xml | 3 +- 9 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 addons/delivery/models/product_packaging.py create mode 100644 addons/delivery/views/product_packaging_view.xml diff --git a/addons/delivery/__openerp__.py b/addons/delivery/__openerp__.py index 590a913b82b..48ab56e0a05 100644 --- a/addons/delivery/__openerp__.py +++ b/addons/delivery/__openerp__.py @@ -19,6 +19,7 @@ invoices from picking, the system is able to add and compute the shipping line. 'views/delivery_view.xml', 'views/partner_view.xml', 'views/product_template_view.xml', + 'views/product_packaging_view.xml', 'data/delivery_data.xml', 'views/report_shipping.xml', 'views/report_deliveryslip.xml' diff --git a/addons/delivery/models/__init__.py b/addons/delivery/models/__init__.py index d593c2c3957..33fb6434d71 100644 --- a/addons/delivery/models/__init__.py +++ b/addons/delivery/models/__init__.py @@ -4,6 +4,7 @@ import delivery_carrier import delivery_price_rule import product_template +import product_packaging import sale_order import partner import stock_picking diff --git a/addons/delivery/models/product_packaging.py b/addons/delivery/models/product_packaging.py new file mode 100644 index 00000000000..1b5f9b7f262 --- /dev/null +++ b/addons/delivery/models/product_packaging.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +from openerp import models, fields + + +class ProductPackaging(models.Model): + _inherit = 'product.packaging' + + height = fields.Integer('Height') + width = fields.Integer('Width') + length = fields.Integer('Length') + max_weight = fields.Float('Max Weight', help='Maximum weight shippable in this packaging') + shipper_package_code = fields.Char('Package Code') + package_carrier_type = fields.Selection([('none', 'No carrier integration')], string='Carrier', default='none') + + _sql_constraints = [ + ('positive_height', 'CHECK(height>=0)', 'Height must be positive'), + ('positive_width', 'CHECK(width>=0)', 'Width must be positive'), + ('positive_length', 'CHECK(length>=0)', 'Length must be positive'), + ('positive_max_weight', 'CHECK(max_weight>=0.0)', 'Max Weight must be positive'), + ] diff --git a/addons/delivery/models/stock_picking.py b/addons/delivery/models/stock_picking.py index 9c1b93440c2..ef1c6503383 100644 --- a/addons/delivery/models/stock_picking.py +++ b/addons/delivery/models/stock_picking.py @@ -6,6 +6,7 @@ from openerp.exceptions import UserError import openerp.addons.decimal_precision as dp + class StockQuantPackage(models.Model): _inherit = "stock.quant.package" @@ -21,6 +22,27 @@ class StockQuantPackage(models.Model): self.weight = weight weight = fields.Float(compute='_compute_weight') + shipping_weight = fields.Float(string='Shipping Weight', help="Can be changed during the 'put in pack' to adjust the weight of the shipping.") + + +class StockPackOperation(models.Model): + _inherit = 'stock.pack.operation' + + @api.multi + def manage_package_type(self): + self.ensure_one() + return { + 'name': _('Package Details'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'stock.quant.package', + 'view_id': self.env.ref('delivery.view_quant_package_form_save').id, + 'target': 'new', + 'res_id': self.result_package_id.id, + 'context': { + 'current_package_carrier_type': self.picking_id.carrier_id.delivery_type if self.picking_id.carrier_id.delivery_type not in ['base_on_rule', 'fixed'] else 'none', + }, + } class StockPicking(models.Model): @@ -52,6 +74,11 @@ class StockPicking(models.Model): weight += uom_obj._compute_qty_obj(packop.product_uom_id , packop.product_qty, packop.product_id.uom_id) * packop.product_id.weight self.weight_bulk = weight + @api.one + @api.depends('package_ids', 'weight_bulk') + def _compute_shipping_weight(self): + self.shipping_weight = self.weight_bulk + sum([pack.shipping_weight for pack in self.package_ids]) + carrier_price = fields.Float(string="Shipping Cost", readonly=True) delivery_type = fields.Selection(related='carrier_id.delivery_type', readonly=True) carrier_id = fields.Many2one("delivery.carrier", string="Carrier") @@ -62,6 +89,7 @@ class StockPicking(models.Model): weight_uom_id = fields.Many2one('product.uom', string='Unit of Measure', required=True, readonly="1", help="Unit of measurement for Weight", default=_default_uom) 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') @api.depends('product_id', 'move_lines') def _cal_weight(self): @@ -81,6 +109,30 @@ class StockPicking(models.Model): return res + @api.multi + def put_in_pack(self): + self.ensure_one() + package_id = super(StockPicking, self).put_in_pack() + package = self.env['stock.quant.package'].browse(package_id) + + # By default, sum the weights of all package operations contained in this package + pack_operation_ids = self.env['stock.pack.operation'].search([('result_package_id', '=', package_id)]) + package_weight = sum([x.qty_done * x.product_id.weight for x in pack_operation_ids]) + package.shipping_weight = package_weight + + return { + 'name': _('Package Details'), + 'type': 'ir.actions.act_window', + 'view_mode': 'form', + 'res_model': 'stock.quant.package', + 'view_id': self.env.ref('delivery.view_quant_package_form_save').id, + 'target': 'new', + 'res_id': package_id, + 'context': { + 'current_package_carrier_type': self.carrier_id.delivery_type if self.carrier_id.delivery_type not in ['base_on_rule', 'fixed'] else 'none', + }, + } + @api.multi def send_to_shipper(self): self.ensure_one() @@ -115,6 +167,17 @@ class StockPicking(models.Model): self.message_post(body=msg) self.carrier_tracking_ref = False + @api.multi + def check_packages_are_identical(self): + '''Some shippers require identical packages in the same shipment. This utility checks it.''' + self.ensure_one() + if self.package_ids: + packages = [p.packaging_id for p in self.package_ids] + if len(set(packages)) != 1: + package_names = ', '.join([str(p.name) for p in packages]) + raise UserError(_('You are shipping different packaging types in the same shipment.\nPackaging Types: %s' % package_names)) + return True + class StockReturnPicking(models.TransientModel): _inherit = 'stock.return.picking' diff --git a/addons/delivery/views/delivery_view.xml b/addons/delivery/views/delivery_view.xml index 6b474b0989f..5ba8dde9665 100644 --- a/addons/delivery/views/delivery_view.xml +++ b/addons/delivery/views/delivery_view.xml @@ -166,6 +166,7 @@ + @@ -177,6 +178,9 @@