From a5a6e80b315e6c47e400b893564ffe3179697c11 Mon Sep 17 00:00:00 2001 From: dadaloop82 Date: Mon, 27 Apr 2026 13:45:10 +0000 Subject: [PATCH] fix: use product_shopping_name in all Bring! add paths from low-stock flow - inventory_use API now returns product_shopping_name in response - showLowStockBringPrompt: uses generic shopping name (e.g. Affettato) as Bring! item name, specific product name + brand as specification field - addLowStockToBring: reads from window._lowStockName instead of arg - Auto-add on depletion JS fallback: same generic-name pattern - Deduplication check now tries both shoppingName and raw name --- api/index.php | 5 ++++- assets/js/app.js | 33 +++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/api/index.php b/api/index.php index c1dff16..24e3861 100644 --- a/api/index.php +++ b/api/index.php @@ -1120,7 +1120,7 @@ function useFromInventory(PDO $db): void { $totalRemaining = round((float)($stmt->fetchColumn() ?: 0), 6); // Get product info for low-stock prompt - $stmt = $db->prepare("SELECT name, brand, unit, default_quantity, package_unit FROM products WHERE id = ?"); + $stmt = $db->prepare("SELECT name, brand, unit, default_quantity, package_unit, shopping_name FROM products WHERE id = ?"); $stmt->execute([$productId]); $prodInfo = $stmt->fetch(); @@ -1132,6 +1132,9 @@ function useFromInventory(PDO $db): void { $response['product_unit'] = $prodInfo['unit']; $response['product_default_qty'] = (float)($prodInfo['default_quantity'] ?: 0); $response['product_package_unit'] = $prodInfo['package_unit'] ?: ''; + // Generic shopping name for Bring! (e.g. "Affettato" for "Mortadella IGP") + $shopping = $prodInfo['shopping_name'] ?: computeShoppingName($prodInfo['name'], '', $prodInfo['brand']); + $response['product_shopping_name'] = $shopping; } if ($openedId) $response['opened_id'] = $openedId; echo json_encode($response); diff --git a/assets/js/app.js b/assets/js/app.js index 4cd5cac..3f01562 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -5918,6 +5918,10 @@ function _matchBringToSmart(bringName, smartItems) { function showLowStockBringPrompt(result, afterCallback) { const name = result.product_name || currentProduct?.name || ''; + // Generic shopping name (e.g. "Affettato" for "Mortadella IGP"). Falls back to + // the specific name when shopping_name is not set (older API call), so behaviour + // is unchanged for legacy callers. + const shoppingName = result.product_shopping_name || name; const unit = result.product_unit || currentProduct?.unit || 'pz'; const defaultQty = result.product_default_qty || parseFloat(currentProduct?.default_quantity) || 0; const totalRemaining = result.total_remaining; @@ -5927,12 +5931,13 @@ function showLowStockBringPrompt(result, afterCallback) { if (totalRemaining <= 0) { // Backend auto-adds to Bring! when fully depleted. If it failed (Bring not // configured, or product already on list), silently attempt it from JS. - if (!result.added_to_bring && name) { + if (!result.added_to_bring && shoppingName) { // Fire-and-forget โ€” don't block the callback + // Use generic shopping name; specific name goes into specification. + const spec = shoppingName !== name ? name + (result.product_brand ? ` ยท ${result.product_brand}` : '') : ''; (async () => { try { - const spec = name; - const payload = { items: [{ name, specification: spec }] }; + const payload = { items: [{ name: shoppingName, specification: spec }] }; if (shoppingListUUID) payload.listUUID = shoppingListUUID; const data = await api('bring_add', {}, 'POST', payload); if (data.success && data.added > 0) { @@ -5962,7 +5967,7 @@ function showLowStockBringPrompt(result, afterCallback) { // --- Deduplication check --- // 1. Already on Bring! list (shoppingItems)? - const alreadyOnBring = _findSimilarItem(name, shoppingItems); + const alreadyOnBring = _findSimilarItem(shoppingName, shoppingItems) || _findSimilarItem(name, shoppingItems); if (alreadyOnBring) { // Already present (same or similar item). Just inform and continue. showToast(`๐Ÿ›’ "${escapeHtml(alreadyOnBring.name)}" giร  nella lista della spesa`, 'info'); @@ -5971,7 +5976,7 @@ function showLowStockBringPrompt(result, afterCallback) { } // 2. In smart shopping predictions? - const smartMatch = _findSimilarItem(name, smartShoppingItems); + const smartMatch = _findSimilarItem(shoppingName, smartShoppingItems) || _findSimilarItem(name, smartShoppingItems); const smartUrgencyLabel = { critical: '๐Ÿ”ด Urgente', high: '๐ŸŸ  Presto', medium: '๐ŸŸก Pianifica', low: '๐ŸŸข Previsione' }; @@ -5983,9 +5988,13 @@ function showLowStockBringPrompt(result, afterCallback) { `; } - // Build specification from product name for Bring + // _lowStockName = generic name that goes into Bring! (e.g. "Affettato") + // _lowStockSpec = specific product name used as specification (e.g. "Mortadella IGP") window._lowStockAfterCallback = afterCallback; - window._lowStockSpec = name; + window._lowStockName = shoppingName; + window._lowStockSpec = shoppingName !== name + ? name + (result.product_brand ? ` ยท ${result.product_brand}` : '') + : name; document.getElementById('modal-content').innerHTML = `