Globale Oeffnungsfrist in die Einstellungen

Die letzte Station der Vererbungskette hatte keine Oberflaeche: Artikel >
Kategorie (naechster Vorfahr) > global. Die Kategorien konnten seit dem
letzten Commit abweichen, aber der Wert, von dem alles ausgeht, liess
sich nur per API setzen.

Er steht jetzt in der Karte "Ablaufwarnung", direkt unter der
Vorwarnzeit - beides sind Fristen, die man im selben Moment einstellt.
Mindestens 1 Tag, denn er ist Pflicht: Waere er leer, bekaeme eine
angebrochene Packung gar kein "zu verbrauchen bis".

Von Hand geprueft: 3 auf 4 Tage geaendert und gespeichert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-02 14:39:20 +02:00
co-authored by Claude Opus 5
parent f61c76034c
commit 7ce07daa97
+21
View File
@@ -10,6 +10,10 @@ import { DATE_FORMATS, formatDate } from "../units";
import { applyFavicon } from "../branding"; import { applyFavicon } from "../branding";
const EXPIRY_KEY = "expiry_warning_days"; const EXPIRY_KEY = "expiry_warning_days";
// Haltbarkeit nach dem Anbrechen. Der Wert ganz oben in der Kette: Artikel >
// Kategorie (naechster Vorfahr) > hier. Weil er die letzte Station ist, darf er
// nicht leer sein - sonst haette eine angebrochene Packung kein Verbrauchsdatum.
const OPEN_DAYS_KEY = "open_days";
const RECEIPT_KEY = "receipt_match_threshold"; const RECEIPT_KEY = "receipt_match_threshold";
const SESSION_KEY = "session_days"; const SESSION_KEY = "session_days";
@@ -28,6 +32,7 @@ export default function Settings() {
const { reload } = useSettings(); const { reload } = useSettings();
const toast = useToast(); const toast = useToast();
const [days, setDays] = useState(""); const [days, setDays] = useState("");
const [openDays, setOpenDays] = useState("");
const [threshold, setThreshold] = useState(""); const [threshold, setThreshold] = useState("");
const [dateFormat, setDateFormat] = useState("de"); const [dateFormat, setDateFormat] = useState("de");
const [sessionDays, setSessionDays] = useState("30"); const [sessionDays, setSessionDays] = useState("30");
@@ -38,6 +43,7 @@ export default function Settings() {
try { try {
const settings = await api.listSettings(); const settings = await api.listSettings();
setDays(settings.find((s) => s.key === EXPIRY_KEY)?.value ?? "7"); setDays(settings.find((s) => s.key === EXPIRY_KEY)?.value ?? "7");
setOpenDays(settings.find((s) => s.key === OPEN_DAYS_KEY)?.value ?? "3");
setThreshold(settings.find((s) => s.key === RECEIPT_KEY)?.value ?? "45"); setThreshold(settings.find((s) => s.key === RECEIPT_KEY)?.value ?? "45");
setDateFormat(settings.find((s) => s.key === DATE_FORMAT_KEY)?.value ?? "de"); setDateFormat(settings.find((s) => s.key === DATE_FORMAT_KEY)?.value ?? "de");
setSessionDays(settings.find((s) => s.key === SESSION_KEY)?.value ?? "30"); setSessionDays(settings.find((s) => s.key === SESSION_KEY)?.value ?? "30");
@@ -53,6 +59,8 @@ export default function Settings() {
setError(null); setBusy(true); setError(null); setBusy(true);
try { try {
await api.setSetting(EXPIRY_KEY, String(parseInt(days, 10))); await api.setSetting(EXPIRY_KEY, String(parseInt(days, 10)));
// Mindestens 1: "0 Tage" waere keine Frist, sondern ein Widerspruch.
await api.setSetting(OPEN_DAYS_KEY, String(Math.max(1, parseInt(openDays, 10) || 1)));
await api.setSetting(RECEIPT_KEY, String(Math.max(0, Math.min(100, parseInt(threshold, 10) || 0)))); await api.setSetting(RECEIPT_KEY, String(Math.max(0, Math.min(100, parseInt(threshold, 10) || 0))));
await api.setSetting(DATE_FORMAT_KEY, dateFormat); await api.setSetting(DATE_FORMAT_KEY, dateFormat);
await api.setSetting(SESSION_KEY, sessionDays); await api.setSetting(SESSION_KEY, sessionDays);
@@ -97,6 +105,19 @@ export default function Settings() {
bereits überschritten ist), erscheinen auf der Übersicht unter „Bald ablaufend“. bereits überschritten ist), erscheinen auf der Übersicht unter „Bald ablaufend“.
</p> </p>
<label>
Nach Öffnung haltbar (Tage)
<input type="number" min="1" step="1" value={openDays}
onChange={(e) => setOpenDays(e.target.value)} style={{ maxWidth: 160 }} />
</label>
<p className="muted small mt-0">
Wie lange eine angebrochene Packung noch gilt, wenn weder der Artikel
noch eine seiner Kategorien etwas anderes sagt. Dieser Wert ist die
letzte Station der Kette und deshalb Pflicht – ohne ihn bekäme eine
offene Packung kein „zu verbrauchen bis“. Abweichungen stehen bei den
Kategorien unter „Maße &amp; Frist“.
</p>
<div className="card-head" style={{ marginTop: "var(--sp-5)" }}> <div className="card-head" style={{ marginTop: "var(--sp-5)" }}>
<Icon name="cart" /><h2>Kassenzettel-Scan</h2> <Icon name="cart" /><h2>Kassenzettel-Scan</h2>
</div> </div>