Compare commits

..

20 commits

Author SHA1 Message Date
Frederik Jaeckel
c2987eb3e1 Tryton 7.0 2023-12-01 12:40:37 +01:00
Frederik Jaeckel
900c2b975c formatting 2023-12-01 12:39:05 +01:00
Frederik Jaeckel
40d3a9e825 Tryton 6.8: test, info 2023-06-06 15:56:32 +02:00
Frederik Jaeckel
1163a8125d export: set digits - format numbers 2023-06-06 15:41:58 +02:00
Frederik Jaeckel
d0e2c8bc52 formatting, optimize code 2023-06-06 15:22:57 +02:00
Frederik Jaeckel
6cf6584f92 setup.py 2023-02-14 10:47:30 +01:00
Frederik Jaeckel
ea282daa05 test korrigiert 2022-09-16 10:40:28 +02:00
Frederik Jaeckel
ef84ca3ada test für splitbuchung mit transfer 2022-09-13 22:19:20 +02:00
Frederik Jaeckel
c09644e660 splitbuchung: konvertiert transfers + test 2022-09-13 18:14:06 +02:00
Frederik Jaeckel
197f35d3bb import: transfer buchungen korrigiert 2022-09-13 11:29:43 +02:00
Frederik Jaeckel
1a4ed7a1df qif-import: ignoriert leere buchungen, prüft buchungstyp und kategorietyp 2022-09-12 18:52:22 +02:00
Frederik Jaeckel
2db020f5d8 import: für umbuchungen optimiert + test 2022-09-08 17:29:10 +02:00
Frederik Jaeckel
9e6cfb210f übersetzung 2022-09-08 12:53:48 +02:00
Frederik Jaeckel
18093219a8 transaktion: check für fehlende kategorie 2022-09-08 11:20:28 +02:00
Frederik Jaeckel
79620f8cbb transaktionen: export + test 2022-09-05 10:13:20 +02:00
Frederik Jaeckel
35a31cff69 transaktion: import korrigiert 2022-09-03 20:36:16 +02:00
Frederik Jaeckel
833f49c9a6 import: party, transaction
übersetzung korrigiert
2022-09-02 14:33:12 +02:00
Frederik Jaeckel
50cbb2cc37 party: qif import 2022-09-01 17:13:55 +02:00
Frederik Jaeckel
0287452fe8 import der transaktionen begonnen 2022-09-01 14:48:04 +02:00
Frederik Jaeckel
b50927753b kategorie: export als qif 2022-08-31 17:32:01 +02:00
15 changed files with 429 additions and 354 deletions

View file

@ -9,25 +9,11 @@ pip install mds-cashbook-dataexchange
Requires Requires
======== ========
- Tryton 6.0 - Tryton 7.0
Changes Changes
======= =======
*6.0.3 - 13.09.2022* *7.0.0 - 01.12.2023*
- add: import of split-bookings - compatibility to Tryton 7.0
- updt: transfers
*6.0.2 - 05.09.2022*
- category: qif-export
- party, transactions: qif-import/export
*6.0.1 - 31.08.2022*
- add: qif - category - import
*6.0.0 - 28.08.2022*
- init

View file

@ -7,9 +7,11 @@ from trytond.pool import Pool
from .category import Category from .category import Category
from .book import Book from .book import Book
from .qiftool import QifTool from .qiftool import QifTool
from .qif_import_wiz import ImportQifWizard, ImportQifWizardStart, ImportQifWizardInfo from .qif_import_wiz import (
ImportQifWizard, ImportQifWizardStart, ImportQifWizardInfo)
from .qif_export import QifCategoryExport, QifBookExport from .qif_export import QifCategoryExport, QifBookExport
def register(): def register():
Pool.register( Pool.register(
QifTool, QifTool,

View file

@ -3,7 +3,6 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta from trytond.pool import Pool, PoolMeta
@ -28,13 +27,13 @@ class Book(metaclass=PoolMeta):
Book2 = pool.get('cashbook.book') Book2 = pool.get('cashbook.book')
qif_content = QifTool.split_by_type(qifdata) qif_content = QifTool.split_by_type(qifdata)
if not 'Bank' in qif_content.keys(): if 'Bank' not in qif_content.keys():
return None return None
(to_create, msg_list, fail_cnt) = QifTool.convert_transactions_to_create( (to_create, msg_list, fail_cnt) = \
QifTool.convert_transactions_to_create(
book, book,
QifTool.qif_read_transactions(qif_content['Bank']) QifTool.qif_read_transactions(qif_content['Bank']))
)
if fail_cnt == 0: if fail_cnt == 0:
Book2.write(*[ Book2.write(*[
[book], [book],

View file

@ -3,7 +3,6 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from trytond.transaction import Transaction
from trytond.pool import Pool, PoolMeta from trytond.pool import Pool, PoolMeta
@ -18,8 +17,9 @@ class Category(metaclass=PoolMeta):
Category2 = pool.get('cashbook.category') Category2 = pool.get('cashbook.category')
QifTool = pool.get('cashbook_dataexchange.qiftool') QifTool = pool.get('cashbook_dataexchange.qiftool')
categories = Category2.search([], categories = Category2.search(
order=[('cattype', 'ASC'), ('rec_name', 'ASC')]) [],
order=[('cattype', 'ASC'), ('rec_name', 'ASC')])
export = ['!Type:Cat'] export = ['!Type:Cat']
export.extend([QifTool.qif_export_category(x) for x in categories]) export.extend([QifTool.qif_export_category(x) for x in categories])
@ -34,7 +34,7 @@ class Category(metaclass=PoolMeta):
Category2 = pool.get('cashbook.category') Category2 = pool.get('cashbook.category')
type_data = QifTool.split_by_type(qifdata) type_data = QifTool.split_by_type(qifdata)
if not 'Cat' in type_data.keys(): if 'Cat' not in type_data.keys():
return None return None
to_create = QifTool.convert_categories_to_create( to_create = QifTool.convert_categories_to_create(

View file

@ -8,7 +8,6 @@ from trytond.pool import Pool
from slugify import slugify from slugify import slugify
class QifCategoryExport(Report): class QifCategoryExport(Report):
__name__ = 'cashbook_dataexchange.rep_category' __name__ = 'cashbook_dataexchange.rep_category'
@ -40,7 +39,7 @@ class QifBookExport(Report):
IrDate = pool.get('ir.date') IrDate = pool.get('ir.date')
Book = pool.get('cashbook.book') Book = pool.get('cashbook.book')
books = Book.search([('id', '=', data.get('id', -1))]) books = Book.search([('id', '=', data.get('id', -1))])
if len(books) == 1: if len(books) == 1:
return ( return (
'qif', 'qif',
@ -51,7 +50,7 @@ class QifBookExport(Report):
'book': books[0].name, 'book': books[0].name,
}, max_length=100, word_boundary=True, save_order=True), }, max_length=100, word_boundary=True, save_order=True),
) )
else : else:
return ( return (
'txt', 'txt',
'not cashbook found', 'not cashbook found',

View file

@ -7,26 +7,26 @@ from trytond.transaction import Transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.model import ModelView, fields from trytond.model import ModelView, fields
from trytond.wizard import Wizard, StateTransition, StateView, Button from trytond.wizard import Wizard, StateTransition, StateView, Button
from trytond.transaction import Transaction
from trytond.i18n import gettext from trytond.i18n import gettext
from trytond.pyson import Eval, Bool from trytond.pyson import Eval, Bool
from trytond.report import Report from trytond.report import Report
from decimal import Decimal
class ImportQifWizardStart(ModelView): class ImportQifWizardStart(ModelView):
'Import QIF-File' 'Import QIF-File'
__name__ = 'cashbook_dataexchange.qif_imp_wiz.start' __name__ = 'cashbook_dataexchange.qif_imp_wiz.start'
company = fields.Many2One(model_name='company.company', company = fields.Many2One(
model_name='company.company',
string="Company", required=True, string="Company", required=True,
states={'invisible': True}) states={'invisible': True})
book = fields.Many2One(string='Cashbook', readonly=True, book = fields.Many2One(
string='Cashbook', readonly=True,
model_name='cashbook.book', model_name='cashbook.book',
states={ states={
'invisible': ~Bool(Eval('book')), 'invisible': ~Bool(Eval('book'))})
}) file_ = fields.Binary(
file_ = fields.Binary(string="QIF-File", required=True, string="QIF-File", required=True,
help='Quicken Interchange Format') help='Quicken Interchange Format')
@classmethod @classmethod
@ -40,15 +40,15 @@ class ImportQifWizardInfo(ModelView):
'Import QIF-File' 'Import QIF-File'
__name__ = 'cashbook_dataexchange.qif_imp_wiz.info' __name__ = 'cashbook_dataexchange.qif_imp_wiz.info'
company = fields.Many2One(model_name='company.company', company = fields.Many2One(
string="Company", required=True, model_name='company.company', string="Company",
states={'invisible': True}) required=True, states={'invisible': True})
book = fields.Many2One(string='Cash Book', readonly=True, book = fields.Many2One(
model_name='cashbook.book', string='Cash Book', readonly=True, model_name='cashbook.book',
states={ states={
'invisible': ~Bool(Eval('book')), 'invisible': ~Bool(Eval('book'))})
}) allowimport = fields.Boolean(
allowimport = fields.Boolean(string='Import Enabled', string='Import Enabled',
states={'invisible': True}) states={'invisible': True})
info = fields.Text(string='Information', readonly=True) info = fields.Text(string='Information', readonly=True)
@ -60,21 +60,23 @@ class ImportQifWizard(Wizard):
__name__ = 'cashbook_dataexchange.qif_imp_wiz' __name__ = 'cashbook_dataexchange.qif_imp_wiz'
start_state = 'start' start_state = 'start'
start = StateView(model_name='cashbook_dataexchange.qif_imp_wiz.start', \ start = StateView(
view='cashbook_dataexchange.qif_imp_wiz_start_form', \ model_name='cashbook_dataexchange.qif_imp_wiz.start',
view='cashbook_dataexchange.qif_imp_wiz_start_form',
buttons=[ buttons=[
Button(string='Cancel', state='end', icon='tryton-cancel'), Button(string='Cancel', state='end', icon='tryton-cancel'),
Button(string='Read File', state='readf', icon='tryton-forward', default=True), Button(
]) string='Read File', state='readf',
showinfo = StateView(model_name='cashbook_dataexchange.qif_imp_wiz.info', \ icon='tryton-forward', default=True)])
view='cashbook_dataexchange.qif_imp_wiz_info_form', \ showinfo = StateView(
model_name='cashbook_dataexchange.qif_imp_wiz.info',
view='cashbook_dataexchange.qif_imp_wiz_info_form',
buttons=[ buttons=[
Button(string='Cancel', state='end', icon='tryton-cancel'), Button(string='Cancel', state='end', icon='tryton-cancel'),
Button(string='Import Data', state='importf', icon='tryton-import', default=True, Button(
states={ string='Import Data', state='importf',
'readonly': Eval('allowimport', False) == False, icon='tryton-import', default=True,
}), states={'readonly': ~Eval('allowimport', False)})])
])
readf = StateTransition() readf = StateTransition()
importf = StateTransition() importf = StateTransition()
@ -86,8 +88,7 @@ class ImportQifWizard(Wizard):
values = { values = {
'company': Transaction().context.get('company'), 'company': Transaction().context.get('company'),
'book': None, 'book': None}
}
model = context.get('active_model', '') model = context.get('active_model', '')
if model == 'cashbook.book': if model == 'cashbook.book':
@ -146,7 +147,8 @@ class ImportQifWizard(Wizard):
# read file content, extract categories # read file content, extract categories
qif_content = QifTool.split_by_type(file_content) qif_content = QifTool.split_by_type(file_content)
if 'Cat' in qif_content.keys(): if 'Cat' in qif_content.keys():
to_create = QifTool.convert_categories_to_create(QifTool.qif_read_categories(qif_content['Cat'])) to_create = QifTool.convert_categories_to_create(
QifTool.qif_read_categories(qif_content['Cat']))
in_categories = [] in_categories = []
out_categories = [] out_categories = []
@ -156,43 +158,44 @@ class ImportQifWizard(Wizard):
self.showinfo.info = gettext( self.showinfo.info = gettext(
'cashbook_dataexchange.msg_wiz_categories_found', 'cashbook_dataexchange.msg_wiz_categories_found',
categories = '\n'.join( categories='\n'.join(
[''] + [''] +
['%s (in)' % x for x in in_categories]+ ['%s (in)' % x for x in in_categories] +
[''] + [''] +
['%s (out)' % x for x in out_categories] ['%s (out)' % x for x in out_categories]
) ))
)
if len(to_create) > 0: if len(to_create) > 0:
self.showinfo.allowimport = True self.showinfo.allowimport = True
else : else:
self.showinfo.info = gettext('cashbook_dataexchange.msg_wiz_no_categories') self.showinfo.info = gettext(
'cashbook_dataexchange.msg_wiz_no_categories')
elif model == 'party.party': elif model == 'party.party':
# read file content, extract parties # read file content, extract parties
qif_content = QifTool.split_by_type(file_content) qif_content = QifTool.split_by_type(file_content)
if 'Bank' in qif_content.keys(): if 'Bank' in qif_content.keys():
to_create = QifTool.convert_parties_to_create( to_create = QifTool.convert_parties_to_create(
QifTool.qif_read_transactions(qif_content['Bank']) QifTool.qif_read_transactions(qif_content['Bank']))
)
self.showinfo.info = gettext( self.showinfo.info = gettext(
'cashbook_dataexchange.msg_wiz_parties_found', 'cashbook_dataexchange.msg_wiz_parties_found',
numparties = len(to_create), numparties=len(to_create),
) + '\n\n' + '\n'.join([x['name'] for x in to_create]) ) + '\n\n' + '\n'.join([x['name'] for x in to_create])
if len(to_create) > 0: if len(to_create) > 0:
self.showinfo.allowimport = True self.showinfo.allowimport = True
else : else:
self.showinfo.info = gettext('cashbook_dataexchange.msg_wiz_no_bank') self.showinfo.info = gettext(
'cashbook_dataexchange.msg_wiz_no_bank')
elif model == 'cashbook.book': elif model == 'cashbook.book':
info_lst = [] info_lst = []
# read file content, extract categories # read file content, extract categories
qif_content = QifTool.split_by_type(file_content) qif_content = QifTool.split_by_type(file_content)
if 'Bank' in qif_content.keys(): if 'Bank' in qif_content.keys():
(to_create, msg_list, fail_cnt) = QifTool.convert_transactions_to_create( (to_create, msg_list, fail_cnt) = \
QifTool.convert_transactions_to_create(
self.start.book, self.start.book,
QifTool.qif_read_transactions(qif_content['Bank']) QifTool.qif_read_transactions(qif_content['Bank']))
)
if len(msg_list) > 0: if len(msg_list) > 0:
info_lst.append(gettext('cashbook_dataexchange.msg_wiz_transactions_error')) info_lst.append(gettext(
'cashbook_dataexchange.msg_wiz_transactions_error'))
info_lst.append('') info_lst.append('')
short_lst = [] short_lst = []
@ -204,22 +207,29 @@ class ImportQifWizard(Wizard):
# count # count
if fail_cnt == 0: if fail_cnt == 0:
debit = sum([x['amount'] for x in to_create if x['bookingtype'] in ['out', 'mvout', 'spout']]) debit = sum([
credit = sum([x['amount'] for x in to_create if x['bookingtype'] in ['in', 'mvin', 'spin']]) x['amount'] for x in to_create
if x['bookingtype'] in ['out', 'mvout', 'spout']])
credit = sum([
x['amount'] for x in to_create
if x['bookingtype'] in ['in', 'mvin', 'spin']])
balance = credit - debit balance = credit - debit
if len(msg_list) > 0: if len(msg_list) > 0:
msg_list.append('') msg_list.append('')
info_lst.append(gettext( info_lst.append(gettext(
'cashbook_dataexchange.msg_wiz_transactions_found', 'cashbook_dataexchange.msg_wiz_transactions_found',
quantity = len(to_create), quantity=len(to_create),
balance = Report.format_currency(balance, None, self.start.book.currency), balance=Report.format_currency(
credit = Report.format_currency(credit, None, self.start.book.currency), balance, None, self.start.book.currency),
debit = Report.format_currency(debit, None, self.start.book.currency), credit=Report.format_currency(
)) credit, None, self.start.book.currency),
debit=Report.format_currency(
debit, None, self.start.book.currency)))
self.showinfo.allowimport = True self.showinfo.allowimport = True
else : else:
info_lst.append(gettext('cashbook_dataexchange.msg_wiz_no_bank')) info_lst.append(gettext(
'cashbook_dataexchange.msg_wiz_no_bank'))
self.showinfo.info = '\n'.join(info_lst) self.showinfo.info = '\n'.join(info_lst)
return 'showinfo' return 'showinfo'
@ -241,14 +251,13 @@ class ImportQifWizard(Wizard):
if model == 'cashbook.category': if model == 'cashbook.category':
if file_content: if file_content:
records = Category.create_from_qif(file_content) Category.create_from_qif(file_content)
elif model == 'cashbook.book': elif model == 'cashbook.book':
if file_content: if file_content:
Book.create_from_qif(self.showinfo.book, file_content) Book.create_from_qif(self.showinfo.book, file_content)
lines = Line.search([ lines = Line.search([
('cashbook.id', '=', self.showinfo.book.id), ('cashbook.id', '=', self.showinfo.book.id),
('state', '=', 'edit'), ('state', '=', 'edit')])
])
if len(lines) > 0: if len(lines) > 0:
Line.wfcheck(lines) Line.wfcheck(lines)
elif model == 'party.party': elif model == 'party.party':
@ -261,4 +270,3 @@ class ImportQifWizard(Wizard):
return 'end' return 'end'
# end ImportQifWizard # end ImportQifWizard

View file

@ -26,11 +26,11 @@ class QifTool(Model):
for line in lines: for line in lines:
if line.startswith('!Type:'): if line.startswith('!Type:'):
current_type = line[len('!Type:'):].strip() current_type = line[len('!Type:'):].strip()
else : else:
if current_type is None: if current_type is None:
continue continue
if not current_type in blocks.keys(): if current_type not in blocks.keys():
blocks[current_type] = [] blocks[current_type] = []
blocks[current_type].append(line.strip()) blocks[current_type].append(line.strip())
@ -82,7 +82,8 @@ class QifTool(Model):
for line in booktxt.strip().split('\n'): for line in booktxt.strip().split('\n'):
line_txt = line[1:].strip() line_txt = line[1:].strip()
if line.startswith('D'): # date if line.startswith('D'): # date
booking['date'] = datetime.strptime(line_txt, '%d.%m.%Y').date() booking['date'] = datetime.strptime(
line_txt, '%d.%m.%Y').date()
elif line.startswith('T'): # total elif line.startswith('T'): # total
booking['amount'] = cls.get_amount_from_txt(line_txt) booking['amount'] = cls.get_amount_from_txt(line_txt)
elif line.startswith('U'): # total elif line.startswith('U'): # total
@ -103,24 +104,26 @@ class QifTool(Model):
elif line.startswith('L'): # category, account elif line.startswith('L'): # category, account
if line_txt.startswith('[') and line_txt.endswith(']'): if line_txt.startswith('[') and line_txt.endswith(']'):
booking['account'] = line_txt[1:-1] booking['account'] = line_txt[1:-1]
else : else:
booking['category'] = line_txt booking['category'] = line_txt
elif line.startswith('S'): # split: category, account elif line.startswith('S'): # split: category, account
if line_txt.startswith('[') and line_txt.endswith(']'): if line_txt.startswith('[') and line_txt.endswith(']'):
booking['split'].append({ booking['split'].append({
'account': line_txt[1:-1], 'account': line_txt[1:-1],
}) })
else : else:
booking['split'].append({ booking['split'].append({
'category': line_txt, 'category': line_txt,
}) })
elif line.startswith('E'): # split: memo elif line.startswith('E'): # split: memo
booking['split'][-1]['description'] = line_txt booking['split'][-1]['description'] = line_txt
elif line.startswith('$'): # split: amount elif line.startswith('$'): # split: amount
booking['split'][-1]['amount'] = cls.get_amount_from_txt(line_txt) booking['split'][-1]['amount'] = \
cls.get_amount_from_txt(line_txt)
elif line.startswith('£'): # split: amount elif line.startswith('£'): # split: amount
booking['split'][-1]['amount'] = cls.get_amount_from_txt(line_txt) booking['split'][-1]['amount'] = \
else : cls.get_amount_from_txt(line_txt)
else:
raise ValueError('unknown line-code: %s' % (line)) raise ValueError('unknown line-code: %s' % (line))
result.append(booking) result.append(booking)
return result return result
@ -138,7 +141,7 @@ class QifTool(Model):
return amount return amount
elif line.bookingtype in ['out', 'spout', 'mvout']: elif line.bookingtype in ['out', 'spout', 'mvout']:
return amount * Decimal('-1.0') return amount * Decimal('-1.0')
else : else:
raise ValueError('invalid bookingtype: %s' % line.bookingtype) raise ValueError('invalid bookingtype: %s' % line.bookingtype)
for line in book.lines: for line in book.lines:
@ -148,7 +151,10 @@ class QifTool(Model):
}) })
# total # total
result.append('T%(total)s' % { result.append('T%(total)s' % {
'total': Report.format_number(get_amount_by_bookingstate(line.amount, line), None), 'total': Report.format_number(
get_amount_by_bookingstate(line.amount, line),
None,
digits=book.currency.digits),
}) })
# state # state
result.append('C%(state)s' % { result.append('C%(state)s' % {
@ -164,8 +170,8 @@ class QifTool(Model):
if p_address: if p_address:
if len(p_address.full_address.strip()) > 0: if len(p_address.full_address.strip()) > 0:
result.append('A%(address)s' % { result.append('A%(address)s' % {
'address': p_address.full_address.replace('\n', ', ').strip(), 'address': p_address.full_address.replace(
}) '\n', ', ').strip()})
# category # category
if line.category: if line.category:
result.append('L%(category)s' % { result.append('L%(category)s' % {
@ -192,7 +198,10 @@ class QifTool(Model):
'memo': splitline.description.replace('\n', '; ') 'memo': splitline.description.replace('\n', '; ')
}) })
result.append('$%(total)s' % { result.append('$%(total)s' % {
'total': Report.format_number(get_amount_by_bookingstate(splitline.amount, line), None), 'total': Report.format_number(
get_amount_by_bookingstate(splitline.amount, line),
None,
digits=book.currency.digits),
}) })
result.append('^') result.append('^')
return '\n'.join(result) return '\n'.join(result)
@ -210,17 +219,15 @@ class QifTool(Model):
if len(parties) == 0: if len(parties) == 0:
msg_txt = gettext( msg_txt = gettext(
'cashbook_dataexchange.mds_import_party_notfound', 'cashbook_dataexchange.mds_import_party_notfound',
pname = partyname, pname=partyname)
)
elif len(parties) == 1: elif len(parties) == 1:
party_id = parties[0].id party_id = parties[0].id
else : else:
party_id = parties[0].id party_id = parties[0].id
msg_txt = gettext( msg_txt = gettext(
'cashbook_dataexchange.mds_import_many_parties_found', 'cashbook_dataexchange.mds_import_many_parties_found',
pname = partyname, pname=partyname,
pname2 = parties[0].rec_name, pname2=parties[0].rec_name)
)
return (party_id, msg_txt) return (party_id, msg_txt)
@classmethod @classmethod
@ -241,13 +248,13 @@ class QifTool(Model):
elif len(books) == 0: elif len(books) == 0:
msg_txt = gettext( msg_txt = gettext(
'cashbook_dataexchange.mds_import_book_notfound', 'cashbook_dataexchange.mds_import_book_notfound',
bookname = account_name, bookname=account_name,
) )
else : else:
msg_txt = gettext( msg_txt = gettext(
'cashbook_dataexchange.mds_import_many_books_found', 'cashbook_dataexchange.mds_import_many_books_found',
bookname1 = account_name, bookname1=account_name,
bookname2 = books[0].rec_name, bookname2=books[0].rec_name,
) )
book_obj = books[0] book_obj = books[0]
return (book_obj, msg_txt) return (book_obj, msg_txt)
@ -269,13 +276,13 @@ class QifTool(Model):
elif len(categories) == 0: elif len(categories) == 0:
msg_txt = gettext( msg_txt = gettext(
'cashbook_dataexchange.mds_import_category_notfound', 'cashbook_dataexchange.mds_import_category_notfound',
catname = catname, catname=catname,
) )
else : else:
msg_txt = gettext( msg_txt = gettext(
'cashbook_dataexchange.mds_import_many_categories_found', 'cashbook_dataexchange.mds_import_many_categories_found',
catname1 = catname, catname1=catname,
catname2 = '%(name)s [%(type)s]' % { catname2='%(name)s [%(type)s]' % {
'name': categories[0].rec_name, 'name': categories[0].rec_name,
'type': categories[0].cattype, 'type': categories[0].cattype,
}, },
@ -294,13 +301,13 @@ class QifTool(Model):
""" """
result = [] result = []
for catname in catdict.keys(): for catname in catdict.keys():
if do_search == True: if do_search is True:
c_lst = Category.search([ c_lst = Category.search([
('cattype', '=', ctype), ('cattype', '=', ctype),
('name', '=', catname), ('name', '=', catname),
('parent', '=', None) if parent is None else ('parent.id', '=', parent.id), ('parent', '=', None)
]) if parent is None else ('parent.id', '=', parent.id)])
else : else:
c_lst = [] c_lst = []
if len(c_lst) == 0: if len(c_lst) == 0:
@ -312,13 +319,15 @@ class QifTool(Model):
cat1['parent'] = parent.id cat1['parent'] = parent.id
if len(catdict[catname]['childs']) > 0: if len(catdict[catname]['childs']) > 0:
childs = get_create(ctype, catdict[catname]['childs'], None, False) childs = get_create(
ctype, catdict[catname]['childs'], None, False)
if len(childs) > 0: if len(childs) > 0:
cat1['childs'] = [('create', childs)] cat1['childs'] = [('create', childs)]
result.append(cat1) result.append(cat1)
else : else:
if len(catdict[catname]['childs']) > 0: if len(catdict[catname]['childs']) > 0:
result.extend(get_create(ctype, catdict[catname]['childs'], c_lst[0], True)) result.extend(get_create(
ctype, catdict[catname]['childs'], c_lst[0], True))
return result return result
to_create = [] to_create = []
for typ1 in ['in', 'out']: for typ1 in ['in', 'out']:
@ -343,8 +352,7 @@ class QifTool(Model):
if Party.search_count([ if Party.search_count([
('rec_name', 'ilike', '%%%(pname)s%%' % { ('rec_name', 'ilike', '%%%(pname)s%%' % {
'pname': transaction['party'], 'pname': transaction['party'],
}) })]) == 0:
]) == 0:
to_create.append({ to_create.append({
'name': transaction['party'], 'name': transaction['party'],
'addresses': [('create', [{ 'addresses': [('create', [{
@ -361,15 +369,15 @@ class QifTool(Model):
Line = Pool().get('cashbook.line') Line = Pool().get('cashbook.line')
if Line.search_count([ if Line.search_count([
('cashbook.id', '=', book.id), ('cashbook.id', '=', book.id),
('booktransf.id', '=', line['booktransf']), ('booktransf.id', '=', line['booktransf']),
('date', '=', line['date']), ('date', '=', line['date']),
#('description', '=', line['description']), # ('description', '=', line['description']),
('amount', '=', line['amount']), ('amount', '=', line['amount']),
('bookingtype', '=', line['bookingtype']), ('bookingtype', '=', line['bookingtype']),
]) > 0: ]) > 0:
return True return True
else : else:
return False return False
@classmethod @classmethod
@ -382,7 +390,8 @@ class QifTool(Model):
fail_cnt = 0 fail_cnt = 0
category = account = None category = account = None
if cat_name is not None: if cat_name is not None:
(category, msg_txt) = cls.get_category_by_name(book.company, cat_name) (category, msg_txt) = cls.get_category_by_name(
book.company, cat_name)
if category is None: if category is None:
msg_list.append(msg_txt) msg_list.append(msg_txt)
fail_cnt += 1 fail_cnt += 1
@ -394,7 +403,8 @@ class QifTool(Model):
return (category, account, msg_list, fail_cnt) return (category, account, msg_list, fail_cnt)
@classmethod @classmethod
def convert_transactions_to_create(cls, book, transactions, split2edit=True): def convert_transactions_to_create(
cls, book, transactions, split2edit=True):
""" convert read transactions to create-command """ convert read transactions to create-command
split2edit: True = split-bookings are 'edit', False = dont change split2edit: True = split-bookings are 'edit', False = dont change
""" """
@ -409,14 +419,16 @@ class QifTool(Model):
msg_list = [] msg_list = []
fail_cnt = 0 fail_cnt = 0
for transaction in transactions: for transaction in transactions:
line = {x:transaction[x] for x in [ line = {
'date', 'amount', 'description', 'state', x: transaction[x]
] if x in transaction.keys()} for x in ['date', 'amount', 'description', 'state']
if x in transaction.keys()}
if 'description' in line.keys(): if 'description' in line.keys():
line['description'] = updt_description(line['description']) line['description'] = updt_description(line['description'])
(category, account, msg_lst2, fail_cnt2) = cls.get_category_account(book, transaction) (category, account, msg_lst2, fail_cnt2) = \
cls.get_category_account(book, transaction)
msg_list.extend(msg_lst2) msg_list.extend(msg_lst2)
if fail_cnt2 > 0: if fail_cnt2 > 0:
fail_cnt += fail_cnt2 fail_cnt += fail_cnt2
@ -441,7 +453,7 @@ class QifTool(Model):
if line['amount'] < Decimal('0.0'): if line['amount'] < Decimal('0.0'):
line['bookingtype'] = 'mvout' line['bookingtype'] = 'mvout'
line['amount'] = line['amount'].copy_negate() line['amount'] = line['amount'].copy_negate()
else : else:
line['bookingtype'] = 'mvin' line['bookingtype'] = 'mvin'
line['booktransf'] = account.id line['booktransf'] = account.id
@ -452,34 +464,36 @@ class QifTool(Model):
del transaction['party'] del transaction['party']
line['description'] = '; '.join(descr_lst) line['description'] = '; '.join(descr_lst)
line['state'] = 'edit' line['state'] = 'edit'
if cls.check_counter_transaction(book, line) == True: if cls.check_counter_transaction(book, line) is True:
# counter-transaction already exists # counter-transaction already exists
continue continue
else : else:
# transaction: no category, no account - ignore? # transaction: no category, no account - ignore?
if line.get('amount', Decimal('0.0')) == Decimal('0.0'): if line.get('amount', Decimal('0.0')) == Decimal('0.0'):
# no amount --> ignore! # no amount --> ignore!
tr_info = {'trdate': '-', 'amount':'-'} tr_info = {'trdate': '-', 'amount': '-'}
if 'date' in transaction.keys(): if 'date' in transaction.keys():
tr_info['trdate'] = Report.format_date(transaction['date'], None) tr_info['trdate'] = Report.format_date(
transaction['date'], None)
if 'amount' in transaction.keys(): if 'amount' in transaction.keys():
tr_info['amount'] = Report.format_currency( tr_info['amount'] = Report.format_currency(
transaction['amount'], transaction['amount'],
None, None,
book.currency) book.currency)
tr_info['descr'] = transaction.get('description', '-') tr_info['descr'] = transaction.get('description', '-')
msg_list.append(gettext( msg_list.append(gettext(
'cashbook_dataexchange.msg_ignore_null_booking', 'cashbook_dataexchange.msg_ignore_null_booking',
trinfo = '%(trdate)s, %(amount)s, %(descr)s' % tr_info, trinfo='%(trdate)s, %(amount)s, %(descr)s' % tr_info,
)) ))
continue continue
# party # party
if 'party' in transaction.keys(): if 'party' in transaction.keys():
(party_id, msg_txt) = cls.get_party_by_name(transaction['party']) (party_id, msg_txt) = cls.get_party_by_name(
transaction['party'])
if party_id is not None: if party_id is not None:
line['party'] = party_id line['party'] = party_id
else : else:
fail_cnt += 1 fail_cnt += 1
if msg_txt is not None: if msg_txt is not None:
msg_list.append(msg_txt) msg_list.append(msg_txt)
@ -496,28 +510,34 @@ class QifTool(Model):
split_lines = [] split_lines = []
for sp_line in transaction['split']: for sp_line in transaction['split']:
(category, account, msg_lst2, fail_cnt2) = cls.get_category_account(book, sp_line) (category, account, msg_lst2, fail_cnt2) = \
cls.get_category_account(book, sp_line)
msg_list.extend(msg_lst2) msg_list.extend(msg_lst2)
if fail_cnt2 > 0: if fail_cnt2 > 0:
fail_cnt += fail_cnt2 fail_cnt += fail_cnt2
continue continue
split_line = { split_line = {
'amount': sp_line['amount'] \ 'amount': sp_line['amount']
if line['bookingtype'].endswith('in') else sp_line['amount'].copy_negate(), if line['bookingtype'].endswith('in')
'description': updt_description(sp_line.get('description', None)), else sp_line['amount'].copy_negate(),
'description': updt_description(
sp_line.get('description', None)),
} }
if category: if category:
# category match to bookingtype? # category match to bookingtype?
if ((category.cattype == 'in') and line['bookingtype'].endswith('out')) or\ if ((category.cattype == 'in') and
((category.cattype == 'out') and line['bookingtype'].endswith('in')): line['bookingtype'].endswith('out')) or \
((category.cattype == 'out') and
line['bookingtype'].endswith('in')):
msg_list.append(gettext( msg_list.append(gettext(
'cashbook_dataexchange.mds_import_category_not_match', 'cashbook_dataexchange.' +
catname = '%s [%s]' % (category.rec_name, category.cattype), 'mds_import_category_not_match',
bktype = line['bookingtype'], catname='%s [%s]' % (
data = str(transaction), category.rec_name, category.cattype),
)) bktype=line['bookingtype'],
data=str(transaction)))
fail_cnt += 1 fail_cnt += 1
continue continue
split_line['splittype'] = 'cat' split_line['splittype'] = 'cat'
@ -525,7 +545,7 @@ class QifTool(Model):
elif account: elif account:
split_line['splittype'] = 'tr' split_line['splittype'] = 'tr'
split_line['booktransf'] = account.id split_line['booktransf'] = account.id
else : else:
continue continue
split_lines.append(split_line) split_lines.append(split_line)
@ -533,7 +553,7 @@ class QifTool(Model):
if len(split_lines) > 0: if len(split_lines) > 0:
line['splitlines'] = [('create', split_lines)] line['splitlines'] = [('create', split_lines)]
if split2edit == True: if split2edit is True:
if 'splitlines' in line.keys(): if 'splitlines' in line.keys():
line['state'] = 'edit' line['state'] = 'edit'
@ -542,13 +562,13 @@ class QifTool(Model):
if line.get('category', None) is None: if line.get('category', None) is None:
msg_list.append(gettext( msg_list.append(gettext(
'cashbook_dataexchange.mds_import_no_category', 'cashbook_dataexchange.mds_import_no_category',
trdata = str(transaction))) trdata=str(transaction)))
fail_cnt += 1 fail_cnt += 1
elif line['bookingtype'] in ['mvin', 'mvout']: elif line['bookingtype'] in ['mvin', 'mvout']:
if line.get('booktransf', None) is None: if line.get('booktransf', None) is None:
msg_list.append(gettext( msg_list.append(gettext(
'cashbook_dataexchange.mds_import_no_account', 'cashbook_dataexchange.mds_import_no_account',
trdata = str(transaction))) trdata=str(transaction)))
fail_cnt += 1 fail_cnt += 1
to_create.append(line) to_create.append(line)
@ -593,9 +613,10 @@ class QifTool(Model):
cattype = 'out' cattype = 'out'
elif line.startswith('I'): elif line.startswith('I'):
cattype = 'in' cattype = 'in'
else : else:
raise ValueError('invalid line: %s (%s)' % (line, cattxt)) raise ValueError('invalid line: %s (%s)' % (line, cattxt))
categories[cattype] = add_category(categories[cattype], catname, cattype) categories[cattype] = add_category(
categories[cattype], catname, cattype)
return categories return categories
@classmethod @classmethod

View file

@ -2,7 +2,7 @@
""" """
# Always prefer setuptools over distutils # Always prefer setuptools over distutils
from setuptools import setup, find_packages from setuptools import setup
# To use a consistent encoding # To use a consistent encoding
from codecs import open from codecs import open
from os import path from os import path
@ -36,10 +36,10 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f:
l2 = i.strip().split(';') l2 = i.strip().split(';')
if len(l2) < 4: if len(l2) < 4:
continue continue
modversion[l2[0]] = {'min':l2[1], 'max':l2[2], 'prefix':l2[3]} modversion[l2[0]] = {'min': l2[1], 'max': l2[2], 'prefix': l2[3]}
# tryton-version # tryton-version
major_version = 6 major_version = 7
minor_version = 0 minor_version = 0
requires = ['python-slugify'] requires = ['python-slugify']
@ -51,56 +51,59 @@ for dep in info.get('depends', []):
prefix = modversion[dep]['prefix'] prefix = modversion[dep]['prefix']
if len(modversion[dep]['max']) > 0: if len(modversion[dep]['max']) > 0:
requires.append('%s_%s >= %s, <= %s' % requires.append('%s_%s >= %s, <= %s' % (
(prefix, dep, modversion[dep]['min'], modversion[dep]['max'])) prefix, dep, modversion[dep]['min'],
else : modversion[dep]['max']))
requires.append('%s_%s >= %s' % else:
(prefix, dep, modversion[dep]['min'])) requires.append('%s_%s >= %s' % (
else : prefix, dep, modversion[dep]['min']))
requires.append('%s_%s >= %s.%s, < %s.%s' % else:
('trytond', dep, major_version, minor_version, requires.append('%s_%s >= %s.%s, < %s.%s' % (
'trytond', dep, major_version, minor_version,
major_version, minor_version + 1)) major_version, minor_version + 1))
requires.append('trytond >= %s.%s, < %s.%s' % requires.append('trytond >= %s.%s, < %s.%s' % (
(major_version, minor_version, major_version, minor_version + 1)) major_version, minor_version, major_version, minor_version + 1))
setup(name='%s_%s' % (PREFIX, MODULE), setup(
name='%s_%s' % (PREFIX, MODULE),
version=info.get('version', '0.0.1'), version=info.get('version', '0.0.1'),
description='Tryton module to add import/export to cashbook.', description='Tryton module to add import/export to cashbook.',
long_description=long_description, long_description=long_description,
long_description_content_type='text/x-rst',
url='https://www.m-ds.de/', url='https://www.m-ds.de/',
download_url='https://scmdev.m-ds.de/Tryton/Extra/cashbook_dataexchange',
author='martin-data services', author='martin-data services',
author_email='service@m-ds.de', author_email='service@m-ds.de',
license='GPL-3', license='GPL-3',
classifiers=[ classifiers=[
'Development Status :: 5 - Production/Stable', 'Development Status :: 5 - Production/Stable',
'Environment :: Plugins', 'Environment :: Plugins',
'Framework :: Tryton', 'Framework :: Tryton',
'Intended Audience :: Developers', 'Intended Audience :: Developers',
'Intended Audience :: Customer Service', 'Intended Audience :: Customer Service',
'Intended Audience :: Information Technology', 'Intended Audience :: Information Technology',
'Intended Audience :: Financial and Insurance Industry', 'Intended Audience :: Financial and Insurance Industry',
'Topic :: Office/Business', 'Topic :: Office/Business',
'Topic :: Office/Business :: Financial :: Accounting', 'Topic :: Office/Business :: Financial :: Accounting',
'Natural Language :: German', 'Natural Language :: German',
'Natural Language :: English', 'Natural Language :: English',
'Operating System :: OS Independent', 'Operating System :: OS Independent',
'License :: OSI Approved :: GNU General Public License (GPL)', 'License :: OSI Approved :: GNU General Public License (GPL)',
'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
], ],
keywords='tryton cashbook import export', keywords='tryton cashbook import export',
package_dir={'trytond.modules.%s' % MODULE: '.'}, package_dir={'trytond.modules.%s' % MODULE: '.'},
packages=[ packages=[
'trytond.modules.%s' % MODULE, 'trytond.modules.%s' % MODULE,
], ],
package_data={ package_data={
'trytond.modules.%s' % MODULE: (info.get('xml', []) 'trytond.modules.%s' % MODULE: (info.get('xml', []) + [
+ ['tryton.cfg', 'locale/*.po', 'tests/*.py', 'tryton.cfg', 'locale/*.po', 'tests/*.py',
'report/*.fods', 'view/*.xml', 'report/*.fods', 'view/*.xml',
'versiondep.txt', 'README.rst']), 'versiondep.txt', 'README.rst']),
}, },
install_requires=requires, install_requires=requires,
zip_safe=False, zip_safe=False,
entry_points=""" entry_points="""

View file

@ -1,27 +1,4 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of # -*- coding: utf-8 -*-
# this repository contains the full copyright notices and license terms. # 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
import trytond.tests.test_tryton # full copyright notices and license terms.
import unittest
from trytond.modules.cashbook_dataexchange.tests.test_category import CategoryTestCase
from trytond.modules.cashbook_dataexchange.tests.test_party import PartyTestCase
from trytond.modules.cashbook_dataexchange.tests.test_transaction import TransactionTestCase
__all__ = ['suite']
class CashbookExchangeTestCase(\
CategoryTestCase,\
PartyTestCase,\
TransactionTestCase,\
):
'Test cashbook exchange module'
module = 'cashbook_dataexchange'
# end CashbookExchangeTestCase
def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(CashbookExchangeTestCase))
return suite

View file

@ -5,14 +5,13 @@
from datetime import date from datetime import date
from decimal import Decimal from decimal import Decimal
from trytond.tests.test_tryton import ModuleTestCase, with_transaction from trytond.tests.test_tryton import with_transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.transaction import Transaction from trytond.transaction import Transaction
from trytond.modules.cashbook.tests import CashbookTestCase from .qifdata import qif_types
from .qifdata import qif_category, qif_types
class CategoryTestCase(CashbookTestCase): class CategoryTestCase(object):
'Test cashbook categoy module' 'Test cashbook categoy module'
module = 'cashbook_dataexchange' module = 'cashbook_dataexchange'
@ -22,13 +21,13 @@ class CategoryTestCase(CashbookTestCase):
""" """
pool = Pool() pool = Pool()
Category = pool.get('cashbook.category') Category = pool.get('cashbook.category')
ImportWiz = pool.get('cashbook_dataexchange.qif_imp_wiz', type='wizard') ImportWiz = pool.get(
'cashbook_dataexchange.qif_imp_wiz', type='wizard')
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id,
'active_model': 'cashbook.category', 'active_model': 'cashbook.category'}):
}):
(sess_id, start_state, end_state) = ImportWiz.create() (sess_id, start_state, end_state) = ImportWiz.create()
w_obj = ImportWiz(sess_id) w_obj = ImportWiz(sess_id)
self.assertEqual(start_state, 'start') self.assertEqual(start_state, 'start')
@ -49,8 +48,9 @@ class CategoryTestCase(CashbookTestCase):
self.assertEqual(list(result.keys()), ['view']) self.assertEqual(list(result.keys()), ['view'])
self.assertEqual(result['view']['defaults']['company'], company.id) self.assertEqual(result['view']['defaults']['company'], company.id)
self.assertEqual(result['view']['defaults']['info'], self.assertEqual(
"""The following categories are now imported:\n result['view']['defaults']['info'],
"""The following categories are now imported:\n
Gehalt (in) Gehalt (in)
Gehalt/Zulagen (in) Gehalt/Zulagen (in)
@ -88,10 +88,14 @@ Lebensmittel (out)""")
self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy') self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy')
self.assertEqual(records[9].rec_name, 'Telefon/Telco3') self.assertEqual(records[9].rec_name, 'Telefon/Telco3')
self.assertEqual(records[10].rec_name, 'Telekommunikation') self.assertEqual(records[10].rec_name, 'Telekommunikation')
self.assertEqual(records[11].rec_name, 'Telekommunikation/Fernsehen') self.assertEqual(
self.assertEqual(records[12].rec_name, 'Telekommunikation/Online-Dienste') records[11].rec_name, 'Telekommunikation/Fernsehen')
self.assertEqual(records[13].rec_name, 'Telekommunikation/Telefon') self.assertEqual(
self.assertEqual(records[14].rec_name, 'Telekommunikation/Telefon/Test1') records[12].rec_name, 'Telekommunikation/Online-Dienste')
self.assertEqual(
records[13].rec_name, 'Telekommunikation/Telefon')
self.assertEqual(
records[14].rec_name, 'Telekommunikation/Telefon/Test1')
@with_transaction() @with_transaction()
def test_category_create_by_qif_emptydb(self): def test_category_create_by_qif_emptydb(self):
@ -102,8 +106,7 @@ Lebensmittel (out)""")
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id}):
}):
records = Category.create_from_qif(qif_types) records = Category.create_from_qif(qif_types)
records = Category.search([], order=[('rec_name', 'ASC')]) records = Category.search([], order=[('rec_name', 'ASC')])
@ -120,10 +123,14 @@ Lebensmittel (out)""")
self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy') self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy')
self.assertEqual(records[9].rec_name, 'Telefon/Telco3') self.assertEqual(records[9].rec_name, 'Telefon/Telco3')
self.assertEqual(records[10].rec_name, 'Telekommunikation') self.assertEqual(records[10].rec_name, 'Telekommunikation')
self.assertEqual(records[11].rec_name, 'Telekommunikation/Fernsehen') self.assertEqual(
self.assertEqual(records[12].rec_name, 'Telekommunikation/Online-Dienste') records[11].rec_name, 'Telekommunikation/Fernsehen')
self.assertEqual(records[13].rec_name, 'Telekommunikation/Telefon') self.assertEqual(
self.assertEqual(records[14].rec_name, 'Telekommunikation/Telefon/Test1') records[12].rec_name, 'Telekommunikation/Online-Dienste')
self.assertEqual(
records[13].rec_name, 'Telekommunikation/Telefon')
self.assertEqual(
records[14].rec_name, 'Telekommunikation/Telefon/Test1')
result = Category.export_as_qif() result = Category.export_as_qif()
self.assertEqual(result, """!Type:Cat self.assertEqual(result, """!Type:Cat
@ -183,8 +190,7 @@ I
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id}):
}):
cat1, = Category.create([{ cat1, = Category.create([{
'name': 'Telekommunikation', 'name': 'Telekommunikation',
'cattype': 'out', 'cattype': 'out',
@ -199,7 +205,7 @@ I
self.assertEqual(records[0].rec_name, 'Telekommunikation') self.assertEqual(records[0].rec_name, 'Telekommunikation')
self.assertEqual(records[1].rec_name, 'Telekommunikation/Telefon') self.assertEqual(records[1].rec_name, 'Telekommunikation/Telefon')
records1 = Category.create_from_qif(qif_types) Category.create_from_qif(qif_types)
records = Category.search([], order=[('rec_name', 'ASC')]) records = Category.search([], order=[('rec_name', 'ASC')])
self.assertEqual(len(records), 15) self.assertEqual(len(records), 15)
@ -215,10 +221,14 @@ I
self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy') self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy')
self.assertEqual(records[9].rec_name, 'Telefon/Telco3') self.assertEqual(records[9].rec_name, 'Telefon/Telco3')
self.assertEqual(records[10].rec_name, 'Telekommunikation') self.assertEqual(records[10].rec_name, 'Telekommunikation')
self.assertEqual(records[11].rec_name, 'Telekommunikation/Fernsehen') self.assertEqual(
self.assertEqual(records[12].rec_name, 'Telekommunikation/Online-Dienste') records[11].rec_name, 'Telekommunikation/Fernsehen')
self.assertEqual(records[13].rec_name, 'Telekommunikation/Telefon') self.assertEqual(
self.assertEqual(records[14].rec_name, 'Telekommunikation/Telefon/Test1') records[12].rec_name, 'Telekommunikation/Online-Dienste')
self.assertEqual(
records[13].rec_name, 'Telekommunikation/Telefon')
self.assertEqual(
records[14].rec_name, 'Telekommunikation/Telefon/Test1')
@with_transaction() @with_transaction()
def test_qiftool_split_types(self): def test_qiftool_split_types(self):
@ -228,18 +238,25 @@ I
result = QifTool.split_by_type(qif_types) result = QifTool.split_by_type(qif_types)
self.assertEqual(len(result.keys()), 2) self.assertEqual(len(result.keys()), 2)
self.assertEqual(result['Cat'], 'NGehalt\nI\n^\nNGehalt:Zulagen\n'+ self.assertEqual(
'I\n^\nNTelekommunikation\nE\n^\nNTelekommunikation:Online-Dienste\n'+ result['Cat'],
'E\n^\nNTelekommunikation:Telefon\nE\n^\nNTelekommunikation:Telefon:Test1\n'+ 'NGehalt\nI\n^\nNGehalt:Zulagen\nI\n^\nNTelekommunikation' +
'E\n^\nNTelefon:Telco1-Tablett\n'+ '\nE\n^\nNTelekommunikation:Online-Dienste\n' +
'E\n^\nNTelefon:Telco2-Handy\nE\n^\nNTelefon:Telco3\nE\n^\n'+ 'E\n^\nNTelekommunikation:Telefon\nE\n^\nN' +
'NTelekommunikation:Fernsehen\nE\n^\nNFernsehen:TV-Company\nE\n'+ 'Telekommunikation:Telefon:Test1\n' +
'E\n^\nNTelefon:Telco1-Tablett\n' +
'E\n^\nNTelefon:Telco2-Handy\nE\n^\nNTelefon:Telco3\nE\n^\n' +
'NTelekommunikation:Fernsehen\nE\n^\nNFernsehen:TV-Company\nE\n' +
'^\nNFernsehen:GEZ\nE\n^\nNLebensmittel\nE\n^') '^\nNFernsehen:GEZ\nE\n^\nNLebensmittel\nE\n^')
self.assertEqual(result['Bank'], 'D04.12.2013\nT7,12\nCX\nPOpening Balance\n'+ self.assertEqual(
'L[Bargeld]\n^\nD05.12.2013\nCX\nM05.12/06.42UHR TT TELTOW\nT-29,00\n'+ result['Bank'],
'PGA NR00002168 BLZ10000000 0\nL[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\n'+ 'D04.12.2013\nT7,12\nCX\n' +
'T-56,37\nPFoodshop Zehlendorf\nLLebensmittel\n^\nD06.12.2013\nCX\n'+ 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\nM05.12/' +
'Mreturn of bottles\nT1,45\nPFoodshop Zehlendorf\nLLebensmittel\n^\n') '06.42UHR TT TELTOW\nT-29,00\n' +
'PGA NR00002168 BLZ10000000 0\nL[S-Giro]\n^\nD05.12.2013' +
'\nCX\nMsome food\nT-56,37\nPFoodshop Zehlendorf\n' +
'LLebensmittel\n^\nD06.12.2013\nCX\nMreturn of bottles\n' +
'T1,45\nPFoodshop Zehlendorf\nLLebensmittel\n^\n')
@with_transaction() @with_transaction()
def test_qiftool_convert_transactions(self): def test_qiftool_convert_transactions(self):
@ -253,8 +270,7 @@ I
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id}):
}):
types = self.prep_type() types = self.prep_type()
books = Book.create([{ books = Book.create([{
'name': 'Cash Book', 'name': 'Cash Book',
@ -263,7 +279,6 @@ I
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}, { }, {
'name': 'S-Giro', 'name': 'S-Giro',
'btype': types.id, 'btype': types.id,
@ -271,7 +286,6 @@ I
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}, { }, {
'name': 'Bargeld', 'name': 'Bargeld',
'btype': types.id, 'btype': types.id,
@ -279,7 +293,6 @@ I
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}]) }])
self.assertEqual(books[0].name, 'Cash Book') self.assertEqual(books[0].name, 'Cash Book')
self.assertEqual(books[1].name, 'S-Giro') self.assertEqual(books[1].name, 'S-Giro')
@ -316,17 +329,21 @@ I
'company': company.id, 'company': company.id,
}]) }])
tr_list = QifTool.qif_read_transactions('D04.12.2013\nT7,12\nCX\n'+ tr_list = QifTool.qif_read_transactions(
'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n'+ 'D04.12.2013\nT7,12\nCX\n' +
'M05.12/06.42UHR TT TELTOW\nT-29,00\nPGA NR00002168 BLZ10000000 0\n'+ 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n' +
'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\n'+ 'M05.12/06.42UHR TT TELTOW\nT-29,00\nPGA NR00002168 ' +
'PFoodshop Zehlendorf\nLLebensmittel\n^\nD22.10.2020\n'+ 'BLZ10000000 0\n' +
'CX\nMLebensmittel\nT-55,84\nPreal,- Teltow\nLLebensmittel\n'+ 'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\n' +
'SLebensmittel\nELebensmittel\n$-49,36\nSKosmetik\nEKlopapier\n'+ 'PFoodshop Zehlendorf\nLLebensmittel\n^\nD22.10.2020\n' +
'$-2,99\nSHaushaltschemie\nESagrotan\n$-3,49\n'+ 'CX\nMLebensmittel\nT-55,84\nPreal,- Teltow\nLLebensmittel\n' +
'SLebensmittel\nELebensmittel\n$-49,36\nSKosmetik\n' +
'EKlopapier\n' +
'$-2,99\nSHaushaltschemie\nESagrotan\n$-3,49\n' +
'S[S-Giro]\nEtransfer out\n$-3,49\n^\n') 'S[S-Giro]\nEtransfer out\n$-3,49\n^\n')
(to_create, msg_txt, fail_cnt) = QifTool.convert_transactions_to_create(books[0], tr_list) (to_create, msg_txt, fail_cnt) = \
QifTool.convert_transactions_to_create(books[0], tr_list)
self.assertEqual(msg_txt, []) self.assertEqual(msg_txt, [])
self.assertEqual(to_create, [{ self.assertEqual(to_create, [{
'date': date(2013, 12, 4), 'date': date(2013, 12, 4),
@ -338,11 +355,12 @@ I
}, { }, {
'date': date(2013, 12, 5), 'date': date(2013, 12, 5),
'amount': Decimal('29.00'), 'amount': Decimal('29.00'),
'description': '05.12/06.42UHR TT TELTOW',
'state': 'edit', 'state': 'edit',
'bookingtype': 'mvout', 'bookingtype': 'mvout',
'booktransf': books[1].id, 'booktransf': books[1].id,
'description': 'GA NR00002168 BLZ10000000 0; 05.12/06.42UHR TT TELTOW', 'description':
'GA NR00002168 BLZ10000000 0; 05.12/06.42UHR ' +
'TT TELTOW',
}, { }, {
'date': date(2013, 12, 5), 'date': date(2013, 12, 5),
'amount': Decimal('56.37'), 'amount': Decimal('56.37'),
@ -380,8 +398,7 @@ I
'amount': Decimal('3.49'), 'amount': Decimal('3.49'),
'description': 'transfer out', 'description': 'transfer out',
'booktransf': books[1].id, 'booktransf': books[1].id,
}], }])],
)],
}]) }])
Book.write(*[ Book.write(*[
[books[0]], [books[0]],
@ -397,13 +414,15 @@ I
""" """
QifTool = Pool().get('cashbook_dataexchange.qiftool') QifTool = Pool().get('cashbook_dataexchange.qiftool')
result = QifTool.qif_read_transactions('D04.12.2013\nT7,12\nCX\n'+ result = QifTool.qif_read_transactions(
'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n'+ 'D04.12.2013\nT7,12\nCX\n' +
'M05.12/06.42UHR TT TELTOW\nT290,00\nPGA NR00002168 BLZ10000000 0\n'+ 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n' +
'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\n'+ 'M05.12/06.42UHR TT TELTOW\nT290,00\nPGA ' +
'PFoodshop Zehlendorf\nLLebensmittel\n^\nD22.10.2020\n'+ 'NR00002168 BLZ10000000 0\n' +
'CX\nMLebensmittel\nT-55,84\nPreal,- Teltow\nLLebensmittel\n'+ 'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\n' +
'SLebensmittel\nELebensmittel\n$-49,36\nSKosmetik\nEKlopapier\n'+ 'PFoodshop Zehlendorf\nLLebensmittel\n^\nD22.10.2020\n' +
'CX\nMLebensmittel\nT-55,84\nPreal,- Teltow\nLLebensmittel\n' +
'SLebensmittel\nELebensmittel\n$-49,36\nSKosmetik\nEKlopapier\n' +
'$-2,99\nSHaushaltschemie\nESagrotan\n$-3,49\n^\n') '$-2,99\nSHaushaltschemie\nESagrotan\n$-3,49\n^\n')
self.assertEqual(result, [{ self.assertEqual(result, [{
'split': [], 'split': [],
@ -456,8 +475,10 @@ I
""" """
QifTool = Pool().get('cashbook_dataexchange.qiftool') QifTool = Pool().get('cashbook_dataexchange.qiftool')
result = QifTool.qif_read_categories('NGehalt\nI\n^\nNGehalt:Zulagen\nI\n^'+ result = QifTool.qif_read_categories(
'NTelekommunikation\nE\n^\nNTelekommunikation:Online-Dienste\nE\n^') 'NGehalt\nI\n^\nNGehalt:Zulagen\nI\n^' +
'NTelekommunikation\nE\n^\nNTelekommunikation:' +
'Online-Dienste\nE\n^')
self.assertEqual(result, { self.assertEqual(result, {
'in': { 'in': {
'Gehalt': { 'Gehalt': {

View file

@ -3,15 +3,13 @@
# The COPYRIGHT file at the top level of this repository contains the # The COPYRIGHT file at the top level of this repository contains the
# full copyright notices and license terms. # full copyright notices and license terms.
from datetime import date from trytond.tests.test_tryton import with_transaction
from decimal import Decimal
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.transaction import Transaction from trytond.transaction import Transaction
from .qifdata import qif_types from .qifdata import qif_types
class PartyTestCase(ModuleTestCase): class PartyTestCase(object):
'Test cashbook party module' 'Test cashbook party module'
module = 'cashbook_dataexchange' module = 'cashbook_dataexchange'
@ -21,13 +19,13 @@ class PartyTestCase(ModuleTestCase):
""" """
pool = Pool() pool = Pool()
Party = pool.get('party.party') Party = pool.get('party.party')
ImportWiz = pool.get('cashbook_dataexchange.qif_imp_wiz', type='wizard') ImportWiz = pool.get(
'cashbook_dataexchange.qif_imp_wiz', type='wizard')
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id,
'active_model': 'party.party', 'active_model': 'party.party'}):
}):
(sess_id, start_state, end_state) = ImportWiz.create() (sess_id, start_state, end_state) = ImportWiz.create()
w_obj = ImportWiz(sess_id) w_obj = ImportWiz(sess_id)
self.assertEqual(start_state, 'start') self.assertEqual(start_state, 'start')
@ -48,8 +46,9 @@ class PartyTestCase(ModuleTestCase):
self.assertEqual(list(result.keys()), ['view']) self.assertEqual(list(result.keys()), ['view'])
self.assertEqual(result['view']['defaults']['company'], company.id) self.assertEqual(result['view']['defaults']['company'], company.id)
self.assertEqual(result['view']['defaults']['info'], self.assertEqual(
"""The following 3 parties are now imported:\n result['view']['defaults']['info'],
"""The following 3 parties are now imported:\n
Opening Balance Opening Balance
GA NR00002168 BLZ10000000 0 GA NR00002168 BLZ10000000 0
Foodshop Zehlendorf""") Foodshop Zehlendorf""")
@ -64,7 +63,8 @@ Foodshop Zehlendorf""")
self.assertEqual(len(records), 4) self.assertEqual(len(records), 4)
self.assertEqual(records[0].rec_name, 'Foodshop Zehlendorf') self.assertEqual(records[0].rec_name, 'Foodshop Zehlendorf')
self.assertEqual(records[1].rec_name, 'GA NR00002168 BLZ10000000 0') self.assertEqual(
records[1].rec_name, 'GA NR00002168 BLZ10000000 0')
self.assertEqual(records[2].rec_name, 'm-ds') self.assertEqual(records[2].rec_name, 'm-ds')
self.assertEqual(records[3].rec_name, 'Opening Balance') self.assertEqual(records[3].rec_name, 'Opening Balance')

24
tests/test_module.py Normal file
View file

@ -0,0 +1,24 @@
# -*- 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.
from trytond.modules.cashbook.tests.test_module import CashbookTestCase
from .category import CategoryTestCase
from .party import PartyTestCase
from .transaction import TransactionTestCase
class CashbookExchangeTestCase(
CashbookTestCase,
CategoryTestCase,
PartyTestCase,
TransactionTestCase):
'Test cashbook exchange module'
module = 'cashbook_dataexchange'
# end CashbookExchangeTestCase
del CashbookTestCase

View file

@ -5,13 +5,13 @@
from datetime import date from datetime import date
from decimal import Decimal from decimal import Decimal
from trytond.tests.test_tryton import ModuleTestCase, with_transaction from trytond.tests.test_tryton import with_transaction
from trytond.pool import Pool from trytond.pool import Pool
from trytond.transaction import Transaction from trytond.transaction import Transaction
from .qifdata import qif_types from .qifdata import qif_types
class TransactionTestCase(ModuleTestCase): class TransactionTestCase(object):
'Test cashbook transaction module' 'Test cashbook transaction module'
module = 'cashbook_dataexchange' module = 'cashbook_dataexchange'
@ -26,8 +26,7 @@ class TransactionTestCase(ModuleTestCase):
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id}):
}):
types = self.prep_type() types = self.prep_type()
books = Book.create([{ books = Book.create([{
'name': 'Cash Book', 'name': 'Cash Book',
@ -36,7 +35,6 @@ class TransactionTestCase(ModuleTestCase):
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}, { }, {
'name': 'S-Giro', 'name': 'S-Giro',
'btype': types.id, 'btype': types.id,
@ -44,7 +42,6 @@ class TransactionTestCase(ModuleTestCase):
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}]) }])
Book.write(*[ Book.write(*[
@ -52,21 +49,24 @@ class TransactionTestCase(ModuleTestCase):
{ {
'lines': [('create', [{ 'lines': [('create', [{
'date': date(2022, 6, 1), 'date': date(2022, 6, 1),
'bookingtype':'mvout', 'bookingtype': 'mvout',
'amount': Decimal('10.0'), 'amount': Decimal('10.0'),
'booktransf': books[1].id, 'booktransf': books[1].id,
'description': 'transfer', 'description': 'transfer',
}])], }])],
}]) }])
self.assertEqual(len(books[0].lines), 1) self.assertEqual(len(books[0].lines), 1)
self.assertEqual(books[0].lines[0].rec_name, self.assertEqual(
books[0].lines[0].rec_name,
'06/01/2022|to|-10.00 usd|transfer [S-Giro | 0.00 usd | Open]') '06/01/2022|to|-10.00 usd|transfer [S-Giro | 0.00 usd | Open]')
self.assertEqual(len(books[1].lines), 0) self.assertEqual(len(books[1].lines), 0)
Line.wfcheck(books[0].lines) Line.wfcheck(books[0].lines)
self.assertEqual(len(books[1].lines), 1) self.assertEqual(len(books[1].lines), 1)
self.assertEqual(books[1].lines[0].rec_name, self.assertEqual(
'06/01/2022|from|10.00 usd|transfer [Cash Book | -10.00 usd | Open]') books[1].lines[0].rec_name,
'06/01/2022|from|10.00 usd|transfer [Cash Book ' +
'| -10.00 usd | Open]')
self.assertEqual(QifTool.check_counter_transaction(books[1], { self.assertEqual(QifTool.check_counter_transaction(books[1], {
'booktransf': books[0].id, 'booktransf': books[0].id,
@ -84,13 +84,13 @@ class TransactionTestCase(ModuleTestCase):
Party = pool.get('party.party') Party = pool.get('party.party')
Category = pool.get('cashbook.category') Category = pool.get('cashbook.category')
Book = pool.get('cashbook.book') Book = pool.get('cashbook.book')
ImportWiz = pool.get('cashbook_dataexchange.qif_imp_wiz', type='wizard') ImportWiz = pool.get(
'cashbook_dataexchange.qif_imp_wiz', type='wizard')
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id,
'active_model': 'cashbook.book', 'active_model': 'cashbook.book'}):
}):
types = self.prep_type() types = self.prep_type()
books = Book.create([{ books = Book.create([{
'name': 'Cash Book', 'name': 'Cash Book',
@ -99,7 +99,6 @@ class TransactionTestCase(ModuleTestCase):
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}, { }, {
'name': 'S-Giro', 'name': 'S-Giro',
'btype': types.id, 'btype': types.id,
@ -107,7 +106,6 @@ class TransactionTestCase(ModuleTestCase):
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}, { }, {
'name': 'Bargeld', 'name': 'Bargeld',
'btype': types.id, 'btype': types.id,
@ -115,18 +113,17 @@ class TransactionTestCase(ModuleTestCase):
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}]) }])
Party.create([{ Party.create([{
'name': 'GA NR00002168 BLZ10000000 0', 'name': 'GA NR00002168 BLZ10000000 0',
'addresses':[('create', [{}])], 'addresses': [('create', [{}])],
}, { }, {
'name': 'Foodshop Zehlendorf', 'name': 'Foodshop Zehlendorf',
'addresses':[('create', [{}])], 'addresses': [('create', [{}])],
}, { }, {
'name': 'Opening Balance', 'name': 'Opening Balance',
'addresses':[('create', [{}])], 'addresses': [('create', [{}])],
}]) }])
Category.create([{ Category.create([{
@ -156,8 +153,9 @@ class TransactionTestCase(ModuleTestCase):
self.assertEqual(list(result.keys()), ['view']) self.assertEqual(list(result.keys()), ['view'])
self.assertEqual(result['view']['defaults']['company'], company.id) self.assertEqual(result['view']['defaults']['company'], company.id)
self.assertEqual(result['view']['defaults']['info'], self.assertEqual(
"""The following transactionen are now imported: result['view']['defaults']['info'],
"""The following transactionen are now imported:
Credit: usd7.12 Credit: usd7.12
Debit: usd83.92 Debit: usd83.92
Balance: -usd76.80 Balance: -usd76.80
@ -174,10 +172,20 @@ Number of transactions: 4""")
self.assertEqual(len(books[0].lines), 4) self.assertEqual(len(books[0].lines), 4)
self.assertEqual(books[0].lines[0].rec_name, '12/04/2013|from|7.12 usd|Opening Balance [Bargeld | -7.12 usd | Open]') self.assertEqual(
self.assertEqual(books[0].lines[1].rec_name, '12/05/2013|to|-29.00 usd|GA NR00002168 BLZ10000000 0; 05.12/06.42 [S-Giro | 29.00 usd | Open]') books[0].lines[0].rec_name,
self.assertEqual(books[0].lines[2].rec_name, '12/05/2013|Exp|-56.37 usd|some food [Lebensmittel]') '12/04/2013|from|7.12 usd|Opening Balance ' +
self.assertEqual(books[0].lines[3].rec_name, '12/06/2013|Exp|1.45 usd|return of bottles [Lebensmittel]') '[Bargeld | -7.12 usd | Open]')
self.assertEqual(
books[0].lines[1].rec_name,
'12/05/2013|to|-29.00 usd|GA NR00002168 BLZ10000000 ' +
'0; 05.12/06.42 [S-Giro | 29.00 usd | Open]')
self.assertEqual(
books[0].lines[2].rec_name,
'12/05/2013|Exp|-56.37 usd|some food [Lebensmittel]')
self.assertEqual(
books[0].lines[3].rec_name,
'12/06/2013|Exp|1.45 usd|return of bottles [Lebensmittel]')
self.assertEqual(Book.export_as_qif(books[0]), """!Type:Bank self.assertEqual(Book.export_as_qif(books[0]), """!Type:Bank
D12/04/2013 D12/04/2013
@ -216,13 +224,13 @@ Mreturn of bottles
Party = pool.get('party.party') Party = pool.get('party.party')
Category = pool.get('cashbook.category') Category = pool.get('cashbook.category')
Book = pool.get('cashbook.book') Book = pool.get('cashbook.book')
ImportWiz = pool.get('cashbook_dataexchange.qif_imp_wiz', type='wizard') ImportWiz = pool.get(
'cashbook_dataexchange.qif_imp_wiz', type='wizard')
company = self.prep_company() company = self.prep_company()
with Transaction().set_context({ with Transaction().set_context({
'company': company.id, 'company': company.id,
'active_model': 'cashbook.book', 'active_model': 'cashbook.book'}):
}):
types = self.prep_type() types = self.prep_type()
books = Book.create([{ books = Book.create([{
'name': 'From Book', 'name': 'From Book',
@ -231,7 +239,6 @@ Mreturn of bottles
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}, { }, {
'name': 'To Book', 'name': 'To Book',
'btype': types.id, 'btype': types.id,
@ -239,12 +246,11 @@ Mreturn of bottles
'currency': company.currency.id, 'currency': company.currency.id,
'number_sequ': self.prep_sequence().id, 'number_sequ': self.prep_sequence().id,
'start_date': date(2010, 1, 1), 'start_date': date(2010, 1, 1),
'start_balance': Decimal('0.0'),
}]) }])
Party.create([{ Party.create([{
'name': 'Foodshop Zehlendorf', 'name': 'Foodshop Zehlendorf',
'addresses':[('create', [{}])], 'addresses': [('create', [{}])],
}]) }])
Category.create([{ Category.create([{
@ -290,8 +296,9 @@ L[To Book]
self.assertEqual(list(result.keys()), ['view']) self.assertEqual(list(result.keys()), ['view'])
self.assertEqual(result['view']['defaults']['company'], company.id) self.assertEqual(result['view']['defaults']['company'], company.id)
self.assertEqual(result['view']['defaults']['info'], self.assertEqual(
"""The following transactionen are now imported: result['view']['defaults']['info'],
"""The following transactionen are now imported:
Credit: usd0.00 Credit: usd0.00
Debit: usd57.55 Debit: usd57.55
Balance: -usd57.55 Balance: -usd57.55
@ -309,11 +316,19 @@ Number of transactions: 2""")
self.assertEqual(len(books[0].lines), 2) self.assertEqual(len(books[0].lines), 2)
self.assertEqual(len(books[1].lines), 1) self.assertEqual(len(books[1].lines), 1)
self.assertEqual(books[0].lines[0].rec_name, '12/04/2013|to|-7.30 usd|Transfer to book [To Book | 7.30 usd | Open]') self.assertEqual(
books[0].lines[0].rec_name,
'12/04/2013|to|-7.30 usd|Transfer to book ' +
'[To Book | 7.30 usd | Open]')
self.assertEqual(books[0].lines[0].state, 'check') self.assertEqual(books[0].lines[0].state, 'check')
self.assertEqual(books[0].lines[1].rec_name, '12/05/2013|Exp|-50.25 usd|some food [Lebensmittel]') self.assertEqual(
books[0].lines[1].rec_name,
'12/05/2013|Exp|-50.25 usd|some food [Lebensmittel]')
self.assertEqual(books[0].lines[1].state, 'check') self.assertEqual(books[0].lines[1].state, 'check')
self.assertEqual(books[1].lines[0].rec_name, '12/04/2013|from|7.30 usd|Transfer to book [From Book | -57.55 usd | Open]') self.assertEqual(
books[1].lines[0].rec_name,
'12/04/2013|from|7.30 usd|Transfer to book ' +
'[From Book | -57.55 usd | Open]')
self.assertEqual(books[1].lines[0].state, 'check') self.assertEqual(books[1].lines[0].state, 'check')
# run wizard again - import to 'To Book' # run wizard again - import to 'To Book'
@ -366,8 +381,9 @@ $-7,00
self.assertEqual(list(result.keys()), ['view']) self.assertEqual(list(result.keys()), ['view'])
self.assertEqual(result['view']['defaults']['company'], company.id) self.assertEqual(result['view']['defaults']['company'], company.id)
self.assertEqual(result['view']['defaults']['info'], self.assertEqual(
"""The following transactionen are now imported: result['view']['defaults']['info'],
"""The following transactionen are now imported:
Credit: usd0.00 Credit: usd0.00
Debit: usd20.00 Debit: usd20.00
Balance: -usd20.00 Balance: -usd20.00
@ -385,18 +401,37 @@ Number of transactions: 2""")
self.assertEqual(len(books[0].lines), 3) self.assertEqual(len(books[0].lines), 3)
self.assertEqual(len(books[1].lines), 3) self.assertEqual(len(books[1].lines), 3)
self.assertEqual(books[0].lines[0].rec_name, '12/04/2013|to|-7.30 usd|Transfer to book [To Book | -12.70 usd | Open]') self.assertEqual(
self.assertEqual(books[0].lines[0].state, 'check') books[0].lines[0].rec_name,
self.assertEqual(books[0].lines[1].rec_name, '12/05/2013|Exp|-50.25 usd|some food [Lebensmittel]') '12/04/2013|to|-7.30 usd|Transfer to book ' +
self.assertEqual(books[0].lines[1].state, 'check') '[To Book | -12.70 usd | Open]')
self.assertEqual(books[0].lines[2].rec_name, '12/06/2013|from|7.00 usd|Transfer to From-Book [To Book | -12.70 usd | Open]') self.assertEqual(
self.assertEqual(books[0].lines[2].state, 'check') books[0].lines[0].state, 'check')
self.assertEqual(
books[0].lines[1].rec_name,
'12/05/2013|Exp|-50.25 usd|some food [Lebensmittel]')
self.assertEqual(
books[0].lines[1].state, 'check')
self.assertEqual(
books[0].lines[2].rec_name,
'12/06/2013|from|7.00 usd|Transfer to From-Book ' +
'[To Book | -12.70 usd | Open]')
self.assertEqual(
books[0].lines[2].state, 'check')
self.assertEqual(books[1].lines[0].rec_name, '12/04/2013|from|7.30 usd|Transfer to book [From Book | -50.55 usd | Open]') self.assertEqual(
books[1].lines[0].rec_name,
'12/04/2013|from|7.30 usd|Transfer to book [From Book ' +
'| -50.55 usd | Open]')
self.assertEqual(books[1].lines[0].state, 'check') self.assertEqual(books[1].lines[0].state, 'check')
self.assertEqual(books[1].lines[1].rec_name, '12/06/2013|Exp/Sp|-10.00 usd|Splitbooking with category and account [-]') self.assertEqual(
books[1].lines[1].rec_name,
'12/06/2013|Exp/Sp|-10.00 usd|Splitbooking with category' +
' and account [-]')
self.assertEqual(books[1].lines[1].state, 'check') self.assertEqual(books[1].lines[1].state, 'check')
self.assertEqual(books[1].lines[2].rec_name, '12/10/2013|Exp|-10.00 usd|some food [Lebensmittel]') self.assertEqual(
books[1].lines[2].rec_name,
'12/10/2013|Exp|-10.00 usd|some food [Lebensmittel]')
self.assertEqual(books[1].lines[2].state, 'check') self.assertEqual(books[1].lines[2].state, 'check')
# end PartyTestCase # end PartyTestCase

View file

@ -1,5 +1,5 @@
[tryton] [tryton]
version=6.0.3 version=7.0.0
depends: depends:
cashbook cashbook
xml: xml:

View file

@ -1 +1 @@
cashbook;6.0.10;6.0.999;mds cashbook;7.0.31;7.0.999;mds