asset:tabellenzugriff optimiert,
diagram: darstellung in diagramm ergänzt
This commit is contained in:
parent
047b6980e4
commit
7bb3e4f929
9 changed files with 352 additions and 6 deletions
|
@ -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')
|
||||||
|
|
18
asset.py
18
asset.py
|
@ -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
112
diagram.py
Normal 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
16
diagram.xml
Normal 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>
|
12
locale/de.po
12
locale/de.po
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
14
view/graph_form.xml
Normal 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>
|
Loading…
Reference in a new issue