add: field 'asset_gainloss' + searcher + test +todos

This commit is contained in:
Frederik Jaeckel 2023-02-15 22:34:52 +01:00
parent a1ede23740
commit 4e7d2c2ba9
3 changed files with 125 additions and 14 deletions

36
line.py
View file

@ -128,7 +128,7 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
states = {
'invisible': Eval('feature', '') != 'asset',
}, depends=['currency_digits', 'feature']),
'get_gainloss_data')
'get_yield_data', searcher='search_asset_gainloss')
@classmethod
def get_gainloss_data_sql(cls):
@ -307,12 +307,24 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
)
return [('id', 'in', query)]
@classmethod
def search_asset_gainloss(cls, name, clause):
""" search for profit/loss
"""
Operator = fields.SQL_OPERATORS[clause[1]]
(tab_line, tab_query) = cls.get_gainloss_data_sql()
query = tab_query.select(
tab_query.id,
where=Operator(tab_query.gainloss, clause[2]),
)
return [('id', 'in', query)]
@classmethod
def get_yield_data(cls, lines, names):
""" collect data for fee, dividend, gain/loss per line
"""
Line2 = Pool().get('cashbook.line')
(tab_line, query) = cls.get_yield_data_sql()
cursor = Transaction().connection.cursor()
def quantize_val(value, line):
@ -323,6 +335,11 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
).quantize(Decimal(str(1/10**line.currency_digits)))
result = {x:{y.id: None for y in lines} for x in names}
# read fee, dividend
name_set = set({'trade_fee', 'asset_dividend'}).intersection(set(names))
if len(name_set) > 0:
(tab_line, query) = cls.get_yield_data_sql()
query.where = tab_line.id.in_([x.id for x in lines])
cursor.execute(*query)
records = cursor.fetchall()
@ -333,9 +350,20 @@ class Line(SecondUomMixin, metaclass=PoolMeta):
'trade_fee': quantize_val(record[1], line),
'asset_dividend': quantize_val(record[2], line),
}
for name in names:
for name in list(name_set):
result[name][record[0]] = values[name]
# read asset_gainloss
if 'asset_gainloss' in names:
(tab_line, query) = cls.get_gainloss_data_sql()
query.where = tab_line.id.in_([x.id for x in lines])
cursor.execute(*query)
records = cursor.fetchall()
for record in records:
line = Line2(record[0])
result['asset_gainloss'][record[0]] = quantize_val(record[1], line)
return result
def get_rec_name(self, name):

View file

@ -292,4 +292,83 @@ class YieldTestCase(ModuleTestCase):
self.assertEqual(lines[0].rec_name,
'05/01/2022|Rev/Sp|7.00 usd|Dividend [-]|0.0000 u')
# add counter-account for profit or loss of
# depot-account
book_gainloss, = Cashbook.create([{
'name': 'Profit-Loss',
'btype': type_cash.id,
'company': company.id,
'currency': company.currency.id,
'number_sequ': self.prep_sequence().id,
'start_date': date(2022, 5, 1),
}])
# sale all shares with profit and fee
# buy: 23.50
# sale: 32.90 (+40%)
# fee: 2.50
# asset (buy amount): 23.50
# booking: asset -> cash: - 30.40
# asset -> (category) fee: - 2.50
# asset <- gain-loss: 9.40
# -------
# 0.00
self.assertEqual(book_asset.rec_name, 'Depot | 23.50 usd | Open | 3.0000 u')
self.assertEqual(book_gainloss.rec_name, 'Profit-Loss | 0.00 usd | Open')
lines = Line.create([{
'cashbook': book_asset.id,
'date': date(2022, 5, 2),
'bookingtype': 'spout',
'description': 'all out',
'splitlines': [('create', [{
'splittype': 'tr',
'booktransf': book_cash.id,
'description': 'sale with 40% profit',
'quantity': Decimal('3.0'),
'amount': Decimal('30.4'),
}, {
'splittype': 'cat',
'description': 'trade fee',
'category': as_cfg.fee_category.id,
'amount': Decimal('2.5'),
'quantity': Decimal('0.0'),
}, {
'splittype': 'tr',
'booktransf': book_gainloss.id,
'description': 'profit of sale',
'amount': Decimal('-9.4'),
'quantity': Decimal('0.0'),
}])],
}])
self.assertEqual(len(lines), 1)
self.assertEqual(lines[0].rec_name,
'05/02/2022|Exp/Sp|-23.50 usd|all out [-]|-3.0000 u')
Line.wfcheck(lines)
self.assertEqual(lines[0].rec_name,
'05/02/2022|Exp/Sp|-23.50 usd|all out [-]|-3.0000 u')
self.assertEqual(len(lines[0].splitlines), 3)
self.assertEqual(lines[0].splitlines[0].rec_name,
'Exp/Sp|30.40 usd|sale with 40% profit [Cash | 22.90 usd | Open]|3.0000 u')
self.assertEqual(lines[0].splitlines[1].rec_name,
'Exp/Sp|2.50 usd|trade fee [Fee]|0.0000 u')
self.assertEqual(lines[0].splitlines[2].rec_name,
'Exp/Sp|-9.40 usd|profit of sale [Profit-Loss | -9.40 usd | Open]|0.0000 u')
print('\n# line:', lines[0].asset_gainloss, lines[0].asset_dividend, lines[0].trade_fee)
self.assertEqual(lines[0].asset_gainloss, Decimal('0.0'))
self.assertEqual(lines[0].asset_dividend, Decimal('0.0'))
self.assertEqual(lines[0].trade_fee, Decimal('0.0'))
self.assertEqual(book_asset.rec_name, 'Depot | 0.00 usd | Open | 0.0000 u')
# negative amount on profit/loss-account means success
self.assertEqual(book_gainloss.rec_name, 'Profit-Loss | -9.40 usd | Open')
# check searcher
lines = Line.search([('asset_gainloss', '=', Decimal('-9.4'))])
self.assertEqual(len(lines), 1)
self.assertEqual(lines[0].rec_name,
'Exp/Sp|-9.40 usd|profit of sale [Profit-Loss | -9.40 usd | Open]|0.0000 u')
# end YieldTestCase

View file

@ -24,7 +24,7 @@ full copyright notices and license terms. -->
</xpath>
<xpath expr="/form/notebook/page[@name='description']" position="after">
<page name="current_value" col="5" string="Performance">
<page name="current_value" col="6" string="Performance">
<label name="current_value"/>
<field name="current_value" symbol="currency"/>
<label name="diff_amount"/>
@ -39,6 +39,10 @@ full copyright notices and license terms. -->
<field name="trade_fee"/>
<label name="asset_dividend"/>
<field name="asset_dividend"/>
<newline/>
<label name="asset_gainloss"/>
<field name="asset_gainloss"/>
</page>
</xpath>