feat: AI price estimation for shopping list with per-item real-time display
- Add get_shopping_price / get_all_shopping_prices API endpoints - AI (Gemini) estimates retail price per natural unit (pack, piece, bunch) instead of always per-kg — avoids absurd totals like €1609 - _calcEstimatedTotal: proper g/ml→package conversion using defQty + regex on unit_label; only 'kg'/'l' labels trigger weight/volume math - Cache key bumped to v2 to invalidate old per-kg cached entries - Suggested quantity cap lowered from 20 to 10 conf/pz - Unit mismatch guard: if totalUsed >> buyCount*5 for unit=conf, use purchase frequency instead of raw consumption rate - JS _buildPricePayload: use smartShoppingItems for qty/unit (not Bring! spec) - JS _cachedPrices: persist in sessionStorage (survives navigation); validated by _qty/_unit metadata so stale totals auto-invalidate - Price display redesigned: right-side column per row (price-col-main + price-col-unit) instead of small inline badge - fetchAllPrices: buttons disabled immediately before guard check; running total uses only current shoppingItems (not Object.values cache) - Background refresh: always silent (removed 90s interaction condition) - visibilitychange: sets _bgCall=true for shopping before refreshCurrentPage - .gitignore: add runtime data files (bring_migrate_ts, shopping_price_cache, anomaly_dismissed, opened_shelf_cache, shopping_name_cache) - Remove bring_catalog.json and bring_migrate_ts.json from tracking
This commit is contained in:
+22
-6
@@ -103,11 +103,13 @@
|
||||
"banner_expired_action_throw": "Habe ich weggeworfen",
|
||||
"banner_expired_action_edit": "Datum korrigieren",
|
||||
"banner_anomaly_action_edit": "Bestand korrigieren",
|
||||
"banner_anomaly_action_dismiss": "Menge ist korrekt", "banner_no_expiry_title": "Ablaufdatum fehlt: {name}",
|
||||
"banner_anomaly_action_dismiss": "Menge ist korrekt",
|
||||
"banner_no_expiry_title": "Ablaufdatum fehlt: {name}",
|
||||
"banner_no_expiry_detail": "Dieses Produkt hat kein Ablaufdatum. Möchten Sie eines hinzufügen oder bestätigen, dass es nicht verfällt?",
|
||||
"banner_no_expiry_action_set": "Ablaufdatum setzen",
|
||||
"banner_no_expiry_action_dismiss": "Läuft nicht ab ✓",
|
||||
"banner_no_expiry_toast_dismissed": "Als 'läuft nicht ab' markiert", "banner_expiring_title": "Bald ablaufend",
|
||||
"banner_no_expiry_toast_dismissed": "Als 'läuft nicht ab' markiert",
|
||||
"banner_expiring_title": "Bald ablaufend",
|
||||
"banner_expiring_today": "Läuft heute ab!",
|
||||
"banner_expiring_tomorrow": "Läuft morgen ab",
|
||||
"banner_expiring_days": "Läuft in {days} Tagen ab",
|
||||
@@ -133,8 +135,7 @@
|
||||
"banner_anomaly_phantom_title": "mehr Bestand als erwartet",
|
||||
"banner_anomaly_phantom_detail": "Bestand zeigt {inv_qty} {unit}, aber laut Buchungen solltest du nur {expected_qty} {unit} haben. Hast du Bestand ohne Buchung hinzugefügt?",
|
||||
"banner_anomaly_untracked_title": "Anfangsbestand nicht als Eingang gebucht",
|
||||
"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_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?",
|
||||
"consumed": "Verbraucht: {n} ({pct}%)",
|
||||
@@ -161,7 +162,8 @@
|
||||
"label_quantity": "📦 Menge",
|
||||
"label_added": "📅 Hinzugefügt",
|
||||
"empty_text": "Keine Produkte hier.<br>Scanne ein Produkt, um es hinzuzufügen!",
|
||||
"empty_db": "Keine Produkte in der Datenbank.<br>Scanne ein Produkt, um loszulegen!"
|
||||
"empty_db": "Keine Produkte in der Datenbank.<br>Scanne ein Produkt, um loszulegen!",
|
||||
"qty_trace": "< 1"
|
||||
},
|
||||
"scan": {
|
||||
"title": "Produkt scannen",
|
||||
@@ -344,7 +346,7 @@
|
||||
"suggestions_title": "💡 KI-Vorschläge",
|
||||
"suggestions_add": "✅ Ausgewählte zu Bring! hinzufügen",
|
||||
"search_prices": "🔍 Alle Preise suchen",
|
||||
"suggest_btn": "🤖 Einkaufsvorschläge",
|
||||
"suggest_btn": "Einkaufsvorschläge",
|
||||
"smart_title": "🧠 Intelligente Vorhersagen",
|
||||
"smart_empty": "Keine Vorhersagen verfügbar.<br>Füge Produkte zur Vorratskammer hinzu, um intelligente Vorhersagen zu erhalten.",
|
||||
"smart_filter_all": "Alle",
|
||||
@@ -416,6 +418,10 @@
|
||||
"savings_offers": "· 🏷️ Du sparst €{amount} mit Angeboten",
|
||||
"searching_progress": "Suche {current}/{total}...",
|
||||
"remove_error": "Fehler beim Entfernen",
|
||||
"btn_fetch_prices": "Preise suchen",
|
||||
"price_total_label": "💰 Geschätzter Gesamtpreis:",
|
||||
"price_loading": "Preise werden gesucht…",
|
||||
"price_not_found": "Preis n/v",
|
||||
"suggest_loading": "Analyse läuft...",
|
||||
"suggest_error": "Fehler bei der Vorschlagserstellung",
|
||||
"priority_high": "Hoch",
|
||||
@@ -508,6 +514,15 @@
|
||||
"email_label": "📧 Bring! E-Mail",
|
||||
"password_label": "🔒 Bring! Passwort"
|
||||
},
|
||||
"price": {
|
||||
"title": "💰 Preisschätzung (KI)",
|
||||
"hint": "Zeigt geschätzte Kosten pro Produkt in der Einkaufsliste mithilfe von KI an.",
|
||||
"enabled_label": "Preisschätzung aktivieren",
|
||||
"country_label": "🌍 Referenzland",
|
||||
"currency_label": "💱 Währung",
|
||||
"update_label": "🔄 Preise aktualisieren alle",
|
||||
"update_suffix": "Monate"
|
||||
},
|
||||
"recipe": {
|
||||
"title": "🍳 Rezept-Einstellungen",
|
||||
"hint": "Konfiguriere die Standardoptionen für die Rezeptgenerierung.",
|
||||
@@ -906,6 +921,7 @@
|
||||
},
|
||||
"meal_plan": {
|
||||
"reset_success": "Wochenplan zurückgesetzt",
|
||||
"not_available": "nicht im Vorrat verfügbar",
|
||||
"suggested_by": "vom Wochenplan vorgeschlagen"
|
||||
},
|
||||
"kiosk_session": {
|
||||
|
||||
Reference in New Issue
Block a user