import wizard
This commit is contained in:
parent
94687139b1
commit
77d6e5f8ef
8 changed files with 382 additions and 0 deletions
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
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue