diff --git a/addons/delivery/models/delivery_carrier.py b/addons/delivery/models/delivery_carrier.py index 593ab9beb54..b8b6c29fddc 100644 --- a/addons/delivery/models/delivery_carrier.py +++ b/addons/delivery/models/delivery_carrier.py @@ -333,7 +333,7 @@ class DeliveryCarrier(models.Model): self.ensure_one() self = self.sudo() order = order.sudo() - total = weight = volume = quantity = 0 + total = weight = volume = quantity = wv = 0 total_delivery = 0.0 for line in order.order_line: if line.state == 'cancel': @@ -347,6 +347,7 @@ class DeliveryCarrier(models.Model): qty = line.product_uom._compute_quantity(line.product_uom_qty, line.product_id.uom_id) weight += (line.product_id.weight or 0.0) * qty volume += (line.product_id.volume or 0.0) * qty + wv += (line.product_id.weight or 0.0) * (line.product_id.volume or 0.0) * qty quantity += qty total = (order.amount_total or 0.0) - total_delivery @@ -356,23 +357,23 @@ class DeliveryCarrier(models.Model): # 2- saved weight to use on sale order # 3- total order line weight as fallback weight = self.env.context.get('order_weight') or order.shipping_weight or weight - return self._get_price_from_picking(total, weight, volume, quantity) + return self._get_price_from_picking(total, weight, volume, quantity, wv=wv) - def _get_price_dict(self, total, weight, volume, quantity): + def _get_price_dict(self, total, weight, volume, quantity, wv=0.): '''Hook allowing to retrieve dict to be used in _get_price_from_picking() function. Hook to be overridden when we need to add some field to product and use it in variable factor from price rules. ''' return { 'price': total, 'volume': volume, 'weight': weight, - 'wv': volume * weight, + 'wv': wv or volume * weight, 'quantity': quantity } - def _get_price_from_picking(self, total, weight, volume, quantity): + def _get_price_from_picking(self, total, weight, volume, quantity, wv=0.): price = 0.0 criteria_found = False - price_dict = self._get_price_dict(total, weight, volume, quantity) + price_dict = self._get_price_dict(total, weight, volume, quantity, wv=wv) if self.free_over and total >= self.amount: return 0 for line in self.price_rule_ids: diff --git a/addons/delivery/tests/test_delivery_cost.py b/addons/delivery/tests/test_delivery_cost.py index d64d92d635b..a5d2a7d4582 100644 --- a/addons/delivery/tests/test_delivery_cost.py +++ b/addons/delivery/tests/test_delivery_cost.py @@ -353,3 +353,41 @@ class TestDeliveryCost(common.TransactionCase): ('is_delivery', '=', True) ]) self.assertEqual(line.price_unit, self.normal_delivery.fixed_price) + + def test_price_with_weight_volume_variable(self): + """ Test that the price is correctly computed when the variable is weight*volume. """ + qty = 3 + list_price = 2 + volume = 2.5 + weight = 1.5 + sale_order = self.env['sale.order'].create({ + 'partner_id': self.partner_18.id, + 'order_line': [ + (0, 0, { + 'product_id': self.env['product.product'].create({ + 'name': 'wv', + 'weight': weight, + 'volume': volume, + }).id, + 'product_uom_qty': qty, + 'product_uom': self.product_uom_unit.id, + }), + ], + }) + delivery = self.env['delivery.carrier'].create({ + 'name': 'Delivery Charges', + 'delivery_type': 'base_on_rule', + 'product_id': self.product_delivery_normal.id, + 'price_rule_ids': [(0, 0, { + 'variable': 'price', + 'operator': '>=', + 'max_value': 0, + 'list_price': list_price, + 'variable_factor': 'wv', + })] + }) + self.assertEqual( + delivery._get_price_available(sale_order), + qty * list_price * weight * volume, + "The shipping price is not correctly computed with variable weight*volume.", + )