transaktionen: export + test
This commit is contained in:
parent
35a31cff69
commit
79620f8cbb
9 changed files with 168 additions and 17 deletions
|
@ -8,7 +8,7 @@ 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
|
from .qif_export import QifCategoryExport, QifBookExport
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
Pool.register(
|
Pool.register(
|
||||||
|
@ -20,6 +20,7 @@ def register():
|
||||||
module='cashbook_dataexchange', type_='model')
|
module='cashbook_dataexchange', type_='model')
|
||||||
Pool.register(
|
Pool.register(
|
||||||
QifCategoryExport,
|
QifCategoryExport,
|
||||||
|
QifBookExport,
|
||||||
module='cashbook_dataexchange', type_='report')
|
module='cashbook_dataexchange', type_='report')
|
||||||
Pool.register(
|
Pool.register(
|
||||||
ImportQifWizard,
|
ImportQifWizard,
|
||||||
|
|
20
book.py
20
book.py
|
@ -10,20 +10,14 @@ from trytond.pool import Pool, PoolMeta
|
||||||
class Book(metaclass=PoolMeta):
|
class Book(metaclass=PoolMeta):
|
||||||
__name__ = 'cashbook.book'
|
__name__ = 'cashbook.book'
|
||||||
|
|
||||||
# ~ @classmethod
|
@classmethod
|
||||||
# ~ def export_as_qif(cls):
|
def export_as_qif(cls, book):
|
||||||
# ~ """ export all transactions as QIF
|
""" export all transactions as QIF
|
||||||
# ~ """
|
"""
|
||||||
# ~ pool = Pool()
|
pool = Pool()
|
||||||
# ~ Category2 = pool.get('cashbook.category')
|
QifTool = pool.get('cashbook_dataexchange.qiftool')
|
||||||
# ~ QifTool = pool.get('cashbook_dataexchange.qiftool')
|
|
||||||
|
|
||||||
# ~ categories = Category2.search([],
|
return QifTool.qif_export_book(book)
|
||||||
# ~ order=[('cattype', 'ASC'), ('rec_name', 'ASC')])
|
|
||||||
|
|
||||||
# ~ export = ['!Type:Cat']
|
|
||||||
# ~ export.extend([QifTool.qif_export_category(x) for x in categories])
|
|
||||||
# ~ return '\n'.join(export)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create_from_qif(cls, book, qifdata):
|
def create_from_qif(cls, book, qifdata):
|
||||||
|
|
|
@ -66,6 +66,10 @@ msgctxt "model:ir.action,name:qif_category_report"
|
||||||
msgid "Export QIF-File"
|
msgid "Export QIF-File"
|
||||||
msgstr "QIF-Datei exportieren"
|
msgstr "QIF-Datei exportieren"
|
||||||
|
|
||||||
|
msgctxt "model:ir.action,name:qif_transaction_report"
|
||||||
|
msgid "Export QIF-File"
|
||||||
|
msgstr "QIF-Datei exportieren"
|
||||||
|
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
# cashbook_dataexchange.qif_imp_wiz #
|
# cashbook_dataexchange.qif_imp_wiz #
|
||||||
|
|
|
@ -7,8 +7,8 @@ msgid "The following categories are now imported:\n%(categories)s"
|
||||||
msgstr "The following categories are now imported:\n%(categories)s"
|
msgstr "The following categories are now imported:\n%(categories)s"
|
||||||
|
|
||||||
msgctxt "model:ir.message,text:msg_wiz_transactions_found"
|
msgctxt "model:ir.message,text:msg_wiz_transactions_found"
|
||||||
msgid "The following transactionen are now imported:\nBalance: %(balance)s\nNumber of transactions: %(quantity)s"
|
msgid "The following transactionen are now imported:\nCredit: %(credit)s\nDebit: %(debit)s\nBalance: %(balance)s\nNumber of transactions: %(quantity)s"
|
||||||
msgstr "The following transactionen are now imported:\nBalance: %(balance)s\nNumber of transactions: %(quantity)s"
|
msgstr "The following transactionen are now imported:\nCredit: %(credit)s\nDebit: %(debit)s\nBalance: %(balance)s\nNumber of transactions: %(quantity)s"
|
||||||
|
|
||||||
msgctxt "model:ir.message,text:msg_wiz_parties_found"
|
msgctxt "model:ir.message,text:msg_wiz_parties_found"
|
||||||
msgid "The following %(numparties)s parties are now imported:"
|
msgid "The following %(numparties)s parties are now imported:"
|
||||||
|
@ -58,6 +58,10 @@ msgctxt "model:ir.action,name:qif_category_report"
|
||||||
msgid "Export QIF-File"
|
msgid "Export QIF-File"
|
||||||
msgstr "Export QIF-File"
|
msgstr "Export QIF-File"
|
||||||
|
|
||||||
|
msgctxt "model:ir.action,name:qif_transaction_report"
|
||||||
|
msgid "Export QIF-File"
|
||||||
|
msgstr "Export QIF-File"
|
||||||
|
|
||||||
msgctxt "model:cashbook_dataexchange.qif_imp_wiz,name:"
|
msgctxt "model:cashbook_dataexchange.qif_imp_wiz,name:"
|
||||||
msgid "Import QIF-File"
|
msgid "Import QIF-File"
|
||||||
msgstr "Import QIF-File"
|
msgstr "Import QIF-File"
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
from trytond.report import Report
|
from trytond.report import Report
|
||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
|
from slugify import slugify
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class QifCategoryExport(Report):
|
class QifCategoryExport(Report):
|
||||||
|
@ -25,3 +27,38 @@ class QifCategoryExport(Report):
|
||||||
'%s-categories' % IrDate.today().isoformat().replace('-', ''))
|
'%s-categories' % IrDate.today().isoformat().replace('-', ''))
|
||||||
|
|
||||||
# end QifCategoryExport
|
# end QifCategoryExport
|
||||||
|
|
||||||
|
|
||||||
|
class QifBookExport(Report):
|
||||||
|
__name__ = 'cashbook_dataexchange.rep_book'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def execute(cls, ids, data):
|
||||||
|
""" filename for export
|
||||||
|
"""
|
||||||
|
pool = Pool()
|
||||||
|
IrDate = pool.get('ir.date')
|
||||||
|
Book = pool.get('cashbook.book')
|
||||||
|
|
||||||
|
books = Book.search([('id', '=', data.get('id', -1))])
|
||||||
|
if len(books) == 1:
|
||||||
|
return (
|
||||||
|
'qif',
|
||||||
|
Book.export_as_qif(books[0]),
|
||||||
|
False,
|
||||||
|
slugify('%(date)s-transactions-%(book)s' % {
|
||||||
|
'date': IrDate.today().isoformat().replace('-', ''),
|
||||||
|
'book': books[0].name,
|
||||||
|
}, max_length=100, word_boundary=True, save_order=True),
|
||||||
|
)
|
||||||
|
else :
|
||||||
|
return (
|
||||||
|
'txt',
|
||||||
|
'not cashbook found',
|
||||||
|
False,
|
||||||
|
'%(date)s-transactions-%(book)s' % {
|
||||||
|
'date': IrDate.today().isoformat().replace('-', ''),
|
||||||
|
'book': 'not-found',
|
||||||
|
})
|
||||||
|
|
||||||
|
# end QifBookExport
|
||||||
|
|
|
@ -19,5 +19,19 @@ full copyright notices and license terms. -->
|
||||||
<field name="action" ref="qif_category_report"/>
|
<field name="action" ref="qif_category_report"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.action.report" id="qif_transaction_report">
|
||||||
|
<field name="name">Export QIF-File</field>
|
||||||
|
<field name="model">cashbook.book</field>
|
||||||
|
<field name="report_name">cashbook_dataexchange.rep_book</field>
|
||||||
|
<field name="report">cashbook_dataexchange/report/export.fods</field>
|
||||||
|
<field name="template_extension">ods</field>
|
||||||
|
<field name="single" eval="True"/>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.keyword" id="qif_transaction_report-keyword">
|
||||||
|
<field name="keyword">form_action</field>
|
||||||
|
<field name="model">cashbook.book,-1</field>
|
||||||
|
<field name="action" ref="qif_transaction_report"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|
73
qiftool.py
73
qiftool.py
|
@ -6,6 +6,7 @@
|
||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
from trytond.model import Model
|
from trytond.model import Model
|
||||||
from trytond.i18n import gettext
|
from trytond.i18n import gettext
|
||||||
|
from trytond.report import Report
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
@ -119,6 +120,78 @@ class QifTool(Model):
|
||||||
result.append(booking)
|
result.append(booking)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def qif_export_book(cls, book):
|
||||||
|
""" export book
|
||||||
|
"""
|
||||||
|
result = ['!Type:Bank']
|
||||||
|
|
||||||
|
def get_amount_by_bookingstate(amount, line):
|
||||||
|
""" get amount with sign
|
||||||
|
"""
|
||||||
|
if line.bookingtype in ['in', 'spin', 'mvin']:
|
||||||
|
return amount
|
||||||
|
elif line.bookingtype in ['out', 'spout', 'mvout']:
|
||||||
|
return amount * Decimal('-1.0')
|
||||||
|
else :
|
||||||
|
raise ValueError('invalid bookingtype: %s' % line.bookingtype)
|
||||||
|
|
||||||
|
for line in book.lines:
|
||||||
|
# date
|
||||||
|
result.append('D%(date)s' % {
|
||||||
|
'date': Report.format_date(line.date, None),
|
||||||
|
})
|
||||||
|
# total
|
||||||
|
result.append('T%(total)s' % {
|
||||||
|
'total': Report.format_number(get_amount_by_bookingstate(line.amount, line), None),
|
||||||
|
})
|
||||||
|
# state
|
||||||
|
result.append('C%(state)s' % {
|
||||||
|
'state': 'X' if line.state in ['check', 'done'] else '*',
|
||||||
|
})
|
||||||
|
# party
|
||||||
|
if line.party:
|
||||||
|
result.append('P%(party)s' % {
|
||||||
|
'party': line.party.rec_name,
|
||||||
|
})
|
||||||
|
# address
|
||||||
|
p_address = line.party.address_get()
|
||||||
|
if p_address:
|
||||||
|
if len(p_address.full_address.strip()) > 0:
|
||||||
|
result.append('A%(address)s' % {
|
||||||
|
'address': p_address.full_address.replace('\n', ', ').strip(),
|
||||||
|
})
|
||||||
|
# category
|
||||||
|
if line.category:
|
||||||
|
result.append('L%(category)s' % {
|
||||||
|
'category': line.category.rec_name.replace('/', ':'),
|
||||||
|
})
|
||||||
|
# account
|
||||||
|
if line.booktransf:
|
||||||
|
result.append('L[%(account)s]' % {
|
||||||
|
'account': line.booktransf.name,
|
||||||
|
})
|
||||||
|
# description
|
||||||
|
if line.description:
|
||||||
|
result.append('M%(memo)s' % {
|
||||||
|
'memo': line.description.replace('\n', '; ')
|
||||||
|
})
|
||||||
|
|
||||||
|
# split-booking
|
||||||
|
for splitline in line.splitlines:
|
||||||
|
result.append('S%(category)s' % {
|
||||||
|
'category': splitline.category.rec_name.replace('/', ':'),
|
||||||
|
})
|
||||||
|
if splitline.description:
|
||||||
|
result.append('E%(memo)s' % {
|
||||||
|
'memo': splitline.description.replace('\n', '; ')
|
||||||
|
})
|
||||||
|
result.append('$%(total)s' % {
|
||||||
|
'total': Report.format_number(get_amount_by_bookingstate(splitline.amount, line), None),
|
||||||
|
})
|
||||||
|
result.append('^')
|
||||||
|
return '\n'.join(result)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_party_by_name(cls, partyname):
|
def get_party_by_name(cls, partyname):
|
||||||
""" find party
|
""" find party
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -42,7 +42,7 @@ with open(path.join(here, 'versiondep.txt'), encoding='utf-8') as f:
|
||||||
major_version = 6
|
major_version = 6
|
||||||
minor_version = 0
|
minor_version = 0
|
||||||
|
|
||||||
requires = []
|
requires = ['python-slugify']
|
||||||
for dep in info.get('depends', []):
|
for dep in info.get('depends', []):
|
||||||
if not re.match(r'(ir|res|webdav)(\W|$)', dep):
|
if not re.match(r'(ir|res|webdav)(\W|$)', dep):
|
||||||
if dep in modversion.keys():
|
if dep in modversion.keys():
|
||||||
|
|
|
@ -87,6 +87,8 @@ class TransactionTestCase(ModuleTestCase):
|
||||||
self.assertEqual(result['view']['defaults']['company'], company.id)
|
self.assertEqual(result['view']['defaults']['company'], company.id)
|
||||||
self.assertEqual(result['view']['defaults']['info'],
|
self.assertEqual(result['view']['defaults']['info'],
|
||||||
"""The following transactionen are now imported:
|
"""The following transactionen are now imported:
|
||||||
|
Credit: usd297.12
|
||||||
|
Debit: usd56.37
|
||||||
Balance: usd240.75
|
Balance: usd240.75
|
||||||
Number of transactions: 3""")
|
Number of transactions: 3""")
|
||||||
|
|
||||||
|
@ -105,4 +107,26 @@ Number of transactions: 3""")
|
||||||
self.assertEqual(book.lines[1].rec_name, '12/05/2013|Rev|290.00 usd|05.12/06.42UHR TT TELTOW [S-Giro]')
|
self.assertEqual(book.lines[1].rec_name, '12/05/2013|Rev|290.00 usd|05.12/06.42UHR TT TELTOW [S-Giro]')
|
||||||
self.assertEqual(book.lines[2].rec_name, '12/05/2013|Exp|-56.37 usd|some food [Lebensmittel]')
|
self.assertEqual(book.lines[2].rec_name, '12/05/2013|Exp|-56.37 usd|some food [Lebensmittel]')
|
||||||
|
|
||||||
|
self.assertEqual(Book.export_as_qif(book), """!Type:Bank
|
||||||
|
D12/04/2013
|
||||||
|
T7.12
|
||||||
|
CX
|
||||||
|
POpening Balance
|
||||||
|
LBargeld
|
||||||
|
^
|
||||||
|
D12/05/2013
|
||||||
|
T290.00
|
||||||
|
CX
|
||||||
|
PGA NR00002168 BLZ10000000 0
|
||||||
|
LS-Giro
|
||||||
|
M05.12/06.42UHR TT TELTOW
|
||||||
|
^
|
||||||
|
D12/05/2013
|
||||||
|
T-56.37
|
||||||
|
CX
|
||||||
|
PFoodshop Zehlendorf
|
||||||
|
LLebensmittel
|
||||||
|
Msome food
|
||||||
|
^""")
|
||||||
|
|
||||||
# end PartyTestCase
|
# end PartyTestCase
|
||||||
|
|
Loading…
Reference in a new issue