asset: online-quelle als liste
This commit is contained in:
parent
8760fd4aab
commit
b8495231e5
8 changed files with 171 additions and 100 deletions
|
@ -4,7 +4,7 @@
|
|||
# full copyright notices and license terms.
|
||||
|
||||
from trytond.pool import Pool
|
||||
from .asset import Asset
|
||||
from .asset import Asset, AssetSourceRel
|
||||
from .rate import Rate
|
||||
from .identifier import Identifier
|
||||
from .cron import Cron
|
||||
|
@ -16,6 +16,7 @@ from .diagram import GraphDef, ChartPoint
|
|||
def register():
|
||||
Pool.register(
|
||||
OnlineSource,
|
||||
AssetSourceRel,
|
||||
Asset,
|
||||
Rate,
|
||||
Identifier,
|
||||
|
|
99
asset.py
99
asset.py
|
@ -78,15 +78,16 @@ class Asset(ModelSQL, ModelView):
|
|||
help='Stock market symbol'),
|
||||
'get_identifiers', searcher='search_identifier')
|
||||
|
||||
updtsource = fields.Many2One(string='Update Source',
|
||||
help='Select a source for the course update.',
|
||||
ondelete='SET NULL', model_name='investment.source')
|
||||
updtsources = fields.Many2Many(string='Update Sources',
|
||||
help='Select sources for the course update. The course sources are tried until a valid value has been read.',
|
||||
relation_name='investment.asset_source_rel',
|
||||
origin='asset', target='source')
|
||||
updtdays = fields.Selection(string='Select days', required=True,
|
||||
selection=sel_updtdays)
|
||||
updttime = fields.Time(string='Time',
|
||||
states={
|
||||
'readonly': ~Bool(Eval('updtsource')),
|
||||
}, depends=['updtsource'])
|
||||
'readonly': ~Bool(Eval('updtsources')),
|
||||
}, depends=['updtsources'])
|
||||
nextupdate = fields.Function(fields.DateTime(string='Next Update',
|
||||
readonly=True),
|
||||
'get_nextupdates', searcher='search_nextupdate')
|
||||
|
@ -113,12 +114,48 @@ class Asset(ModelSQL, ModelView):
|
|||
readonly=True, digits=(16,digits_percent)),
|
||||
'get_percentage_change', searcher='search_percentage')
|
||||
|
||||
@classmethod
|
||||
def __register__(cls, module_name):
|
||||
""" register and migrate
|
||||
"""
|
||||
super(Asset, cls).__register__(module_name)
|
||||
cls.migrate_updtsource(module_name)
|
||||
|
||||
@classmethod
|
||||
def __setup__(cls):
|
||||
super(Asset, cls).__setup__()
|
||||
cls._order.insert(0, ('name', 'ASC'))
|
||||
cls._order.insert(0, ('date', 'DESC'))
|
||||
|
||||
@classmethod
|
||||
def migrate_updtsource(cls, module_name):
|
||||
""" replace 'updtsource' by relation
|
||||
"""
|
||||
pool = Pool()
|
||||
Asset2 = pool.get('investment.asset')
|
||||
|
||||
asset_table = Asset2.__table_handler__(module_name)
|
||||
if asset_table.column_exist('updtsource'):
|
||||
AssetSourceRel = pool.get('investment.asset_source_rel')
|
||||
tab_asset = Asset2.__table__()
|
||||
cursor = Transaction().connection.cursor()
|
||||
|
||||
query = tab_asset.select(
|
||||
tab_asset.id,
|
||||
tab_asset.updtsource,
|
||||
where = tab_asset.updtsource != None,
|
||||
)
|
||||
cursor.execute(*query)
|
||||
records = cursor.fetchall()
|
||||
to_create = [{
|
||||
'asset': x[0],
|
||||
'source': x[1],
|
||||
} for x in records]
|
||||
|
||||
if len(to_create) > 0:
|
||||
AssetSourceRel.create(to_create)
|
||||
asset_table.drop_column('updtsource')
|
||||
|
||||
@classmethod
|
||||
def view_attributes(cls):
|
||||
return super().view_attributes() + [
|
||||
|
@ -164,11 +201,11 @@ class Asset(ModelSQL, ModelView):
|
|||
"""
|
||||
return 'work'
|
||||
|
||||
@fields.depends('updtsource', 'updttime')
|
||||
def on_change_updtsource(self):
|
||||
@fields.depends('updtsources', 'updttime')
|
||||
def on_change_updtsources(self):
|
||||
""" clear time-fields
|
||||
"""
|
||||
if self.updtsource is None:
|
||||
if len(self.updtsources) == 0:
|
||||
self.updttime = None
|
||||
else :
|
||||
self.updttime = time(11, 30)
|
||||
|
@ -513,15 +550,21 @@ class Asset(ModelSQL, ModelView):
|
|||
"""
|
||||
pool = Pool()
|
||||
Asset = pool.get('investment.asset')
|
||||
AssetSourceRel = pool.get('investment.asset_source_rel')
|
||||
Rate = pool.get('investment.rate')
|
||||
tab_asset = Asset.__table__()
|
||||
tab_rate = Rate.__table__()
|
||||
tab_rel = AssetSourceRel.__table__()
|
||||
context = Transaction().context
|
||||
|
||||
query_date = context.get('qdate', CurrentDate() - Literal(1))
|
||||
|
||||
# get last date of rate
|
||||
tab_date = tab_asset.join(tab_rate,
|
||||
tab_date = tab_asset.join(tab_rel,
|
||||
# link to asset-source-relation to check if
|
||||
# there are online-sources set
|
||||
condition=tab_rel.asset == tab_asset.id,
|
||||
).join(tab_rate,
|
||||
condition=tab_asset.id == tab_rate.asset,
|
||||
type_ = 'LEFT OUTER',
|
||||
).select(
|
||||
|
@ -531,7 +574,6 @@ class Asset(ModelSQL, ModelView):
|
|||
tab_asset.updttime,
|
||||
distinct_on = [tab_asset.id],
|
||||
order_by = [tab_asset.id, tab_rate.date.desc],
|
||||
where=tab_asset.updtsource != None,
|
||||
)
|
||||
|
||||
query = tab_date.select(
|
||||
|
@ -768,27 +810,18 @@ class Asset(ModelSQL, ModelView):
|
|||
]):
|
||||
OnlineSource.update_rate(asset)
|
||||
|
||||
@classmethod
|
||||
def create(cls, vlist):
|
||||
""" add debit/credit
|
||||
"""
|
||||
vlist = [x.copy() for x in vlist]
|
||||
for values in vlist:
|
||||
if 'updtsource' in values.keys():
|
||||
if values['updtsource'] is None:
|
||||
values['updttime'] = None
|
||||
return super(Asset, cls).create(vlist)
|
||||
|
||||
@classmethod
|
||||
def write(cls, *args):
|
||||
""" deny update if cashbook.line!='open',
|
||||
add or update debit/credit
|
||||
"""
|
||||
actions = iter(args)
|
||||
for lines, values in zip(actions, actions):
|
||||
if 'updtsource' in values.keys():
|
||||
if values['updtsource'] is None:
|
||||
values['updttime'] = None
|
||||
super(Asset, cls).write(*args)
|
||||
|
||||
# end Asset
|
||||
|
||||
|
||||
class AssetSourceRel(ModelSQL):
|
||||
'Asset Source Relation'
|
||||
__name__ = 'investment.asset_source_rel'
|
||||
|
||||
source = fields.Many2One(string='Online Source', select=True,
|
||||
required=True, model_name='investment.source',
|
||||
ondelete='CASCADE')
|
||||
asset = fields.Many2One(string='Asset', select=True,
|
||||
required=True, model_name='investment.asset',
|
||||
ondelete='CASCADE')
|
||||
|
||||
# end AssetSourceRel
|
||||
|
|
28
locale/de.po
28
locale/de.po
|
@ -182,13 +182,13 @@ msgctxt "help:investment.asset,date:"
|
|||
msgid "Date of current rate"
|
||||
msgstr "Datum des aktuellen Kurses"
|
||||
|
||||
msgctxt "field:investment.asset,updtsource:"
|
||||
msgid "Update Source"
|
||||
msgstr "Kursquelle"
|
||||
msgctxt "field:investment.asset,updtsources:"
|
||||
msgid "Update Sources"
|
||||
msgstr "Kursquellen"
|
||||
|
||||
msgctxt "help:investment.asset,updtsource:"
|
||||
msgid "Select a source for the course update."
|
||||
msgstr "Wählen Sie eine Quelle für die Kursaktualisierung aus."
|
||||
msgctxt "help:investment.asset,updtsources:"
|
||||
msgid "Select sources for the course update. The course sources are tried until a valid value has been read."
|
||||
msgstr "Wählen Sie Quellen für die Kursaktualisierung aus. Die Kursquellen werden probiert bis ein gültiger Wert gelesen wurde."
|
||||
|
||||
msgctxt "field:investment.asset,updttime:"
|
||||
msgid "Time"
|
||||
|
@ -251,6 +251,22 @@ msgid "Mon - Sun"
|
|||
msgstr "Mo - So"
|
||||
|
||||
|
||||
###############################
|
||||
# investment.asset-source-rel #
|
||||
###############################
|
||||
msgctxt "model:investment.asset_source_rel,name:"
|
||||
msgid "Asset Source Relation"
|
||||
msgstr "Vermögenswert Quelle Verknüpfung"
|
||||
|
||||
msgctxt "field:investment.asset_source_rel,source:"
|
||||
msgid "Source"
|
||||
msgstr "Quelle"
|
||||
|
||||
msgctxt "field:investment.asset_source_rel,asset:"
|
||||
msgid "Asset"
|
||||
msgstr "Vermögenswert"
|
||||
|
||||
|
||||
#####################
|
||||
# investment.source #
|
||||
#####################
|
||||
|
|
24
locale/en.po
24
locale/en.po
|
@ -154,13 +154,13 @@ msgctxt "help:investment.asset,date:"
|
|||
msgid "Date of current rate"
|
||||
msgstr "Date of current rate"
|
||||
|
||||
msgctxt "field:investment.asset,updtsource:"
|
||||
msgid "Update Source"
|
||||
msgstr "Update Source"
|
||||
msgctxt "field:investment.asset,updtsources:"
|
||||
msgid "Update Sources"
|
||||
msgstr "Update Sources"
|
||||
|
||||
msgctxt "help:investment.asset,updtsource:"
|
||||
msgid "Select a source for the course update."
|
||||
msgstr "Select a source for the course update."
|
||||
msgctxt "help:investment.asset,updtsources:"
|
||||
msgid "Select sources for the course update. The course sources are tried until a valid value has been read."
|
||||
msgstr "Select sources for the course update. The course sources are tried until a valid value has been read."
|
||||
|
||||
msgctxt "field:investment.asset,updttime:"
|
||||
msgid "Time"
|
||||
|
@ -222,6 +222,18 @@ msgctxt "selection:investment.asset,updtdays:"
|
|||
msgid "Mon - Sun"
|
||||
msgstr "Mon - Sun"
|
||||
|
||||
msgctxt "model:investment.asset_source_rel,name:"
|
||||
msgid "Asset Source Relation"
|
||||
msgstr "Asset Source Relation"
|
||||
|
||||
msgctxt "field:investment.asset_source_rel,source:"
|
||||
msgid "Source"
|
||||
msgstr "Source"
|
||||
|
||||
msgctxt "field:investment.asset_source_rel,asset:"
|
||||
msgid "Asset"
|
||||
msgstr "Asset"
|
||||
|
||||
msgctxt "model:investment.source,name:"
|
||||
msgid "Online Source"
|
||||
msgstr "Online Source"
|
||||
|
|
|
@ -222,48 +222,56 @@ class OnlineSource(ModelSQL, ModelView):
|
|||
"""
|
||||
pool = Pool()
|
||||
Rate = pool.get('investment.rate')
|
||||
IrDate = pool.get('ir.date')
|
||||
|
||||
if asset.updtsource is None:
|
||||
if len(asset.updtsources) == 0:
|
||||
return
|
||||
rate_data = cls.read_from_website(
|
||||
asset.updtsource,
|
||||
isin = asset.isin,
|
||||
nsin = asset.wkn,
|
||||
symbol = asset.secsymb,
|
||||
)
|
||||
|
||||
if len(asset.updtsource.rgxident or '') > 0:
|
||||
# check result - same code?
|
||||
code = rate_data.get('code', None)
|
||||
if code:
|
||||
asset_code = getattr(asset, {
|
||||
'isin': 'isin',
|
||||
'nsin': 'wkn',
|
||||
'symbol': 'secsymb',
|
||||
}[asset.updtsource.rgxidtype])
|
||||
if (asset_code or '').lower() != code.lower():
|
||||
# fail
|
||||
logger.warning(
|
||||
'update_rate: got wrong code "%(wrong)s" - expected "%(exp)s"' % {
|
||||
'exp': asset_code,
|
||||
'wrong': code,
|
||||
})
|
||||
return False
|
||||
for updtsource in asset.updtsources:
|
||||
rate_data = cls.read_from_website(
|
||||
updtsource,
|
||||
isin = asset.isin,
|
||||
nsin = asset.wkn,
|
||||
symbol = asset.secsymb,
|
||||
)
|
||||
|
||||
to_create = {
|
||||
'date': rate_data.get('date', None),
|
||||
'rate': rate_data.get('rate', None),
|
||||
'asset': asset.id,
|
||||
}
|
||||
if (to_create['date'] is not None) and \
|
||||
(to_create['rate'] is not None):
|
||||
# check if exists
|
||||
if Rate.search_count([
|
||||
('asset.id', '=', asset.id),
|
||||
('date', '=', to_create['date']),
|
||||
]) == 0:
|
||||
Rate.create([to_create])
|
||||
return True
|
||||
if len(updtsource.rgxident or '') > 0:
|
||||
# check result - same code?
|
||||
code = rate_data.get('code', None)
|
||||
if code:
|
||||
asset_code = getattr(asset, {
|
||||
'isin': 'isin',
|
||||
'nsin': 'wkn',
|
||||
'symbol': 'secsymb',
|
||||
}[updtsource.rgxidtype])
|
||||
if (asset_code or '').lower() != code.lower():
|
||||
# fail
|
||||
logger.warning(
|
||||
'update_rate: got wrong code "%(wrong)s" - expected "%(exp)s"' % {
|
||||
'exp': asset_code,
|
||||
'wrong': code,
|
||||
})
|
||||
continue
|
||||
|
||||
to_create = {
|
||||
'date': rate_data.get('date', None),
|
||||
'rate': rate_data.get('rate', None),
|
||||
'asset': asset.id,
|
||||
}
|
||||
if (to_create['date'] is not None) and \
|
||||
(to_create['rate'] is not None):
|
||||
# check if exists
|
||||
if Rate.search_count([
|
||||
('asset.id', '=', asset.id),
|
||||
('date', '=', to_create['date']),
|
||||
]) == 0:
|
||||
Rate.create([to_create])
|
||||
return True
|
||||
else :
|
||||
# if we got a record for today - stop
|
||||
# otherwise try next source
|
||||
if to_create['date'] == IrDate.today():
|
||||
break
|
||||
return False
|
||||
|
||||
def get_regex_result(self, html_text, field_name):
|
||||
|
|
|
@ -568,18 +568,19 @@ class AssetTestCase(ModuleTestCase):
|
|||
'name': 'Source 1',
|
||||
}])
|
||||
|
||||
self.assertEqual(asset.updtsource, None)
|
||||
self.assertEqual(len(asset.updtsources), 0)
|
||||
self.assertEqual(asset.updttime, time(14,0))
|
||||
|
||||
asset.updtsource = o_source
|
||||
asset.updtsources = [o_source]
|
||||
asset.updttime = time(10, 45)
|
||||
asset.save()
|
||||
self.assertEqual(asset.updtsource.rec_name, 'Source 1')
|
||||
self.assertEqual(len(asset.updtsources), 1)
|
||||
self.assertEqual(asset.updtsources[0].rec_name, 'Source 1')
|
||||
self.assertEqual(asset.updttime, time(10, 45))
|
||||
|
||||
asset.updtsource = None
|
||||
asset.on_change_updtsource()
|
||||
self.assertEqual(asset.updtsource, None)
|
||||
asset.updtsources = []
|
||||
asset.on_change_updtsources()
|
||||
self.assertEqual(len(asset.updtsources), 0)
|
||||
self.assertEqual(asset.updttime, None)
|
||||
|
||||
@with_transaction()
|
||||
|
@ -606,7 +607,7 @@ class AssetTestCase(ModuleTestCase):
|
|||
Asset.write(*[
|
||||
[asset],
|
||||
{
|
||||
'updtsource': o_source.id,
|
||||
'updtsources': [('add', [o_source.id])],
|
||||
'updttime': time(10, 45),
|
||||
}])
|
||||
|
||||
|
@ -616,7 +617,8 @@ class AssetTestCase(ModuleTestCase):
|
|||
# re-read to make context work
|
||||
asset2, = Asset.browse([asset.id])
|
||||
|
||||
self.assertEqual(asset2.updtsource.rec_name, 'Source 1')
|
||||
self.assertEqual(len(asset2.updtsources), 1)
|
||||
self.assertEqual(asset2.updtsources[0].rec_name, 'Source 1')
|
||||
self.assertEqual(asset2.updttime, time(10, 45))
|
||||
self.assertEqual(len(asset2.rates), 0)
|
||||
# qdate = 2022-10-14 simulates existence of record at this day
|
||||
|
@ -643,7 +645,7 @@ class AssetTestCase(ModuleTestCase):
|
|||
self.assertEqual(len(asset.rates), 1)
|
||||
|
||||
asset2, = Asset.browse([asset.id])
|
||||
self.assertEqual(asset.updtsource.rec_name, 'Source 1')
|
||||
self.assertEqual(asset.updtsources[0].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, 17))
|
||||
|
@ -668,7 +670,7 @@ class AssetTestCase(ModuleTestCase):
|
|||
self.assertEqual(len(asset.rates), 2)
|
||||
|
||||
asset2, = Asset.browse([asset.id])
|
||||
self.assertEqual(asset2.updtsource.rec_name, 'Source 1')
|
||||
self.assertEqual(asset2.updtsources[0].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, 18))
|
||||
|
|
|
@ -64,7 +64,7 @@ class SourceTestCase(ModuleTestCase):
|
|||
Asset.write(*[
|
||||
[asset],
|
||||
{
|
||||
'updtsource': osource.id,
|
||||
'updtsources': [('add', [osource.id])],
|
||||
}])
|
||||
|
||||
with Transaction().set_context({
|
||||
|
@ -76,7 +76,8 @@ class SourceTestCase(ModuleTestCase):
|
|||
self.assertEqual(asset2.isin, 'XC0009655157')
|
||||
self.assertEqual(asset2.secsymb, '1472977')
|
||||
self.assertEqual(asset2.updttime, time(14, 0))
|
||||
self.assertEqual(asset2.updtsource.rec_name, 'Source 1')
|
||||
self.assertEqual(len(asset2.updtsources), 1)
|
||||
self.assertEqual(asset2.updtsources[0].rec_name, 'Source 1')
|
||||
self.assertEqual(asset2.updtdays, 'work')
|
||||
self.assertEqual(asset2.nextupdate, datetime(2022, 10, 3, 14, 0))
|
||||
self.assertEqual(len(asset.rates), 0)
|
||||
|
|
|
@ -57,14 +57,12 @@ full copyright notices and license terms. -->
|
|||
<field name="rates" mode="tree,form,graph"/>
|
||||
</page>
|
||||
<page id="pgupdate" col="4" string="Course Update">
|
||||
<label name="updtsource"/>
|
||||
<field name="updtsource"/>
|
||||
<label name="updttime"/>
|
||||
<field name="updttime"/>
|
||||
|
||||
<label id="labupdt" colspan="2" string=" "/>
|
||||
<label name="updtdays"/>
|
||||
<field name="updtdays"/>
|
||||
|
||||
<field name="updtsources" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
|
|
Loading…
Reference in a new issue