evaluation: extend categories-diff/percent/value + tests

This commit is contained in:
Frederik Jaeckel 2023-02-05 14:39:00 +01:00
parent 82bdf3e05b
commit a80fac0e0b
9 changed files with 236 additions and 22 deletions

View file

@ -9,7 +9,8 @@ from trytond.transaction import Transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.i18n import gettext from trytond.i18n import gettext
from .colors import sel_color as sel_bgcolor 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 = [ sel_chart = [
@ -77,7 +78,7 @@ class Evaluation(sequence_ordered(), ModelSQL, ModelView):
relation_name='cashbook_report.eval_line', relation_name='cashbook_report.eval_line',
origin='evaluation', target='category', origin='evaluation', target='category',
states={ states={
'invisible': Eval('dtype', '') != 'categories', 'invisible': Eval('dtype', '').in_(category_types),
}, depends=['dtype']) }, depends=['dtype'])
line_values = fields.One2Many(string='Line Values', line_values = fields.One2Many(string='Line Values',

View file

@ -19,7 +19,10 @@ class InvestmentEvaluation(metaclass=PoolMeta):
result.extend([ result.extend([
('cashbooks_gldiff', gettext('cashbook_report.msg_dtype_cashbook_gldiff')), ('cashbooks_gldiff', gettext('cashbook_report.msg_dtype_cashbook_gldiff')),
('cashbooks_glperc', gettext('cashbook_report.msg_dtype_cashbook_glperc')), ('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 return result
@ -29,6 +32,67 @@ class InvestmentEvaluation(metaclass=PoolMeta):
class InvestmentLine(metaclass=PoolMeta): class InvestmentLine(metaclass=PoolMeta):
__name__ = 'cashbook_report.eval_line' __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): def get_value_cashbooks_gldiff(self):
""" amount of profit/loss of cashbooks """ amount of profit/loss of cashbooks
""" """

View file

@ -11,7 +11,7 @@ from trytond.transaction import Transaction
from trytond.i18n import gettext from trytond.i18n import gettext
from trytond.exceptions import UserError from trytond.exceptions import UserError
from trytond.pool import Pool from trytond.pool import Pool
from .templates import cashbook_types from .templates import cashbook_types, category_types
class EvaluationLine(ModelSQL, ModelView): class EvaluationLine(ModelSQL, ModelView):
@ -39,7 +39,7 @@ class EvaluationLine(ModelSQL, ModelView):
category = fields.Many2One(string='Category', select=True, ondelete='CASCADE', category = fields.Many2One(string='Category', select=True, ondelete='CASCADE',
model_name='cashbook.bookcategory', model_name='cashbook.bookcategory',
states={ states={
'required': Eval('eval_dtype', '') == 'categories', 'required': Eval('eval_dtype', '').in_(category_types),
}, depends=['eval_dtype']) }, depends=['eval_dtype'])
# dtype + currency of evaluation # dtype + currency of evaluation
@ -164,7 +164,7 @@ class EvaluationLine(ModelSQL, ModelView):
'cashbook_report.msg_invalid_dtype', 'cashbook_report.msg_invalid_dtype',
typename = gettext('cashbook_report.msg_dtype_currency'), 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): (record.category is not None):
raise UserError(gettext( raise UserError(gettext(
'cashbook_report.msg_invalid_dtype', 'cashbook_report.msg_invalid_dtype',

View file

@ -35,8 +35,20 @@ msgid "Currencies"
msgstr "Währungen" msgstr "Währungen"
msgctxt "model:ir.message,text:msg_dtype_category" msgctxt "model:ir.message,text:msg_dtype_category"
msgid "Categories" msgid "Categories [Amount]"
msgstr "Kategorien" 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" msgctxt "model:ir.message,text:msg_name_graph"
msgid "Graph: %(gname)s" msgid "Graph: %(gname)s"

View file

@ -31,8 +31,20 @@ msgid "Currencies"
msgstr "Currencies" msgstr "Currencies"
msgctxt "model:ir.message,text:msg_dtype_category" msgctxt "model:ir.message,text:msg_dtype_category"
msgid "Categories" msgid "Categories [Amount]"
msgstr "Categories" 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" msgctxt "model:ir.message,text:msg_name_graph"
msgid "Graph: %(gname)s" msgid "Graph: %(gname)s"

View file

@ -27,7 +27,16 @@ full copyright notices and license terms. -->
<field name="text">Currencies</field> <field name="text">Currencies</field>
</record> </record>
<record model="ir.message" id="msg_dtype_category"> <record model="ir.message" id="msg_dtype_category">
<field name="text">Categories</field> <field name="text">Categories [Amount]</field>
</record>
<record model="ir.message" id="msg_dtype_category_gldiff">
<field name="text">Categories [Amount of Profit/Loss]</field>
</record>
<record model="ir.message" id="msg_dtype_category_glvalue">
<field name="text">Categories [Current Value]</field>
</record>
<record model="ir.message" id="msg_dtype_category_glperc">
<field name="text">Categories [Percent of Profit/Loss]</field>
</record> </record>
<record model="ir.message" id="msg_name_graph"> <record model="ir.message" id="msg_name_graph">
<field name="text">Graph: %(gname)s</field> <field name="text">Graph: %(gname)s</field>

View file

@ -4,6 +4,7 @@
# full copyright notices and license terms. # full copyright notices and license terms.
cashbook_types = ['cashbooks', 'cashbooks_gldiff', 'cashbooks_glperc', 'cashbooks_glvalue'] cashbook_types = ['cashbooks', 'cashbooks_gldiff', 'cashbooks_glperc', 'cashbooks_glvalue']
category_types = ['categories', 'category_gldiff', 'category_glvalue', 'category_glperc']
template_view_line = '<field name="balance" fill="%(fill)s" empty="0" string="%(string)s"/>' template_view_line = '<field name="balance" fill="%(fill)s" empty="0" string="%(string)s"/>'

View file

@ -730,6 +730,7 @@ class ReportTestCase(CashbookTestCase):
Asset = pool.get('investment.asset') Asset = pool.get('investment.asset')
Product = pool.get('product.template') Product = pool.get('product.template')
Uom = pool.get('product.uom') Uom = pool.get('product.uom')
CbCategory = pool.get('cashbook.bookcategory')
at, = AccType.create([{ at, = AccType.create([{
'name': 'depot', 'name': 'depot',
@ -759,23 +760,50 @@ class ReportTestCase(CashbookTestCase):
'rate': Decimal('1750.0'), 'rate': Decimal('1750.0'),
}, ])], }, ])],
}]) }])
self.assertEqual(asset.rec_name,
AccType.write(*[ 'Aurum | 1,750.0000 usd/u | 05/01/2022')
[books[0].btype],
{
'feature': 'asset',
}])
books = self.prep_report_3books() books = self.prep_report_3books()
cb_cat, = CbCategory.create([{'name': 'CB Category'}])
Book.write(*[ Book.write(*[
books, books,
{ {
'btype': at.id,
'asset': asset.id, 'asset': asset.id,
'categories': [('add', [cb_cat.id])],
'quantity_uom': asset.uom.id, 'quantity_uom': asset.uom.id,
'quantity_digits': 3, '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([{ evaluation, = Evaluation.create([{
'name': 'Evaluation 1', 'name': 'Evaluation 1',
'dtype': 'cashbooks_gldiff', 'dtype': 'cashbooks_gldiff',
@ -789,9 +817,96 @@ class ReportTestCase(CashbookTestCase):
self.assertEqual(evaluation.bgcolor, '#ffffc0') self.assertEqual(evaluation.bgcolor, '#ffffc0')
self.assertEqual(evaluation.currency.code, 'EUR') self.assertEqual(evaluation.currency.code, 'EUR')
self.assertEqual(evaluation.line_values[0].balance, Decimal('23.81')) self.assertEqual(evaluation.line_values[0].balance, Decimal('857.14'))
self.assertEqual(evaluation.line_values[1].balance, Decimal('11.90')) self.assertEqual(evaluation.line_values[1].balance, Decimal('476.19'))
self.assertEqual(evaluation.line_values[2].balance, Decimal('23.00')) 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() @with_transaction()
def test_report_chart_pie_book_red(self): def test_report_chart_pie_book_red(self):

View file

@ -4,7 +4,7 @@ depends:
res res
cashbook cashbook
cashbook_bookcategory cashbook_bookcategory
#extras_depend: extras_depend:
dashboard dashboard
cashbook_investment cashbook_investment
xml: xml: