MHD per Texterkennung einlesen
In der Chargenzeile beim Einlagern gibt es einen Knopf "MHD scannen". Er oeffnet die Texterkennung von VisionKit; erkannte Daten erscheinen als Vorschlag und werden erst uebernommen, wenn man sie antippt. Bewusst kein automatisches Uebernehmen: Eine Fehllesung beim MHD faellt sonst erst auf, wenn die Ware bereits falsch einsortiert ist. Der Parser deckt die Schreibweisen ab, die auf Verpackungen vorkommen - Tagesdaten (12.09.2026, 2026-09-12, 12/09/2026, 12.09.26) und Monatsangaben (09/2026, 09.2026, 2026-09, 09/26). Erkennt der Aufdruck nur Monat und Jahr, stellt sich die Eingabe sichtbar auf Monat/Jahr um. Damit aus Chargennummern und EAN-Codes keine Phantasiedaten werden, greifen mehrere Einschraenkungen: Muster mit Tag werden zuerst geprueft, ein bereits erkannter Textabschnitt wird nicht erneut ausgewertet, Monate ausserhalb 1-12 entfallen und das Jahr muss im Fenster von fuenf Jahren rueckwaerts bis dreissig vorwaerts liegen. Der Knopf erscheint nur, wenn das Geraet Texterkennung unterstuetzt (Neural Engine); sonst bleibt die Eingabe von Hand. Getestet: Der Parser wurde eigenstaendig uebersetzt und gegen 14 Faelle geprueft, alle korrekt - darunter, dass "12.09.2026" nicht als Monatsangabe gelesen wird, dass eine EAN keine Treffer erzeugt und dass unplausible Jahre und Monate verworfen werden. Der iOS-Geraetebuild laeuft fehlerfrei durch. Die Erkennung an einer echten Verpackung habe ich nicht selbst ausprobiert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -211,3 +211,109 @@ struct NewProductRequest: Codable {
|
||||
case groupId = "group_id"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Listen (Einkaufsliste, bald ablaufend)
|
||||
|
||||
struct ShoppingItem: Codable, Identifiable {
|
||||
let productId: Int
|
||||
let name: String
|
||||
let baseUnit: String
|
||||
let packageSize: Double?
|
||||
let stock: Double
|
||||
let minStock: Double
|
||||
let deficit: Double
|
||||
|
||||
var id: Int { productId }
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name, stock, deficit
|
||||
case productId = "product_id"
|
||||
case baseUnit = "base_unit"
|
||||
case packageSize = "package_size"
|
||||
case minStock = "min_stock"
|
||||
}
|
||||
}
|
||||
|
||||
struct GroupShoppingItem: Codable, Identifiable {
|
||||
let groupId: Int
|
||||
let name: String
|
||||
let stock: Double
|
||||
let minStock: Double
|
||||
let deficit: Double
|
||||
let unitName: String
|
||||
let productCount: Int
|
||||
|
||||
var id: Int { groupId }
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name, stock, deficit
|
||||
case groupId = "group_id"
|
||||
case minStock = "min_stock"
|
||||
case unitName = "unit_name"
|
||||
case productCount = "product_count"
|
||||
}
|
||||
}
|
||||
|
||||
struct ExpiringItem: Codable, Identifiable {
|
||||
let lotId: Int
|
||||
let productId: Int
|
||||
let productName: String
|
||||
let quantity: Double
|
||||
let baseUnit: String
|
||||
let bestBefore: String
|
||||
let bestBeforePrecision: String?
|
||||
let daysLeft: Int
|
||||
let packageSize: Double?
|
||||
let packageLabel: String?
|
||||
let unitName: String
|
||||
let unitFactor: Double
|
||||
|
||||
var id: Int { lotId }
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case quantity
|
||||
case lotId = "lot_id"
|
||||
case productId = "product_id"
|
||||
case productName = "product_name"
|
||||
case baseUnit = "base_unit"
|
||||
case bestBefore = "best_before"
|
||||
case bestBeforePrecision = "best_before_precision"
|
||||
case daysLeft = "days_left"
|
||||
case packageSize = "package_size"
|
||||
case packageLabel = "package_label"
|
||||
case unitName = "unit_name"
|
||||
case unitFactor = "unit_factor"
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Aenderungen
|
||||
|
||||
/// Nur gesetzte Felder werden geschickt (PATCH).
|
||||
struct ProductUpdateRequest: Codable {
|
||||
var name: String?
|
||||
var brand: String?
|
||||
var packageSize: Double?
|
||||
var packageLabel: String?
|
||||
var datePrecision: String?
|
||||
var minStock: Double?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case name, brand
|
||||
case packageSize = "package_size"
|
||||
case packageLabel = "package_label"
|
||||
case datePrecision = "date_precision"
|
||||
case minStock = "min_stock"
|
||||
}
|
||||
}
|
||||
|
||||
struct LotUpdateRequest: Codable {
|
||||
var quantity: Double?
|
||||
var bestBefore: String?
|
||||
var bestBeforePrecision: String?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case quantity
|
||||
case bestBefore = "best_before"
|
||||
case bestBeforePrecision = "best_before_precision"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user