diff --git a/README.rst b/README.rst index 64a022f..f9ed603 100644 --- a/README.rst +++ b/README.rst @@ -9,25 +9,11 @@ pip install mds-cashbook-dataexchange Requires ======== -- Tryton 6.0 +- Tryton 7.0 Changes ======= -*6.0.3 - 13.09.2022* +*7.0.0 - 01.12.2023* -- add: import of split-bookings -- 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 +- compatibility to Tryton 7.0 diff --git a/__init__.py b/__init__.py index ca56a2a..eca81a7 100644 --- a/__init__.py +++ b/__init__.py @@ -7,9 +7,11 @@ from trytond.pool import Pool from .category import Category from .book import Book 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 + def register(): Pool.register( QifTool, diff --git a/book.py b/book.py index c1c9036..392877e 100644 --- a/book.py +++ b/book.py @@ -3,7 +3,6 @@ # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. -from trytond.transaction import Transaction from trytond.pool import Pool, PoolMeta @@ -28,13 +27,13 @@ class Book(metaclass=PoolMeta): Book2 = pool.get('cashbook.book') qif_content = QifTool.split_by_type(qifdata) - if not 'Bank' in qif_content.keys(): + if 'Bank' not in qif_content.keys(): 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, - QifTool.qif_read_transactions(qif_content['Bank']) - ) + QifTool.qif_read_transactions(qif_content['Bank'])) if fail_cnt == 0: Book2.write(*[ [book], diff --git a/category.py b/category.py index 0f08960..3430c44 100644 --- a/category.py +++ b/category.py @@ -3,7 +3,6 @@ # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. -from trytond.transaction import Transaction from trytond.pool import Pool, PoolMeta @@ -18,8 +17,9 @@ class Category(metaclass=PoolMeta): Category2 = pool.get('cashbook.category') QifTool = pool.get('cashbook_dataexchange.qiftool') - categories = Category2.search([], - order=[('cattype', 'ASC'), ('rec_name', 'ASC')]) + categories = Category2.search( + [], + order=[('cattype', 'ASC'), ('rec_name', 'ASC')]) export = ['!Type:Cat'] export.extend([QifTool.qif_export_category(x) for x in categories]) @@ -34,7 +34,7 @@ class Category(metaclass=PoolMeta): Category2 = pool.get('cashbook.category') type_data = QifTool.split_by_type(qifdata) - if not 'Cat' in type_data.keys(): + if 'Cat' not in type_data.keys(): return None to_create = QifTool.convert_categories_to_create( diff --git a/qif_export.py b/qif_export.py index b764cd7..c8066a6 100644 --- a/qif_export.py +++ b/qif_export.py @@ -8,7 +8,6 @@ from trytond.pool import Pool from slugify import slugify - class QifCategoryExport(Report): __name__ = 'cashbook_dataexchange.rep_category' @@ -40,7 +39,7 @@ class QifBookExport(Report): IrDate = pool.get('ir.date') 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: return ( 'qif', @@ -51,7 +50,7 @@ class QifBookExport(Report): 'book': books[0].name, }, max_length=100, word_boundary=True, save_order=True), ) - else : + else: return ( 'txt', 'not cashbook found', diff --git a/qif_import_wiz.py b/qif_import_wiz.py index a74b31f..d79f927 100644 --- a/qif_import_wiz.py +++ b/qif_import_wiz.py @@ -7,26 +7,26 @@ from trytond.transaction import Transaction 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.i18n import gettext from trytond.pyson import Eval, Bool from trytond.report import Report -from decimal import Decimal class ImportQifWizardStart(ModelView): 'Import QIF-File' __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, states={'invisible': True}) - book = fields.Many2One(string='Cashbook', readonly=True, + book = fields.Many2One( + string='Cashbook', readonly=True, model_name='cashbook.book', states={ - 'invisible': ~Bool(Eval('book')), - }) - file_ = fields.Binary(string="QIF-File", required=True, + 'invisible': ~Bool(Eval('book'))}) + file_ = fields.Binary( + string="QIF-File", required=True, help='Quicken Interchange Format') @classmethod @@ -40,15 +40,15 @@ class ImportQifWizardInfo(ModelView): 'Import QIF-File' __name__ = 'cashbook_dataexchange.qif_imp_wiz.info' - company = fields.Many2One(model_name='company.company', - string="Company", required=True, - states={'invisible': True}) - book = fields.Many2One(string='Cash Book', readonly=True, - model_name='cashbook.book', + company = fields.Many2One( + model_name='company.company', string="Company", + required=True, states={'invisible': True}) + book = fields.Many2One( + string='Cash Book', readonly=True, model_name='cashbook.book', states={ - 'invisible': ~Bool(Eval('book')), - }) - allowimport = fields.Boolean(string='Import Enabled', + 'invisible': ~Bool(Eval('book'))}) + allowimport = fields.Boolean( + string='Import Enabled', states={'invisible': True}) info = fields.Text(string='Information', readonly=True) @@ -60,21 +60,23 @@ class ImportQifWizard(Wizard): __name__ = 'cashbook_dataexchange.qif_imp_wiz' start_state = 'start' - start = StateView(model_name='cashbook_dataexchange.qif_imp_wiz.start', \ - view='cashbook_dataexchange.qif_imp_wiz_start_form', \ + start = StateView( + model_name='cashbook_dataexchange.qif_imp_wiz.start', + view='cashbook_dataexchange.qif_imp_wiz_start_form', buttons=[ Button(string='Cancel', state='end', icon='tryton-cancel'), - Button(string='Read File', state='readf', icon='tryton-forward', default=True), - ]) - showinfo = StateView(model_name='cashbook_dataexchange.qif_imp_wiz.info', \ - view='cashbook_dataexchange.qif_imp_wiz_info_form', \ + Button( + string='Read File', state='readf', + icon='tryton-forward', default=True)]) + showinfo = StateView( + model_name='cashbook_dataexchange.qif_imp_wiz.info', + view='cashbook_dataexchange.qif_imp_wiz_info_form', buttons=[ Button(string='Cancel', state='end', icon='tryton-cancel'), - Button(string='Import Data', state='importf', icon='tryton-import', default=True, - states={ - 'readonly': Eval('allowimport', False) == False, - }), - ]) + Button( + string='Import Data', state='importf', + icon='tryton-import', default=True, + states={'readonly': ~Eval('allowimport', False)})]) readf = StateTransition() importf = StateTransition() @@ -86,8 +88,7 @@ class ImportQifWizard(Wizard): values = { 'company': Transaction().context.get('company'), - 'book': None, - } + 'book': None} model = context.get('active_model', '') if model == 'cashbook.book': @@ -146,7 +147,8 @@ class ImportQifWizard(Wizard): # read file content, extract categories qif_content = QifTool.split_by_type(file_content) 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 = [] out_categories = [] @@ -156,43 +158,44 @@ class ImportQifWizard(Wizard): self.showinfo.info = gettext( '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] - ) - ) + )) if len(to_create) > 0: self.showinfo.allowimport = True - else : - self.showinfo.info = gettext('cashbook_dataexchange.msg_wiz_no_categories') + else: + self.showinfo.info = gettext( + 'cashbook_dataexchange.msg_wiz_no_categories') elif model == 'party.party': # read file content, extract parties qif_content = QifTool.split_by_type(file_content) if 'Bank' in qif_content.keys(): 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( '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]) if len(to_create) > 0: self.showinfo.allowimport = True - else : - self.showinfo.info = gettext('cashbook_dataexchange.msg_wiz_no_bank') + else: + self.showinfo.info = gettext( + 'cashbook_dataexchange.msg_wiz_no_bank') elif model == 'cashbook.book': info_lst = [] # read file content, extract categories qif_content = QifTool.split_by_type(file_content) 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, - QifTool.qif_read_transactions(qif_content['Bank']) - ) + QifTool.qif_read_transactions(qif_content['Bank'])) 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('') short_lst = [] @@ -204,22 +207,29 @@ class ImportQifWizard(Wizard): # count if fail_cnt == 0: - debit = sum([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']]) + debit = sum([ + 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 if len(msg_list) > 0: msg_list.append('') info_lst.append(gettext( 'cashbook_dataexchange.msg_wiz_transactions_found', - quantity = len(to_create), - balance = Report.format_currency(balance, 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), - )) + quantity=len(to_create), + balance=Report.format_currency( + balance, 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 - else : - info_lst.append(gettext('cashbook_dataexchange.msg_wiz_no_bank')) + else: + info_lst.append(gettext( + 'cashbook_dataexchange.msg_wiz_no_bank')) self.showinfo.info = '\n'.join(info_lst) return 'showinfo' @@ -241,14 +251,13 @@ class ImportQifWizard(Wizard): if model == 'cashbook.category': if file_content: - records = Category.create_from_qif(file_content) + Category.create_from_qif(file_content) elif model == 'cashbook.book': if file_content: Book.create_from_qif(self.showinfo.book, file_content) lines = Line.search([ ('cashbook.id', '=', self.showinfo.book.id), - ('state', '=', 'edit'), - ]) + ('state', '=', 'edit')]) if len(lines) > 0: Line.wfcheck(lines) elif model == 'party.party': @@ -261,4 +270,3 @@ class ImportQifWizard(Wizard): return 'end' # end ImportQifWizard - diff --git a/qiftool.py b/qiftool.py index 2647767..b40ca40 100644 --- a/qiftool.py +++ b/qiftool.py @@ -26,11 +26,11 @@ class QifTool(Model): for line in lines: if line.startswith('!Type:'): current_type = line[len('!Type:'):].strip() - else : + else: if current_type is None: continue - if not current_type in blocks.keys(): + if current_type not in blocks.keys(): blocks[current_type] = [] blocks[current_type].append(line.strip()) @@ -82,7 +82,8 @@ class QifTool(Model): 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() + booking['date'] = datetime.strptime( + line_txt, '%d.%m.%Y').date() elif line.startswith('T'): # total booking['amount'] = cls.get_amount_from_txt(line_txt) elif line.startswith('U'): # total @@ -103,24 +104,26 @@ class QifTool(Model): elif line.startswith('L'): # category, account if line_txt.startswith('[') and line_txt.endswith(']'): booking['account'] = line_txt[1:-1] - else : + else: booking['category'] = line_txt elif line.startswith('S'): # split: category, account if line_txt.startswith('[') and line_txt.endswith(']'): booking['split'].append({ 'account': line_txt[1:-1], }) - else : + else: 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'] = cls.get_amount_from_txt(line_txt) + booking['split'][-1]['amount'] = \ + cls.get_amount_from_txt(line_txt) elif line.startswith('£'): # split: amount - booking['split'][-1]['amount'] = cls.get_amount_from_txt(line_txt) - else : + booking['split'][-1]['amount'] = \ + cls.get_amount_from_txt(line_txt) + else: raise ValueError('unknown line-code: %s' % (line)) result.append(booking) return result @@ -138,7 +141,7 @@ class QifTool(Model): return amount elif line.bookingtype in ['out', 'spout', 'mvout']: return amount * Decimal('-1.0') - else : + else: raise ValueError('invalid bookingtype: %s' % line.bookingtype) for line in book.lines: @@ -148,7 +151,10 @@ class QifTool(Model): }) # total 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 result.append('C%(state)s' % { @@ -164,8 +170,8 @@ class QifTool(Model): if p_address: if len(p_address.full_address.strip()) > 0: result.append('A%(address)s' % { - 'address': p_address.full_address.replace('\n', ', ').strip(), - }) + 'address': p_address.full_address.replace( + '\n', ', ').strip()}) # category if line.category: result.append('L%(category)s' % { @@ -192,7 +198,10 @@ class QifTool(Model): 'memo': splitline.description.replace('\n', '; ') }) 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('^') return '\n'.join(result) @@ -210,17 +219,15 @@ class QifTool(Model): if len(parties) == 0: msg_txt = gettext( 'cashbook_dataexchange.mds_import_party_notfound', - pname = partyname, - ) + pname=partyname) elif len(parties) == 1: party_id = parties[0].id - else : + else: party_id = parties[0].id msg_txt = gettext( 'cashbook_dataexchange.mds_import_many_parties_found', - pname = partyname, - pname2 = parties[0].rec_name, - ) + pname=partyname, + pname2=parties[0].rec_name) return (party_id, msg_txt) @classmethod @@ -241,13 +248,13 @@ class QifTool(Model): elif len(books) == 0: msg_txt = gettext( 'cashbook_dataexchange.mds_import_book_notfound', - bookname = account_name, + bookname=account_name, ) - else : + else: msg_txt = gettext( 'cashbook_dataexchange.mds_import_many_books_found', - bookname1 = account_name, - bookname2 = books[0].rec_name, + bookname1=account_name, + bookname2=books[0].rec_name, ) book_obj = books[0] return (book_obj, msg_txt) @@ -269,13 +276,13 @@ class QifTool(Model): elif len(categories) == 0: msg_txt = gettext( 'cashbook_dataexchange.mds_import_category_notfound', - catname = catname, + catname=catname, ) - else : + else: msg_txt = gettext( 'cashbook_dataexchange.mds_import_many_categories_found', - catname1 = catname, - catname2 = '%(name)s [%(type)s]' % { + catname1=catname, + catname2='%(name)s [%(type)s]' % { 'name': categories[0].rec_name, 'type': categories[0].cattype, }, @@ -294,13 +301,13 @@ class QifTool(Model): """ result = [] for catname in catdict.keys(): - if do_search == True: + if do_search is True: c_lst = Category.search([ - ('cattype', '=', ctype), - ('name', '=', catname), - ('parent', '=', None) if parent is None else ('parent.id', '=', parent.id), - ]) - else : + ('cattype', '=', ctype), + ('name', '=', catname), + ('parent', '=', None) + if parent is None else ('parent.id', '=', parent.id)]) + else: c_lst = [] if len(c_lst) == 0: @@ -312,13 +319,15 @@ class QifTool(Model): cat1['parent'] = parent.id 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: cat1['childs'] = [('create', childs)] result.append(cat1) - else : + else: 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 to_create = [] for typ1 in ['in', 'out']: @@ -343,8 +352,7 @@ class QifTool(Model): if Party.search_count([ ('rec_name', 'ilike', '%%%(pname)s%%' % { 'pname': transaction['party'], - }) - ]) == 0: + })]) == 0: to_create.append({ 'name': transaction['party'], 'addresses': [('create', [{ @@ -361,15 +369,15 @@ class QifTool(Model): Line = Pool().get('cashbook.line') if Line.search_count([ - ('cashbook.id', '=', book.id), - ('booktransf.id', '=', line['booktransf']), - ('date', '=', line['date']), - #('description', '=', line['description']), - ('amount', '=', line['amount']), - ('bookingtype', '=', line['bookingtype']), - ]) > 0: + ('cashbook.id', '=', book.id), + ('booktransf.id', '=', line['booktransf']), + ('date', '=', line['date']), + # ('description', '=', line['description']), + ('amount', '=', line['amount']), + ('bookingtype', '=', line['bookingtype']), + ]) > 0: return True - else : + else: return False @classmethod @@ -382,7 +390,8 @@ class QifTool(Model): fail_cnt = 0 category = account = 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: msg_list.append(msg_txt) fail_cnt += 1 @@ -394,7 +403,8 @@ class QifTool(Model): return (category, account, msg_list, fail_cnt) @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 split2edit: True = split-bookings are 'edit', False = dont change """ @@ -409,14 +419,16 @@ class QifTool(Model): msg_list = [] fail_cnt = 0 for transaction in transactions: - line = {x:transaction[x] for x in [ - 'date', 'amount', 'description', 'state', - ] if x in transaction.keys()} + line = { + x: transaction[x] + for x in ['date', 'amount', 'description', 'state'] + if x in transaction.keys()} if 'description' in line.keys(): 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) if fail_cnt2 > 0: fail_cnt += fail_cnt2 @@ -441,7 +453,7 @@ class QifTool(Model): if line['amount'] < Decimal('0.0'): line['bookingtype'] = 'mvout' line['amount'] = line['amount'].copy_negate() - else : + else: line['bookingtype'] = 'mvin' line['booktransf'] = account.id @@ -452,34 +464,36 @@ class QifTool(Model): del transaction['party'] line['description'] = '; '.join(descr_lst) line['state'] = 'edit' - if cls.check_counter_transaction(book, line) == True: + if cls.check_counter_transaction(book, line) is True: # counter-transaction already exists continue - else : + else: # transaction: no category, no account - ignore? if line.get('amount', Decimal('0.0')) == Decimal('0.0'): # no amount --> ignore! - tr_info = {'trdate': '-', 'amount':'-'} + tr_info = {'trdate': '-', 'amount': '-'} 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(): - tr_info['amount'] = Report.format_currency( + tr_info['amount'] = Report.format_currency( transaction['amount'], None, book.currency) tr_info['descr'] = transaction.get('description', '-') msg_list.append(gettext( '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 # party 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: line['party'] = party_id - else : + else: fail_cnt += 1 if msg_txt is not None: msg_list.append(msg_txt) @@ -496,28 +510,34 @@ class QifTool(Model): split_lines = [] 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) if fail_cnt2 > 0: fail_cnt += fail_cnt2 continue split_line = { - 'amount': sp_line['amount'] \ - if line['bookingtype'].endswith('in') else sp_line['amount'].copy_negate(), - 'description': updt_description(sp_line.get('description', None)), + 'amount': sp_line['amount'] + if line['bookingtype'].endswith('in') + else sp_line['amount'].copy_negate(), + 'description': updt_description( + sp_line.get('description', None)), } if category: # category match to bookingtype? - if ((category.cattype == 'in') and line['bookingtype'].endswith('out')) or\ - ((category.cattype == 'out') and line['bookingtype'].endswith('in')): + if ((category.cattype == 'in') and + line['bookingtype'].endswith('out')) or \ + ((category.cattype == 'out') and + line['bookingtype'].endswith('in')): msg_list.append(gettext( - 'cashbook_dataexchange.mds_import_category_not_match', - catname = '%s [%s]' % (category.rec_name, category.cattype), - bktype = line['bookingtype'], - data = str(transaction), - )) + 'cashbook_dataexchange.' + + 'mds_import_category_not_match', + catname='%s [%s]' % ( + category.rec_name, category.cattype), + bktype=line['bookingtype'], + data=str(transaction))) fail_cnt += 1 continue split_line['splittype'] = 'cat' @@ -525,7 +545,7 @@ class QifTool(Model): elif account: split_line['splittype'] = 'tr' split_line['booktransf'] = account.id - else : + else: continue split_lines.append(split_line) @@ -533,7 +553,7 @@ class QifTool(Model): if len(split_lines) > 0: line['splitlines'] = [('create', split_lines)] - if split2edit == True: + if split2edit is True: if 'splitlines' in line.keys(): line['state'] = 'edit' @@ -542,13 +562,13 @@ class QifTool(Model): if line.get('category', None) is None: msg_list.append(gettext( 'cashbook_dataexchange.mds_import_no_category', - trdata = str(transaction))) + trdata=str(transaction))) fail_cnt += 1 elif line['bookingtype'] in ['mvin', 'mvout']: if line.get('booktransf', None) is None: msg_list.append(gettext( 'cashbook_dataexchange.mds_import_no_account', - trdata = str(transaction))) + trdata=str(transaction))) fail_cnt += 1 to_create.append(line) @@ -593,9 +613,10 @@ class QifTool(Model): cattype = 'out' elif line.startswith('I'): cattype = 'in' - else : + else: 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 @classmethod diff --git a/setup.py b/setup.py index acb487d..e212258 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ """ # Always prefer setuptools over distutils -from setuptools import setup, find_packages +from setuptools import setup # To use a consistent encoding from codecs import open from os import path @@ -36,10 +36,10 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f: l2 = i.strip().split(';') if len(l2) < 4: 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 -major_version = 6 +major_version = 7 minor_version = 0 requires = ['python-slugify'] @@ -51,56 +51,59 @@ for dep in info.get('depends', []): prefix = modversion[dep]['prefix'] if len(modversion[dep]['max']) > 0: - requires.append('%s_%s >= %s, <= %s' % - (prefix, dep, modversion[dep]['min'], modversion[dep]['max'])) - else : - requires.append('%s_%s >= %s' % - (prefix, dep, modversion[dep]['min'])) - else : - requires.append('%s_%s >= %s.%s, < %s.%s' % - ('trytond', dep, major_version, minor_version, + requires.append('%s_%s >= %s, <= %s' % ( + prefix, dep, modversion[dep]['min'], + modversion[dep]['max'])) + else: + requires.append('%s_%s >= %s' % ( + prefix, dep, modversion[dep]['min'])) + else: + requires.append('%s_%s >= %s.%s, < %s.%s' % ( + 'trytond', dep, major_version, minor_version, major_version, minor_version + 1)) -requires.append('trytond >= %s.%s, < %s.%s' % - (major_version, minor_version, major_version, minor_version + 1)) +requires.append('trytond >= %s.%s, < %s.%s' % ( + 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'), description='Tryton module to add import/export to cashbook.', long_description=long_description, + long_description_content_type='text/x-rst', url='https://www.m-ds.de/', + download_url='https://scmdev.m-ds.de/Tryton/Extra/cashbook_dataexchange', author='martin-data services', author_email='service@m-ds.de', license='GPL-3', classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Plugins', - 'Framework :: Tryton', - 'Intended Audience :: Developers', - 'Intended Audience :: Customer Service', - 'Intended Audience :: Information Technology', - 'Intended Audience :: Financial and Insurance Industry', - 'Topic :: Office/Business', - 'Topic :: Office/Business :: Financial :: Accounting', - 'Natural Language :: German', - 'Natural Language :: English', - 'Operating System :: OS Independent', - 'License :: OSI Approved :: GNU General Public License (GPL)', - 'Programming Language :: Python :: 3.7', - 'Programming Language :: Python :: 3.8', + 'Development Status :: 5 - Production/Stable', + 'Environment :: Plugins', + 'Framework :: Tryton', + 'Intended Audience :: Developers', + 'Intended Audience :: Customer Service', + 'Intended Audience :: Information Technology', + 'Intended Audience :: Financial and Insurance Industry', + 'Topic :: Office/Business', + 'Topic :: Office/Business :: Financial :: Accounting', + 'Natural Language :: German', + 'Natural Language :: English', + 'Operating System :: OS Independent', + 'License :: OSI Approved :: GNU General Public License (GPL)', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', ], - keywords='tryton cashbook import export', package_dir={'trytond.modules.%s' % MODULE: '.'}, packages=[ 'trytond.modules.%s' % MODULE, ], package_data={ - 'trytond.modules.%s' % MODULE: (info.get('xml', []) - + ['tryton.cfg', 'locale/*.po', 'tests/*.py', - 'report/*.fods', 'view/*.xml', - 'versiondep.txt', 'README.rst']), + 'trytond.modules.%s' % MODULE: (info.get('xml', []) + [ + 'tryton.cfg', 'locale/*.po', 'tests/*.py', + 'report/*.fods', 'view/*.xml', + 'versiondep.txt', 'README.rst']), }, - install_requires=requires, zip_safe=False, entry_points=""" diff --git a/tests/__init__.py b/tests/__init__.py index 1ee073c..cf7e957 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,27 +1,4 @@ -# This file is part of Tryton. The COPYRIGHT file at the top level of -# this repository contains the full copyright notices and license terms. - -import trytond.tests.test_tryton -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 +# -*- 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. diff --git a/tests/test_category.py b/tests/category.py similarity index 81% rename from tests/test_category.py rename to tests/category.py index 6fed058..fdbd2a6 100644 --- a/tests/test_category.py +++ b/tests/category.py @@ -5,14 +5,13 @@ from datetime import date 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.transaction import Transaction -from trytond.modules.cashbook.tests import CashbookTestCase -from .qifdata import qif_category, qif_types +from .qifdata import qif_types -class CategoryTestCase(CashbookTestCase): +class CategoryTestCase(object): 'Test cashbook categoy module' module = 'cashbook_dataexchange' @@ -22,13 +21,13 @@ class CategoryTestCase(CashbookTestCase): """ pool = Pool() 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() with Transaction().set_context({ - 'company': company.id, - 'active_model': 'cashbook.category', - }): + 'company': company.id, + 'active_model': 'cashbook.category'}): (sess_id, start_state, end_state) = ImportWiz.create() w_obj = ImportWiz(sess_id) self.assertEqual(start_state, 'start') @@ -49,8 +48,9 @@ class CategoryTestCase(CashbookTestCase): self.assertEqual(list(result.keys()), ['view']) self.assertEqual(result['view']['defaults']['company'], company.id) - self.assertEqual(result['view']['defaults']['info'], -"""The following categories are now imported:\n + self.assertEqual( + result['view']['defaults']['info'], + """The following categories are now imported:\n Gehalt (in) Gehalt/Zulagen (in) @@ -88,10 +88,14 @@ Lebensmittel (out)""") self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy') self.assertEqual(records[9].rec_name, 'Telefon/Telco3') self.assertEqual(records[10].rec_name, 'Telekommunikation') - self.assertEqual(records[11].rec_name, 'Telekommunikation/Fernsehen') - self.assertEqual(records[12].rec_name, 'Telekommunikation/Online-Dienste') - self.assertEqual(records[13].rec_name, 'Telekommunikation/Telefon') - self.assertEqual(records[14].rec_name, 'Telekommunikation/Telefon/Test1') + self.assertEqual( + records[11].rec_name, 'Telekommunikation/Fernsehen') + self.assertEqual( + 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() def test_category_create_by_qif_emptydb(self): @@ -102,8 +106,7 @@ Lebensmittel (out)""") company = self.prep_company() with Transaction().set_context({ - 'company': company.id, - }): + 'company': company.id}): records = Category.create_from_qif(qif_types) 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[9].rec_name, 'Telefon/Telco3') self.assertEqual(records[10].rec_name, 'Telekommunikation') - self.assertEqual(records[11].rec_name, 'Telekommunikation/Fernsehen') - self.assertEqual(records[12].rec_name, 'Telekommunikation/Online-Dienste') - self.assertEqual(records[13].rec_name, 'Telekommunikation/Telefon') - self.assertEqual(records[14].rec_name, 'Telekommunikation/Telefon/Test1') + self.assertEqual( + records[11].rec_name, 'Telekommunikation/Fernsehen') + self.assertEqual( + 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() self.assertEqual(result, """!Type:Cat @@ -183,8 +190,7 @@ I company = self.prep_company() with Transaction().set_context({ - 'company': company.id, - }): + 'company': company.id}): cat1, = Category.create([{ 'name': 'Telekommunikation', 'cattype': 'out', @@ -199,7 +205,7 @@ I self.assertEqual(records[0].rec_name, 'Telekommunikation') 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')]) self.assertEqual(len(records), 15) @@ -215,10 +221,14 @@ I self.assertEqual(records[8].rec_name, 'Telefon/Telco2-Handy') self.assertEqual(records[9].rec_name, 'Telefon/Telco3') self.assertEqual(records[10].rec_name, 'Telekommunikation') - self.assertEqual(records[11].rec_name, 'Telekommunikation/Fernsehen') - self.assertEqual(records[12].rec_name, 'Telekommunikation/Online-Dienste') - self.assertEqual(records[13].rec_name, 'Telekommunikation/Telefon') - self.assertEqual(records[14].rec_name, 'Telekommunikation/Telefon/Test1') + self.assertEqual( + records[11].rec_name, 'Telekommunikation/Fernsehen') + self.assertEqual( + 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() def test_qiftool_split_types(self): @@ -228,18 +238,25 @@ I result = QifTool.split_by_type(qif_types) self.assertEqual(len(result.keys()), 2) - self.assertEqual(result['Cat'], 'NGehalt\nI\n^\nNGehalt:Zulagen\n'+ - 'I\n^\nNTelekommunikation\nE\n^\nNTelekommunikation:Online-Dienste\n'+ - 'E\n^\nNTelekommunikation:Telefon\nE\n^\nNTelekommunikation: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'+ + self.assertEqual( + result['Cat'], + 'NGehalt\nI\n^\nNGehalt:Zulagen\nI\n^\nNTelekommunikation' + + '\nE\n^\nNTelekommunikation:Online-Dienste\n' + + 'E\n^\nNTelekommunikation:Telefon\nE\n^\nN' + + '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^') - self.assertEqual(result['Bank'], 'D04.12.2013\nT7,12\nCX\nPOpening Balance\n'+ - 'L[Bargeld]\n^\nD05.12.2013\nCX\nM05.12/06.42UHR TT TELTOW\nT-29,00\n'+ - 'PGA NR00002168 BLZ10000000 0\nL[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\n'+ - 'T-56,37\nPFoodshop Zehlendorf\nLLebensmittel\n^\nD06.12.2013\nCX\n'+ - 'Mreturn of bottles\nT1,45\nPFoodshop Zehlendorf\nLLebensmittel\n^\n') + self.assertEqual( + result['Bank'], + 'D04.12.2013\nT7,12\nCX\n' + + 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\nM05.12/' + + '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() def test_qiftool_convert_transactions(self): @@ -253,8 +270,7 @@ I company = self.prep_company() with Transaction().set_context({ - 'company': company.id, - }): + 'company': company.id}): types = self.prep_type() books = Book.create([{ 'name': 'Cash Book', @@ -263,7 +279,6 @@ I 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }, { 'name': 'S-Giro', 'btype': types.id, @@ -271,7 +286,6 @@ I 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }, { 'name': 'Bargeld', 'btype': types.id, @@ -279,7 +293,6 @@ I 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }]) self.assertEqual(books[0].name, 'Cash Book') self.assertEqual(books[1].name, 'S-Giro') @@ -316,17 +329,21 @@ I 'company': company.id, }]) - tr_list = QifTool.qif_read_transactions('D04.12.2013\nT7,12\nCX\n'+ - 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n'+ - 'M05.12/06.42UHR TT TELTOW\nT-29,00\nPGA NR00002168 BLZ10000000 0\n'+ - 'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\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'+ + tr_list = QifTool.qif_read_transactions( + 'D04.12.2013\nT7,12\nCX\n' + + 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n' + + 'M05.12/06.42UHR TT TELTOW\nT-29,00\nPGA NR00002168 ' + + 'BLZ10000000 0\n' + + 'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\n' + + 'PFoodshop Zehlendorf\nLLebensmittel\n^\nD22.10.2020\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') - (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(to_create, [{ 'date': date(2013, 12, 4), @@ -338,11 +355,12 @@ I }, { 'date': date(2013, 12, 5), 'amount': Decimal('29.00'), - 'description': '05.12/06.42UHR TT TELTOW', 'state': 'edit', 'bookingtype': 'mvout', '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), 'amount': Decimal('56.37'), @@ -380,8 +398,7 @@ I 'amount': Decimal('3.49'), 'description': 'transfer out', 'booktransf': books[1].id, - }], - )], + }])], }]) Book.write(*[ [books[0]], @@ -397,13 +414,15 @@ I """ QifTool = Pool().get('cashbook_dataexchange.qiftool') - result = QifTool.qif_read_transactions('D04.12.2013\nT7,12\nCX\n'+ - 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n'+ - 'M05.12/06.42UHR TT TELTOW\nT290,00\nPGA NR00002168 BLZ10000000 0\n'+ - 'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\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'+ + result = QifTool.qif_read_transactions( + 'D04.12.2013\nT7,12\nCX\n' + + 'POpening Balance\nL[Bargeld]\n^\nD05.12.2013\nCX\n' + + 'M05.12/06.42UHR TT TELTOW\nT290,00\nPGA ' + + 'NR00002168 BLZ10000000 0\n' + + 'L[S-Giro]\n^\nD05.12.2013\nCX\nMsome food\nT-56,37\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') self.assertEqual(result, [{ 'split': [], @@ -456,8 +475,10 @@ I """ QifTool = Pool().get('cashbook_dataexchange.qiftool') - result = QifTool.qif_read_categories('NGehalt\nI\n^\nNGehalt:Zulagen\nI\n^'+ - 'NTelekommunikation\nE\n^\nNTelekommunikation:Online-Dienste\nE\n^') + result = QifTool.qif_read_categories( + 'NGehalt\nI\n^\nNGehalt:Zulagen\nI\n^' + + 'NTelekommunikation\nE\n^\nNTelekommunikation:' + + 'Online-Dienste\nE\n^') self.assertEqual(result, { 'in': { 'Gehalt': { diff --git a/tests/test_party.py b/tests/party.py similarity index 79% rename from tests/test_party.py rename to tests/party.py index a315e7b..4a6f113 100644 --- a/tests/test_party.py +++ b/tests/party.py @@ -3,15 +3,13 @@ # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. -from datetime import date -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.transaction import Transaction from .qifdata import qif_types -class PartyTestCase(ModuleTestCase): +class PartyTestCase(object): 'Test cashbook party module' module = 'cashbook_dataexchange' @@ -21,13 +19,13 @@ class PartyTestCase(ModuleTestCase): """ pool = Pool() 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() with Transaction().set_context({ - 'company': company.id, - 'active_model': 'party.party', - }): + 'company': company.id, + 'active_model': 'party.party'}): (sess_id, start_state, end_state) = ImportWiz.create() w_obj = ImportWiz(sess_id) self.assertEqual(start_state, 'start') @@ -48,8 +46,9 @@ class PartyTestCase(ModuleTestCase): self.assertEqual(list(result.keys()), ['view']) self.assertEqual(result['view']['defaults']['company'], company.id) - self.assertEqual(result['view']['defaults']['info'], -"""The following 3 parties are now imported:\n + self.assertEqual( + result['view']['defaults']['info'], + """The following 3 parties are now imported:\n Opening Balance GA NR00002168 BLZ10000000 0 Foodshop Zehlendorf""") @@ -64,7 +63,8 @@ Foodshop Zehlendorf""") self.assertEqual(len(records), 4) 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[3].rec_name, 'Opening Balance') diff --git a/tests/test_module.py b/tests/test_module.py new file mode 100644 index 0000000..42fe0a0 --- /dev/null +++ b/tests/test_module.py @@ -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 diff --git a/tests/test_transaction.py b/tests/transaction.py similarity index 73% rename from tests/test_transaction.py rename to tests/transaction.py index ea4c8e0..b4448cf 100644 --- a/tests/test_transaction.py +++ b/tests/transaction.py @@ -5,13 +5,13 @@ from datetime import date 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.transaction import Transaction from .qifdata import qif_types -class TransactionTestCase(ModuleTestCase): +class TransactionTestCase(object): 'Test cashbook transaction module' module = 'cashbook_dataexchange' @@ -26,8 +26,7 @@ class TransactionTestCase(ModuleTestCase): company = self.prep_company() with Transaction().set_context({ - 'company': company.id, - }): + 'company': company.id}): types = self.prep_type() books = Book.create([{ 'name': 'Cash Book', @@ -36,7 +35,6 @@ class TransactionTestCase(ModuleTestCase): 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }, { 'name': 'S-Giro', 'btype': types.id, @@ -44,7 +42,6 @@ class TransactionTestCase(ModuleTestCase): 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }]) Book.write(*[ @@ -52,21 +49,24 @@ class TransactionTestCase(ModuleTestCase): { 'lines': [('create', [{ 'date': date(2022, 6, 1), - 'bookingtype':'mvout', + 'bookingtype': 'mvout', 'amount': Decimal('10.0'), 'booktransf': books[1].id, 'description': 'transfer', }])], }]) 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]') self.assertEqual(len(books[1].lines), 0) Line.wfcheck(books[0].lines) self.assertEqual(len(books[1].lines), 1) - self.assertEqual(books[1].lines[0].rec_name, - '06/01/2022|from|10.00 usd|transfer [Cash Book | -10.00 usd | Open]') + self.assertEqual( + 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], { 'booktransf': books[0].id, @@ -84,13 +84,13 @@ class TransactionTestCase(ModuleTestCase): Party = pool.get('party.party') Category = pool.get('cashbook.category') 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() with Transaction().set_context({ - 'company': company.id, - 'active_model': 'cashbook.book', - }): + 'company': company.id, + 'active_model': 'cashbook.book'}): types = self.prep_type() books = Book.create([{ 'name': 'Cash Book', @@ -99,7 +99,6 @@ class TransactionTestCase(ModuleTestCase): 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }, { 'name': 'S-Giro', 'btype': types.id, @@ -107,7 +106,6 @@ class TransactionTestCase(ModuleTestCase): 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }, { 'name': 'Bargeld', 'btype': types.id, @@ -115,18 +113,17 @@ class TransactionTestCase(ModuleTestCase): 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }]) Party.create([{ 'name': 'GA NR00002168 BLZ10000000 0', - 'addresses':[('create', [{}])], + 'addresses': [('create', [{}])], }, { 'name': 'Foodshop Zehlendorf', - 'addresses':[('create', [{}])], + 'addresses': [('create', [{}])], }, { 'name': 'Opening Balance', - 'addresses':[('create', [{}])], + 'addresses': [('create', [{}])], }]) Category.create([{ @@ -156,8 +153,9 @@ class TransactionTestCase(ModuleTestCase): self.assertEqual(list(result.keys()), ['view']) self.assertEqual(result['view']['defaults']['company'], company.id) - self.assertEqual(result['view']['defaults']['info'], -"""The following transactionen are now imported: + self.assertEqual( + result['view']['defaults']['info'], + """The following transactionen are now imported: Credit: usd7.12 Debit: usd83.92 Balance: -usd76.80 @@ -174,10 +172,20 @@ Number of transactions: 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(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( + books[0].lines[0].rec_name, + '12/04/2013|from|7.12 usd|Opening Balance ' + + '[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 D12/04/2013 @@ -216,13 +224,13 @@ Mreturn of bottles Party = pool.get('party.party') Category = pool.get('cashbook.category') 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() with Transaction().set_context({ - 'company': company.id, - 'active_model': 'cashbook.book', - }): + 'company': company.id, + 'active_model': 'cashbook.book'}): types = self.prep_type() books = Book.create([{ 'name': 'From Book', @@ -231,7 +239,6 @@ Mreturn of bottles 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }, { 'name': 'To Book', 'btype': types.id, @@ -239,12 +246,11 @@ Mreturn of bottles 'currency': company.currency.id, 'number_sequ': self.prep_sequence().id, 'start_date': date(2010, 1, 1), - 'start_balance': Decimal('0.0'), }]) Party.create([{ 'name': 'Foodshop Zehlendorf', - 'addresses':[('create', [{}])], + 'addresses': [('create', [{}])], }]) Category.create([{ @@ -290,8 +296,9 @@ L[To Book] self.assertEqual(list(result.keys()), ['view']) self.assertEqual(result['view']['defaults']['company'], company.id) - self.assertEqual(result['view']['defaults']['info'], -"""The following transactionen are now imported: + self.assertEqual( + result['view']['defaults']['info'], + """The following transactionen are now imported: Credit: usd0.00 Debit: usd57.55 Balance: -usd57.55 @@ -309,11 +316,19 @@ Number of transactions: 2""") self.assertEqual(len(books[0].lines), 2) 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[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[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') # run wizard again - import to 'To Book' @@ -366,8 +381,9 @@ $-7,00 self.assertEqual(list(result.keys()), ['view']) self.assertEqual(result['view']['defaults']['company'], company.id) - self.assertEqual(result['view']['defaults']['info'], -"""The following transactionen are now imported: + self.assertEqual( + result['view']['defaults']['info'], + """The following transactionen are now imported: Credit: usd0.00 Debit: usd20.00 Balance: -usd20.00 @@ -385,18 +401,37 @@ Number of transactions: 2""") self.assertEqual(len(books[0].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(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[0].lines[0].rec_name, + '12/04/2013|to|-7.30 usd|Transfer to book ' + + '[To Book | -12.70 usd | Open]') + 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].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[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[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') # end PartyTestCase diff --git a/tryton.cfg b/tryton.cfg index 780e658..c0d91af 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -1,5 +1,5 @@ [tryton] -version=6.0.3 +version=7.0.0 depends: cashbook xml: diff --git a/versiondep.txt b/versiondep.txt index f35d598..bae9199 100644 --- a/versiondep.txt +++ b/versiondep.txt @@ -1 +1 @@ -cashbook;6.0.10;6.0.999;mds +cashbook;7.0.31;7.0.999;mds