From e51932e7326a707102d47aee2a2a817878e4b0e8 Mon Sep 17 00:00:00 2001 From: Frederik Jaeckel Date: Fri, 10 Mar 2023 16:45:50 +0100 Subject: [PATCH] report: add totla-yield, tests todo --- investment.py | 233 ++++++++++++++++++++++++++----------------- locale/de.po | 8 ++ locale/en.po | 8 ++ tests/test_report.py | 144 ++++++++++++++++++++------ 4 files changed, 269 insertions(+), 124 deletions(-) diff --git a/investment.py b/investment.py index 3b339be..ffe7540 100644 --- a/investment.py +++ b/investment.py @@ -20,12 +20,15 @@ class InvestmentEvaluation(metaclass=PoolMeta): ('cashbooks_gldiff', gettext('cashbook_report.msg_dtype_cashbook_gldiff')), ('cashbooks_glperc', gettext('cashbook_report.msg_dtype_cashbook_glperc')), ('cashbooks_glvalue', gettext('cashbook_report.msg_dtype_cashbooks_glvalue')), + ('cashbooks_glyield', gettext('cashbook_report.msg_dtype_cashbooks_glyield')), ('category_gldiff', gettext('cashbook_report.msg_dtype_category_gldiff')), ('category_glvalue', gettext('cashbook_report.msg_dtype_category_glvalue')), ('category_glperc', gettext('cashbook_report.msg_dtype_category_glperc')), + ('category_glyield', gettext('cashbook_report.msg_dtype_category_glyield')), ('types_gldiff', gettext('cashbook_report.msg_dtype_types_gldiff')), ('types_glvalue', gettext('cashbook_report.msg_dtype_types_glvalue')), ('types_glperc', gettext('cashbook_report.msg_dtype_types_glperc')), + ('types_glyield', gettext('cashbook_report.msg_dtype_types_glyield')), ]) return result @@ -35,26 +38,6 @@ class InvestmentEvaluation(metaclass=PoolMeta): class InvestmentLine(metaclass=PoolMeta): __name__ = 'cashbook_report.eval_line' - def get_value_types_glperc(self): - """ get percent of profit/loss by type - """ - if self.dtype is None: - return None - - return self.get_percent_by_query([ - ('btype.id', '=', self.dtype.id), - ]) - - def get_value_category_glperc(self): - """ get percent of profit/loss by category - """ - if self.category is None: - return None - - return self.get_percent_by_query([ - ('categories.id', '=', self.category.id), - ]) - def get_percent_by_query(self, query): """ get percentual difference of bookings in categories converted to currency of evaluation @@ -80,69 +63,6 @@ class InvestmentLine(metaclass=PoolMeta): ) return Decimal('0.0') - def get_value_types_glvalue(self): - """ get current value by type - """ - if self.dtype is None: - return None - - return self.get_currentvalue_by_query([ - ('btype.id', '=', self.dtype.id), - ]) - - def get_value_category_glvalue(self): - """ get current value by category - """ - if self.category is None: - return None - - return self.get_currentvalue_by_query([ - ('categories.id', '=', self.category.id), - ]) - - def get_currentvalue_by_query(self, query): - """ get current value of bookings in categories - converted to currency of evaluation - """ - Book = Pool().get('cashbook.book') - - query2 = [('state', '=', 'open')] - query2.extend(query) - books = Book.search(query2) - - result = Decimal('0.0') - if len(books) > 0: - for book in books: - if book.feature == 'asset': - if book.current_value_ref is not None: - result += book.current_value_ref - else : - if book.balance_ref is not None: - result += book.balance_ref - return self.convert_to_evalcurrency( - books[0].company.currency, result) - return result - - def get_value_types_gldiff(self): - """ get difference amount by type - """ - if self.dtype is None: - return None - - return self.get_difference_by_query([ - ('btype.id', '=', self.dtype.id), - ]) - - def get_value_category_gldiff(self): - """ get difference amount by category - """ - if self.category is None: - return None - - return self.get_difference_by_query([ - ('categories.id', '=', self.category.id), - ]) - def get_difference_by_query(self, query): """ get difference amount of bookings in categories converted to currency of evaluation @@ -163,6 +83,137 @@ class InvestmentLine(metaclass=PoolMeta): books[0].company.currency, result) return result + def get_currentvalue_by_query(self, query): + """ get current value of bookings in categories + converted to currency of evaluation + """ + Book = Pool().get('cashbook.book') + + query2 = [('state', '=', 'open')] + query2.extend(query) + books = Book.search(query2) + + result = Decimal('0.0') + if len(books) > 0: + for book in books: + if (book.feature == 'asset') or \ + ((book.feature is None) and (book.current_value_ref is not None)): + if book.current_value_ref is not None: + result += book.current_value_ref + else : + if book.balance_ref is not None: + result += book.balance_ref + return self.convert_to_evalcurrency( + books[0].company.currency, result) + return result + + def get_totalyield_by_query(self, query): + """ get total yield of cashbookings + converted to currency of evaluation + """ + Book = Pool().get('cashbook.book') + + query2 = [('state', '=', 'open')] + query2.extend(query) + books = Book.search(query2) + + result = Decimal('0.0') + if len(books) > 0: + for book in books: + if (book.feature == 'asset') and (book.yield_balance is not None): + result += self.convert_to_evalcurrency( + books[0].currency, book.yield_balance) + return result + + def get_value_category_glperc(self): + """ get percent of profit/loss by category + """ + if self.category is None: + return None + + return self.get_percent_by_query([ + ('categories.id', '=', self.category.id), + ]) + + def get_value_category_gldiff(self): + """ get difference amount by category + """ + if self.category is None: + return None + + return self.get_difference_by_query([ + ('categories.id', '=', self.category.id), + ]) + + def get_value_category_glvalue(self): + """ get current value by category + """ + if self.category is None: + return None + + return self.get_currentvalue_by_query([ + ('categories.id', '=', self.category.id), + ]) + + def get_value_category_glyield(self): + """ get total yield by type + """ + if self.category is None: + return None + + return self.get_totalyield_by_query([ + ('categories.id', '=', self.category.id), + ]) + + def get_value_types_glperc(self): + """ get percent of profit/loss by type + """ + if self.dtype is None: + return None + + return self.get_percent_by_query([ + ('btype.id', '=', self.dtype.id), + ]) + + def get_value_types_gldiff(self): + """ get difference amount by type + """ + if self.dtype is None: + return None + + return self.get_difference_by_query([ + ('btype.id', '=', self.dtype.id), + ]) + + def get_value_types_glvalue(self): + """ get current value by type + """ + if self.dtype is None: + return None + + return self.get_currentvalue_by_query([ + ('btype.id', '=', self.dtype.id), + ]) + + def get_value_types_glyield(self): + """ get total yield by type + """ + if self.dtype is None: + return None + + return self.get_totalyield_by_query([ + ('btype.id', '=', self.dtype.id), + ]) + + def get_value_cashbooks_glperc(self): + """ percent of profit/loss of cashbooks + """ + if self.cashbook: + if self.cashbook.feature == 'asset': + return self.cashbook.diff_percent + else : + return Decimal('0.0') + def get_value_cashbooks_gldiff(self): """ amount of profit/loss of cashbooks """ @@ -182,22 +233,22 @@ class InvestmentLine(metaclass=PoolMeta): Currency = Pool().get('currency.currency') if self.cashbook: - if self.cashbook.feature == 'asset': + if (self.cashbook.feature == 'asset') or \ + ((self.cashbook.feature is None) and (self.cashbook.current_value is not None)): return self.convert_to_evalcurrency( self.cashbook.currency, self.cashbook.current_value) else : return self.convert_to_evalcurrency( self.cashbook.currency, - self.cashbook.balance_ref) + self.cashbook.balance) - def get_value_cashbooks_glperc(self): - """ percent of profit/loss of cashbooks + def get_value_cashbooks_glyield(self): + """ total yield of investment """ if self.cashbook: - if self.cashbook.feature == 'asset': - return self.cashbook.diff_percent - else : - return Decimal('0.0') + return self.get_totalyield_by_query([ + ('id', '=', self.cashbook.id) + ]) # end InvestmentLine diff --git a/locale/de.po b/locale/de.po index 1a4cfa0..658c3df 100644 --- a/locale/de.po +++ b/locale/de.po @@ -26,6 +26,10 @@ msgctxt "model:ir.message,text:msg_dtype_cashbooks_glvalue" msgid "Cashbooks [Current Value]" msgstr "Kassenbücher [aktueller Wert]" +msgctxt "model:ir.message,text:msg_dtype_cashbooks_glyield" +msgid "Cashbooks [Total Yield]" +msgstr "Kassenbücher [Gesamtertrag]" + msgctxt "model:ir.message,text:msg_dtype_type" msgid "Types of Cashbooks [Amount]" msgstr "Typen von Kassenbüchern [Betrag]" @@ -62,6 +66,10 @@ msgctxt "model:ir.message,text:msg_dtype_category_glperc" msgid "Categories [Percent of Profit/Loss]" msgstr "Kategorien [Prozent Gewinn/Verlust]" +msgctxt "model:ir.message,text:msg_dtype_category_glyield" +msgid "Categories [Total Yield]" +msgstr "Kategorien [Gesamtertrag]" + msgctxt "model:ir.message,text:msg_name_graph" msgid "Graph: %(gname)s" msgstr "Diagramm: %(gname)s" diff --git a/locale/en.po b/locale/en.po index 3f49cf3..7472c99 100644 --- a/locale/en.po +++ b/locale/en.po @@ -22,6 +22,10 @@ msgctxt "model:ir.message,text:msg_dtype_cashbooks_glvalue" msgid "Cashbooks [Current Value]" msgstr "Cashbooks [Current Value]" +msgctxt "model:ir.message,text:msg_dtype_cashbooks_glyield" +msgid "Cashbooks [Total Yield]" +msgstr "Cashbooks [Total Yield]" + msgctxt "model:ir.message,text:msg_dtype_type" msgid "Types of Cashbooks [Amount]" msgstr "Types of Cashbooks [Amount]" @@ -58,6 +62,10 @@ msgctxt "model:ir.message,text:msg_dtype_category_glperc" msgid "Categories [Percent of Profit/Loss]" msgstr "Categories [Percent of Profit/Loss]" +msgctxt "model:ir.message,text:msg_dtype_category_glyield" +msgid "Categories [Total Yield]" +msgstr "Categories [Total Yield]" + msgctxt "model:ir.message,text:msg_name_graph" msgid "Graph: %(gname)s" msgstr "Graph: %(gname)s" diff --git a/tests/test_report.py b/tests/test_report.py index cc211bc..8004a45 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -7,12 +7,12 @@ from trytond.tests.test_tryton import ModuleTestCase, with_transaction, activate from trytond.pool import Pool from trytond.transaction import Transaction from trytond.exceptions import UserError -from trytond.modules.cashbook.tests import CashbookTestCase +from trytond.modules.cashbook_investment.tests import CashbookInvestmentTestCase from datetime import date from decimal import Decimal -class ReportTestCase(CashbookTestCase): +class ReportTestCase(CashbookInvestmentTestCase): 'Test cashbook book report module' module = 'cashbook_report' @@ -28,13 +28,28 @@ class ReportTestCase(CashbookTestCase): """ pool = Pool() Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') + BookType = pool.get('cashbook.type') ResUser = pool.get('res.user') user_admin, = ResUser.search([]) - type_cash = self.prep_type() - type_bank = self.prep_type(name='Bank', short='BK') - company = self.prep_company() + company = self.prep_company() + asset_cfg = self.prep_yield_config( + fee = 'Fee', + dividend = 'Dividend', + gainloss = 'Gain-Loss', + company = company) + + type_cash, = BookType.search([('name', '=', 'Cash')]) + type_bank = self.prep_type(name='Bank', short='BK') + type_asset = self.prep_type(name='Asset', short='A') + + BookType.write(*[ + [type_asset], + { + 'feature': 'asset', + }]) ResUser.write(*[ [user_admin], { @@ -43,9 +58,14 @@ class ReportTestCase(CashbookTestCase): }]) self.assertEqual(user_admin.company.id, company.id) - (usd, euro) = self.prep_2nd_currency(company) sequ_id = self.prep_sequence().id category = self.prep_category(cattype='in') + asset = self.prep_asset_item( + company=company, + product = self.prep_asset_product(name='Product 1')) + self.assertEqual(asset.symbol, 'usd/u') + (usd, euro) = self.prep_2nd_currency(company) + party = self.prep_party() books = Book.create([{ 'name': 'Book 1', @@ -113,8 +133,43 @@ class ReportTestCase(CashbookTestCase): 'category': category.id, 'party': party.id, }])], + }, { + 'name': 'Book 4 - Asset', + 'btype': type_asset.id, + 'asset': asset.id, + 'quantity_uom': asset.uom.id, + 'company': company.id, + 'currency': euro.id, + 'number_sequ': sequ_id, + 'start_date': date(2022, 4, 1), + 'lines': [('create', [{ + 'date': date(2022, 5, 1), + 'description': 'Buy Shares', + 'bookingtype': 'in', + 'amount': Decimal('100.0'), + 'quantity': Decimal('1.0'), + 'category': category.id, + 'party': party.id, + }, { + 'date': date(2022, 5, 5), + 'description': 'Fee', + 'bookingtype': 'out', + 'amount': Decimal('2.5'), + 'quantity': Decimal('0.0'), + 'category': asset_cfg.fee_category.id, + 'party': party.id, + }, { + 'date': date(2022, 5, 3), + 'description': 'Dividend', + 'bookingtype': 'in', + 'amount': Decimal('5.0'), + 'quantity': Decimal('0.0'), + 'category': asset_cfg.dividend_category.id, + 'party': party.id, + }])], }]) - self.assertEqual(len(books), 3) + Line.wfcheck([line for book in books for line in book.lines]) + self.assertEqual(len(books), 4) self.assertEqual(books[0].name, 'Book 1') self.assertEqual(books[0].btype.rec_name, 'CAS - Cash') self.assertEqual(len(books[0].lines), 2) @@ -129,6 +184,11 @@ class ReportTestCase(CashbookTestCase): self.assertEqual(books[2].btype.rec_name, 'BK - Bank') self.assertEqual(len(books[2].lines), 2) self.assertEqual(books[2].balance, Decimal('23.0')) + + self.assertEqual(books[3].name, 'Book 4 - Asset') + self.assertEqual(books[3].btype.rec_name, 'A - Asset') + self.assertEqual(len(books[3].lines), 3) + self.assertEqual(books[3].balance, Decimal('102.5')) return books @with_transaction() @@ -158,6 +218,7 @@ class ReportTestCase(CashbookTestCase): ('cashbook_hasbookings', '=', True) ]), 2) + Lines.wfedit(books[2].lines) Lines.delete(books[2].lines) self.assertEqual(euro.cashbook_hasbookings, False) @@ -264,13 +325,15 @@ class ReportTestCase(CashbookTestCase): 'dtype': 'types', 'types': [('add', [x.id for x in Type.search([])])], }]) - self.assertEqual(len(evaluation2.types), 2) + self.assertEqual(len(evaluation2.types), 3) self.assertEqual(evaluation2.currency.rec_name, 'Euro') - self.assertEqual(len(evaluation2.line_values), 2) - self.assertEqual(evaluation2.line_values[0].name, 'BK - Bank') - self.assertEqual(evaluation2.line_values[0].balance, Decimal('0.0')) - self.assertEqual(evaluation2.line_values[1].name, 'CAS - Cash') - self.assertEqual(evaluation2.line_values[1].balance, Decimal('35.71')) + self.assertEqual(len(evaluation2.line_values), 3) + self.assertEqual(evaluation2.line_values[0].name, 'A - Asset') + self.assertEqual(evaluation2.line_values[0].balance, Decimal('35.71')) + self.assertEqual(evaluation2.line_values[1].name, 'BK - Bank') + self.assertEqual(evaluation2.line_values[1].balance, Decimal('0.0')) + self.assertEqual(evaluation2.line_values[2].name, 'CAS - Cash') + self.assertEqual(evaluation2.line_values[2].balance, Decimal('35.71')) evaluation3, = Evaluation.create([{ 'name': 'Evaluation User 1 - Currencies', @@ -457,8 +520,8 @@ class ReportTestCase(CashbookTestCase): 'dtype': 'cashbooks', 'cashbooks': [('add', [x.id for x in books])], }]) - self.assertEqual(len(evaluation.cashbooks), 3) - self.assertEqual(len(evaluation.line_values), 3) + self.assertEqual(len(evaluation.cashbooks), 4) + self.assertEqual(len(evaluation.line_values), 4) self.assertEqual(evaluation.line_values[0].name, 'Book 1 | 25.00 usd | Open') self.assertEqual(evaluation.line_values[0].name_line, None) @@ -512,7 +575,7 @@ class ReportTestCase(CashbookTestCase): 'dtype': 'cashbooks', 'cashbooks': [('add', [x.id for x in books])], }]) - self.assertEqual(len(evaluation.cashbooks), 3) + self.assertEqual(len(evaluation.cashbooks), 4) self.assertEqual(len(evaluation.types), 0) self.assertEqual(len(evaluation.currencies), 0) self.assertEqual(len(evaluation.categories), 0) @@ -525,7 +588,7 @@ class ReportTestCase(CashbookTestCase): { 'dtype': 'cashbooks_gldiff', }]) - self.assertEqual(len(evaluation.cashbooks), 3) + self.assertEqual(len(evaluation.cashbooks), 4) self.assertEqual(len(evaluation.types), 0) self.assertEqual(len(evaluation.currencies), 0) self.assertEqual(len(evaluation.categories), 0) @@ -535,7 +598,7 @@ class ReportTestCase(CashbookTestCase): { 'dtype': 'cashbooks_glperc', }]) - self.assertEqual(len(evaluation.cashbooks), 3) + self.assertEqual(len(evaluation.cashbooks), 4) self.assertEqual(len(evaluation.types), 0) self.assertEqual(len(evaluation.currencies), 0) self.assertEqual(len(evaluation.categories), 0) @@ -549,7 +612,7 @@ class ReportTestCase(CashbookTestCase): 'types': [('add', [x.id for x in Types.search([])])], }]) self.assertEqual(len(evaluation.cashbooks), 0) - self.assertEqual(len(evaluation.types), 2) + self.assertEqual(len(evaluation.types), 3) self.assertEqual(len(evaluation.currencies), 0) self.assertEqual(len(evaluation.categories), 0) @@ -560,7 +623,7 @@ class ReportTestCase(CashbookTestCase): 'dtype': 'types', }]) self.assertEqual(len(evaluation.cashbooks), 0) - self.assertEqual(len(evaluation.types), 2) + self.assertEqual(len(evaluation.types), 3) self.assertEqual(len(evaluation.currencies), 0) self.assertEqual(len(evaluation.categories), 0) @@ -724,6 +787,7 @@ class ReportTestCase(CashbookTestCase): pool = Pool() Evaluation = pool.get('cashbook_report.evaluation') Book = pool.get('cashbook.book') + Line = pool.get('cashbook.line') company = self.prep_company() with Transaction().set_context({ @@ -772,6 +836,7 @@ class ReportTestCase(CashbookTestCase): books = self.prep_report_3books() cb_cat, = CbCategory.create([{'name': 'CB Category'}]) + Line.wfedit([books.lines]) Book.write(*[ books, { @@ -955,26 +1020,31 @@ class ReportTestCase(CashbookTestCase): """) - self.assertEqual(len(evaluation.cashbooks), 3) + self.assertEqual(len(evaluation.cashbooks), 4) self.assertEqual(evaluation.cashbooks[0].rec_name, 'Book 1 | 25.00 usd | Open') self.assertEqual(evaluation.cashbooks[1].rec_name, 'Book 2 | 12.50 usd | Open') self.assertEqual(evaluation.cashbooks[2].rec_name, 'Book 3 | 23.00 € | Open') + self.assertEqual(evaluation.cashbooks[3].rec_name, 'Book 4 - Asset | 102.50 € | Open | 1.0000 u') self.assertEqual(evaluation.cashbooks[0].currency.code, 'usd') self.assertEqual(evaluation.cashbooks[1].currency.code, 'usd') self.assertEqual(evaluation.cashbooks[2].currency.code, 'EUR') + self.assertEqual(evaluation.cashbooks[3].currency.code, 'EUR') - self.assertEqual(len(evaluation.line_values), 3) + self.assertEqual(len(evaluation.line_values), 4) self.assertEqual(evaluation.line_values[0].name, 'Book 1 | 25.00 usd | Open') self.assertEqual(evaluation.line_values[1].name, 'Book 2 | 12.50 usd | Open') self.assertEqual(evaluation.line_values[2].name, 'Book 3 | 23.00 € | Open') + self.assertEqual(evaluation.line_values[3].name, 'Book 4 - Asset | 102.50 € | Open | 1.0000 u') self.assertEqual(evaluation.line_values[0].eval_currency.code, 'EUR') self.assertEqual(evaluation.line_values[1].eval_currency.code, 'EUR') self.assertEqual(evaluation.line_values[2].eval_currency.code, 'EUR') + self.assertEqual(evaluation.line_values[3].eval_currency.code, 'EUR') self.assertEqual(evaluation.line_values[0].balance, Decimal('23.81')) self.assertEqual(evaluation.line_values[1].balance, Decimal('11.90')) self.assertEqual(evaluation.line_values[2].balance, Decimal('23.00')) + self.assertEqual(evaluation.line_values[3].balance, Decimal('102.50')) @with_transaction() def test_report_chart_pie_type_red(self): @@ -1006,19 +1076,27 @@ class ReportTestCase(CashbookTestCase): # 37.50 USD, Cash # 23.00 EUR, Bank - self.assertEqual(len(evaluation.types), 2) - self.assertEqual(evaluation.types[0].rec_name, 'BK - Bank') - self.assertEqual(evaluation.types[1].rec_name, 'CAS - Cash') - # 23.00 EUR - self.assertEqual(len(evaluation.line_values), 2) + self.assertEqual(len(evaluation.types), 3) + self.assertEqual(evaluation.types[0].rec_name, 'A - Asset') + self.assertEqual(evaluation.types[1].rec_name, 'BK - Bank') + self.assertEqual(evaluation.types[2].rec_name, 'CAS - Cash') + + self.assertEqual(len(evaluation.line_values), 3) + + # xx.xx USD --> EUR + self.assertEqual(evaluation.line_values[0].name, 'A - Asset') self.assertEqual(evaluation.line_values[0].eval_currency.code, 'EUR') - self.assertEqual(evaluation.line_values[0].name, 'BK - Bank') - self.assertEqual(evaluation.line_values[0].balance, Decimal('23.0')) + self.assertEqual(evaluation.line_values[0].balance, Decimal('102.50')) + + # 23.00 EUR + self.assertEqual(evaluation.line_values[1].eval_currency.code, 'EUR') + self.assertEqual(evaluation.line_values[1].name, 'BK - Bank') + self.assertEqual(evaluation.line_values[1].balance, Decimal('23.0')) # 37.50 USD --> EUR - self.assertEqual(evaluation.line_values[1].name, 'CAS - Cash') - self.assertEqual(evaluation.line_values[1].eval_currency.code, 'EUR') - self.assertEqual(evaluation.line_values[1].balance, Decimal('35.71')) + self.assertEqual(evaluation.line_values[2].name, 'CAS - Cash') + self.assertEqual(evaluation.line_values[2].eval_currency.code, 'EUR') + self.assertEqual(evaluation.line_values[2].balance, Decimal('35.71')) @with_transaction() def test_report_chart_pie_currency_red(self): @@ -1053,7 +1131,7 @@ class ReportTestCase(CashbookTestCase): self.assertEqual(len(evaluation.line_values), 2) self.assertEqual(evaluation.line_values[0].name, 'Euro') - self.assertEqual(evaluation.line_values[0].balance, Decimal('23.0')) + self.assertEqual(evaluation.line_values[0].balance, Decimal('125.5')) self.assertEqual(evaluation.line_values[1].name, 'usd') self.assertEqual(evaluation.line_values[1].balance, Decimal('35.71'))