Git Product home page Git Product logo

jejik-mt940's People

Contributors

casperbakker avatar cn42 avatar faustimetal avatar geekdevs avatar jorgenhorstink avatar larsiinger avatar nannehuiges avatar patromo avatar sandermarechal avatar serazoli avatar twitnic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jejik-mt940's Issues

SEPA/IBAN consequences

Hi,

I've been using your parser and it is by far the best structured parser out there, thanks for that. I was just wondering if you're planning to update the parser to accomodate the new SEPA/IBAN changes. I've been trying to make some changes to the parser myself, but I'm sure I'll break more than I'll fix.

Thanks for considering.

Regards,
Sander Spruijt

Cannot read ING files

I suppose this code should be changed in:

Parser/Ing.php

From:

public function accept($text)
{
return substr($text, 7, 6) === 'INGBNL';
}

To:

return substr($text, 6, 6) === 'INGBNL';

Rabobank MT940S

As from 1 april Rabobank drops support for the MT940 Unstructured although MT940 Structured still is going to have support. As for now, the datatime function is not working for the MT940S. As many are still using this repo, does anyone has a solution to this?

Account holder field.

Not sure where to put this, as this is more of a discussion then an issue, so no problem if you want this somewhere else :)
Anyway:

I'm mostly using ABN-AMRO imports, and found out that I can reliably find the name of the accountholder ('tenaamstelling"). I'm sure this is not feasable for all banks, though some should be able to have some sort of parsing for this too.

Its clear where the function for parsing this should go: just like the contraAccount function, it can go in the AbnAmro.php parser file. But the problem is that you want the Transaction to actually have a contraAccountHolder field. This would be unused for most of the parsers, so it feels not completely right to do it on one hand, but on the other hand it is the only place it can go AFAIK. I'm not really comfortable to add a child-class for the transaction with a special Abn-version just for this field at this point, as this would require some class-checking when using the lib.

You can see what I'm trying to do / what I did in my accountHolder fork , i've not done a pull request because of above doubts. Any thoughts about it?

Empty transaction data for ABNAMRO

We are using your package to read the MT940 file a client is uploading. The client uses ABNAMRO.
The account statements, opening, closing balances can be read.

But when we read the transactions we get the correct amount of transactions, but the transaction data is quite empty. The sample response would be something like this:

0 => Jejik\MT940\Statement {#1645 ▼
    -number: "2201/1"
    -account: Jejik\MT940\Account {#1728 ▶}
    -openingBalance: Jejik\MT940\Balance {#1643 ▶}
    -closingBalance: Jejik\MT940\Balance {#1646 ▶}
    -transactions: array:10 [▼
      0 => Jejik\MT940\Transaction {#1709 ▼
        -contraAccount: null
        -amount: 426.27
        -description: """
          /TRTP/SEPA OVERBOEKING/IBAN/NL70TRIO0123456789/BIC/TRIONL2U/NAME/
          TEST MT940 NAME CLIENT/REMI/FACTUURNUMMER 12345678/EREF/2024011
          9225235TRIONL2UXXXE000030076
          """
        -valueDate: DateTime @1705618800 {#1639 …1}
        -bookDate: DateTime @1705618800 {#1636 …1}
        -code: null
        -ref: null
        -bankRef: null
        -supplementaryDetails: null
        -gvc: null
        -txText: null
        -primanota: null
        -extCode: null
        -eref: null
        -bic: null
        -iban: null
        -accountHolder: null
        -kref: null
        -mref: null
        -cred: null
        -svwz: null
        -purp: null
        -debt: null
        -coam: null
        -oamt: null
        -abwa: null
        -abwe: null
      }
      1 => Jejik\MT940\Transaction {#1697 ▶}
      2 => Jejik\MT940\Transaction {#1714 ▶}
      3 => Jejik\MT940\Transaction {#1708 ▶}
      4 => Jejik\MT940\Transaction {#1703 ▶}
      5 => Jejik\MT940\Transaction {#1695 ▶}
      6 => Jejik\MT940\Transaction {#1729 ▶}
      7 => Jejik\MT940\Transaction {#1738 ▶}
      8 => Jejik\MT940\Transaction {#1741 ▶}
      9 => Jejik\MT940\Transaction {#1744 ▶}
    ]
  }

Why is all the transaction data empty? When we use getIBAN for example it response with an empty string.

If you want to try it with a demo ABNAMRO file, you can use this string below. Its different than we use, but it also gives back a empty transaction data.

ABNANL2A
940
ABNANL2A
:20:ABN AMRO BANK NV
:25:123456789
:28:13501/1
:60F:C120511EUR5138,61
:61:1205120514C500,01N654NONREF
:86:/TRTP/SEPA OVERBOEKING/IBAN/FR12345678901234/BIC/GEFRADAM
/NAME/QASD JGRED/REMI/Dit zijn de omschrijvingsregels/EREF/NOTPRO
VIDED
:62F:C120514EUR5638,62

PostFinance MT940 parser

Is there already a parser around for the swiss bank PostFinance?
I could provide a sample file.

Couldn't parse other currencies than EUR

MT940/Parser/AbstractParser.php - line 313

Actually any other currency is not acceptable, third letter of currency i.e. "USD" dosn't match in transaction method:

/(\d{6})(\d{4})?((?:C|D)R?)([0-9,]{1,15})/

"EUR" will be matched correctly. I suppose it should be:

/(\d{6})(\d{4})?((?:C|D)[A-Z]?)([0-9,]{1,15})/

It influence on line 319, which also expect EUR as currency :)

Setting a custom Statement class is broken in php 7.4 and upwards

Because statementBody has a return type of Statement, you can't use a custom Statement class, because it will error saying that "CustomStatementClassX is not Statement".

This was fixed in a previous release, but reverted yesterday because it broke compability with EOL php version 7.3.

To enable it in all version you have to remove the return type completely. To reenable support for php 7.4 and upwards you have to reinstate the interface as the return type.

Parse special character sequences in Triodos MT940

Triodos uses strange prefixes in their MT940 files. See https://www.triodos.nl/downloads/betalen/zak-handleiding-en-voorschriften-europese-incasso.pdf?audience=Business (page 13)

A transaction now looks like this:
000>100000000000

20ALBERT HEIJN 1184 \GRONINGE>21N \ BETAALAUTOMAAT 18-10-14
22 14:17 PASNR. 001>310197958397

While it should be

0000000000000
ALBERT HEIJN 1184 \GRONINGEN \ BETAALAUTOMAAT 18-10-14
14:17 PASNR. 001 0197958397

Quickfix:

protected function description($description) {
    return preg_replace('/>[0-9]{2}/', '', $description);
}

addParser() doesn't act like expected

My code crashes on adding my last own parser. Parser "ABN-AMRO" does not exist.
This is my code:

$this->addParsers($this->getDefaultParsers());  
$this->addParser('My-ING', Ing::class, 'ING');  
$this->addParser('My-TRIODOS', Triodos::class, 'Triodos');  
$this->addParser('My-RABOBANK', Rabobank::class, 'Rabobank');  
$this->addParser('My-ABN-AMRO', AbnAmro::class, 'ABN-AMRO');

Expected outcome:

array:8 [
  "My-ABN-AMRO" => "My\MT940\Parsers\AbnAmro"
  "ABN-AMRO" => "Jejik\MT940\Parser\AbnAmro"
  "My-ING" => "My\MT940\Parsers\Ing"
  "ING" => "Jejik\MT940\Parser\Ing"
  "My-RABOBANK" => "My\MT940\Parsers\Rabobank"
  "Rabobank" => "Jejik\MT940\Parser\Rabobank"
  "Sns" => "Jejik\MT940\Parser\Sns"
  "My-TRIODOS" => "My\MT940\Parsers\Triodos"
  "Triodos" => "Jejik\MT940\Parser\Triodos"
]

actual outcome

array:8 [
  "ABN-AMRO" => "Jejik\MT940\Parser\AbnAmro"
  0 => "StepOrange\MT940\Parsers\Rabobank"
  1 => "StepOrange\MT940\Parsers\Triodos"
  2 => "StepOrange\MT940\Parsers\Ing"
  "ING" => "Jejik\MT940\Parser\Ing"
  "Rabobank" => "Jejik\MT940\Parser\Rabobank"
  "Sns" => "Jejik\MT940\Parser\Sns"
  "Triodos" => "Jejik\MT940\Parser\Triodos"
]

If we look at the method addParser we see 3 things:

  1. $offset == 0 is considerd false this is causing the problem and is incorrect.
  2. based on StackOverflow this method should use array_slice()
  3. The test for addParser doesn't cover this

Current code

public function addParser($name, $class, $before = null)
    {
        if ($before === null) {
            $this->parsers[$name] = $class;
            return $this;
        }

        if ($offset = array_search($before, array_keys($this->parsers))) {
            array_splice($this->parsers, $offset, 0, array($name => $class));
            return $this;
        }

        throw new \RuntimeException(sprintf('Parser "%s" does not exist.', $before));
    }

Code after fixing

public function addParser($name, $class, $before = null)
    {
        if ($before === null) {
            $this->parsers[$name] = $class;
            return $this;
        }
        $offset = array_search($before, array_keys($this->parsers));
        if ($offset !== false) {
            $this->parsers = array_slice($this->parsers , 0, $offset, true) +
                [$name => $class] +
                array_slice($this->parsers , $offset, count($this->parsers)-$offset, true);
            return $this;
        }

        throw new \RuntimeException(sprintf('Parser "%s" does not exist.', $before));
    }

ING MT940 using different line endings

I just noticed how the ING bank seems to have switched to '\n' line endings; this is against their own formatting rules which state that CS2 (\r\n) line endings should be used.

Anyway, I patched AbstractParser.php to do a simple detect on the type of line endings used and adjust the regex in getLine and some offsets accordingly.

32a33,37
>      * Detected line endings used in this MT940 file
>      */
>     protected $le = "\r\n";
> 
>     /**
58a64,67
>         // Detect if CS2 or *nix line endings are used
>         if(strpos("\r\n", $text) !== false) $this->le = "\r\n";
>         else $this->le = "\n";
> 
83,86c92,95
<         $pcre = '/(?:^|\r\n)\:(' . $id . ')\:'   // ":<id>:" at the start of a line
<               . '(.+)'                           // Contents of the line
<               . '(:?$|\r\n\:[[:alnum:]]{2,3}\:)' // End of the text or next ":<id>:"
<               . '/Us';                           // Ungreedy matching

---
>         $pcre = '/(?:^|'.$this->le.')\:(' . $id . ')\:'     // ":<id>:" at the start of a line
>               . '(.+)'                                      // Contents of the line
>               . '(:?$|'.$this->le.'\:[[:alnum:]]{2,3}\:)'   // End of the text or next ":<id>:"
>               . '/Us';                                      // Ungreedy matching
133c142
<             $offset += 4 + $length + 2;

---
>             $offset += 4 + $length + strlen($this->le);
141c150
<                     $offset += 4 + $length + 2;

---
>                     $offset += 4 + $length + strlen($this->le);

'RuntimeException' with message 'No suitable parser found.'

Hello.

I'm trying to understand how to use this parser, so I'm not sure if it's me or my MT940 file's fault ;-)
My sta file is from ING (Poland).

I've tried this:

<?php
require 'vendor/autoload.php';
use Jejik\MT940\Reader;

$mt940file = 'test.sta';
$reader = new Reader();
var_dump($reader->getParsers());
$reader->setParsers(array('ING' => 'Jejik\MT940\Parser\Ing'));
var_dump($reader->getParsers());

$statements = $reader->getStatements(file_get_contents($mt940file));
foreach ($statements as $statement) {
  echo $statement->getOpeningBalance()->getAmount() . "\n";
  foreach ($statement->getTransactions() as $transaction) {
    echo $transaction->getAmount() . "\n";
  }
  echo $statement->getClosingBalance()->getAmount() . "\n";
}

But all I get is:

array(0) {
}
array(1) {
  ["ING"]=>
  string(22) "Jejik\MT940\Parser\Ing"
}
PHP Fatal error:  Uncaught exception 'RuntimeException' with message 'No suitable parser found.' in /tmp/mt940-2/vendor/jejik/mt940/lib/Jejik/MT940/Reader.php:489
Stack trace:
#0 /tmp/mt940-2/index.php(17): Jejik\MT940\Reader->getStatements(':20:MT940\r\n:25:...')
#1 {main}
  thrown in /tmp/mt940-2/vendor/jejik/mt940/lib/Jejik/MT940/Reader.php on line 489

Did I forget something or is it something with my test.sta?

Can't use every statement

Dear Sander,

You build a perfect MT940 package. I have installed it into my server en i am using it actually. But i couldn't get every statement running. I have tried something like this:

$tmpFile =dirname(DIR).'/mt940/upload/' . $_FILES["file"]["name"];
$reader = new Reader();
$statements = $reader->getStatements(file_get_contents($tmpFile));
$x=0;
foreach ($statements as $statement)
{
$e_bank = $statement->getAccount()->getName();
$e_account = $statement->getAccount()->getNumber();
$e_startPrice = $statement->getOpeningBalance()->getAmount();

foreach ($statement->getTransactions() as $transaction) 
{
    $e__price[$i] = $transaction->getAmount();
    if ($transaction->getContraAccount()) 
    {
            $e__accountName[$i] = $transaction->getContraAccount()->getName(); 
        $e__account[$i] = $transaction->getContraAccount()->getNumber();    
    }       

    //$e__debitcredit[$i] = $transaction->debitcredit;
        $e__description[$i] = $transaction->getDescription();
    //$e__valueTimestamp[$i] = $transaction->getBookDate();
    //$e__entryTimestamp[$i] = $transaction->getValueDate();
    $i++;  
}

$e_endPrice = $statement->getClosingBalance()->getAmount();
$e_number = $statement->getNumber(); 

}

//$e__valueTimestamp[$i] = $transaction->getBookDate();
//$e__entryTimestamp[$i] = $transaction->getValueDate();

I couldn't get getBookDate() and getValueDate(). I have an crash if I try to get it.

A second issue is that I can't get any bank info.
$e_bank = $statement->getAccount()->getName();

Normally I have to get the bank name by the code above but i can't get it. I don't know what I am doing wrong.

I have exported de MT940 file of an ING account. Normally i have to get the contra bank name and contra account number but i couldn't get it with the code below:
if ($transaction->getContraAccount())
{
$e__accountName[$i] = $transaction->getContraAccount()->getName();
$e__account[$i] = $transaction->getContraAccount()->getNumber();
}

Can u help me with that?

Yours sincerly
A. Pehlivan

No suitable parser found.

$xml = '{1:F01INMASARI9XXX3816963020}{2:I940INMASAR0XXXXN}{3:{108:381696302011020}}{4:
:20:20380617-85
:25:68200059703000
:28C:85/1
:60F:C380616SAR17457739841,32
:61:3806160617DR1228,75NTRFNONREF//1FT381679WS1G
Outward Telex Payment
:61:3806160617DR678,75NTRFNONREF//1FT38167ZTDT8
Outward Telex Payment
:61:3806170617DR150,00NTRFNONREF//1604FT38168SZ6
AC Transfer
:62F:C380617SAR17457737783,82
:64:C380617SAR17457737783,82
-}';

$reader = new Reader();

// Parse the ING bank statement content
$statements = $reader->getStatements($xml);

// Loop through the parsed statements
foreach ($statements as $statement) {
// Access statement data
echo "Account Number: " . $statement->getAccountNumber() . PHP_EOL;
echo "Start Date: " . $statement->getStartDate()->format('Y-m-d') . PHP_EOL;
echo "End Date: " . $statement->getEndDate()->format('Y-m-d') . PHP_EOL;

// Loop through transactions
foreach ($statement->getTransactions() as $transaction) {
    echo "Transaction Date: " . $transaction->getDate()->format('Y-m-d') . PHP_EOL;
    echo "Description: " . $transaction->getDescription() . PHP_EOL;
    echo "Amount: " . $transaction->getAmount() . PHP_EOL;
    echo PHP_EOL;
}

}

Barclays SEPA Parser

Hi there,
Wondering if you wouldn't mind lending a hand for a Barclays SEPA Parser - I have a full spec document along with some real files to work with?

How is it best to pass these on?

Line :28C: issue

Hi, thanks for this great parser.

I have an issue on the statementNumber-method in AbstractParser.php

protected function statementNumber(string $text): ?string
   {
       if ($number = $this->getLine('28|28C', $text)) {
           return $number;
       }

       return null;
   }

My mta file has the following line:
:28C:0

and I get this Error message:
Argument 2 passed to Jejik\MT940\Reader::createStatement() must be of the type string, null given

Any idea, why '0' is not passed?
I attached the SWIFT file, causing this problem.

Umsaetze_92835_11.03.2020.txt

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.