diff --git a/pos/static/js/accounting.js b/pos/static/js/accounting.js index d0367be..195abdf 100644 --- a/pos/static/js/accounting.js +++ b/pos/static/js/accounting.js @@ -388,11 +388,92 @@ const Accounting = (() => { document.addEventListener('DOMContentLoaded', init); + // ---- Exportar placeholder ---- + function exportarContabilidad() { + alert('Exportar: proximamente'); + } + + // ---- Nueva Poliza modal ---- + function showNewEntryModal() { + const overlay = document.getElementById('newEntryModalOverlay'); + if (!overlay) return; + // Set default date to today + const dateInput = overlay.querySelector('#entryDate'); + if (dateInput && !dateInput.value) { + dateInput.value = new Date().toISOString().slice(0, 10); + } + document.getElementById('entryResult').innerHTML = ''; + overlay.style.display = 'flex'; + } + + function closeNewEntryModal() { + const overlay = document.getElementById('newEntryModalOverlay'); + if (overlay) overlay.style.display = 'none'; + } + + function addEntryLine() { + const container = document.getElementById('entryLines'); + if (!container) return; + const line = document.createElement('div'); + line.className = 'entry-line'; + line.style.cssText = 'display:grid;grid-template-columns:2fr 1fr 1fr auto;gap:var(--space-2);margin-bottom:var(--space-2);align-items:center;'; + line.innerHTML = + '' + + '' + + '' + + ''; + container.appendChild(line); + } + + async function submitNewEntry() { + const date = document.getElementById('entryDate').value; + const type = document.getElementById('entryType').value; + const description = document.getElementById('entryDescription').value.trim(); + const resultEl = document.getElementById('entryResult'); + + if (!date || !description) { + resultEl.innerHTML = 'Fecha y descripcion son obligatorios.'; + return; + } + + const lines = []; + document.querySelectorAll('#entryLines .entry-line').forEach(row => { + const account = row.querySelector('.entry-account').value.trim(); + const debit = parseFloat(row.querySelector('.entry-debit').value) || 0; + const credit = parseFloat(row.querySelector('.entry-credit').value) || 0; + if (account && (debit || credit)) { + lines.push({ account, debit, credit }); + } + }); + + if (!lines.length) { + resultEl.innerHTML = 'Agregue al menos una partida.'; + return; + } + + try { + await api('/entries', { + method: 'POST', + body: JSON.stringify({ date, type, description, lines }), + }); + resultEl.innerHTML = 'Poliza creada exitosamente.'; + setTimeout(() => closeNewEntryModal(), 1200); + } catch (e) { + resultEl.innerHTML = 'Error: ' + e.message + ''; + } + } + // Expose switchTab globally for onclick handlers in HTML window.switchTab = switchTab; + window.exportarContabilidad = exportarContabilidad; + window.showNewEntryModal = showNewEntryModal; + window.closeNewEntryModal = closeNewEntryModal; + window.addEntryLine = addEntryLine; + window.submitNewEntry = submitNewEntry; return { switchTab, loadAging, loadAccountsPayable, loadBalanceSheet, loadIncomeStatement, loadCashFlow, loadReconciliation, loadPeriodClose, + exportarContabilidad, showNewEntryModal, closeNewEntryModal, addEntryLine, submitNewEntry, }; })(); diff --git a/pos/static/js/inventory.js b/pos/static/js/inventory.js index 59d96c4..b16199f 100644 --- a/pos/static/js/inventory.js +++ b/pos/static/js/inventory.js @@ -70,7 +70,7 @@ } tbody.innerHTML = items.map(function (it) { - return '' + + return '' + '' + esc(it.barcode) + '' + '' + esc(it.part_number) + '' + '' + esc(it.name) + '' + @@ -82,8 +82,8 @@ '$' + fmt(it.price_3) + '' + '' + esc(it.location) + '' + '' + - ' ' + - '' + + ' ' + + '' + ''; }).join(''); @@ -439,6 +439,61 @@ w.print(); } + // ===================================================================== + // PRODUCT DETAIL MODAL (shows item info + movement history) + // ===================================================================== + + function viewProductDetail(itemId) { + apiFetch(API + '/items/' + itemId).then(function (data) { + if (!data || data.error) { + alert(data ? data.error : 'Error de red'); + return; + } + var history = data.history || []; + var html = ''; + + // Product info header + html += '
'; + html += '
No. Parte' + esc(data.part_number) + '
'; + html += '
Nombre' + esc(data.name) + '
'; + html += '
Marca' + esc(data.brand) + '
'; + html += '
Codigo de Barras' + esc(data.barcode) + '
'; + html += '
Ubicacion' + esc(data.location || '-') + '
'; + html += '
Stock' + (data.stock || 0) + '
'; + html += '
'; + + // Prices + html += '
'; + html += '
Costo$' + fmt(data.cost) + '
'; + html += '
Precio 1$' + fmt(data.price_1) + '
'; + html += '
Precio 2$' + fmt(data.price_2) + '
'; + html += '
Precio 3$' + fmt(data.price_3) + '
'; + html += '
'; + + // Movement history + html += '
Historial de Movimientos
'; + if (!history.length) { + html += '

Sin movimientos

'; + } else { + html += ''; + history.forEach(function (h) { + var qtyColor = h.quantity > 0 ? 'var(--color-success)' : 'var(--color-error)'; + html += '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''; + }); + html += '
FechaTipoCantidadCostoEmpleadoNotas
' + esc(h.date) + '' + esc(h.type) + '' + (h.quantity > 0 ? '+' : '') + h.quantity + '' + (h.cost ? '$' + fmt(h.cost) : '\u2014') + '' + esc(h.employee) + '' + esc(h.notes) + '
'; + } + document.getElementById('historyContent').innerHTML = html; + document.getElementById('historyModal').classList.add('is-open'); + }); + } + // ===================================================================== // EXPOSE GLOBALS (for onclick handlers in HTML) // ===================================================================== @@ -446,6 +501,7 @@ window._loadItems = function (p) { loadItems(p); }; window.loadItems = function (p, q) { loadItems(p, q); }; window.viewHistory = viewHistory; + window.viewProductDetail = viewProductDetail; window.closeHistoryModal = closeHistoryModal; window.showCreateModal = showCreateModal; window.closeCreateModal = closeCreateModal; diff --git a/pos/static/js/invoicing.js b/pos/static/js/invoicing.js index fecc6b2..bd65a73 100644 --- a/pos/static/js/invoicing.js +++ b/pos/static/js/invoicing.js @@ -438,11 +438,56 @@ const Invoicing = (() => { document.addEventListener('DOMContentLoaded', init); + // ---- Nueva Factura modal ---- + function showNewInvoiceModal() { + const overlay = document.getElementById('newInvoiceModalOverlay'); + if (!overlay) return; + const input = overlay.querySelector('#invoiceSaleId'); + if (input) input.value = ''; + document.getElementById('invoiceResult').innerHTML = ''; + overlay.style.display = 'flex'; + } + + function closeNewInvoiceModal() { + const overlay = document.getElementById('newInvoiceModalOverlay'); + if (overlay) overlay.style.display = 'none'; + } + + async function submitNewInvoice() { + const saleId = parseInt(document.getElementById('invoiceSaleId').value); + const resultEl = document.getElementById('invoiceResult'); + if (!saleId) { + resultEl.innerHTML = 'Ingrese un ID de venta valido.'; + return; + } + try { + const result = await api('/invoice', { + method: 'POST', + body: JSON.stringify({ sale_id: saleId }), + }); + resultEl.innerHTML = 'Factura generada: ' + (result.provisional_folio || 'CFDI-' + (result.id || '')) + ''; + loadFacturas(); + setTimeout(() => closeNewInvoiceModal(), 1500); + } catch (e) { + resultEl.innerHTML = 'Error: ' + e.message + ''; + } + } + + // ---- Nota de Credito placeholder ---- + function notaCreditoPlaceholder() { + alert('Nota de credito: proximamente'); + } + // Expose switchTab globally for onclick handlers in HTML window.switchTab = switchTab; + window.showNewInvoiceModal = showNewInvoiceModal; + window.closeNewInvoiceModal = closeNewInvoiceModal; + window.submitNewInvoice = submitNewInvoice; + window.notaCreditoPlaceholder = notaCreditoPlaceholder; return { switchTab, loadFacturas, loadNotas, loadComplementos, loadCancelaciones, showDetail, showCancelModal, confirmCancel, processQueue, + showNewInvoiceModal, closeNewInvoiceModal, submitNewInvoice, notaCreditoPlaceholder, }; })(); diff --git a/pos/templates/accounting.html b/pos/templates/accounting.html index 55451d3..a41d1c7 100644 --- a/pos/templates/accounting.html +++ b/pos/templates/accounting.html @@ -1370,11 +1370,11 @@ - - @@ -2250,6 +2250,55 @@ + + + diff --git a/pos/templates/dashboard.html b/pos/templates/dashboard.html index 22d7893..f39d1cb 100644 --- a/pos/templates/dashboard.html +++ b/pos/templates/dashboard.html @@ -1431,7 +1431,7 @@ Sucursal Centro - - - + +
+

Ingrese el ID de la venta para generar el CFDI (Ingreso).

+
+ + +
+
+
+
+ + +
+ + +