diff --git a/assets/js/app.js b/assets/js/app.js index c1c1664..65d1497 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -7736,12 +7736,20 @@ async function confirmMoveAfterUse(productId, fromLoc, toLoc, openedId) { } async function submitUseAll() { - // Gate: show a countdown-confirmation before the destructive use_all call const name = currentProduct ? currentProduct.name : ''; const items0 = _useCurrentItems ? _useCurrentItems.filter(i => parseFloat(i.quantity) > 0) : []; + + // If there are opened packages, show the disambiguation FIRST (before the destructive confirm) + const allOpened = items0.filter(_isOpenedInventoryItem); + if (allOpened.length >= 1) { + _showUseAllDisambiguation(allOpened, items0); + return; + } + + // No opened packages → standard destructive confirm const totalQty = items0.reduce((s, i) => s + parseFloat(i.quantity || 0), 0); const unit = items0[0]?.unit || 'pz'; - const qtyStr = formatQuantity(totalQty, unit, items0[0]?.default_quantity, items0[0]?.package_unit); + const qtyStr = stripHtml(formatQuantity(totalQty, unit, items0[0]?.default_quantity, items0[0]?.package_unit)); _showDestructiveConfirm( t('use.use_all_confirm_title') || '✅ Finisci tutto', `${t('use.use_all_confirm_msg') || 'Conferma che hai finito tutto il prodotto:'} "${name}" (${qtyStr})`, @@ -7751,44 +7759,20 @@ async function submitUseAll() { } async function _doSubmitUseAll() { + // Called only when there are no opened packages (submitUseAll already handles disambiguation) showLoading(true); try { - const currentLoc = document.getElementById('use-location')?.value || '__all__'; - const items = _useCurrentItems.filter(i => parseFloat(i.quantity) > 0); - - const allOpened = items.filter(_isOpenedInventoryItem); - - let useLocation; - - if (allOpened.length >= 1) { - // One or more opened packages → always ask the user what they mean - showLoading(false); - _showUseAllDisambiguation(allOpened, items); - return; - } else { - // No opened packages anywhere → finish everything (original behaviour) - useLocation = '__all__'; - } - - const isOpenedFinish = useLocation !== '__all__' && items.some( - i => i.location === useLocation && _isOpenedInventoryItem(i) - ); - const result = await api('inventory_use', {}, 'POST', { product_id: currentProduct.id, use_all: true, - location: useLocation, + location: '__all__', }); showLoading(false); if (result.success) { - const toastMsg = isOpenedFinish - ? `🔓 ${t('use.toast_opened_finished').replace('{name}', currentProduct.name)}` - : `📤 ${currentProduct.name} terminato!`; - showToast(toastMsg, 'success'); + showToast(`📤 ${currentProduct.name} terminato!`, 'success'); if (result.added_to_bring) { setTimeout(() => showToast(t('use.toast_bring'), 'info'), 1500); } - // Check low stock (product may exist at other locations) showLowStockBringPrompt(result, () => showPage('dashboard')); } else { showToast(result.error || 'Errore', 'error'); @@ -7805,23 +7789,23 @@ async function _doSubmitUseAll() { */ function _showUseAllDisambiguation(openedItems, allItems) { const contentEl = document.getElementById('modal-content'); + const name = currentProduct ? currentProduct.name : ''; + const locButtons = openedItems.map(item => { const locInfo = LOCATIONS[item.location] || { icon: '📦', label: item.location }; - const qtyStr = formatQuantity(parseFloat(item.quantity), item.unit, item.default_quantity, item.package_unit); + const qtyStr = stripHtml(formatQuantity(parseFloat(item.quantity), item.unit, item.default_quantity, item.package_unit)); return ``; }).join(''); // Option to finish everything const totalQty = allItems.reduce((s, i) => s + parseFloat(i.quantity), 0); const unit = allItems[0]?.unit || 'pz'; - const defaultQty = allItems[0]?.default_quantity; - const pkgUnit = allItems[0]?.package_unit; - const totalStr = formatQuantity(totalQty, unit, defaultQty, pkgUnit); + const totalStr = stripHtml(formatQuantity(totalQty, unit, allItems[0]?.default_quantity, allItems[0]?.package_unit)); contentEl.innerHTML = `
${t('use.disambiguation_hint')}
${locButtons} `; document.getElementById('modal-overlay').style.display = 'flex'; } +function _confirmThenSubmitUseAllAt(location, isOpenedOnly) { + const name = currentProduct ? currentProduct.name : ''; + const items = _useCurrentItems ? _useCurrentItems.filter(i => parseFloat(i.quantity) > 0) : []; + if (isOpenedOnly) { + // Finisce solo la confezione aperta — azione leggera, nessun confirm necessario + _submitUseAllAt(location, true); + return; + } + // Finisce tutto — richiede confirm distruttivo + const totalQty = items.reduce((s, i) => s + parseFloat(i.quantity || 0), 0); + const unit = items[0]?.unit || 'pz'; + const qtyStr = stripHtml(formatQuantity(totalQty, unit, items[0]?.default_quantity, items[0]?.package_unit)); + _showDestructiveConfirm( + t('use.use_all_confirm_title') || '✅ Finisci tutto', + `${t('use.use_all_confirm_msg') || 'Conferma che hai finito tutto il prodotto:'} "${name}" (${qtyStr})`, + () => _submitUseAllAt('__all__', false), + t('use.use_all_confirm_btn') || '✅ Sì, finito' + ); +} + async function _submitUseAllAt(location, isOpenedOnly) { showLoading(true); try { @@ -10321,6 +10325,11 @@ function escapeHtml(str) { return div.innerHTML; } +function stripHtml(str) { + if (!str) return ''; + return str.replace(/<[^>]*>/g, ''); +} + function formatDate(dateStr) { if (!dateStr) return ''; const d = new Date(dateStr + 'T00:00:00'); diff --git a/index.html b/index.html index 0b2b071..da7e3b1 100644 --- a/index.html +++ b/index.html @@ -1462,6 +1462,6 @@