Files
tradon/modules/account_statement_mt940/account.py
2026-03-14 09:42:12 +00:00

132 lines
4.9 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from io import BytesIO, TextIOWrapper
from mt940 import (
MT940, abn_amro_description, ing_description, regiobank_description)
from trytond.i18n import gettext
from trytond.model import fields
from trytond.modules.account_statement.exceptions import ImportStatementError
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
class StatementImportStart(metaclass=PoolMeta):
__name__ = 'account.statement.import.start'
mt940_bank = fields.Selection([
(None, ""),
('rabo', "Rabo"),
('abn_amro', "ABN AMRO"),
('ing', "ING"),
('regiobank', "RegioBank"),
], "Bank",
states={
'invisible': Eval('file_format') != 'mt940',
})
@classmethod
def __setup__(cls):
super().__setup__()
cls.file_format.selection.append(('mt940', "MT940"))
class StatementImport(metaclass=PoolMeta):
__name__ = 'account.statement.import'
def parse_mt940(self, encoding=None):
file_ = TextIOWrapper(BytesIO(self.start.file_), encoding=encoding)
mt940 = MT940(file_)
for mt940_statement in mt940.statements:
statement = self.mt940_statement(mt940_statement)
origins = []
for transaction in mt940_statement.transactions:
origins.extend(self.mt940_origin(mt940_statement, transaction))
statement.origins = origins
yield statement
def mt940_statement(self, mt940_statement):
pool = Pool()
Statement = pool.get('account.statement')
Journal = pool.get('account.statement.journal')
statement = Statement()
statement.name = mt940_statement.information
statement.company = self.start.company
account, currency = (
self.mt940_statement_account_currency(mt940_statement))
start_balance = mt940_statement.start_balance
end_balance = mt940_statement.end_balance
statement.journal = Journal.get_by_bank_account(
statement.company, account,
currency=currency or start_balance.currency)
if not statement.journal:
raise ImportStatementError(
gettext('account_statement.msg_import_no_journal',
account=mt940_statement.account))
statement.date = end_balance.date
statement.start_balance = start_balance.amount
statement.end_balance = end_balance.amount
statement.total_amount = (
end_balance.amount - start_balance.amount)
statement.number_of_lines = len(mt940_statement.transactions)
return statement
def mt940_statement_account_currency(self, mt940_statement):
if self.start.mt940_bank == 'rabo':
return mt940_statement.account.split(' ', 1)
return mt940_statement.account, None
def mt940_origin(self, mt940_statement, transaction):
pool = Pool()
Origin = pool.get('account.statement.origin')
origin = Origin()
origin.number = transaction.id
origin.date = transaction.date
origin.amount = transaction.amount
origin.party = self.mt940_party(mt940_statement, transaction)
origin.description = ''.join(transaction.description.splitlines())
origin.information = self.mt940_information(
mt940_statement, transaction)
return [origin]
def mt940_party(self, mt940_statement, transaction):
pool = Pool()
AccountNumber = pool.get('bank.account.number')
account = self.mt940_account(mt940_statement, transaction)
if account:
numbers = AccountNumber.search(['OR',
('number', '=', account),
('number_compact', '=', account),
])
if len(numbers) == 1:
number, = numbers
if number.account.owners:
return number.account.owners[0]
def mt940_account(self, mt940_statement, transaction):
if self.start.mt940_bank == 'abn_amro':
description = abn_amro_description(transaction.description)
return description.get('account')
elif self.start.mt940_bank == 'ing':
description = ing_description(transaction.description)
return description.get('cntp', {}).get('account_number')
elif self.start.mt940_bank == 'regiobank':
description = regiobank_description(transaction.description)
return description.get('account')
def mt940_information(self, mt940_statement, transaction):
information = {}
for name in [
'reference',
'institution_reference',
'additional_data']:
value = getattr(transaction, name)
if value:
information['mt940_' + name] = value
return information