asset: abfrage updatezeitpunkt optimiert, anzeige der vortagsprozente, farbe für zeilen

This commit is contained in:
Frederik Jaeckel 2022-11-25 11:00:03 +01:00
parent 57cb06d60e
commit 31c76dfb48
5 changed files with 117 additions and 98 deletions

114
asset.py
View file

@ -6,12 +6,12 @@
from trytond.model import ModelView, ModelSQL, fields from trytond.model import ModelView, ModelSQL, fields
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.pyson import Eval, Bool, And from trytond.pyson import Eval, Bool, And, If
from trytond.report import Report from trytond.report import Report
from decimal import Decimal from decimal import Decimal
from datetime import time from datetime import time
from sql.functions import CurrentTime, CurrentDate from sql.functions import CurrentDate, CurrentTimestamp
from sql.conditionals import Case from sql.conditionals import Case, Coalesce
from sql import Literal from sql import Literal
@ -76,9 +76,9 @@ class Asset(ModelSQL, ModelView):
states={ states={
'readonly': ~Bool(Eval('updtsource')), 'readonly': ~Bool(Eval('updtsource')),
}, depends=['updtsource']) }, depends=['updtsource'])
updtneeded = fields.Function(fields.Boolean(string='Course update needed', nextupdtate = fields.Function(fields.DateTime(string='Next Update',
readonly=True), readonly=True),
'on_change_with_updtneeded', searcher='search_updtneeded') 'get_nextupdtates', searcher='search_nextupdtate')
# percentage change # percentage change
change_today = fields.Function(fields.Numeric(string='Previous Day', change_today = fields.Function(fields.Numeric(string='Previous Day',
@ -102,6 +102,15 @@ class Asset(ModelSQL, ModelView):
readonly=True, digits=(16,1)), readonly=True, digits=(16,1)),
'get_percentage_change') 'get_percentage_change')
@classmethod
def view_attributes(cls):
return super().view_attributes() + [
('/tree', 'visual',
If(Eval('change_today', 0) < 0, 'warning',
If(Eval('change_today', 0) > 0, 'success', '')
)),
]
@classmethod @classmethod
def default_currency(cls): def default_currency(cls):
""" currency of company """ currency of company
@ -218,8 +227,6 @@ class Asset(ModelSQL, ModelView):
for name in names: for name in names:
result[name][record[0]] = values[name] result[name][record[0]] = values[name]
print('-- result:', result)
return result return result
@ -320,48 +327,70 @@ class Asset(ModelSQL, ModelView):
if self.company.currency.id != self.currency.id: if self.company.currency.id != self.currency.id:
return self.company.currency.id return self.company.currency.id
@fields.depends('id')
def on_change_with_updtneeded(self, name=None):
""" get state of update
"""
Asset2 = Pool().get('investment.asset')
if self.id:
if Asset2.search_count([
('updtneeded', '=', True),
('id', '=', self.id)
]) == 1:
return True
return False
@classmethod @classmethod
def search_updtneeded(cls, names, clause): def get_next_update_datetime_sql(cls):
""" search for assets to update """ get sql for datetime of next planned update
""" """
pool = Pool() pool = Pool()
Asset2 = pool.get('investment.asset') Asset = pool.get('investment.asset')
Rate = pool.get('investment.rate') Rate = pool.get('investment.rate')
tab_asset = Asset2.__table__() tab_asset = Asset.__table__()
tab_rate = Rate.__table__() tab_rate = Rate.__table__()
context = Transaction().context
query_date = context.get('qdate', CurrentDate() - Literal(1))
query = tab_asset.join(tab_rate,
condition=tab_asset.id == tab_rate.asset,
type_ = 'LEFT OUTER',
).select(
tab_asset.id,
((Coalesce(tab_rate.date, query_date) + Literal(1)) + \
tab_asset.updttime).as_('updttime'),
distinct_on = [tab_asset.id],
order_by = [tab_asset.id, tab_rate.date.desc],
where=(tab_asset.updtsource != None),
)
return query
@classmethod
def get_nextupdtates(cls, assets, names):
""" get timestamp of next update
"""
Asset2 = Pool().get('investment.asset')
tab_updt = Asset2.get_next_update_datetime_sql()
cursor = Transaction().connection.cursor()
query = tab_updt.select(
tab_updt.id,
tab_updt.updttime,
where=tab_updt.id.in_([x.id for x in assets]),
)
cursor.execute(*query)
records = cursor.fetchall()
result = {x:{y.id: None for y in assets} for x in names}
for record in records:
(id1, updt) = record
r1 = {'nextupdtate': updt}
for n in names:
result[n][id1] = r1[n]
return result
@classmethod
def search_nextupdtate(cls, names, clause):
""" search for assets to update
"""
Asset2 = Pool().get('investment.asset')
tab_updt = Asset2.get_next_update_datetime_sql()
Operator = fields.SQL_OPERATORS[clause[1]] Operator = fields.SQL_OPERATORS[clause[1]]
context = Transaction().context context = Transaction().context
query_date = context.get('qdate', CurrentDate()) query = tab_updt.select(
query_time = context.get('qtime', CurrentTime()) tab_updt.id,
where=Operator(tab_updt.updttime, clause[2]),
query = tab_asset.join(tab_rate,
condition=(tab_asset.id==tab_rate.asset) & \
(tab_rate.date == query_date),
type_ = 'LEFT OUTER',
).select(tab_asset.id,
where=Operator(
Case(
((tab_rate.id == None) & \
(tab_asset.updtsource != None) & \
(tab_asset.updttime <= query_time), True),
default_ = False,
),
clause[2]),
) )
return [('id', 'in', query)] return [('id', 'in', query)]
@ -473,8 +502,9 @@ class Asset(ModelSQL, ModelView):
Asset2 = pool.get('investment.asset') Asset2 = pool.get('investment.asset')
OnlineSource = pool.get('investment.source') OnlineSource = pool.get('investment.source')
query_time = context.get('qdatetime', CurrentTimestamp())
for asset in Asset2.search([ for asset in Asset2.search([
('updtneeded', '=', True), ('updttime', '<=', query_time),
]): ]):
OnlineSource.update_rate(asset) OnlineSource.update_rate(asset)

View file

@ -190,9 +190,9 @@ msgctxt "field:investment.asset,updttime:"
msgid "Time" msgid "Time"
msgstr "Zeitpunkt" msgstr "Zeitpunkt"
msgctxt "field:investment.asset,updtneeded:" msgctxt "field:investment.asset,nextupdtate:"
msgid "Course update needed" msgid "Next Update"
msgstr "Kursaktualisierung nötig" msgstr "nächste Aktualisierung"
msgctxt "field:investment.asset,change_today:" msgctxt "field:investment.asset,change_today:"
msgid "Previous Day" msgid "Previous Day"

View file

@ -162,9 +162,9 @@ msgctxt "field:investment.asset,updttime:"
msgid "Time" msgid "Time"
msgstr "Time" msgstr "Time"
msgctxt "field:investment.asset,updtneeded:" msgctxt "field:investment.asset,nextupdtate:"
msgid "Course update needed" msgid "Next Update"
msgstr "Course update needed" msgstr "Next Update"
msgctxt "field:investment.asset,change_today:" msgctxt "field:investment.asset,change_today:"
msgid "Previous Day" msgid "Previous Day"

View file

@ -8,7 +8,7 @@ from trytond.pool import Pool
from trytond.modules.company.tests import create_company from trytond.modules.company.tests import create_company
from trytond.transaction import Transaction from trytond.transaction import Transaction
from decimal import Decimal from decimal import Decimal
from datetime import time, date from datetime import time, date, datetime
class AssetTestCase(ModuleTestCase): class AssetTestCase(ModuleTestCase):
@ -221,31 +221,23 @@ class AssetTestCase(ModuleTestCase):
'updtsource': o_source.id, 'updtsource': o_source.id,
'updttime': time(10, 45), 'updttime': time(10, 45),
}]) }])
self.assertEqual(asset.updtsource.rec_name, 'Source 1')
self.assertEqual(asset.updttime, time(10, 45))
self.assertEqual(len(asset.rates), 0)
with Transaction().set_context({ with Transaction().set_context({
'qdate': date(2022, 10, 15), 'qdate': date(2022, 10, 14),
'qtime': time(10, 30),
}): }):
# re-read to make context work # re-read to make context work
asset2, = Asset.browse([asset.id]) asset2, = Asset.browse([asset.id])
# no rates exists - wait for 10:45
self.assertEqual(asset2.updtneeded, False)
self.assertEqual(
Asset.search_count([('updtneeded', '=', True)]),
0)
with Transaction().set_context({ self.assertEqual(asset2.updtsource.rec_name, 'Source 1')
'qdate': date(2022, 10, 15), self.assertEqual(asset2.updttime, time(10, 45))
'qtime': time(10, 46), self.assertEqual(len(asset2.rates), 0)
}): self.assertEqual(asset2.nextupdtate, datetime(2022, 10, 15, 10, 45))
# no rates exists - run at 10:46
asset2, = Asset.browse([asset.id])
self.assertEqual(asset2.updtneeded, True)
self.assertEqual( self.assertEqual(
Asset.search_count([('updtneeded', '=', True)]), Asset.search_count([('nextupdtate', '<', datetime(2022, 10, 15, 10, 45))]),
0)
self.assertEqual(
Asset.search_count([('nextupdtate', '>=', datetime(2022, 10, 15, 10, 45))]),
1) 1)
# add rate at yesterday # add rate at yesterday
@ -259,27 +251,19 @@ class AssetTestCase(ModuleTestCase):
}]) }])
self.assertEqual(len(asset.rates), 1) self.assertEqual(len(asset.rates), 1)
with Transaction().set_context({ asset2, = Asset.browse([asset.id])
'qdate': date(2022, 10, 15), self.assertEqual(asset.updtsource.rec_name, 'Source 1')
'qtime': time(10, 30), self.assertEqual(asset.updttime, time(10, 45))
}): self.assertEqual(len(asset.rates), 1)
# 1x rate exists - run at 10:30 self.assertEqual(asset.rates[0].date, date(2022, 10, 14))
asset2, = Asset.browse([asset.id]) self.assertEqual(asset.nextupdtate, datetime(2022, 10, 15, 10, 45))
self.assertEqual(asset2.updtneeded, False)
self.assertEqual(
Asset.search_count([('updtneeded', '=', True)]),
0)
with Transaction().set_context({ self.assertEqual(
'qdate': date(2022, 10, 15), Asset.search_count([('nextupdtate', '<', datetime(2022, 10, 15, 10, 45))]),
'qtime': time(10, 46), 0)
}): self.assertEqual(
# 1x rate exists yesterday - run at 10:46 Asset.search_count([('nextupdtate', '>=', datetime(2022, 10, 15, 10, 45))]),
asset2, = Asset.browse([asset.id]) 1)
self.assertEqual(asset2.updtneeded, True)
self.assertEqual(
Asset.search_count([('updtneeded', '=', True)]),
1)
# add rate at today # add rate at today
Asset.write(*[ Asset.write(*[
@ -292,16 +276,19 @@ class AssetTestCase(ModuleTestCase):
}]) }])
self.assertEqual(len(asset.rates), 2) self.assertEqual(len(asset.rates), 2)
with Transaction().set_context({ asset2, = Asset.browse([asset.id])
'qdate': date(2022, 10, 15), self.assertEqual(asset2.updtsource.rec_name, 'Source 1')
'qtime': time(10, 47), self.assertEqual(asset2.updttime, time(10, 45))
}): self.assertEqual(len(asset2.rates), 2)
# 1x rate exists today - run at 10:47 self.assertEqual(asset2.rates[0].date, date(2022, 10, 15))
asset2, = Asset.browse([asset.id]) self.assertEqual(asset2.nextupdtate, datetime(2022, 10, 16, 10, 45))
self.assertEqual(asset2.updtneeded, False)
self.assertEqual( self.assertEqual(
Asset.search_count([('updtneeded', '=', True)]), Asset.search_count([('nextupdtate', '<', datetime(2022, 10, 15, 10, 45))]),
0) 0)
self.assertEqual(
Asset.search_count([('nextupdtate', '>=', datetime(2022, 10, 15, 10, 45))]),
1)
@with_transaction() @with_transaction()
def test_asset_indentifiers(self): def test_asset_indentifiers(self):

View file

@ -8,7 +8,9 @@ full copyright notices and license terms. -->
<label name="rate" /> <label name="rate" />
<field name="rate" symbol="currency"/> <field name="rate" symbol="currency"/>
<label id="labdate" colspan="4" string=" "/> <label id="labdate" colspan="2" string=" "/>
<label name="nextupdtate" />
<field name="nextupdtate"/>
<label name="date" /> <label name="date" />
<field name="date"/> <field name="date"/>