From 590fbe3aa8144d952cd7d36c1d3f243ba2637ceb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 16 Sep 2023 10:30:44 +0200 Subject: [PATCH] Use origin description as fallback description for account move and line Closes #12571 --- modules/account/CHANGELOG | 1 + modules/account/account.py | 27 +++++++++- modules/account/general_ledger.fodt | 4 +- modules/account/move.py | 54 ++++++++++++++++--- .../tests/scenario_move_line_group.rst | 2 +- .../account/view/general_ledger_line_list.xml | 4 +- modules/account/view/move_form.xml | 4 +- modules/account/view/move_line_form.xml | 4 +- .../move_line_list_payable_receivable.xml | 4 +- .../account/view/move_line_list_reconcile.xml | 4 +- modules/account/view/move_line_tree.xml | 4 +- modules/account/view/move_line_tree_move.xml | 2 +- modules/account/view/move_tree.xml | 2 +- .../view/move_line_list_deposit.xml | 4 +- .../view/move_line_list_payment.xml | 4 +- modules/account_move_line_grouping/account.py | 4 +- ...ove_line_group_form_payable_receivable.xml | 4 +- .../view/move_line_group_list.xml | 2 +- ...ve_line_group_list_payabale_receivable.xml | 2 +- .../analytic_account/view/move_line_list.xml | 4 +- 20 files changed, 103 insertions(+), 37 deletions(-) diff --git a/modules/account/CHANGELOG b/modules/account/CHANGELOG index 951587cf57..3dcf219d27 100644 --- a/modules/account/CHANGELOG +++ b/modules/account/CHANGELOG @@ -1,3 +1,4 @@ +* Use origin description as fallback description * Post write-off and exchange moves when reconcile posted lines * Post cancelled, grouped, rescheduled and delegated moves * Rename close state to closed diff --git a/modules/account/account.py b/modules/account/account.py index 1340c4dcd5..3f964ae542 100644 --- a/modules/account/account.py +++ b/modules/account/account.py @@ -31,6 +31,7 @@ from .common import ActivePeriodMixin, ContextCompanyMixin, PeriodMixin from .exceptions import ( AccountValidationError, ChartWarning, FiscalYearNotFoundError, SecondCurrencyError) +from .move import DescriptionOriginMixin def TypeMixin(template=False): @@ -2322,7 +2323,7 @@ class OpenGeneralLedgerAccountParty(Wizard): return action, {} -class GeneralLedgerLine(ModelSQL, ModelView): +class GeneralLedgerLine(DescriptionOriginMixin, ModelSQL, ModelView): 'General Ledger Line' __name__ = 'account.general_ledger.line' @@ -2354,7 +2355,10 @@ class GeneralLedgerLine(ModelSQL, ModelView): 'get_balance') origin = fields.Reference('Origin', selection='get_origin') description = fields.Char('Description') - move_description = fields.Char('Move Description') + move_description_used = fields.Function( + fields.Char("Move Description"), + 'get_move_field', + searcher='search_move_field') amount_second_currency = Monetary( "Amount Second Currency", currency='second_currency', digits='second_currency') @@ -2375,6 +2379,7 @@ class GeneralLedgerLine(ModelSQL, ModelView): super(GeneralLedgerLine, cls).__setup__() cls.__access__.add('account') cls._order.insert(0, ('date', 'ASC')) + cls.description_used.setter = None @classmethod def table_query(cls): @@ -2425,6 +2430,24 @@ class GeneralLedgerLine(ModelSQL, ModelView): ).join(account, condition=line.account == account.id ).select(*columns, where=line_query) + def get_move_field(self, name): + field = getattr(self.__class__, name) + if name.startswith('move_'): + name = name[5:] + value = getattr(self.move, name) + if isinstance(value, ModelSQL): + if field._type == 'reference': + return str(value) + return value.id + return value + + @classmethod + def search_move_field(cls, name, clause): + nested = clause[0][len(name):] + if name.startswith('move_'): + name = name[5:] + return [('move.' + name + nested, *clause[1:])] + def get_currency(self, name): return self.company.currency.id diff --git a/modules/account/general_ledger.fodt b/modules/account/general_ledger.fodt index ba4614e873..27a516da86 100644 --- a/modules/account/general_ledger.fodt +++ b/modules/account/general_ledger.fodt @@ -910,7 +910,7 @@ <format_currency(line.balance, user.language, company.currency)> - <line.description or ''><line.move_description or ''> + <line.description or ''><line.move_description_used or ''> <getattr(line.origin, 'rec_name', '')> @@ -976,4 +976,4 @@ </for> - \ No newline at end of file + diff --git a/modules/account/move.py b/modules/account/move.py index b3dd3258ac..0289a971d7 100644 --- a/modules/account/move.py +++ b/modules/account/move.py @@ -21,7 +21,7 @@ from trytond.pool import Pool from trytond.pyson import Bool, Eval, If, PYSONEncoder from trytond.report import Report from trytond.rpc import RPC -from trytond.tools import grouped_slice, reduce_ids +from trytond.tools import firstline, grouped_slice, reduce_ids from trytond.transaction import Transaction, check_access from trytond.wizard import ( Button, StateAction, StateTransition, StateView, Wizard) @@ -39,7 +39,48 @@ _LINE_STATES = { } -class Move(ModelSQL, ModelView): +class DescriptionOriginMixin: + __slots__ = () + + description_used = fields.Function( + fields.Char("Description", states=_MOVE_STATES), + 'on_change_with_description_used', + setter='set_description_used', + searcher='search_description_used') + + @fields.depends('description', 'origin') + def on_change_with_description_used(self, name=None): + description = self.description + if not description and hasattr(self.origin, 'description'): + description = firstline(self.origin.description or '') + return description + + @classmethod + def set_description_used(cls, moves, name, value): + moves = [m for m in moves if m.description_used != value] + if moves: + cls.write(moves, {'description': value}) + + @classmethod + def search_description_used(cls, name, clause): + pool = Pool() + domain = ['OR', [ + ('description', '!=', None), + ('description', '!=', ''), + ('description', *clause[1:]), + ], + ] + for origin, _ in cls.get_origin(): + if not origin: + continue + Model = pool.get(origin) + if 'description' in Model._fields: + domain.append( + ('origin.description', *clause[1:3], origin, *clause[3:])) + return domain + + +class Move(DescriptionOriginMixin, ModelSQL, ModelView): 'Account Move' __name__ = 'account.move' _rec_name = 'number' @@ -800,7 +841,7 @@ class MoveLineMixin: return [('account.rec_name',) + tuple(clause[1:])] -class Line(MoveLineMixin, ModelSQL, ModelView): +class Line(DescriptionOriginMixin, MoveLineMixin, ModelSQL, ModelView): 'Account Move Line' __name__ = 'account.move.line' @@ -870,9 +911,10 @@ class Line(MoveLineMixin, ModelSQL, ModelView): fields.Reference("Move Origin", selection='get_move_origin'), 'get_move_field', searcher='search_move_field') description = fields.Char('Description', states=_states) - move_description = fields.Function(fields.Char('Move Description', - states=_states), - 'get_move_field', setter='set_move_field', + move_description_used = fields.Function( + fields.Char("Move Description", states=_states), + 'get_move_field', + setter='set_move_field', searcher='search_move_field') amount_second_currency = Monetary( "Amount Second Currency", diff --git a/modules/account/tests/scenario_move_line_group.rst b/modules/account/tests/scenario_move_line_group.rst index bb8e6a663e..30af19ac51 100644 --- a/modules/account/tests/scenario_move_line_group.rst +++ b/modules/account/tests/scenario_move_line_group.rst @@ -138,7 +138,7 @@ Group lines:: Decimal('50') >>> delegate_to.maturity_date == period.start_date + dt.timedelta(days=2) True - >>> delegate_to.move_description + >>> delegate_to.move_description_used 'Group lines' Cancelling the delegation move:: diff --git a/modules/account/view/general_ledger_line_list.xml b/modules/account/view/general_ledger_line_list.xml index 88d604576c..0f1cffc0a5 100644 --- a/modules/account/view/general_ledger_line_list.xml +++ b/modules/account/view/general_ledger_line_list.xml @@ -6,8 +6,8 @@ this repository contains the full copyright notices and license terms. --> - - + + diff --git a/modules/account/view/move_form.xml b/modules/account/view/move_form.xml index 1adcbdd338..995b6d53b4 100644 --- a/modules/account/view/move_form.xml +++ b/modules/account/view/move_form.xml @@ -19,8 +19,8 @@ this repository contains the full copyright notices and license terms. -->