';
}).join('');
// Store items for cart lookup
window._catalogItems = {};
items.forEach(function (it) { window._catalogItems[it.id] = it; });
}
function renderPagination(pg) {
var el = document.getElementById('pagination');
if (!pg || pg.total_pages <= 1) { el.innerHTML = ''; return; }
var html = '';
html += '' + pg.page + ' / ' + pg.total_pages + '';
html += '';
el.innerHTML = html;
}
function renderActiveFilters() {
var el = document.getElementById('activeFilters');
var chips = [];
if (currentFilters.category) chips.push('Cat: ' + currentFilters.category + ' ×');
if (currentFilters.brand) chips.push('' + escHtml(currentFilters.brand) + ' ×');
if (currentFilters.vehicle_brand) chips.push('Vehiculo: ' + escHtml(currentFilters.vehicle_brand) + ' ×');
el.innerHTML = chips.join('');
}
// ─── Sidebar filters ───
async function loadCategories() {
var data = await apiFetch(API + '/catalog/categories');
if (!data) return;
var ul = document.getElementById('categoryList');
var cats = data.data || [];
if (!cats.length) { ul.innerHTML = '
Sin categorias
'; return; }
ul.innerHTML = '
Todas
' +
cats.map(function (c) { return '
Cat #' + c.id + ' (' + c.count + ')
'; }).join('');
}
async function loadBrands() {
var data = await apiFetch(API + '/catalog/brands');
if (!data) return;
var ul = document.getElementById('brandList');
var brands = data.data || [];
if (!brands.length) { ul.innerHTML = '
Sin marcas
'; return; }
ul.innerHTML = '
Todas
' +
brands.map(function (b) { return '
' + escHtml(b.name) + ' (' + b.count + ')
'; }).join('');
}
// ─── Barcode scanner ───
async function lookupBarcode(code) {
var data = await apiFetch(API + '/catalog/barcode/' + encodeURIComponent(code));
if (!data || data.error) { alert('Parte no encontrada: ' + code); return; }
addToCart(data);
}
// Listen for rapid keypress (barcode scanners type fast, then Enter)
document.addEventListener('keydown', function (e) {
if (e.key === 'F1') { e.preventDefault(); document.getElementById('searchInput').focus(); return; }
if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') return;
if (e.key === 'Enter' && barcodeBuffer.length >= 4) {
lookupBarcode(barcodeBuffer.trim());
barcodeBuffer = '';
return;
}
if (e.key.length === 1) {
barcodeBuffer += e.key;
clearTimeout(barcodeTimeout);
barcodeTimeout = setTimeout(function () { barcodeBuffer = ''; }, 200);
}
});
// ─── Cart ───
function addToCart(item) {
var existing = cartItems.find(function (c) { return c.id === item.id; });
if (existing) {
existing.quantity += 1;
} else {
cartItems.push({
id: item.id, part_number: item.part_number, name: item.name,
brand: item.brand, price: item.price_1, tax_rate: item.tax_rate || 0.16,
unit: item.unit || 'PZA', stock: item.stock, quantity: 1
});
}
saveCart();
renderCart();
}
function removeFromCart(index) {
cartItems.splice(index, 1);
saveCart();
renderCart();
}
function updateQuantity(index, qty) {
qty = parseInt(qty);
if (qty <= 0) { removeFromCart(index); return; }
cartItems[index].quantity = qty;
saveCart();
renderCart();
}
function clearCartFn() {
cartItems = [];
saveCart();
renderCart();
}
function saveCart() {
localStorage.setItem('pos_cart', JSON.stringify(cartItems));
}
function renderCart() {
var badge = document.getElementById('cartBadge');
var total = cartItems.reduce(function (s, c) { return s + c.quantity; }, 0);
badge.textContent = total;
badge.style.display = total > 0 ? 'flex' : 'none';
var container = document.getElementById('cartItems');
var empty = document.getElementById('cartEmpty');
var checkoutBtn = document.getElementById('checkoutBtn');
if (!cartItems.length) {
container.innerHTML = '';
empty.style.display = 'block';
checkoutBtn.disabled = true;
document.getElementById('cartSubtotal').textContent = '$0.00';
document.getElementById('cartTax').textContent = '$0.00';
document.getElementById('cartTotal').textContent = '$0.00';
return;
}
empty.style.display = 'none';
checkoutBtn.disabled = false;
var subtotal = 0;
var tax = 0;
container.innerHTML = cartItems.map(function (c, i) {
var lineTotal = c.price * c.quantity;
var lineTax = lineTotal * c.tax_rate;
subtotal += lineTotal;
tax += lineTax;
return '
' +
'
' +
'
' + escHtml(c.name) + '
' +
'
' + escHtml(c.part_number) + '
' +
'
' +
'' +
'' + c.quantity + '' +
'' +
'
' +
'
' +
'
$' + fmt(lineTotal) + '
' +
'' +
'
';
}).join('');
document.getElementById('cartSubtotal').textContent = '$' + fmt(subtotal);
document.getElementById('cartTax').textContent = '$' + fmt(tax);
document.getElementById('cartTotal').textContent = '$' + fmt(subtotal + tax);
}
function toggleCart() {
document.getElementById('cartSidebar').classList.toggle('open');
}
function goToCheckout() {
localStorage.setItem('pos_cart', JSON.stringify(cartItems));
window.location.href = '/pos/sale';
}
// ─── External availability ───
async function checkExternalAvailability(partNumber) {
var pn = partNumber || currentFilters.q || '';
if (!pn) return;
var section = document.getElementById('externalSection');
var results = document.getElementById('externalResults');
section.style.display = 'block';
results.innerHTML = '
Buscando en bodegas...
';
var data = await apiFetch(API + '/catalog/external-availability/' + encodeURIComponent(pn));
if (!data || !data.data || !data.data.length) {
results.innerHTML = '
No se encontraron resultados externos para "' + escHtml(pn) + '"