asset: abfrage updatezeitpunkt optimiert, anzeige der vortagsprozente, farbe für zeilen
This commit is contained in:
parent
57cb06d60e
commit
31c76dfb48
5 changed files with 117 additions and 98 deletions
114
asset.py
114
asset.py
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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"/>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue