asset:tabellenzugriff optimiert,

diagram: darstellung in diagramm ergänzt
This commit is contained in:
Frederik Jaeckel 2022-11-26 22:42:02 +01:00
parent 047b6980e4
commit 7bb3e4f929
9 changed files with 352 additions and 6 deletions

View file

@ -10,6 +10,7 @@ from .identifier import Identifier
from .cron import Cron from .cron import Cron
from .onlinesource import OnlineSource from .onlinesource import OnlineSource
from .update_wiz import UpdateSoureWizard from .update_wiz import UpdateSoureWizard
from .diagram import GraphDef, ChartPoint
def register(): def register():
@ -20,6 +21,10 @@ def register():
Identifier, Identifier,
Cron, Cron,
module='investment', type_='model') module='investment', type_='model')
Pool.register(
GraphDef,
ChartPoint,
module='investment', type_='model', depends=['diagram'])
Pool.register( Pool.register(
UpdateSoureWizard, UpdateSoureWizard,
module='investment', type_='wizard') module='investment', type_='wizard')

View file

@ -244,9 +244,10 @@ class Asset(ModelSQL, ModelView):
return self.company.currency.id return self.company.currency.id
@classmethod @classmethod
def get_percentage_sql(cls, name_lst): def get_percentage_sql(cls, name_lst, select_date=True):
""" get table for percentages and dates, """ get table for percentages and dates,
generate adapted query generate adapted query
select_date: True = select newest date
""" """
pool = Pool() pool = Pool()
Rate = pool.get('investment.rate') Rate = pool.get('investment.rate')
@ -270,13 +271,17 @@ class Asset(ModelSQL, ModelView):
condition=tab_asset.id==tab_rate_today.asset, condition=tab_asset.id==tab_rate_today.asset,
).select( ).select(
tab_asset.id, tab_asset.id,
tab_rate_today.id.as_('id_rate'),
tab_rate_today.date, tab_rate_today.date,
tab_rate_today.rate, tab_rate_today.rate,
distinct_on=[tab_asset.id],
order_by=[tab_asset.id, tab_rate_today.date.desc],
where=tab_rate_today.date <= query_date,
) )
# limit to newest date until 'query_date'
if select_date == True:
query_today.distinct_on=[tab_asset.id]
query_today.order_by=[tab_asset.id, tab_rate_today.date.desc]
query_today.where=tab_rate_today.date <= query_date
# create join for requested fields, to minimize database-load # create join for requested fields, to minimize database-load
query = query_today query = query_today
for name in name_lst: for name in name_lst:
@ -290,6 +295,7 @@ class Asset(ModelSQL, ModelView):
# add select for requested fields to join # add select for requested fields to join
select_lst = [ select_lst = [
query_today.id, query_today.id,
query_today.id_rate,
query_today.date, query_today.date,
] ]
for name in name_lst: for name in name_lst:
@ -301,14 +307,14 @@ class Asset(ModelSQL, ModelView):
else_ = None, else_ = None,
).as_(name)) ).as_(name))
order_by_lst = [query_today.id] order_by_lst = [query_today.id, query_today.id_rate]
order_by_lst.extend([ order_by_lst.extend([
rate_tab[name]['tab'].date.desc for name in name_lst rate_tab[name]['tab'].date.desc for name in name_lst
]) ])
query = query.select( query = query.select(
*select_lst, *select_lst,
distinct_on=[query_today.id], distinct_on=[query_today.id, query_today.id_rate],
order_by=order_by_lst, order_by=order_by_lst,
) )
return query return query

112
diagram.py Normal file
View file

@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
# This file is part of the investment-module from m-ds for Tryton.
# The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms.
from trytond.model import ModelView, ModelSQL, fields
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from sql.functions import Function
from datetime import timedelta
from decimal import Decimal
class Concat2(Function):
""" concat columns
"""
__slots__ = ()
_function = 'concat'
# end Concat2
class GraphDef(metaclass=PoolMeta):
__name__ = 'diagram.graphdef'
asset = fields.Many2One(string='Asset',
model_name='investment.asset',
states={
'invisible': Eval('dtype', '') != 'investment.asset',
'required': Eval('dtype', '') == 'investment.asset',
}, depends=['dtype'])
@classmethod
def _get_dtypes(cls):
""" return list of types
"""
l1 = super(GraphDef, cls)._get_dtypes()
l1.append('investment.asset')
return l1
def get_recname_value(self):
""" value by dtype
"""
if self.dtype == 'investment.asset':
return getattr(self.asset, 'rec_name', '-')
return super(GraphDef, self).get_recname_value()
def get_field_key(self):
""" get to read value from json
"""
if self.dtype == 'investment.asset':
return 'asset%d' % self.asset.id
return super(GraphDef, self).get_field_key()
def get_scaling_for_investment_asset(self):
""" get scaling for currency
"""
Rate = Pool().get('investment.rate')
if self.scaling == 'fix':
return None
if self.scaling == 'alldata':
query = [('asset.id', '=', self.asset.id)]
elif self.scaling == 'view':
query = [
('asset.id', '=', self.asset.id),
('date', '>=', self.chart.used_start_date()),
('date', '<=', self.chart.used_end_date()),
]
elif self.scaling == 'six':
query = [
('asset.id', '=', self.asset.id),
('date', '>=', self.chart.used_start_date() - timedelta(days=180)),
('date', '<=', self.chart.used_end_date()),
]
min_rec = Rate.search(query, limit=1, order=[('rate', 'ASC')])
max_rec = Rate.search(query, limit=1, order=[('rate', 'DESC')])
min_val = min_rec[0].rate if len(min_rec) > 0 else None
max_val = max_rec[0].rate if len(max_rec) > 0 else None
return self.compute_scaling_factor(min_val, max_val)
# end GraphDef
class ChartPoint(metaclass=PoolMeta):
__name__ = 'diagram.point'
@classmethod
def get_table_parts(cls):
""" return a list of tables to union,
table must contain the columns:
date, key, val
"""
pool = Pool()
Rate = pool.get('investment.rate')
tab_rate = Rate.__table__()
tabparts = super(ChartPoint, cls).get_table_parts()
# rate
tabparts.append(tab_rate.select(
tab_rate.date,
Concat2('asset', tab_rate.asset).as_('key'),
tab_rate.rate.as_('val'),
))
return tabparts
# end ChartPoint

16
diagram.xml Normal file
View file

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!-- This file is part of the investment-module from m-ds for Tryton.
The COPYRIGHT file at the top level of this repository contains the
full copyright notices and license terms. -->
<tryton>
<data depends="diagram">
<!-- views -->
<record model="ir.ui.view" id="graph_view_form">
<field name="model">diagram.graphdef</field>
<field name="inherit" ref="diagram.graph_view_form"/>
<field name="name">graph_form</field>
</record>
</data>
</tryton>

View file

@ -449,3 +449,15 @@ msgstr "Wertpapierkennnummer (WKN)"
msgctxt "selection:product.identifier,type:" msgctxt "selection:product.identifier,type:"
msgid "Stock market symbol" msgid "Stock market symbol"
msgstr "Börsensymbol" msgstr "Börsensymbol"
####################
# diagram.graphdef #
####################
msgctxt "view:diagram.graphdef:"
msgid "Asset"
msgstr "Vermögenswert"
msgctxt "field:diagram.graphdef,asset:"
msgid "Asset"
msgstr "Vermögenswert"

View file

@ -406,3 +406,11 @@ msgctxt "selection:product.identifier,type:"
msgid "National Securities Identifying Number (NSIN)" msgid "National Securities Identifying Number (NSIN)"
msgstr "National Securities Identifying Number (NSIN)" msgstr "National Securities Identifying Number (NSIN)"
msgctxt "selection:product.identifier,type:"
msgid "Stock market symbol"
msgstr "Stock market symbol"
msgctxt "view:diagram.graphdef:"
msgid "Asset"
msgstr "Asset"

View file

@ -112,6 +112,176 @@ class AssetTestCase(ModuleTestCase):
self.assertEqual(asset.rec_name, 'Product 1 - 2.4500 usd/Unit [05/15/2022]') self.assertEqual(asset.rec_name, 'Product 1 - 2.4500 usd/Unit [05/15/2022]')
self.assertEqual(Asset.search_count([('name', '=', 'Product 1')]), 1) self.assertEqual(Asset.search_count([('name', '=', 'Product 1')]), 1)
@with_transaction()
def test_asset_percentages_dateselect1(self):
""" create asset, add rates, check selection of
specific date - fixed date
"""
Asset = Pool().get('investment.asset')
cursor = Transaction().connection.cursor()
company = self.prep_asset_company()
product = self.prep_asset_product(
name='Product 1',
description='some asset')
asset1 = self.prep_asset_item(
company=company,
product = product)
self.assertEqual(asset1.rec_name, 'Product 1 - - usd/Unit [-]')
Asset.write(*[
[asset1],
{
'rates': [('create', [{
'date': date(2022, 5, 15),
'rate': Decimal('2.45'),
}, {
'date': date(2022, 5, 16),
'rate': Decimal('2.6'),
}, {
'date': date(2022, 5, 12),
'rate': Decimal('2.0'),
}, {
'date': date(2022, 5, 3),
'rate': Decimal('3.6'),
}])],
},
])
self.assertEqual(asset1.rec_name, 'Product 1 - 2.6000 usd/Unit [05/16/2022]')
self.assertEqual(len(asset1.rates), 4)
self.assertEqual(asset1.rates[0].date, date(2022, 5, 16))
self.assertEqual(asset1.rates[1].date, date(2022, 5, 15))
self.assertEqual(asset1.rates[2].date, date(2022, 5, 12))
self.assertEqual(asset1.rates[3].date, date(2022, 5, 3))
# query fixed date
tab_percent = Asset.get_percentage_sql(['day1'], select_date = False)
query = tab_percent.select(
tab_percent.id,
tab_percent.date,
tab_percent.day1,
where=(tab_percent.date==date(2022, 5, 16)) & \
(tab_percent.id==asset1.id),
)
cursor.execute(*query)
records = cursor.fetchall()
# there should be one record, three colums
self.assertEqual(len(records), 1)
self.assertEqual(len(records[0]), 3)
self.assertEqual(records[0][0], asset1.id)
self.assertEqual(records[0][1], date(2022, 5, 16))
self.assertEqual(records[0][2].quantize(Decimal('0.01')), Decimal('6.12'))
@with_transaction()
def test_asset_percentages_dateselect2(self):
""" create asset, add rates, check selection of
specific date - date-column
"""
pool = Pool()
Asset = pool.get('investment.asset')
Rate = pool.get('investment.rate')
tab_rate = Rate.__table__()
cursor = Transaction().connection.cursor()
company = self.prep_asset_company()
product = self.prep_asset_product(
name='Product 1',
description='some asset')
asset1 = self.prep_asset_item(
company=company,
product = product)
asset2 = self.prep_asset_item(
company=company,
product = product)
Asset.write(*[
[asset1],
{
'rates': [('create', [{
'date': date(2022, 5, 15),
'rate': Decimal('2.45'),
}, {
'date': date(2022, 5, 16),
'rate': Decimal('2.6'),
}, {
'date': date(2022, 5, 12),
'rate': Decimal('2.0'),
}, {
'date': date(2022, 5, 3),
'rate': Decimal('3.6'),
}])],
},
[asset2],
{
'rates': [('create', [{
'date': date(2022, 5, 17),
'rate': Decimal('1.5'),
}, {
'date': date(2022, 5, 16),
'rate': Decimal('2.0'),
}, {
'date': date(2022, 5, 15),
'rate': Decimal('2.5'),
}, {
'date': date(2022, 5, 14),
'rate': Decimal('3.0'),
}, {
'date': date(2022, 5, 13),
'rate': Decimal('3.5'),
}, {
'date': date(2022, 5, 12),
'rate': Decimal('4.0'),
}, {
'date': date(2022, 5, 11),
'rate': Decimal('4.5'),
}, ])],
},
])
self.assertEqual(asset1.rec_name, 'Product 1 - 2.6000 usd/Unit [05/16/2022]')
self.assertEqual(len(asset1.rates), 4)
self.assertEqual(asset2.rec_name, 'Product 1 - 1.5000 usd/Unit [05/17/2022]')
self.assertEqual(len(asset2.rates), 7)
self.assertEqual(asset1.rates[0].date, date(2022, 5, 16))
self.assertEqual(asset1.rates[1].date, date(2022, 5, 15))
self.assertEqual(asset1.rates[2].date, date(2022, 5, 12))
self.assertEqual(asset1.rates[3].date, date(2022, 5, 3))
# query date-column
tab_percent = Asset.get_percentage_sql(['day1'], select_date = False)
query = tab_rate.join(tab_percent,
condition=(tab_percent.id_rate == tab_rate.id)
).select(
tab_percent.id,
tab_percent.date,
tab_percent.day1,
where=tab_percent.id==asset1.id,
order_by=[tab_percent.date.asc]
)
cursor.execute(*query)
records = cursor.fetchall()
# there should be 4x records, three colums
self.assertEqual(len(records), 4)
self.assertEqual(len(records[0]), 3)
self.assertEqual(records[0][0], asset1.id)
self.assertEqual(records[0][1], date(2022, 5, 3))
self.assertEqual(records[0][2], None)
self.assertEqual(records[1][0], asset1.id)
self.assertEqual(records[1][1], date(2022, 5, 12))
self.assertEqual(records[1][2], None)
self.assertEqual(records[2][0], asset1.id)
self.assertEqual(records[2][1], date(2022, 5, 15))
self.assertEqual(records[2][2].quantize(Decimal('0.01')), Decimal('22.5'))
self.assertEqual(records[3][0], asset1.id)
self.assertEqual(records[3][1], date(2022, 5, 16))
self.assertEqual(records[3][2].quantize(Decimal('0.01')), Decimal('6.12'))
@with_transaction() @with_transaction()
def test_asset_percentages_daterange(self): def test_asset_percentages_daterange(self):
""" create asset, add rates, check selection of """ create asset, add rates, check selection of

View file

@ -6,6 +6,8 @@ depends:
company company
currency currency
product product
extras_depends:
diagram
xml: xml:
icon.xml icon.xml
message.xml message.xml
@ -15,5 +17,6 @@ xml:
sources_def.xml sources_def.xml
update_wiz.xml update_wiz.xml
rate.xml rate.xml
diagram.xml
menu.xml menu.xml
cron.xml cron.xml

14
view/graph_form.xml Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!-- This file is part of the investment-module from m-ds for Tryton.
The COPYRIGHT file at the top level of this repository contains the
full copyright notices and license terms. -->
<data>
<xpath expr="/form/separator[@name='currency']" position="before">
<separator name="asset" colspan="6" string="Asset"/>
<label name="asset"/>
<field name="asset"/>
<newline/>
</xpath>
</data>