From 6ad8a312b4e27fa8814508e458e6540aade901ca Mon Sep 17 00:00:00 2001 From: Stefan Rijnhart Date: Wed, 2 Oct 2013 12:19:02 +0200 Subject: [PATCH] [FIX] Move line names overflow when using full IBAN and CAMT statement identifier as bank statement identification in OpenERP --- account_banking/parsers/models.py | 28 ++++++++++++++++++++++++++++ account_banking_camt/camt.py | 24 ++++++++++++++++++------ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/account_banking/parsers/models.py b/account_banking/parsers/models.py index a1abd777c..960bed9b8 100644 --- a/account_banking/parsers/models.py +++ b/account_banking/parsers/models.py @@ -19,6 +19,7 @@ # ############################################################################## +import re from tools.translate import _ class mem_bank_statement(object): @@ -353,6 +354,33 @@ class parser(object): name = "%s-%d" % (base, suffix) return name + def get_unique_account_identifier(self, cr, account): + """ + Get an identifier for a local bank account, based on the last + characters of the account number with minimum length 3. + The identifier should be unique amongst the company accounts + + Presumably, the bank account is one of the company accounts + itself but importing bank statements for non-company accounts + is not prevented anywhere else in the system so the 'account' + param being a company account is not enforced here either. + """ + def normalize(account_no): + return re.sub('\s', '', account_no) + + account = normalize(account) + cr.execute( + """SELECT acc_number FROM res_partner_bank + WHERE company_id IS NOT NULL""") + accounts = [normalize(row[0]) for row in cr.fetchall()] + tail_length = 3 + while tail_length <= len(account): + tail = account[-tail_length:] + if len([acc for acc in accounts if acc.endswith(tail)]) < 2: + return tail + tail_length += 1 + return account + def parse(self, cr, data): ''' Parse data. diff --git a/account_banking_camt/camt.py b/account_banking_camt/camt.py index d39b05ffe..7384a036b 100644 --- a/account_banking_camt/camt.py +++ b/account_banking_camt/camt.py @@ -123,18 +123,30 @@ CAMT Format parser self.get_balance_type_node(node, 'ITBD')) return self.parse_amount(nodes[-1]) - def parse_Stmt(self, node): + def parse_Stmt(self, cr, node): """ - Parse a single Stmt node + Parse a single Stmt node. + + Be sure to craft a unique, but short enough statement identifier, + as it is used as the basis of the generated move lines' names + which overflow when using the full IBAN and CAMT statement id. """ statement = models.mem_bank_statement() statement.local_account = ( self.xpath(node, './ns:Acct/ns:Id/ns:IBAN')[0].text if self.xpath(node, './ns:Acct/ns:Id/ns:IBAN') else self.xpath(node, './ns:Acct/ns:Id/ns:Othr/ns:Id')[0].text) - statement.id = "%s-%s" % ( - statement.local_account, - node.find(self.ns + 'Id').text) + + identifier = node.find(self.ns + 'Id').text + if identifier.upper().startswith('CAMT053'): + identifier = identifier[7:] + statement.id = self.get_unique_statement_id( + cr, "%s-%s" % ( + self.get_unique_account_identifier( + cr, statement.local_account), + identifier) + ) + statement.local_currency = self.xpath(node, './ns:Acct/ns:Ccy')[0].text statement.start_balance = self.get_start_balance(node) statement.end_balance = self.get_end_balance(node) @@ -260,5 +272,5 @@ CAMT Format parser self.assert_tag(root[0][0], 'GrpHdr') statements = [] for node in root[0][1:]: - statements.append(self.parse_Stmt(node)) + statements.append(self.parse_Stmt(cr, node)) return statements