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:
@@ -1,5 +1,10 @@
|
||||
import SwiftUI
|
||||
|
||||
/// Damit sich eine UUID direkt als sheet(item:) verwenden laesst.
|
||||
extension UUID: Identifiable {
|
||||
public var id: UUID { self }
|
||||
}
|
||||
|
||||
extension Date {
|
||||
/// Erster Tag des Monats - so wird eine Monatsangabe an den Server geschickt.
|
||||
var startOfMonth: Date {
|
||||
@@ -77,6 +82,8 @@ struct CheckInFormView: View {
|
||||
/// Gilt fuer den ganzen Vorgang: Auf einer Packung steht entweder ein
|
||||
/// Tagesdatum oder nur Monat/Jahr - nicht beides gemischt.
|
||||
@State private var precision: String = "day"
|
||||
/// Charge, fuer die gerade das MHD abgescannt wird.
|
||||
@State private var scanLineId: UUID?
|
||||
@State private var unit: String = ""
|
||||
@State private var locationId: Int?
|
||||
@State private var busy = false
|
||||
@@ -156,6 +163,15 @@ struct CheckInFormView: View {
|
||||
} else {
|
||||
DatePicker("MHD", selection: $line.bestBefore, displayedComponents: .date)
|
||||
}
|
||||
if DateScanView.isSupported {
|
||||
Button {
|
||||
scanLineId = line.id
|
||||
} label: {
|
||||
Label("MHD scannen", systemImage: "text.viewfinder")
|
||||
.font(.callout)
|
||||
}
|
||||
.buttonStyle(.borderless)
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding(.vertical, 2)
|
||||
@@ -181,6 +197,19 @@ struct CheckInFormView: View {
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .topBarLeading) { Button("Abbrechen") { dismiss() } }
|
||||
}
|
||||
.sheet(item: $scanLineId) { id in
|
||||
NavigationStack {
|
||||
DateScanView { datum, erkanntePraezision in
|
||||
// Nennt der Aufdruck keinen Tag, stellt sich die Eingabe
|
||||
// sichtbar auf Monat/Jahr um.
|
||||
if erkanntePraezision == "month" { precision = "month" }
|
||||
if let index = lines.firstIndex(where: { $0.id == id }) {
|
||||
lines[index].bestBefore = datum
|
||||
lines[index].hasDate = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onAppear {
|
||||
// Gibt es ein Gebinde, ist das die naheliegende Eingabe.
|
||||
unit = packageOptionName ?? product.unitName
|
||||
|
||||
Reference in New Issue
Block a user