diff --git a/shopinvader_product/README.rst b/shopinvader_product/README.rst index bdef789aad..3069002f90 100644 --- a/shopinvader_product/README.rst +++ b/shopinvader_product/README.rst @@ -7,7 +7,7 @@ Shopinvader Product !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:108725a6e1659f18f04423fb53395d547a639cda223fa0765860ff9f87867519 + !! source digest: sha256:323ae4391f7ab00feeca0e747db58cf8bb8f1a62924e577cec901128dc1bd8ea !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -25,6 +25,9 @@ Shopinvader Product This addon makes products (and categories) suitable for shopinvader. Adding revelant fields and pydantic schemas for serialization. +To serialize product prices, you'll need an extra addon like +``shopinvader_search_engine_product_price`` + .. IMPORTANT:: This is an alpha version, the data model and design can change at any time without warning. Only for development or testing purpose, do not use in production. diff --git a/shopinvader_product/models/product_product.py b/shopinvader_product/models/product_product.py index d72b16f4a7..75170925af 100644 --- a/shopinvader_product/models/product_product.py +++ b/shopinvader_product/models/product_product.py @@ -5,11 +5,9 @@ from itertools import groupby from odoo import api, fields, models -from odoo.tools import float_compare, float_is_zero from odoo.addons.base_sparse_field.models.fields import Serialized -from ..utils import float_round from .tools import sanitize_attr_name @@ -27,7 +25,6 @@ class ProductProduct(models.Model): short_name = fields.Char(compute="_compute_names") full_name = fields.Char(compute="_compute_names") main = fields.Boolean(compute="_compute_main_product") - price = Serialized(compute="_compute_price", string="Shopinvader Price") def _compute_variant_attributes(self): for record in self: @@ -99,115 +96,3 @@ def get_value(record, key): } for record in self: record.main = main_by_product.get(record.product_tmpl_id.id) == record.id - - @api.depends_context("pricelist", "default_role", "fposition", "company", "date") - def _compute_price(self): - for record in self: - record.price = record._get_all_price() - - def _get_all_price(self): - self.ensure_one() - res = {} - pricelist = self._context.get("pricelist") - default_role = self._context.get("default_role", "default") - if pricelist: - fposition = self._context.get("fposition") - company = self._context.get("company") - date = self._context.get("date") - res[default_role] = self._get_price( - pricelist=pricelist, fposition=fposition, company=company, date=date - ) - return res - - def _get_price( - self, qty=1.0, pricelist=None, fposition=None, company=None, date=None - ): - """Computes the product prices - - :param qty: The product quantity, used to apply pricelist rules. - :param pricelist: Optional. Get prices for a specific pricelist. - :param fposition: Optional. Apply fiscal position to product taxes. - :param company: Optional. - :param date: Optional. - - :returns: dict with the following keys: - - The product unitary price - True if product taxes are included in . - - If the pricelist.discount_policy is "without_discount": - The original price (before pricelist is applied). - The discounted percentage. - """ - self.ensure_one() - AccountTax = self.env["account.tax"] - product = self.record_id - # Apply company - product = product.with_company(company) if company else product - company = company or self.env.company - # Always filter taxes by the company - taxes = product.taxes_id.filtered(lambda tax: tax.company_id == company) - # Apply fiscal position - taxes = fposition.map_tax(taxes) if fposition else taxes - # Set context. Some of the methods used here depend on these values - product_context = dict( - self.env.context, - quantity=qty, - pricelist=pricelist.id if pricelist else None, - fiscal_position=fposition, - date=date, - ) - product = product.with_context(**product_context) - pricelist = pricelist.with_context(**product_context) if pricelist else None - price_unit = ( - pricelist._get_product_price(product, qty, date=date) - if pricelist - else product.lst_price - ) - price_unit = AccountTax._fix_tax_included_price_company( - price_unit, product.taxes_id, taxes, company - ) - price_dp = self.env["decimal.precision"].precision_get("Product Price") - price_unit = float_round(price_unit, price_dp) - res = { - "value": price_unit, - "tax_included": any(tax.price_include for tax in taxes), - # Default values in case price.discount_policy != "without_discount" - "original_value": price_unit, - "discount": 0.0, - } - # Handle pricelists.discount_policy == "without_discount" - if pricelist and pricelist.discount_policy == "without_discount": - # Get the price rule - price_unit, rule_id = pricelist._get_product_price_rule( - product, qty, date=date - ) - # Get the price before applying the pricelist - original_price_unit = product.lst_price - price_dp = self.env["decimal.precision"].precision_get("Product Price") - # Compute discount - if not float_is_zero( - original_price_unit, precision_digits=price_dp - ) and float_compare( - original_price_unit, price_unit, precision_digits=price_dp - ): - discount = ( - (original_price_unit - price_unit) / original_price_unit * 100 - ) - # Apply the right precision on discount - discount_dp = self.env["decimal.precision"].precision_get("Discount") - discount = float_round(discount, discount_dp) - else: - discount = 0.00 - # Compute prices - original_price_unit = AccountTax._fix_tax_included_price_company( - original_price_unit, product.taxes_id, taxes, company - ) - original_price_unit = float_round(original_price_unit, price_dp) - res.update( - { - "original_value": original_price_unit, - "discount": discount, - } - ) - return res diff --git a/shopinvader_product/readme/DESCRIPTION.rst b/shopinvader_product/readme/DESCRIPTION.rst index d0bfea6130..b88e531d7d 100644 --- a/shopinvader_product/readme/DESCRIPTION.rst +++ b/shopinvader_product/readme/DESCRIPTION.rst @@ -1,2 +1,5 @@ This addon makes products (and categories) suitable for shopinvader. Adding revelant fields and pydantic schemas for serialization. + +To serialize product prices, you'll need an extra addon like +``shopinvader_search_engine_product_price`` \ No newline at end of file diff --git a/shopinvader_product/schemas/__init__.py b/shopinvader_product/schemas/__init__.py index b1e73e7f28..2c9eb45e0d 100644 --- a/shopinvader_product/schemas/__init__.py +++ b/shopinvader_product/schemas/__init__.py @@ -1,2 +1,2 @@ from .category import ProductCategory, ShortProductCategory -from .product import ProductProduct, ProductTemplate, ProductTemplatePriceInfo +from .product import ProductProduct, ProductTemplate diff --git a/shopinvader_product/schemas/product.py b/shopinvader_product/schemas/product.py index 2b64777fe6..101ee5d549 100644 --- a/shopinvader_product/schemas/product.py +++ b/shopinvader_product/schemas/product.py @@ -16,13 +16,6 @@ def from_product_template(cls, odoo_rec): return cls.model_construct(name=odoo_rec.display_name) -class ProductTemplatePriceInfo(StrictExtendableBaseModel): - value: float = 0 - tax_included: bool = False - original_value: float = 0 - discount: float = 0 - - class ProductProduct(StrictExtendableBaseModel): id: int model: ProductTemplate @@ -33,7 +26,6 @@ class ProductProduct(StrictExtendableBaseModel): categories: list[ShortProductCategory] = [] sku: str | None = None variant_attributes: dict[str, Any] = {} - price: dict[str, ProductTemplatePriceInfo] = {} @classmethod def from_product_product(cls, odoo_rec): @@ -52,5 +44,4 @@ def from_product_product(cls, odoo_rec): ], sku=odoo_rec.default_code or None, variant_attributes=odoo_rec.variant_attributes, - price=odoo_rec.price, ) diff --git a/shopinvader_product/static/description/index.html b/shopinvader_product/static/description/index.html index ec03c593b3..c4c338046e 100644 --- a/shopinvader_product/static/description/index.html +++ b/shopinvader_product/static/description/index.html @@ -367,11 +367,13 @@

Shopinvader Product

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:108725a6e1659f18f04423fb53395d547a639cda223fa0765860ff9f87867519 +!! source digest: sha256:323ae4391f7ab00feeca0e747db58cf8bb8f1a62924e577cec901128dc1bd8ea !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Alpha License: AGPL-3 shopinvader/odoo-shopinvader

This addon makes products (and categories) suitable for shopinvader. Adding revelant fields and pydantic schemas for serialization.

+

To serialize product prices, you’ll need an extra addon like +shopinvader_search_engine_product_price

Important

This is an alpha version, the data model and design can change at any time without warning. diff --git a/shopinvader_product/utils.py b/shopinvader_product/utils.py deleted file mode 100644 index a842a47855..0000000000 --- a/shopinvader_product/utils.py +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright 2021 Camptocamp (http://www.camptocamp.com). -# @author Simone Orsi -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo.tools import float_repr - - -def float_round(value, dp): - # be carefull odoo rounding implementation do not return the shortest - # representation of a float this mean if the price_unit is 211.70 - # you will have 211.70000000000002 - # See issue: https://github.com/shopinvader/odoo-shopinvader/issues/1041 - # Odony exemple: https://gist.github.com/odony/5269a695545902e7e23e761e20a9ec8c - return float(float_repr(value, dp)) diff --git a/shopinvader_search_engine/tests/test_product_binding.py b/shopinvader_search_engine/tests/test_product_binding.py index b626aa8e54..598d36ee37 100644 --- a/shopinvader_search_engine/tests/test_product_binding.py +++ b/shopinvader_search_engine/tests/test_product_binding.py @@ -15,7 +15,6 @@ def test_serialize(self): self.assertEqual(data["variant_count"], 2) self.assertEqual(data["sku"], "VORCHAIR-001") self.assertEqual(data["variant_attributes"], {"color": "blue"}) - self.assertEqual(data["price"], {}) def test_main_variant_index(self): variants = self.product.product_tmpl_id.product_variant_ids