(function() { 'use strict'; const API = '/pos/api/supplier-catalog'; const VEHICLE_API = '/pos/api/inventory/vehicles'; const token = localStorage.getItem('pos_token') || ''; let state = { q: '', category: '', make: '', model: '', year: '', engine: '', myeId: null, page: 1, perPage: 30, totalPages: 1, categories: [], items: [] }; function headers() { return { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' }; } let scAbort = null; let scSeq = 0; async function apiFetch(url) { if (scAbort) { scAbort.abort(); scAbort = null; } const ctrl = new AbortController(); scAbort = ctrl; try { const resp = await fetch(url, { headers: headers(), signal: ctrl.signal }); if (resp.status === 401) { window.location.href = '/pos/login'; return null; } if (!resp.ok) { console.error('API error', url, resp.status); return null; } return resp.json(); } catch (e) { if (e.name === 'AbortError') return null; console.error('API error', url, e); return null; } } async function apiFetchSeq(url) { const mySeq = ++scSeq; const data = await apiFetch(url); if (!data || scSeq !== mySeq) return null; return data; } // ─── Categories ───────────────────────────────────────────── async function loadCategories() { const data = await apiFetch(API + '/categories'); if (!data) return; state.categories = data.categories || []; renderCategories(); } function renderCategories() { const el = document.getElementById('categoriesGrid'); if (!el) return; let html = '
' + '
Todas
' + state.categories.reduce((a,c)=>a+c.count,0) + ' items
'; state.categories.forEach(function(c) { html += '
' + '
' + escapeHtml(c.name) + '
' + c.count + ' items
'; }); el.innerHTML = html; } window.selectCategory = function(name) { state.category = name; state.page = 1; renderCategories(); doSearch(); }; // ─── Vehicle filters ──────────────────────────────────────── async function loadMakes() { const data = await apiFetch(VEHICLE_API + '/makes'); if (!data) return; const sel = document.getElementById('filterMake'); sel.innerHTML = ''; (data.data || []).forEach(function(m) { sel.innerHTML += ''; }); } window.onMakeChange = async function() { const sel = document.getElementById('filterMake'); state.make = sel.value; state.model = ''; state.year = ''; state.engine = ''; state.myeId = null; document.getElementById('filterModel').disabled = true; document.getElementById('filterYear').disabled = true; document.getElementById('filterEngine').disabled = true; if (!state.make) { doSearch(); return; } const makes = await apiFetchSeq(VEHICLE_API + '/makes'); if (!makes) return; const brand = (makes.data || []).find(function(m) { return m.name_brand === state.make; }); if (!brand) { doSearch(); return; } const models = await apiFetchSeq(VEHICLE_API + '/models?brand_id=' + brand.id_brand); if (!models) return; const msel = document.getElementById('filterModel'); msel.innerHTML = ''; (models.data || []).forEach(function(m) { msel.innerHTML += ''; }); msel.disabled = false; doSearch(); }; window.onModelChange = async function() { const sel = document.getElementById('filterModel'); const modelId = sel.value; state.model = modelId ? sel.options[sel.selectedIndex].text : ''; state.year = ''; state.engine = ''; state.myeId = null; document.getElementById('filterYear').disabled = true; document.getElementById('filterEngine').disabled = true; if (!modelId) { doSearch(); return; } const years = await apiFetchSeq(VEHICLE_API + '/years?model_id=' + modelId); if (!years) return; const ysel = document.getElementById('filterYear'); ysel.innerHTML = ''; (years.data || []).forEach(function(y) { ysel.innerHTML += ''; }); ysel.disabled = false; doSearch(); }; window.onYearChange = async function() { const sel = document.getElementById('filterYear'); const yearId = sel.value; const modelId = document.getElementById('filterModel').value; state.year = yearId ? sel.options[sel.selectedIndex].text : ''; state.engine = ''; state.myeId = null; document.getElementById('filterEngine').disabled = true; if (!yearId || !modelId) { doSearch(); return; } const engines = await apiFetchSeq(VEHICLE_API + '/engines?model_id=' + modelId + '&year_id=' + yearId); if (!engines) return; const esel = document.getElementById('filterEngine'); esel.innerHTML = ''; (engines.data || []).forEach(function(e) { const label = escapeHtml(e.name_engine) + (e.trim_level ? ' (' + escapeHtml(e.trim_level) + ')' : ''); esel.innerHTML += ''; }); esel.disabled = false; doSearch(); }; // ─── Search ───────────────────────────────────────────────── window.doSearch = async function() { state.q = document.getElementById('searchInput').value.trim(); const engineSel = document.getElementById('filterEngine'); state.myeId = engineSel.value || null; let url = API + '/search?page=' + state.page + '&per_page=' + state.perPage; if (state.q) url += '&q=' + encodeURIComponent(state.q); if (state.category) url += '&category=' + encodeURIComponent(state.category); if (state.myeId) { url += '&mye_id=' + state.myeId; } else { if (state.make) url += '&make=' + encodeURIComponent(state.make); if (state.model) url += '&model=' + encodeURIComponent(state.model); if (state.year) url += '&year=' + encodeURIComponent(state.year); } const data = await apiFetch(url); if (!data) return; state.items = data.data || []; state.totalPages = (data.pagination || {}).total_pages || 1; renderItems(); renderPagination(); }; window.clearFilters = function() { document.getElementById('searchInput').value = ''; document.getElementById('filterMake').value = ''; document.getElementById('filterModel').innerHTML = ''; document.getElementById('filterModel').disabled = true; document.getElementById('filterYear').innerHTML = ''; document.getElementById('filterYear').disabled = true; document.getElementById('filterEngine').innerHTML = ''; document.getElementById('filterEngine').disabled = true; state.q = ''; state.category = ''; state.make = ''; state.model = ''; state.year = ''; state.engine = ''; state.myeId = null; state.page = 1; renderCategories(); doSearch(); }; // ─── Render results ───────────────────────────────────────── function renderItems() { const el = document.getElementById('partsGrid'); if (!el) return; if (!state.items.length) { el.innerHTML = '
🔍

Sin resultados

Intenta con otros filtros o terminos de busqueda.

'; return; } el.innerHTML = state.items.map(function(it) { return '
' + '
' + escapeHtml(it.sku) + '
' + '
' + escapeHtml(it.name) + '
' + '
' + '' + escapeHtml(it.category || 'SIN CATEGORIA') + '' + ' ' + escapeHtml(it.supplier_name) + '' + '
' + '
'; }).join(''); } function renderPagination() { const el = document.getElementById('pagination'); if (!el) return; if (state.totalPages <= 1) { el.innerHTML = ''; return; } let html = ''; html += 'Pagina ' + state.page + ' de ' + state.totalPages + ''; html += ''; el.innerHTML = html; } window.goPage = function(p) { state.page = p; doSearch(); }; // ─── Detail modal ─────────────────────────────────────────── window.openDetail = async function(id) { const data = await apiFetch(API + '/items/' + id); if (!data) return; document.getElementById('modalTitle').textContent = escapeHtml(data.sku); let html = ''; html += '
' + escapeHtml(data.name) + '
'; html += '

Informacion

' + '

Proveedor: ' + escapeHtml(data.supplier_name) + '
Categoria: ' + escapeHtml(data.category || 'N/A') + '

'; if (data.interchanges && data.interchanges.length) { html += '

Intercambios

' + data.interchanges.map(function(ix) { return '' + escapeHtml(ix.brand) + ' — ' + escapeHtml(ix.part_number) + ''; }).join('') + '
'; } if (data.compatibilities && data.compatibilities.length) { var seenCompat = {}; var uniqCompat = data.compatibilities.filter(function(c) { var key = (c.make || '') + '|' + (c.model || '') + '|' + (c.year || '') + '|' + (c.engine || ''); if (seenCompat[key]) return false; seenCompat[key] = true; return true; }); html += '

Vehiculos compatibles (' + uniqCompat.length + ')

' + '
' + uniqCompat.slice(0, 50).map(function(c) { return '
' + '' + escapeHtml(c.make || '') + ' ' + escapeHtml(c.model || '') + '
' + (c.year || '') + ' ' + escapeHtml(c.engine || '') + '
'; }).join('') + (uniqCompat.length > 50 ? '
... y ' + (uniqCompat.length - 50) + ' mas
' : '') + '
'; } document.getElementById('modalBody').innerHTML = html; document.getElementById('detailModal').classList.add('open'); }; window.closeModal = function() { document.getElementById('detailModal').classList.remove('open'); }; // ─── Utils ────────────────────────────────────────────────── function escapeHtml(s) { if (s == null) return ''; return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } // ─── Init ─────────────────────────────────────────────────── function init() { if (!token) { window.location.href = '/pos/login'; return; } loadCategories(); loadMakes(); doSearch().then(function() { var params = new URLSearchParams(window.location.search); var id = params.get('id'); if (id) { openDetail(parseInt(id)); } }); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();