← Back to team overview

banking-addons-team team mailing list archive

[Merge] lp:~therp-nl/banking-addons/6.1_lp1117319_abnamro_sepa_line into lp:banking-addons

 

Ronald Portier (Therp) has proposed merging lp:~therp-nl/banking-addons/6.1_lp1117319_abnamro_sepa_line into lp:banking-addons.

Requested reviews:
  Stefan Rijnhart (Therp) (stefan-therp)
  Guewen Baconnier @ Camptocamp (gbaconnier-c2c)
Related bugs:
  Bug #1117319 in Banking Addons: "Not all sepa lines are supported on bank import"
  https://bugs.launchpad.net/banking-addons/+bug/1117319

For more details, see:
https://code.launchpad.net/~therp-nl/banking-addons/6.1_lp1117319_abnamro_sepa_line/+merge/159403

Make it possible to import abnamro statement files with extended sepa attributes in line.

Taking into account the remarks by Stefan I streamlined the code , hopefully solving the errors.
-- 
https://code.launchpad.net/~therp-nl/banking-addons/6.1_lp1117319_abnamro_sepa_line/+merge/159403
Your team Banking Addons Team is subscribed to branch lp:banking-addons.
=== modified file 'account_banking_nl_abnamro/abnamro.py'
--- account_banking_nl_abnamro/abnamro.py	2012-10-27 19:53:50 +0000
+++ account_banking_nl_abnamro/abnamro.py	2013-04-17 14:26:29 +0000
@@ -155,28 +155,55 @@
             The string consists of slash separated KEY/VALUE pairs,
             but the slash is allowed to and known to occur in VALUE as well!
             """
-            items = field[1:].split('/') # skip leading slash
+            def _sepa_message(field, reason):
+                return _(
+                    'unable to parse SEPA string: %s - %s' % (field, reason))
+
+            def _get_next_key(items, start):
+                '''Find next key, starting from start, returns the key found,
+                the start position in the array and the end position + 1'''
+                known_keys = [
+                    'TRTP', 'IBAN', 'BIC', 'NAME', 'RTRN', 'EREF', 'SWOC',
+                    'REMI', 'ADDR', 'CPRP', 'CREF', 'CSID', 'ISDT', 'MARF',
+                    'NRTX', 'NRTXR', 'PREF', 'PURP', 'REFOB', 'RREF', 'RTYP',
+                    'SVCL', 'SWOD', 'BENM//ID', 'ORDP//ID', 'ORDP//RID',
+                    'ORIG//CSID', 'ORIG//MARF', 'ULTD//NAME', 'ULTD//ID',
+                    'ULTB//NAME', 'ULTB//ID'
+                ]
+                items_len = len(items)
+                start_index = start
+                # Search until start after end of items
+                while start_index < items_len:
+                    end_index = start_index + 1
+                    while end_index < items_len:
+                        key = '/'.join(items[start_index:end_index])
+                        if  key in known_keys:
+                            return (key, start_index, end_index)
+                        end_index += 1
+                    start_index += 1
+                return False
+
+            items = field[1:].split('/')
+            assert len(items) > 1, _sepa_message(field, _('too few items'))
             sepa_dict = {}
-            prev_key = False
-            known_keys = ['TRTP', 'IBAN', 'BIC', 'NAME', 'RTRN', 'EREF',
-                          'SWOC', 'REMI', ]
-            while items:
-                if len(items) == 1:
-                    raise osv.except_osv(
-                        _('Error !'),
-                        _("unable to parse SEPA string: %s") % field)
-                key = items.pop(0)
-                if key not in known_keys:
-                    # either an unknown key or a value containing a slash
-                    if prev_key:
-                        sepa_dict[prev_key] = sepa_dict[prev_key] + '/' + key
-                    else:
-                        raise osv.except_osv(
-                            _('Error !'),
-                            _("unable to parse SEPA string: %s") % field)
-                else:
-                    sepa_dict[key] = items.pop(0).strip()
-                    prev_key = key
+            item_index = 0
+            items_len = len(items)
+            key_info = _get_next_key(items, item_index)
+            assert key_info, _sepa_message(
+                field, _('no key found for start %d') % item_index)
+            assert key_info[1] == 0, _sepa_message(
+                field, _('invalid data found before key %s') % key_info[0])
+            while key_info:
+                sepa_key = key_info[0]
+                item_index = key_info[2]
+                # Find where next key - if any - starts
+                key_info = _get_next_key(items, item_index)
+                value_end_index = (key_info and key_info[1]) or items_len
+                sepa_value = (
+                    ((value_end_index > item_index)
+                    and '/'.join(items[item_index:value_end_index]))
+                    or '')
+                sepa_dict[sepa_key] = sepa_value
             return sepa_dict
 
         def parse_type(field):


Follow ups