diff --git a/README.md b/README.md index f0ac638..337bc6b 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 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: @@ -45,26 +34,47 @@ 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)); - ?> ``` +### Included engines +Currently the following engines are included: -Known issues ------------- +- 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)) -I've provided a phpunit test for some engines, but am missing some test-data... +### Custom engines +To override engines or just try a one-off engine on a file, you can pass an engine into the `parse`-method: -Future plans ------------- +```php +parse(file_get_contents($tmpFile), $engine); +?> +``` -This is GitHub, you know where to find me :) +## Known issues +I've provided unittests but please take a look at the github issue tracker for the latest ideas's, issues or other stuff.. -License -------- +## 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! + +## 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 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); 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(); diff --git a/src/Parser/Banking/Mt940/Engine/Knab.php b/src/Parser/Banking/Mt940/Engine/Knab.php index adaba33..eb95ae3 100644 --- a/src/Parser/Banking/Mt940/Engine/Knab.php +++ b/src/Parser/Banking/Mt940/Engine/Knab.php @@ -99,6 +99,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 a5f94d2..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 ''; } @@ -126,7 +130,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