From b4608428fb310a9d1d017caa042d9f23a65bc282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Thu, 4 Jan 2024 23:55:09 +0100 Subject: [PATCH] Compute name of the product for sale, purchase and invoice lines Instead of having the code in the report templates, we use a property that can be extended without updating the template. Closes #12892 --- modules/account_invoice/invoice.fodt | 4 ++-- modules/account_invoice/invoice.py | 7 ++++++- modules/purchase/invoice.py | 11 +++++++++++ modules/purchase/purchase.fodt | 11 +++-------- modules/purchase/purchase.py | 11 ++++++++++- modules/sale/sale.fodt | 4 ++-- modules/sale/sale.py | 6 +++++- modules/sale_product_customer/__init__.py | 3 ++- modules/sale_product_customer/account.py | 19 +++++++++++++++++++ modules/sale_product_customer/product.py | 20 +++++++++++++------- modules/sale_product_customer/sale.py | 8 ++++++++ modules/sale_product_customer/tryton.cfg | 1 + 12 files changed, 82 insertions(+), 23 deletions(-) create mode 100644 modules/sale_product_customer/account.py diff --git a/modules/account_invoice/invoice.fodt b/modules/account_invoice/invoice.fodt index 53036bad04..33fd423373 100644 --- a/modules/account_invoice/invoice.fodt +++ b/modules/account_invoice/invoice.fodt @@ -818,8 +818,8 @@ - <if test="line.product"> - <line.product.rec_name> + <if test="line.product_name"> + <line.product_name> </if> <if test="line.description"> <for each="description in line.description.split('\n')"> diff --git a/modules/account_invoice/invoice.py b/modules/account_invoice/invoice.py index e18ceb8f89..017baaae5c 100644 --- a/modules/account_invoice/invoice.py +++ b/modules/account_invoice/invoice.py @@ -29,7 +29,8 @@ from trytond.pool import Pool from trytond.pyson import Bool, Eval, Id, If from trytond.report import Report from trytond.rpc import RPC -from trytond.tools import firstline, grouped_slice, reduce_ids, slugify +from trytond.tools import ( + cached_property, firstline, grouped_slice, reduce_ids, slugify) from trytond.transaction import Transaction from trytond.wizard import ( Button, StateAction, StateReport, StateTransition, StateView, Wizard) @@ -2636,6 +2637,10 @@ class InvoiceLine(sequence_ordered(), ModelSQL, ModelView, TaxableMixin): if not self.unit or self.unit.category != category: self.unit = self.product.default_uom.id + @cached_property + def product_name(self): + return self.product.rec_name if self.product else '' + @fields.depends('product') def on_change_with_product_uom_category(self, name=None): return self.product.default_uom_category if self.product else None diff --git a/modules/purchase/invoice.py b/modules/purchase/invoice.py index e1ed67e279..1b5592ad79 100644 --- a/modules/purchase/invoice.py +++ b/modules/purchase/invoice.py @@ -7,6 +7,7 @@ from trytond.model import ModelView, Workflow, fields from trytond.model.exceptions import AccessError from trytond.pool import Pool, PoolMeta from trytond.pyson import Eval +from trytond.tools import cached_property from trytond.transaction import Transaction, without_check_access @@ -110,6 +111,16 @@ class InvoiceLine(metaclass=PoolMeta): ('type', '=', Eval('type')), ] + @cached_property + def product_name(self): + pool = Pool() + PurchaseLine = pool.get('purchase.line') + name = super().product_name + if (isinstance(self.origin, PurchaseLine) + and self.origin.product_supplier): + name = self.origin.product_supplier.rec_name + return name + @fields.depends('origin') def on_change_with_product_uom_category(self, name=None): pool = Pool() diff --git a/modules/purchase/purchase.fodt b/modules/purchase/purchase.fodt index 53b2add235..6e3331840f 100644 --- a/modules/purchase/purchase.fodt +++ b/modules/purchase/purchase.fodt @@ -707,14 +707,9 @@ - <choose> - <when test="line.product_supplier"> - <line.product_supplier.rec_name> - </when> - <when test="line.product"> - <line.product.rec_name> - </when> - </choose> + <if test="line.product_name"> + <line.product_name> + </if> <if test="line.description"> <for each="description in line.description.split('\n')"> <description> diff --git a/modules/purchase/purchase.py b/modules/purchase/purchase.py index 0d64f765df..ee97c208e4 100644 --- a/modules/purchase/purchase.py +++ b/modules/purchase/purchase.py @@ -25,7 +25,7 @@ from trytond.modules.currency.fields import Monetary from trytond.modules.product import price_digits from trytond.pool import Pool from trytond.pyson import Bool, Eval, If, PYSONEncoder -from trytond.tools import firstline +from trytond.tools import cached_property, firstline from trytond.transaction import Transaction from trytond.wizard import ( Button, StateAction, StateTransition, StateView, Wizard) @@ -1467,6 +1467,15 @@ class Line(sequence_ordered(), ModelSQL, ModelView): self.amount = self.on_change_with_amount() + @cached_property + def product_name(self): + if self.product_supplier: + return self.product_supplier.rec_name + elif self.product: + return self.product.rec_name + else: + return '' + @fields.depends( 'type', 'product', methods=['on_change_with_company', '_get_tax_rule_pattern']) diff --git a/modules/sale/sale.fodt b/modules/sale/sale.fodt index e59c16b2ab..3f18041274 100644 --- a/modules/sale/sale.fodt +++ b/modules/sale/sale.fodt @@ -698,8 +698,8 @@ - <if test="line.product"> - <line.product.rec_name> + <if test="line.product_name"> + <line.product_name> </if> <if test="line.description"> <for each="description in line.description.split('\n')"> diff --git a/modules/sale/sale.py b/modules/sale/sale.py index 9c06fc5a50..ab7ad16615 100644 --- a/modules/sale/sale.py +++ b/modules/sale/sale.py @@ -25,7 +25,7 @@ from trytond.modules.currency.fields import Monetary from trytond.modules.product import price_digits from trytond.pool import Pool from trytond.pyson import Bool, Eval, If, PYSONEncoder -from trytond.tools import firstline, sortable_values +from trytond.tools import cached_property, firstline, sortable_values from trytond.transaction import Transaction from trytond.wizard import ( Button, StateAction, StateTransition, StateView, Wizard) @@ -1550,6 +1550,10 @@ class SaleLine(TaxableMixin, sequence_ordered(), ModelSQL, ModelView): self.amount = self.on_change_with_amount() + @cached_property + def product_name(self): + return self.product.rec_name if self.product else '' + @fields.depends( 'type', 'product', methods=['on_change_with_company', '_get_tax_rule_pattern']) diff --git a/modules/sale_product_customer/__init__.py b/modules/sale_product_customer/__init__.py index 1e19b01cb1..40cd0dc71d 100644 --- a/modules/sale_product_customer/__init__.py +++ b/modules/sale_product_customer/__init__.py @@ -3,7 +3,7 @@ from trytond.pool import Pool -from . import product, sale +from . import account, product, sale __all__ = ['register'] @@ -14,6 +14,7 @@ def register(): product.Product, product.ProductCustomer, sale.Line, + account.InvoiceLine, module='sale_product_customer', type_='model') Pool.register( sale.AmendmentLine, diff --git a/modules/sale_product_customer/account.py b/modules/sale_product_customer/account.py new file mode 100644 index 0000000000..2af96e6399 --- /dev/null +++ b/modules/sale_product_customer/account.py @@ -0,0 +1,19 @@ +# This file is part of Tryton. The COPYRIGHT file at the top level of +# this repository contains the full copyright notices and license terms. + +from trytond.pool import Pool, PoolMeta +from trytond.tools import cached_property + + +class InvoiceLine(metaclass=PoolMeta): + __name__ = 'account.invoice.line' + + @cached_property + def product_name(self): + pool = Pool() + SaleLine = pool.get('sale.line') + name = super().product_name + if (isinstance(self.origin, SaleLine) + and self.origin.product_customer): + name = self.origin.product_customer.rec_name + return name diff --git a/modules/sale_product_customer/product.py b/modules/sale_product_customer/product.py index 91f69c6b00..466319e37f 100644 --- a/modules/sale_product_customer/product.py +++ b/modules/sale_product_customer/product.py @@ -52,14 +52,20 @@ class ProductCustomer( self.template = self.product.template def get_rec_name(self, name): - if self.name: - name = self.name - elif self.product: - name = self.product.name + if not self.name and not self.code: + if self.product: + name = self.product.rec_name + else: + name = self.template.rec_name else: - name = self.template.name - if self.code: - name = '[' + self.code + '] ' + name + if self.name: + name = self.name + elif self.product: + name = self.product.name + else: + name = self.template.name + if self.code: + name = '[' + self.code + '] ' + name return name @classmethod diff --git a/modules/sale_product_customer/sale.py b/modules/sale_product_customer/sale.py index 7f37683c71..f121ea730a 100644 --- a/modules/sale_product_customer/sale.py +++ b/modules/sale_product_customer/sale.py @@ -4,6 +4,7 @@ from trytond.model import fields from trytond.pool import PoolMeta from trytond.pyson import Bool, Eval, If +from trytond.tools import cached_property class Line(metaclass=PoolMeta): @@ -62,6 +63,13 @@ class Line(metaclass=PoolMeta): self.product, = self.product_customer.template.products self.on_change_product() + @cached_property + def product_name(self): + name = super().product_name + if self.product_customer: + name = self.product_customer.rec_name + return name + class AmendmentLine(metaclass=PoolMeta): __name__ = 'sale.amendment.line' diff --git a/modules/sale_product_customer/tryton.cfg b/modules/sale_product_customer/tryton.cfg index bcbfbb4eb1..80410e67ef 100644 --- a/modules/sale_product_customer/tryton.cfg +++ b/modules/sale_product_customer/tryton.cfg @@ -1,6 +1,7 @@ [tryton] version=7.1.0 depends: + account_invoice ir product sale