diff --git a/pos/static/js/inventory.js b/pos/static/js/inventory.js new file mode 100644 index 0000000..c0a0228 --- /dev/null +++ b/pos/static/js/inventory.js @@ -0,0 +1,298 @@ +// /home/Autopartes/pos/static/js/inventory.js +// Inventory management UI: CRUD, purchases, adjustments, transfers, physical count, alerts + +(function () { + 'use strict'; + + const API = '/pos/api/inventory'; + const token = localStorage.getItem('pos_token'); + if (!token) { window.location.href = '/pos/login'; return; } + + const headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' }; + let currentPage = 1; + let currentSearch = ''; + let draftCountId = null; + + // --- API helper --- + async function apiFetch(url, opts) { + const resp = await fetch(url, Object.assign({ headers: headers }, opts || {})); + if (resp.status === 401) { localStorage.removeItem('pos_token'); window.location.href = '/pos/login'; return null; } + return resp.json(); + } + + // --- Tab switching --- + document.querySelectorAll('.tab').forEach(function (tab) { + tab.addEventListener('click', function () { + document.querySelectorAll('.tab').forEach(function (t) { t.classList.remove('active'); }); + document.querySelectorAll('.tab-content').forEach(function (c) { c.classList.remove('active'); }); + tab.classList.add('active'); + document.getElementById('tab-' + tab.dataset.tab).classList.add('active'); + + if (tab.dataset.tab === 'alerts') loadAlerts(); + }); + }); + + // --- Products --- + async function loadItems(page, search) { + currentPage = page || 1; + currentSearch = search !== undefined ? search : currentSearch; + var params = new URLSearchParams({ page: currentPage, per_page: 50 }); + if (currentSearch) params.set('q', currentSearch); + + var data = await apiFetch(API + '/items?' + params.toString()); + if (!data) return; + + var tbody = document.getElementById('productTableBody'); + var items = data.data || []; + if (!items.length) { tbody.innerHTML = '
| ID | Esperado | Contado | Diferencia |
|---|---|---|---|
| ' + r.inventory_id + ' | ' + r.expected + ' | ' + r.counted + ' | ' + (r.difference > 0 ? '+' : '') + r.difference + ' |
Sin alertas activas
'; return; } + + el.innerHTML = alerts.map(function (a) { + var cls = a.severity === 'critical' ? 'alert-critical' : (a.severity === 'warning' ? 'alert-warning' : 'alert-info'); + var icon = a.type === 'zero' ? 'AGOTADO' : (a.type === 'low' ? 'BAJO' : 'EXCESO'); + return 'Sin movimientos
'; } + else { + html = '| Fecha | Tipo | Cantidad | Costo | Empleado | Notas |
|---|---|---|---|---|---|
| ' + h.date + ' | ' + h.type + ' | ' + (h.quantity > 0 ? '+' : '') + h.quantity + ' | ' + (h.cost ? '$' + fmt(h.cost) : '-') + ' | ' + esc(h.employee) + ' | ' + esc(h.notes) + ' |
' + partNumber + '
'); + w.document.write('' + name + '
'); + w.document.write(''); + w.document.close(); + w.print(); + } + + // --- Helpers --- + function fmt(n) { return (parseFloat(n) || 0).toFixed(2); } + function esc(s) { if (!s) return ''; var d = document.createElement('div'); d.textContent = s; return d.innerHTML; } + + // --- Expose globals --- + window._loadItems = function (p) { loadItems(p); }; + window.viewHistory = viewHistory; + window.closeHistoryModal = closeHistoryModal; + window.showCreateModal = showCreateModal; + window.closeCreateModal = closeCreateModal; + window.createItem = createItem; + window.recordPurchase = recordPurchase; + window.recordAdjustment = recordAdjustment; + window.recordTransfer = recordTransfer; + window.addCountLine = addCountLine; + window.startPhysicalCount = startPhysicalCount; + window.approvePhysicalCount = approvePhysicalCount; + window.cancelDraft = cancelDraft; + window.loadAlerts = loadAlerts; + window.printBarcode = printBarcode; + + // --- Init --- + loadItems(1); +})(); diff --git a/pos/templates/inventory.html b/pos/templates/inventory.html new file mode 100644 index 0000000..44e6707 --- /dev/null +++ b/pos/templates/inventory.html @@ -0,0 +1,191 @@ + + + + + + +| Cod. Barras | No. Parte | Nombre | Marca | Stock | Costo | P1 | P2 | P3 | Ubicacion | Acciones |
|---|
Fase 1: Ingrese los conteos. Se generara un borrador con comparacion esperado vs contado. Fase 2: Apruebe para aplicar ajustes.
+