/* ============================================================ VENTA DIARIA Muestra las ventas consolidadas de un día específico. Agrega todas las facturas del día y suma unidades por producto. Depende de: STATE.adminInvoices (cargado por utils.js/loadPersistedData). Funciones de entrada: initDailySales() — llamado desde app.js al cargar la página renderDailySales(dateStr) — re-renderiza al cambiar fecha downloadDailySalesPDF() — genera y descarga el PDF del día ============================================================ */ /** * Inicializa la sección Venta Diaria. * Establece la fecha de hoy y renderiza el reporte. */ function initDailySales() { const input = document.getElementById('daily-sales-date'); if (!input) return; const today = new Date().toISOString().slice(0, 10); input.value = today; renderDailySales(today); } /** * Setea la fecha al día de hoy y re-renderiza. */ function setDailySalesToday() { const today = new Date().toISOString().slice(0, 10); const input = document.getElementById('daily-sales-date'); if (input) input.value = today; renderDailySales(today); } /** * Agrega las facturas de un día y retorna el resumen. * @param {string} dateStr — fecha en formato YYYY-MM-DD * @returns {{ items: Array, totalAmount: number, totalInvoices: number, totalUnits: number }} */ function getDailySalesData(dateStr) { if (!dateStr || !Array.isArray(STATE.adminInvoices)) { return { items: [], totalAmount: 0, totalInvoices: 0, totalUnits: 0 }; } // Filtrar facturas del día. inv.date puede ser es-AR ("25/4/2025 14:30:00") o ISO. const dayInvoices = STATE.adminInvoices.filter(inv => { return parseDateToYMD(inv.date || '') === dateStr; }); // Acumular unidades y montos por producto const byProduct = {}; dayInvoices.forEach(inv => { (inv.items || []).forEach(item => { const pid = item.id || item.product_id || item.name; if (!byProduct[pid]) { byProduct[pid] = { id: pid, name: item.name || '(sin nombre)', qty: 0, totalRevenue: 0, }; } const qty = Number(item.qty) || 0; const price = Number(item.price) || 0; byProduct[pid].qty += qty; byProduct[pid].totalRevenue += price * qty; }); }); const items = Object.values(byProduct).sort((a, b) => b.totalRevenue - a.totalRevenue); const totalAmount = items.reduce((s, i) => s + i.totalRevenue, 0); const totalUnits = items.reduce((s, i) => s + i.qty, 0); return { items, totalAmount, totalInvoices: dayInvoices.length, totalUnits }; } /** * Renderiza la tabla de venta diaria en el DOM. * @param {string} dateStr — fecha en formato YYYY-MM-DD */ function renderDailySales(dateStr) { if (!dateStr) return; const data = getDailySalesData(dateStr); // Tarjetas resumen const elAmount = document.getElementById('daily-total-amount'); const elInvoices = document.getElementById('daily-total-invoices'); const elUnits = document.getElementById('daily-total-units'); if (elAmount) elAmount.textContent = fmt(data.totalAmount); if (elInvoices) elInvoices.textContent = data.totalInvoices; if (elUnits) elUnits.textContent = data.totalUnits + ' u.'; // Título y subtítulo const titleEl = document.getElementById('daily-sales-title'); const subtitleEl = document.getElementById('daily-sales-subtitle'); if (titleEl) { const [year, month, day] = dateStr.split('-'); titleEl.textContent = `Ventas del ${day}/${month}/${year}`; } if (subtitleEl) subtitleEl.textContent = data.totalInvoices > 0 ? `${data.totalInvoices} factura${data.totalInvoices !== 1 ? 's' : ''}` : ''; const emptyEl = document.getElementById('daily-sales-empty'); const tableWrapper = document.getElementById('daily-sales-table-wrapper'); const tbody = document.getElementById('daily-sales-tbody'); const footerUnits = document.getElementById('daily-footer-units'); const footerTotal = document.getElementById('daily-footer-total'); if (data.items.length === 0) { if (emptyEl) emptyEl.classList.remove('hidden'); if (tableWrapper) tableWrapper.classList.add('hidden'); return; } if (emptyEl) emptyEl.classList.add('hidden'); if (tableWrapper) tableWrapper.classList.remove('hidden'); if (tbody) { tbody.innerHTML = data.items.map(item => { const avgPrice = item.qty > 0 ? item.totalRevenue / item.qty : 0; return `