Preis-Vorschlag: Auswahl aus mehreren erkannten Beträgen
Findet die Beleg-Analyse mehrere Beträge, liefert der Upload jetzt eine Kandidatenliste (bester Tipp zuerst). Web und iOS bieten dann ein Dropdown zur Auswahl des richtigen Kaufpreises, statt nur den automatischen Tipp. 1 neuer Test; Backend-Suite gruen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -104,6 +104,7 @@ struct ItemEditView: View {
|
||||
@State private var documents: [ItemDocument] = []
|
||||
@State private var suggWarranty: String?
|
||||
@State private var suggPrice: Int?
|
||||
@State private var suggPriceCandidates: [Int] = []
|
||||
@State private var busy = false
|
||||
@State private var busyDoc = false
|
||||
@State private var error: String?
|
||||
@@ -164,11 +165,24 @@ struct ItemEditView: View {
|
||||
VStack(alignment: .leading, spacing: 6) {
|
||||
Text("Im Beleg erkannt:").font(.caption).foregroundStyle(.secondary)
|
||||
if let w = suggWarranty { Text("Garantie bis \(w)") }
|
||||
if let p = suggPrice { Text("Kaufpreis \(ItemEditView.formatCents(p)) \(currency)") }
|
||||
if suggPriceCandidates.count > 1 {
|
||||
// Mehrere Beträge gefunden – Auswahl anbieten.
|
||||
Picker("Kaufpreis", selection: Binding(
|
||||
get: { suggPrice ?? suggPriceCandidates.first ?? 0 },
|
||||
set: { suggPrice = $0 }
|
||||
)) {
|
||||
ForEach(suggPriceCandidates, id: \.self) { c in
|
||||
Text("\(ItemEditView.formatCents(c)) \(currency)").tag(c)
|
||||
}
|
||||
}
|
||||
.pickerStyle(.menu)
|
||||
} else if let p = suggPrice {
|
||||
Text("Kaufpreis \(ItemEditView.formatCents(p)) \(currency)")
|
||||
}
|
||||
HStack {
|
||||
Button("Übernehmen") { applySuggestion() }
|
||||
Spacer()
|
||||
Button("Verwerfen") { suggWarranty = nil; suggPrice = nil }
|
||||
Button("Verwerfen") { verwerfeVorschlag() }
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
.font(.callout)
|
||||
@@ -289,6 +303,7 @@ struct ItemEditView: View {
|
||||
itemId: item.id, data: data, filename: filename, contentType: contentType)
|
||||
suggWarranty = res.suggestedWarrantyUntil
|
||||
suggPrice = res.suggestedPriceCents
|
||||
suggPriceCandidates = res.suggestedPriceCandidates
|
||||
await reloadDocuments()
|
||||
} catch { self.error = error.localizedDescription }
|
||||
}
|
||||
@@ -319,8 +334,13 @@ struct ItemEditView: View {
|
||||
private func applySuggestion() {
|
||||
if let w = suggWarranty, let d = stringToDate(w) { warranty = d; hasWarranty = true }
|
||||
if let p = suggPrice { priceText = ItemEditView.formatCents(p) }
|
||||
verwerfeVorschlag()
|
||||
}
|
||||
|
||||
private func verwerfeVorschlag() {
|
||||
suggWarranty = nil
|
||||
suggPrice = nil
|
||||
suggPriceCandidates = []
|
||||
}
|
||||
|
||||
/// Eingabe in Hauptwährungseinheit → Rappen/Cent.
|
||||
|
||||
@@ -635,11 +635,21 @@ struct ItemDocumentUpload: Codable {
|
||||
let id: Int
|
||||
let suggestedWarrantyUntil: String?
|
||||
let suggestedPriceCents: Int?
|
||||
let suggestedPriceCandidates: [Int]
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case suggestedWarrantyUntil = "suggested_warranty_until"
|
||||
case suggestedPriceCents = "suggested_price_cents"
|
||||
case suggestedPriceCandidates = "suggested_price_candidates"
|
||||
}
|
||||
|
||||
init(from decoder: Decoder) throws {
|
||||
let c = try decoder.container(keyedBy: CodingKeys.self)
|
||||
id = try c.decode(Int.self, forKey: .id)
|
||||
suggestedWarrantyUntil = try c.decodeIfPresent(String.self, forKey: .suggestedWarrantyUntil)
|
||||
suggestedPriceCents = try c.decodeIfPresent(Int.self, forKey: .suggestedPriceCents)
|
||||
suggestedPriceCandidates = try c.decodeIfPresent([Int].self, forKey: .suggestedPriceCandidates) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user