[IMP] product,sale: extract computation of price before discount

So that we can in the future harmonize more easily the discount
computation between sale, point_of_sale, e-commerce, ...

closes odoo/odoo#123849

Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
Victor Feyens
2023-06-06 13:10:31 +02:00
parent d9679cafe0
commit 4e6db76aba
2 changed files with 47 additions and 39 deletions
@@ -403,19 +403,19 @@ class PricelistItem(models.Model):
return price
def _compute_base_price(self, product, quantity, uom, date, target_currency):
def _compute_base_price(self, product, quantity, uom, date, currency):
""" Compute the base price for a given rule
:param product: recordset of product (product.product/product.template)
:param float qty: quantity of products requested (in given uom)
:param uom: unit of measure (uom.uom record)
:param datetime date: date to use for price computation and currency conversions
:param target_currency: pricelist currency
:param currency: currency in which the returned price must be expressed
:returns: base price, expressed in provided pricelist currency
:rtype: float
"""
target_currency.ensure_one()
currency.ensure_one()
rule_base = self.base or 'list_price'
if rule_base == 'pricelist' and self.base_pricelist_id:
@@ -430,7 +430,36 @@ class PricelistItem(models.Model):
src_currency = product.currency_id
price = product._price_compute(rule_base, uom=uom, date=date)[product.id]
if src_currency != target_currency:
price = src_currency._convert(price, target_currency, self.env.company, date, round=False)
if src_currency != currency:
price = src_currency._convert(price, currency, self.env.company, date, round=False)
return price
def _compute_price_before_discount(self, *args, **kwargs):
"""Compute the base price of the lowest pricelist rule whose pricelist discount_policy
is set to show the discount to the customer.
:param product: recordset of product (product.product/product.template)
:param float qty: quantity of products requested (in given uom)
:param uom: unit of measure (uom.uom record)
:param datetime date: date to use for price computation and currency conversions
:param currency: currency in which the returned price must be expressed
:returns: base price, expressed in provided pricelist currency
:rtype: float
"""
pricelist_rule = self
if pricelist_rule and pricelist_rule.pricelist_id.discount_policy == 'without_discount':
pricelist_item = pricelist_rule
# Find the lowest pricelist rule whose pricelist is configured to show the discount
# to the customer.
while (
pricelist_item.base == 'pricelist'
and pricelist_item.base_pricelist_id.discount_policy == 'without_discount'
):
rule_id = pricelist_item.base_pricelist_id._get_product_rule(*args, **kwargs)
pricelist_item = self.env['product.pricelist.item'].browse(rule_id)
pricelist_rule = pricelist_item
return pricelist_rule._compute_base_price(*args, **kwargs)
+13 -34
View File
@@ -476,14 +476,13 @@ class SaleOrderLine(models.Model):
self.ensure_one()
self.product_id.ensure_one()
pricelist_rule = self.pricelist_item_id
order_date = self.order_id.date_order or fields.Date.today()
product = self.product_id.with_context(**self._get_product_price_context())
quantity = self.product_uom_qty or 1.0
uom = self.product_uom or self.product_id.uom_id
price = pricelist_rule._compute_price(
product, quantity, uom, order_date, currency=self.currency_id)
price = self.pricelist_item_id._compute_price(
product=self.product_id.with_context(**self._get_product_price_context()),
quantity=self.product_uom_qty or 1.0,
uom=self.product_uom,
date=self.order_id.date_order,
currency=self.currency_id,
)
return price
@@ -507,34 +506,14 @@ class SaleOrderLine(models.Model):
self.ensure_one()
self.product_id.ensure_one()
pricelist_rule = self.pricelist_item_id
order_date = self.order_id.date_order or fields.Date.today()
product = self.product_id.with_context(**self._get_product_price_context())
quantity = self.product_uom_qty or 1.0
uom = self.product_uom
if pricelist_rule:
pricelist_item = pricelist_rule
if pricelist_item.pricelist_id.discount_policy == 'without_discount':
# Find the lowest pricelist rule whose pricelist is configured
# to show the discount to the customer.
while pricelist_item.base == 'pricelist' and pricelist_item.base_pricelist_id.discount_policy == 'without_discount':
rule_id = pricelist_item.base_pricelist_id._get_product_rule(
product, quantity, currency=self.currency_id, uom=uom, date=order_date)
pricelist_item = self.env['product.pricelist.item'].browse(rule_id)
pricelist_rule = pricelist_item
price = pricelist_rule._compute_base_price(
product,
quantity,
uom,
order_date,
target_currency=self.currency_id,
return self.pricelist_item_id._compute_price_before_discount(
product=self.product_id.with_context(**self._get_product_price_context()),
quantity=self.product_uom_qty or 1.0,
uom=self.product_uom,
date=self.order_id.date_order,
currency=self.currency_id,
)
return price
@api.depends('product_id', 'product_uom', 'product_uom_qty')
def _compute_discount(self):
for line in self: