[FIX] delivery: fix price when variable is weight*volume
Before this commit, when using a shipping method with the variable weight*volume for price computation, the price was growing with the square of the ordered quantities. This is because both volume and weight were multiplied by the quantity, before being multiplied with each other in the next step. This commit fixes the issue by introducing the variable weight*volume at the beginning of the computation. In order not to break anything in stable, the new variable is added as a kwarg to the useful methods. OPW-3802315 closes odoo/odoo#159007 X-original-commit: 0a8db0fa14bb63abd0b2a8f0234d86700b6c1e2e Signed-off-by: Vallaeys Valentin (vava) <vava@odoo.com>
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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.",
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user