From bec9b466fca326390448c065f7b09757f8e751f1 Mon Sep 17 00:00:00 2001 From: Stefan Zwischenbrugger Date: Wed, 1 Apr 2026 12:54:28 +0200 Subject: [PATCH] Update OCR-Positionsauswahl nach Uebernahme konsistent. Bereits uebernommene Positionen bleiben in der OCR-Liste abgewaehlt und manuell demarkierte Zeilen werden pro Bon gespeichert, damit die Auswahl auch nach erneutem OCR erhalten bleibt. Made-with: Cursor --- .../Controllers/ReceiptScanController.php | 20 +++++++++++++++++++ resources/views/receipt-scans/index.blade.php | 13 +++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/ReceiptScanController.php b/app/Http/Controllers/ReceiptScanController.php index 4677374..8b42d5b 100644 --- a/app/Http/Controllers/ReceiptScanController.php +++ b/app/Http/Controllers/ReceiptScanController.php @@ -115,6 +115,9 @@ class ReceiptScanController extends Controller if (isset($previousMeta['validated_at'])) { $rawMeta['validated_at'] = $previousMeta['validated_at']; } + if (isset($previousMeta['item_selection_state']) && is_array($previousMeta['item_selection_state'])) { + $rawMeta['item_selection_state'] = $previousMeta['item_selection_state']; + } $nextStoreName = $receiptScan->store_name; if (trim((string) $nextStoreName) === '' && is_string($ocr['store_name'] ?? null) && trim($ocr['store_name']) !== '') { @@ -182,6 +185,17 @@ class ReceiptScanController extends Controller $prices = $validated['row_prices'] ?? []; $qtys = $validated['row_qty'] ?? []; $take = $validated['row_take'] ?? []; + $selectionState = []; + foreach ($labels as $i => $labelRaw) { + $label = trim((string) $labelRaw); + if ($label === '') { + continue; + } + $priceRaw = trim((string) ($prices[$i] ?? '')); + $qtyRaw = trim((string) ($qtys[$i] ?? '')); + $selectionKey = $this->suggestionRowKey($label, $priceRaw, $qtyRaw); + $selectionState[$selectionKey] = isset($take[$i]); + } $rows = collect($labels) ->map(function ($label, $i) use ($prices, $qtys, $take) { @@ -285,6 +299,7 @@ class ReceiptScanController extends Controller $meta = is_array($receiptScan->raw_meta) ? $receiptScan->raw_meta : []; $meta['validated_items'] = $rows->all(); $meta['validated_at'] = Carbon::now()->toISOString(); + $meta['item_selection_state'] = $selectionState; $receiptScan->update(['raw_meta' => $meta]); return back()->with( @@ -398,6 +413,11 @@ class ReceiptScanController extends Controller return trim(preg_replace('/\s+[A-E]\s*$/u', '', $raw) ?? $raw); } + private function suggestionRowKey(string $label, string $priceRaw, string $quantityRaw): string + { + return mb_strtolower(trim($label)).'|'.trim($priceRaw).'|'.trim($quantityRaw); + } + /** * @return list */ diff --git a/resources/views/receipt-scans/index.blade.php b/resources/views/receipt-scans/index.blade.php index 5e9f207..7d933a3 100644 --- a/resources/views/receipt-scans/index.blade.php +++ b/resources/views/receipt-scans/index.blade.php @@ -149,6 +149,9 @@ ->filter() ->all(); $appliedSet = array_flip($appliedLowerKeys); + $selectionState = is_array($scan->raw_meta['item_selection_state'] ?? null) + ? $scan->raw_meta['item_selection_state'] + : []; @endphp

@@ -177,13 +180,21 @@ $listKey = mb_strtolower(trim($label)); $listStatus = $listProductLookup[$listKey] ?? null; $wasAppliedFromReceipt = $listKey !== '' && isset($appliedSet[$listKey]); + $selectionKey = $listKey.'|'.trim((string) $priceRaw).'|'.trim((string) $qtyRaw); + $storedSelection = $selectionState[$selectionKey] ?? null; + $defaultChecked = $storedSelection !== null + ? (bool) $storedSelection + : (! $isUncertain); + if ($wasAppliedFromReceipt) { + $defaultChecked = false; + } @endphp