iOS: Benachrichtigungs-Kategorien laden + Ein-/Auslager-Meldung huebscher

1) In den Benachrichtigungs-Regeln liess sich keine Kategorie waehlen: der Abruf
   holte den ganzen Snapshot (Produkte + Ablauf + Kategorien) - schlug ein Teil
   fehl, kamen auch die Kategorien leer. snapshot ist jetzt widerstandsfaehig
   (Teilausfaelle egal), und die Regel-Bearbeitung holt nur noch die Kategorien.

2) Die gruene Erfolgsmeldung ist jetzt eine saubere, eingerueckte Pille mit Titel
   ("Eingelagert"/"Ausgelagert") und Detailzeile ("Neuer Bestand: 2 Packungen").
   Die Einheit steht in der Mehrzahl (Gebinde-Plural vom Server; Basiseinheiten
   wie Gramm bleiben unveraendert).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-07-29 15:04:25 +02:00
parent a0979a0780
commit 8250b5dc84
7 changed files with 68 additions and 31 deletions

View File

@@ -13,18 +13,39 @@ final class DisplaySettings: ObservableObject {
static let fallbackFormat = "de"
@Published private(set) var dateFormat = DisplaySettings.fallbackFormat
/// Gebinde-Mehrzahlformen (Einzahl -> Mehrzahl), z.B. Packung" -> Packungen".
@Published private(set) var packagePlural: [String: String] = ["Packung": "Packungen"]
private init() {}
/// Nach der Anmeldung aufrufen. Schlaegt der Abruf fehl, bleibt es beim
/// Nach der Anmeldung aufrufen. Schlaegt ein Abruf fehl, bleibt es beim
/// deutschen Standard - an einer fehlenden Einstellung darf die Anzeige
/// nicht scheitern.
func load() async {
guard let entries = try? await APIClient.shared.settings() else { return }
if let entry = entries.first(where: { $0.key == DisplaySettings.dateFormatKey }),
if let entries = try? await APIClient.shared.settings(),
let entry = entries.first(where: { $0.key == DisplaySettings.dateFormatKey }),
!entry.value.isEmpty {
dateFormat = entry.value
}
if let typen = try? await APIClient.shared.packageTypes() {
var map = ["Packung": "Packungen"]
for t in typen where !t.singular.isEmpty { map[t.singular] = t.plural }
packagePlural = map
}
}
/// Ein Gebinde in der passenden Zahlform: 1 Packung", aber 2 Packungen".
func gebinde(_ count: Double, _ singular: String) -> String {
count == 1 ? singular : (packagePlural[singular] ?? singular)
}
/// Artikeleinheit mit Mehrzahl: bei Packungen die Gebinde-Mehrzahl, sonst die
/// Basiseinheit (Gramm/Milliliter/Stück im Deutschen ohne Mehrzahl).
func articleUnit(_ product: Product, count: Double) -> String {
if let size = product.packageSize, size > 0 {
return gebinde(count, product.packageLabel ?? "Packung")
}
return product.articleUnitLabel
}
// MARK: - Datum