From f586c99df9de4d6df353b0005f4fac0ec8687e2d Mon Sep 17 00:00:00 2001 From: luis Date: Thu, 2 Apr 2026 12:43:36 +0200 Subject: [PATCH 1/3] add purchase_price_review_status --- purchase_price_review_status/README.md | 9 ++ purchase_price_review_status/__init__.py | 1 + purchase_price_review_status/__manifest__.py | 16 ++++ purchase_price_review_status/i18n/es.po | 39 ++++++++ .../i18n/purchase_price_review_status.pot | 38 ++++++++ .../models/__init__.py | 2 + .../models/purchase_order.py | 11 +++ .../models/stock_picking.py | 12 +++ .../views/purchase_order_views.xml | 93 +++++++++++++++++++ .../views/stock_picking_views.xml | 39 ++++++++ 10 files changed, 260 insertions(+) create mode 100644 purchase_price_review_status/README.md create mode 100644 purchase_price_review_status/__init__.py create mode 100644 purchase_price_review_status/__manifest__.py create mode 100644 purchase_price_review_status/i18n/es.po create mode 100644 purchase_price_review_status/i18n/purchase_price_review_status.pot create mode 100644 purchase_price_review_status/models/__init__.py create mode 100644 purchase_price_review_status/models/purchase_order.py create mode 100644 purchase_price_review_status/models/stock_picking.py create mode 100644 purchase_price_review_status/views/purchase_order_views.xml create mode 100644 purchase_price_review_status/views/stock_picking_views.xml diff --git a/purchase_price_review_status/README.md b/purchase_price_review_status/README.md new file mode 100644 index 0000000..e58f78c --- /dev/null +++ b/purchase_price_review_status/README.md @@ -0,0 +1,9 @@ +# Purchase Price Review Status + +Adds a boolean field on purchase orders to indicate whether purchase prices were reviewed against receipts. + +It decorates list views according to these rules: + +- Green: not fully received and prices reviewed. +- Red: not fully received and prices not reviewed. +- Default color: fully received (unchanged behavior). diff --git a/purchase_price_review_status/__init__.py b/purchase_price_review_status/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/purchase_price_review_status/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/purchase_price_review_status/__manifest__.py b/purchase_price_review_status/__manifest__.py new file mode 100644 index 0000000..3c0df01 --- /dev/null +++ b/purchase_price_review_status/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2026 Criptomart +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Purchase Price Review Status", + "version": "16.0.1.0.0", + "summary": "Track if purchase prices were reviewed and color PO/receipt lists", + "license": "AGPL-3", + "author": "Criptomart", + "website": "https://criptomart.net", + "depends": ["purchase_stock"], + "data": [ + "views/purchase_order_views.xml", + "views/stock_picking_views.xml", + ], + "installable": True, +} diff --git a/purchase_price_review_status/i18n/es.po b/purchase_price_review_status/i18n/es.po new file mode 100644 index 0000000..36d5adc --- /dev/null +++ b/purchase_price_review_status/i18n/es.po @@ -0,0 +1,39 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_price_review_status +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-02 00:00+0000\n" +"PO-Revision-Date: 2026-04-02 00:00+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: purchase_price_review_status +#: model:ir.model.fields,field_description:purchase_price_review_status.field_purchase_order__prices_reviewed +#: model:ir.model.fields,field_description:purchase_price_review_status.field_stock_picking__purchase_prices_reviewed +msgid "Purchase Prices Reviewed" +msgstr "Precios de Compra Revisados" + +#. module: purchase_price_review_status +#: model:ir.model.fields,help:purchase_price_review_status.field_purchase_order__prices_reviewed +msgid "Indicates whether purchase prices were reviewed against the receipt." +msgstr "Indica si los precios de compra fueron revisados con la recepción." + +#. module: purchase_price_review_status +#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_purchase_order_filter_price_review +#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.purchase_order_view_search_price_review +msgid "Prices Not Reviewed" +msgstr "Precios No Revisados" + +#. module: purchase_price_review_status +#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_picking_internal_search_price_review +msgid "Purchase Prices Not Reviewed" +msgstr "Precios de Compra No Revisados" diff --git a/purchase_price_review_status/i18n/purchase_price_review_status.pot b/purchase_price_review_status/i18n/purchase_price_review_status.pot new file mode 100644 index 0000000..f97265d --- /dev/null +++ b/purchase_price_review_status/i18n/purchase_price_review_status.pot @@ -0,0 +1,38 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_price_review_status +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-02 00:00+0000\n" +"PO-Revision-Date: 2026-04-02 00:00+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: purchase_price_review_status +#: model:ir.model.fields,field_description:purchase_price_review_status.field_purchase_order__prices_reviewed +#: model:ir.model.fields,field_description:purchase_price_review_status.field_stock_picking__purchase_prices_reviewed +msgid "Purchase Prices Reviewed" +msgstr "" + +#. module: purchase_price_review_status +#: model:ir.model.fields,help:purchase_price_review_status.field_purchase_order__prices_reviewed +msgid "Indicates whether purchase prices were reviewed against the receipt." +msgstr "" + +#. module: purchase_price_review_status +#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_purchase_order_filter_price_review +#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.purchase_order_view_search_price_review +msgid "Prices Not Reviewed" +msgstr "" + +#. module: purchase_price_review_status +#: model_terms:ir.ui.view,arch_db:purchase_price_review_status.view_picking_internal_search_price_review +msgid "Purchase Prices Not Reviewed" +msgstr "" diff --git a/purchase_price_review_status/models/__init__.py b/purchase_price_review_status/models/__init__.py new file mode 100644 index 0000000..d2e1293 --- /dev/null +++ b/purchase_price_review_status/models/__init__.py @@ -0,0 +1,2 @@ +from . import purchase_order +from . import stock_picking diff --git a/purchase_price_review_status/models/purchase_order.py b/purchase_price_review_status/models/purchase_order.py new file mode 100644 index 0000000..06f017f --- /dev/null +++ b/purchase_price_review_status/models/purchase_order.py @@ -0,0 +1,11 @@ +from odoo import fields, models + + +class PurchaseOrder(models.Model): + _inherit = "purchase.order" + + prices_reviewed = fields.Boolean( + string="Purchase Prices Reviewed", + default=False, + help="Indicates whether purchase prices were reviewed against the receipt.", + ) diff --git a/purchase_price_review_status/models/stock_picking.py b/purchase_price_review_status/models/stock_picking.py new file mode 100644 index 0000000..1c8511b --- /dev/null +++ b/purchase_price_review_status/models/stock_picking.py @@ -0,0 +1,12 @@ +from odoo import fields, models + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + purchase_prices_reviewed = fields.Boolean( + related="purchase_id.prices_reviewed", + string="Purchase Prices Reviewed", + readonly=True, + store=False, + ) diff --git a/purchase_price_review_status/views/purchase_order_views.xml b/purchase_price_review_status/views/purchase_order_views.xml new file mode 100644 index 0000000..1d49ce6 --- /dev/null +++ b/purchase_price_review_status/views/purchase_order_views.xml @@ -0,0 +1,93 @@ + + + + + purchase.order.form.price.review + purchase.order + + + + + + + + + + purchase.order.view.tree.price.review + purchase.order + + + + receipt_status != 'full' and prices_reviewed + receipt_status != 'full' and not prices_reviewed + + + + + + + + + + purchase.order.tree.price.review + purchase.order + + + + receipt_status != 'full' and prices_reviewed + receipt_status != 'full' and not prices_reviewed + + + + + + + + + + purchase.order.kpis.tree.price.review + purchase.order + + + + receipt_status != 'full' and prices_reviewed + receipt_status != 'full' and not prices_reviewed + + + + + + + + + + purchase.order.filter.price.review + purchase.order + + + + + + + + + + purchase.order.view.search.price.review + purchase.order + + + + + + + + + diff --git a/purchase_price_review_status/views/stock_picking_views.xml b/purchase_price_review_status/views/stock_picking_views.xml new file mode 100644 index 0000000..b281490 --- /dev/null +++ b/purchase_price_review_status/views/stock_picking_views.xml @@ -0,0 +1,39 @@ + + + + + stock.picking.tree.price.review + stock.picking + + + + picking_type_code == 'incoming' and state not in ('done', 'cancel') and purchase_id and purchase_prices_reviewed + picking_type_code == 'incoming' and state not in ('done', 'cancel') and purchase_id and not purchase_prices_reviewed + + + + + + + + + + stock.picking.internal.search.price.review + stock.picking + + + + + + + + + From 91971ae56b747b5bc89cae1ba7ddfde41a0b92a3 Mon Sep 17 00:00:00 2001 From: luis Date: Thu, 2 Apr 2026 13:02:18 +0200 Subject: [PATCH 2/3] add purchase_order_supplierinfo_update_triple_discount --- .../README.md | 9 +++ .../__init__.py | 1 + .../__manifest__.py | 18 ++++++ .../i18n/es.po | 62 +++++++++++++++++++ ...er_supplierinfo_update_triple_discount.pot | 61 ++++++++++++++++++ .../models/__init__.py | 2 + .../models/purchase_order_line.py | 43 +++++++++++++ .../models/res_config_settings.py | 32 ++++++++++ .../views/res_config_settings_views.xml | 47 ++++++++++++++ 9 files changed, 275 insertions(+) create mode 100644 purchase_order_supplierinfo_update_triple_discount/README.md create mode 100644 purchase_order_supplierinfo_update_triple_discount/__init__.py create mode 100644 purchase_order_supplierinfo_update_triple_discount/__manifest__.py create mode 100644 purchase_order_supplierinfo_update_triple_discount/i18n/es.po create mode 100644 purchase_order_supplierinfo_update_triple_discount/i18n/purchase_order_supplierinfo_update_triple_discount.pot create mode 100644 purchase_order_supplierinfo_update_triple_discount/models/__init__.py create mode 100644 purchase_order_supplierinfo_update_triple_discount/models/purchase_order_line.py create mode 100644 purchase_order_supplierinfo_update_triple_discount/models/res_config_settings.py create mode 100644 purchase_order_supplierinfo_update_triple_discount/views/res_config_settings_views.xml diff --git a/purchase_order_supplierinfo_update_triple_discount/README.md b/purchase_order_supplierinfo_update_triple_discount/README.md new file mode 100644 index 0000000..707ce28 --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/README.md @@ -0,0 +1,9 @@ +# Purchase Order Supplierinfo Update Triple Discount + +This module extends `purchase_order_supplierinfo_update` to optionally update triple discount fields in supplierinfo when confirming purchase orders. + +## Features + +- Adds three Purchase settings to enable/disable synchronization for each field independently. +- Keeps original behavior for supplier price update. +- Updates `discount1`, `discount2` and `discount3` from purchase order lines to supplierinfo only for the enabled fields. diff --git a/purchase_order_supplierinfo_update_triple_discount/__init__.py b/purchase_order_supplierinfo_update_triple_discount/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/purchase_order_supplierinfo_update_triple_discount/__manifest__.py b/purchase_order_supplierinfo_update_triple_discount/__manifest__.py new file mode 100644 index 0000000..26ecfaf --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/__manifest__.py @@ -0,0 +1,18 @@ +# Copyright 2026 Criptomart +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Purchase Order Supplierinfo Update Triple Discount", + "version": "16.0.1.0.0", + "summary": "Optionally sync triple discounts to supplierinfo on purchase confirmation", + "license": "AGPL-3", + "author": "Criptomart", + "website": "https://criptomart.net", + "depends": [ + "purchase_order_supplierinfo_update", + "purchase_triple_discount", + ], + "data": [ + "views/res_config_settings_views.xml", + ], + "installable": True, +} diff --git a/purchase_order_supplierinfo_update_triple_discount/i18n/es.po b/purchase_order_supplierinfo_update_triple_discount/i18n/es.po new file mode 100644 index 0000000..0fa0b2e --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/i18n/es.po @@ -0,0 +1,62 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_order_supplierinfo_update_triple_discount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-02 00:00+0000\n" +"PO-Revision-Date: 2026-04-02 00:00+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1 +msgid "Update Supplierinfo Discount 1" +msgstr "Actualizar Descuento 1 en Info de Proveedor" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2 +msgid "Update Supplierinfo Discount 2" +msgstr "Actualizar Descuento 2 en Info de Proveedor" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3 +msgid "Update Supplierinfo Discount 3" +msgstr "Actualizar Descuento 3 en Info de Proveedor" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1 +msgid "If enabled, confirming a purchase order will update discount1." +msgstr "Si está habilitado, al confirmar una orden de compra se actualizará el descuento1." + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2 +msgid "If enabled, confirming a purchase order will update discount2." +msgstr "Si está habilitado, al confirmar una orden de compra se actualizará el descuento2." + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3 +msgid "If enabled, confirming a purchase order will update discount3." +msgstr "Si está habilitado, al confirmar una orden de compra se actualizará el descuento3." + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount +msgid "Update discount1 from purchase lines into supplierinfo" +msgstr "Actualizar descuento1 de las líneas de compra en la info del proveedor" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount +msgid "Update discount2 from purchase lines into supplierinfo" +msgstr "Actualizar descuento2 de las líneas de compra en la info del proveedor" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount +msgid "Update discount3 from purchase lines into supplierinfo" +msgstr "Actualizar descuento3 de las líneas de compra en la info del proveedor" diff --git a/purchase_order_supplierinfo_update_triple_discount/i18n/purchase_order_supplierinfo_update_triple_discount.pot b/purchase_order_supplierinfo_update_triple_discount/i18n/purchase_order_supplierinfo_update_triple_discount.pot new file mode 100644 index 0000000..7781983 --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/i18n/purchase_order_supplierinfo_update_triple_discount.pot @@ -0,0 +1,61 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * purchase_order_supplierinfo_update_triple_discount +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-04-02 00:00+0000\n" +"PO-Revision-Date: 2026-04-02 00:00+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1 +msgid "Update Supplierinfo Discount 1" +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2 +msgid "Update Supplierinfo Discount 2" +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,field_description:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3 +msgid "Update Supplierinfo Discount 3" +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount1 +msgid "If enabled, confirming a purchase order will update discount1." +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount2 +msgid "If enabled, confirming a purchase order will update discount2." +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model:ir.model.fields,help:purchase_order_supplierinfo_update_triple_discount.field_res_config_settings__update_supplierinfo_discount3 +msgid "If enabled, confirming a purchase order will update discount3." +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount +msgid "Update discount1 from purchase lines into supplierinfo" +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount +msgid "Update discount2 from purchase lines into supplierinfo" +msgstr "" + +#. module: purchase_order_supplierinfo_update_triple_discount +#: model_terms:ir.ui.view,arch_db:purchase_order_supplierinfo_update_triple_discount.res_config_settings_view_form_purchase_supplierinfo_triple_discount +msgid "Update discount3 from purchase lines into supplierinfo" +msgstr "" diff --git a/purchase_order_supplierinfo_update_triple_discount/models/__init__.py b/purchase_order_supplierinfo_update_triple_discount/models/__init__.py new file mode 100644 index 0000000..247ce48 --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/models/__init__.py @@ -0,0 +1,2 @@ +from . import purchase_order_line +from . import res_config_settings diff --git a/purchase_order_supplierinfo_update_triple_discount/models/purchase_order_line.py b/purchase_order_supplierinfo_update_triple_discount/models/purchase_order_line.py new file mode 100644 index 0000000..d4c685f --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/models/purchase_order_line.py @@ -0,0 +1,43 @@ +from odoo import models +from odoo.tools.misc import str2bool + + +class PurchaseOrderLine(models.Model): + _inherit = "purchase.order.line" + + _SUPPLIERINFO_DISCOUNT_CONFIG = { + "discount1": ( + "purchase_order_supplierinfo_update_triple_discount" + ".update_supplierinfo_discount1" + ), + "discount2": ( + "purchase_order_supplierinfo_update_triple_discount" + ".update_supplierinfo_discount2" + ), + "discount3": ( + "purchase_order_supplierinfo_update_triple_discount" + ".update_supplierinfo_discount3" + ), + } + + def _update_supplierinfo(self, seller): + """Extend supplierinfo update to optionally sync each discount field.""" + self.ensure_one() + super()._update_supplierinfo(seller) + if not seller: + return + + config = self.env["ir.config_parameter"].sudo() + values = {} + for field_name, parameter_name in self._SUPPLIERINFO_DISCOUNT_CONFIG.items(): + if field_name not in self._fields or field_name not in seller._fields: + continue + should_update = str2bool( + config.get_param(parameter_name, default=False), + default=False, + ) + if should_update: + values[field_name] = self[field_name] + + if values: + seller.sudo().write(values) diff --git a/purchase_order_supplierinfo_update_triple_discount/models/res_config_settings.py b/purchase_order_supplierinfo_update_triple_discount/models/res_config_settings.py new file mode 100644 index 0000000..cc22e0e --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/models/res_config_settings.py @@ -0,0 +1,32 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + update_supplierinfo_discount1 = fields.Boolean( + string="Update Supplierinfo Discount 1", + config_parameter=( + "purchase_order_supplierinfo_update_triple_discount" + ".update_supplierinfo_discount1" + ), + help="If enabled, confirming a purchase order will update discount1.", + ) + + update_supplierinfo_discount2 = fields.Boolean( + string="Update Supplierinfo Discount 2", + config_parameter=( + "purchase_order_supplierinfo_update_triple_discount" + ".update_supplierinfo_discount2" + ), + help="If enabled, confirming a purchase order will update discount2.", + ) + + update_supplierinfo_discount3 = fields.Boolean( + string="Update Supplierinfo Discount 3", + config_parameter=( + "purchase_order_supplierinfo_update_triple_discount" + ".update_supplierinfo_discount3" + ), + help="If enabled, confirming a purchase order will update discount3.", + ) diff --git a/purchase_order_supplierinfo_update_triple_discount/views/res_config_settings_views.xml b/purchase_order_supplierinfo_update_triple_discount/views/res_config_settings_views.xml new file mode 100644 index 0000000..ccddda2 --- /dev/null +++ b/purchase_order_supplierinfo_update_triple_discount/views/res_config_settings_views.xml @@ -0,0 +1,47 @@ + + + + + res.config.settings.view.form.purchase.supplierinfo.triple.discount + res.config.settings + + + +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ +
From 524e3d643c9d66cc66a1f437f48adce0399cdbe9 Mon Sep 17 00:00:00 2001 From: luis Date: Thu, 2 Apr 2026 14:23:36 +0200 Subject: [PATCH 3/3] product_sale_price_from_pricelist: allow to configure rounding of list_price_theoritical after taxes. Add the configured pricelist margin in product form view --- product_sale_price_from_pricelist/i18n/es.po | 27 ++++++++++ .../product_sale_price_from_pricelist.pot | 27 ++++++++++ .../models/product_pricelist.py | 10 +++- .../models/product_template.py | 52 +++++++++++++++++-- .../views/product_view.xml | 14 +++++ 5 files changed, 126 insertions(+), 4 deletions(-) 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