From 2a480b74bbd6ab1f2a17e02c6ee029e8b2899c9e Mon Sep 17 00:00:00 2001 From: snt Date: Wed, 11 Feb 2026 21:04:18 +0100 Subject: [PATCH] Add update price button with notification to product views - Add action_update_list_price button in form and list views - Button shows only when compute type is not manual_update - Return notification message with update results - Invalidate cache to refresh UI automatically - Show updated products with old and new prices - Display skipped products with manual update mode --- .../models/product_template.py | 70 ++++++++++++++++--- .../views/product_view.xml | 16 +++++ 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/product_sale_price_from_pricelist/models/product_template.py b/product_sale_price_from_pricelist/models/product_template.py index 79c0720..2397270 100644 --- a/product_sale_price_from_pricelist/models/product_template.py +++ b/product_sale_price_from_pricelist/models/product_template.py @@ -3,10 +3,12 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import exceptions, models, fields, api, _ -from odoo.exceptions import UserError import logging -import math + +from odoo import _ +from odoo import fields +from odoo import models +from odoo.exceptions import UserError _logger = logging.getLogger(__name__) @@ -77,14 +79,14 @@ class ProductTemplate(models.Model): partial_price = template.product_variant_id._get_price( qty=1, pricelist=pricelist ) - + _logger.info( "[PRICE DEBUG] Product %s [%s]: partial_price result = %s", template.default_code or template.name, template.id, partial_price, ) - + # Compute taxes to add if not template.taxes_id: raise UserError( @@ -93,7 +95,7 @@ class ProductTemplate(models.Model): ) % template.name ) - + base_price = partial_price.get("value", 0.0) or 0.0 _logger.info( "[PRICE DEBUG] Product %s [%s]: base_price from pricelist = %.2f, last_purchase_price = %.2f", @@ -102,10 +104,10 @@ class ProductTemplate(models.Model): base_price, template.last_purchase_price_received, ) - + # Use base price without taxes (taxes will be calculated automatically on sales) theoretical_price = base_price - + _logger.info( "[PRICE] Product %s [%s]: Computed theoretical price %.2f (previous: %.2f, current list_price: %.2f)", template.default_code or template.name, @@ -131,11 +133,14 @@ class ProductTemplate(models.Model): ) def action_update_list_price(self): + updated_products = [] + skipped_products = [] + for template in self: if template.last_purchase_price_compute_type != "manual_update": # First compute the theoretical price template._compute_theoritical_price() - + old_price = template.list_price template.list_price = template.list_price_theoritical template.last_purchase_price_updated = False @@ -146,6 +151,53 @@ class ProductTemplate(models.Model): old_price, template.list_price, ) + updated_products.append( + ( + template.name or template.default_code, + old_price, + template.list_price, + ) + ) + else: + skipped_products.append(template.name or template.default_code) + + # Invalidate cache to refresh UI + self.invalidate_recordset( + ["list_price", "list_price_theoritical", "last_purchase_price_updated"] + ) + + # Build notification message + message = "" + if updated_products: + message += _("✓ Products updated: %s") % len(updated_products) + if len(updated_products) <= 5: + message += "\n\n" + for name, old, new in updated_products: + message += _("• %s: %.2f → %.2f\n") % (name, old, new) + + if skipped_products: + if message: + message += "\n\n" + message += _("⚠ Skipped (manual update): %s") % len(skipped_products) + if len(skipped_products) <= 5: + message += "\n" + for name in skipped_products: + message += _("• %s\n") % name + + if not updated_products and not skipped_products: + message = _("No products to update.") + + return { + "type": "ir.actions.client", + "tag": "display_notification", + "params": { + "title": _("Price Update"), + "message": message, + "type": "success" if updated_products else "warning", + "sticky": False, + "next": {"type": "ir.actions.act_window_close"}, + }, + } def price_compute( self, price_type, uom=None, currency=None, company=False, date=False diff --git a/product_sale_price_from_pricelist/views/product_view.xml b/product_sale_price_from_pricelist/views/product_view.xml index 6fb357b..e452fed 100644 --- a/product_sale_price_from_pricelist/views/product_view.xml +++ b/product_sale_price_from_pricelist/views/product_view.xml @@ -16,6 +16,14 @@ +