diff --git a/product_sale_price_from_pricelist/i18n/es.po b/product_sale_price_from_pricelist/i18n/es.po index 272316f..002dd2c 100644 --- a/product_sale_price_from_pricelist/i18n/es.po +++ b/product_sale_price_from_pricelist/i18n/es.po @@ -17,6 +17,33 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 3.6\n" +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step +msgid "Sale Price Rounding Step" +msgstr "Redondeo del precio de venta" + +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step +msgid "Round the theoretical sale price (after taxes) to the nearest multiple of this value. Set to 0.00 to disable rounding (e.g. 0.05 rounds to the nearest 5 cents)." +msgstr "Redondea el precio de venta teórico (con impuestos) al múltiplo más cercano de este valor. Pon 0,00 para desactivar el redondeo (p. ej. 0,05 redondea al céntimo más cercano de 5)." + +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_product__configured_sale_margin +#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_template__configured_sale_margin +msgid "Configured sale margin (%)" +msgstr "Margen de venta configurado (%)" + +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_product__configured_sale_margin +#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_template__configured_sale_margin +msgid "Effective margin configured by the automatic pricelist chain for this product. It reflects tariff configuration, not the current manual sale price." +msgstr "Margen efectivo configurado por la cadena de tarifas automáticas para este producto. Refleja la configuración de tarifas, no el precio de venta manual actual." + +#. module: product_sale_price_from_pricelist +#: model_terms:ir.ui.view,arch_db:product_sale_price_from_pricelist.product_pricelist_view_price_rounding +msgid "Sale Price Rounding" +msgstr "Redondeo del precio de venta" + #. module: product_sale_price_from_pricelist #: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist_item__base msgid "" diff --git a/product_sale_price_from_pricelist/i18n/product_sale_price_from_pricelist.pot b/product_sale_price_from_pricelist/i18n/product_sale_price_from_pricelist.pot index 4875e43..b5019fc 100644 --- a/product_sale_price_from_pricelist/i18n/product_sale_price_from_pricelist.pot +++ b/product_sale_price_from_pricelist/i18n/product_sale_price_from_pricelist.pot @@ -15,6 +15,33 @@ msgstr "" "Content-Transfer-Encoding: \n" "Plural-Forms: \n" +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step +msgid "Sale Price Rounding Step" +msgstr "" + +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist__price_rounding_step +msgid "Round the theoretical sale price (after taxes) to the nearest multiple of this value. Set to 0.00 to disable rounding (e.g. 0.05 rounds to the nearest 5 cents)." +msgstr "" + +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_product__configured_sale_margin +#: model:ir.model.fields,field_description:product_sale_price_from_pricelist.field_product_template__configured_sale_margin +msgid "Configured sale margin (%)" +msgstr "" + +#. module: product_sale_price_from_pricelist +#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_product__configured_sale_margin +#: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_template__configured_sale_margin +msgid "Effective margin configured by the automatic pricelist chain for this product. It reflects tariff configuration, not the current manual sale price." +msgstr "" + +#. module: product_sale_price_from_pricelist +#: model_terms:ir.ui.view,arch_db:product_sale_price_from_pricelist.product_pricelist_view_price_rounding +msgid "Sale Price Rounding" +msgstr "" + #. module: product_sale_price_from_pricelist #: model:ir.model.fields,help:product_sale_price_from_pricelist.field_product_pricelist_item__base msgid "" diff --git a/product_sale_price_from_pricelist/models/product_pricelist.py b/product_sale_price_from_pricelist/models/product_pricelist.py index 72400e4..1442d6b 100644 --- a/product_sale_price_from_pricelist/models/product_pricelist.py +++ b/product_sale_price_from_pricelist/models/product_pricelist.py @@ -4,7 +4,7 @@ # import logging -from odoo import api, models +from odoo import api, fields, models # _logger = logging.getLogger(__name__) @@ -12,6 +12,14 @@ from odoo import api, models class ProductPricelist(models.Model): _inherit = "product.pricelist" + price_rounding_step = fields.Float( + string="Sale Price Rounding Step", + digits=(12, 2), + default=0.0, + help="Round the theoretical sale price (after taxes) to the nearest multiple of this value. " + "Set to 0.00 to disable rounding (e.g. 0.05 rounds to the nearest 5 cents).", + ) + def _compute_price_rule(self, products, qty, uom=None, date=False, **kwargs): ProductPricelistItem = self.env["product.pricelist.item"] ProductProduct = self.env["product.product"] diff --git a/product_sale_price_from_pricelist/models/product_template.py b/product_sale_price_from_pricelist/models/product_template.py index ad79bd0..49c10a7 100644 --- a/product_sale_price_from_pricelist/models/product_template.py +++ b/product_sale_price_from_pricelist/models/product_template.py @@ -45,6 +45,51 @@ class ProductTemplate(models.Model): required=True, company_dependent=True, ) + configured_sale_margin = fields.Float( + string="Configured sale margin (%)", + digits="Discount", + compute="_compute_configured_sale_margin", + help="Effective margin configured by the automatic pricelist chain for " + "this product. It reflects tariff configuration, not the current " + "manual sale price.", + ) + + def _compute_configured_sale_margin(self): + pricelist_id = ( + self.env["ir.config_parameter"] + .sudo() + .get_param("product_sale_price_from_pricelist.product_pricelist_automatic") + or False + ) + if not pricelist_id: + for template in self: + template.configured_sale_margin = 0.0 + return + + pricelist = self.env["product.pricelist"].browse(int(pricelist_id)) + for template in self: + template.configured_sale_margin = 0.0 + if ( + not template.product_variant_id + or template.last_purchase_price_compute_type == "manual_update" + or not template.last_purchase_price_received + ): + continue + + # Get the final untaxed price after all chained pricelists are applied. + final_price = template.product_variant_id._get_price( + qty=1, + pricelist=pricelist, + ) + untaxed_price = final_price.get(template.product_variant_id.id, {}).get( + "value" + ) + if untaxed_price is None: + continue + + template.configured_sale_margin = ( + (untaxed_price / template.last_purchase_price_received) - 1.0 + ) * 100.0 def _compute_theoritical_price(self): pricelist_obj = self.env["product.pricelist"] @@ -82,9 +127,10 @@ class ProductTemplate(models.Model): tax_price["taxes"][0]["amount"] + partial_price[template.product_variant_id.id]["value"] ) - # Round to 0.05 - if round(price_with_taxes % 0.05, 2) != 0: - price_with_taxes = round(price_with_taxes * 20) / 20 + # Round to configurable step (defined on the pricelist) + step = pricelist.price_rounding_step + if step: + price_with_taxes = math.ceil(price_with_taxes / step) * step template.write( { diff --git a/product_sale_price_from_pricelist/views/product_view.xml b/product_sale_price_from_pricelist/views/product_view.xml index eca9ce8..9a59924 100644 --- a/product_sale_price_from_pricelist/views/product_view.xml +++ b/product_sale_price_from_pricelist/views/product_view.xml @@ -23,6 +23,7 @@ readonly="1" /> + @@ -40,6 +41,19 @@ + + product.pricelist.view.price.rounding + product.pricelist + + + + + + + + + + product.print.supermarket.res.config.settings.form res.config.settings