cashbook/importer/import_qif.py

220 lines
7.1 KiB
Python
Raw Normal View History

2022-08-26 21:47:51 +00:00
# -*- coding: utf-8 -*-
# This file is part of the cashbook-module from m-ds for Tryton.
# The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms.
file_name = 'bargeld.qif'
company_name = 'm-ds'
replace_catnames = [
('Musik/Kino', 'Musik, Kino'),
]
from quiffen import Qif
2022-08-26 21:47:51 +00:00
from proteus import config, Model
from datetime import date
import json
from datetime import datetime
from decimal import Decimal
2022-08-26 21:47:51 +00:00
cfg1 = config.set_trytond(
'postgresql://postgres:test1@localhost:5432/tr44/',
user='admin',
config_file='/home/trytproj/projekt/py3tr60/etc/trytond.conf')
# check active modules
need_modules = ['cashbook', 'party', 'company']
IrModule = Model.get('ir.module')
mod_lst = IrModule.find([
('state', '=', 'activated'),
('name', 'in', need_modules),
])
if not len(mod_lst) == len(need_modules):
raise ValueError('einige module sind nicht aktiviert!')
def qif_split_by_type(file_name):
""" split file by type
2022-08-26 21:47:51 +00:00
"""
lines = []
with open(file_name, 'r') as fhdl:
print('-- read file "%s"' % file_name)
lines = fhdl.readlines()
blocks = {}
current_type = None
for line in lines:
if line.startswith('!Type:'):
current_type = line[len('!Type:'):].strip()
else :
if not current_type in blocks.keys():
blocks[current_type] = []
blocks[current_type].append(line.strip())
for block in blocks.keys():
blocks[block] = '\n'.join(blocks[block])
print ('-- found type: %s (%d bytes)' % (block, len(blocks[block])))
return blocks
# end qif_split_by_type
def qif_read_categories(catdata):
""" read categories from text
"""
def add_category(catdict, namelst, ctype):
""" add category to dict
"""
if not namelst[0] in catdict.keys():
catdict[namelst[0]] = {'type': ctype, 'childs': {}}
if len(namelst) > 1:
catdict[namelst[0]]['childs'] = add_category(
catdict[namelst[0]]['childs'],
[namelst[1]],
ctype)
return catdict
categories = {'in': {}, 'out': {}}
for cattxt in catdata.split('^'):
if len(cattxt.strip()) == 0:
continue
catname = None
cattype = None
for line in cattxt.strip().split('\n'):
if line.startswith('N'):
catname = line[1:].strip().split(':')
elif line.startswith('E'):
cattype = 'out'
elif line.startswith('I'):
cattype = 'in'
else :
raise ValueError('invalid line: %s (%s)' % (line, cattxt))
categories[cattype] = add_category(categories[cattype], catname, cattype)
return categories
# end qif_read_categories
def qif_read_bank(bankdata):
""" read content of bookings
"""
result = []
def get_amount_from_txt(amount_txt):
""" convert text to Decimal
"""
if (',' in amount_txt) and (amount_txt[-3] == '.'):
# '.' = decimal, ',' = tousand
amount_txt = amount_txt.replace(',', '.')
elif ('.' in amount_txt) and (amount_txt[-3] == ','):
# ',' = decimal, '.' = tousand
amount_txt = amount_txt.replace('.', '')
amount_txt = amount_txt.replace(',', '.')
elif ',' in amount_txt:
amount_txt = amount_txt.replace(',', '.')
return Decimal(amount_txt)
for booktxt in bankdata.split('^'):
if len(booktxt.strip()) == 0:
continue
booking = {'split': []}
for line in booktxt.strip().split('\n'):
line_txt = line[1:].strip()
if line.startswith('D'): # date
booking['date'] = datetime.strptime(line_txt, '%d.%m.%Y').date()
elif line.startswith('T'): # total
booking['amount'] = get_amount_from_txt(line_txt)
elif line.startswith('U'): # total
booking['amount'] = get_amount_from_txt(line_txt)
elif line.startswith('P'): # party
booking['party'] = line_txt
elif line.startswith('A'): # address
booking['address'] = line_txt
elif line.startswith('N'): # address
booking['checknumber'] = line_txt
elif line.startswith('M'): # memo
booking['description'] = line_txt
elif line.startswith('C'): # state
booking['state'] = {
'X': 'check',
'*': 'edit',
}.get(line_txt, 'edit')
elif line.startswith('L'): # category, account
if line_txt.startswith('[') and line_txt.endswith(']'):
booking['account'] = line_txt[1:-1]
else :
booking['category'] = line_txt
elif line.startswith('S'): # split: category
booking['split'].append({
'category': line_txt,
})
elif line.startswith('E'): # split: memo
booking['split'][-1]['description'] = line_txt
elif line.startswith('$'): # split: amount
booking['split'][-1]['amount'] = get_amount_from_txt(line_txt)
elif line.startswith('£'): # split: amount
booking['split'][-1]['amount'] = get_amount_from_txt(line_txt)
else :
raise ValueError('unknown line-code: %s' % (line))
result.append(booking)
return result
2022-08-26 21:47:51 +00:00
# end qif_read_bank
def get_category_create(categories, cattype):
""" convert categories in create-list
"""
result = []
for cat_name in categories.keys():
cat_name2 = cat_name
for repl in replace_catnames:
cat_name2 = cat_name.replace(repl[0], repl[1])
if cattype != categories[cat_name]['type']:
raise ValueError('cattype dont match')
cat1 = {
'name': cat_name2,
'cattype': categories[cat_name]['type'],
}
if len(categories[cat_name]['childs']) > 0:
childs = get_category_create(categories[cat_name]['childs'], cattype)
if len(childs) > 0:
cat1['childs'] = [('create', childs)]
result.append(cat1)
return result
# end get_category_tree
2022-08-26 21:47:51 +00:00
Company = Model.get('company.company')
company1, = Company.find([('rec_name', '=', company_name)])
qif_type_data = qif_split_by_type(file_name)
if 'Cat' in qif_type_data.keys():
Category = Model.get('cashbook.category')
categories = qif_read_categories(qif_type_data['Cat'])
to_create = get_category_create(categories['in'], 'in')
to_create.extend(get_category_create(categories['out'], 'out'))
if len(to_create) > 0:
try :
catlst = Category.create(to_create, context={'company': company1.id})
print('-- created %d categories' % len(catlst))
except:
print('-- categories alredy exist')
if 'Bank' in qif_type_data.keys():
bookings = qif_read_bank(qif_type_data['Bank'])
print('-- bookings:', bookings)