fix(pos): wire buttons in contabilidad, facturacion, inventario, dashboard
- Contabilidad: Nueva Poliza modal + Exportar placeholder - Facturacion: Nueva Factura modal (sale_id input) + Nota Credito placeholder - Inventario: click en producto abre detalle con historial - Dashboard: Ver Detalles navega a paginas relevantes, campana a alertas Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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 =
|
||||
'<input type="text" placeholder="Cuenta contable" class="entry-account" style="padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />' +
|
||||
'<input type="number" placeholder="Debe" class="entry-debit" step="0.01" style="padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />' +
|
||||
'<input type="number" placeholder="Haber" class="entry-credit" step="0.01" style="padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />' +
|
||||
'<button class="btn btn--ghost btn--sm" onclick="this.closest(\'.entry-line\').remove()">×</button>';
|
||||
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 = '<span style="color:var(--color-error);">Fecha y descripcion son obligatorios.</span>';
|
||||
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 = '<span style="color:var(--color-error);">Agregue al menos una partida.</span>';
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await api('/entries', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ date, type, description, lines }),
|
||||
});
|
||||
resultEl.innerHTML = '<span style="color:var(--color-success);">Poliza creada exitosamente.</span>';
|
||||
setTimeout(() => closeNewEntryModal(), 1200);
|
||||
} catch (e) {
|
||||
resultEl.innerHTML = '<span style="color:var(--color-error);">Error: ' + e.message + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
}
|
||||
|
||||
tbody.innerHTML = items.map(function (it) {
|
||||
return '<tr>' +
|
||||
return '<tr style="cursor:pointer;" onclick="viewProductDetail(' + it.id + ')">' +
|
||||
'<td class="td--mono">' + esc(it.barcode) + '</td>' +
|
||||
'<td class="td--mono">' + esc(it.part_number) + '</td>' +
|
||||
'<td class="td--primary">' + esc(it.name) + '</td>' +
|
||||
@@ -82,8 +82,8 @@
|
||||
'<td style="text-align:right" class="td--amount">$' + fmt(it.price_3) + '</td>' +
|
||||
'<td>' + esc(it.location) + '</td>' +
|
||||
'<td>' +
|
||||
'<button class="btn btn--ghost btn--sm" onclick="viewHistory(' + it.id + ')">Historial</button> ' +
|
||||
'<button class="btn btn--ghost btn--sm" onclick="printBarcode(\'' + esc(it.barcode) + '\',\'' + esc(it.part_number) + '\',\'' + esc(it.name) + '\')">Etiqueta</button>' +
|
||||
'<button class="btn btn--ghost btn--sm" onclick="event.stopPropagation();viewHistory(' + it.id + ')">Historial</button> ' +
|
||||
'<button class="btn btn--ghost btn--sm" onclick="event.stopPropagation();printBarcode(\'' + esc(it.barcode) + '\',\'' + esc(it.part_number) + '\',\'' + esc(it.name) + '\')">Etiqueta</button>' +
|
||||
'</td></tr>';
|
||||
}).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 += '<div style="display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid var(--color-border);">';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">No. Parte</span><strong>' + esc(data.part_number) + '</strong></div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Nombre</span><strong>' + esc(data.name) + '</strong></div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Marca</span>' + esc(data.brand) + '</div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Codigo de Barras</span><span style="font-family:var(--font-mono);">' + esc(data.barcode) + '</span></div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Ubicacion</span>' + esc(data.location || '-') + '</div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Stock</span><strong style="font-size:1.2em;">' + (data.stock || 0) + '</strong></div>';
|
||||
html += '</div>';
|
||||
|
||||
// Prices
|
||||
html += '<div style="display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid var(--color-border);">';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Costo</span><span class="td--amount">$' + fmt(data.cost) + '</span></div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Precio 1</span><span class="td--amount">$' + fmt(data.price_1) + '</span></div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Precio 2</span><span class="td--amount">$' + fmt(data.price_2) + '</span></div>';
|
||||
html += '<div><span style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;display:block;">Precio 3</span><span class="td--amount">$' + fmt(data.price_3) + '</span></div>';
|
||||
html += '</div>';
|
||||
|
||||
// Movement history
|
||||
html += '<div style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:var(--tracking-widest);margin-bottom:8px;">Historial de Movimientos</div>';
|
||||
if (!history.length) {
|
||||
html += '<p style="color:var(--color-text-muted);text-align:center;padding:var(--space-4);">Sin movimientos</p>';
|
||||
} else {
|
||||
html += '<table class="data-table"><thead><tr><th>Fecha</th><th>Tipo</th><th>Cantidad</th><th>Costo</th><th>Empleado</th><th>Notas</th></tr></thead><tbody>';
|
||||
history.forEach(function (h) {
|
||||
var qtyColor = h.quantity > 0 ? 'var(--color-success)' : 'var(--color-error)';
|
||||
html += '<tr>' +
|
||||
'<td style="font-size:var(--text-caption);">' + esc(h.date) + '</td>' +
|
||||
'<td>' + esc(h.type) + '</td>' +
|
||||
'<td style="color:' + qtyColor + ';font-weight:600;">' + (h.quantity > 0 ? '+' : '') + h.quantity + '</td>' +
|
||||
'<td class="td--amount">' + (h.cost ? '$' + fmt(h.cost) : '\u2014') + '</td>' +
|
||||
'<td>' + esc(h.employee) + '</td>' +
|
||||
'<td style="font-size:var(--text-caption);">' + esc(h.notes) + '</td>' +
|
||||
'</tr>';
|
||||
});
|
||||
html += '</tbody></table>';
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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 = '<span style="color:var(--color-error);">Ingrese un ID de venta valido.</span>';
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const result = await api('/invoice', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ sale_id: saleId }),
|
||||
});
|
||||
resultEl.innerHTML = '<span style="color:var(--color-success);">Factura generada: ' + (result.provisional_folio || 'CFDI-' + (result.id || '')) + '</span>';
|
||||
loadFacturas();
|
||||
setTimeout(() => closeNewInvoiceModal(), 1500);
|
||||
} catch (e) {
|
||||
resultEl.innerHTML = '<span style="color:var(--color-error);">Error: ' + e.message + '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
// ---- 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,
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -1370,11 +1370,11 @@
|
||||
<option>Enero 2026</option>
|
||||
<option>Diciembre 2025</option>
|
||||
</select>
|
||||
<button class="btn btn--secondary">
|
||||
<button class="btn btn--secondary" onclick="window.exportarContabilidad()">
|
||||
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
Exportar
|
||||
</button>
|
||||
<button class="btn btn--primary">
|
||||
<button class="btn btn--primary" onclick="window.showNewEntryModal()">
|
||||
<svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
Nueva Póliza
|
||||
</button>
|
||||
@@ -2250,6 +2250,55 @@
|
||||
</main>
|
||||
</div><!-- /app-shell -->
|
||||
|
||||
<!-- Nueva Poliza Modal -->
|
||||
<div id="newEntryModalOverlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:9999;align-items:center;justify-content:center;">
|
||||
<div style="background:var(--color-surface-1);border-radius:var(--radius-lg);width:min(640px,90vw);max-height:85vh;overflow-y:auto;box-shadow:var(--shadow-lg);">
|
||||
<div style="padding:var(--space-5) var(--space-6);border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;">
|
||||
<div style="font-family:var(--font-heading);font-size:var(--text-h4);font-weight:var(--heading-weight-primary);">Nueva Poliza</div>
|
||||
<button class="btn btn--ghost btn--sm" onclick="window.closeNewEntryModal()">×</button>
|
||||
</div>
|
||||
<div style="padding:var(--space-6);">
|
||||
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4);margin-bottom:var(--space-4);">
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-caption);color:var(--color-text-muted);margin-bottom:var(--space-1);text-transform:uppercase;letter-spacing:var(--tracking-widest);">Fecha</label>
|
||||
<input type="date" id="entryDate" style="width:100%;padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />
|
||||
</div>
|
||||
<div>
|
||||
<label style="display:block;font-size:var(--text-caption);color:var(--color-text-muted);margin-bottom:var(--space-1);text-transform:uppercase;letter-spacing:var(--tracking-widest);">Tipo</label>
|
||||
<select id="entryType" style="width:100%;padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);">
|
||||
<option value="ingreso">Ingreso</option>
|
||||
<option value="egreso">Egreso</option>
|
||||
<option value="diario">Diario</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-bottom:var(--space-4);">
|
||||
<label style="display:block;font-size:var(--text-caption);color:var(--color-text-muted);margin-bottom:var(--space-1);text-transform:uppercase;letter-spacing:var(--tracking-widest);">Descripcion</label>
|
||||
<input type="text" id="entryDescription" placeholder="Concepto de la poliza" style="width:100%;padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />
|
||||
</div>
|
||||
<div style="margin-bottom:var(--space-3);">
|
||||
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--space-2);">
|
||||
<label style="font-size:var(--text-caption);color:var(--color-text-muted);text-transform:uppercase;letter-spacing:var(--tracking-widest);">Partidas</label>
|
||||
<button class="btn btn--ghost btn--sm" onclick="window.addEntryLine()">+ Agregar linea</button>
|
||||
</div>
|
||||
<div id="entryLines">
|
||||
<div class="entry-line" style="display:grid;grid-template-columns:2fr 1fr 1fr auto;gap:var(--space-2);margin-bottom:var(--space-2);align-items:center;">
|
||||
<input type="text" placeholder="Cuenta contable" class="entry-account" style="padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />
|
||||
<input type="number" placeholder="Debe" class="entry-debit" step="0.01" style="padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />
|
||||
<input type="number" placeholder="Haber" class="entry-credit" step="0.01" style="padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />
|
||||
<button class="btn btn--ghost btn--sm" onclick="this.closest('.entry-line').remove()">×</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="entryResult" style="margin-bottom:var(--space-3);"></div>
|
||||
</div>
|
||||
<div style="padding:var(--space-4) var(--space-6);border-top:1px solid var(--color-border);display:flex;justify-content:flex-end;gap:var(--space-3);">
|
||||
<button class="btn btn--ghost" onclick="window.closeNewEntryModal()">Cancelar</button>
|
||||
<button class="btn btn--primary" onclick="window.submitNewEntry()">Guardar Poliza</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/accounting.js"></script>
|
||||
|
||||
@@ -1431,7 +1431,7 @@
|
||||
</svg>
|
||||
Sucursal Centro
|
||||
</div>
|
||||
<button class="icon-btn" title="Notificaciones">
|
||||
<button class="icon-btn" title="Notificaciones" onclick="window.location.href='/pos/inventory#alertas'">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M8 1a5 5 0 00-5 5v3l-1.5 2h13L13 9V6a5 5 0 00-5-5z" stroke="currentColor" stroke-width="1.4"/>
|
||||
<path d="M6.5 13a1.5 1.5 0 003 0" stroke="currentColor" stroke-width="1.4"/>
|
||||
@@ -1457,7 +1457,7 @@
|
||||
<section>
|
||||
<div class="section-header">
|
||||
<span class="section-title">Resumen del día</span>
|
||||
<span class="section-action">Ver detalle →</span>
|
||||
<a href="/pos/reports" class="section-action" style="text-decoration:none;color:inherit;">Ver detalle →</a>
|
||||
</div>
|
||||
<div class="kpi-grid">
|
||||
|
||||
@@ -1656,7 +1656,7 @@
|
||||
<div style="font-family:var(--font-heading);font-weight:var(--heading-weight-secondary);font-size:var(--text-body-sm);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--color-text-secondary);">
|
||||
Top Productos
|
||||
</div>
|
||||
<div style="font-size:var(--text-caption);color:var(--color-primary);font-weight:var(--font-weight-semibold);cursor:pointer;">Ver todos</div>
|
||||
<a href="/pos/inventory" style="font-size:var(--text-caption);color:var(--color-primary);font-weight:var(--font-weight-semibold);cursor:pointer;text-decoration:none;">Ver todos</a>
|
||||
</div>
|
||||
<div class="rank-list">
|
||||
|
||||
@@ -1729,7 +1729,7 @@
|
||||
<div style="font-family:var(--font-heading);font-weight:var(--heading-weight-secondary);font-size:var(--text-body-sm);letter-spacing:var(--tracking-wider);text-transform:uppercase;color:var(--color-text-secondary);">
|
||||
Top Clientes
|
||||
</div>
|
||||
<div style="font-size:var(--text-caption);color:var(--color-primary);font-weight:var(--font-weight-semibold);cursor:pointer;">Ver todos</div>
|
||||
<a href="/pos/customers" style="font-size:var(--text-caption);color:var(--color-primary);font-weight:var(--font-weight-semibold);cursor:pointer;text-decoration:none;">Ver todos</a>
|
||||
</div>
|
||||
<div class="rank-list">
|
||||
|
||||
@@ -1886,7 +1886,7 @@
|
||||
</svg>
|
||||
En vivo
|
||||
</div>
|
||||
<div class="section-action" style="margin:0;">Ver historial →</div>
|
||||
<a href="/pos/reports" class="section-action" style="margin:0;text-decoration:none;color:inherit;">Ver historial →</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-wrap themed-scrollbar">
|
||||
|
||||
@@ -1522,14 +1522,14 @@
|
||||
</svg>
|
||||
Exportar
|
||||
</button>
|
||||
<button class="btn btn--secondary">
|
||||
<button class="btn btn--secondary" onclick="window.notaCreditoPlaceholder()">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M9 14l-4-4 4-4"/>
|
||||
<path d="M5 10h11a4 4 0 0 1 0 8h-1"/>
|
||||
</svg>
|
||||
Nota de Crédito
|
||||
</button>
|
||||
<button class="btn btn--primary">
|
||||
<button class="btn btn--primary" onclick="window.showNewInvoiceModal()">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<line x1="12" y1="5" x2="12" y2="19"/>
|
||||
<line x1="5" y1="12" x2="19" y2="12"/>
|
||||
@@ -2699,6 +2699,28 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Nueva Factura Modal -->
|
||||
<div id="newInvoiceModalOverlay" style="display:none;position:fixed;inset:0;background:rgba(0,0,0,0.5);z-index:9999;align-items:center;justify-content:center;">
|
||||
<div style="background:var(--color-surface-1);border-radius:var(--radius-lg);width:min(480px,90vw);box-shadow:var(--shadow-lg);">
|
||||
<div style="padding:var(--space-5) var(--space-6);border-bottom:1px solid var(--color-border);display:flex;justify-content:space-between;align-items:center;">
|
||||
<div style="font-family:var(--font-heading);font-size:var(--text-h4);font-weight:var(--heading-weight-primary);">Nueva Factura</div>
|
||||
<button class="btn btn--ghost btn--sm" onclick="window.closeNewInvoiceModal()">×</button>
|
||||
</div>
|
||||
<div style="padding:var(--space-6);">
|
||||
<p style="font-size:var(--text-body-sm);color:var(--color-text-muted);margin-bottom:var(--space-4);">Ingrese el ID de la venta para generar el CFDI (Ingreso).</p>
|
||||
<div style="margin-bottom:var(--space-4);">
|
||||
<label style="display:block;font-size:var(--text-caption);color:var(--color-text-muted);margin-bottom:var(--space-1);text-transform:uppercase;letter-spacing:var(--tracking-widest);">ID de Venta</label>
|
||||
<input type="number" id="invoiceSaleId" placeholder="Ej: 1042" style="width:100%;padding:var(--space-2) var(--space-3);border:1px solid var(--color-border);border-radius:var(--radius-md);background:var(--color-surface-2);color:var(--color-text-primary);font-size:var(--text-body-sm);" />
|
||||
</div>
|
||||
<div id="invoiceResult" style="margin-bottom:var(--space-3);"></div>
|
||||
</div>
|
||||
<div style="padding:var(--space-4) var(--space-6);border-top:1px solid var(--color-border);display:flex;justify-content:flex-end;gap:var(--space-3);">
|
||||
<button class="btn btn--ghost" onclick="window.closeNewInvoiceModal()">Cancelar</button>
|
||||
<button class="btn btn--primary" onclick="window.submitNewInvoice()">Generar Factura</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/invoicing.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user