fix(barcode): look up product info before checking auto_add_to_inventory

Previously, get_or_create_product was only called when auto_add was true,
so scan responses with auto_add=false returned no product details. Now the
DB lookup always runs when product_info is available; inventory insertion
is still conditional on auto_add_to_inventory. Fixes preview-only barcode
scans returning empty product fields.
This commit is contained in:
pyr0ball 2026-05-11 11:33:02 -07:00
parent e57f46f4b6
commit 8c765b7da2

View file

@ -478,7 +478,8 @@ async def scan_barcode_image(
from app.services.openfoodfacts import OpenFoodFactsService from app.services.openfoodfacts import OpenFoodFactsService
from app.services.expiration_predictor import ExpirationPredictor from app.services.expiration_predictor import ExpirationPredictor
barcodes = await asyncio.to_thread(BarcodeScanner().scan_image, temp_file) image_bytes = temp_file.read_bytes()
barcodes = await asyncio.to_thread(BarcodeScanner().scan_from_bytes, image_bytes)
if not barcodes: if not barcodes:
return BarcodeScanResponse( return BarcodeScanResponse(
success=False, barcodes_found=0, results=[], success=False, barcodes_found=0, results=[],
@ -500,9 +501,10 @@ async def scan_barcode_image(
product_info = await off.lookup_product(code) product_info = await off.lookup_product(code)
product_source = "openfoodfacts" product_source = "openfoodfacts"
db_product = None
inventory_item = None inventory_item = None
if product_info and auto_add_to_inventory: if product_info:
product, _ = await asyncio.to_thread( db_product, _ = await asyncio.to_thread(
store.get_or_create_product, store.get_or_create_product,
product_info.get("name", code), product_info.get("name", code),
code, code,
@ -512,6 +514,7 @@ async def scan_barcode_image(
source=product_source, source=product_source,
source_data=product_info, source_data=product_info,
) )
if auto_add_to_inventory:
exp = predictor.predict_expiration( exp = predictor.predict_expiration(
product_info.get("category", ""), product_info.get("category", ""),
location, location,
@ -523,18 +526,18 @@ async def scan_barcode_image(
resolved_unit = product_info.get("pack_unit") or "count" resolved_unit = product_info.get("pack_unit") or "count"
inventory_item = await asyncio.to_thread( inventory_item = await asyncio.to_thread(
store.add_inventory_item, store.add_inventory_item,
product["id"], location, db_product["id"], location,
quantity=resolved_qty, quantity=resolved_qty,
unit=resolved_unit, unit=resolved_unit,
expiration_date=str(exp) if exp else None, expiration_date=str(exp) if exp else None,
source="barcode_scan", source="barcode_scan",
) )
product_found = product_info is not None product_found = db_product is not None
needs_capture = not product_found and has_visual_capture needs_capture = not product_found and has_visual_capture
results.append({ results.append({
"barcode": code, "barcode": code,
"barcode_type": bc.get("type", "unknown"), "barcode_type": bc.get("type", "unknown"),
"product": ProductResponse.model_validate(product_info) if product_info else None, "product": ProductResponse.model_validate(db_product) if db_product else None,
"inventory_item": InventoryItemResponse.model_validate(inventory_item) if inventory_item else None, "inventory_item": InventoryItemResponse.model_validate(inventory_item) if inventory_item else None,
"added_to_inventory": inventory_item is not None, "added_to_inventory": inventory_item is not None,
"needs_manual_entry": not product_found and not needs_capture, "needs_manual_entry": not product_found and not needs_capture,