/* ============================================================ BULK PRODUCTS EDIT ============================================================ */ function toggleProductSelection(productId) { if (STATE.selectedProductsForBulkEdit.has(productId)) { removeSelectedProduct(productId); } else { addSelectedProduct(productId); } renderStockTable(); updateBulkEditPanel(); } function selectAllProducts() { STATE.products.forEach(p => addSelectedProduct(p.id)); renderStockTable(); updateBulkEditPanel(); } function deselectAllProducts() { clearSelectedProducts(); renderStockTable(); updateBulkEditPanel(); } function updateBulkEditPanel() { const panel = document.getElementById('bulk-edit-panel'); if (!panel) return; if (!hasSelectedProducts()) { panel.style.display = 'none'; return; } const count = getSelectedProducts().length; panel.style.display = 'block'; const countEl = document.getElementById('bulk-edit-count'); if (countEl) countEl.textContent = count; } function applyBulkEdit() { const costChangeInput = document.getElementById('bulk-edit-cost-change'); const saleChangeInput = document.getElementById('bulk-edit-sale-change'); const costChange = parseFloat(costChangeInput?.value) || 0; const saleChange = parseFloat(saleChangeInput?.value) || 0; if (costChange === 0 && saleChange === 0) { showToast('Ingresa un cambio de porcentaje', 'warning'); return; } const selectedIds = getSelectedProducts(); const affectedProducts = STATE.products.filter(p => selectedIds.includes(p.id)); if (!affectedProducts.length) { showToast('Selecciona al menos un producto', 'warning'); return; } // Show preview const previewHtml = `

Se afectarán ${affectedProducts.length} producto(s):

${affectedProducts.map(p => { const newCost = costChange !== 0 ? Math.round(p.cost * (1 + costChange / 100)) : p.cost; const newSale = saleChange !== 0 ? Math.round(p.sale * (1 + saleChange / 100)) : calculateSalePrice(newCost, p.margin); return ` `; }).join('')}
Producto Costo Actual Nuevo Costo Venta Actual Nueva Venta
${escapeHtml(p.name.substring(0, 30))} ${fmt(p.cost)} ${fmt(newCost)} ${fmt(p.sale)} ${fmt(newSale)}
`; const backdrop = document.createElement('div'); backdrop.className = 'overlay open'; backdrop.style.cssText = ` position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); z-index: 10000; display: flex; align-items: center; justify-content: center; `; const dialog = document.createElement('div'); dialog.className = 'card'; dialog.style.cssText = ` background: white; border-radius: 12px; padding: 24px; max-width: 800px; width: 90%; box-shadow: 0 20px 25px rgba(0, 0, 0, 0.15); z-index: 10001; max-height: 80vh; overflow-y: auto; `; dialog.innerHTML = `

Revisar cambios

${previewHtml}
`; backdrop.appendChild(dialog); document.body.appendChild(backdrop); document.getElementById('bulk-preview-cancel').onclick = () => { backdrop.remove(); }; document.getElementById('bulk-preview-confirm').onclick = () => { // Apply changes affectedProducts.forEach(p => { if (costChange !== 0) { p.cost = Math.round(p.cost * (1 + costChange / 100)); } if (saleChange !== 0) { p.sale = Math.round(p.sale * (1 + saleChange / 100)); } else if (costChange !== 0) { p.sale = calculateSalePrice(p.cost, p.margin); } }); persistData(); renderStockTable(); clearSelectedProducts(); updateBulkEditPanel(); backdrop.remove(); showToast(`Se actualizaron ${affectedProducts.length} producto(s)`, 'success'); // Clear inputs if (costChangeInput) costChangeInput.value = ''; if (saleChangeInput) saleChangeInput.value = ''; }; backdrop.onclick = (e) => { if (e.target === backdrop) { backdrop.remove(); } }; } function cancelBulkEdit() { clearSelectedProducts(); renderStockTable(); updateBulkEditPanel(); const costChangeInput = document.getElementById('bulk-edit-cost-change'); const saleChangeInput = document.getElementById('bulk-edit-sale-change'); if (costChangeInput) costChangeInput.value = ''; if (saleChangeInput) saleChangeInput.value = ''; }