iOS: eigene Kategorie-Felder schon beim Anlegen ausfuellen
Beim Neuanlegen eines Gegenstands (z.B. T-Shirt) werden jetzt die eigenen Felder der gewaehlten Kategorie (Groesse, Farbe, ...) geladen und angezeigt - vorher tauchten sie erst in der Detailansicht nach dem Anlegen auf. NewProductRequest traegt die Werte via field_values mit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -309,6 +309,8 @@ struct NewProductRequest: Codable {
|
|||||||
var individual: Bool? = nil
|
var individual: Bool? = nil
|
||||||
/// Verbrauchsgegenstand: Gegenstand wie ein Lebensmittel (Charge) geführt.
|
/// Verbrauchsgegenstand: Gegenstand wie ein Lebensmittel (Charge) geführt.
|
||||||
var bulk: Bool? = nil
|
var bulk: Bool? = nil
|
||||||
|
/// Selbst definierte Feldwerte der Kategorie: {feld_id (als Text): Wert}.
|
||||||
|
var fieldValues: [String: String?]? = nil
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case barcode, name, brand, individual, bulk
|
case barcode, name, brand, individual, bulk
|
||||||
@@ -319,6 +321,7 @@ struct NewProductRequest: Codable {
|
|||||||
case datePrecision = "date_precision"
|
case datePrecision = "date_precision"
|
||||||
case groupId = "group_id"
|
case groupId = "group_id"
|
||||||
case categoryId = "category_id"
|
case categoryId = "category_id"
|
||||||
|
case fieldValues = "field_values"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ struct ProductFormView: View {
|
|||||||
@State private var pendingImage: UIImage?
|
@State private var pendingImage: UIImage?
|
||||||
@State private var showCamera = false
|
@State private var showCamera = false
|
||||||
@State private var pickerItem: PhotosPickerItem?
|
@State private var pickerItem: PhotosPickerItem?
|
||||||
|
// Eigene Felder der (Gegenstands-)Kategorie – schon beim Anlegen ausfüllbar.
|
||||||
|
@State private var fieldDefs: [FieldDefinition] = []
|
||||||
|
@State private var fieldValues: [String: String] = [:]
|
||||||
|
|
||||||
private let baseUnits = [("piece", "Stück"), ("gram", "Gramm"), ("milliliter", "Milliliter")]
|
private let baseUnits = [("piece", "Stück"), ("gram", "Gramm"), ("milliliter", "Milliliter")]
|
||||||
// Beschriftungen kommen sonst aus DisplaySettings.baseUnitLabel.
|
// Beschriftungen kommen sonst aus DisplaySettings.baseUnitLabel.
|
||||||
@@ -179,6 +182,15 @@ struct ProductFormView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Eigene Felder der Gegenstands-Kategorie (z.B. Größe, Farbe beim
|
||||||
|
// T-Shirt) – schon beim Anlegen ausfüllbar, nicht erst danach.
|
||||||
|
if !fieldDefs.isEmpty {
|
||||||
|
Section("Eigene Felder") {
|
||||||
|
ForEach(fieldDefs) { def in
|
||||||
|
ObjectFieldRow(def: def, value: fieldBinding(def))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// Foto direkt beim Anlegen – z.B. wenn Open Food/Products Facts keins
|
// Foto direkt beim Anlegen – z.B. wenn Open Food/Products Facts keins
|
||||||
// liefert. Wird nach dem Anlegen hochgeladen (dann gibt es eine ID).
|
// liefert. Wird nach dem Anlegen hochgeladen (dann gibt es eine ID).
|
||||||
Section("Foto") {
|
Section("Foto") {
|
||||||
@@ -222,6 +234,16 @@ struct ProductFormView: View {
|
|||||||
pickerItem = nil
|
pickerItem = nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onChange(of: selectedCategoryId) { cid in
|
||||||
|
// Bei einer Gegenstands-Kategorie deren (vererbte) Felder nachladen.
|
||||||
|
Task {
|
||||||
|
if let cid, categories.first(where: { $0.id == cid })?.isObject == true {
|
||||||
|
fieldDefs = (try? await APIClient.shared.categoryFields(categoryId: cid)) ?? []
|
||||||
|
} else {
|
||||||
|
fieldDefs = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.onAppear(perform: prefill)
|
.onAppear(perform: prefill)
|
||||||
.task {
|
.task {
|
||||||
groups = (try? await APIClient.shared.groups()) ?? []
|
groups = (try? await APIClient.shared.groups()) ?? []
|
||||||
@@ -243,6 +265,19 @@ struct ProductFormView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func fieldBinding(_ def: FieldDefinition) -> Binding<String> {
|
||||||
|
let key = String(def.id)
|
||||||
|
return Binding(get: { fieldValues[key] ?? "" }, set: { fieldValues[key] = $0 })
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Werte der geltenden eigenen Felder als {feld_id: Wert} – nil, wenn keine.
|
||||||
|
private func eigeneFeldwerte() -> [String: String?]? {
|
||||||
|
guard !fieldDefs.isEmpty else { return nil }
|
||||||
|
var fv: [String: String?] = [:]
|
||||||
|
for def in fieldDefs { fv[String(def.id)] = fieldValues[String(def.id)] ?? "" }
|
||||||
|
return fv
|
||||||
|
}
|
||||||
|
|
||||||
private func prefill() {
|
private func prefill() {
|
||||||
if let initialType { modus = initialType }
|
if let initialType { modus = initialType }
|
||||||
barcode = suggestion?.barcode ?? prefillBarcode ?? ""
|
barcode = suggestion?.barcode ?? prefillBarcode ?? ""
|
||||||
@@ -277,7 +312,8 @@ struct ProductFormView: View {
|
|||||||
groupId: selectedGroupId,
|
groupId: selectedGroupId,
|
||||||
categoryId: selectedCategoryId,
|
categoryId: selectedCategoryId,
|
||||||
individual: modus == "object" ? (objMode == "individual") : nil,
|
individual: modus == "object" ? (objMode == "individual") : nil,
|
||||||
bulk: modus == "object" ? (objMode == "bulk") : nil
|
bulk: modus == "object" ? (objMode == "bulk") : nil,
|
||||||
|
fieldValues: eigeneFeldwerte()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
// Vorgemerktes Foto hochladen – ein Fehler darf das Anlegen nicht
|
// Vorgemerktes Foto hochladen – ein Fehler darf das Anlegen nicht
|
||||||
|
|||||||
Reference in New Issue
Block a user