Die Preisliste als Leitartefakt¶
Nachtrag zum Preiskonzept, 2026-08-08. Anlass ist die Rückmeldung aus der Nutzung, nachdem alle Arbeitspakete des Preiskonzepts umgesetzt waren: das Bepreisen ist zu kompliziert. Dieser Nachtrag überprüft die bisherigen Absprachen, kippt einige davon und setzt ein neues Leitartefakt: die menschenlesbare Preisliste pro Preisgruppe — das Dokument, das ein Labor seinem Kunden übergibt.
Stand 2026-08-08: P1 (Endpunkt GET /price-list), P2 (Seite
/price/list mit Inline-Betrag-Edit, CSV-Export und den drei Anfängen
inklusive Beispiel-Startvorlage POST /price-list/example), P5
(Tab-Konsolidierung: drei Reiter Übersicht / Preisliste / Verwaltung, die
bisherigen Sichten als Werkzeugzeile darunter; der Übersichts-Schritt „keine
Preise" führt in die Preisliste), P4 (Verschmelzung Artikel & Leistungen:
Artikel-Detailseite mit Leistungspreis-Sektion, /price/services leitet um)
und P3 (PDF-Export: Report-Familie price_list mit Datenvertrag
price-list, Briefkopf über das Berichts-Overlay, Generierung von der
Preislisten-Seite aus) sind umgesetzt — alle Arbeitspakete dieses
Nachtrags sind damit abgeschlossen.
Nachtrag 2026-08-13 — P6, zweisprachig: Die Liste führt je Preiskategorie
und je Katalogartikel einen zweiten Namen (name_secondary), und eine
Sprachwahl im Kopf gilt für Anzeige, CSV und PDF gleichermaßen: Erstsprache,
Zweitsprache oder beide. Welche Sprache die zweite ist, ist eine Einstellung
(settings.price.price_list_second_language, Vorgabe Englisch), keine
Spaltenbenennung. Aufgelöst wird die Sprache im Datensatz-Builder, nicht in
der Berichtsvorlage — deshalb folgt auch eine bestehende 1.0-Vorlage der
Sprachwahl, ohne von ihr zu wissen. Gepflegt wird der Zweitname nach Regel R2
in der Liste selbst, zusätzlich in der Kategoriemaske, am Artikel und über die
optionale Import-Spalte „Preiskategorie Zweitsprache". Begründung und
verworfene Alternativen:
ADR 2026-08-13.
1. Der Befund, ehrlich¶
Das Preiskonzept hat sein Modellziel erreicht: Kaskade mit Herkunftsauskunft, Kategorien statt 20.000 Typzeilen, Vererbung, Zuschläge, Staffeln, Währung. Jedes Arbeitspaket ist für sich begründet. In Summe ist eine Oberfläche entstanden, die das Modell zeigt statt die Arbeit:
- Sieben Reiter (Übersicht, Preise, Leistungen, Preiskategorien, Preisgruppen, Zuschläge, Matrix) stehen gleichberechtigt nebeneinander. Sie sind die Geschichte der Arbeitspakete, nicht der Weg des Anwenders.
- Zwei Pflege-Orte für dieselben Datensätze: „Leistungen" bepreist
Standardartikel (
service_id→standard_article), die Artikelverwaltung pflegt dieselben Artikel mit einem eigenen Standardpreis. Wer einen Reinigungspreis sucht, muss wissen, welcher der beiden Orte gerade zuständig ist. - Die flache Zeilenliste erklärt ihre Zahlen nicht. Eine Zeile „82,00 / Typ X / Gruppe A / ab 2026-01-01" sagt nicht, warum 82 — ob das ein Kategoriepreis, eine Typ-Ausnahme oder eine Ableitung ist. Das beantwortet heute nur das „Preis prüfen"-Panel, eine Einzelabfrage. Ein Mensch, der die Preisstellung als Ganzes sehen will, hat keine Sicht dafür.
Der Maßstab war bisher das Modell. Der Maßstab des Labors ist ein Dokument.
2. Das Leitartefakt: die Preisliste, wie der Kunde sie kennt¶
Die Vorlage liegt im Repo:
samples/preiskategorien-uebernahme/
— die echte Liste eines Kalibrierlabors. Zehn Oberkategorien („Messverstärker",
„Elektrische Messgeräte"), darunter 44 Kategorien mit je einem Betrag an
der feinsten Ebene, dazu einzelne Zusatzleistungen („Temperature sensor
additional point — 25"). Diese Liste ist das Angebot; Kunden kennen sie so
(Übernahme-Konzept). Das ist gelebte
Laborphilosophie: Preisarbeit beginnt mit so einer Liste (die alte wird
mitgebracht) und endet mit so einer Liste (die neue geht an den Kunden).
Daraus folgt der rote Faden:
Von der Liste zur Liste. Am Anfang steht eine Preisliste — mitgebracht und eingelesen (existiert:
price-classes:import) oder, für ein neues Labor ohne eigene Liste, eine Beispiel-Preisliste als Startvorlage. In der Mitte wird in der Liste gepflegt, am Ende wird die Liste übergeben (Export als PDF/CSV). Alles andere — Matrix, Zeilentabellen, Diagnose — sind Werkzeuge dahinter.
Drei Anfänge, ein Ziel. Der leere Zustand der Preislisten-Seite bietet:
- Eigene Liste einspielen — der Übernahmeweg für Bestandslabore (CSV/Excel, Übernahme-Konzept).
- Mit Beispiel-Preisliste starten — für neue Labore ohne eigene Liste: eine mitgelieferte, generische Startvorlage (Kategoriebaum nach dem Muster der echten Kundenliste: Oberkategorien wie „Elektrische Messgeräte", „Druck", „Temperatur" mit typischen Unterkategorien und deutlich als Beispiel markierten Beträgen). Ein Klick legt sie an, danach wird sie in der Liste angepasst statt auf einem leeren Blatt begonnen. Optional und einmalig — bei vorhandenen Kategorien wird der Weg nicht angeboten.
- Leer beginnen — geführt über die nächsten Schritte der Übersicht (Kategorie anlegen → Betrag setzen → Mitglieder zusortieren).
Die kombinierte Preisliste pro Preisgruppe hat drei Abschnitte, in den Worten des Labors:
| Abschnitt | Fachlich | Datenquelle |
|---|---|---|
| Kalibrierpreise — je Kategorie, mit Typ-/Prozedur-Ausnahmen eingerückt | der Aufwand je Geräteklasse | price_classes-Baum + service_prices (Kategoriezeilen) + prices (Typ-Ausnahmen) |
| Leistungsverrechnungspreise — zusätzlicher Prüfpunkt, Sondermessung | Zusatzaufwand je Leistung, ggf. typabhängig | service_prices mit service_id |
| Standardartikel — Gerät reinigen, Versand, Verpackung | Katalogposition mit einem Preis | standard_article.price |
Kopfzeilen der Liste tragen, was echte Laborlisten auch drucken: Währung (AP 7) und die pauschalen Konditionen als Fußnoten („DAkkS +30 %", „ab 10 Stück −10 %") — Zuschläge und Staffeln erscheinen also in der Liste, nicht als eigene Ziele.
3. Überprüfung der bisherigen Absprachen¶
Was bleibt, was kippt — Punkt für Punkt:
Bleibt (das Modell trägt):
- Die Kaskade mit Herkunftsauskunft (
matched_by, ADR-012/032) bleibt der Motor. Die Liste zeigt geltende Beträge; warum ein Betrag gilt, beantwortet weiterhin „Preis prüfen". Motor und Cockpit sind getrennt. - Kategorien bepreisen, Typzeilen sind Ausnahmen (AP 11/14) — das ist exakt die Struktur der Kundenliste und wird durch sie erst sichtbar.
- Zuschläge statt Komplexitätszeilen, Staffeln, Vererbung, Währung (AP 9/11b/7) — sie werden zu Fußnoten und Kopfzeilen der Liste, ihr Datenmodell bleibt.
- V1-Autarkie und Multi-DB — unberührt.
- Der Import einer mitgebrachten Liste (
price-classes:import) — er ist der Anfang des roten Fadens und bleibt der Übernahmeweg.
Kippt (die Oberfläche folgte den Arbeitspaketen, nicht dem Anwender):
- ~~Sieben gleichberechtigte Reiter~~ → drei: Übersicht (Führung + Preis prüfen), Preisliste (das Leitartefakt, neu), Verwaltung (alle bisherigen Sichten als Werkzeuge). Die Matrix wird vom Zwischenziel zum Lücken-Werkzeug unter Verwaltung — sie war die beste verfügbare Gesamt-Sicht, solange es die Preisliste nicht gab.
- ~~Zwei Pflege-Orte für Artikel/Leistungen~~ → einer. Der Reiter
„Leistungen" als eigene Maske entfällt; Katalogeintrag (Stammdaten +
Standardpreis) und seine typ-/gruppenabhängigen Preiszeilen
(
service_prices) werden eine Sicht — die Preiszeilen als Abschnitt der Artikel-Detailseite (Muster: Staffelpreise-Sektion). Verschmolzen wird die Oberfläche, nicht die Tabellen:standard_articleist eine V1-Tabelle und trägt Stammdaten, die Auftragspositionen unabhängig von jeder Preiszeile brauchen. - ~~Die flache Zeilenliste als Standard-Sicht auf „Preise"~~ → sie bleibt als Werkzeug (Gültigkeiten, Historie, Staffelpflege, Import/Export, Massenanpassung, stillgelegte Zeilen), verliert aber die Rolle einer Hauptsicht. Kein Mensch liest Preisstellung aus Zeilen.
Vereinfachte Arbeitsregeln (ersetzen die implizite „je AP ein Reiter"-Logik):
- R1 — Die Preisliste ist der Ort der Wahrheit für Menschen. Jede neue Preisfunktion muss beantworten, wo sie in der Liste erscheint (als Zeile, Fußnote oder gar nicht). Was nirgends erscheint, bekommt keinen Reiter.
- R2 — Gepflegt wird, wo gelesen wird. Beträge ändern direkt in der Preisliste (Inline-Edit auf der Kategoriezeile); Zeilentabellen sind für Sonderfälle, nicht für die Preisrunde.
- R3 — Ein Datensatz, ein Ort. Keine zwei Masken über derselben Tabelle.
- R4 — Werkzeuge heißen Werkzeuge. Diagnose- und Massenfunktionen stehen unter Verwaltung, nicht neben dem Leitartefakt.
4. Zielbild der Oberfläche¶
Preise
├── Übersicht (bleibt: Kennzahlen, geführte nächste Schritte, Preis prüfen)
├── Preisliste (NEU, zentral)
│ Kopf: Preisgruppe ▾ Stichtag ▾ Währung [Export PDF] [Export CSV]
│ Fußnoten: aktive Zuschläge („DAkkS +30 %"), Staffel-Konditionen
│ A. Kalibrierpreise — Kategoriebaum mit Beträgen (Inline-Edit),
│ Typ-/Prozedur-Ausnahmen eingerückt darunter
│ B. Zusatzleistungen — Leistungen mit Preis (+ typabhängige Zeilen)
│ C. Standardartikel — Katalog mit Standardpreis
└── Verwaltung (Werkzeuge: Zeilenliste, Artikel & Leistungen,
Kategorien, Gruppen, Zuschläge, Matrix/Lücken)
Eine Zeile der Liste zeigt den geltenden Betrag der gewählten Gruppe am Stichtag — inklusive Ableitung (kenntlich gemacht, z. B. kursiv mit „aus Basispreis +10 %"). Damit beantwortet die Liste die Frage, die die flache Tabelle nie beantworten konnte: was gilt hier eigentlich gerade, als Ganzes?
Auf schmalen Displays (unter md) rendert dieselbe Seite die Zeilen als
antippbare Liste statt als Tabelle: sichtbar bleiben Bezeichnung und Betrag,
Nummer, Hinweis und Staffeln stehen in der Detailansicht des Eintrags, die
ein Tipp auf die Zeile öffnet — dort wird der Betrag auch geändert. Vier
Spalten nebeneinander machen die Seite sonst breiter als das Fenster, und
weggescrollt ist die Nummernspalte gar nicht mehr auffindbar.
5. Was zu bauen ist (neue Arbeitspakete)¶
| AP | Inhalt | Aufwand |
|---|---|---|
| P1 — Preislisten-Endpunkt | GET /price-list?group=&date=: die kombinierte Struktur (Kategoriebaum mit geltenden Beträgen samt Herkunft, Typ-Ausnahmen, Leistungen, Standardartikel, aktive Zuschläge/Staffel-Fußnoten). Nutzt Finder, Resolver und Ableitung — nichts Neues rechnen, nur zusammenstellen |
2–3 PT |
| P2 — Preislisten-Seite | /price/list als zentraler Reiter: Lesen + Inline-Betrag-Edit (schreibt die jeweilige Quellzeile), CSV-Export sofort. Leerer Zustand mit den drei Anfängen (Import, Beispiel-Startvorlage per POST /price-list/example über den bestehenden Listen-Importer, leer + geführt) |
2–3 PT |
| P3 — PDF-Export | Report-Familie price-list (Contract wie order-document): die übergabefähige Kundenliste mit Briefkopf |
2–3 PT |
| P4 — Verschmelzung Artikel & Leistungen | Eine Maske: Artikel-Detail mit service_prices-Sektion; Reiter „Leistungen" entfällt, Weiterleitung |
1–2 PT |
| P5 — Tab-Konsolidierung | Drei Reiter, bisherige Sichten unter Verwaltung; Menü- und Handbuch-Anpassung | 1 PT |
| P6 — Zweisprachig (Nachtrag 2026-08-13) | Zweitname je Kategorie und Artikel, Sprachwahl für Anzeige/CSV/PDF, Auflösung im Datensatz-Builder (Contract 1.1) | 2 PT |
Empfohlene Reihenfolge: P1 → P2 → P5 → P4 → P3. Die Liste zuerst lesbar machen (P1/P2), dann die Oberfläche darum ordnen (P5/P4); das PDF (P3) ist die Kür und braucht die stabile Struktur aus P1.
6. Trade-offs, ehrlich¶
- Ein neuer Aggregat-Endpunkt (P1) ist eine weitere Stelle, die die Kaskade konsumiert. Gegengewicht: er rechnet nichts selbst, er ruft dieselben Dienste wie Lookup und Matrix — driftet also nicht.
- Inline-Edit in der Liste schreibt in drei verschiedene Tabellen, je
nachdem welche Zeile man anfasst (Kategoriezeile →
service_prices, Typ-Ausnahme →prices, Artikel →standard_article). Das ist genau die Komplexität, die der Anwender nicht mehr sehen soll — sie wandert in den Endpunkt, der je Zeile Quelle und Schreibziel mitliefert. - Die Matrix verliert ihren Rang. Wer heute mit ihr arbeitet, findet sie unter Verwaltung wieder; ihre Lücken-Funktion übernimmt langfristig die Übersicht („Kategorie X hat in Gruppe B keinen Betrag").
- Die Preisliste zeigt eine Gruppe zur Zeit — bewusst. Der Vergleich über Gruppen bleibt Sache der Matrix (Werkzeug). Beides in eine Sicht zu pressen war der Fehler, der die Matrix unlesbar gemacht hätte.
7. Bezug zu den bestehenden Konzepten¶
- Preiskonzept: Modell und Kaskade gelten unverändert; dieser Nachtrag ordnet die Oberfläche neu (ersetzt die implizite Sieben-Reiter-Struktur aus §5/§8).
- Geführte Preiseinrichtung: die Statusseite bleibt der Einstieg; ihr „nächster Schritt" zeigt künftig auf die Preisliste statt auf Einzelwerkzeuge.
- Preisliste übernehmen: der Import ist der Anfang des roten Fadens; sein Zielbild (Kategoriebaum + Beträge) ist dasselbe wie das der neuen Preislisten-Sicht — Übernahme und Pflege landen erstmals im selben Bild.