fix: barcode EAN checksum validation + recipe persons dialog conflict
- Manual barcode input now blocks on invalid EAN checksum (was warning-only) - Native BarcodeDetector now validates EAN/UPC checksum before confirming - Renamed duplicate adjustRecipePersons (rescaler) to scaleRecipePersons to restore +/- buttons in the recipe generation dialog - Added error.barcode_checksum translation key (all 5 languages) - Bump version to v1.7.35
This commit is contained in:
+21
-1
@@ -151,6 +151,12 @@
|
||||
"banner_anomaly_untracked_detail": "Du hast <strong>{inv_qty} {unit}</strong> im Bestand, aber die gebuchten Abgänge übersteigen die Eingänge — der Anfangsbestand wurde wahrscheinlich nie als \"Eingang\" erfasst. Bitte korrigiere die Menge oder trage die fehlenden Eingänge nach.",
|
||||
"banner_anomaly_ghost_title": "weniger Bestand als erwartet",
|
||||
"banner_anomaly_ghost_detail": "Laut Buchungen solltest du {expected_qty} {unit} von {name} haben, aber der Bestand zeigt nur {inv_qty} {unit}. Hast du etwas ohne Buchung entnommen?",
|
||||
"banner_dup_loss_title": "Prüfung Doppelabbuchung: {name}",
|
||||
"banner_dup_loss_detail": "Mögliche doppelte Buchung in {location}: zwei schnelle Abgänge ({qty_pair}) in ~{seconds}s. Bitte prüfen und ggf. korrigieren.",
|
||||
"banner_dup_loss_action_fix": "Menge korrigieren",
|
||||
"banner_dup_loss_action_open": "Produktkarte öffnen",
|
||||
"banner_dup_loss_action_done": "Bereits geprüft",
|
||||
"banner_dup_loss_toast_done": "Prüfung als erledigt markiert",
|
||||
"consumed": "Verbraucht: {n} ({pct}%)",
|
||||
"wasted": "Weggeworfen: {n} ({pct}%)",
|
||||
"more_opened": "und {n} weitere geöffnet...",
|
||||
@@ -221,10 +227,23 @@
|
||||
"status_invalid": "Ungültig: {code} — versuche erneut",
|
||||
"status_confirmed": "Bestätigt!",
|
||||
"status_parallel": "Kombinierter Scan aktiv...",
|
||||
"status_ocr_searching": "Ich lese die Barcode-Ziffern...",
|
||||
"status_ai_visual_searching": "Jetzt versuche ich, das Produkt zu erkennen...",
|
||||
"method_ai_ocr": "Gemini OCR",
|
||||
"method_ai_vision": "Gemini Vision",
|
||||
"ai_fallback_searching": "KI identifiziert Produkt...",
|
||||
"ai_fallback_found": "Produkt von KI erkannt",
|
||||
"ai_fallback_not_found": "KI: Produkt nicht erkannt",
|
||||
"ai_fallback_exhausted": "KI: Produkt nicht erkannt — Barcode erneut scannen"
|
||||
"ai_fallback_exhausted": "KI: Produkt nicht erkannt — Barcode erneut scannen",
|
||||
"ai_overlay_msg": "Gemini Vision analysiert das Produkt...",
|
||||
"ai_retry_btn": "Mit KI erneut versuchen",
|
||||
"ai_match_title": "Produkt von KI erkannt",
|
||||
"ai_match_subtitle": "Waehle ein vorhandenes Produkt oder fuege das erkannte hinzu.",
|
||||
"ai_match_existing": "Mogliche Treffer in der Vorratskammer",
|
||||
"ai_match_none": "Keine ahnlichen Produkte in der Vorratskammer gefunden.",
|
||||
"ai_match_use_btn": "Dieses nutzen",
|
||||
"ai_match_add_btn": "\"{name}\" hinzufugen",
|
||||
"ai_detected_label": "KI erkannt"
|
||||
},
|
||||
"action": {
|
||||
"title": "Was möchtest du tun?",
|
||||
@@ -1069,6 +1088,7 @@
|
||||
"ai_quota": "KI-Kontingent erschöpft. Bitte in ein paar Minuten erneut versuchen.",
|
||||
"barcode_empty": "Barcode eingeben",
|
||||
"barcode_format": "Barcode darf nur Zahlen enthalten (4-14 Ziffern)",
|
||||
"barcode_checksum": "Ungültiger EAN-Prüfziffer — bitte die Barcode-Ziffern prüfen",
|
||||
"min_chars": "Mindestens 2 Zeichen eingeben",
|
||||
"not_in_inventory": "Produkt nicht im Bestand",
|
||||
"appliance_exists": "Gerät bereits vorhanden",
|
||||
|
||||
+21
-1
@@ -151,6 +151,12 @@
|
||||
"banner_anomaly_untracked_detail": "You have <strong>{inv_qty} {unit}</strong> in inventory, but recorded outflows exceed inflows — the initial stock was likely never added as an \"in\" transaction. You can correct the quantity or log the missing entries.",
|
||||
"banner_anomaly_ghost_title": "you have less stock than expected",
|
||||
"banner_anomaly_ghost_detail": "Based on recorded operations you should have {expected_qty} {unit} of {name}, but inventory shows only {inv_qty} {unit}. Did you take stock without recording it?",
|
||||
"banner_dup_loss_title": "Double-consume check: {name}",
|
||||
"banner_dup_loss_detail": "Possible duplicate entry in {location}: two close out events ({qty_pair}) in ~{seconds}s. Please verify and fix if needed.",
|
||||
"banner_dup_loss_action_fix": "Fix quantity",
|
||||
"banner_dup_loss_action_open": "Open product card",
|
||||
"banner_dup_loss_action_done": "Already checked",
|
||||
"banner_dup_loss_toast_done": "Check marked as reviewed",
|
||||
"consumed": "Consumed: {n} ({pct}%)",
|
||||
"wasted": "Wasted: {n} ({pct}%)",
|
||||
"more_opened": "and {n} more opened...",
|
||||
@@ -221,10 +227,23 @@
|
||||
"status_invalid": "Invalid: {code} — retrying",
|
||||
"status_confirmed": "Confirmed!",
|
||||
"status_parallel": "Using combined scan methods...",
|
||||
"status_ocr_searching": "Reading the barcode digits...",
|
||||
"status_ai_visual_searching": "Now trying to recognize the product...",
|
||||
"method_ai_ocr": "Gemini OCR",
|
||||
"method_ai_vision": "Gemini Vision",
|
||||
"ai_fallback_searching": "AI identifying product...",
|
||||
"ai_fallback_found": "Product identified by AI",
|
||||
"ai_fallback_not_found": "AI: product not recognized",
|
||||
"ai_fallback_exhausted": "AI: product not recognized — try scanning the barcode"
|
||||
"ai_fallback_exhausted": "AI: product not recognized — try scanning the barcode",
|
||||
"ai_overlay_msg": "Gemini Vision is analyzing the product...",
|
||||
"ai_retry_btn": "Retry with AI",
|
||||
"ai_match_title": "Product recognized by AI",
|
||||
"ai_match_subtitle": "Choose an existing pantry item or add the detected one.",
|
||||
"ai_match_existing": "Possible pantry matches",
|
||||
"ai_match_none": "No similar pantry products found.",
|
||||
"ai_match_use_btn": "Use this",
|
||||
"ai_match_add_btn": "Add \"{name}\"",
|
||||
"ai_detected_label": "AI detected"
|
||||
},
|
||||
"action": {
|
||||
"title": "What do you want to do?",
|
||||
@@ -1069,6 +1088,7 @@
|
||||
"ai_quota": "AI quota exhausted. Please try again in a few minutes.",
|
||||
"barcode_empty": "Enter a barcode",
|
||||
"barcode_format": "Barcode must contain only numbers (4-14 digits)",
|
||||
"barcode_checksum": "Invalid EAN checksum — please check the barcode digits",
|
||||
"min_chars": "Type at least 2 characters",
|
||||
"not_in_inventory": "Product not in inventory",
|
||||
"appliance_exists": "Appliance already exists",
|
||||
|
||||
+21
-1
@@ -149,6 +149,12 @@
|
||||
"banner_anomaly_untracked_detail": "Tienes <strong>{inv_qty} {unit}</strong> en inventario, pero las salidas registradas superan las entradas — el stock inicial probablemente nunca se añadió como transacción «entrada». Puedes corregir la cantidad o registrar las entradas faltantes.",
|
||||
"banner_anomaly_ghost_title": "tienes menos stock del esperado",
|
||||
"banner_anomaly_ghost_detail": "Según las operaciones registradas deberías tener {expected_qty} {unit} de {name}, pero el inventario solo muestra {inv_qty} {unit}. ¿Tomaste stock sin registrarlo?",
|
||||
"banner_dup_loss_title": "Control de doble salida: {name}",
|
||||
"banner_dup_loss_detail": "Posible registro duplicado en {location}: dos salidas seguidas ({qty_pair}) en ~{seconds}s. Revisa y corrige si hace falta.",
|
||||
"banner_dup_loss_action_fix": "Corregir cantidad",
|
||||
"banner_dup_loss_action_open": "Abrir ficha del producto",
|
||||
"banner_dup_loss_action_done": "Ya revisado",
|
||||
"banner_dup_loss_toast_done": "Control marcado como revisado",
|
||||
"consumed": "Consumido: {n} ({pct}%)",
|
||||
"wasted": "Desperdiciado: {n} ({pct}%)",
|
||||
"more_opened": "y {n} más abiertos...",
|
||||
@@ -218,10 +224,23 @@
|
||||
"status_invalid": "Inválido: {code} — reintentando",
|
||||
"status_confirmed": "Confirmado!",
|
||||
"status_parallel": "Escaneo combinado activo...",
|
||||
"status_ocr_searching": "Estoy leyendo los números del código de barras...",
|
||||
"status_ai_visual_searching": "Ahora intento reconocer el producto...",
|
||||
"method_ai_ocr": "Gemini OCR",
|
||||
"method_ai_vision": "Gemini Vision",
|
||||
"ai_fallback_searching": "Identificación de IA en curso...",
|
||||
"ai_fallback_found": "Producto identificado por IA",
|
||||
"ai_fallback_not_found": "IA: producto no reconocido",
|
||||
"ai_fallback_exhausted": "IA: producto no reconocido — prueba a escanear el código"
|
||||
"ai_fallback_exhausted": "IA: producto no reconocido — prueba a escanear el código",
|
||||
"ai_overlay_msg": "Gemini Vision está analizando el producto...",
|
||||
"ai_retry_btn": "Reintentar con IA",
|
||||
"ai_match_title": "Producto reconocido por IA",
|
||||
"ai_match_subtitle": "Elige un producto ya en despensa o agrega el detectado.",
|
||||
"ai_match_existing": "Posibles coincidencias en despensa",
|
||||
"ai_match_none": "No se encontraron productos similares en despensa.",
|
||||
"ai_match_use_btn": "Usar este",
|
||||
"ai_match_add_btn": "Agregar \"{name}\"",
|
||||
"ai_detected_label": "IA detecto"
|
||||
},
|
||||
"action": {
|
||||
"title": "¿Qué quieres hacer?",
|
||||
@@ -1020,6 +1039,7 @@
|
||||
"ai_quota": "Cuota de IA agotada. Inténtalo de nuevo en unos minutos.",
|
||||
"barcode_empty": "Introduce un código de barras",
|
||||
"barcode_format": "El código de barras solo puede contener números (4-14 dígitos)",
|
||||
"barcode_checksum": "Suma de comprobación EAN inválida — verifica los dígitos del código",
|
||||
"min_chars": "Escribe al menos 2 caracteres",
|
||||
"not_in_inventory": "Producto no en inventario",
|
||||
"appliance_exists": "El electrodoméstico ya existe",
|
||||
|
||||
+21
-1
@@ -149,6 +149,12 @@
|
||||
"banner_anomaly_untracked_detail": "Vous avez <strong>{inv_qty} {unit}</strong> en inventaire, mais les sorties enregistrées dépassent les entrées — le stock initial n'a probablement jamais été ajouté comme transaction « entrée ». Vous pouvez corriger la quantité ou saisir les entrées manquantes.",
|
||||
"banner_anomaly_ghost_title": "vous avez moins de stock que prévu",
|
||||
"banner_anomaly_ghost_detail": "D'après les opérations enregistrées vous devriez avoir {expected_qty} {unit} de {name}, mais l'inventaire n'en montre que {inv_qty} {unit}. Avez-vous pris du stock sans l'enregistrer ?",
|
||||
"banner_dup_loss_title": "Vérification double sortie : {name}",
|
||||
"banner_dup_loss_detail": "Doublon possible dans {location} : deux sorties rapprochées ({qty_pair}) en ~{seconds}s. Vérifiez et corrigez si besoin.",
|
||||
"banner_dup_loss_action_fix": "Corriger la quantité",
|
||||
"banner_dup_loss_action_open": "Ouvrir la fiche produit",
|
||||
"banner_dup_loss_action_done": "Déjà vérifié",
|
||||
"banner_dup_loss_toast_done": "Contrôle marqué comme vérifié",
|
||||
"consumed": "Consommé : {n} ({pct}%)",
|
||||
"wasted": "Gaspillé : {n} ({pct}%)",
|
||||
"more_opened": "et {n} autres ouverts...",
|
||||
@@ -218,10 +224,23 @@
|
||||
"status_invalid": "Invalide : {code} — nouvel essai",
|
||||
"status_confirmed": "Confirmé !",
|
||||
"status_parallel": "Scan combiné actif...",
|
||||
"status_ocr_searching": "Je lis les chiffres du code-barres...",
|
||||
"status_ai_visual_searching": "J'essaie maintenant de reconnaître le produit...",
|
||||
"method_ai_ocr": "Gemini OCR",
|
||||
"method_ai_vision": "Gemini Vision",
|
||||
"ai_fallback_searching": "Identification IA en cours...",
|
||||
"ai_fallback_found": "Produit identifié par l'IA",
|
||||
"ai_fallback_not_found": "IA : produit non reconnu",
|
||||
"ai_fallback_exhausted": "IA : produit non reconnu — réessayez avec le code-barres"
|
||||
"ai_fallback_exhausted": "IA : produit non reconnu — réessayez avec le code-barres",
|
||||
"ai_overlay_msg": "Gemini Vision analyse le produit...",
|
||||
"ai_retry_btn": "Reessayer avec l'IA",
|
||||
"ai_match_title": "Produit reconnu par l'IA",
|
||||
"ai_match_subtitle": "Choisissez un produit deja en stock ou ajoutez celui detecte.",
|
||||
"ai_match_existing": "Correspondances possibles dans le stock",
|
||||
"ai_match_none": "Aucun produit similaire trouve dans le stock.",
|
||||
"ai_match_use_btn": "Utiliser celui-ci",
|
||||
"ai_match_add_btn": "Ajouter \"{name}\"",
|
||||
"ai_detected_label": "IA a detecte"
|
||||
},
|
||||
"action": {
|
||||
"title": "Que voulez-vous faire ?",
|
||||
@@ -1020,6 +1039,7 @@
|
||||
"ai_quota": "Quota IA épuisé. Réessayez dans quelques minutes.",
|
||||
"barcode_empty": "Entrez un code-barres",
|
||||
"barcode_format": "Le code-barres ne doit contenir que des chiffres (4-14 chiffres)",
|
||||
"barcode_checksum": "Somme de contrôle EAN invalide — vérifiez les chiffres du code-barres",
|
||||
"min_chars": "Tapez au moins 2 caractères",
|
||||
"not_in_inventory": "Produit absent de l'inventaire",
|
||||
"appliance_exists": "L'appareil existe déjà",
|
||||
|
||||
+21
-1
@@ -151,6 +151,12 @@
|
||||
"banner_anomaly_untracked_detail": "Hai <strong>{inv_qty} {unit}</strong> in inventario, ma le uscite registrate superano le entrate — le scorte iniziali probabilmente non sono mai state aggiunte come entrata. Puoi correggere la quantità o registrare le entrate mancanti.",
|
||||
"banner_anomaly_ghost_title": "hai meno scorte del previsto",
|
||||
"banner_anomaly_ghost_detail": "In base alle operazioni registrate dovresti avere {expected_qty} {unit} di {name}, ma l'inventario mostra solo {inv_qty} {unit}. Hai prelevato senza registrarlo?",
|
||||
"banner_dup_loss_title": "Controllo doppio scarico: {name}",
|
||||
"banner_dup_loss_detail": "Possibile doppia registrazione in {location}: due uscite ravvicinate ({qty_pair}) in ~{seconds}s. Verifica se va corretta.",
|
||||
"banner_dup_loss_action_fix": "Correggi quantità",
|
||||
"banner_dup_loss_action_open": "Apri scheda prodotto",
|
||||
"banner_dup_loss_action_done": "Già verificato",
|
||||
"banner_dup_loss_toast_done": "Controllo segnato come verificato",
|
||||
"consumed": "Consumati: {n} ({pct}%)",
|
||||
"wasted": "Buttati: {n} ({pct}%)",
|
||||
"more_opened": "e altri {n} prodotti aperti...",
|
||||
@@ -221,10 +227,23 @@
|
||||
"status_invalid": "Non valido: {code} — riprovo",
|
||||
"status_confirmed": "Confermato!",
|
||||
"status_parallel": "Doppia scansione attiva...",
|
||||
"status_ocr_searching": "Sto leggendo i numeri del codice a barre...",
|
||||
"status_ai_visual_searching": "Ora provo a riconoscere il prodotto...",
|
||||
"method_ai_ocr": "Gemini OCR",
|
||||
"method_ai_vision": "Gemini Vision",
|
||||
"ai_fallback_searching": "Identificazione AI in corso...",
|
||||
"ai_fallback_found": "Prodotto identificato dall'AI",
|
||||
"ai_fallback_not_found": "AI: prodotto non riconosciuto",
|
||||
"ai_fallback_exhausted": "AI: prodotto non riconosciuto — riprova con il barcode"
|
||||
"ai_fallback_exhausted": "AI: prodotto non riconosciuto — riprova con il barcode",
|
||||
"ai_overlay_msg": "Gemini Vision sta analizzando il prodotto...",
|
||||
"ai_retry_btn": "Riprova con AI",
|
||||
"ai_match_title": "Prodotto riconosciuto con AI",
|
||||
"ai_match_subtitle": "Scegli se usare un prodotto gia presente oppure aggiungere quello rilevato.",
|
||||
"ai_match_existing": "Possibili corrispondenze in dispensa",
|
||||
"ai_match_none": "Nessun prodotto simile trovato in dispensa.",
|
||||
"ai_match_use_btn": "Usa questo",
|
||||
"ai_match_add_btn": "Aggiungi \"{name}\"",
|
||||
"ai_detected_label": "AI ha trovato"
|
||||
},
|
||||
"action": {
|
||||
"title": "Cosa vuoi fare?",
|
||||
@@ -1069,6 +1088,7 @@
|
||||
"ai_quota": "Quota AI esaurita. Riprova tra qualche minuto.",
|
||||
"barcode_empty": "Inserisci un codice a barre",
|
||||
"barcode_format": "Il codice a barre deve contenere solo numeri (4-14 cifre)",
|
||||
"barcode_checksum": "Checksum EAN non valido — verifica le cifre del codice",
|
||||
"min_chars": "Scrivi almeno 2 caratteri",
|
||||
"not_in_inventory": "Prodotto non nell'inventario",
|
||||
"appliance_exists": "Elettrodomestico già presente",
|
||||
|
||||
Reference in New Issue
Block a user