Hauptuntersuchung: Ableitung aus Erstzulassung und Wartungsplan, drittes Feld entfernt
Gemeldet: Wartungsplan leer, Erstzulassung 01.03.2025, erwartet 01.03.2028 -
gezeigt wurden drei verschiedene Antworten (Uebersicht 01.08.2026, Mein Audi
"August 2026", Service "kein Eintrag im Wartungsplan").
Ursache war das Profilfeld hauptuntersuchung_faellig ("08/2026"), das die
Ableitung ueberstimmte, in keiner Oberflaeche ein Eingabefeld hatte und im
Backend kein Schema. Drei Bildschirme verarbeiteten denselben Wert
verschieden. Das Feld ist samt Lese- und Schreibweg entfernt; es gibt jetzt
zwei Quellen: Wartungsplan + 24 Monate, sonst Erstzulassung + 36 Monate.
Dabei mitbehoben:
* Die Service-Kachel verschluckte abgeleitete Termine, sobald kein
Wartungsplan-Eintrag dahinterstand.
* monatePlus() in der App verlor einen Tag ueber die Zeitumstellung (drei von
fuenf gemessenen Faellen) - betraf Oelwechsel- und Inspektionsprognose
genauso. Das Panel rechnete dort seit jeher richtig.
* Die App verlangte fuer jeden Wartungsplan-Eintrag eine Kilometerangabe. Eine
Hauptuntersuchung ist rein datumsbasiert; ohne km waere der erste HU-Eintrag
ignoriert worden. Ausserdem nahm das Panel den ersten Treffer der Liste, die
App den juengsten - beide nehmen jetzt den juengsten.
* Monatsgenauigkeit ("03/2025") bleibt auf beiden Seiten erhalten.
Neu: paritaet_hu.test.ts vergleicht die App gegen die aus der Panel-Quelle
herausgeschnittenen Originalfunktionen, 15 Faelle. Gesamt 292 App-Tests, 73
Python-Tests mit 231 Untertests, 0 Tracebacks. Live an der Testinstanz auf
allen drei gemeldeten Bildschirmen geprueft.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -225,7 +225,6 @@ function profilZuCar(p, status) {
|
||||
finAutomatisch: p.fahrzeug.fin_automatisch !== false,
|
||||
details: p.fahrzeug.details,
|
||||
erstzulassung: p.fahrzeug.erstzulassung,
|
||||
hu: p.fahrzeug.hauptuntersuchung_faellig,
|
||||
odo: status.km ?? 0,
|
||||
odoBekannt: status.km != null,
|
||||
tankPct: status.tankprozent ?? 0,
|
||||
@@ -287,7 +286,6 @@ function configCarZuProfil(vorherigesProfil) {
|
||||
p.fahrzeug.zusatz = CONFIG.fahrzeugzusatz;
|
||||
p.fahrzeug.untertitel = CONFIG.fahrzeuguntertitel;
|
||||
p.fahrzeug.kennzeichen = CONFIG.kennzeichen;
|
||||
p.fahrzeug.hauptuntersuchung_faellig = CAR.hu;
|
||||
p.fahrzeug.fin = CAR.fin;
|
||||
p.fahrzeug.fin_automatisch = CAR.finAutomatisch;
|
||||
p.fahrzeug.erstzulassung = CAR.erstzulassung;
|
||||
@@ -2362,7 +2360,7 @@ function vHome() {
|
||||
const datum = t.kmDatum || t.datum;
|
||||
const hauptwert = restKm !== null
|
||||
? `${de(restKm)}<span class="unit">km</span>`
|
||||
: (datum ? dedat(datum) : "–");
|
||||
: (datum === t.datum ? datumText(t.datum, t.genau) : (datum ? dedat(datum) : "–"));
|
||||
// Ohne Restkilometer steht das Datum selbst im Zahlenfeld - auf Nutzerwunsch
|
||||
// jetzt in derselben Groesse wie die km-Zahl (vorher 30px, damit "15.04.2027"
|
||||
// auf 375px nicht umbricht - am laufenden Panel geprueft, dass es bei 40px
|
||||
@@ -2924,6 +2922,17 @@ function vService() {
|
||||
const fmDatum = fm.ts ? dedat(new Date(fm.ts)) : null;
|
||||
const hatMeldung = fm.km != null || fmDatum;
|
||||
const iv = intervalle(t);
|
||||
/* Ohne Wartungsplan-Eintrag und ohne Fahrzeugmeldung bleibt bei der
|
||||
Hauptuntersuchung trotzdem ein Termin uebrig: der aus der
|
||||
Erstzulassung abgeleitete (siehe hauptuntersuchungsTermin()). Bis zum
|
||||
05.09.2026 hat diese Kachel ihn verschluckt und "kein Eintrag im
|
||||
Wartungsplan" gezeigt, waehrend die Uebersicht denselben Termin
|
||||
auswies - gemeldet vom Eigentuemer, zwei Bildschirme, zwei
|
||||
Antworten. */
|
||||
if (!iv && !hatMeldung && t.datum) return `<div class="termingruppe">
|
||||
<div class="tg-kopf">${kopf}</div>
|
||||
<div class="tg-wert">${datumText(t.datum, t.genau)}</div>
|
||||
</div>`;
|
||||
if (!iv && !hatMeldung) return `<div class="termingruppe">
|
||||
<div class="tg-kopf">${kopf}</div>
|
||||
<div class="tg-wert leer">kein Eintrag im Wartungsplan</div>
|
||||
@@ -3122,27 +3131,56 @@ function gewaehlterTermin() {
|
||||
return auswahl[Math.min(svAuswahl, auswahl.length - 1)];
|
||||
}
|
||||
|
||||
/* Die Hauptuntersuchung hat drei moegliche Quellen, in dieser Reihenfolge:
|
||||
/* Die Hauptuntersuchung hat ZWEI Quellen, in dieser Reihenfolge:
|
||||
|
||||
1. die im Profil EINGETRAGENE Faelligkeit (CAR.hu). Sie steht auf dem
|
||||
Pruefbericht und ist damit die belastbarste Angabe - bis zum
|
||||
04.09.2026 hat das Panel sie gar nicht benutzt, obwohl sie
|
||||
gespeichert war (Befund des Eigentuemers).
|
||||
2. der letzte Servicebuch-Eintrag plus 24 Monate.
|
||||
3. die Erstzulassung plus 24 Monate.
|
||||
1. der letzte Servicebuch-Eintrag plus **24** Monate.
|
||||
2. die Erstzulassung plus **36** Monate.
|
||||
|
||||
Die 36 gegen 24 sind kein Versehen: die erste Hauptuntersuchung eines
|
||||
Neuwagens ist nach drei Jahren faellig, jede weitere nach zwei.
|
||||
|
||||
Es gibt KEINE dritte Quelle mehr. Bis zum 05.09.2026 stand hier zuerst
|
||||
ein Profilfeld `hauptuntersuchung_faellig`, das alles andere ueberstimmt
|
||||
hat. Dieses Feld hatte in keiner der beiden Oberflaechen ein
|
||||
Eingabefeld und im Backend kein Schema - es lag nur als toter Schluessel
|
||||
in fahrzeugprofil.json und war von dort weder zu sehen noch zu aendern.
|
||||
Gemeldet vom Eigentuemer am 05.09.2026: Wartungsplan leer, Erstzulassung
|
||||
01.03.2025, angezeigt wurde trotzdem August 2026 - das war jener tote
|
||||
Schluessel ("08/2026"). Das Feld ist samt Lese- und Schreibweg
|
||||
entfernt; die Ableitung ist die einzige Quelle. */
|
||||
const HU_MONATE_FOLGE = 24;
|
||||
const HU_MONATE_ERSTE = 36;
|
||||
|
||||
/* Der JUENGSTE Hauptuntersuchungs-Eintrag des Wartungsplans.
|
||||
|
||||
Nicht ueber letzterEintrag(): das nimmt mit .find() den ersten Treffer in
|
||||
Listenreihenfolge, waehrend die App nach Datum absteigend sortiert. Bei
|
||||
mehreren Eintraegen haetten beide Seiten verschiedene Termine gezeigt,
|
||||
ohne dass man es der Anzeige ansieht. */
|
||||
function letzteHauptuntersuchung() {
|
||||
let beste = null;
|
||||
let besteZeit = null;
|
||||
for (const e of CAR.service.buch) {
|
||||
if (!e || typeof e.art !== "string" || !e.art.toLowerCase().includes("hauptunter")) continue;
|
||||
const z = datumAusText(e.datum);
|
||||
if (!z) continue;
|
||||
if (besteZeit === null || z.zeit > besteZeit) { beste = e; besteZeit = z.zeit; }
|
||||
}
|
||||
return beste;
|
||||
}
|
||||
|
||||
Zu 3.: das ging vorher NUR mit einer Erstzulassung im Format MM/JJJJ.
|
||||
Ein vollstaendiges Datum (01.03.2025) - eine voellig richtige Eingabe -
|
||||
liess den Termin still leer. datumAusText() nimmt jetzt beide Formen. */
|
||||
function hauptuntersuchungsTermin(bauen) {
|
||||
const gesetzt = datumAusText(CAR.hu);
|
||||
if (gesetzt) {
|
||||
return { art: "Hauptuntersuchung", km: null, datum: gesetzt.zeit, kmDatum: null,
|
||||
zuerst: "zeit", basis: null, ziel: gesetzt.zeit, genau: gesetzt.genau };
|
||||
const eintrag = letzteHauptuntersuchung();
|
||||
if (eintrag) {
|
||||
return bauen("Hauptuntersuchung", eintrag, null, HU_MONATE_FOLGE);
|
||||
}
|
||||
const erst = datumAusText(CAR.erstzulassung);
|
||||
return bauen("Hauptuntersuchung", letzterEintrag("hauptuntersuchung"), null, 24,
|
||||
const termin = bauen("Hauptuntersuchung", null, null, HU_MONATE_ERSTE,
|
||||
erst ? erst.zeit : null);
|
||||
// Eine Erstzulassung als "03/2025" nennt keinen Tag. Dann nennt auch der
|
||||
// abgeleitete Termin keinen - "01.03.2028" waere eine Erfindung.
|
||||
if (erst && erst.genau === "monat") termin.genau = "monat";
|
||||
return termin;
|
||||
}
|
||||
|
||||
function termine() {
|
||||
|
||||
Reference in New Issue
Block a user