/**
* cuentas.js — Accounts receivable logic for Nexus Autoparts
*/
(function () {
'use strict';
var API = '';
var currentCustomerId = null;
var customerPage = 1;
// ================================================================
// Utility
// ================================================================
function toast(msg, type) {
var el = document.createElement('div');
el.className = 'toast ' + (type || 'success');
el.textContent = msg;
document.body.appendChild(el);
setTimeout(function () { el.remove(); }, 3000);
}
function api(path, opts) {
opts = opts || {};
return fetch(API + path, opts).then(function (r) {
if (!r.ok) return r.json().then(function (d) { throw new Error(d.error || 'Error'); });
return r.json();
});
}
function esc(s) {
if (!s) return '';
var d = document.createElement('div');
d.textContent = s;
return d.innerHTML;
}
function fmt(n) {
return '$' + (parseFloat(n) || 0).toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
function fmtDate(d) {
if (!d) return '';
var dt = new Date(d);
return dt.toLocaleDateString('es-MX', { day: '2-digit', month: 'short', year: 'numeric' });
}
// ================================================================
// Customer List
// ================================================================
var searchTimer = null;
document.getElementById('customer-search').addEventListener('input', function () {
clearTimeout(searchTimer);
searchTimer = setTimeout(function () {
customerPage = 1;
loadCustomers();
}, 400);
});
function loadCustomers() {
var search = document.getElementById('customer-search').value;
var grid = document.getElementById('customer-grid');
grid.innerHTML = '
Cargando...
';
var params = '?page=' + customerPage + '&per_page=30';
if (search) params += '&search=' + encodeURIComponent(search);
api('/api/pos/customers' + params).then(function (res) {
var data = res.data || [];
if (data.length === 0) {
grid.innerHTML = 'No se encontraron clientes
';
document.getElementById('customer-pagination').innerHTML = '';
return;
}
grid.innerHTML = data.map(function (c) {
return '' +
'
' + esc(c.name) + '
' +
'
' + esc(c.rfc || 'Sin RFC') + '
' +
'
' +
'' + fmt(c.balance) + '' +
'Limite: ' + fmt(c.credit_limit) + '
';
}).join('');
grid.querySelectorAll('.customer-card-item').forEach(function (card) {
card.addEventListener('click', function () {
showCustomerDetail(parseInt(card.getAttribute('data-id')));
});
});
// Pagination
var pag = res.pagination;
var pagEl = document.getElementById('customer-pagination');
if (pag.total_pages <= 1) { pagEl.innerHTML = ''; return; }
pagEl.innerHTML = '' +
'Pag ' + pag.page + '/' + pag.total_pages + '' +
'';
pagEl.querySelectorAll('button').forEach(function (btn) {
btn.addEventListener('click', function () {
customerPage = parseInt(btn.getAttribute('data-p'));
loadCustomers();
});
});
}).catch(function (err) {
console.error('Error loading customers:', err);
grid.innerHTML = 'Error al cargar clientes
';
});
}
// ================================================================
// Customer Detail
// ================================================================
function showCustomerDetail(customerId) {
currentCustomerId = customerId;
document.getElementById('list-view').style.display = 'none';
document.getElementById('detail-view').style.display = 'block';
api('/api/pos/customers/' + customerId + '/statement').then(function (res) {
var c = res.customer;
document.getElementById('dh-name').textContent = c.name;
document.getElementById('dh-rfc').textContent = c.rfc || 'Sin RFC';
var balEl = document.getElementById('dh-balance');
balEl.textContent = fmt(c.balance);
balEl.className = 'dh-value ' + (c.balance > 0 ? 'danger' : 'success');
document.getElementById('dh-limit').textContent = fmt(c.credit_limit);
document.getElementById('dh-terms').textContent = c.payment_terms + ' dias';
// Invoices
var invBody = document.getElementById('invoice-list');
if (res.invoices.length === 0) {
invBody.innerHTML = '| Sin facturas |
';
} else {
invBody.innerHTML = res.invoices.map(function (i) {
return '' +
'| ' + esc(i.folio) + ' | ' +
'' + fmtDate(i.date_issued) + ' | ' +
'' + fmt(i.total) + ' | ' +
'' + fmt(i.amount_paid) + ' | ' +
'' + i.status + ' |
';
}).join('');
}
// Payments
var payBody = document.getElementById('payment-list');
if (res.payments.length === 0) {
payBody.innerHTML = '| Sin pagos |
';
} else {
payBody.innerHTML = res.payments.map(function (p) {
return '' +
'| ' + fmtDate(p.date_payment) + ' | ' +
'' + fmt(p.amount) + ' | ' +
'' + esc(p.payment_method) + ' | ' +
'' + esc(p.reference || '') + ' | ' +
'' + esc(p.invoice_folio || 'General') + ' |
';
}).join('');
}
// Populate invoice dropdown for payment form
var invSelect = document.getElementById('pay-invoice');
invSelect.innerHTML = '';
res.invoices.filter(function (i) { return i.status !== 'paid' && i.status !== 'cancelled'; })
.forEach(function (i) {
invSelect.innerHTML += '';
});
});
}
document.getElementById('btn-back-list').addEventListener('click', function () {
document.getElementById('detail-view').style.display = 'none';
document.getElementById('list-view').style.display = 'block';
currentCustomerId = null;
loadCustomers();
});
// ================================================================
// Register Payment
// ================================================================
document.getElementById('btn-pay').addEventListener('click', function () {
var amount = parseFloat(document.getElementById('pay-amount').value);
if (!amount || amount <= 0) {
toast('Ingresa un monto valido', 'error');
return;
}
var invoiceId = document.getElementById('pay-invoice').value;
api('/api/pos/payments', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
customer_id: currentCustomerId,
amount: amount,
payment_method: document.getElementById('pay-method').value,
reference: document.getElementById('pay-reference').value.trim() || null,
invoice_id: invoiceId ? parseInt(invoiceId) : null,
notes: document.getElementById('pay-notes').value.trim() || null
})
}).then(function () {
toast('Pago de ' + fmt(amount) + ' registrado');
// Clear form
document.getElementById('pay-amount').value = '';
document.getElementById('pay-reference').value = '';
document.getElementById('pay-notes').value = '';
// Refresh detail
showCustomerDetail(currentCustomerId);
}).catch(function (err) {
toast(err.message, 'error');
});
});
// ================================================================
// Init
// ================================================================
loadCustomers();
})();