changeset 8:251e86dfc340

Add support for ING :86: specific format
author Nicolas Évrard <nicoe@b2ck.com>
date Tue, 16 Dec 2014 18:37:02 +0100
parents dfca95618d7d
children a645ef6c6c6a
files CHANGELOG mt940/__init__.py mt940/test.py
diffstat 3 files changed, 82 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Tue Jul 08 18:10:10 2014 +0200
+++ b/CHANGELOG	Tue Dec 16 18:37:02 2014 +0100
@@ -1,2 +1,4 @@
+* Add support for ING specific description format
+
 Version 0.1 - 2014-06-25
 * Initial release
--- a/mt940/__init__.py	Tue Jul 08 18:10:10 2014 +0200
+++ b/mt940/__init__.py	Tue Dec 16 18:37:02 2014 +0100
@@ -2,7 +2,8 @@
 # -*- coding: utf-8 -*-
 #
 # Copyright (c) 2013, Cédric Krier
-# Copyright (c) 2013, B2CK
+# Copyright (c) 2014, Nicolas Évrard
+# Copyright (c) 2013-2014, B2CK
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -29,7 +30,8 @@
 """a parser for MT940 files
 """
 __version__ = '0.2'
-__all__ = ['MT940', 'rabo_description', 'abn_amro_description']
+__all__ = ['MT940', 'rabo_description', 'abn_amro_description',
+    'ing_description']
 
 from collections import namedtuple, defaultdict
 from decimal import Decimal
@@ -219,3 +221,48 @@
         values['account'] = m.group(1)
     values.update(_find_swift_tags(ABN_AMRO_TAGS, description))
     return values
+
+ING_TAGS = re.compile(r'/(RTRN|EREF|PREF|MARF|CSID|CNTP|REMI|PURP|ULT[CD])/')
+ING_TAGS_DEFINITION = {
+    'RTRN': ('rtrn', []),
+    'EREF': ('eref', []),
+    'PREF': ('pref', []),
+    'MARF': ('marf', []),
+    'CSID': ('csid', []),
+    'CNTP': ('cntp', ['account_number', 'bic', 'name', 'city']),
+    'REMI': ('remi', ['code', 'issuer', 'remittance_info']),
+    'PURP': ('purp', []),
+    'ULTC': ('ultc', ['name', 'id']),
+    'ULTD': ('ultd', ['name', 'id']),
+    }
+
+
+def ing_description(description):
+    "Return dictionnary with ING informations"
+    description = ''.join(description.splitlines())
+    values = {}
+    ing_tags = iter(ING_TAGS.split(description)[1:])
+    for tag, tag_value in zip(ing_tags, ing_tags):
+        tag_value = tag_value[:-1]
+        name, subfields = ING_TAGS_DEFINITION[tag]
+
+        if not subfields:
+            values[name] = tag_value
+            continue
+
+        values[name] = {}
+        if 'name' in subfields or 'remittance_info' in subfields:
+            special_tag = 'name' if 'name' in subfields else 'remittance_info'
+            tag_idx = subfields.index(special_tag)
+            subtags = tag_value.split('/', tag_idx)
+            for sf_name, sf_value in zip(subfields[:tag_idx], subtags[:-1]):
+                values[name][sf_name] = sf_value
+            subtags = subtags[-1].rsplit('/', len(subfields) - tag_idx - 1)
+            for sf_name, sf_value in zip(subfields[tag_idx:], subtags):
+                values[name][sf_name] = sf_value
+        else:
+            subtags = tag_value.split('/')
+            for sf_name, sf_value in zip(subfields, subtags):
+                values[name][sf_name] = sf_value
+
+    return values
--- a/mt940/test.py	Tue Jul 08 18:10:10 2014 +0200
+++ b/mt940/test.py	Tue Dec 16 18:37:02 2014 +0100
@@ -2,7 +2,8 @@
 # -*- coding: utf-8 -*-
 #
 # Copyright (c) 2013, Cédric Krier
-# Copyright (c) 2013, B2CK
+# Copyright (c) 2014, Nicolas Évrard
+# Copyright (c) 2013-2014, B2CK
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -34,7 +35,8 @@
 from decimal import Decimal
 
 here = os.path.dirname(__file__)
-from mt940 import MT940, rabo_description, abn_amro_description
+from mt940 import (MT940, rabo_description, abn_amro_description,
+    ing_description)
 
 
 class TestMT940(unittest.TestCase):
@@ -128,5 +130,32 @@
         self.assertEqual(abn_amro_description('foo'), {})
         self.assertEqual(rabo_description('/FOO/BAR/NAME/'), {})
 
+
+class TestINGDescription(unittest.TestCase):
+
+    def test_tag(self):
+        description = """/EREF/170330P40411570.4342.2964442//CNTP/
+NL94RABO0123456789/RABONL2U/ENERGIE BEDRIJF///REMI/USTD//
+170330/REM INFO/"""
+
+        self.assertEqual(ing_description(description), {
+                'eref': '170330P40411570.4342.2964442',
+                'cntp': {
+                    'account_number': 'NL94RABO0123456789',
+                    'bic': 'RABONL2U',
+                    'name': 'ENERGIE BEDRIJF',
+                    'city': '',
+                    },
+                'remi': {
+                    'code': 'USTD',
+                    'issuer': '',
+                    'remittance_info': '170330/REM INFO',
+                    },
+                })
+
+    def test_non_ing(self):
+        self.assertEqual(ing_description('foo'), {})
+        self.assertEqual(ing_description('/FOO/BAR/NAME/'), {})
+
 if __name__ == '__main__':
     unittest.main()