Browse Source

[ENH] Support zip files.

pull/36/head
Ronald Portier (Therp BV) 9 years ago
parent
commit
26fac7bfa7
  1. 33
      account_bank_statement_import/models/account_bank_statement_import.py
  2. 30
      account_bank_statement_import_camt/test_files/test-camt053.xml
  3. BIN
      account_bank_statement_import_camt/test_files/test-camt053.zip
  4. 11
      account_bank_statement_import_camt/tests/test_import_bank_statement.py
  5. 2
      account_bank_statement_import_mt940_base/mt940.py
  6. BIN
      bank_statement_parse_camt/test_files/test-camt053.zip

33
account_bank_statement_import/models/account_bank_statement_import.py

@ -2,6 +2,8 @@
"""Framework for importing bank statement files."""
import logging
import base64
from StringIO import StringIO
from zipfile import ZipFile, BadZipfile # BadZipFile in Python >= 3.2
from openerp import api, models, fields
from openerp.tools.translate import _
@ -52,7 +54,7 @@ class AccountBankStatementImport(models.TransientModel):
@api.multi
def import_file(self):
""" Process the file chosen in the wizard, create bank statement(s) and
"""Process the file chosen in the wizard, create bank statement(s) and
go to reconciliation."""
self.ensure_one()
data_file = base64.b64decode(self.data_file)
@ -71,13 +73,38 @@ class AccountBankStatementImport(models.TransientModel):
'type': 'ir.actions.client',
}
@api.model
def _parse_all_files(self, data_file):
"""Parse one file or multiple files from zip-file.
Return array of statements for further processing.
"""
statements = []
files = [data_file]
try:
with ZipFile(StringIO(data_file), 'r') as archive:
files = [
archive.read(filename) for filename in archive.namelist()
if not filename.endswith('/')
]
except BadZipfile:
pass
# Parse the file(s)
for import_file in files:
# The appropriate implementation module(s) returns the statements.
# Actually we don't care wether all the files have the same
# format. Although unlikely you might mix mt940 and camt files
# in one zipfile.
statements += self._parse_file(import_file)
return statements
@api.model
def _import_file(self, data_file):
""" Create bank statement(s) from file."""
# The appropriate implementation module returns the required data
statement_ids = []
notifications = []
parse_result = self._parse_file(data_file)
parse_result = self._parse_all_files(data_file)
# Check for old version result, with separate currency and account
if isinstance(parse_result, tuple) and len(parse_result) == 3:
(currency_code, account_number, statements) = parse_result
@ -125,7 +152,7 @@ class AccountBankStatementImport(models.TransientModel):
return self._create_bank_statement(stmt_vals)
@api.model
def _parse_file(self, data_file):
def _parse_file(self, dummy_data_file):
""" Each module adding a file support must extends this method. It
processes the file if it can, returns super otherwise, resulting in a
chain of responsability.

30
account_bank_statement_import_camt/test_files/test-camt053.xml

@ -2,15 +2,15 @@
<BkToCstmrStmt>
<GrpHdr>
<MsgId>TESTBANK/NL/1420561226673</MsgId>
<CreDtTm>2013-01-06T16:20:26.673Z</CreDtTm>
<CreDtTm>2014-01-06T16:20:26.673Z</CreDtTm>
</GrpHdr>
<Stmt>
<Id>1234Test/1</Id>
<LglSeqNb>2</LglSeqNb>
<CreDtTm>2013-01-06T16:20:26.673Z</CreDtTm>
<CreDtTm>2014-01-06T16:20:26.673Z</CreDtTm>
<FrToDt>
<FrDtTm>2013-01-05T00:00:00.000Z</FrDtTm>
<ToDtTm>2013-01-05T23:59:59.999Z</ToDtTm>
<FrDtTm>2014-01-05T00:00:00.000Z</FrDtTm>
<ToDtTm>2014-01-05T23:59:59.999Z</ToDtTm>
</FrToDt>
<Acct>
<Id>
@ -32,7 +32,7 @@
<Amt Ccy="EUR">15568.27</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</Dt>
</Bal>
<Bal>
@ -44,7 +44,7 @@
<Amt Ccy="EUR">15121.12</Amt>
<CdtDbtInd>CRDT</CdtDbtInd>
<Dt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</Dt>
</Bal>
<Ntry>
@ -52,10 +52,10 @@
<CdtDbtInd>DBIT</CdtDbtInd>
<Sts>BOOK</Sts>
<BookgDt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</BookgDt>
<ValDt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</ValDt>
<BkTxCd>
<Domn>
@ -104,9 +104,9 @@
</CdtrAgt>
</RltdAgts>
<RmtInf>
<Ustrd>Insurance policy 857239PERIOD 01.01.2013 - 31.12.2013</Ustrd>
<Ustrd>Insurance policy 857239PERIOD 01.01.2014 - 31.12.2014</Ustrd>
</RmtInf>
<AddtlTxInf>MKB Insurance 859239PERIOD 01.01.2013 - 31.12.2013</AddtlTxInf>
<AddtlTxInf>MKB Insurance 859239PERIOD 01.01.2014 - 31.12.2014</AddtlTxInf>
</TxDtls>
</NtryDtls>
</Ntry>
@ -116,10 +116,10 @@
<RvslInd>true</RvslInd>
<Sts>BOOK</Sts>
<BookgDt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</BookgDt>
<ValDt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</ValDt>
<BkTxCd>
<Domn>
@ -182,10 +182,10 @@
<CdtDbtInd>CRDT</CdtDbtInd>
<Sts>BOOK</Sts>
<BookgDt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</BookgDt>
<ValDt>
<Dt>2013-01-05</Dt>
<Dt>2014-01-05</Dt>
</ValDt>
<BkTxCd>
<Domn>
@ -202,7 +202,7 @@
<NtryDtls>
<TxDtls>
<Refs>
<InstrId>INNDNL2U20130105000217200000708</InstrId>
<InstrId>INNDNL2U20140105000217200000708</InstrId>
<EndToEndId>115</EndToEndId>
</Refs>
<AmtDtls>

BIN
account_bank_statement_import_camt/test_files/test-camt053.zip

11
account_bank_statement_import_camt/tests/test_import_bank_statement.py

@ -31,11 +31,10 @@ class TestImport(TestStatementFile):
{
'remote_account': 'NL46ABNA0499998748',
'transferred_amount': -754.25,
'value_date': '2013-01-05',
'value_date': '2014-01-05',
'ref': '435005714488-ABNO33052620',
},
]
# statement name is account number + '-' + date of last 62F line:
self._test_statement_import(
'account_bank_statement_import_camt', 'test-camt053.xml',
'1234Test/1',
@ -43,3 +42,11 @@ class TestImport(TestStatementFile):
start_balance=15568.27, end_balance=15121.12,
transactions=transactions
)
def test_zip_import(self):
"""Test import of multiple statements from zip file."""
self._test_statement_import(
'account_bank_statement_import_camt', 'test-camt053.zip',
'1234Test/2', # Only name of first statement
local_account='NL77ABNA0574908765',
)

2
account_bank_statement_import_mt940_base/mt940.py

@ -111,7 +111,7 @@ class MT940(object):
This in fact uses the ING syntax, override in others."""
self.mt940_type = 'General'
self.header_lines = 3 # Number of lines to skip
self.header_regex = '^0000 01INGBNL2AXXXX|^{1'
self.header_regex = '^0000 01INGBNL2AXXXX|^{1' # Start of header
self.footer_regex = '^-}$|^-XXX$' # Stop processing on seeing this
self.tag_regex = '^:[0-9]{2}[A-Z]*:' # Start of new tag
self.current_statement = None

BIN
bank_statement_parse_camt/test_files/test-camt053.zip

Loading…
Cancel
Save