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 34faf91476
commit cba2117d13
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.transaction import Transaction
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 decimal import Decimal
from datetime import time
from sql.functions import CurrentTime, CurrentDate
from sql.conditionals import Case
from sql.functions import CurrentDate, CurrentTimestamp
from sql.conditionals import Case, Coalesce
from sql import Literal
@ -76,9 +76,9 @@ class Asset(ModelSQL, ModelView):
states={
'readonly': ~Bool(Eval('updtsource')),
}, depends=['updtsource'])
updtneeded = fields.Function(fields.Boolean(string='Course update needed',
nextupdtate = fields.Function(fields.DateTime(string='Next Update',
readonly=True),
'on_change_with_updtneeded', searcher='search_updtneeded')
'get_nextupdtates', searcher='search_nextupdtate')
# percentage change
change_today = fields.Function(fields.Numeric(string='Previous Day',
@ -102,6 +102,15 @@ class Asset(ModelSQL, ModelView):
readonly=True, digits=(16,1)),
'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
def default_currency(cls):
""" currency of company
@ -218,8 +227,6 @@ class Asset(ModelSQL, ModelView):
for name in names:
result[name][record[0]] = values[name]
print('-- result:', result)
return result
@ -320,48 +327,70 @@ class Asset(ModelSQL, ModelView):
if self.company.currency.id != self.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
def search_updtneeded(cls, names, clause):
""" search for assets to update
def get_next_update_datetime_sql(cls):
""" get sql for datetime of next planned update
"""
pool = Pool()
Asset2 = pool.get('investment.asset')
Asset = pool.get('investment.asset')
Rate = pool.get('investment.rate')
tab_asset = Asset2.__table__()
tab_asset = Asset.__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]]
context = Transaction().context
query_date = context.get('qdate', CurrentDate())
query_time = context.get('qtime', CurrentTime())
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]),
query = tab_updt.select(
tab_updt.id,
where=Operator(tab_updt.updttime, clause[2]),
)
return [('id', 'in', query)]
@ -473,8 +502,9 @@ class Asset(ModelSQL, ModelView):
Asset2 = pool.get('investment.asset')
OnlineSource = pool.get('investment.source')
query_time = context.get('qdatetime', CurrentTimestamp())
for asset in Asset2.search([
('updtneeded', '=', True),
('updttime', '<=', query_time),
]):
OnlineSource.update_rate(asset)

View file

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

View file

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

View file

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

View file

@ -8,7 +8,9 @@ full copyright notices and license terms. -->
<label name="rate" />
<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" />
<field name="date"/>