From 32bf33fb23d54b93f988b94f56ff2b52c5c05590 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Mon, 3 Oct 2022 23:36:04 +0200 Subject: [PATCH] amount/rate/amount_2nd - ok+test --- book.py | 10 ++--- line.py | 107 +++++++++++++++++++++++++++------------------ tests/test_line.py | 38 +++++++++++++++- 3 files changed, 106 insertions(+), 49 deletions(-) diff --git a/book.py b/book.py index e480030..873e765 100644 --- a/book.py +++ b/book.py @@ -4,7 +4,7 @@ # full copyright notices and license terms. from trytond.model import Workflow, ModelView, ModelSQL, fields, Check, tree -from trytond.pyson import Eval, Or, Bool, Id +from trytond.pyson import Eval, Or, Bool, Id, Len from trytond.exceptions import UserError from trytond.i18n import gettext from trytond.transaction import Transaction @@ -59,7 +59,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView): states={ 'readonly': Or( STATES['readonly'], - Bool(Eval('lines')), + Len(Eval('lines')) > 0, ), }, depends=DEPENDS+['lines']) owner = fields.Many2One(string='Owner', required=True, select=True, @@ -97,7 +97,7 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView): states={ 'readonly': Or( STATES2['readonly'], - Bool(Eval('lines')), + Len(Eval('lines')) > 0, ), 'invisible': STATES2['invisible'], 'required': ~STATES2['invisible'], @@ -122,11 +122,11 @@ class Book(tree(separator='/'), Workflow, ModelSQL, ModelView): 'on_change_with_currency_digits') currency = fields.Many2One(string='Currency', select=True, - model_name='currency.currency', readonly=True, + model_name='currency.currency', states={ 'readonly': Or( STATES2['readonly'], - Bool(Eval('lines', [])), + Len(Eval('lines', [])) > 0, ), }, depends=DEPENDS2+['lines']) currency_digits = fields.Function(fields.Integer(string='Currency Digits', diff --git a/line.py b/line.py index 2461e12..f82e6fd 100644 --- a/line.py +++ b/line.py @@ -105,6 +105,7 @@ class Line(Workflow, ModelSQL, ModelView): domain=[ ('owner.id', '=', Eval('owner_cashbook', -1)), ('id', '!=', Eval('cashbook', -1)), + ('btype', '!=', None), ], states={ 'readonly': STATES['readonly'], @@ -313,8 +314,13 @@ class Line(Workflow, ModelSQL, ModelView): 'description': line.description, 'booktransf': line.cashbook.id, 'reference': line.id, + 'amount': line.amount \ + if line.cashbook.currency.id == line.booktransf.currency.id \ + else line.amount_2nd_currency, + 'amount_2nd_currency': line.amount \ + if line.cashbook.currency.id != line.booktransf.currency.id \ + else None, } - values.update(line.get_amount_by_second_currency(line.booktransf.currency)) values.update(cls.get_debit_credit(values)) to_create_line.append(values) elif line.bookingtype in ['spout', 'spin']: @@ -562,6 +568,31 @@ class Line(Workflow, ModelSQL, ModelView): self.splitlines = [] self.booktransf = None + @fields.depends('booktransf', '_parent_booktransf.currency', 'date',\ + 'currency', 'amount', 'amount_2nd_currency') + def on_change_booktransf(self): + """ update amount_2nd_currency + """ + pool = Pool() + Currency = pool.get('currency.currency') + IrDate = pool.get('ir.date') + + if (self.booktransf is None) or (self.currency is None): + return + + if self.amount is not None: + if self.booktransf.currency.id != self.currency.id: + with Transaction().set_context({ + 'date': self.date or IrDate.today(), + }): + self.amount_2nd_currency = Currency.compute( + self.currency, + self.amount, + self.booktransf.currency + ) + return + self.amount_2nd_currency = None + @fields.depends('currency', 'booktransf', '_parent_booktransf.currency', \ 'amount', 'amount_2nd_currency', 'rate_2nd_currency') def on_change_amount(self): @@ -570,38 +601,18 @@ class Line(Workflow, ModelSQL, ModelView): self.on_change_rate_2nd_currency() @fields.depends('booktransf', '_parent_booktransf.currency', \ - 'currency', 'amount', 'amount_2nd_currency', 'rate_2nd_currency') - def on_change_booktransf(self): - """ update amount_2nd_currency - """ - Currency = Pool().get('currency.currency') - - if self.booktransf: - if self.currency: - if self.amount is not None: - if self.booktransf.currency.id != self.currency.id: - self.amount_2nd_currency = Currency.compute( - self.currency, - self.amount, - self.booktransf.currency - ) - self.rate_2nd_currency = self.on_change_with_rate_2nd_currency() - return - self.amount_2nd_currency = None - - @fields.depends('currency', 'booktransf', '_parent_booktransf.currency', \ 'amount', 'amount_2nd_currency', 'rate_2nd_currency') def on_change_rate_2nd_currency(self): """ update amount_2nd_currency by rate """ - if (self.amount is None) or (self.rate_2nd_currency is None): + if (self.amount is None) or (self.rate_2nd_currency is None) or \ + (self.booktransf is None): return - if self.currency: - if self.booktransf: - if self.currency.id != self.booktransf.currency.id: - self.amount_2nd_currency = self.booktransf.currency.round( - self.amount * self.rate_2nd_currency - ) + + if self.currency.id != self.booktransf.currency.id: + self.amount_2nd_currency = self.booktransf.currency.round( + self.amount * self.rate_2nd_currency + ) @classmethod def set_rate_2nd_currency(cls, lines, name, value): @@ -631,15 +642,20 @@ class Line(Workflow, ModelSQL, ModelView): if len(to_write) > 0: Line2.write(*to_write) - @fields.depends('amount', 'amount_2nd_currency', 'currency2nd') + @fields.depends('amount', 'amount_2nd_currency', 'rate_2nd_currency') + def on_change_amount_2nd_currency(self): + """ update rate_2nd_currency by rate + """ + self.rate_2nd_currency = self.on_change_with_rate_2nd_currency() + + @fields.depends('amount', 'amount_2nd_currency') def on_change_with_rate_2nd_currency(self, name=None): """ get current rate from amount """ Rate = Pool().get('currency.currency.rate') if (self.amount is not None) and \ - (self.amount_2nd_currency is not None) and \ - (self.currency2nd is not None): + (self.amount_2nd_currency is not None): if self.amount != Decimal('0.0'): exp = Decimal(Decimal(1) / 10 ** Rate.rate.digits[1]) return (self.amount_2nd_currency / self.amount).quantize(exp) @@ -863,24 +879,29 @@ class Line(Workflow, ModelSQL, ModelView): pool = Pool() Currency = pool.get('currency.currency') Cashbook = pool.get('cashbook.book') + IrDate = pool.get('ir.date') cashbook = values.get('cashbook', None) booktransf = values.get('booktransf', None) amount = values.get('amount', None) amount_2nd_currency = values.get('amount_2nd_currency', None) - if cashbook: - if booktransf: - if amount is not None: - if amount_2nd_currency is None: - cashbook = Cashbook(cashbook) - booktransf = Cashbook(booktransf) - if cashbook.currency.id != booktransf.currency.id: - values['amount_2nd_currency'] = Currency.compute( - cashbook.currency, - amount, - booktransf.currency, - ) + if (cashbook is None) or (booktransf is None): + return values + + if amount is not None: + if amount_2nd_currency is None: + cashbook = Cashbook(cashbook) + booktransf = Cashbook(booktransf) + if cashbook.currency.id != booktransf.currency.id: + with Transaction().set_context({ + 'date': values.get('date', IrDate.today()), + }): + values['amount_2nd_currency'] = Currency.compute( + cashbook.currency, + amount, + booktransf.currency, + ) return values @classmethod diff --git a/tests/test_line.py b/tests/test_line.py index f1a2463..f2f6d1a 100644 --- a/tests/test_line.py +++ b/tests/test_line.py @@ -24,12 +24,25 @@ class LineTestCase(ModuleTestCase): pool = Pool() Book = pool.get('cashbook.book') Lines = pool.get('cashbook.line') + Currency = pool.get('currency.currency') types = self.prep_type() company = self.prep_company() # add EURO, set company-currency to EURO (usd, euro) = self.prep_2nd_currency(company) + self.assertEqual(len(usd.rates), 1) + self.assertEqual(usd.rates[0].date, date(2022, 5, 2)) + self.assertEqual(usd.rates[0].rate, Decimal('1.05')) + Currency.write(*[ + [usd], + { + 'rates': [('create', [{ + 'rate': Decimal('1.02'), + 'date': date(2022, 6, 1), + }])], + }]) + self.assertEqual(len(usd.rates), 2) books = Book.create([{ 'name': 'Book USD', @@ -50,6 +63,7 @@ class LineTestCase(ModuleTestCase): self.assertEqual(books[0].rec_name, 'Book USD | 0.00 usd | Open') self.assertEqual(books[1].rec_name, 'Book EURO | 0.00 € | Open') + # rate @ 2022-05-02: 1.05 Book.write(*[ [books[0]], { @@ -68,7 +82,27 @@ class LineTestCase(ModuleTestCase): # auto-created self.assertEqual(books[0].lines[0].amount_2nd_currency, Decimal('9.52')) self.assertEqual(books[0].lines[0].rate_2nd_currency, Decimal('0.952')) + Lines.delete(books[0].lines) + # rate @ 2022-06-01: 1.02 + Book.write(*[ + [books[0]], + { + 'lines': [('create', [{ + 'date': date(2022, 6, 1), + 'description': 'Transfer USD --> EUR', + 'bookingtype': 'mvout', + 'amount': Decimal('10.0'), + 'booktransf': books[1].id, + }])], + }]) + self.assertEqual(len(books[0].lines), 1) + self.assertEqual(books[0].lines[0].rec_name, + '06/01/2022|to|-10.00 usd|Transfer USD --> EUR [Book EURO | 0.00 € | Open]') + self.assertEqual(books[0].lines[0].amount, Decimal('10.0')) + # auto-created + self.assertEqual(books[0].lines[0].amount_2nd_currency, Decimal('9.80')) + self.assertEqual(books[0].lines[0].rate_2nd_currency, Decimal('0.98')) Lines.delete(books[0].lines) Book.write(*[ @@ -117,7 +151,8 @@ class LineTestCase(ModuleTestCase): self.assertEqual(books[0].lines[0].amount, Decimal('12.0')) books[0].lines[0].amount_2nd_currency = Decimal('10.5') - self.assertEqual(books[0].lines[0].on_change_with_rate_2nd_currency(), Decimal('0.875')) + books[0].lines[0].on_change_amount_2nd_currency() + self.assertEqual(books[0].lines[0].rate_2nd_currency, Decimal('0.875')) self.assertEqual(books[0].lines[0].amount_2nd_currency, Decimal('10.5')) self.assertEqual(books[0].lines[0].amount, Decimal('12.0')) @@ -171,6 +206,7 @@ class LineTestCase(ModuleTestCase): self.assertEqual(len(books[1].lines), 0) self.assertEqual(books[0].lines[0].rec_name, '05/05/2022|to|-10.00 usd|Transfer USD --> EUR [Book EURO | 0.00 € | Open]') + self.assertEqual(books[0].lines[0].amount_2nd_currency, Decimal('9.52')) self.assertEqual(books[0].lines[0].reference, None) self.assertEqual(len(books[0].lines[0].references), 0) self.assertEqual(books[0].lines[0].reconciliation, None)