From cc666bcf43f024287aef97c4041dc94b010201db Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Wed, 7 Sep 2022 16:36:13 +0000 Subject: [PATCH] [IMP] delivery_hibou: weight or volumetric package selection --- delivery_hibou/models/delivery.py | 33 ++++++++++++- delivery_hibou/models/stock.py | 12 +++++ delivery_hibou/tests/test_delivery_hibou.py | 55 +++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/delivery_hibou/models/delivery.py b/delivery_hibou/models/delivery.py index c604c02a..fd6fb9e7 100644 --- a/delivery_hibou/models/delivery.py +++ b/delivery_hibou/models/delivery.py @@ -17,9 +17,40 @@ class DeliveryCarrier(models.Model): string='Procurement Priority', help='Priority for this carrier. Will affect pickings ' 'and procurements related to this carrier.') + package_by_field = fields.Selection([ + ('', 'Use Default Package Type'), + ('weight', 'Weight'), + ('volume', 'Volume'), + ], string='Packaging by Product Field') + + # Package selection + def get_package_type_for_order(self, order): + if self.package_by_field == 'weight': + return self._get_package_type_for_order(order, 'max_weight', 'weight') + elif self.package_by_field == 'volume': + return self._get_package_type_for_order(order, 'package_volume', 'volume') + attr = getattr(self, '%s_default_packaging_id' % (self.delivery_type, ), None) + if attr: + return attr() + attr = getattr(self, '%s_default_package_type_id' % (self.delivery_type, ), None) + if attr: + return attr() + return self.env['stock.package.type'] + + def _get_package_type_for_order(self, order, package_type_field, product_field): + order_total = sum(order.order_line.filtered(lambda ol: ol.product_id.type in ('product', 'consu')).mapped(lambda ol: ol.product_id[product_field] * ol.product_uom_qty)) + if order_total: + package_types = self.env['stock.package.type'].search([ + ('package_carrier_type', 'in', ('none', False, self.delivery_type)), + ('use_in_package_selection', '=', True), + ], order=package_type_field) + package_type = None + for package_type in package_types: + if package_type[package_type_field] >= order_total: + return package_type + return package_types if not package_type else package_type # Utility - def get_insurance_value(self, order=None, picking=None, package=None): value = 0.0 if order: diff --git a/delivery_hibou/models/stock.py b/delivery_hibou/models/stock.py index 050a7f03..b045dc4b 100644 --- a/delivery_hibou/models/stock.py +++ b/delivery_hibou/models/stock.py @@ -2,6 +2,18 @@ from odoo import api, fields, models, _ from odoo.exceptions import UserError +class StockPackageType(models.Model): + _inherit = 'stock.package.type' + + use_in_package_selection = fields.Boolean() + package_volume = fields.Float(compute='_compute_package_volume', store=True) + + @api.depends('packaging_length', 'width', 'height') + def _compute_package_volume(self): + for pt in self: + pt.package_volume = pt.packaging_length * pt.width * pt.height + + class StockQuantPackage(models.Model): _inherit = 'stock.quant.package' diff --git a/delivery_hibou/tests/test_delivery_hibou.py b/delivery_hibou/tests/test_delivery_hibou.py index 1dd9aa99..43d1de71 100644 --- a/delivery_hibou/tests/test_delivery_hibou.py +++ b/delivery_hibou/tests/test_delivery_hibou.py @@ -7,6 +7,11 @@ class TestDeliveryHibou(common.TransactionCase): super(TestDeliveryHibou, self).setUp() self.partner = self.env.ref('base.res_partner_address_13') self.product = self.env.ref('product.product_product_7') + self.product.write({ + 'type': 'product', + 'weight': 1.0, + 'volume': 15.0, + }) # Create Shipping Account self.shipping_account = self.env['partner.shipping.account'].create({ 'name': '123123', @@ -20,6 +25,26 @@ class TestDeliveryHibou(common.TransactionCase): self.carrier = self.env['delivery.carrier'].create({ 'name': 'Test Carrier1', 'product_id': self.delivery_product.id, + 'delivery_type': 'fixed', + }) + # update all other package types to have + self.package_type_large = self.env['stock.package.type'].create({ + 'name': 'Large 15x15x15', + 'packaging_length': 15.0, + 'height': 15.0, + 'width': 15.0, + 'max_weight': 50.0, + 'package_carrier_type': 'none', + 'use_in_package_selection': True, + }) + self.package_type_small = self.env['stock.package.type'].create({ + 'name': 'Small 2x2x4', + 'packaging_length': 4.0, + 'height': 2.0, + 'width': 2.0, + 'max_weight': 1.0, + 'package_carrier_type': 'none', + 'use_in_package_selection': True, }) def test_delivery_hibou(self): @@ -40,6 +65,7 @@ class TestDeliveryHibou(common.TransactionCase): 'shipping_account_id': self.shipping_account.id, 'order_line': [(0, 0, { 'product_id': self.product.id, + 'product_uom_qty': 2.0, })] }) self.assertFalse(sale_order.carrier_id) @@ -62,6 +88,35 @@ class TestDeliveryHibou(common.TransactionCase): self.assertEqual(sale_order.picking_ids.shipping_account_id, self.shipping_account) self.assertEqual(sale_order.carrier_id.get_third_party_account(order=sale_order), self.shipping_account) + # Test Package selection + default_package_type = sale_order.carrier_id.get_package_type_for_order(sale_order) + self.assertFalse(default_package_type, 'Fixed should not have a default packaging type.') + + # by product weight + sale_order.carrier_id.package_by_field = 'weight' + + default_package_type = sale_order.carrier_id.get_package_type_for_order(sale_order) + self.assertTrue(default_package_type) + self.assertEqual(default_package_type, self.package_type_large) + + # change qty ordered to try to get the small package type + sale_order.order_line.write({ + 'product_uom_qty': 1.0, + }) + default_package_type = sale_order.carrier_id.get_package_type_for_order(sale_order) + self.assertEqual(default_package_type, self.package_type_small) + + # by product volume + sale_order.carrier_id.package_by_field = 'volume' + default_package_type = sale_order.carrier_id.get_package_type_for_order(sale_order) + self.assertEqual(default_package_type, self.package_type_small) + + sale_order.order_line.write({ + 'product_uom_qty': 2.0, + }) + default_package_type = sale_order.carrier_id.get_package_type_for_order(sale_order) + self.assertEqual(default_package_type, self.package_type_large) + # Test attn test_ref = 'TEST100' self.assertEqual(sale_order.carrier_id.get_attn(order=sale_order), False)