diff --git a/evaluation.py b/evaluation.py index 513fc64..178c9ad 100644 --- a/evaluation.py +++ b/evaluation.py @@ -9,7 +9,8 @@ from trytond.transaction import Transaction from trytond.pool import Pool from trytond.i18n import gettext from .colors import sel_color as sel_bgcolor -from .templates import template_view_graph, template_view_line, cashbook_types +from .templates import template_view_graph, template_view_line, \ + cashbook_types, category_types sel_chart = [ @@ -77,7 +78,7 @@ class Evaluation(sequence_ordered(), ModelSQL, ModelView): relation_name='cashbook_report.eval_line', origin='evaluation', target='category', states={ - 'invisible': Eval('dtype', '') != 'categories', + 'invisible': Eval('dtype', '').in_(category_types), }, depends=['dtype']) line_values = fields.One2Many(string='Line Values', diff --git a/investment.py b/investment.py index d67e24c..ace4e73 100644 --- a/investment.py +++ b/investment.py @@ -19,7 +19,10 @@ class InvestmentEvaluation(metaclass=PoolMeta): result.extend([ ('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_glvalue', gettext('cashbook_report.msg_dtype_cashbooks_glvalue')), + ('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')), ]) return result @@ -29,6 +32,67 @@ class InvestmentEvaluation(metaclass=PoolMeta): class InvestmentLine(metaclass=PoolMeta): __name__ = 'cashbook_report.eval_line' + def get_value_category_glperc(self): + """ get percentual difference of bookings in categories + converted to currency of evaluation + """ + Book = Pool().get('cashbook.book') + + if self.category is None: + return None + + books = Book.search([ + ('state', '=', 'open'), + ('categories.id', '=', self.category.id), + ]) + value = Decimal('0.0') + amount = Decimal('0.0') + + if len(books) > 0: + value = sum([x.current_value_ref for x in books]) + amount = sum([x.balance_ref for x in books]) + if amount != Decimal('0.0'): + return ( + Decimal('100.0') * value / amount - Decimal('100.0') + ).quantize(Decimal(str(1 / 10 ** self.currency_digits))) + return Decimal('0.0') + + def get_value_category_glvalue(self): + """ get current value of bookings in categories + converted to currency of evaluation + """ + Book = Pool().get('cashbook.book') + + if self.category is None: + return None + + books = Book.search([ + ('state', '=', 'open'), + ('categories.id', '=', self.category.id), + ]) + result = Decimal('0.0') + if len(books) > 0: + result = sum([x.current_value_ref for x in books]) + return result + + def get_value_category_gldiff(self): + """ get difference amount of bookings in categories + converted to currency of evaluation + """ + Book = Pool().get('cashbook.book') + + if self.category is None: + return None + + books = Book.search([ + ('state', '=', 'open'), + ('categories.id', '=', self.category.id), + ]) + result = Decimal('0.0') + if len(books) > 0: + result = sum([x.current_value_ref - x.balance_ref for x in books]) + return result + def get_value_cashbooks_gldiff(self): """ amount of profit/loss of cashbooks """ diff --git a/line.py b/line.py index edb7b99..a44b266 100644 --- a/line.py +++ b/line.py @@ -11,7 +11,7 @@ from trytond.transaction import Transaction from trytond.i18n import gettext from trytond.exceptions import UserError from trytond.pool import Pool -from .templates import cashbook_types +from .templates import cashbook_types, category_types class EvaluationLine(ModelSQL, ModelView): @@ -39,7 +39,7 @@ class EvaluationLine(ModelSQL, ModelView): category = fields.Many2One(string='Category', select=True, ondelete='CASCADE', model_name='cashbook.bookcategory', states={ - 'required': Eval('eval_dtype', '') == 'categories', + 'required': Eval('eval_dtype', '').in_(category_types), }, depends=['eval_dtype']) # dtype + currency of evaluation @@ -164,7 +164,7 @@ class EvaluationLine(ModelSQL, ModelView): 'cashbook_report.msg_invalid_dtype', typename = gettext('cashbook_report.msg_dtype_currency'), )) - if (record.evaluation.dtype != 'categories') and \ + if (record.evaluation.dtype not in category_types) and \ (record.category is not None): raise UserError(gettext( 'cashbook_report.msg_invalid_dtype', diff --git a/locale/de.po b/locale/de.po index c3c2744..ba30cac 100644 --- a/locale/de.po +++ b/locale/de.po @@ -35,8 +35,20 @@ msgid "Currencies" msgstr "Währungen" msgctxt "model:ir.message,text:msg_dtype_category" -msgid "Categories" -msgstr "Kategorien" +msgid "Categories [Amount]" +msgstr "Kategorien [Betrag]" + +msgctxt "model:ir.message,text:msg_dtype_category_gldiff" +msgid "Categories [Amount of Profit/Loss]" +msgstr "Kategorien [Betrag Gewinn/Verlust]" + +msgctxt "model:ir.message,text:msg_dtype_category_glvalue" +msgid "Categories [Current Value]" +msgstr "Kategorien [aktueller Wert]" + +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_name_graph" msgid "Graph: %(gname)s" diff --git a/locale/en.po b/locale/en.po index 0966cbb..cd993f7 100644 --- a/locale/en.po +++ b/locale/en.po @@ -31,8 +31,20 @@ msgid "Currencies" msgstr "Currencies" msgctxt "model:ir.message,text:msg_dtype_category" -msgid "Categories" -msgstr "Categories" +msgid "Categories [Amount]" +msgstr "Categories [Amount]" + +msgctxt "model:ir.message,text:msg_dtype_category_gldiff" +msgid "Categories [Amount of Profit/Loss]" +msgstr "Categories [Amount of Profit/Loss]" + +msgctxt "model:ir.message,text:msg_dtype_category_glvalue" +msgid "Categories [Current Value]" +msgstr "Categories [Current Value]" + +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_name_graph" msgid "Graph: %(gname)s" diff --git a/message.xml b/message.xml index ec34ead..82d0674 100644 --- a/message.xml +++ b/message.xml @@ -27,7 +27,16 @@ full copyright notices and license terms. --> Currencies - Categories + Categories [Amount] + + + Categories [Amount of Profit/Loss] + + + Categories [Current Value] + + + Categories [Percent of Profit/Loss] Graph: %(gname)s diff --git a/templates.py b/templates.py index 95e3857..9c9e9af 100644 --- a/templates.py +++ b/templates.py @@ -4,6 +4,7 @@ # full copyright notices and license terms. cashbook_types = ['cashbooks', 'cashbooks_gldiff', 'cashbooks_glperc', 'cashbooks_glvalue'] +category_types = ['categories', 'category_gldiff', 'category_glvalue', 'category_glperc'] template_view_line = '' diff --git a/tests/test_report.py b/tests/test_report.py index c75cbe2..6e995cd 100644 --- a/tests/test_report.py +++ b/tests/test_report.py @@ -730,6 +730,7 @@ class ReportTestCase(CashbookTestCase): Asset = pool.get('investment.asset') Product = pool.get('product.template') Uom = pool.get('product.uom') + CbCategory = pool.get('cashbook.bookcategory') at, = AccType.create([{ 'name': 'depot', @@ -759,23 +760,50 @@ class ReportTestCase(CashbookTestCase): 'rate': Decimal('1750.0'), }, ])], }]) - - AccType.write(*[ - [books[0].btype], - { - 'feature': 'asset', - }]) + self.assertEqual(asset.rec_name, + 'Aurum | 1,750.0000 usd/u | 05/01/2022') books = self.prep_report_3books() + cb_cat, = CbCategory.create([{'name': 'CB Category'}]) Book.write(*[ books, { + 'btype': at.id, 'asset': asset.id, + 'categories': [('add', [cb_cat.id])], 'quantity_uom': asset.uom.id, 'quantity_digits': 3, + 'lines': [('write', + [books[0].lines[0].id], # usd + {'quantity': Decimal('2.0'), 'amount': Decimal('3000.0')}, + [books[0].lines[1].id], + {'quantity': Decimal('2.0'), 'amount': Decimal('3100.0')}, + [books[1].lines[0].id], # usd + {'quantity': Decimal('2.0'), 'amount': Decimal('3200.0')}, + [books[1].lines[1].id], + {'quantity': Decimal('2.0'), 'amount': Decimal('3300.0')}, + [books[2].lines[0].id], # euro + {'quantity': Decimal('2.0'), 'amount': Decimal('3300.0')}, + [books[2].lines[1].id], + {'quantity': Decimal('2.0'), 'amount': Decimal('3400.0')}, + )], }]) - self.assertEqual(books[0].rec_name, 'ss') + self.assertEqual(books[0].rec_name, 'Book 1 | 6,100.00 usd | Open | 4.000 u') + self.assertEqual(books[0].current_value, Decimal('7000.0')) + self.assertEqual(books[0].diff_amount, Decimal('900.0')) + self.assertEqual(books[0].diff_percent, Decimal('14.75')) + self.assertEqual(books[1].rec_name, 'Book 2 | 6,500.00 usd | Open | 4.000 u') + self.assertEqual(books[1].current_value, Decimal('7000.0')) + self.assertEqual(books[1].diff_amount, Decimal('500.0')) + self.assertEqual(books[1].diff_percent, Decimal('7.69')) + + self.assertEqual(books[2].rec_name, 'Book 3 | 6,700.00 € | Open | 4.000 u') + self.assertEqual(books[2].current_value, Decimal('6666.67')) + self.assertEqual(books[2].diff_amount, Decimal('-33.33')) + self.assertEqual(books[2].diff_percent, Decimal('-0.5')) + + # evaluation: amount-difference evaluation, = Evaluation.create([{ 'name': 'Evaluation 1', 'dtype': 'cashbooks_gldiff', @@ -789,9 +817,96 @@ class ReportTestCase(CashbookTestCase): self.assertEqual(evaluation.bgcolor, '#ffffc0') self.assertEqual(evaluation.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[0].balance, Decimal('857.14')) + self.assertEqual(evaluation.line_values[1].balance, Decimal('476.19')) + self.assertEqual(evaluation.line_values[2].balance, Decimal('-33.33')) + + # evaluation: percent-difference + evaluation2, = Evaluation.create([{ + 'name': 'Evaluation 2', + 'dtype': 'cashbooks_glperc', + 'chart': 'hbar', + 'cashbooks': [('add', [x.id for x in books])], + }]) + self.assertEqual(evaluation2.dtype, 'cashbooks_glperc') + self.assertEqual(evaluation2.chart, 'hbar') + self.assertEqual(evaluation2.legend, True) + self.assertEqual(evaluation2.maincolor, 'default') + self.assertEqual(evaluation2.bgcolor, '#ffffc0') + self.assertEqual(evaluation2.currency.code, 'EUR') + + self.assertEqual(evaluation2.line_values[0].balance, Decimal('14.75')) + self.assertEqual(evaluation2.line_values[1].balance, Decimal('7.69')) + self.assertEqual(evaluation2.line_values[2].balance, Decimal('-0.5')) + + # evaluation: percent-difference + evaluation3, = Evaluation.create([{ + 'name': 'Evaluation 3', + 'dtype': 'cashbooks_glvalue', + 'chart': 'hbar', + 'cashbooks': [('add', [x.id for x in books])], + }]) + self.assertEqual(evaluation3.dtype, 'cashbooks_glvalue') + self.assertEqual(evaluation3.chart, 'hbar') + self.assertEqual(evaluation3.legend, True) + self.assertEqual(evaluation3.maincolor, 'default') + self.assertEqual(evaluation3.bgcolor, '#ffffc0') + self.assertEqual(evaluation3.currency.code, 'EUR') + + self.assertEqual(evaluation3.line_values[0].balance, Decimal('6666.67')) + self.assertEqual(evaluation3.line_values[1].balance, Decimal('6666.67')) + self.assertEqual(evaluation3.line_values[2].balance, Decimal('6666.67')) + + # evaluation: category-current value + evaluation4, = Evaluation.create([{ + 'name': 'Evaluation 4', + 'dtype': 'category_glvalue', + 'chart': 'hbar', + 'categories': [('add', [cb_cat.id])], + }]) + self.assertEqual(evaluation4.dtype, 'category_glvalue') + self.assertEqual(evaluation4.chart, 'hbar') + self.assertEqual(evaluation4.legend, True) + self.assertEqual(evaluation4.maincolor, 'default') + self.assertEqual(evaluation4.bgcolor, '#ffffc0') + self.assertEqual(evaluation4.currency.code, 'EUR') + + self.assertEqual(len(evaluation4.line_values), 1) + self.assertEqual(evaluation4.line_values[0].balance, Decimal('20000.01')) + + # evaluation: category- difference amount + evaluation5, = Evaluation.create([{ + 'name': 'Evaluation 5', + 'dtype': 'category_gldiff', + 'chart': 'hbar', + 'categories': [('add', [cb_cat.id])], + }]) + self.assertEqual(evaluation5.dtype, 'category_gldiff') + self.assertEqual(evaluation5.chart, 'hbar') + self.assertEqual(evaluation5.legend, True) + self.assertEqual(evaluation5.maincolor, 'default') + self.assertEqual(evaluation5.bgcolor, '#ffffc0') + self.assertEqual(evaluation5.currency.code, 'EUR') + + self.assertEqual(len(evaluation5.line_values), 1) + self.assertEqual(evaluation5.line_values[0].balance, Decimal('1300.01')) + + # evaluation: category- difference amount + evaluation6, = Evaluation.create([{ + 'name': 'Evaluation 6', + 'dtype': 'category_glperc', + 'chart': 'hbar', + 'categories': [('add', [cb_cat.id])], + }]) + self.assertEqual(evaluation6.dtype, 'category_glperc') + self.assertEqual(evaluation6.chart, 'hbar') + self.assertEqual(evaluation6.legend, True) + self.assertEqual(evaluation6.maincolor, 'default') + self.assertEqual(evaluation6.bgcolor, '#ffffc0') + self.assertEqual(evaluation6.currency.code, 'EUR') + + self.assertEqual(len(evaluation6.line_values), 1) + self.assertEqual(evaluation6.line_values[0].balance, Decimal('6.95')) @with_transaction() def test_report_chart_pie_book_red(self): diff --git a/tryton.cfg b/tryton.cfg index a53b760..4d73694 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -4,7 +4,7 @@ depends: res cashbook cashbook_bookcategory -#extras_depend: +extras_depend: dashboard cashbook_investment xml: