[FIX] sale_margin: purchase_price performance.

When installing sale_margin, the computed fields will be computed on existing
sale.order and sale.order.line in database.  On huge databases, the computation
may take a lot of time, depending on the configuration (multi-company, multi-currency, ...)

The current commit improves the computation of the purchase_price
(recently changed to a computed field), by avoiding unnecessary currency
conversions when possible (one less query to get the conversion rates).

In a multi-currency database where the products have no cost defined
(standard_price field), the sale_margin installation takes up to 50% less time.

closes odoo/odoo#52338

X-original-commit: 3c9841d1aa4fc5b10012c8239a31d6e7f8676fc0
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
Victor Feyens
2020-06-03 10:36:18 +00:00
parent 72087777ac
commit 8a48aee8eb
+8 -2
View File
@@ -25,6 +25,12 @@ class SaleOrderLine(models.Model):
line = line.with_company(line.company_id)
product = line.product_id
product_cost = product.standard_price
if not product_cost:
# If the standard_price is 0
# Avoid unnecessary computations
# and currency conversions
line.purchase_price = 0.0
continue
fro_cur = product.cost_currency_id
to_cur = line.currency_id or line.order_id.currency_id
if line.product_uom and line.product_uom != product.uom_id:
@@ -38,7 +44,7 @@ class SaleOrderLine(models.Model):
company=line.company_id or self.env.company,
date=line.order_id.date_order or fields.Date.today(),
round=False,
) if to_cur else product_cost
) if to_cur and product_cost else product_cost
# The pricelist may not have been set, therefore no conversion
# is needed because we don't know the target currency..
@@ -46,7 +52,7 @@ class SaleOrderLine(models.Model):
def _compute_margin(self):
for line in self:
line.margin = line.price_subtotal - (line.purchase_price * line.product_uom_qty)
line.margin_percent = line.price_subtotal and line.margin/line.price_subtotal
line.margin_percent = line.price_subtotal and line.margin/line.price_subtotal
class SaleOrder(models.Model):