Tankstellenmarke als eigenes Feld, Belegfelder in der App richtig zugeordnet
Die Marke steht auf jedem Beleg, war aber nirgends gespeichert: der Parser erkennt sie seit dem 16.08.2026, faltete sie aber nur in station_name. Fuer jeden Beleg, den eine aeltere Fassung eingelesen hat, blieb dort der Betreibername stehen und die Marke war danach nicht mehr zu holen. - shell_beleg_parser: station_brand als eigenes Feld aus beiden Parserwegen, dazu marke_aus_text()/marke_aus_pdf() - sie lesen nur den Belegkopf und haengen nicht am vollstaendigen Einlesen. - belege.marken_nachtragen(): traegt die Marke einmal beim Start aus der abgelegten Belegdatei nach. Nur wo das Feld gar nicht vorkommt und die Datei liegt; ein einmal eingetragenes Feld wird nie ueberschrieben. - Panel und App: die gespeicherte Marke geht vor, geraten wird nur, wo keine da ist. Ein Teil, der fuer sich genommen eine Kopfmarke ist, taugt zudem nie als Ort. Dazu Punkt 5 der Meldung vom 04.09.2026: ein eingelesener Beleg fuellte nur Datum und Uhrzeit. Der Parser las ihn immer vollstaendig - die App fragte liter/kosten/station/ersparnis/kraftstoff ab, veroeffentlicht werden aber die Namen des Belegs (liters/fuel_total_eur/station_name/discount/fuel_type). Uebereingestimmt hat allein ts. Die Zuordnung steht jetzt als belegFormularwerte() in daten/belegentwurf.ts und wird gegen die echte Nutzlast dieses Belegs geprueft. tsc sauber, 258 Tests (die drei neuen Marken-Tests gegen den alten Stand als scheiternd nachgewiesen), vite build sauber, Panel als Modul geparst, Parser-Suite 11 Tests gegen elf echte Belege. Panel und App liefern fuer elf Faelle byteweise dasselbe. Live in audi_ha_test auf 2026.9.4.21 ohne Traceback: Uebersicht "Shell, Nuernberger Str., Ansbach", Einzelbeleg zweizeilig mit Marke, und der echte geteilte Beleg fuellt durchs Backend das ganze Formular.
This commit is contained in:
@@ -10726,3 +10726,132 @@ Beleg liest sich `Nürnberger Str., Ansbach`, und der Einzelbeleg zeigt
|
||||
**Nicht geprueft, weil es ohne Mac nicht geht:** dass die Registrierung auf dem
|
||||
Geraet greift. Das zeigt erst der naechste Xcode-Lauf - und der bricht jetzt ab,
|
||||
wenn sie fehlt.
|
||||
|
||||
## CN. Die Marke stand auf jedem Beleg - und war nirgends gespeichert. Dazu: warum ein eingelesener Beleg nur Datum und Uhrzeit fuellte (2026.9.4.21)
|
||||
|
||||
### 1. "In einem Beleg soll die Marke, falls vorhanden, erkannt werden"
|
||||
|
||||
Der Einzelbeleg vom 10.11.2025 las sich nach Abschnitt CM
|
||||
`Nürnberger Str. 74` / `91522 Ansbach` - richtig zerlegt, aber ohne Marke. Die
|
||||
Frage war also nicht, ob die Zerlegung stimmt, sondern woher die Marke kommen
|
||||
soll.
|
||||
|
||||
**Sie steht auf dem Beleg.** Nachgesehen statt vermutet - die erste Zeile jedes
|
||||
abgelegten PDFs:
|
||||
|
||||
| Beleg | Zeile 0 | gespeicherter `station_name` |
|
||||
|---|---|---|
|
||||
| e-receipt9 | `Shell-Station` | `Hermann Mogler Mineralölg. GmbH` |
|
||||
| e-receipt5 | `Shell Station` | `TC Sengül GmbH` |
|
||||
| e-receipt | `SHELL STATION` | `A. Zrenner GmbH` |
|
||||
| receipt_2026… | `SHELL TANKSTELLE, 6450 SÖLDEN` | `Shell, SÖLDEN` |
|
||||
|
||||
Der Parser **erkennt** die Marke seit dem 16.08.2026 (`_marke()`, nur im
|
||||
Belegkopf gesucht) - er hat sie aber nur in den Anzeigenamen gefaltet
|
||||
(`_tankstelle()`). Fuer jeden Beleg, den eine aeltere Fassung eingelesen hat,
|
||||
blieb dort der Betreibername stehen, und die Marke war danach **nirgends mehr
|
||||
zu holen**. Ein Feld, das nur als Nebenprodukt einer Zeichenkette existiert,
|
||||
ist kein Feld.
|
||||
|
||||
**Jetzt eigenes Feld** `station_brand`, aus beiden Parser-Wegen. Dazu zwei
|
||||
oeffentliche Funktionen: `marke_aus_text()` und `marke_aus_pdf()` - sie lesen
|
||||
nur den Kopf und haengen damit **nicht** am vollstaendigen Einlesen. Ein Beleg,
|
||||
an dem beide Parser scheitern wuerden, gibt seine Marke trotzdem her.
|
||||
|
||||
**Das Nachtragen** (`belege.marken_nachtragen`) laeuft einmal beim Start, an
|
||||
genau der Stelle, die dafuer schon da war (`_nach_start`, direkt hinter
|
||||
`screening.durchfuehren` - deren Kommentar beschreibt woertlich diesen Fall:
|
||||
"was ihre neuen Felder nachtragen koennen, soll nicht bis zur naechsten Fahrt
|
||||
warten"). Vorsichtig gehalten:
|
||||
|
||||
* angefasst wird nur, wo `station_brand` **gar nicht vorkommt** und die
|
||||
Belegdatei tatsaechlich liegt;
|
||||
* ein einmal eingetragenes Feld - auch mit Wert `None` - wird nie
|
||||
ueberschrieben. Damit ueberschreibt es keine Korrektur von Hand und laeuft
|
||||
nicht bei jedem Start erneut ueber dieselben Belege;
|
||||
* geschrieben wird nur, wenn sich wirklich etwas geaendert hat.
|
||||
|
||||
Am Testcontainer geprueft: erster Start
|
||||
`Tankstellenmarke bei 5 Beleg(en) nachgetragen (Shell)`, zweiter Start **keine
|
||||
Zeile mehr**. Genau die fuenf Vorgaenge mit Belegdatei tragen das Feld.
|
||||
|
||||
**Gespeichert schlaegt geraten.** In beiden Codebasen nimmt
|
||||
`tankstelleTeile(name, adresse, marke)` die gespeicherte Angabe vorweg und
|
||||
faellt nur dort auf `markeErkennen(name)` zurueck, wo keine da ist: bei
|
||||
Vorgaengen ohne Beleg, bei von Hand eingetragenen Tankstellen, und solange das
|
||||
Nachtragen nicht gelaufen ist.
|
||||
|
||||
Beim Nebeneinanderlegen von Panel und App fiel noch etwas auf, das vorher nicht
|
||||
auffallen konnte: steht im Namen eine ANDERE Marke als die gespeicherte, rutschte
|
||||
die aus dem Namen in den **Ort** ("Aral" als Ortsname). Die alte Regel verglich
|
||||
nur mit der gewaehlten Marke. Jetzt gilt: ein Teil, der fuer sich genommen eine
|
||||
Kopfmarke IST, taugt nie als Ort.
|
||||
|
||||
### 2. Punkt 5 aus Abschnitt CM: der Beleg kam mit Datum und Uhrzeit an
|
||||
|
||||
Der Eigentuemer hat den Beleg geschickt (Shell, Richard-Wagner-Str. 9,
|
||||
Ingolstadt, 43,87 l fuer 95,60 EUR) - liegt als
|
||||
`tests/belegparser/belege/geteilt-2026-09-04.pdf`, gitignored.
|
||||
|
||||
**Der Parser liest ihn vollstaendig.** `_parsen()` greift, alle Werte stimmen.
|
||||
Der Fehler sass in der App:
|
||||
|
||||
| App fragte ab | belege.py veroeffentlicht |
|
||||
|---|---|
|
||||
| `liter` | `liters` |
|
||||
| `kosten` | `fuel_total_eur` |
|
||||
| `ersparnis` | `discount` |
|
||||
| `station` | `station_name` |
|
||||
| `kraftstoff` | `fuel_type` |
|
||||
| `km` | *(gar nicht - §7.7 Regel 2)* |
|
||||
| `ts` | `ts` |
|
||||
|
||||
Uebereingestimmt hat **allein `ts`** - deshalb Datum und Uhrzeit und sonst
|
||||
nichts. Der Kraftstoff im Bildschirmfoto war nicht vom Beleg, sondern
|
||||
`KRAFTSTOFFSORTEN[0]`. Das Panel hat die Namen in `tankFelder()` immer richtig
|
||||
benutzt; die App hatte sich ihre eigenen ausgedacht.
|
||||
|
||||
**Meine Einschaetzung in Abschnitt CM war zu kurz gegriffen.** Dass der
|
||||
Teilen-Weg und die Dateiauswahl denselben `belegLesen()` benutzen, stimmte -
|
||||
daraus folgte aber nicht "also nicht die App". Beide Wege waren gleich kaputt.
|
||||
Richtig war nur, es nicht ohne den Beleg zu entscheiden.
|
||||
|
||||
Die Zuordnung steht jetzt als `belegFormularwerte()` in
|
||||
`daten/belegentwurf.ts`, nicht mehr als `if`-Zeilen im Bildschirm - **als
|
||||
Funktion laesst sie sich gegen eine echte Nutzlast pruefen, in den `if`-Zeilen
|
||||
konnte sie es nicht**. Die Nutzlast im Test ist die echte Ausgabe fuer diesen
|
||||
Beleg, kein erfundenes Beispiel.
|
||||
|
||||
Nebenbei mitgenommen: `0` ist ein Wert, kein fehlendes Feld. Ein Beleg mit
|
||||
0,00 EUR Rabatt darf nicht wie "kein Rabatt angegeben" aussehen - deshalb
|
||||
`== null` und nicht `!wert`.
|
||||
|
||||
### Verifiziert
|
||||
|
||||
`tsc --noEmit` sauber, **258 Tests** (von 246: 6 fuer die gespeicherte Marke,
|
||||
6 fuer die Formularwerte), `vite build` sauber, Panel als **Modul** geparst,
|
||||
Parser-Suite **11 Tests** gegen jetzt elf echte Belege.
|
||||
|
||||
**Die drei Marken-Tests gegen den alten Stand laufen lassen** (`marke`-Parameter
|
||||
ignoriert): 3 von 36 scheitern, danach wieder 36 gruen. Der Test misst also,
|
||||
was er behauptet.
|
||||
|
||||
**Panel und App byteweise gleich** fuer elf Faelle mit und ohne gespeicherte
|
||||
Marke - die Panel-Funktionen aus dem Buendel geschnitten und in Node gegen
|
||||
dieselben Eingaben laufen lassen, nicht nachgebaut.
|
||||
|
||||
**Live in `audi_ha_test` (2026.9.4.21, 0 Tracebacks):**
|
||||
* Uebersicht `Shell, Nürnberger Str., Ansbach`, Einzelbeleg
|
||||
`Shell, Nürnberger Str. 74` / `91522 Ansbach`.
|
||||
* Den echten geteilten Beleg ueber `beleg_hochladen` durchs Backend geschickt
|
||||
und die veroeffentlichte Entitaet gelesen: `station_brand: "Shell"`, und die
|
||||
Formularzuordnung ergibt daraus `43.87` / `95.6` / `11.84` /
|
||||
`Shell, Richard-Wagner-Str. 9, Ingolstadt` / `V-Power Racing` /
|
||||
`2026-04-03T00:55` - also das ganze Formular, nicht nur die Uhrzeit.
|
||||
* Die Prueflast danach wieder entfernt (`/config/www/pruefbeleg.pdf` und die
|
||||
verwaiste `belege/geteilt-pruefung.pdf`; kein Tankvorgang zeigte darauf).
|
||||
|
||||
**Nicht geprueft:** die iOS-Huelle - die Aenderungen der App liegen im
|
||||
OTA-Buendel (2026.9.4.21) und brauchen keinen Xcode-Lauf. Der offene Punkt aus
|
||||
Abschnitt CM bleibt: dass die `packageClassList`-Registrierung auf dem Geraet
|
||||
greift, zeigt erst der naechste Xcode-Lauf.
|
||||
|
||||
Reference in New Issue
Block a user