nemiah / phpFinTS

PHP library to communicate with FinTS/HBCI servers
MIT License
131 stars 40 forks source link

$bookingDate parsing in MT940 #62

Closed na-oma closed 2 months ago

na-oma commented 4 years ago

@nemiah 61:1906290701 (bzw: 61:1812310102 61:1901011228) 19 = Jahr 0629 = 29.06. (valutaDate) 0701 = 01.07. (bookingDate)

$year = substr($transaction, 0, 2);
$valutaDate = $this->getDate($year . substr($transaction, 2, 4));

$bookingDate = substr($transaction, 6, 4);

// if valuta date is earlier than booking date, then it must be in the new year.
$year = substr($transaction, 2, 2) < substr($transaction, 6, 2) ? --$year : $year;

if (substr($transaction, 2, 2) == '12' && substr($transaction, 6, 2) == '01') {
$year++;
} elseif (substr($transaction, 2, 2) == '01' && substr($transaction, 6, 2) == '12') {
$year--;
}
$bookingDate = $this->getDate($year . $bookingDate);

Wenn ich richtig schaue, wird aus:

61:1906290701 29.06.19 und 01.07.18 = falsch

61:1812310102 31.12.18 und 02.01.19 = richtig

61:1901011228 01.01.19 und 28.12.17 = falsch

ohne

// if valuta date is earlier than booking date, then it must be in the new year.
$year = substr($transaction, 2, 2) < substr($transaction, 6, 2) ? --$year : $year;

würde es passen

Originally posted by @djm03 in https://github.com/nemiah/phpFinTS/issues/43#issuecomment-533894705

na-oma commented 4 years ago

https://github.com/nemiah/phpFinTS/blob/e8b18a753d65762d278dfe8641b127d31439ba1a/lib/Fhp/Parser/MT940.php#L125

Da irgendein Schlaufuchs im Standard in einer 500 Zeichen Nachricht 2 Zeichen sparen wollte, muss an dieser Stelle von einer einzigen Jahreszahl auf das Jahr von zwei verschiedenen Daten geschlossen werden. Wenn ich den Code richtig interpretiere, nimmt er an, dass laut MT940-Standard ein Valuta-Date niemals vor einem Booking-Date liegen kann. M.a.W. Valuta-Datum kommt immer nach/ist gleich Booking-Date. Wenn dann der Monat des Valuta-Dates tatsächlich vor dem Monat des Booking-Dates liegt, geht der Code davon aus, dass das Booking-Date im Jahr davor liegt, während das Valuta-Date im aktuellen Jahr liegt, deshalb wird ein Jahr abgezogen.

61:1906290701 29.06.19 und 01.07.18 = falsch

Ist laut Standard überhaupt erlaubt, das als 29.06.19 (valuta) und 01.07.19 (booking) zu interpretieren?

61:1901011228 01.01.19 und 28.12.17 = falsch

Da scheint definitiv was faul zu sein, Standard hin oder her. Zwei Jahre sollten das nicht sein...er zieht nochmal ein Jahr zusätzlich ab...

Ich kenne leider den Standard nicht auswendig, also weiss ich nicht, ob das Valuta-Datum auch vor dem Booking-Datum liegen darf.

djm03 commented 4 years ago

Es gibt mittlerweile die Echtzeit-Gutschrift, zumindest sehe ich dort immer wieder den Fall. Aktuell zb:

61:1909280930 61:1909290930 61:1908310902

na-oma commented 4 years ago

Hmm, dann scheint das wohl möglich zu sein, dass Valuta-Date vor Booking-Date.

Dann ist die einzige Frage, ob beide Daten um ca. 1 Jahr auseinanderliegen können? Dann könnte man nicht mehr unterscheiden ob

1909280930

als

Valuta: 28.09.19 und Booking: 30.09.19

oder

Valuta: 28.09.19 und Booking: 30.09.18 (also ein Jahr eher)

geparst werden soll.

Man könnte natürlich einfach definieren, dass Booking und Valuta maximal ein halbes Jahr auseinanderliegen, und dann immer das Booking-Date genommen wird, was am nächsten am Valuta-Date liegt.

Vielleicht reicht ja dein Fix die Zeile zu löschen und deckt alle Fälle ab? Ich steh grad auf dem Schlauch^^ Mach doch mal n Pullrequest.

djm03 commented 4 years ago

Ich wüßte jetzt nicht warum Booking und Valuta länger als ein paar Tage auseinander liegen sollten. Ob das entfernen der einen Zeile alles abdeckt, weiß ich jedoch auch nicht. Zumindest würde es die mit "falsch" angegebenen Ergebnisse korrigieren.

nemiah commented 4 years ago

Schick einfach mal einen PR, mir scheint es ein Fortschritt zu sein :wink:

Magellanth commented 4 years ago

Ist durch https://github.com/nemiah/phpFinTS/pull/202 behoben, kann auch zu.