MHD nur mit Monat und Jahr in Web-UI und iOS-App
Setzt den Backend-Umbau in beiden Oberflaechen um. Die Genauigkeit gilt jeweils fuer den ganzen Einlager-Vorgang und nicht je Charge: Auf einer Packung steht entweder ein Tagesdatum oder nur Monat/Jahr, gemischt kommt das nicht vor. Vorbelegt wird sie aus dem Produkt, laesst sich aber im Vorgang umstellen. Web-UI: Umschalter im Kopf der Chargenliste; das Eingabefeld wechselt zwischen type="date" und type="month". Im Produktformular gibt es das neue Feld "MHD-Angabe" neben der Gebinde-Bezeichnung. Anzeige laeuft ueber den Settings-Context, damit das eingestellte Datumsformat erhalten bleibt und Monatsangaben ueberall als "09/2026" erscheinen (Auslagern, Uebersicht, Chargentabelle). Die Abgelaufen-Warnung prueft bei Monatsangaben gegen den Monatsletzten - sonst haette eine Packung schon am Monatsersten als abgelaufen gegolten. iOS: Auswahl "Tagesdatum / nur Monat/Jahr" im Einlagern-Formular und beim Anlegen eines Artikels. SwiftUI hat keinen DatePicker ohne Tag, deshalb ein eigener MonthYearPicker aus zwei Auswahlfeldern; die Jahresliste reicht zwei Jahre zurueck (bereits abgelaufene Ware) und fuenfzehn nach vorn (Konserven). Die Chargenauswahl beim Auslagern zeigt Monatsangaben ebenfalls ohne Tag. Getestet: Web-Build (vite) und iOS-Geraetebuild laufen fehlerfrei durch, die App ist auf dem iPhone installiert. Das Verhalten in der Oberflaeche ist noch nicht von Hand durchgeklickt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -81,6 +81,38 @@ export function formatDate(iso, format = "de") {
|
||||
}
|
||||
}
|
||||
|
||||
// ---- MHD-Genauigkeit ----
|
||||
// Intern steht immer ein volles Datum (bei Monatsangaben der Monatsletzte).
|
||||
// Nur die Anzeige und das Eingabefeld richten sich nach der Genauigkeit.
|
||||
|
||||
/** MHD anzeigen: Monatsangaben ohne Tag, also "09/2026". */
|
||||
export function formatBestBefore(iso, precision, format = "de") {
|
||||
if (!iso) return "–";
|
||||
if (precision !== "month") return formatDate(iso, format);
|
||||
const date = new Date(`${iso}T00:00:00`);
|
||||
if (Number.isNaN(date.getTime())) return iso;
|
||||
return `${String(date.getMonth() + 1).padStart(2, "0")}/${date.getFullYear()}`;
|
||||
}
|
||||
|
||||
/** "2026-09-30" -> "2026-09" für <input type="month">. */
|
||||
export function toMonthInput(iso) {
|
||||
return iso ? iso.slice(0, 7) : "";
|
||||
}
|
||||
|
||||
/** "2026-09" -> "2026-09-01"; das Backend legt daraus den Monatsletzten. */
|
||||
export function fromMonthInput(value) {
|
||||
return value ? `${value}-01` : "";
|
||||
}
|
||||
|
||||
/** "2026-09" -> "2026-09-30". Fuer Ablauf-Warnungen: ein Monats-MHD laeuft
|
||||
* erst am Monatsende ab, nicht am Monatsanfang. */
|
||||
export function monthInputToLastDay(value) {
|
||||
if (!value) return "";
|
||||
const [year, month] = value.split("-").map(Number);
|
||||
if (!year || !month) return "";
|
||||
return new Date(Date.UTC(year, month, 0)).toISOString().slice(0, 10);
|
||||
}
|
||||
|
||||
// MHD lesbar als Zeitspanne: "in 3 Tagen", "in 1 Woche", "vor 2 Wochen".
|
||||
// Deutsch nach "in"/"vor" steht im Dativ: 1 Tag / 3 Tagen, 1 Woche / 2 Wochen.
|
||||
export function relativeExpiry(daysLeft) {
|
||||
|
||||
Reference in New Issue
Block a user