import wizard
This commit is contained in:
parent
94687139b1
commit
77d6e5f8ef
8 changed files with 382 additions and 0 deletions
|
@ -11,6 +11,7 @@ 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
|
from .diagram import GraphDef, ChartPoint
|
||||||
|
from .import_wiz import ImportWizard, ImportWizardStart
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
|
@ -21,6 +22,7 @@ def register():
|
||||||
Rate,
|
Rate,
|
||||||
Identifier,
|
Identifier,
|
||||||
Cron,
|
Cron,
|
||||||
|
ImportWizardStart,
|
||||||
module='investment', type_='model')
|
module='investment', type_='model')
|
||||||
Pool.register(
|
Pool.register(
|
||||||
GraphDef,
|
GraphDef,
|
||||||
|
@ -28,5 +30,6 @@ def register():
|
||||||
module='investment', type_='model', depends=['diagram'])
|
module='investment', type_='model', depends=['diagram'])
|
||||||
Pool.register(
|
Pool.register(
|
||||||
UpdateSoureWizard,
|
UpdateSoureWizard,
|
||||||
|
ImportWizard,
|
||||||
module='investment', type_='wizard')
|
module='investment', type_='wizard')
|
||||||
|
|
||||||
|
|
218
import_wiz.py
Normal file
218
import_wiz.py
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
# -*- 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 io import StringIO
|
||||||
|
from datetime import datetime, date
|
||||||
|
from decimal import Decimal
|
||||||
|
import csv
|
||||||
|
from trytond.pool import Pool
|
||||||
|
from trytond.model import ModelView, fields
|
||||||
|
from trytond.wizard import Wizard, StateTransition, StateView, Button
|
||||||
|
from trytond.transaction import Transaction
|
||||||
|
from trytond.exceptions import UserError
|
||||||
|
from trytond.i18n import gettext
|
||||||
|
|
||||||
|
|
||||||
|
sel_dec_divider = [
|
||||||
|
(',', ','),
|
||||||
|
('.', '.'),
|
||||||
|
]
|
||||||
|
|
||||||
|
sel_date_fmt = [
|
||||||
|
('%d.%m.%Y', 'dd.mm.yyyy'),
|
||||||
|
('%Y-%m-%d', 'yyyy-mm-dd'),
|
||||||
|
('%m/%d/%Y', 'mm/dd/yyyy'),
|
||||||
|
]
|
||||||
|
|
||||||
|
sel_field_delimiter = [
|
||||||
|
(';', ';'),
|
||||||
|
(',', ','),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ImportWizardStart(ModelView):
|
||||||
|
'Import CSV-File'
|
||||||
|
__name__ = 'investment.imp_wiz.start'
|
||||||
|
|
||||||
|
asset = fields.Many2One(string='Asset', readonly=True,
|
||||||
|
model_name='investment.asset')
|
||||||
|
file_ = fields.Binary(string="CSV-File", required=True)
|
||||||
|
dec_divider = fields.Selection(string='Decimal divider',
|
||||||
|
required=True, selection=sel_dec_divider)
|
||||||
|
date_fmt = fields.Selection(string='Date format',
|
||||||
|
required=True, selection=sel_date_fmt)
|
||||||
|
field_delimiter = fields.Selection(string='Field delimiter',
|
||||||
|
required=True, selection=sel_field_delimiter)
|
||||||
|
|
||||||
|
# end ImportWizardStart
|
||||||
|
|
||||||
|
|
||||||
|
class ImportWizard(Wizard):
|
||||||
|
'Import CSV-File'
|
||||||
|
__name__ = 'investment.imp_wiz'
|
||||||
|
|
||||||
|
start_state = 'start'
|
||||||
|
start = StateView(model_name='investment.imp_wiz.start', \
|
||||||
|
view='investment.imp_wiz_start_form', \
|
||||||
|
buttons=[
|
||||||
|
Button(string='Cancel', state='end', icon='tryton-cancel'),
|
||||||
|
Button(string='Import File', state='importf', icon='tryton-import', default=True),
|
||||||
|
])
|
||||||
|
importf = StateTransition()
|
||||||
|
|
||||||
|
def default_start(self, fields):
|
||||||
|
""" show asset
|
||||||
|
"""
|
||||||
|
context = Transaction().context
|
||||||
|
|
||||||
|
values = {
|
||||||
|
'dec_divider': ',',
|
||||||
|
'date_fmt': '%d.%m.%Y',
|
||||||
|
'field_delimiter': ';',
|
||||||
|
}
|
||||||
|
values['asset'] = context.get('active_id', None)
|
||||||
|
return values
|
||||||
|
|
||||||
|
def transition_importf(self):
|
||||||
|
""" read file, import
|
||||||
|
"""
|
||||||
|
pool = Pool()
|
||||||
|
ImportWiz = pool.get('investment.imp_wiz', type='wizard')
|
||||||
|
|
||||||
|
if self.start.file_ is not None:
|
||||||
|
(lines, max_date, min_date) = ImportWiz.read_csv_file(
|
||||||
|
self.start.file_.decode('utf8'),
|
||||||
|
dec_divider = self.start.dec_divider,
|
||||||
|
date_fmt = self.start.date_fmt,
|
||||||
|
delimiter = self.start.field_delimiter)
|
||||||
|
|
||||||
|
if len(lines) > 0:
|
||||||
|
ImportWiz.upload_rates(
|
||||||
|
self.start.asset,
|
||||||
|
lines, min_date, max_date)
|
||||||
|
return 'end'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def upload_rates(cls, asset, rates_list, min_date, max_date):
|
||||||
|
""" upload new rates to asset
|
||||||
|
"""
|
||||||
|
Rate = Pool().get('investment.rate')
|
||||||
|
|
||||||
|
# get rate in date-range
|
||||||
|
rates = Rate.search([
|
||||||
|
('asset.id', '=', asset.id),
|
||||||
|
('date', '>=', min_date),
|
||||||
|
('date', '<=', max_date),
|
||||||
|
])
|
||||||
|
existing_dates = [x.date for x in rates]
|
||||||
|
done_dates = []
|
||||||
|
|
||||||
|
to_create = []
|
||||||
|
for rate in rates_list:
|
||||||
|
if rate['date'] in existing_dates:
|
||||||
|
continue
|
||||||
|
if rate['date'] in done_dates:
|
||||||
|
continue
|
||||||
|
|
||||||
|
to_create.append({
|
||||||
|
'asset': asset.id,
|
||||||
|
'date': rate['date'],
|
||||||
|
'rate': rate['rate'],
|
||||||
|
})
|
||||||
|
done_dates.append(rate['date'])
|
||||||
|
|
||||||
|
if len(to_create) > 0:
|
||||||
|
print('-- to_create:', to_create)
|
||||||
|
Rate.create(to_create)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def read_csv_file(cls, file_content, dec_divider, date_fmt, delimiter):
|
||||||
|
""" read file-content from csv
|
||||||
|
"""
|
||||||
|
result = []
|
||||||
|
|
||||||
|
del_chars = ['.', ',']
|
||||||
|
del_chars.remove(dec_divider)
|
||||||
|
min_date = None
|
||||||
|
max_date = None
|
||||||
|
min_rate = None
|
||||||
|
max_rate = None
|
||||||
|
|
||||||
|
with StringIO(file_content) as fhdl:
|
||||||
|
csv_lines = csv.DictReader(fhdl,
|
||||||
|
fieldnames = ['date', 'rate'],
|
||||||
|
dialect='excel',
|
||||||
|
delimiter=delimiter)
|
||||||
|
|
||||||
|
for line in csv_lines:
|
||||||
|
# skip first line
|
||||||
|
if line.get('date', '') == 'date':
|
||||||
|
continue
|
||||||
|
|
||||||
|
try :
|
||||||
|
date_val = datetime.strptime(line.get('date', None).strip(), date_fmt).date()
|
||||||
|
except :
|
||||||
|
raise UserError(gettext(
|
||||||
|
'investment.msg_import_err_date',
|
||||||
|
datefmt = date_fmt,
|
||||||
|
colnr = '1',
|
||||||
|
))
|
||||||
|
try :
|
||||||
|
rate_val = line.get('rate', None).replace(del_chars[0], '').strip()
|
||||||
|
rate_val = Decimal(rate_val.replace(dec_divider, '.'))
|
||||||
|
except :
|
||||||
|
raise UserError(gettext(
|
||||||
|
'investment.msg_import_err_date',
|
||||||
|
datefmt = 'dd%sdd' % dec_divider,
|
||||||
|
colnr = '2',
|
||||||
|
))
|
||||||
|
|
||||||
|
if isinstance(date_val, date) and isinstance(rate_val, Decimal):
|
||||||
|
result.append({'date': date_val, 'rate': rate_val})
|
||||||
|
|
||||||
|
# date range
|
||||||
|
if max_date is None:
|
||||||
|
max_date = date_val
|
||||||
|
else :
|
||||||
|
if max_date < date_val:
|
||||||
|
max_date = date_val
|
||||||
|
|
||||||
|
if min_date is None:
|
||||||
|
min_date = date_val
|
||||||
|
else :
|
||||||
|
if min_date > date_val:
|
||||||
|
min_date = date_val
|
||||||
|
|
||||||
|
# rate range
|
||||||
|
if max_rate is None:
|
||||||
|
max_rate = rate_val
|
||||||
|
else :
|
||||||
|
if max_rate < rate_val:
|
||||||
|
max_rate = rate_val
|
||||||
|
|
||||||
|
if min_rate is None:
|
||||||
|
min_rate = rate_val
|
||||||
|
else :
|
||||||
|
if min_rate > rate_val:
|
||||||
|
min_rate = rate_val
|
||||||
|
else :
|
||||||
|
raise UserError(gettext(
|
||||||
|
'investment.msg_err_unknown_content',
|
||||||
|
linetxt = line,
|
||||||
|
))
|
||||||
|
|
||||||
|
# ~ print('- found %d records' % len(result))
|
||||||
|
# ~ print('- dates from %s to %s' % (
|
||||||
|
# ~ min_date.isoformat() if min_date is not None else '-',
|
||||||
|
# ~ max_date.isoformat() if max_date is not None else '-',
|
||||||
|
# ~ ))
|
||||||
|
# ~ print('- rates from %s to %s' % (
|
||||||
|
# ~ str(min_rate) if min_rate is not None else '-',
|
||||||
|
# ~ str(max_rate) if max_rate is not None else '-',
|
||||||
|
# ~ ))
|
||||||
|
return (result, max_date, min_date)
|
||||||
|
|
||||||
|
# end ImportWizard
|
||||||
|
|
31
import_wiz.xml
Normal file
31
import_wiz.xml
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?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>
|
||||||
|
|
||||||
|
<record model="ir.ui.view" id="imp_wiz_start_form">
|
||||||
|
<field name="model">investment.imp_wiz.start</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">import_start_form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.action.wizard" id="act_import_wizard">
|
||||||
|
<field name="name">Import CSV-File</field>
|
||||||
|
<field name="wiz_name">investment.imp_wiz</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action-res.group"
|
||||||
|
id="act_import_wizard-group_investment_admin">
|
||||||
|
<field name="action" ref="act_import_wizard"/>
|
||||||
|
<field name="group" ref="group_investment_admin"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.action.keyword" id="act_import_wizard-cat-keyword">
|
||||||
|
<field name="keyword">form_action</field>
|
||||||
|
<field name="model">investment.asset,-1</field>
|
||||||
|
<field name="action" ref="act_import_wizard"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</tryton>
|
56
locale/de.po
56
locale/de.po
|
@ -34,6 +34,14 @@ msgctxt "model:ir.message,text:msg_currency_rate_positive"
|
||||||
msgid "A asset rate must be positive."
|
msgid "A asset rate must be positive."
|
||||||
msgstr "Der Kurs des Vermögenswertes muss positiv sein."
|
msgstr "Der Kurs des Vermögenswertes muss positiv sein."
|
||||||
|
|
||||||
|
msgctxt "model:ir.message,text:msg_import_err_date"
|
||||||
|
msgid "failed to read column %(colnr)s of file, expected date (format: %(datefmt)s)"
|
||||||
|
msgstr "Fehler beim Lesen von Spalte %(colnr)s der Datei, erwartetes Datum (Format: %(datefmt)s)"
|
||||||
|
|
||||||
|
msgctxt "model:ir.message,text:msg_err_unknown_content"
|
||||||
|
msgid "failed to identify row content: %(linetxt)s"
|
||||||
|
msgstr "Zeileninhalt konnte nicht identifiziert werden: %(linetxt)s"
|
||||||
|
|
||||||
|
|
||||||
##############
|
##############
|
||||||
# ir.ui.menu #
|
# ir.ui.menu #
|
||||||
|
@ -66,6 +74,10 @@ msgctxt "model:ir.action,name:updt_source_wiz"
|
||||||
msgid "Update Source"
|
msgid "Update Source"
|
||||||
msgstr "Quelle aktualisieren"
|
msgstr "Quelle aktualisieren"
|
||||||
|
|
||||||
|
msgctxt "model:ir.action,name:act_import_wizard"
|
||||||
|
msgid "Import CSV-File"
|
||||||
|
msgstr "CSV-Datei importieren"
|
||||||
|
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# ir.action.act_window.domain #
|
# ir.action.act_window.domain #
|
||||||
|
@ -83,6 +95,50 @@ msgid "All"
|
||||||
msgstr "Alle"
|
msgstr "Alle"
|
||||||
|
|
||||||
|
|
||||||
|
############################
|
||||||
|
# investment.imp_wiz.start #
|
||||||
|
############################
|
||||||
|
msgctxt "model:investment.imp_wiz.start,name:"
|
||||||
|
msgid "Import CSV-File"
|
||||||
|
msgstr "CSV-Datei importieren"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,asset:"
|
||||||
|
msgid "Asset"
|
||||||
|
msgstr "Vermögenswert"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,file_:"
|
||||||
|
msgid "CSV-File"
|
||||||
|
msgstr "CSV-Datei"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,dec_divider:"
|
||||||
|
msgid "Decimal divider"
|
||||||
|
msgstr "Dezimaltrenner"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,date_fmt:"
|
||||||
|
msgid "Date format"
|
||||||
|
msgstr "Datumsformat"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,field_delimiter:"
|
||||||
|
msgid "Field delimiter"
|
||||||
|
msgstr "Feldtrenner"
|
||||||
|
|
||||||
|
|
||||||
|
######################
|
||||||
|
# investment.imp_wiz #
|
||||||
|
######################
|
||||||
|
msgctxt "model:investment.imp_wiz,name:"
|
||||||
|
msgid "Import CSV-File"
|
||||||
|
msgstr "CSV-Datei importieren"
|
||||||
|
|
||||||
|
msgctxt "wizard_button:investment.imp_wiz,start,end:"
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Abbruch"
|
||||||
|
|
||||||
|
msgctxt "wizard_button:investment.imp_wiz,start,importf:"
|
||||||
|
msgid "Import File"
|
||||||
|
msgstr "Datei importieren"
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# investment.source_update #
|
# investment.source_update #
|
||||||
############################
|
############################
|
||||||
|
|
48
locale/en.po
48
locale/en.po
|
@ -22,6 +22,14 @@ msgctxt "model:ir.message,text:msg_currency_rate_positive"
|
||||||
msgid "A asset rate must be positive."
|
msgid "A asset rate must be positive."
|
||||||
msgstr "A asset rate must be positive."
|
msgstr "A asset rate must be positive."
|
||||||
|
|
||||||
|
msgctxt "model:ir.message,text:msg_import_err_date"
|
||||||
|
msgid "failed to read column %(colnr)s of file, expected date (format: %(datefmt)s)"
|
||||||
|
msgstr "failed to read column %(colnr)s of file, expected date (format: %(datefmt)s)"
|
||||||
|
|
||||||
|
msgctxt "model:ir.message,text:msg_err_unknown_content"
|
||||||
|
msgid "failed to identify row content: %(linetxt)s"
|
||||||
|
msgstr "failed to identify row content: %(linetxt)s"
|
||||||
|
|
||||||
msgctxt "model:ir.ui.menu,name:menu_investment"
|
msgctxt "model:ir.ui.menu,name:menu_investment"
|
||||||
msgid "Investment"
|
msgid "Investment"
|
||||||
msgstr "Investment"
|
msgstr "Investment"
|
||||||
|
@ -46,6 +54,10 @@ msgctxt "model:ir.action,name:updt_source_wiz"
|
||||||
msgid "Update Source"
|
msgid "Update Source"
|
||||||
msgstr "Update Source"
|
msgstr "Update Source"
|
||||||
|
|
||||||
|
msgctxt "model:ir.action,name:act_import_wizard"
|
||||||
|
msgid "Import CSV-File"
|
||||||
|
msgstr "Import CSV-File"
|
||||||
|
|
||||||
msgctxt "model:ir.action.act_window.domain,name:act_asset_domain_current"
|
msgctxt "model:ir.action.act_window.domain,name:act_asset_domain_current"
|
||||||
msgid "Current"
|
msgid "Current"
|
||||||
msgstr "Current"
|
msgstr "Current"
|
||||||
|
@ -58,6 +70,42 @@ msgctxt "model:ir.action.act_window.domain,name:act_asset_domain_all"
|
||||||
msgid "All"
|
msgid "All"
|
||||||
msgstr "All"
|
msgstr "All"
|
||||||
|
|
||||||
|
msgctxt "model:investment.imp_wiz.start,name:"
|
||||||
|
msgid "Import CSV-File"
|
||||||
|
msgstr "Import CSV-File"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,asset:"
|
||||||
|
msgid "Asset"
|
||||||
|
msgstr "Asset"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,file_:"
|
||||||
|
msgid "CSV-File"
|
||||||
|
msgstr "CSV-File"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,dec_divider:"
|
||||||
|
msgid "Decimal divider"
|
||||||
|
msgstr "Decimal divider"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,date_fmt:"
|
||||||
|
msgid "Date format"
|
||||||
|
msgstr "Date format"
|
||||||
|
|
||||||
|
msgctxt "field:investment.imp_wiz.start,field_delimiter:"
|
||||||
|
msgid "Field delimiter"
|
||||||
|
msgstr "Field delimiter"
|
||||||
|
|
||||||
|
msgctxt "model:investment.imp_wiz,name:"
|
||||||
|
msgid "Import CSV-File"
|
||||||
|
msgstr "Import CSV-File"
|
||||||
|
|
||||||
|
msgctxt "wizard_button:investment.imp_wiz,start,end:"
|
||||||
|
msgid "Cancel"
|
||||||
|
msgstr "Cancel"
|
||||||
|
|
||||||
|
msgctxt "wizard_button:investment.imp_wiz,start,importf:"
|
||||||
|
msgid "Import File"
|
||||||
|
msgstr "Import File"
|
||||||
|
|
||||||
msgctxt "model:investment.source_update,name:"
|
msgctxt "model:investment.source_update,name:"
|
||||||
msgid "Update Source"
|
msgid "Update Source"
|
||||||
msgstr "Update Source"
|
msgstr "Update Source"
|
||||||
|
|
|
@ -11,6 +11,12 @@ full copyright notices and license terms. -->
|
||||||
<record model="ir.message" id="msg_rate_positive">
|
<record model="ir.message" id="msg_rate_positive">
|
||||||
<field name="text">A asset rate must be positive.</field>
|
<field name="text">A asset rate must be positive.</field>
|
||||||
</record>
|
</record>
|
||||||
|
<record model="ir.message" id="msg_import_err_date">
|
||||||
|
<field name="text">failed to read column %(colnr)s of file, expected date (format: %(datefmt)s)</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.message" id="msg_err_unknown_content">
|
||||||
|
<field name="text">failed to identify row content: %(linetxt)s</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|
|
@ -18,5 +18,6 @@ xml:
|
||||||
update_wiz.xml
|
update_wiz.xml
|
||||||
rate.xml
|
rate.xml
|
||||||
diagram.xml
|
diagram.xml
|
||||||
|
import_wiz.xml
|
||||||
menu.xml
|
menu.xml
|
||||||
cron.xml
|
cron.xml
|
||||||
|
|
19
view/import_start_form.xml
Normal file
19
view/import_start_form.xml
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?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. -->
|
||||||
|
<form col="4">
|
||||||
|
<label name="asset"/>
|
||||||
|
<field name="asset" colspan="3"/>
|
||||||
|
|
||||||
|
<label name="dec_divider"/>
|
||||||
|
<field name="dec_divider"/>
|
||||||
|
<label name="date_fmt"/>
|
||||||
|
<field name="date_fmt"/>
|
||||||
|
<label name="field_delimiter"/>
|
||||||
|
<field name="field_delimiter"/>
|
||||||
|
<newline/>
|
||||||
|
|
||||||
|
<label name="file_"/>
|
||||||
|
<field name="file_"/>
|
||||||
|
</form>
|
Loading…
Reference in a new issue