diff --git a/sale_order_line_price_unit_control/README.rst b/sale_order_line_price_unit_control/README.rst new file mode 100644 index 00000000..6ac50e91 --- /dev/null +++ b/sale_order_line_price_unit_control/README.rst @@ -0,0 +1,29 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +================================== +Sale order line price unit control +================================== + +* When confirming a sales order, verify that none of its lines have a unit + price equal to 1. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, +please check there if your issue has already been reported. If you spotted +it first, help us smash it by providing detailed and welcomed feedback. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Contributors +------------ + +* Berezi Amubieta +* Ana Juaristi diff --git a/sale_order_line_price_unit_control/__init__.py b/sale_order_line_price_unit_control/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/sale_order_line_price_unit_control/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_order_line_price_unit_control/__manifest__.py b/sale_order_line_price_unit_control/__manifest__.py new file mode 100644 index 00000000..58fe5396 --- /dev/null +++ b/sale_order_line_price_unit_control/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2021 Alfredo de la Fuente - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "Sale Order Line Price Unit Control", + "version": "18.0.1.0.0", + "category": "Sales", + "license": "AGPL-3", + "author": "AvanzOSC", + "website": "https://github.com/avanzosc/sale-addons", + "depends": [ + "sale_management", + ], + "data": [], + "installable": True, +} diff --git a/sale_order_line_price_unit_control/i18n/en_US.po b/sale_order_line_price_unit_control/i18n/en_US.po new file mode 100644 index 00000000..f3889fb3 --- /dev/null +++ b/sale_order_line_price_unit_control/i18n/en_US.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_order_line_price_unit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-01-27 07:43+0000\n" +"PO-Revision-Date: 2026-01-27 07:43+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: sale_order_line_price_unit_control +#: model:ir.model,name:sale_order_line_price_unit_control.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_order_line_price_unit_control +#. odoo-python +#: code:addons/sale_order_line_price_unit_control/models/sale_order.py:0 +msgid "" +"You have %(num_lines)s with an amount less than or equal to %(price_unit)s." +msgstr "" diff --git a/sale_order_line_price_unit_control/i18n/es.po b/sale_order_line_price_unit_control/i18n/es.po new file mode 100644 index 00000000..9bfffba7 --- /dev/null +++ b/sale_order_line_price_unit_control/i18n/es.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_order_line_price_unit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-01-27 07:44+0000\n" +"PO-Revision-Date: 2026-01-27 07:44+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: sale_order_line_price_unit_control +#: model:ir.model,name:sale_order_line_price_unit_control.model_sale_order +msgid "Sales Order" +msgstr "Pedido de venta" + +#. module: sale_order_line_price_unit_control +#. odoo-python +#: code:addons/sale_order_line_price_unit_control/models/sale_order.py:0 +msgid "" +"You have %(num_lines)s with an amount less than or equal to %(price_unit)s." +msgstr "Tiene %(num_lines)s lĂ­nea(s) con un importe menor o igual a %(price_unit)s." diff --git a/sale_order_line_price_unit_control/i18n/fr.po b/sale_order_line_price_unit_control/i18n/fr.po new file mode 100644 index 00000000..8ce42224 --- /dev/null +++ b/sale_order_line_price_unit_control/i18n/fr.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_order_line_price_unit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-01-27 07:43+0000\n" +"PO-Revision-Date: 2026-01-27 07:43+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: sale_order_line_price_unit_control +#: model:ir.model,name:sale_order_line_price_unit_control.model_sale_order +msgid "Sales Order" +msgstr "Commande client" + +#. module: sale_order_line_price_unit_control +#. odoo-python +#: code:addons/sale_order_line_price_unit_control/models/sale_order.py:0 +msgid "" +"You have %(num_lines)s with an amount less than or equal to %(price_unit)s." +msgstr "" diff --git a/sale_order_line_price_unit_control/i18n/it.po b/sale_order_line_price_unit_control/i18n/it.po new file mode 100644 index 00000000..57522ea4 --- /dev/null +++ b/sale_order_line_price_unit_control/i18n/it.po @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_order_line_price_unit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-01-27 07:43+0000\n" +"PO-Revision-Date: 2026-01-27 07:43+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: sale_order_line_price_unit_control +#: model:ir.model,name:sale_order_line_price_unit_control.model_sale_order +msgid "Sales Order" +msgstr "Ordine di vendita" + +#. module: sale_order_line_price_unit_control +#. odoo-python +#: code:addons/sale_order_line_price_unit_control/models/sale_order.py:0 +msgid "" +"You have %(num_lines)s with an amount less than or equal to %(price_unit)s." +msgstr "" diff --git a/sale_order_line_price_unit_control/i18n/sale_order_line_price_unit_control.pot b/sale_order_line_price_unit_control/i18n/sale_order_line_price_unit_control.pot new file mode 100644 index 00000000..f3889fb3 --- /dev/null +++ b/sale_order_line_price_unit_control/i18n/sale_order_line_price_unit_control.pot @@ -0,0 +1,28 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_order_line_price_unit_control +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-01-27 07:43+0000\n" +"PO-Revision-Date: 2026-01-27 07:43+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: sale_order_line_price_unit_control +#: model:ir.model,name:sale_order_line_price_unit_control.model_sale_order +msgid "Sales Order" +msgstr "" + +#. module: sale_order_line_price_unit_control +#. odoo-python +#: code:addons/sale_order_line_price_unit_control/models/sale_order.py:0 +msgid "" +"You have %(num_lines)s with an amount less than or equal to %(price_unit)s." +msgstr "" diff --git a/sale_order_line_price_unit_control/models/__init__.py b/sale_order_line_price_unit_control/models/__init__.py new file mode 100644 index 00000000..6aacb753 --- /dev/null +++ b/sale_order_line_price_unit_control/models/__init__.py @@ -0,0 +1 @@ +from . import sale_order diff --git a/sale_order_line_price_unit_control/models/sale_order.py b/sale_order_line_price_unit_control/models/sale_order.py new file mode 100644 index 00000000..bcaee452 --- /dev/null +++ b/sale_order_line_price_unit_control/models/sale_order.py @@ -0,0 +1,30 @@ +# Copyright 2021 Alfredo de la Fuente - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import _, models +from odoo.exceptions import UserError +from odoo.tools import config + + +class SaleOrder(models.Model): + _inherit = "sale.order" + + def action_confirm(self): + if config["test_enable"] and not self.env.context.get("check_amount_less"): + return super().action_confirm() + for sale in self: + min_price_unit = sale._get_min_price_unit() + lines = sale.order_line.filtered( + lambda x, min_price_unit=min_price_unit: x.price_unit == min_price_unit + ) + if lines: + raise UserError( + _( + "You have %(num_lines)s with an amount less than or " + "equal to %(price_unit)s." + ) + % {"num_lines": len(lines), "price_unit": min_price_unit} + ) + return super().action_confirm() + + def _get_min_price_unit(self): + return 1 diff --git a/sale_order_line_price_unit_control/pyproject.toml b/sale_order_line_price_unit_control/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/sale_order_line_price_unit_control/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/sale_order_line_price_unit_control/tests/__init__.py b/sale_order_line_price_unit_control/tests/__init__.py new file mode 100644 index 00000000..206e933c --- /dev/null +++ b/sale_order_line_price_unit_control/tests/__init__.py @@ -0,0 +1 @@ +from . import test_sale_order_line_price_unit_control diff --git a/sale_order_line_price_unit_control/tests/test_sale_order_line_price_unit_control.py b/sale_order_line_price_unit_control/tests/test_sale_order_line_price_unit_control.py new file mode 100644 index 00000000..797ab263 --- /dev/null +++ b/sale_order_line_price_unit_control/tests/test_sale_order_line_price_unit_control.py @@ -0,0 +1,22 @@ +# Copyright 2021 Alfredo de la Fuente - AvanzOSC +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo.exceptions import UserError +from odoo.tests.common import TransactionCase + + +class TestSaleOrderLinePriceUnitControl(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cond = [("state", "=", "draft")] + cls.sale = cls.env["sale.order"].search(cond, limit=1) + cond = [("state", "=", "draft"), ("id", "!=", cls.sale.id)] + cls.sale2 = cls.env["sale.order"].search(cond, limit=1) + + def test_sale_order_line_price_unit_control(self): + self.sale2.order_line[0].write({"price_unit": 1}) + self.sale2.action_confirm() + self.assertEqual(self.sale2.state, "sale") + self.sale.order_line[0].write({"price_unit": 1}) + with self.assertRaises(UserError): + self.sale.with_context(check_amount_less=True).action_confirm()