From f9fc3f1ac5a1ceaaa554ad6336ed5e244a95f7fd Mon Sep 17 00:00:00 2001 From: niyp-odoo Date: Tue, 22 Jul 2025 18:37:42 +0530 Subject: [PATCH] [IMP] sale: auto-recalculate global discount on order line changes Enhanced the Sales Order logic to automatically recalculate and update the global discount line whenever sale order lines are added, updated, or deleted. This ensures that the discount remains in sync with the current order total. If all product lines are removed, the discount line is also removed. This improves data consistency and reduces the need for manual discount updates. task-4962386 --- discount_update/__init__.py | 1 + discount_update/__manifest__.py | 7 +++++ discount_update/models/__init__.py | 2 ++ discount_update/models/sale_order.py | 38 +++++++++++++++++++++++ discount_update/models/sale_order_line.py | 31 ++++++++++++++++++ 5 files changed, 79 insertions(+) create mode 100644 discount_update/__init__.py create mode 100644 discount_update/__manifest__.py create mode 100644 discount_update/models/__init__.py create mode 100644 discount_update/models/sale_order.py create mode 100644 discount_update/models/sale_order_line.py diff --git a/discount_update/__init__.py b/discount_update/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/discount_update/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/discount_update/__manifest__.py b/discount_update/__manifest__.py new file mode 100644 index 00000000000..0de9b0b2690 --- /dev/null +++ b/discount_update/__manifest__.py @@ -0,0 +1,7 @@ +{ + 'name': "Discount Update", + 'version': "1.0", + 'depends': ["sale_management"], + 'insallable': True, + 'license': 'LGPL-3' +} diff --git a/discount_update/models/__init__.py b/discount_update/models/__init__.py new file mode 100644 index 00000000000..2d7ee6c3dc7 --- /dev/null +++ b/discount_update/models/__init__.py @@ -0,0 +1,2 @@ +from . import sale_order +from . import sale_order_line diff --git a/discount_update/models/sale_order.py b/discount_update/models/sale_order.py new file mode 100644 index 00000000000..b9e440c1a74 --- /dev/null +++ b/discount_update/models/sale_order.py @@ -0,0 +1,38 @@ +from odoo import fields, models + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + discount_percentage = fields.Float(string="Global Discount (%)") + wizard_ids = fields.One2many( + "sale.order.discount", "sale_order_id", string="Discount Wizards" + ) + + def _update_discount(self): + + discount_product = self.env["product.product"].search([("name", "=", "Discount")], limit=1) + if not discount_product: + return + + total_amount = sum(line.price_total for line in self.order_line if not line.is_discount_line()) + if not total_amount: + discount_lines = self.order_line.filtered(lambda l: l.is_discount_line()) + discount_lines.unlink() + return + + if self.wizard_ids: + discount_percentage = self.wizard_ids[-1].discount_percentage + else: + return + + discount_amount = total_amount * (discount_percentage) + discount_line = self.order_line.filtered(lambda l: l.is_discount_line()) + + if discount_line: + discount_line.write( + { + "price_unit": discount_amount * (-1), + "name": f"Discount{discount_percentage * 100:.2f}%", + } + ) diff --git a/discount_update/models/sale_order_line.py b/discount_update/models/sale_order_line.py new file mode 100644 index 00000000000..b4b439127b5 --- /dev/null +++ b/discount_update/models/sale_order_line.py @@ -0,0 +1,31 @@ +from odoo import api, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + def is_discount_line(self): + discount_product = self.order_id.env["product.product"].search([("name", "=", "Discount")], limit=1) + return self.product_id == discount_product + + def unlink(self): + order_ids = self.mapped("order_id") + res = super().unlink() + for order in order_ids: + order._update_discount() + return res + + @api.model_create_multi + def create(self, vals): + lines = super().create(vals) + for line in lines: + if line.order_id and not line.is_discount_line(): + line.order_id._update_discount() + return lines + + def write(self, vals): + res = super().write(vals) + for line in self: + if not line.is_discount_line(): + line.order_id._update_discount() + return res