# -*- 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 from proteus import config, Model from datetime import date import json from datetime import datetime from decimal import Decimal 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 """ 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 # 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 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)