From 86e0678c12f1812759ebeb9f8ed3ad02b4d1abf7 Mon Sep 17 00:00:00 2001 From: Robin Speekenbrink Date: Thu, 2 Jun 2016 12:35:18 +0200 Subject: [PATCH 1/8] updated RABO parsing to support /REMI/ stuff better. This should also address #36 I've added more sample data (taken from https://github.com/dovadi/mt940/blob/master/test/fixtures/rabobank_sepa.txt) with slight alterations... The tests are kind of crude, but seem to demonstrate the workings of the description parsing... --- src/Parser/Banking/Mt940/Engine/Rabo.php | 2 +- .../Banking/Mt940/Engine/Rabo/ParseTest.php | 41 ++++++++++ .../Banking/Mt940/Engine/Rabo/README.md | 1 + test/Parser/Banking/Mt940/Engine/Rabo/sample3 | 74 +++++++++++++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 test/Parser/Banking/Mt940/Engine/Rabo/README.md create mode 100644 test/Parser/Banking/Mt940/Engine/Rabo/sample3 diff --git a/src/Parser/Banking/Mt940/Engine/Rabo.php b/src/Parser/Banking/Mt940/Engine/Rabo.php index a5f94d2..5280260 100644 --- a/src/Parser/Banking/Mt940/Engine/Rabo.php +++ b/src/Parser/Banking/Mt940/Engine/Rabo.php @@ -126,7 +126,7 @@ protected function sanitizeDescription($string) { $description = parent::sanitizeDescription($string); if (strpos($description, '/REMI/') !== false - && preg_match('#/REMI/(.*?)/(ISDT|CSID|RTRN)/#s', $description, $results) && !empty($results[1]) + && preg_match('#/REMI/(.*?)(/((PURP|ISDT|CSID|RTRN)/)|$)#s', $description, $results) && !empty($results[1]) ) { return $results[1]; } diff --git a/test/Parser/Banking/Mt940/Engine/Rabo/ParseTest.php b/test/Parser/Banking/Mt940/Engine/Rabo/ParseTest.php index 5714c45..3b970c1 100644 --- a/test/Parser/Banking/Mt940/Engine/Rabo/ParseTest.php +++ b/test/Parser/Banking/Mt940/Engine/Rabo/ParseTest.php @@ -55,4 +55,45 @@ public function testCorrectHandlingOfVariousStatementPricing() $this->assertEquals(2145.23, $statements[0]->getEndPrice()); $this->assertEquals(-3145.35, $statements[0]->getDeltaPrice()); } + + public function testHandlingOfDescriptions() { + $this->engine->loadString(file_get_contents(__DIR__.'/sample')); + $statements = $this->engine->parse(); + $this->assertSame('Contante storting Overige', $statements[4]->getTransactions()[1]->getDescription()); + $this->assertSame('INVOICE 38', $statements[14]->getTransactions()[3]->getDescription()); + $this->assertSame('VOLGENS AFSPRAAK', $statements[15]->getTransactions()[0]->getDescription()); + $this->assertSame('FAKTUUR 3549', $statements[15]->getTransactions()[1]->getDescription()); + + $this->engine->loadString(file_get_contents(__DIR__.'/sample3')); + $statements = $this->engine->parse(); + // enclosed + $this->assertSame('674725433 1120000153447185 14144467636004962', $statements[0]->getTransactions()[0]->getDescription()); + // ending + $this->assertSame('861835-574631143', $statements[0]->getTransactions()[2]->getDescription()); + // with slash + $this->assertSame('/IBS.00008908/ 1001680-P796142 KINDEROPVANG', $statements[0]->getTransactions()[3]->getDescription()); + + $this->assertSame('Factuur 307472', $statements[1]->getTransactions()[0]->getDescription()); + + $this->engine->loadString(<<engine->parse(); + $this->assertSame('some descripton here thatends with', $statements[1]->getTransactions()[0]->getDescription()); + } } diff --git a/test/Parser/Banking/Mt940/Engine/Rabo/README.md b/test/Parser/Banking/Mt940/Engine/Rabo/README.md new file mode 100644 index 0000000..684318c --- /dev/null +++ b/test/Parser/Banking/Mt940/Engine/Rabo/README.md @@ -0,0 +1 @@ +Sample 3 was copied from https://github.com/dovadi/mt940/blob/master/test/fixtures/rabobank_sepa.txt \ No newline at end of file diff --git a/test/Parser/Banking/Mt940/Engine/Rabo/sample3 b/test/Parser/Banking/Mt940/Engine/Rabo/sample3 new file mode 100644 index 0000000..34454e4 --- /dev/null +++ b/test/Parser/Banking/Mt940/Engine/Rabo/sample3 @@ -0,0 +1,74 @@ +:940: +:20:940S130403 +:25:NL50RABO0123456789 +:28C:0 +:60F:C130402EUR000000001147,95 + +:61:130403D000000000127,50N102EREF +NL96RBOS0523149468 +:86:/EREF/02-04-2013 22:56 1120000153447185/BENM//NAME/Nespresso Nede +rland B.V./REMI/674725433 1120000153447185 14144467636004962 +/ISDT/2013-04-03 + +:61:130403C000000000169,90N122NONREF +0663616476 +:86:/ORDP//NAME/Bedrijf B.V./REMI/NR.201303-111/11.3.2013 +NR.201303-112/11.3.2013/ISDT/2013-04-03 + +:61:131125C000000000173,50N541NONREF +NL02INGB0002447973 +:86:/ORDP//NAME/Hr R Kuil en/of Mw A Kuil-Germain/REMI/861835-5746311 +43 + +:61:131206C000000000171,66N122NONREF +0444656227 +:86:/ORDP//NAME/D VAN WAARD CJ/REMI//IBS.00008908/ 1001680-P796142 KI +NDEROPVANG + +:62F:C130403EUR000000001190,35 + +:20:940S130404 +:25:NL50RABO0123456789 +:28C:0 +:60F:C130403EUR000000001190,35 + +:61:130404D000000000585,60N071NONREF +P004500018 +:86:/BENM//NAME/DIVV afd parkeergebouwewn/REMI/Factuur 307472/ISDT/20 +13-04-04 + +:61:130404C000000001640,76N127NONREF +0117888613 +:86:/ORDP//NAME/DLN CONSULTING/REMI/factuurnummer 201303-128cursus ce +rtified PO/ISDT/2013-04-04 + +:61:130404D000000000674,73N060NONREF +P004238192 +:86:/BENM//NAME/INFRACOM INTERNET BV/REMI/BETALINGSKENM. 231732INCASS +O FACTUUR 231732INCASSO 02-04-2013INFRACOM INTERNET BV*ZWOLLE +/ISDT/2013-04-04 + +:61:130401D000000000130,29N093NONREF +:86:/REMI/KostenPeriode 01-01-2013 t/m 31-03-2013/ISDT/2013-04-01 + +:61:130404C000000002050,95N122NONREF +0691765731 +:86:/ORDP//NAME/Wehkamp BV +04 + +:61:130404C000000001923,90N541EREF +NL82RBOS0602069890 +:86:/EREF/1134027115/ORDP//NAME/BEDRIJF NV/ADDR/STRAATWEG 68 123 +2 AA AMSTERDAM THE NETHERLANDS NL/REMI/Ref: 201302-080/ISDT/2013-04- +04 + +:61:130404C000000013431,00N122NONREF +0477502946 +:86:/ORDP//NAME/EVEREST BV/REMI/12420/20001512 201303-088 XX201303-08 +8XX ZILVERLINE TRAINING1098 TW AMSTERDAM/ISDT/2013-04-04 + +:61:130920C000000000384,75N541NONREF +NL54INGB0006752576 +:86:/ACCW/NL54INGB0006752576,INGBNL2A/ORDP//NAME/Hr A B Huibers en/of + Mw S L Huibers-Huveneers/REMI/1000122-P5549161 +:62F:C130404EUR000000018846,34 \ No newline at end of file From a2b7670859218b219e5051d223b1b73a99acfcf2 Mon Sep 17 00:00:00 2001 From: Robin Speekenbrink Date: Thu, 23 Jun 2016 16:13:55 +0200 Subject: [PATCH 2/8] sort registered engines before detection Make sure the registered engines are sorted by key to prevent injecting banks at varioius orders and not having the detection adhere to the injected order... This allows: ```php $mt940::registerEngine('BankMiddle', 1000); $mt940::registerEngine('BankLast', 1001); $mt940::registerEngine('BankFirst', 900); // $registeredEnginesOrderDuringDetection = ['BankFirst', 'BankMiddle', 'BankLast'] ``` fixes #39 Thanks for the catch @frans-beech-it --- src/Parser/Banking/Mt940/Engine.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Parser/Banking/Mt940/Engine.php b/src/Parser/Banking/Mt940/Engine.php index 1540210..179b23d 100644 --- a/src/Parser/Banking/Mt940/Engine.php +++ b/src/Parser/Banking/Mt940/Engine.php @@ -95,6 +95,8 @@ public static function isApplicable($string) */ private static function detectBank($string) { + ksort(self::$registeredEngines, SORT_NUMERIC); + foreach (self::$registeredEngines as $engineClass) { if ($engineClass::isApplicable($string)) { return new $engineClass(); From 9ebfe9ead55e5eecc5d232d3c025e219d327b7c4 Mon Sep 17 00:00:00 2001 From: Sam Mousa Date: Thu, 28 Jul 2016 14:09:02 +0000 Subject: [PATCH 3/8] Improved support for KNAB and RABO using new method for passing the NAME. Added support for getting the name from pin transactions by looking for `Betaalautomaat` in the description. --- src/Parser/Banking/Mt940/Engine/Knab.php | 4 ++++ src/Parser/Banking/Mt940/Engine/Rabo.php | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Parser/Banking/Mt940/Engine/Knab.php b/src/Parser/Banking/Mt940/Engine/Knab.php index 64c27a1..83827fd 100644 --- a/src/Parser/Banking/Mt940/Engine/Knab.php +++ b/src/Parser/Banking/Mt940/Engine/Knab.php @@ -80,6 +80,10 @@ protected function parseTransactionAccountName() && !empty($results[1]) ) { return trim($results[1]); + } elseif (preg_match('#/NAME/(.*?)\n?/(REMI|CSID)/#ms', $this->getCurrentTransactionData(), $results) + && !empty($results[1]) + ) { + return trim($results[1]); } } diff --git a/src/Parser/Banking/Mt940/Engine/Rabo.php b/src/Parser/Banking/Mt940/Engine/Rabo.php index 5280260..24853a0 100644 --- a/src/Parser/Banking/Mt940/Engine/Rabo.php +++ b/src/Parser/Banking/Mt940/Engine/Rabo.php @@ -53,22 +53,26 @@ protected function parseTransactionAccountName() { $results = []; // SEPA MT940 Structured - if (preg_match('#/NAME/(.*?)/(REMI|ADDR)/#ms', $this->getCurrentTransactionData(), $results) - && !empty($results[1]) - ) { + if (preg_match('#/NAME/(.+?)\n?/(REMI|ADDR|ISDT|CSID)/#ms', $this->getCurrentTransactionData(), $results)) { $accountName = trim($results[1]); if (!empty($accountName)) { return $this->sanitizeAccountName($accountName); } } - if (preg_match('/^:61:.*? (.*)/m', $this->getCurrentTransactionData(), $results) && !empty($results[1])) { + if (preg_match('/^:61:.*? (.+)/m', $this->getCurrentTransactionData(), $results)) { $accountName = trim($results[1]); if (!empty($accountName)) { return $this->sanitizeAccountName($accountName); } } + if (preg_match('/(.*) Betaalautomaat/', $this->parseTransactionDescription(), $results)) { + $accountName = trim($results[1]); + if (!empty($accountName)) { + return $this->sanitizeAccountName($accountName); + } + } return ''; } From 0369d692c897a97859b4face440796f495de0145 Mon Sep 17 00:00:00 2001 From: Tom Coonen Date: Tue, 6 Sep 2016 12:01:02 +0200 Subject: [PATCH 4/8] Fixed typo in deprecation error. --- src/Banking/Statement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Banking/Statement.php b/src/Banking/Statement.php index 9d0f998..a86a257 100644 --- a/src/Banking/Statement.php +++ b/src/Banking/Statement.php @@ -154,7 +154,7 @@ public function getEndPrice() public function getTimestamp($format = 'U') { trigger_error('Deprecated in favor of splitting the start and end timestamps for a statement. '. - 'Please use setStartTimestamp($format) or setEndTimestamp($format) instead. '. + 'Please use getStartTimestamp($format) or getEndTimestamp($format) instead. '. 'getTimestamp is now getStartTimestamp', E_USER_DEPRECATED); return $this->getStartTimestamp($format); From 78cc74a31dc61fa67291180881c0bfc946eeebcb Mon Sep 17 00:00:00 2001 From: Robin Speekenbrink Date: Thu, 20 Oct 2016 14:12:01 +0200 Subject: [PATCH 5/8] added information on custom parse engines fixes #43 --- README.md | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index f0ac638..88954da 100644 --- a/README.md +++ b/README.md @@ -4,24 +4,15 @@ [![License](https://poser.pugx.org/kingsquare/php-mt940/license.png)](https://packagist.org/packages/kingsquare/php-mt940) [![wercker status](https://app.wercker.com/status/1b20215cc9fee0e4effbe7ad81da1328/s/ "wercker status")](https://app.wercker.com/project/bykey/1b20215cc9fee0e4effbe7ad81da1328) -README -====== - -What is php-mt940? ----------------- - -The php-mt940 package provides a simple lightweight parser for mt940 (dutch bank file format) parsing. The output +# php-mt940? +The php-mt940 package provides a lightweight parser for mt940 (dutch bank file format) parsing. The output is transformed into easy to use dataclasses Transaction_banking which itself contains Statement_banking objects. Pretty straight forward. -Requirements ------------- - +## Requirements * Atleast the latest supported PHP5. This should read 5.4+, but probably 5.3 would work (and you should upgrade) -Installation ------------- - +## Installation If composer is not yet on your system, follow the instructions on [getcomposer.org](https://getcomposer.org/doc/00-intro.md#installation-linux-unix-osx) to do so. To add this dependency to your project, simply run the following command from the root of your project: @@ -30,9 +21,7 @@ To add this dependency to your project, simply run the following command from th This ensures that you install the latest stable release. -How to use the parsers? -------------------- - +## How to use the parsers? I've attached a simple script in the examples directory to explain it a bit more in detail, but after loading the required classes, the usage should be pretty simple: @@ -45,26 +34,37 @@ required classes, the usage should be pretty simple: $parser = new \Kingsquare\Parser\Banking\Mt940(); $tmpFile = __DIR__.'/test.mta'; $parsedStatements = $parser->parse(file_get_contents($tmpFile)); - ?> ``` -Known issues ------------- +### Custom parsers +To override parsers or just try a one-off parser on a file, you can pass an engine into the `parse`-method: -I've provided a phpunit test for some engines, but am missing some test-data... +```php +parse(file_get_contents($tmpFile), $engine); +?> +``` -Contact -------- +## Known issues +I've provided a phpunit test for some engines, but am missing some test-data... -This is GitHub, you know where to find me :) +## Future plans +I do intend to add new engines or keep everything running smoothly, but since i don't have access to any more test files, it's hard to add new engines ;) The `unknown` engine should work or atleast give some idea as to where different banks diverge from the standard. If you do have any ideas, examples or new banks that you'd like to see incorporated, please don't hesitate and send me an issue / pullrequest! -License -------- +## Contact +This is GitHub, you know where to find me :) +## License PHP-MT940 is licensed under the MIT License - see the LICENSE file for details From 46b50f4bf68628e34f23a3e69ac857385e05daa0 Mon Sep 17 00:00:00 2001 From: Robin Speekenbrink Date: Thu, 20 Oct 2016 14:16:10 +0200 Subject: [PATCH 6/8] updated the docs a bit more --- README.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 88954da..f7779cb 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ To add this dependency to your project, simply run the following command from th This ensures that you install the latest stable release. -## How to use the parsers? +## How to use the parser? I've attached a simple script in the examples directory to explain it a bit more in detail, but after loading the required classes, the usage should be pretty simple: @@ -36,9 +36,19 @@ $tmpFile = __DIR__.'/test.mta'; $parsedStatements = $parser->parse(file_get_contents($tmpFile)); ?> ``` - -### Custom parsers -To override parsers or just try a one-off parser on a file, you can pass an engine into the `parse`-method: +### Included engines +Currently the following engines are included: + +- ABNAMRO ([here](./src/Parser/Mt940/Engine/Abn.php)) +- ING ([here](./src/Parser/Mt940/Engine/Ing.php)) +- KNAB ([here](./src/Parser/Mt940/Engine/Knab.php)) +- RABOBANK ([here](./src/Parser/Mt940/Engine/Rabo.php)) +- SPARKASSE ([here](./src/Parser/Mt940/Engine/Spk.php)) +- TRIODOS ([here](./src/Parser/Mt940/Engine/Triodos.php)) +- a default `UNKNOWN`-engine ([here](./src/Parser/Mt940/Engine/Unknown.php)) + +### Custom engines +To override engines or just try a one-off engine on a file, you can pass an engine into the `parse`-method: ```php Date: Thu, 20 Oct 2016 14:17:01 +0200 Subject: [PATCH 7/8] fixed typ0 --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index f7779cb..5523ab7 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,13 @@ $parsedStatements = $parser->parse(file_get_contents($tmpFile)); ### Included engines Currently the following engines are included: -- ABNAMRO ([here](./src/Parser/Mt940/Engine/Abn.php)) -- ING ([here](./src/Parser/Mt940/Engine/Ing.php)) -- KNAB ([here](./src/Parser/Mt940/Engine/Knab.php)) -- RABOBANK ([here](./src/Parser/Mt940/Engine/Rabo.php)) -- SPARKASSE ([here](./src/Parser/Mt940/Engine/Spk.php)) -- TRIODOS ([here](./src/Parser/Mt940/Engine/Triodos.php)) -- a default `UNKNOWN`-engine ([here](./src/Parser/Mt940/Engine/Unknown.php)) +- ABNAMRO ([here](./src/Parser/Banking/Mt940/Engine/Abn.php)) +- ING ([here](./src/Parser/Banking/Mt940/Engine/Ing.php)) +- KNAB ([here](./src/Parser/Banking/Mt940/Engine/Knab.php)) +- RABOBANK ([here](./src/Parser/Banking/Mt940/Engine/Rabo.php)) +- SPARKASSE ([here](./src/Parser/Banking/Mt940/Engine/Spk.php)) +- TRIODOS ([here](./src/Parser/Banking/Mt940/Engine/Triodos.php)) +- a default `UNKNOWN`-engine ([here](./src/Parser/Banking/Mt940/Engine/Unknown.php)) ### Custom engines To override engines or just try a one-off engine on a file, you can pass an engine into the `parse`-method: From 25b8607a4efbf73685d563d0131e6ce4ab883136 Mon Sep 17 00:00:00 2001 From: Robin Speekenbrink Date: Tue, 25 Oct 2016 22:22:23 +0200 Subject: [PATCH 8/8] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5523ab7..337bc6b 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ $parsedStatements = $parser->parse(file_get_contents($tmpFile), $engine); ``` ## Known issues -I've provided a phpunit test for some engines, but am missing some test-data... +I've provided unittests but please take a look at the github issue tracker for the latest ideas's, issues or other stuff.. ## Future plans I do intend to add new engines or keep everything running smoothly, but since i don't have access to any more test files, it's hard to add new engines ;) The `unknown` engine should work or atleast give some idea as to where different banks diverge from the standard. If you do have any ideas, examples or new banks that you'd like to see incorporated, please don't hesitate and send me an issue / pullrequest!