From bbd5e521f36c456c398b91d903970d10abb18c1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 21 May 2024 18:56:03 +0200 Subject: [PATCH] Add secondary unit to sale amendment Closes #13256 --- modules/sale_amendment/sale.py | 15 ++++++--- modules/sale_secondary_unit/CHANGELOG | 1 + modules/sale_secondary_unit/__init__.py | 4 +++ modules/sale_secondary_unit/sale.py | 31 +++++++++++++++++++ modules/sale_secondary_unit/setup.py | 1 + .../tests/scenario_sale_secondary_unit.rst | 27 ++++++++++++++-- modules/sale_secondary_unit/tryton.cfg | 1 + 7 files changed, 73 insertions(+), 7 deletions(-) diff --git a/modules/sale_amendment/sale.py b/modules/sale_amendment/sale.py index 5758527214..c5c516fb1a 100644 --- a/modules/sale_amendment/sale.py +++ b/modules/sale_amendment/sale.py @@ -304,11 +304,6 @@ class AmendmentLine(ModelSQL, ModelView): }) unit = fields.Many2One( 'product.uom', "Unit", ondelete='RESTRICT', - domain=[ - If(Eval('product_uom_category'), - ('category', '=', Eval('product_uom_category')), - ()), - ], states={ 'readonly': Eval('state') != 'draft', 'invisible': Eval('action') != 'line', @@ -336,6 +331,16 @@ class AmendmentLine(ModelSQL, ModelView): def __setup__(cls): super().__setup__() cls.__access__.add('amendment') + unit_categories = cls._unit_categories() + cls.unit.domain = [ + If(Bool(Eval('product_uom_category')), + ('category', 'in', [Eval(c) for c in unit_categories]), + ('category', '!=', -1)), + ] + + @classmethod + def _unit_categories(cls): + return ['product_uom_category'] @fields.depends( 'amendment', diff --git a/modules/sale_secondary_unit/CHANGELOG b/modules/sale_secondary_unit/CHANGELOG index 8a52cfb0ef..1ac36099e2 100644 --- a/modules/sale_secondary_unit/CHANGELOG +++ b/modules/sale_secondary_unit/CHANGELOG @@ -1,3 +1,4 @@ +* Add secondary unit to sale amendment Version 7.2.0 - 2024-04-29 -------------------------- diff --git a/modules/sale_secondary_unit/__init__.py b/modules/sale_secondary_unit/__init__.py index 8cf1c7b662..ae028028ea 100644 --- a/modules/sale_secondary_unit/__init__.py +++ b/modules/sale_secondary_unit/__init__.py @@ -30,3 +30,7 @@ def register(): sale.LineBlanketAgreement, module='sale_secondary_unit', type_='model', depends=['sale_blanket_agreement']) + Pool.register( + sale.AmendmentLine, + module='sale_secondary_unit', type_='model', + depends=['sale_amendment']) diff --git a/modules/sale_secondary_unit/sale.py b/modules/sale_secondary_unit/sale.py index 5922956f96..5ba76ae163 100644 --- a/modules/sale_secondary_unit/sale.py +++ b/modules/sale_secondary_unit/sale.py @@ -314,3 +314,34 @@ class LineBlanketAgreement(metaclass=PoolMeta): rate=self.secondary_uom_rate, round=round) return quantity + + +class AmendmentLine(metaclass=PoolMeta): + __name__ = 'sale.amendment.line' + + product_secondary_uom_category = fields.Function( + fields.Many2One( + 'product.uom.category', "Product Secondary UoM Category", + help="The category of the secondary Unit of Measure " + "for the product."), + 'on_change_with_product_secondary_uom_category') + + @classmethod + def _unit_categories(cls): + return super()._unit_categories() + ['product_secondary_uom_category'] + + @fields.depends('product') + def on_change_with_product_secondary_uom_category(self, name=None): + if self.product and self.product.sale_secondary_uom: + return self.product.sale_secondary_uom.category + + def _apply_line(self, sale, sale_line): + super()._apply_line(sale, sale_line) + if (self.unit and self.product + and self.unit.category != self.product.sale_uom.category): + sale_line.unit = self.line.unit + sale_line.secondary_quantity = self.quantity + sale_line.secondary_unit = self.unit + sale_line.on_change_secondary_quantity() + sale_line.secondary_unit_price = self.unit_price + sale_line.on_change_secondary_unit_price() diff --git a/modules/sale_secondary_unit/setup.py b/modules/sale_secondary_unit/setup.py index 83e0e8f03f..3a6a203a2a 100755 --- a/modules/sale_secondary_unit/setup.py +++ b/modules/sale_secondary_unit/setup.py @@ -49,6 +49,7 @@ requires.append(get_require_version('trytond')) tests_require = [get_require_version('proteus'), get_require_version('trytond_account_invoice_secondary_unit'), + get_require_version('trytond_sale_amendment'), get_require_version('trytond_sale_blanket_agreement'), get_require_version('trytond_stock_secondary_unit'), get_require_version('trytond_sale_product_customer')] diff --git a/modules/sale_secondary_unit/tests/scenario_sale_secondary_unit.rst b/modules/sale_secondary_unit/tests/scenario_sale_secondary_unit.rst index 9639b28686..2b79d4d7ec 100644 --- a/modules/sale_secondary_unit/tests/scenario_sale_secondary_unit.rst +++ b/modules/sale_secondary_unit/tests/scenario_sale_secondary_unit.rst @@ -13,8 +13,9 @@ Imports:: Activate modules:: - >>> config = activate_modules( - ... ['sale_secondary_unit', + >>> config = activate_modules([ + ... 'sale_amendment', + ... 'sale_secondary_unit', ... 'account_invoice_secondary_unit', ... 'stock_secondary_unit']) @@ -129,3 +130,25 @@ Check secondary unit on move:: >>> assertEqual(move.secondary_unit, kg) >>> move.secondary_quantity 2.0 + +Add an amendment:: + + >>> amendment = sale.amendments.new() + >>> line = amendment.lines.new() + >>> line.action = 'line' + >>> line.line = sale.lines[-1] + >>> line.quantity = 1 + >>> line.unit = kg + >>> line.unit_price = Decimal('45.0000') + >>> amendment.click('validate_amendment') + + >>> sale.reload() + >>> line = sale.lines[-1] + >>> line.quantity + 5.0 + >>> line.secondary_quantity + 1.0 + >>> line.unit_price + Decimal('9.0000') + >>> line.secondary_unit_price + Decimal('45.0000') diff --git a/modules/sale_secondary_unit/tryton.cfg b/modules/sale_secondary_unit/tryton.cfg index 8132896b5c..6cc97035d4 100644 --- a/modules/sale_secondary_unit/tryton.cfg +++ b/modules/sale_secondary_unit/tryton.cfg @@ -8,6 +8,7 @@ depends: stock extras_depend: account_invoice_secondary_unit + sale_amendment sale_blanket_agreement sale_opportunity sale_product_customer