fix(multi): FDISK sync, order UX, Ausbildungen display, untracked items

FDISK sync:
- fix(sync): strip 'KFZ-Führerschein / ' prefix from license class select option text before whitelist validation
- fix(sync): fix navigateAndGetTableRows to pick date column with most matches (prevents sidebar tables from hijacking dateColIdx for Beförderungen)
- fix(sync): input.value fallback now falls through to textContent when value is empty
- feat(sync): expand Ausbildungen to capture Kursnummer, Kurz, Kurs (full name), Erfolgscode from FDISK table; add migration 086

External orders (Bestellungen):
- fix(bestellungen): allow erhalten_menge editing in lieferung_pruefen status (resolves deadlock preventing order completion)
- fix(bestellungen): show cost/received warnings for bestellt/teillieferung/lieferung_pruefen, not just when abgeschlossen is next
- feat(bestellungen): rename status labels to Eingereicht, Genehmigt, Teilweise geliefert, Vollständig geliefert
- fix(bestellungen): remove duplicate Bestelldatum from PDF export
- feat(bestellungen): add catalog item autocomplete to creation form (auto-fills bezeichnung + artikelnummer)

Internal orders (Ausruestungsanfrage):
- fix(ausruestung): untracked items with zuweisung_typ='keine' now appear in Nicht-zugewiesen tab (frontend filter was too strict)
- feat(ausruestung): load user-specific personal items when ordering for another user
- feat(ausruestung): auto-set ist_ersatz=true for items from personal equipment list; add toggle for catalog/free-text items
- feat(ausruestung): load item eigenschaften when personal item with artikel_id is checked

Ausbildungen display:
- feat(mitglieder): show kursname (full), kurs_kurzbezeichnung chip, erfolgscode chip (color-coded) per Ausbildung entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Matthias Hochmeister
2026-04-15 13:22:04 +02:00
parent 916aa488d2
commit 50dbf6e9fd
14 changed files with 182 additions and 65 deletions

View File

@@ -0,0 +1,6 @@
-- Add Kursnummer, Kurzbezeichnung, and Erfolgscode columns to ausbildung table
-- These fields are scraped from FDISK's 5-column Ausbildungen detail page
ALTER TABLE ausbildung
ADD COLUMN IF NOT EXISTS kursnummer VARCHAR(32),
ADD COLUMN IF NOT EXISTS kurs_kurzbezeichnung VARCHAR(32),
ADD COLUMN IF NOT EXISTS erfolgscode VARCHAR(64);

View File

@@ -690,7 +690,7 @@ class MemberService {
async getAusbildungen(userId: string): Promise<any[]> {
try {
const result = await pool.query(
`SELECT id, kursname, kurs_datum, ablaufdatum, ort, bemerkung, status, created_at
`SELECT id, kursname, kursnummer, kurs_kurzbezeichnung, erfolgscode, kurs_datum, ablaufdatum, ort, bemerkung, status, created_at
FROM ausbildung
WHERE user_id = $1
ORDER BY kurs_datum DESC NULLS LAST, created_at DESC`,