[RFC]pms: refactor get price product in services

This commit is contained in:
Darío Lodeiros
2022-06-22 17:24:48 +02:00
parent 27d875042e
commit 5bb8872464
2 changed files with 119 additions and 85 deletions

View File

@@ -474,91 +474,13 @@ class PmsService(models.Model):
folio = self.folio_id
reservation = self.reservation_id
origin = folio if folio else reservation
if origin.pricelist_id.discount_policy == "with_discount":
return product.price
final_price, rule_id = origin.pricelist_id.with_context(
product._context
).get_product_price_rule(product, self.product_qty or 1.0, origin.partner_id)
base_price, currency_id = self.with_context(
product._context
)._get_real_price_currency(
product,
rule_id,
self.product_qty,
self.product_id.uom_id,
origin.pricelist_id.id,
return self.env["product.product"]._pms_display_price(
pricelist_id=origin.pricelist_id.id,
product_id=product.id,
company_id=origin.company_id.id,
product_qty=self.product_qty or 1.0,
partner_id=origin.partner_id.id if origin.partner_id else False,
)
if currency_id != origin.pricelist_id.currency_id.id:
base_price = (
self.env["res.currency"]
.browse(currency_id)
.with_context(product._context)
.compute(base_price, origin.pricelist_id.currency_id)
)
# negative discounts (= surcharge) are included in the display price
return max(base_price, final_price)
def _get_real_price_currency(self, product, rule_id, qty, uom, pricelist_id):
"""Retrieve the price before applying the pricelist
:param obj product: object of current product record
:parem float qty: total quantity of product
:param tuple price_and_rule: tuple(price, suitable_rule)
coming from pricelist computation
:param obj uom: unit of measure of current order line
:param integer pricelist_id: pricelist id of sales order"""
PricelistItem = self.env["product.pricelist.item"]
field_name = "lst_price"
currency_id = None
product_currency = product.currency_id
if rule_id:
pricelist_item = PricelistItem.browse(rule_id)
if pricelist_item.pricelist_id.discount_policy == "without_discount":
while (
pricelist_item.base == "pricelist"
and pricelist_item.base_pricelist_id
and pricelist_item.base_pricelist_id.discount_policy
== "without_discount"
):
price, rule_id = pricelist_item.base_pricelist_id.with_context(
uom=uom.id
).get_product_price_rule(product, qty, self.order_id.partner_id)
pricelist_item = PricelistItem.browse(rule_id)
if pricelist_item.base == "standard_price":
field_name = "standard_price"
product_currency = product.cost_currency_id
elif (
pricelist_item.base == "pricelist" and pricelist_item.base_pricelist_id
):
field_name = "price"
product = product.with_context(
pricelist=pricelist_item.base_pricelist_id.id
)
product_currency = pricelist_item.base_pricelist_id.currency_id
currency_id = pricelist_item.pricelist_id.currency_id
if not currency_id:
currency_id = product_currency
cur_factor = 1.0
else:
if currency_id.id == product_currency.id:
cur_factor = 1.0
else:
cur_factor = currency_id._get_conversion_rate(
product_currency,
currency_id,
self.company_id or self.env.company,
self.folio_id.date_order or fields.Date.today(),
)
product_uom = self.env.context.get("uom") or product.uom_id.id
if uom and uom.id != product_uom:
# the unit price is in a different uom
uom_factor = uom._compute_price(1.0, product.uom_id)
else:
uom_factor = 1.0
return product[field_name] * uom_factor * cur_factor, currency_id
# Businness Methods
def _service_day_qty(self):
@@ -602,7 +524,13 @@ class PmsService(models.Model):
] = reservation.board_service_room_id.id
product = self.product_id.with_context(product_context)
return self.env["account.tax"]._fix_tax_included_price_company(
self._get_display_price(product),
self.env["product.product"]._pms_get_display_price(
pricelist_id=pricelist.id,
product=product,
company_id=origin.company_id.id,
product_qty=self.product_qty,
partner_id=partner.id,
),
product.taxes_id,
self.tax_ids,
origin.company_id,

View File

@@ -64,3 +64,109 @@ class ProductProduct(models.Model):
return super(ProductProduct, self).price_compute(
price_type, uom, currency, company
)
@api.model
def _pms_get_display_price(
self, pricelist_id, product, company_id, product_qty=1, partner_id=False
):
pricelist = self.env["product.pricelist"].browse(pricelist_id)
partner = self.env["res.partner"].browse(partner_id) if partner_id else False
if pricelist.discount_policy == "with_discount":
return product.price
final_price, rule_id = pricelist.with_context(
product._context
).get_product_price_rule(product, product_qty or 1.0, partner)
base_price, currency_id = self.with_context(
product._context
)._pms_get_real_price_currency(
product,
rule_id,
product_qty,
product.uom_id,
pricelist.id,
company_id,
partner_id,
)
if currency_id != pricelist.currency_id.id:
base_price = (
self.env["res.currency"]
.browse(currency_id)
.with_context(product._context)
.compute(base_price, pricelist.currency_id)
)
# negative discounts (= surcharge) are included in the display price
return max(base_price, final_price)
@api.model
def _pms_get_real_price_currency(
self,
product,
rule_id,
qty,
uom,
pricelist_id,
company_id=False,
partner_id=False,
):
"""Retrieve the price before applying the pricelist
:param obj product: object of current product record
:parem float qty: total quantity of product
:param tuple price_and_rule: tuple(price, suitable_rule)
coming from pricelist computation
:param obj uom: unit of measure of current order line
:param integer pricelist_id: pricelist id of sales order"""
PricelistItem = self.env["product.pricelist.item"]
field_name = "lst_price"
currency_id = None
product_currency = product.currency_id
company = self.env["res.company"].browse(company_id) if company_id else False
partner = self.env["res.partner"].browse(partner_id) if partner_id else False
if rule_id:
pricelist_item = PricelistItem.browse(rule_id)
if pricelist_item.pricelist_id.discount_policy == "without_discount":
while (
pricelist_item.base == "pricelist"
and pricelist_item.base_pricelist_id
and pricelist_item.base_pricelist_id.discount_policy
== "without_discount"
):
price, rule_id = pricelist_item.base_pricelist_id.with_context(
uom=uom.id
).get_product_price_rule(product, qty, partner)
pricelist_item = PricelistItem.browse(rule_id)
if pricelist_item.base == "standard_price":
field_name = "standard_price"
product_currency = product.cost_currency_id
elif (
pricelist_item.base == "pricelist" and pricelist_item.base_pricelist_id
):
field_name = "price"
product = product.with_context(
pricelist=pricelist_item.base_pricelist_id.id
)
product_currency = pricelist_item.base_pricelist_id.currency_id
currency_id = pricelist_item.pricelist_id.currency_id
if not currency_id:
currency_id = product_currency
cur_factor = 1.0
else:
if currency_id.id == product_currency.id:
cur_factor = 1.0
else:
cur_factor = currency_id._get_conversion_rate(
product_currency,
currency_id,
company,
fields.Date.today(),
)
product_uom = self.env.context.get("uom") or product.uom_id.id
if uom and uom.id != product_uom:
# the unit price is in a different uom
uom_factor = uom._compute_price(1.0, product.uom_id)
else:
uom_factor = 1.0
return product[field_name] * uom_factor * cur_factor, currency_id