[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
This commit is contained in:
committed by
Richard Mathot
parent
e32f6bc950
commit
2ff3749064
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'),
|
||||
]
|
||||
@@ -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'
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
<field name="weight" class="oe_inline"/>
|
||||
<field name="weight_uom_id" nolabel="1" class="oe_inline"/>
|
||||
</div>
|
||||
<field name="shipping_weight"/>
|
||||
<field name="number_of_packages"/>
|
||||
</group>
|
||||
</group>
|
||||
@@ -177,6 +178,9 @@
|
||||
<xpath expr="/form/header/button[last()]" position="after">
|
||||
<button name="send_to_shipper" string="Send to Shipper" type="object" attrs="{'invisible':['|','|','|',('carrier_tracking_ref','!=',False),('delivery_type','in', ['fixed', 'base_on_rule']),('delivery_type','=',False),('state','not in',('done'))]}"/>
|
||||
</xpath>
|
||||
<field name="result_package_id" position="before">
|
||||
<button name="manage_package_type" string="Manage Package Type" type="object" icon="fa-dropbox" groups="stock.group_tracking_lot" attrs="{'invisible': [('result_package_id','=', False)]}"/>
|
||||
</field>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
@@ -199,10 +203,31 @@
|
||||
<field name="arch" type="xml">
|
||||
<field name="company_id" position="before">
|
||||
<field name="weight"/>
|
||||
<field name="shipping_weight"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="view_quant_package_form_save" model="ir.ui.view">
|
||||
<field name="name">stock.quant.package.form.save</field>
|
||||
<field name="model">stock.quant.package</field>
|
||||
<field eval="99" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Package">
|
||||
<group>
|
||||
<field name="packaging_id" domain="[('package_carrier_type', '=', context.get('current_package_carrier_type'))]"/>
|
||||
<field name="shipping_weight"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="write" type="object" string="Save" class="btn btn-sm btn-primary"/>
|
||||
<button string="Discard" special="cancel" class="btn btn-sm btn-default"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="view_move_withweight_form" model="ir.ui.view">
|
||||
<field name="name">stock.move.form.weight</field>
|
||||
<field name="model">stock.move</field>
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record model="ir.ui.view" id="delivery.product_packaging_delivery_form">
|
||||
<field name="name">product.packaging.form.delivery</field>
|
||||
<field name="model">product.packaging</field>
|
||||
<field name="inherit_id" ref="product.product_packaging_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="qty" position="after">
|
||||
<group name="delivery">
|
||||
<field name="package_carrier_type"/>
|
||||
<field name="height"/>
|
||||
<field name="width"/>
|
||||
<field name="length"/>
|
||||
<field name="max_weight"/>
|
||||
<field name="shipper_package_code" groups="base.group_no_one"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="delivery.product_packaging_delivery_tree">
|
||||
<field name="name">product.packaging.tree.delivery</field>
|
||||
<field name="model">product.packaging</field>
|
||||
<field name="inherit_id" ref="product.product_packaging_tree_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="qty" position="after">
|
||||
<field name="height"/>
|
||||
<field name="width"/>
|
||||
<field name="length"/>
|
||||
<field name="max_weight"/>
|
||||
<field name="package_carrier_type"/>
|
||||
<field name="shipper_package_code" groups="base.group_no_one"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -400,7 +400,7 @@
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to define a new product.
|
||||
</p><p>
|
||||
You must define a product for everything you sell, whether it's a physical product, a consumable or a service you offer to customers.
|
||||
You must define a product for everything you sell, whether it's a physical product, a consumable or a service you offer to customers.
|
||||
</p><p>
|
||||
The product form contains information to simplify the sale process: price, notes in the quotation, accounting data, procurement methods, etc.
|
||||
</p>
|
||||
@@ -754,7 +754,7 @@
|
||||
<field name="name"/>
|
||||
</h1>
|
||||
<group>
|
||||
<group>
|
||||
<group name="qty">
|
||||
<field name="qty"/>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
@@ -4188,7 +4188,7 @@ class stock_package(osv.osv):
|
||||
'complete_name': fields.function(_complete_name, type='char', string="Package Name",),
|
||||
'parent_left': fields.integer('Left Parent', select=1),
|
||||
'parent_right': fields.integer('Right Parent', select=1),
|
||||
'packaging_id': fields.many2one('product.packaging', 'Packaging', help="This field should be completed only if everything inside the package share the same product, otherwise it doesn't really makes sense.", select=True),
|
||||
'packaging_id': fields.many2one('product.packaging', 'Package Type', help="This field should be completed only if everything inside the package share the same product, otherwise it doesn't really makes sense.", select=True),
|
||||
'location_id': fields.function(_get_package_info, type='many2one', relation='stock.location', string='Location', multi="package",
|
||||
store={
|
||||
'stock.quant': (_get_packages, ['location_id'], 10),
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
sequence="100" groups="group_stock_manager,base.group_configuration"/>
|
||||
<menuitem id="menu_warehouse_config" name="Warehouse Management" parent="menu_stock_config_settings" groups="base.group_configuration" sequence="1"/>
|
||||
<menuitem id="menu_routes_config" name="Routes" parent="menu_stock_config_settings" sequence="2" groups="stock.group_adv_location"/>
|
||||
<menuitem id="menu_packages_config" name="Packages" parent="menu_stock_config_settings" sequence="3" groups="product.group_stock_packaging"/>
|
||||
<menuitem
|
||||
id="menu_product_in_config_stock" name="Products"
|
||||
parent="stock.menu_stock_config_settings" sequence="4"/>
|
||||
@@ -2165,9 +2166,9 @@
|
||||
</field>
|
||||
</record>
|
||||
<menuitem id="menu_package" name="Packages" parent="menu_stock_inventory_control" action="action_package_view" groups="stock.group_tracking_lot" sequence="102"/>
|
||||
<menuitem id="menu_packagings" name="Packagings" parent="stock.menu_warehouse_report" action="product.action_packaging_view" groups="product.group_stock_packaging" sequence="3"/>
|
||||
|
||||
|
||||
<menuitem id="menu_packagings" name="Package Types" parent="stock.menu_packages_config" action="product.action_packaging_view" groups="product.group_stock_packaging"/>
|
||||
|
||||
<!--Routes-->
|
||||
<record id="stock_location_route_tree" model="ir.ui.view">
|
||||
|
||||
Reference in New Issue
Block a user