diff --git a/CHANGELOG b/CHANGELOG index 82b8d85f11..2b42fabd9a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Use reference field for statement line relation * Create default statement journal * Add support for Python 3.10 * Remove support for Python 3.6 diff --git a/statement.py b/statement.py index 3670da56a6..73dae740af 100644 --- a/statement.py +++ b/statement.py @@ -7,6 +7,7 @@ from itertools import groupby from sql import Null from sql.aggregate import Max, Sum from sql.conditionals import Coalesce +from sql.operators import Concat from trytond.config import config from trytond.i18n import gettext @@ -250,12 +251,12 @@ class Statement(Workflow, ModelSQL, ModelView): invoices = set() for line in self.lines: - if (getattr(line, 'invoice', None) + if (line.invoice and line.invoice.currency == self.company.currency): invoices.add(line.invoice) for origin in self.origins: for line in origin.lines: - if (getattr(line, 'invoice', None) + if (line.invoice and line.invoice.currency == self.company.currency): invoices.add(line.invoice) invoice_id2amount_to_pay = {} @@ -270,7 +271,8 @@ class Statement(Workflow, ModelSQL, ModelView): for origin in origins: lines = list(origin.lines) for line in lines: - if (getattr(line, 'invoice', None) and line.id + if (line.invoice + and line.id and line.invoice.id in invoice_id2amount_to_pay): amount_to_pay = invoice_id2amount_to_pay[line.invoice.id] if (amount_to_pay @@ -297,7 +299,7 @@ class Statement(Workflow, ModelSQL, ModelView): invoices = set() for line in self.lines: - if (getattr(line, 'invoice', None) + if (line.invoice and line.invoice.currency == self.company.currency): invoices.add(line.invoice) invoice_id2amount_to_pay = {} @@ -311,7 +313,7 @@ class Statement(Workflow, ModelSQL, ModelView): lines = list(self.lines) line_offset = 0 for index, line in enumerate(self.lines or []): - if getattr(line, 'invoice', None) and line.id: + if line.invoice and line.id: if line.invoice.id not in invoice_id2amount_to_pay: continue amount_to_pay = invoice_id2amount_to_pay[line.invoice.id] @@ -495,7 +497,7 @@ class Statement(Workflow, ModelSQL, ModelView): gettext('account_statement' '.msg_statement_invoice_paid_cancelled')) Line.write(paid_cancelled_invoice_lines, { - 'invoice': None, + 'related_to': None, }) cls.create_move(statements) @@ -504,9 +506,10 @@ class Statement(Workflow, ModelSQL, ModelView): 'state': 'validated', }) common_lines = [l for l in Line.search([ - ('statement.state', '=', 'draft'), - ('invoice.state', 'in', ['posted', 'paid']), - ]) + ('statement.state', '=', 'draft'), + ('related_to.state', 'in', ['posted', 'paid'], + 'account.invoice'), + ]) if l.invoice.reconciled] if common_lines: warning_key = '_'.join(str(l.id) for l in common_lines) @@ -515,7 +518,7 @@ class Statement(Workflow, ModelSQL, ModelView): gettext('account_statement' '.msg_statement_paid_invoice_draft')) Line.write(common_lines, { - 'invoice': None, + 'related_to': None, }) @classmethod @@ -757,15 +760,22 @@ class Line( ('company', '=', Eval('company', -1)), ], depends=['company']) - invoice = fields.Many2One('account.invoice', 'Invoice', - domain=[ - ('company', '=', Eval('company', -1)), - If(Bool(Eval('party')), [('party', '=', Eval('party'))], []), - If(Bool(Eval('account')), [('account', '=', Eval('account'))], []), - If(Eval('statement_state') == 'draft', - ('state', '=', 'posted'), - ('state', '!=', '')), - ], + related_to = fields.Reference( + "Related To", 'get_relations', + domain={ + 'account.invoice': [ + ('company', '=', Eval('company', -1)), + If(Bool(Eval('party')), + ('party', '=', Eval('party')), + ()), + If(Bool(Eval('account')), + ('account', '=', Eval('account')), + ()), + If(Eval('statement_state') == 'draft', + ('state', '=', 'posted'), + ('state', '!=', '')), + ], + }, states=_states, context={'with_payment': False}, depends=['company', 'party', 'account'] + _depends) @@ -796,11 +806,51 @@ class Line( 'account_statement.msg_line_amount_non_zero'), ] + @classmethod + def __register__(cls, module): + table = cls.__table__() + + super().__register__(module) + + table_h = cls.__table_handler__(module) + cursor = Transaction().connection.cursor() + if table_h.column_exist('invoice'): + cursor.execute(*table.update( + [table.related_to], + [Concat('account.invoice,', table.invoice)], + where=table.invoice != Null)) + table_h.drop_column('invoice') + + @property + @fields.depends('related_to') + def invoice(self): + pool = Pool() + Invoice = pool.get('account.invoice') + related_to = getattr(self, 'related_to', None) + if isinstance(related_to, Invoice) and related_to.id >= 0: + return related_to + + @invoice.setter + def invoice(self, value): + self.related_to = value + @staticmethod def default_amount(): return Decimal(0) - @fields.depends('amount', 'party', 'invoice', 'date') + @classmethod + def _get_relations(cls): + "Return a list of Model names for related_to Reference" + return ['account.invoice'] + + @classmethod + def get_relations(cls): + Model = Pool().get('ir.model') + get_name = Model.get_name + models = cls._get_relations() + return [(None, '')] + [(m, get_name(m)) for m in models] + + @fields.depends('amount', 'party', 'date', methods=['invoice']) def on_change_party(self): if self.party: if self.amount: @@ -817,8 +867,10 @@ class Line( else: self.invoice = None - @fields.depends('amount', 'party', 'account', 'invoice', 'statement', - 'date', '_parent_statement.journal') + @fields.depends( + 'amount', 'party', 'account', 'date', + 'statement', '_parent_statement.journal', + methods=['invoice']) def on_change_amount(self): Currency = Pool().get('currency.currency') if self.party: @@ -845,7 +897,7 @@ class Line( else: self.invoice = None - @fields.depends('account', 'invoice') + @fields.depends('account', methods=['invoice']) def on_change_account(self): if self.invoice: if self.account: @@ -854,8 +906,8 @@ class Line( else: self.invoice = None - @fields.depends('party', 'account', 'invoice') - def on_change_invoice(self): + @fields.depends('party', 'account', methods=['invoice']) + def on_change_related_to(self): if self.invoice: if not self.party: self.party = self.invoice.party @@ -915,7 +967,7 @@ class Line( else: default = default.copy() default.setdefault('move', None) - default.setdefault('invoice', None) + default.setdefault('related_to', None) return super(Line, cls).copy(lines, default=default) @classmethod diff --git a/tests/scenario_account_statement.rst b/tests/scenario_account_statement.rst index 162c3cffff..952cd74680 100644 --- a/tests/scenario_account_statement.rst +++ b/tests/scenario_account_statement.rst @@ -143,7 +143,7 @@ Received 180 from customer:: >>> statement_line.party = customer >>> statement_line.account == receivable True - >>> statement_line.invoice = customer_invoice1 + >>> statement_line.related_to = customer_invoice1 >>> statement_line.amount Decimal('100.00') >>> statement_line = statement.lines[-1] @@ -158,7 +158,7 @@ Received 180 from customer:: >>> statement_line.account == receivable True >>> statement_line.description = 'other description' - >>> statement_line.invoice = customer_invoice2 + >>> statement_line.related_to = customer_invoice2 >>> statement_line.amount Decimal('80.00') @@ -172,7 +172,7 @@ Paid 50 to customer:: >>> statement_line.amount = Decimal('-50') >>> statement_line.party = customer >>> statement_line.account = receivable - >>> statement_line.invoice = customer_credit_note + >>> statement_line.related_to = customer_credit_note Paid 50 to supplier:: @@ -183,7 +183,7 @@ Paid 50 to supplier:: >>> statement_line.party = supplier >>> statement_line.account == payable True - >>> statement_line.invoice = supplier_invoice + >>> statement_line.related_to = supplier_invoice >>> statement_line.amount Decimal('-50.00') >>> statement_line = statement.lines.pop() @@ -302,8 +302,8 @@ Let's test the negative amount version of the supplier/customer invoices:: >>> statement_line.party = customer >>> statement_line.account = receivable >>> statement_line.amount = Decimal(-120) - >>> statement_line.invoice = customer_invoice3 - >>> statement_line.invoice.id == customer_invoice3.id + >>> statement_line.related_to = customer_invoice3 + >>> statement_line.related_to.id == customer_invoice3.id True >>> statement_line = StatementLine() @@ -312,7 +312,7 @@ Let's test the negative amount version of the supplier/customer invoices:: >>> statement_line.party = supplier >>> statement_line.account = payable >>> statement_line.amount = Decimal(50) - >>> statement_line.invoice = supplier_invoice2 + >>> statement_line.related_to = supplier_invoice2 >>> statement_line.amount Decimal('40.00') >>> len(statement.lines) @@ -341,7 +341,7 @@ Testing the use of an invoice in multiple statements:: >>> statement_line.party = customer >>> statement_line.account = receivable >>> statement_line.amount = Decimal(300) - >>> statement_line.invoice = customer_invoice4 + >>> statement_line.related_to = customer_invoice4 >>> statement1.save() >>> statement2 = Statement(name='2', journal=statement_journal) @@ -351,7 +351,7 @@ Testing the use of an invoice in multiple statements:: >>> statement_line.party = customer >>> statement_line.account = receivable >>> statement_line.amount = Decimal(300) - >>> statement_line.invoice = customer_invoice4 + >>> statement_line.related_to = customer_invoice4 >>> statement2.save() >>> statement1.click('validate_statement') # doctest: +IGNORE_EXCEPTION_DETAIL @@ -366,10 +366,10 @@ Testing the use of an invoice in multiple statements:: 'validated' >>> statement1.reload() - >>> bool(statement1.lines[0].invoice) + >>> bool(statement1.lines[0].related_to) True >>> statement2.reload() - >>> bool(statement2.lines[0].invoice) + >>> bool(statement2.lines[0].related_to) False Testing balance validation:: diff --git a/tests/scenario_statement_origin_invoices.rst b/tests/scenario_statement_origin_invoices.rst index 2f07e18145..7b8b00812a 100644 --- a/tests/scenario_statement_origin_invoices.rst +++ b/tests/scenario_statement_origin_invoices.rst @@ -95,7 +95,7 @@ Pending amount is used to fill all invoices:: >>> origin, = statement.origins >>> line = origin.lines.new() - >>> line.invoice = customer_invoice1 + >>> line.related_to = customer_invoice1 >>> line.amount Decimal('100.00') >>> line.party == customer @@ -105,7 +105,7 @@ Pending amount is used to fill all invoices:: >>> origin.pending_amount Decimal('80.00') >>> line = origin.lines.new() - >>> line.invoice = customer_invoice2 + >>> line.related_to = customer_invoice2 >>> line.amount Decimal('80.00') >>> line.party == customer diff --git a/view/statement_line_form.xml b/view/statement_line_form.xml index e5ad083c83..04420e065c 100644 --- a/view/statement_line_form.xml +++ b/view/statement_line_form.xml @@ -16,8 +16,8 @@ this repository contains the full copyright notices and license terms. -->