Eigene Felder: Spalten in der Artikelliste und Export nach Feldwerten

Eigene Felder waren bisher nur im Artikelformular zu sehen. Zwei Luecken
daraus: In den Listen tauchten sie gar nicht auf, und es gab keinen Weg,
gezielt nach einem Feldwert zu exportieren.

SPALTEN. Je eigenem Feld eine Spalte in der Artikelliste, Schluessel
feld:<id> wie im Etikettenexport (die ID und nicht key, der ist nur je
Kategorie eindeutig). Reine Oberflaechenarbeit: GET /products liefert die
Werte laengst mit, Products.jsx warf sie nur weg. Filtern, Sortieren,
Ein-/Ausblenden und das Merken erbt die Spalte von DataTable.

Ja/Nein erscheint als Haken, liefert zum Filtern aber "Ja"/"Nein" - und
"Nein" auch ohne gespeicherten Wert: Wer den Haken wegnimmt, loescht die
Zeile, "nein" und "nie gesetzt" sind in den Daten dasselbe. Zahlen sortieren
als Zahl, sonst stuende "10" vor "9".

DataTable lernt dafuer defaultHidden: Alle Feldspalten starten verborgen und
sind erst auf Wunsch da - sonst hinge die Liste je nach Haushalt voller
Spalten, die fuer die meisten Zeilen gar nicht gelten.

Dabei einen vorhandenen Fehler gefunden: urlState las die Sortierung mit
split(":") und nahm das erste Stueck als Spalte. Bei "feld:12:asc" kam
dadurch "feld" heraus, und die Sortierung fiel beim Neuladen still weg. Jetzt
am LETZTEN Doppelpunkt getrennt.

EXPORT. Die Etikettenvorlagen bekommen einen Wertefilter: feldfilter in der
Konfiguration, mehrere Bedingungen UND-verknuepft, genau verglichen ohne
Ruecksicht auf Gross-/Kleinschreibung, leerer Wert heisst "ohne Wert".
Gefiltert wird in Python ueber die ohnehin geladenen Feldwerte - auf value
liegt kein Index, und "fehlende Zeile zaehlt als leer" braeuchte in SQL je
Bedingung ein NOT EXISTS.

Der Filter gilt auch fuer Einzelstuecke; der Wert haengt am Artikel des
Stuecks. Ein geloeschtes Feld laesst seine Bedingung wegfallen, genau wie
eine Spalte zu einem geloeschten Feld still verschwindet.

Die Sicherung schreibt den Filter wie die Spalten auf Kategorie::Label um -
ohne das zeigte er nach dem Zurueckspielen auf ein fremdes Feld, und der
Export gaebe mehr Zeilen aus als das Original. Dafuer ist _konfiguration aus
dem Router als konfiguration_schreiben in den Dienst gezogen: Sonst haetten
DREI Stellen denselben JSON-Text gebaut.

Zehn neue Tests, 540 gruen. Keine Schemaaenderung - konfiguration ist freies
JSON, alte Vorlagen lesen sich als leerer Filter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-16 16:02:53 +02:00
co-authored by Claude Opus 5
parent 83f7134459
commit dd57d3356a
10 changed files with 590 additions and 45 deletions
+15
View File
@@ -1126,6 +1126,18 @@ class SpalteOut(BaseModel):
titel: str
class FeldFilter(BaseModel):
"""Eine Bedingung auf einem eigenen Feld.
Mehrere Bedingungen muessen alle zutreffen. Verglichen wird genau, aber
ohne Ruecksicht auf Gross-/Kleinschreibung. Ein leerer ``wert`` trifft die
Zeilen OHNE Wert in diesem Feld.
"""
feld_id: int
wert: str = ""
class EtikettenVorlageOut(BaseModel):
model_config = ConfigDict(from_attributes=True)
id: int
@@ -1137,6 +1149,7 @@ class EtikettenVorlageOut(BaseModel):
spalten: list[str] = []
kategorie_ids: list[int] = []
trennzeichen: str = ","
feldfilter: list[FeldFilter] = []
# Nur der Name; die Binaerdaten gehen ueber einen eigenen Endpunkt.
datei_name: str | None = None
updated_at: datetime
@@ -1148,6 +1161,7 @@ class EtikettenVorlageCreate(BaseModel):
spalten: list[str] = []
kategorie_ids: list[int] = []
trennzeichen: str = ","
feldfilter: list[FeldFilter] = []
class EtikettenVorlageUpdate(BaseModel):
@@ -1158,6 +1172,7 @@ class EtikettenVorlageUpdate(BaseModel):
spalten: list[str] | None = None
kategorie_ids: list[int] | None = None
trennzeichen: str | None = None
feldfilter: list[FeldFilter] | None = None
position: int | None = None