Thread: [Hbci4java-help] GVRKUms.UmsLine.instref ändert sich?
Brought to you by:
kleiner77
|
From: Jan B. <ja...@mu...> - 2009-04-21 19:25:40
|
Hallo! Ich versuche, Kontoauszugsdaten zwecks längerfristiger Archivierung in einer Datenbank zu speichern. Dazu rufe ich einmal täglich einen Kontoauszug ab, prüfe, ob die darin enthaltenen Transaktionen schon in der Datenbank gespeichert sind und hänge jene Kontobewegungen, für die das nicht zutrifft an die Datenbanktabelle an. Um zu testen, ob eine Kontobewegung bereits in der Datenbank steht, brauche ich eine Möglichkeit der eindeutigen Identifizierung einer Kontobewegung. Bei Tests mit HBCIBatch habe ich festgestellt, dass bei zwei Abfragen der Kontoauszüge für die selbe Kontobewegung unterschiedliche Werte in GVRKUms.UmsLine.instref stehen können (das passiert selten aber nicht sehr selten). Ich war davon ausgegangen, dass dieser Wert eine Art ID der Kontobewegung darstellt und sich nie ändert. Ist das so gedacht oder ein Fehler der Bank? (in diesem Fall comdirect) Im Feld customerref steht bei dieser Bank übrigens durchgehend NONEREF. Da ausserdem in den Uhrzeitfeldern durchgehend 12:00 Uhr steht, fehlt mir ein Weg, eine eindeutige ID für eine Kontobewegung abzuleiten. Selbst ein Hash über valuta, value, saldo, usage wäre nicht eindeutig: Es können ja durchaus zwei unterschiedliche Transaktionen in all diesen Werten übereinstimmen, demnach den selben Hash haben, aber dennoch zwei unterscheidende Einträge sein. 04.03.2009 12:00 itunes -0,99 saldo: 100,00 EUR 04.03.2009 12:00 Überweisung +0,99 saldo: 100,99 EUR 04.03.2009 12:00 itunes -0,99 saldo: 100,00 EUR In diesem Beispiel sind alle Felder der ersten und dritten Kontobewegung identisch. Ausnahme: instref. Da insref für dieselbe Kontobewegung aber schon morgen einen anderen Wert haben kann, eignet sich dieser Wert nicht für die eindeutige Identifizierung. :( Was habe ich übersehen? dankbar für Ideen, Jan |
|
From: Dirk B. <be...@ad...> - 2009-04-22 06:19:20
|
Jan Bölsche schrieb: > dankbar für Ideen, > Jan Absolut identische Buchungen sollten an einem Tag nicht möglich sein, da müsste dann ein Fehler "Verdacht auf Doppelbuchung" kommen, ich weiß aber nicht ob das wirklich bei jeder Bank so ist. Ich benutze zur eindeutigen Identifizierung das Datum, den Betrag, den Verwendungszweck und den Auftraggeber. |
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-04-22 06:34:31
|
> Absolut identische Buchungen sollten an einem Tag nicht möglich sein, da > müsste dann ein Fehler "Verdacht auf Doppelbuchung" kommen, ich weiß > aber nicht ob das wirklich bei jeder Bank so ist. Ich bin nicht sicher, ob man sich darauf wirklich verlassen kann. Ich glaube (kann ich aber nicht mehr mit 100%iger Sicherheit sagen), ich hätte tatsächlich schonmal HBCI-Kontoauszüge mit exakt identischen Buchungen gesehen, die tatsächlich mehrmals gebucht werden sollten und auch erfolgreich so gebucht wurden. -stefan- |
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-04-22 06:34:20
|
Hallo, > Um zu testen, ob eine Kontobewegung bereits in der Datenbank steht, > brauche ich eine Möglichkeit der eindeutigen Identifizierung einer > Kontobewegung. > > ... > > Was habe ich übersehen? Nichts. Die Daten, die bei den Kontoauszügen zurückgemeldet werden, lassen sich NICHT eindeutig identifzieren (es gibt einfach kein Merkmal bzw. kein Tupel von Merkmalen, welches PRIMARY KEY Charakter hätte). Wie Du schon sagtest - im worst case kann es passieren, dass zwei Buchungen EXAKT identisch sind (die INSTREF ist glaube ich nur ein Kennzeichen der Bank, die die Buchung angestoßen hat - weiß ich aber nicht sicher. In jedem Fall ist das Feld nicht sinnvoll für die eindeutige Identifizierung von Buchungen zu verwenden). Es gibt aber einen anderen Weg, um Dein Problem zu lösen. Beim Abholen von Kontoauszügen gibt es eine nützliche Eigenschaft: Daten, die Du einmal bekommen hast, bekommst Du beim nächsten Abruf des selben Zeitraumes exakt genau so. Es kann nicht passieren, dass sich zwischen zwei Buchungen A und C, die beim ersten Abruf direkt aufeinander folgten, auf einmal eine zusätzliche Buchung B DAZWISCHEN befindet. Es kann höchstens passieren, dass neue Buchungen angehängt werden. Wenn Du also z.B. heute einen Kontoauszug abholst mit Zeitbereich 10.4. bis 22.4., erhälst Du z.B. folgendes: ... 20.4.: Transaktion 1 20.4.: Transaktion 2 21.4.: Transaktion 3 21.4.: Transaktion 4 Ich gehe jetzt davon aus, dass diese Daten nun also in Deiner DB stehen. Später holst Du nochmal Kontoauszüge ab. Du empfängst: ... 20.4.: Transaktion 1 20.4.: Transaktion 2 21.4.: Transaktion 3 21.4.: Transaktion 4 21.4.: Transaktion 5 22.4.: Transaktion 6 Um nun sauber zu "erkennen", welche Transaktionen Du neu importieren musst (T5 und T6) gehst Du wiefolgt vor: 1) Du suchst Dir das Datum der letzten Transaktion, die Du schon in Deiner DB hast (21.4.) 2) Du zählst, WIE VIELE Transaktionen vom 21.4. bereits in Deiner DB enthalten sind (2 Stück, nämlich T3 und T4) 3) Bei den abgeholten Kontoauszügen überspringst Du alle Transaktionen mit Datum vor dem 21.4. (T1 und T2) - denn die hast Du schon in Deiner DB. 4) Bei den Transaktionen vom 21.4. überspringst Du die ersten zwei (T3+T4 - die hast Du auch schon). 5) Alles, was danach folgt, importierst Du als neue Buchungen in Deine DB. Du brauchst beim Abholen von Kontoauszügen eine "Überlappung" mit den bereits existierenden Daten. Du kannst als Startdatum für GVKUmsAll also das größte bereits in Deiner DB bekannte Buchungsdatum verwenden. Im Beispiel hättest Du beim zweiten Abruf als Startdatum anstelle des 10.4. auch den 21.4. verwenden können... Dieses Vorgehen setzt (wie oben geschrieben) voraus, dass einmal abgeholte Kontoauszüge praktisch "fest" sind, sich also nachträglich nicht mehr ändern. Das ist zwar insofern einleuchtend, dass man Konto- auszüge ja theoretisch auch "offline" abholen kann (Kontoauszugs- drucker), und es dort auch nicht möglich ist, dass beim nächsten Ausdruck auf einmal Daten aus der Vergangenheit anders sind. Aber im Onlinebankingforum (http://onlinebanking-forum.de) habe ich von einem Fall gehört, dass beim HBCI-Abruf von Kontoauszügen wohl nachträglich irgendwelche Buchungen auf einmal anders waren. Das SOLLTE ein Einzelfall und ein Fehler gewesen sein - ich denke, man kann davon ausgehen, dass obiger Algorithmus funktioniert. In wallstreet9 benutze ich ein dazu äquivalentes Verfahren seit 2004 ohne Probleme... Viele Grüße -stefan- |
|
From: Jan B. <ja...@mu...> - 2009-04-22 09:02:17
|
Hallo Stefan, vielen Dank für Deine sehr hilfreiche Antwort. In der Tat habe ich heute morgen schon mit genau diesem Vorgehen experimentiert und mir (bzw. Captain FRAG) exakt die Fragen gestellt, die Du im Folgenden beantwortest. Dass Du dieses Verfahren seit 2004 ohne Probleme einsetzt, stimmt mich natürlich sehr zuversichtlich! Etwas macht mich allerdings stutzig: On 22.04.2009, at 08:34, HBCI4Java (Stefan Palme) wrote: > Es gibt aber einen anderen Weg, um Dein Problem zu lösen. Beim Abholen > von Kontoauszügen gibt es eine nützliche Eigenschaft: Daten, die Du > einmal bekommen hast, bekommst Du beim nächsten Abruf des selben > Zeitraumes exakt genau so. Es kann nicht passieren, dass sich zwischen > zwei Buchungen A und C, die beim ersten Abruf direkt aufeinander > folgten, auf einmal eine zusätzliche Buchung B DAZWISCHEN befindet. Es > kann höchstens passieren, dass neue Buchungen angehängt werden. Auf meine Frage: "Ist es möglich, dass für den aktuellen Tag, der ja in der HKKAZ- Antwort nicht komplett sein muss bei einer zweite Abfrage Umsätze nicht nur am Ende dazu kommen, sondern auch an anderen Stellen (zwischen zwei bereits bekannten Umsätzen oder am Anfang z.b.) Sprich: kann man sich auf die Reihenfolge innerhalb eines MT904 verlassen?" antwortet Captain FRAG (Zitat mit freundlicher Genehmigung): > die Reihenfolge muss in der Tat nicht chronologisch sein. In unserem > System kann ich abweichen vom Standard (=Chronologisch) auch andere > Sortierungen für eine Umsatzausgabe hinterlegen. Manchmal sind so > Besonderheiten wie eine Sortierung nach Betrag gewünscht. Regulär > ist aber eine chronologische Ausgabe. Nachvollziehen kann man das > über die Umsatzanlieferung über HBCI allerdings nicht, da dort keine > Uhrzeiten stehen. Ich kenne auch mind. 2 Banksysteme die nicht mal > für den Bankmitarbeiten an der Oberfläche eine Uhrzeit der Buchung > darstellen. Das würde bedeuten, dass zumindest für den "offenen" Buchungstag tatsächlich theoretisch Einträge ZWISCHEN oder VOR bereits bekannten Einträgen auftauchen können. Mir ist aufgefallen, dass bei comdirect die instrefs eines Tages stets kleiner als die des Folgetages sind, innerhalb eines Buchungstages jedoch *absteigen*. Ich werte das als Indiz, dass bei comdirect die Sortierung innerhalb eines Buchungstages absteigend chronologisch ist, neue Buchungen also *oben* auftauchen. (ein Experiment zur Bestätigung dieser Annahme steht noch aus) Man könnte diese Unsicherheit ausschliessen, indem man noch "offene" Buchungstage einfach ignoriert und erst zu einem späteren Zeitpunkt auswertet. Da stellt sich die nächste Frage: Ab wann kann ein Buchungstag als unveränderlich angesehen werden? Reicht es, das sein Datum in der Vergangenheit liegt (maximal gestern), bekommt man also schon 1 Sekunde nach Mitternacht garantiert den unveränderlichen gestrigen Buchungstag? Oder kann die Bank eventuell mehrere Tage hinterher sein? Dann könnte man eventuell davon ausgehen, dass der Tag mit dem aktuellsten Darum in der HBCI-Antwort offen ist und alle anderen fix. Diese Annahme zerbricht allerdings, wenn die Bank z.B. Buchungen macht, die in der Zukunft liegen. Zur Zeit favorisiere ich folgendes Verfahren, das mir recht robust erscheint: 1. Buchungsdatum in der Datenbank aufsteigend sortieren 2. Den drittletzten (z.B.) Eintrag aus dieser Liste als Startdatum verwenden 3. Das aktuelle Datum als Enddatum verwenden 4. Kontoauszüge für Startdatum bis Enddatum per HBCI abfragen 5. Für jeden Buchungstag in der HBCI-Antwort 6. Aus der Datenbank die Liste aller Buchungen für diesen Tag als temporäre Liste (a) lesen 7. Die Buchungen aus der HBCI-Antwort als temporäre Liste (b) lesen 8. Für jeden Eintrag in Lise (b) 9. Ist ein Eintrag in Liste (a) vorhanden, der exakt identisch ist? 10. In diesem Fall: Eintrag aus beiden Listen löschen 11. Die übrigen Einträge in Liste (b) als neue Datensätze in die Datenbank schreiben 12. Ist Liste (a) nicht leer, sind Buchungen verschwunden oder modifiziert worden -> Warnung ausgeben und entsprechenden Datensatz in der Datenbank mit einem Flag als inaktiv markieren. Dieses Verfahren hat folgende Eigenschaften: - Es werden keine Annahmen über die Reihenfolge der einzelnen Buchungen eines Tages gemacht. - Es kann ein Zeitfenster von n Tagen als "offen" gelten. Diese Tage werden auch nachträglich noch abgefragt und Änderungen werden erkannt. - Die Datensätze können zusätzliche, vom User gefüllte Felder enthalten, die intakt bleiben, solange die Bank die entsprechende Buchung nicht nachträglich modifiziert. Sollte sie das tun (esoterischer Fall), sind diese Felder wieder leer und die vorherigen Inhalte sind weiterhin in einem als inaktiv markierten Datensatz gespeichert. Freue mich über Gedanken hierzu. Und Vielen Dank für die kompetenten Antworten! Jan |
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-04-22 09:33:59
|
Hallo Jan,
> Auf meine Frage:
> "Ist es möglich, dass für den aktuellen Tag, der ja in der
> HKKAZ-Antwort nicht komplett sein muss bei einer zweite Abfrage
> Umsätze nicht nur am Ende dazu kommen, sondern auch an anderen Stellen
> (zwischen zwei bereits bekannten Umsätzen oder am Anfang z.b.) Sprich:
> kann man sich auf die Reihenfolge innerhalb eines MT904 verlassen?"
>
> antwortet Captain FRAG (Zitat mit freundlicher Genehmigung):
> > die Reihenfolge muss in der Tat nicht chronologisch sein.
>
> Das würde bedeuten, dass zumindest für den "offenen" Buchungstag
> tatsächlich theoretisch Einträge ZWISCHEN oder VOR bereits bekannten
> Einträgen auftauchen können.
In der Tat bin ich mir beim "aktuellen" Tag da auch nicht ganz sicher.
Mehr dazu siehe unten.
> Mir ist aufgefallen, dass bei comdirect die instrefs eines Tages stets
> kleiner als die des Folgetages sind, innerhalb eines Buchungstages
> jedoch *absteigen*. Ich werte das als Indiz, dass bei comdirect die
> Sortierung innerhalb eines Buchungstages absteigend chronologisch ist,
> neue Buchungen also *oben* auftauchen. (ein Experiment zur Bestätigung
> dieser Annahme steht noch aus)
Bei meiner Bank (Sparkasse) beginnen die INSTREFs an jedem Buchungstag
erneut bei 1, die Buchungen innerhalb eines Tages haben aufsteigende
Werte (also immer von 1..n)
> Dass Du dieses Verfahren seit 2004 ohne Probleme einsetzt, stimmt mich
> natürlich sehr zuversichtlich!
Das tatsächlich von mir verwendete Verfahren weicht in einem kleinen
Punkt von meiner Beschreibung aus der letzten Mail ab (markiert mit *):
1) In der DB wird nach dem höchsten bereits bekannten Buchungsdatum
gesucht (im Beispiel 21.4. mit zwei Buchungen).
2) Es wird eine Umsatzabfrage mit 21.4. als Start- und HEUTE als
End-Datum gemacht.
3*) Aus der DB werden alle Einträge mit dem 21.4. GELÖSCHT
(es werden also T3 und T4 gelöscht)
4*) Aus den empfangenen Kontoauszügen werden nun ALLE Einträge ab dem
21.4. neu importiert (so dass T3-T6 importiert werden).
Damit werde ich (wahrscheinlich mehr oder weniger aus Versehen) dem
Umstand gerecht, den CaptainFRAG geschildert hat - dass nämlich relativ
"frische" Kontoauszüge auch durchaus noch Änderungen unterworfen sein
können.
Allerdings mache ich mit diesem Algorithmus auch eine Annahme, die Du
ebenfalls schon als Frage formuliert hast:
> "Da stellt sich die nächste Frage: Ab wann kann ein Buchungstag als
> unveränderlich angesehen werden? Reicht es, das sein Datum in der
> Vergangenheit liegt (maximal gestern), bekommt man also schon 1
> Sekunde nach Mitternacht garantiert den unveränderlichen gestrigen
> Buchungstag?
Die Antwort auf diese Frage weiß ich nicht sicher. In meiner
Implementierung gehe ich offensichtlich davon aus, dass nur der LETZTE
BUCHUNGSTAG AUS DEN KONTOAUSZÜGEN (muss nicht identisch mit HEUTE sein)
noch veränderlich ist.
Da die von mir verwendete Vorgehensweise jedoch schon so lange
problemlos funktioniert, gehe ich mal davon aus, dass das entweder
generell OK ist oder dass es zumindest mit meiner Bank immer
funktioniert ;-)
> Zur Zeit favorisiere ich folgendes Verfahren, das mir recht robust
> erscheint:
> ...
Klingt gut ;-)
Dein Algorithmus unterscheidet sich damit im wesentlichen von dem in
wallstreet9 implementierten Algorithmus dadurch, dass er nicht nur
den "letzten" Buchungstag komplett neu synchronisiert, sondern dass
dieses Zeitfenster konfigurierbar ist (bei Dir mit "n" bezeichnet).
Außerdem ist Deine Art der Synchronisierung (Abgleich von Buchungen)
nicht so plump wie bei mir (einfach alles löschen und empfangene Daten
neu importieren) ;-)
Da wahrscheinlich relativ wenige Leute außer mir wallstreet9 benutzen
(es ist mehr oder weniger nur eine Beispielanwendung), ist es schwierig
zu sagen, ob das auch bei anderen "immer funktioniert".
Ich glaube, Olaf hat in Hibiscus einen ähnlichen Algorithmus
implementiert, und Hibiscus wird von wesentlich mehr Leuten verwendet.
Vllt. kann er ja mal kurz was dazu sagen (Wie ist der Algorithmus? Sind
Synchronisierungsprobleme in dieser Richtung bekannt?)
Grüße
-stefan-
|
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-04-22 09:42:21
|
> > Auf meine Frage: > > ... > > antwortet Captain FRAG (Zitat mit freundlicher Genehmigung): > > ... Da ich Captain FRAG nur aus dem Onlinebanking-Forum kenne, nehme ich an, Du hast dort gefragt. Finde aber den Thread nicht. Könntest Du mal den Link dahin angeben bitte? Grüße -stefan- |
|
From: Martin P. <aqu...@gm...> - 2009-04-22 16:15:12
|
Moin, On Mittwoch, 22. April 2009, Jan Bölsche wrote: [...] > Zur Zeit favorisiere ich folgendes Verfahren, das mir recht robust > erscheint: [...] In QBankManager - wo wir ja mit dem gleichen Problem zu kaempfen haben - loese ich das bisher so: 1. Frage einen beliebigen Zeitraum ab 2. betrachte die empfangenen Daten: fuer jeden Tag, fuer den wir Daten empfangen haben, tue dies: 2.a: lade alle Umsaetze dieses Tages aus der DB zur Referenz 2.b: fuer jeden abgeholten Umsatz dieses Tages: Zaehle, wie oft dieser Umsatz in der DB fuer diesen Tag schon vorhanden ist 2.c: zaehle, wie oft dieser Umsatz in den abgeholten Daten fuer diesen Tag vorhanden ist 2.d: vergleiche beide Zaehler. Hier gibt es dann theoretisch 3 Moeglichkeiten: a) die Anzahl der passenden Umsaetze in der DB fuer diesen Tag ist kleiner als die der abgeholten, gleichen Umsaetze b) die Anzahl in beiden Stapeln ist gleich c) die Anzahl der passenden Umsaetze in der DB fuer diesen Tag ist groesser als die der abgeholten, gleichen Umsaetze Im Fall a) wird der betrachtete abgeholte Umsatz einfach hinzugefuegt. Im Fall b) wird der betrachtete abgeholte Umsatz ignoriert (weil er ja schon vorhanden ist) Und der Fall c) kann eigentlich gar nicht auftreten, denn das wuerde bedeuten, dass die Bank in einer frueheren Message einen Umsatz gemeldet hat, den sie jetzt in der aktuellen Message nicht mehr sendet, d.h. bei der Bank ist ein Umsatz verschwunden. Dieses Verfahren ist nach meiner Erfahrung wasserdicht und wird inzwischen seit mehreren Jahren erfolgreich verwendet. Es hat die folgenden positiven Eigenschaften: 1) es macht keine Annahmen ueber den Zeitraum, den man abruft. D.h. man kann es fuer jeden Zeitraum verwenden, funktioniert insbesondere auch fuer den aktuellen Tag 2) es fuegt zuverlaessig solche Eintraege hinzu, die wirklich mehrfach aufgetreten sind, die also wirklich mehrere gleiche Buchungen darstellen. 3) es macht keine Annahmen ueber die Reihenfolge der Umsaetze 4) es entfernt zuverlaessig Duplikate Dieser Algorithmus fusst auf der Annahme, dass die Bank keine Umsaetze verschwinden laesst. D.h. wenn eine Buchung bei einem Abruf auftaucht, muss sie auch im naechsten Abruf fuer den gleichen Zeitraum auftauchen. Bei allen Absonderlichkeiten mancher Server-Implementierungen: An diese Regel halten sich bisher offensichtlich wirklich alle Banken ;-) Der Algo ist aber auch fuer den Fall gewappnet, dass sich ein Server nicht daran haelt: Dann naemlich gibt z.B. QBankManager eine Warnung aus. Gruss Martin -- "Things are only impossible until they're not" Martin Preuss - http://www2.aquamaniac.de/ AqBanking - http://www.aqbanking.de/ LibChipcard - http://www.libchipcard.de/ |
|
From: Jan B. <ja...@mu...> - 2009-04-22 16:40:11
|
Hallo Martin, vielen Dank für diese Information. Ich glaube, Dein Verfahren ist funktional äquivalent zu meinem Vorschlag. Ich zähle die Einträge nicht sondern verwende eine temporäre Liste. Das Ergebnis ist aber identisch. Schön daran ist auch, dass man es erkennt, falls die Bank tatsächlich Einträge löscht oder ändert. Schönen Abend! Jan On 22.04.2009, at 18:14, Martin Preuss wrote: > Moin, > > On Mittwoch, 22. April 2009, Jan Bölsche wrote: > [...] >> Zur Zeit favorisiere ich folgendes Verfahren, das mir recht robust >> erscheint: > [...] > > In QBankManager - wo wir ja mit dem gleichen Problem zu kaempfen > haben - loese > ich das bisher so: > > 1. Frage einen beliebigen Zeitraum ab > > 2. betrachte die empfangenen Daten: fuer jeden Tag, fuer den wir Daten > empfangen haben, tue dies: > 2.a: lade alle Umsaetze dieses Tages aus der DB zur Referenz > 2.b: fuer jeden abgeholten Umsatz dieses Tages: Zaehle, wie oft > dieser Umsatz > in der DB fuer diesen Tag schon vorhanden ist > 2.c: zaehle, wie oft dieser Umsatz in den abgeholten Daten fuer > diesen Tag > vorhanden ist > 2.d: vergleiche beide Zaehler. Hier gibt es dann theoretisch 3 > Moeglichkeiten: > a) die Anzahl der passenden Umsaetze in der DB fuer diesen Tag ist > kleiner als > die der abgeholten, gleichen Umsaetze > b) die Anzahl in beiden Stapeln ist gleich > c) die Anzahl der passenden Umsaetze in der DB fuer diesen Tag ist > groesser > als die der abgeholten, gleichen Umsaetze > > Im Fall a) wird der betrachtete abgeholte Umsatz einfach hinzugefuegt. > Im Fall b) wird der betrachtete abgeholte Umsatz ignoriert (weil er > ja schon > vorhanden ist) > Und der Fall c) kann eigentlich gar nicht auftreten, denn das wuerde > bedeuten, > dass die Bank in einer frueheren Message einen Umsatz gemeldet hat, > den sie > jetzt in der aktuellen Message nicht mehr sendet, d.h. bei der Bank > ist ein > Umsatz verschwunden. > > Dieses Verfahren ist nach meiner Erfahrung wasserdicht und wird > inzwischen > seit mehreren Jahren erfolgreich verwendet. > > Es hat die folgenden positiven Eigenschaften: > 1) es macht keine Annahmen ueber den Zeitraum, den man abruft. D.h. > man kann > es fuer jeden Zeitraum verwenden, funktioniert insbesondere auch > fuer den > aktuellen Tag > 2) es fuegt zuverlaessig solche Eintraege hinzu, die wirklich mehrfach > aufgetreten sind, die also wirklich mehrere gleiche Buchungen > darstellen. > 3) es macht keine Annahmen ueber die Reihenfolge der Umsaetze > 4) es entfernt zuverlaessig Duplikate > > Dieser Algorithmus fusst auf der Annahme, dass die Bank keine Umsaetze > verschwinden laesst. D.h. wenn eine Buchung bei einem Abruf > auftaucht, muss > sie auch im naechsten Abruf fuer den gleichen Zeitraum auftauchen. > > Bei allen Absonderlichkeiten mancher Server-Implementierungen: An > diese Regel > halten sich bisher offensichtlich wirklich alle Banken ;-) > > Der Algo ist aber auch fuer den Fall gewappnet, dass sich ein Server > nicht > daran haelt: Dann naemlich gibt z.B. QBankManager eine Warnung aus. > > > Gruss > Martin > > > -- > "Things are only impossible until they're not" > > Martin Preuss - http://www2.aquamaniac.de/ > AqBanking - http://www.aqbanking.de/ > LibChipcard - http://www.libchipcard.de/ > |
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-04-22 16:52:40
|
Hallo Martin, dank auch für Dein Feedback ;-) In Anbetracht der Tatsache, dass meine ursprünglichen Annahmen von 2004 wohl doch nicht immer alle erfüllt werden, sollte ich wohl auch meinen Algorithmus noch ein klein wenig anpassen ;-) Jedenfalls erscheint mir eine auf diesem Prinzip funktionierende Vorgehensweise EINIGERMAßEN zuverlässig. Das einzige Problem, was Du damit nicht abfangen kannst, ist das, was Olaf erwähnt hat. An einem Tag kommen bei der Buchung X die Verwendungs- zweckzeilen mit "äöü", am nächsten Tag enthält die SELBE Buchung statt dessen auf einmal ae, oe, ue. Mit Deinem Algorithmus würde diese Buchung erkannt werden als "neu, habe ich noch nicht" und zur Sammlung der Buchungen hinzugefügt werden, wobei die "alte" Buchung mit "äöü" auf einmal nicht mehr in den Kontoauszügen erscheint und somit die von Dir genannte Warnung aus- gegeben wird... Was passiert eigentlich in diesem Fall (bei Dir Fall (c)): wird dann NUR diese Warnung ausgegeben, oder wird diese auf einmal scheinbar fehlende Buchung aus den lokalen Buchungsdatensätzen gelöscht? In dem Beispiel von Olaf wäre letzteres natürlich richtig (weil die "äöü"- Buchung durch eine "aeoeue"-Buchung "ersetzt" wurde). In einige Fällen kann es aber sicherlich auch sein, dass die auf einmal nicht mehr in den Kontoauszügen zurückgemeldete Buchung tatsächlich existiert und somit in den lokalen Datenbeständen erhalten bleiben sollte... Grüße -stefan- On Wed, 2009-04-22 at 18:14 +0200, Martin Preuss wrote: > Moin, > > On Mittwoch, 22. April 2009, Jan Bölsche wrote: > [...] > > Zur Zeit favorisiere ich folgendes Verfahren, das mir recht robust > > erscheint: > [...] > > In QBankManager - wo wir ja mit dem gleichen Problem zu kaempfen haben - loese > ich das bisher so: > > 1. Frage einen beliebigen Zeitraum ab > > 2. betrachte die empfangenen Daten: fuer jeden Tag, fuer den wir Daten > empfangen haben, tue dies: > 2.a: lade alle Umsaetze dieses Tages aus der DB zur Referenz > 2.b: fuer jeden abgeholten Umsatz dieses Tages: Zaehle, wie oft dieser Umsatz > in der DB fuer diesen Tag schon vorhanden ist > 2.c: zaehle, wie oft dieser Umsatz in den abgeholten Daten fuer diesen Tag > vorhanden ist > 2.d: vergleiche beide Zaehler. Hier gibt es dann theoretisch 3 Moeglichkeiten: > a) die Anzahl der passenden Umsaetze in der DB fuer diesen Tag ist kleiner als > die der abgeholten, gleichen Umsaetze > b) die Anzahl in beiden Stapeln ist gleich > c) die Anzahl der passenden Umsaetze in der DB fuer diesen Tag ist groesser > als die der abgeholten, gleichen Umsaetze > > Im Fall a) wird der betrachtete abgeholte Umsatz einfach hinzugefuegt. > Im Fall b) wird der betrachtete abgeholte Umsatz ignoriert (weil er ja schon > vorhanden ist) > Und der Fall c) kann eigentlich gar nicht auftreten, denn das wuerde bedeuten, > dass die Bank in einer frueheren Message einen Umsatz gemeldet hat, den sie > jetzt in der aktuellen Message nicht mehr sendet, d.h. bei der Bank ist ein > Umsatz verschwunden. > > Dieses Verfahren ist nach meiner Erfahrung wasserdicht und wird inzwischen > seit mehreren Jahren erfolgreich verwendet. > > Es hat die folgenden positiven Eigenschaften: > 1) es macht keine Annahmen ueber den Zeitraum, den man abruft. D.h. man kann > es fuer jeden Zeitraum verwenden, funktioniert insbesondere auch fuer den > aktuellen Tag > 2) es fuegt zuverlaessig solche Eintraege hinzu, die wirklich mehrfach > aufgetreten sind, die also wirklich mehrere gleiche Buchungen darstellen. > 3) es macht keine Annahmen ueber die Reihenfolge der Umsaetze > 4) es entfernt zuverlaessig Duplikate > > Dieser Algorithmus fusst auf der Annahme, dass die Bank keine Umsaetze > verschwinden laesst. D.h. wenn eine Buchung bei einem Abruf auftaucht, muss > sie auch im naechsten Abruf fuer den gleichen Zeitraum auftauchen. > > Bei allen Absonderlichkeiten mancher Server-Implementierungen: An diese Regel > halten sich bisher offensichtlich wirklich alle Banken ;-) > > Der Algo ist aber auch fuer den Fall gewappnet, dass sich ein Server nicht > daran haelt: Dann naemlich gibt z.B. QBankManager eine Warnung aus. > > > Gruss > Martin > > |
|
From: Martin P. <aqu...@gm...> - 2009-04-22 17:12:42
|
Moin, On Mittwoch, 22. April 2009, HBCI4Java (Stefan Palme) wrote: [...] > Das einzige Problem, was Du damit nicht abfangen kannst, ist das, was > Olaf erwähnt hat. An einem Tag kommen bei der Buchung X die Verwendungs- > zweckzeilen mit "äöü", am nächsten Tag enthält die SELBE Buchung statt > dessen auf einmal ae, oe, ue. [...] Das stimmt, allerdings ist dieser Fall hoechst selten. Allerdings ist mir dieser Fall auch schon untergekommen, und zwar ueber die Jahre mehrmals: Naemlich dann, wenn die Bank die Software entsprechend geaendert hatte und ploetzlich andere Umsatzinfos gesendet hat (also mit besagten Aenderungen bei den Umlauten etc). [...] > Was passiert eigentlich in diesem Fall (bei Dir Fall (c)): wird dann > NUR diese Warnung ausgegeben, oder wird diese auf einmal scheinbar > fehlende Buchung aus den lokalen Buchungsdatensätzen gelöscht? In dem > Beispiel von Olaf wäre letzteres natürlich richtig (weil die "äöü"- > Buchung durch eine "aeoeue"-Buchung "ersetzt" wurde). [...] Bestehende Umsaetze werden bei mir niemals entfernt. Der Benutzer hat ja eventuell schon Informationen mit dem gespeicherten Umsatz verbunden, d.h. diese Info einfach zu loeschen faellt weg (sie kann ja auch auf anderem Weg erzeugt worden sein, z.B. durch einen Dateiimport). In einem solchen Fall entstehen also bei mir tatsaechlich Duplikate. Ich nehme das momentan noch hin, weil man solche sehr, sehr selten auftretende Duplikate zumindest in QBankManager recht einfach entfernen lassen kann. Man koennte natuerlich auch die Vergleiche etwas laxer handhaben, so dass man beispielsweise den Verwendungszweck nicht so scharf vergleicht. Das ginge dann, wenn man z.B. immer die Kontoverbindungen des Zahlers im MT940 haette. Leider gibt es aber wie Du ja auch weisst immer noch Banken, die nur extrem rudimentaere Umsatzdaten senden, also insbesondere ohne Kontoverbindungen. In diesem Fall sind die einzigen verwertbaren Daten fast ausschliesslich im Verwendungszweck zu finden :-( BTW: Wenn ich QBankManager nach Duplikaten suchen lasse, vergleiche ich die Verwendungszwecke nicht direkt, sondern mache stattdessen Fuzzy-Vergleiche mit einem einstellbaren Schwellwert. Soetwas in der Art koennte man natuerlich auch beim Import machen, aber diese Methode ist deutlich weniger praezise als der Algo, den QBankManager derzeit fuer den Import verwendet. Bisher ist es mir in den Jahren aber erst zweimal vorgekommen, dass die Bank die Umsatzdaten hinterruecks geaendert hat. Gruss Martin -- "Things are only impossible until they're not" Martin Preuss - http://www2.aquamaniac.de/ AqBanking - http://www.aqbanking.de/ LibChipcard - http://www.libchipcard.de/ |
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-04-22 17:46:47
|
> > Das einzige Problem, was Du damit nicht abfangen kannst, ist das, was
> > Olaf erwähnt hat. An einem Tag kommen bei der Buchung X die Verwendungs-
> > zweckzeilen mit "äöü", am nächsten Tag enthält die SELBE Buchung statt
> > dessen auf einmal ae, oe, ue.
> Das stimmt, allerdings ist dieser Fall hoechst selten.
Allerdings - ähnlich wie alle anderen "Ausrutscher" der Banken bzw.
selten vorkommende UseCases (wer hat schon mehrmals am Tag exakt
gleiche Buchungen).
Aber "wasserdicht" ist Dein Algorithmus damit auch nicht ;-)
> Bestehende Umsaetze werden bei mir niemals entfernt. Der Benutzer hat ja
> eventuell schon Informationen mit dem gespeicherten Umsatz verbunden, d.h.
> diese Info einfach zu loeschen faellt weg (sie kann ja auch auf anderem Weg
> erzeugt worden sein, z.B. durch einen Dateiimport).
Genau - das ist das eigentliche Kernproblem. Dass man schon abgeholte
Umsätze evtl. anderweitig referenziert, dieser Umsatz in neu abgeholten
Kontoauszügen auf einmal nicht mehr zu finden ist und die Anwendung dann
nicht weiß, welcher evtl. neue Umsatzeintrag diesem alten entspricht
(denn dass eine Transaktion tatsächlich mal ohne Ersatz verschwindet
habe ich wirklich noch NIE gehört).
> Man koennte natuerlich auch die Vergleiche etwas laxer handhaben, so dass man
> beispielsweise den Verwendungszweck nicht so scharf vergleicht.
Kommt drauf an, wie man diese "Unschärfe" implementiert. Wenn ich z.B.
massenweise Auszahlungen an das selbe Konto von 1 cent mache und im
Verwendungszweck immer nur einen Zähler erhöhe, so dass sich zwischen
diesen Buchungen praktisch NUR der Verwendungszweck unterscheidet, und
auch nur um einen Zählerwert ("Auszahlung #001", "Auszahlung #002"),
dann wäre das schon schwierig - außer man beschränkt die Unschärfe
auf Buchstaben und/oder Sonderzeichen - dann wären aber zwei
Überweisungen mit Rechnungsnummer "KA12345" und "KB12345" an das
selbe Konto mit selben Betrag auch "identisch" - obwohl sie in
Wirklichkeit zwei tatsächlich verschiedene Buchungen sind.
Besser wäre dann sicherlich eine Art "Normalisierung" in der Art, dass
man sagt, dass alle Umlaute prinzipiell nach "ae oe ue" konvertiert
werden, dass sonderzeichen komplett rausgelöscht werden usw. - und erst
diese normalisierten Verwendungszwecke dann verglichen werden. Aber
auch das hat seine Tücken...
Wie schon gesagt - man kann da beliebig viel Aufwand betreiben und
trotzdem nicht jeden Fall abdecken :-)
Viiiiel einfach wäre es, wenn die Bank eine eindeutige ID für jede
Buchung verwalten würde (tut sie intern bestimmt) und diese ID auch
über HBCI kommunizierbar wäre (geht wahrscheinlich deshalb nicht, weil
SWIFT-MT940 halt kein Feld dafür vorsieht).
> BTW: Wenn ich QBankManager nach Duplikaten suchen lasse, vergleiche ich die
> Verwendungszwecke nicht direkt, sondern mache stattdessen Fuzzy-Vergleiche mit
> einem einstellbaren Schwellwert.
Siehe oben - das kann auch kräftig nach hinten losgehen. Hängt also
immer von den konkreten Daten ab - und einem Nutzer auch noch die
Auswahl zu ermöglichen, ob er Fuzzy-Modul #1, #2 oder #3 verwenden
will, wäre schon irgendwie zuviel verlangt vom armen Anwender :)
Grüße
-stefan-
|
|
From: Martin P. <aqu...@gm...> - 2009-04-22 18:12:56
|
Moin,
On Mittwoch, 22. April 2009, HBCI4Java (Stefan Palme) wrote:
[...]
> Allerdings - ähnlich wie alle anderen "Ausrutscher" der Banken bzw.
> selten vorkommende UseCases (wer hat schon mehrmals am Tag exakt
> gleiche Buchungen).
>
> Aber "wasserdicht" ist Dein Algorithmus damit auch nicht ;-)
[...]
Du kannst immer Faelle finden, auf die gar kein Vorgehen passt. Das
schlimmste, was Dir allerdings in diesem Fall mit meinem Algo passieren kann,
ist, dass Duplikate entstehen, vor denen Du auch noch gewarnt wirst.
Wenn man dann noch beruecksichtigt, dass es ohnehin schon selten ist, dass
mehrere gleiche Umsaetze an einem Tag auftauchen, und es noch seltener ist,
dass die Bank das Format ihrer Umsaetze aendert, kann man schon sagen, dass
der Algo wasserdicht ist ;-)
Zumindest aber Spritzwasser-geschuetzt ;-)
[...]
> > Man koennte natuerlich auch die Vergleiche etwas laxer handhaben, so dass
> > man beispielsweise den Verwendungszweck nicht so scharf vergleicht.
>
> Kommt drauf an, wie man diese "Unschärfe" implementiert. Wenn ich z.B.
> massenweise Auszahlungen an das selbe Konto von 1 cent mache und im
[...]
Ich habe ja schon geschrieben, dass dies unsicherer ist als das, was ich
bisher mache. Und weil solche Faelle sehr selten sind, ist der Aufwand fuer
den Benutzer so wie es jetzt ist deutlich geringer als mit einer Unschaerfe
(bei der es immer mehr falsch positive Faelle gibt als mit der bisherigen
Methode).
[...]
> auch nur um einen Zählerwert ("Auszahlung #001", "Auszahlung #002"),
[...]
Das ist noch einer der einfacheren Faelle: Hier tauchen jeweils 2 "Woerter"
auf, von denen eines 100% gleich ist und das andere 75% (natuerlich mit
abnehmender Aehnlichkeit beim 2. Wort, wenn der Zaehler um mehr als eine
Stelle steigt).
Aber der von Dir geschilderte Fall, dass wilde Kombinationen aus Buchstaben
und Zahlen im Verwendungszweck auftauchen (z.B. Rechnungsnummern, und das ist
ja nicht selten), ist halt damit ueberhaupt nicht zu greifen.
Da muesste man dann noch weitere Informationen dazunehmen, im Idealfall z.B.
die Kontoverbindung der Gegenseite. Aber genau die wird von manchen Banken
halt nicht geliefert, also kann man dieses Vorgehen auch nicht
verallgemeinern.
[...]
> Viiiiel einfach wäre es, wenn die Bank eine eindeutige ID für jede
> Buchung verwalten würde (tut sie intern bestimmt) und diese ID auch
> über HBCI kommunizierbar wäre (geht wahrscheinlich deshalb nicht, weil
> SWIFT-MT940 halt kein Feld dafür vorsieht).
[...]
Naja, gut, man koennte dafuer aber ja einfach eines der bestehenden aber meist
ungenutzten Felder verwenden, oder man definiert einfach ein weiteres ?xx-
Element im Tag :86: oder so... Also moeglich waere das auf jeden Fall.
Mich aergert aber vor allem, dass es bis in die neuesten Versionen der
HBCI-/FinTS-Specs scheinbar nicht moeglich war, sich darauf zu verstaendigen,
ein solches Feld - wie auch immer - einzufuehren.
Man einigt sich ja auch auf immer komplexere Pin-TAN-Verfahren, da muesste
doch auch Raum fuer eine so wirklich *essentielle* Forderung sein...
Letztlich muss man sonst sagen: Fuer eine wirklich sichere Automatisierung ist
HBCI nicht geeignet. EBICS dann aber uebrigends auch nicht, denn auch hier
kommt SWIFT MT940 zum Einsatz... Und das kann ja wohl nicht das letzte Wort
sein...
Gruss
Martin
--
"Things are only impossible until they're not"
Martin Preuss - http://www2.aquamaniac.de/
AqBanking - http://www.aqbanking.de/
LibChipcard - http://www.libchipcard.de/
|
|
From: HBCI4Java (S. Palme) <hbc...@ka...> - 2009-04-22 20:44:47
|
> Mich aergert aber vor allem, dass es bis in die neuesten Versionen der
> HBCI-/FinTS-Specs scheinbar nicht moeglich war, sich darauf zu verstaendigen,
> ein solches Feld - wie auch immer - einzufuehren.
>
> Man einigt sich ja auch auf immer komplexere Pin-TAN-Verfahren, da muesste
> doch auch Raum fuer eine so wirklich *essentielle* Forderung sein...
>
> Letztlich muss man sonst sagen: Fuer eine wirklich sichere Automatisierung ist
> HBCI nicht geeignet. EBICS dann aber uebrigends auch nicht, denn auch hier
> kommt SWIFT MT940 zum Einsatz... Und das kann ja wohl nicht das letzte Wort
> sein...
Ich denke mal, Du antwortest Dir hier selbst. Das Problem liegt
nicht in der HBCI-Spezifikation - so komplex die auch werden mag, hier
werden ja die Kontoauszüge nur als binäre, nicht "interpretierte"
Daten in einem quasi-proprietären Format - nämlich SWIFT-MT940
- transportiert.
Das Problem wäre also das MT940-Format - und das wird an so vielen
anderen Stellen (neben HBCI) auch noch verwendet, dass eine
entsprechende Änderung/Erweiterung wohl nicht zu erwarten ist...
Eine Möglichkeit wäre evtl, in die Antwortsegmente zu einer Umsatz-
anfrage nicht die binären MT940-Daten einzustellen, sondern "richtige"
HBCI-Segmente, wobei z.B. jeweils ein "HITRA"-Segment (= Transaktion)
genau EINE Buchung beschreibt, jeweils mit eigenen DEGs für die
beteiligten Konten, Betrag, Verwendungszwecke etc - also alles schön
in HBCI-Syntax.
Ich vermute aber, dass das
a) evtl. die Nachrichtengröße sprengen könnte (obwohl - soviel größer
als MT940-Datenblöcke wäre ein äquivalentes Segment auch nicht),
und/oder
b) <böse-mode> die HBCI-Spez-Macher und kommerziellen Server-Implementierer
keine Lust haben, so was zu basteln </böse-mode> - vllt. sollte ich
im HBCI4Java-Demo-Server mal so einen proprietären GV implementieren,
nur um zu zeigen, dass es technisch geht...
Andere (technische) Gründe für das Fehlen von "sauberen" HBCI-Segmenten
für Kontoauszugsdaten sehe ich im Moment irgendwie nicht - aber möglicherweise
fehlt mir da auch der Durchblick in der Bankenwelt. Letztendlich wird
die offizielle Begründung für diesen Mangel wohl lauten, dass das ganze
"historisch gewachsen" ist und die MT940-Daten niemals direkt für die
Verarbeitung durch Kundensysteme gedacht waren...
Wie auch immer - solange wir keine eigene groooße Bank betreiben und/oder
eine Software herstellen, die Geld kostet und von Banken gekauft wird, haben
wir da wohl auch kein Mitspracherecht - wie überall stehen hier wohl
kommerzielle Interessen über technisch sinnvollen Lösungen.
Und bevor ich jetzt noch mehr Frust bekomme hör ich lieber auf, weiter
darüber nachzudenken :-)
-stefan-
|
|
From: Martin P. <aqu...@gm...> - 2009-04-22 21:12:16
|
On Mittwoch, 22. April 2009, HBCI4Java (Stefan Palme) wrote: [...] > Ich denke mal, Du antwortest Dir hier selbst. Das Problem liegt > nicht in der HBCI-Spezifikation - so komplex die auch werden mag, hier > werden ja die Kontoauszüge nur als binäre, nicht "interpretierte" > Daten in einem quasi-proprietären Format - nämlich SWIFT-MT940 > - transportiert. [...] Ist mir ja klar. Allerdings: An anderer Stelle hat man sich dazu durchgerungen, ein eigenes Format zu verwenden, naemlich bei den Zahlungsauftraegen (und bei Dauerauftraegen. Und bei terminierten Auftraegen). In diesem Fall werden zwar fuer Sammelauftraege immer noch DTAUS-Daten verwendet (so wie halt SWIFT MT940 beim Umsatzabruf), aber fuer Einzelauftraege gibt es eigene Segmente... Soll heissen: Voellig unmoeglich kann es nicht sein, HBCI-eigene Formate zu verwenden... Und fuer SEPA-Auftraege stellt man ja auch wieder andere Daten ein... Es kann ja keine unloesbare Aufgabe fuer Entwickler von Bankservern sein, hier Daten in einem anderen Format als MT940 zu versenden... Von daher verstehe ich nicht, wo die Blockade eigentlich liegt. Oder kann da eventuell ein Kenner der Banken-IT-Welt naeheres zu sagen? Aber ich bin hier aehnlich pessimistisch wie Du: Da wir uns schon so lange mit dem Problem der fehlenden ID in Umsatzdaten herumschlagen muessen - und sicher nicht nur wir - und es bis heute keine Loesung gibt, vermute ich auch nicht, dass es in naher Zukunft eine geben wird... Gruss Martin -- "Things are only impossible until they're not" Martin Preuss - http://www2.aquamaniac.de/ AqBanking - http://www.aqbanking.de/ LibChipcard - http://www.libchipcard.de/ |