diff --git a/pos/static/js/customers.min.js b/pos/static/js/customers.min.js index 3640222..4bbc9b2 100644 --- a/pos/static/js/customers.min.js +++ b/pos/static/js/customers.min.js @@ -1 +1 @@ -const Customers=(()=>{let e=localStorage.getItem("pos_token")||"",t=1,n=1,o=null,a=null;const i=e=>"$"+parseFloat(e||0).toLocaleString("es-MX",{minimumFractionDigits:2,maximumFractionDigits:2});async function l(t,n={}){n.headers={"Content-Type":"application/json",Authorization:"Bearer "+e};const o=await fetch(t,n);if(401===o.status)return void(window.location.href="/pos/login");const a=await o.json();if(!o.ok)throw new Error(a.error||`HTTP ${o.status}`);return a}const d={1:"Mostrador",2:"Taller",3:"Mayoreo"},r={1:"mostrador",2:"taller",3:"mayoreo"};function s(e){return e.credit_balance>0&&e.credit_limit>0&&e.credit_balance>e.credit_limit?'Mora':'Activo'}function c(e){if(!e)return"--";const t=e.trim().split(/\s+/);return t.length>=2?(t[0][0]+t[1][0]).toUpperCase():e.substring(0,2).toUpperCase()}function m(e){if(!e)return"-";try{return new Date(e).toLocaleDateString("es-MX",{day:"2-digit",month:"short",year:"numeric"})}catch(t){return e}}async function p(e,a){e=e||t;const c=document.getElementById("searchInput");a=void 0!==a?a:c&&c.value||"";try{const c=new URLSearchParams({page:e,per_page:50});a&&c.append("q",a);const p=await l(`/pos/api/customers?${c}`);!function(e){const t=document.getElementById("customersBody");if(!t)return;if(t.innerHTML="",!e||0===e.length)return void(t.innerHTML='Sin resultados.');e.forEach(((e,n)=>{const a=d[e.price_tier]||"Mostrador",l=r[e.price_tier]||"mostrador",c=parseFloat(e.credit_limit||0),p=parseFloat(e.credit_balance||0),u=Math.max(0,c-p),v=c>0?Math.round(p/c*100):0,f=v>=80?"none":v>=60?"low":"",y=String(e.id).padStart(5,"0"),b=document.createElement("tr");o&&o.id===e.id&&(b.className="selected"),b.onclick=()=>g(e.id),b.innerHTML=`\n ${y}\n \n
${e.name||""}
\n
${e.email||""}
\n \n ${e.rfc||"-"}\n ${e.phone||"-"}\n ${e.email||"-"}\n ${a}\n ${i(u)}\n ${m(e.last_purchase||e.created_at)}\n ${s(e)}\n `,t.appendChild(b)}))}(p.data||[]),function(e){const o=document.querySelector(".pagination"),a=document.getElementById("tableInfo");if(!e||!e.total_pages)return o&&(o.innerHTML=""),void(a&&(a.textContent=""));n=e.total_pages,t=e.page;const i=e.total||0,l=e.per_page||50,d=(e.page-1)*l+1,r=Math.min(e.page*l,i);a&&(a.textContent=`Mostrando ${d}–${r} de ${i.toLocaleString("es-MX")} clientes`);if(!o)return;if(n<=1)return void(o.innerHTML="");let s="";s+=``;const c=7;let m=Math.max(1,e.page-3),p=Math.min(n,m+c-1);p-m${t}`;p...',s+=``);s+=``,o.innerHTML=s}(p.pagination||{})}catch(e){console.error("Load customers failed:",e)}}function u(){clearTimeout(a),a=setTimeout((()=>{t=1,p(1)}),300)}async function g(e){try{const n=await l(`/pos/api/customers/${e}`);o=n;const a=document.getElementById("detailEmpty"),u=document.getElementById("detailContent");a&&(a.style.display="none"),u&&(u.style.display="flex");const g=document.getElementById("detailAvatar");g&&(g.textContent=c(n.name));const v=document.getElementById("detailName");v&&(v.textContent=(n.name||"").toUpperCase());const f=document.getElementById("detailRFC");f&&(f.textContent=n.rfc||"-");const y=document.getElementById("detailTipo");if(y){const e=d[n.price_tier]||"Mostrador",t=r[n.price_tier]||"mostrador";y.textContent=e,y.className=`tipo-chip tipo-chip--${t}`}const b=document.getElementById("detailStatus");b&&(b.innerHTML=s(n));const h=(e,t)=>{const n=document.getElementById(e);n&&(n.textContent=t||"-")};h("detailAddress",n.address),h("detailPhone",n.phone),h("detailEmail",n.email),h("detailSince",m(n.created_at)),h("detailLastPurchase",m(n.last_purchase));const x=parseFloat(n.credit_limit||0),E=parseFloat(n.credit_balance||0),C=Math.max(0,x-E),I=x>0?Math.round(E/x*100):0;h("detailCreditLimit",i(x)),h("detailCreditAvail",i(C)),h("detailCreditUsed",i(E)),h("detailCreditPct",I+"%");const B=document.getElementById("detailCreditBar");B&&(B.style.width=I+"%",B.className="progress-bar__fill "+(I<40?"low":I>75?"high":""));const M=document.getElementById("historyBody");if(M){const e=n.recent_purchases||[];0===e.length?M.innerHTML='Sin compras recientes':(M.innerHTML="",e.forEach((e=>{const t="paid"===e.status?"mbadge--paid":"overdue"===e.status?"mbadge--overdue":"mbadge--pending",n="paid"===e.status?"Pagado":"overdue"===e.status?"Vencido":"Pendiente",o=document.createElement("tr");o.innerHTML=`\n ${m(e.created_at)}\n NX-${String(e.id).padStart(5,"0")}\n ${i(e.total)}\n ${n}\n `,M.appendChild(o)})))}!function(e){const t=(e,t)=>{const n=document.getElementById(e);n&&(n.textContent=t||"--")};t("panelAvatar",c(e.name)),t("panelName",e.name),t("panelRfc","RFC: "+(e.rfc||"-"));const n=parseFloat(e.credit_limit||0),o=parseFloat(e.credit_balance||0),a=Math.max(0,n-o),l=n>0?Math.round(o/n*100):0;t("panelCreditLimit",i(n)),t("panelCreditUsed",i(o)),t("panelCreditAvail",i(a));const d=document.getElementById("panelCreditBar");d&&(d.style.width=l+"%");const r=document.getElementById("panelVehicles");if(r){const t=e.vehicle_info||[];0===t.length?r.innerHTML='Sin vehiculos registrados':r.innerHTML=t.map((e=>`
\n ${e.make||""} ${e.model||""} ${e.year||""}\n ${e.plates?` Placas: ${e.plates}`:""}\n
`)).join("")}const s=document.getElementById("panelPurchases");if(s){const t=e.recent_purchases||[];0===t.length?s.innerHTML='Sin compras recientes':s.innerHTML=t.slice(0,5).map((e=>`
\n NX-${String(e.id).padStart(5,"0")} — ${m(e.created_at)}\n ${i(e.total)}\n
`)).join("")}}(n),p(t)}catch(e){console.error("Error loading customer:",e)}}function v(){const e=document.getElementById("customerModal");e&&(document.getElementById("modalTitle").textContent="Nuevo Cliente",document.getElementById("editId").value="",document.getElementById("fName").value="",document.getElementById("fRfc").value="",document.getElementById("fRazonSocial").value="",document.getElementById("fRegimenFiscal").value="",document.getElementById("fUsoCfdi").value="G03",document.getElementById("fCp").value="",document.getElementById("fPhone").value="",document.getElementById("fEmail").value="",document.getElementById("fAddress").value="",document.getElementById("fPriceTier").value="1",document.getElementById("fCreditLimit").value="0",e.classList.add("active"),document.getElementById("fName").focus())}function f(){if(!o)return;const e=o,t=document.getElementById("customerModal");t&&(document.getElementById("modalTitle").textContent="Editar Cliente",document.getElementById("editId").value=e.id,document.getElementById("fName").value=e.name||"",document.getElementById("fRfc").value=e.rfc||"",document.getElementById("fRazonSocial").value=e.razon_social||"",document.getElementById("fRegimenFiscal").value=e.regimen_fiscal||"",document.getElementById("fUsoCfdi").value=e.uso_cfdi||"G03",document.getElementById("fCp").value=e.cp||"",document.getElementById("fPhone").value=e.phone||"",document.getElementById("fEmail").value=e.email||"",document.getElementById("fAddress").value=e.address||"",document.getElementById("fPriceTier").value=e.price_tier||"1",document.getElementById("fCreditLimit").value=e.credit_limit||0,t.classList.add("active"))}function y(){const e=document.getElementById("customerModal");e&&e.classList.remove("active")}async function b(){if(!o)return;const e=document.getElementById("statementModal");if(!e)return;const t=document.getElementById("statementName");t&&(t.textContent=o.name);const n=document.getElementById("statementContent");n&&(n.innerHTML='
Cargando...
'),e.classList.add("active");try{const e=await l(`/pos/api/customers/${o.id}/statement`);let t=`
\n Saldo actual: ${i(e.balance)} |\n Limite: ${i(e.customer?e.customer.credit_limit:0)}\n
`;e.entries&&0!==e.entries.length?(t+='',t+='',e.entries.forEach((e=>{t+=`\n \n \n \n \n \n `})),t+="
FechaConceptoCargoAbonoSaldo
${m(e.date)}${e.description||""}${"charge"===e.type?i(e.amount):""}${"payment"===e.type?i(e.amount):""}${i(e.running_balance)}
"):t+='
Sin movimientos
',n&&(n.innerHTML=t)}catch(e){n&&(n.innerHTML=`
Error: ${e.message}
`)}}function h(){const e=document.getElementById("paymentModal");e&&e.classList.remove("active")}function x(e){g(e),"function"==typeof openSlidePanel&&openSlidePanel()}return window.filterCustomers=function(){u()},e?(window.openNewCustomerModal=v,function(){const e=document.querySelectorAll(".quick-actions .action-btn");e.length>=1&&(e[0].onclick=()=>{o&&(window.location.href="/pos/?customer="+o.id)}),e.length>=2&&(e[1].onclick=()=>f()),e.length>=3&&(e[2].onclick=()=>b()),e.length>=4&&(e[3].onclick=()=>{o&&g(o.id)})}(),window.viewCustomer=x,function(){if(!document.getElementById("customerModal")){const e=document.createElement("div");e.innerHTML='\n ',document.body.appendChild(e)}if(!document.getElementById("statementModal")){const e=document.createElement("div");e.innerHTML='\n ',document.body.appendChild(e)}if(!document.getElementById("paymentModal")){const e=document.createElement("div");e.innerHTML='\n ',document.body.appendChild(e)}if(!document.getElementById("modalStyles")){const e=document.createElement("style");e.id="modalStyles",e.textContent="\n .modal-overlay {\n position: fixed; top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0,0,0,0.5); z-index: 9000;\n display: flex; align-items: center; justify-content: center;\n backdrop-filter: blur(2px);\n }\n .modal-overlay.active { display: flex !important; }\n .modal-box {\n background: var(--color-bg-elevated); border: 1px solid var(--color-border);\n border-radius: var(--radius-lg); width: 90%; max-width: 600px;\n max-height: 85vh; overflow-y: auto;\n box-shadow: var(--shadow-xl);\n }\n .modal-box--wide { max-width: 800px; }\n .modal-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: var(--space-4) var(--space-5);\n border-bottom: 1px solid var(--color-border);\n }\n .modal-header h3 {\n font-family: var(--font-heading); font-size: var(--text-h6);\n font-weight: var(--heading-weight-primary); color: var(--color-text-primary);\n letter-spacing: var(--tracking-wide); text-transform: uppercase;\n }\n .modal-body { padding: var(--space-5); }\n .modal-footer {\n display: flex; justify-content: flex-end; gap: var(--space-3);\n padding: var(--space-4) var(--space-5);\n border-top: 1px solid var(--color-border);\n }\n .form-row { display: flex; gap: var(--space-4); margin-bottom: var(--space-4); }\n .form-row > .form-group { flex: 1; }\n .form-group { margin-bottom: var(--space-4); }\n .form-group label {\n display: block; font-size: var(--text-caption); font-weight: var(--font-weight-semibold);\n color: var(--color-text-muted); text-transform: uppercase; letter-spacing: var(--tracking-wider);\n margin-bottom: var(--space-1);\n }\n .form-input {\n width: 100%; height: 38px; padding: 0 var(--space-3);\n background: var(--color-bg-overlay); border: 1.5px solid var(--color-border);\n border-radius: var(--radius-md); font-family: var(--font-body);\n font-size: var(--text-body-sm); color: var(--color-text-primary); outline: none;\n transition: var(--transition-fast);\n }\n .form-input:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }\n select.form-input { cursor: pointer; }\n ",document.head.appendChild(e)}}(),p(),async function(){try{const e=await l("/pos/api/customers?page=1&per_page=1"),t=e.pagination?e.pagination.total:0,n=document.querySelectorAll(".summary-card__value");n.length>=1&&(n[0].textContent=t.toLocaleString("es-MX"))}catch(e){}}()):window.location.href="/pos/login",{search:u,goToPage:function(e){e<1||e>n||(t=e,p(e))},loadCustomers:p,showDetail:x,selectCustomer:g,closeDetail:function(){o=null;const e=document.getElementById("detailEmpty"),n=document.getElementById("detailContent");e&&(e.style.display="flex"),n&&(n.style.display="none"),p(t)},showCreateModal:v,editCurrent:f,closeModal:y,save:async function(){const e=document.getElementById("fName"),t=e?e.value.trim():"";if(!t)return void alert("Nombre es requerido");const n=e=>{const t=document.getElementById(e);return t?t.value.trim():""},a={name:t,rfc:n("fRfc")||null,razon_social:n("fRazonSocial")||null,regimen_fiscal:n("fRegimenFiscal")||null,uso_cfdi:n("fUsoCfdi")||"G03",cp:n("fCp")||null,phone:n("fPhone")||null,email:n("fEmail")||null,address:n("fAddress")||null,price_tier:parseInt(n("fPriceTier"))||1,credit_limit:parseFloat(n("fCreditLimit"))||0},i=n("editId");try{i?await l(`/pos/api/customers/${i}`,{method:"PUT",body:JSON.stringify(a)}):await l("/pos/api/customers",{method:"POST",body:JSON.stringify(a)}),y(),p(),i&&o&&g(i)}catch(e){alert("Error: "+e.message)}},showStatement:b,closeStatement:function(){const e=document.getElementById("statementModal");e&&e.classList.remove("active")},showPaymentModal:function(){if(!o)return;const e=document.getElementById("paymentModal");e&&(document.getElementById("paymentCustomerName").textContent=o.name,document.getElementById("paymentAmount").value="",document.getElementById("paymentMethod").value="cash",document.getElementById("paymentRef").value="",e.classList.add("active"),document.getElementById("paymentAmount").focus())},closePayment:h,recordPayment:async function(){if(!o)return;const e=parseFloat(document.getElementById("paymentAmount").value);if(!e||e<=0)return void alert("Ingresa un monto valido");const t=document.getElementById("paymentMethod").value,n=document.getElementById("paymentRef").value.trim();try{await l(`/pos/api/customers/${o.id}/payment`,{method:"POST",body:JSON.stringify({amount:e,method:t,reference:n})}),h(),g(o.id)}catch(e){alert("Error: "+e.message)}}}})(); \ No newline at end of file +const Customers=(()=>{let e=localStorage.getItem("pos_token")||"",t=1,n=1,o=null,a=null;const i=e=>"$"+parseFloat(e||0).toLocaleString("es-MX",{minimumFractionDigits:2,maximumFractionDigits:2});async function l(t,n={}){n.headers={"Content-Type":"application/json",Authorization:"Bearer "+e};const o=await fetch(t,n);if(401===o.status)return void(window.location.href="/pos/login");const a=await o.json();if(!o.ok)throw new Error(a.error||`HTTP ${o.status}`);return a}const d={1:"Mostrador",2:"Taller",3:"Mayoreo"},r={1:"mostrador",2:"taller",3:"mayoreo"};function s(e){return e.credit_balance>0&&e.credit_limit>0&&e.credit_balance>e.credit_limit?'Mora':'Activo'}function c(e){if(!e)return"--";const t=e.trim().split(/\s+/);return t.length>=2?(t[0][0]+t[1][0]).toUpperCase():e.substring(0,2).toUpperCase()}function m(e){if(!e)return"-";try{return new Date(e).toLocaleDateString("es-MX",{day:"2-digit",month:"short",year:"numeric"})}catch(t){return e}}async function p(e,o){e=e||t;const a=document.getElementById("searchInput");o=void 0!==o?o:a&&a.value||"";try{const a=new URLSearchParams({page:e,per_page:50});o&&a.append("q",o);const i=await l(`/pos/api/customers?${a}`);!function(e){const t=document.getElementById("customersBody");if(!t)return;if(!e||0===e.length)return void(t.innerHTML='Sin resultados.');g||(g=new VirtualScroll({container:t,rowHeight:52,buffer:3,renderRow:u,emptyHtml:'Sin resultados.'}));g.setData(e)}(i.data||[]),function(e){const o=document.querySelector(".pagination"),a=document.getElementById("tableInfo");if(!e||!e.total_pages)return o&&(o.innerHTML=""),void(a&&(a.textContent=""));n=e.total_pages,t=e.page;const i=e.total||0,l=e.per_page||50,d=(e.page-1)*l+1,r=Math.min(e.page*l,i);a&&(a.textContent=`Mostrando ${d}–${r} de ${i.toLocaleString("es-MX")} clientes`);if(!o)return;if(n<=1)return void(o.innerHTML="");let s="";s+=``;const c=7;let m=Math.max(1,e.page-3),p=Math.min(n,m+c-1);p-m${t}`;p...',s+=``);s+=``,o.innerHTML=s}(i.pagination||{})}catch(e){console.error("Load customers failed:",e)}}function u(e){const t=d[e.price_tier]||"Mostrador",n=r[e.price_tier]||"mostrador",a=parseFloat(e.credit_limit||0),l=parseFloat(e.credit_balance||0),c=Math.max(0,a-l),p=a>0?Math.round(l/a*100):0,u=p>=80?"none":p>=60?"low":"",g=String(e.id).padStart(5,"0");return''+g+'
'+(e.name||"")+'
'+(e.email||"")+'
'+(e.rfc||"-")+''+(e.phone||"-")+''+(e.email||"-")+''+t+''+i(c)+''+m(e.last_purchase||e.created_at)+""+s(e)+""}var g=null;function v(){clearTimeout(a),a=setTimeout((()=>{t=1,p(1)}),300)}async function f(e){try{const n=await l(`/pos/api/customers/${e}`);o=n;const a=document.getElementById("detailEmpty"),u=document.getElementById("detailContent");a&&(a.style.display="none"),u&&(u.style.display="flex");const g=document.getElementById("detailAvatar");g&&(g.textContent=c(n.name));const v=document.getElementById("detailName");v&&(v.textContent=(n.name||"").toUpperCase());const f=document.getElementById("detailRFC");f&&(f.textContent=n.rfc||"-");const y=document.getElementById("detailTipo");if(y){const e=d[n.price_tier]||"Mostrador",t=r[n.price_tier]||"mostrador";y.textContent=e,y.className=`tipo-chip tipo-chip--${t}`}const b=document.getElementById("detailStatus");b&&(b.innerHTML=s(n));const h=(e,t)=>{const n=document.getElementById(e);n&&(n.textContent=t||"-")};h("detailAddress",n.address),h("detailPhone",n.phone),h("detailEmail",n.email),h("detailSince",m(n.created_at)),h("detailLastPurchase",m(n.last_purchase));const x=parseFloat(n.credit_limit||0),C=parseFloat(n.credit_balance||0),E=Math.max(0,x-C),I=x>0?Math.round(C/x*100):0;h("detailCreditLimit",i(x)),h("detailCreditAvail",i(E)),h("detailCreditUsed",i(C)),h("detailCreditPct",I+"%");const B=document.getElementById("detailCreditBar");B&&(B.style.width=I+"%",B.className="progress-bar__fill "+(I<40?"low":I>75?"high":""));const w=document.getElementById("historyBody");if(w){const e=n.recent_purchases||[];0===e.length?w.innerHTML='Sin compras recientes':(w.innerHTML="",e.forEach((e=>{const t="paid"===e.status?"mbadge--paid":"overdue"===e.status?"mbadge--overdue":"mbadge--pending",n="paid"===e.status?"Pagado":"overdue"===e.status?"Vencido":"Pendiente",o=document.createElement("tr");o.innerHTML=`\n ${m(e.created_at)}\n NX-${String(e.id).padStart(5,"0")}\n ${i(e.total)}\n ${n}\n `,w.appendChild(o)})))}!function(e){const t=(e,t)=>{const n=document.getElementById(e);n&&(n.textContent=t||"--")};t("panelAvatar",c(e.name)),t("panelName",e.name),t("panelRfc","RFC: "+(e.rfc||"-"));const n=parseFloat(e.credit_limit||0),o=parseFloat(e.credit_balance||0),a=Math.max(0,n-o),l=n>0?Math.round(o/n*100):0;t("panelCreditLimit",i(n)),t("panelCreditUsed",i(o)),t("panelCreditAvail",i(a));const d=document.getElementById("panelCreditBar");d&&(d.style.width=l+"%");const r=document.getElementById("panelVehicles");if(r){const t=e.vehicle_info||[];0===t.length?r.innerHTML='Sin vehiculos registrados':r.innerHTML=t.map((e=>`
\n ${e.make||""} ${e.model||""} ${e.year||""}\n ${e.plates?` Placas: ${e.plates}`:""}\n
`)).join("")}const s=document.getElementById("panelPurchases");if(s){const t=e.recent_purchases||[];0===t.length?s.innerHTML='Sin compras recientes':s.innerHTML=t.slice(0,5).map((e=>`
\n NX-${String(e.id).padStart(5,"0")} — ${m(e.created_at)}\n ${i(e.total)}\n
`)).join("")}}(n),p(t)}catch(e){console.error("Error loading customer:",e)}}function y(){const e=document.getElementById("customerModal");e&&(document.getElementById("modalTitle").textContent="Nuevo Cliente",document.getElementById("editId").value="",document.getElementById("fName").value="",document.getElementById("fRfc").value="",document.getElementById("fRazonSocial").value="",document.getElementById("fRegimenFiscal").value="",document.getElementById("fUsoCfdi").value="G03",document.getElementById("fCp").value="",document.getElementById("fPhone").value="",document.getElementById("fEmail").value="",document.getElementById("fAddress").value="",document.getElementById("fPriceTier").value="1",document.getElementById("fCreditLimit").value="0",e.classList.add("active"),document.getElementById("fName").focus())}function b(){if(!o)return;const e=o,t=document.getElementById("customerModal");t&&(document.getElementById("modalTitle").textContent="Editar Cliente",document.getElementById("editId").value=e.id,document.getElementById("fName").value=e.name||"",document.getElementById("fRfc").value=e.rfc||"",document.getElementById("fRazonSocial").value=e.razon_social||"",document.getElementById("fRegimenFiscal").value=e.regimen_fiscal||"",document.getElementById("fUsoCfdi").value=e.uso_cfdi||"G03",document.getElementById("fCp").value=e.cp||"",document.getElementById("fPhone").value=e.phone||"",document.getElementById("fEmail").value=e.email||"",document.getElementById("fAddress").value=e.address||"",document.getElementById("fPriceTier").value=e.price_tier||"1",document.getElementById("fCreditLimit").value=e.credit_limit||0,t.classList.add("active"))}function h(){const e=document.getElementById("customerModal");e&&e.classList.remove("active")}async function x(){if(!o)return;const e=document.getElementById("statementModal");if(!e)return;const t=document.getElementById("statementName");t&&(t.textContent=o.name);const n=document.getElementById("statementContent");n&&(n.innerHTML='
Cargando...
'),e.classList.add("active");try{const e=await l(`/pos/api/customers/${o.id}/statement`);let t=`
\n Saldo actual: ${i(e.balance)} |\n Limite: ${i(e.customer?e.customer.credit_limit:0)}\n
`;e.entries&&0!==e.entries.length?(t+='',t+='',e.entries.forEach((e=>{t+=`\n \n \n \n \n \n `})),t+="
FechaConceptoCargoAbonoSaldo
${m(e.date)}${e.description||""}${"charge"===e.type?i(e.amount):""}${"payment"===e.type?i(e.amount):""}${i(e.running_balance)}
"):t+='
Sin movimientos
',n&&(n.innerHTML=t)}catch(e){n&&(n.innerHTML=`
Error: ${e.message}
`)}}function C(){const e=document.getElementById("paymentModal");e&&e.classList.remove("active")}function E(e){f(e),"function"==typeof openSlidePanel&&openSlidePanel()}return window.filterCustomers=function(){v()},e?(window.openNewCustomerModal=y,function(){const e=document.querySelectorAll(".quick-actions .action-btn");e.length>=1&&(e[0].onclick=()=>{o&&(window.location.href="/pos/?customer="+o.id)}),e.length>=2&&(e[1].onclick=()=>b()),e.length>=3&&(e[2].onclick=()=>x()),e.length>=4&&(e[3].onclick=()=>{o&&f(o.id)})}(),window.viewCustomer=E,function(){if(!document.getElementById("customerModal")){const e=document.createElement("div");e.innerHTML='\n ',document.body.appendChild(e)}if(!document.getElementById("statementModal")){const e=document.createElement("div");e.innerHTML='\n ',document.body.appendChild(e)}if(!document.getElementById("paymentModal")){const e=document.createElement("div");e.innerHTML='\n ',document.body.appendChild(e)}if(!document.getElementById("modalStyles")){const e=document.createElement("style");e.id="modalStyles",e.textContent="\n .modal-overlay {\n position: fixed; top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0,0,0,0.5); z-index: 9000;\n display: flex; align-items: center; justify-content: center;\n backdrop-filter: blur(2px);\n }\n .modal-overlay.active { display: flex !important; }\n .modal-box {\n background: var(--color-bg-elevated); border: 1px solid var(--color-border);\n border-radius: var(--radius-lg); width: 90%; max-width: 600px;\n max-height: 85vh; overflow-y: auto;\n box-shadow: var(--shadow-xl);\n }\n .modal-box--wide { max-width: 800px; }\n .modal-header {\n display: flex; align-items: center; justify-content: space-between;\n padding: var(--space-4) var(--space-5);\n border-bottom: 1px solid var(--color-border);\n }\n .modal-header h3 {\n font-family: var(--font-heading); font-size: var(--text-h6);\n font-weight: var(--heading-weight-primary); color: var(--color-text-primary);\n letter-spacing: var(--tracking-wide); text-transform: uppercase;\n }\n .modal-body { padding: var(--space-5); }\n .modal-footer {\n display: flex; justify-content: flex-end; gap: var(--space-3);\n padding: var(--space-4) var(--space-5);\n border-top: 1px solid var(--color-border);\n }\n .form-row { display: flex; gap: var(--space-4); margin-bottom: var(--space-4); }\n .form-row > .form-group { flex: 1; }\n .form-group { margin-bottom: var(--space-4); }\n .form-group label {\n display: block; font-size: var(--text-caption); font-weight: var(--font-weight-semibold);\n color: var(--color-text-muted); text-transform: uppercase; letter-spacing: var(--tracking-wider);\n margin-bottom: var(--space-1);\n }\n .form-input {\n width: 100%; height: 38px; padding: 0 var(--space-3);\n background: var(--color-bg-overlay); border: 1.5px solid var(--color-border);\n border-radius: var(--radius-md); font-family: var(--font-body);\n font-size: var(--text-body-sm); color: var(--color-text-primary); outline: none;\n transition: var(--transition-fast);\n }\n .form-input:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }\n select.form-input { cursor: pointer; }\n ",document.head.appendChild(e)}}(),p(),async function(){try{const e=await l("/pos/api/customers?page=1&per_page=1"),t=e.pagination?e.pagination.total:0,n=document.querySelectorAll(".summary-card__value");n.length>=1&&(n[0].textContent=t.toLocaleString("es-MX"))}catch(e){}}()):window.location.href="/pos/login",{search:v,goToPage:function(e){e<1||e>n||(t=e,p(e))},loadCustomers:p,showDetail:E,selectCustomer:f,closeDetail:function(){o=null;const e=document.getElementById("detailEmpty"),n=document.getElementById("detailContent");e&&(e.style.display="flex"),n&&(n.style.display="none"),p(t)},showCreateModal:y,editCurrent:b,closeModal:h,save:async function(){const e=document.getElementById("fName"),t=e?e.value.trim():"";if(!t)return void alert("Nombre es requerido");const n=e=>{const t=document.getElementById(e);return t?t.value.trim():""},a={name:t,rfc:n("fRfc")||null,razon_social:n("fRazonSocial")||null,regimen_fiscal:n("fRegimenFiscal")||null,uso_cfdi:n("fUsoCfdi")||"G03",cp:n("fCp")||null,phone:n("fPhone")||null,email:n("fEmail")||null,address:n("fAddress")||null,price_tier:parseInt(n("fPriceTier"))||1,credit_limit:parseFloat(n("fCreditLimit"))||0},i=n("editId");try{i?await l(`/pos/api/customers/${i}`,{method:"PUT",body:JSON.stringify(a)}):await l("/pos/api/customers",{method:"POST",body:JSON.stringify(a)}),h(),p(),i&&o&&f(i)}catch(e){alert("Error: "+e.message)}},showStatement:x,closeStatement:function(){const e=document.getElementById("statementModal");e&&e.classList.remove("active")},showPaymentModal:function(){if(!o)return;const e=document.getElementById("paymentModal");e&&(document.getElementById("paymentCustomerName").textContent=o.name,document.getElementById("paymentAmount").value="",document.getElementById("paymentMethod").value="cash",document.getElementById("paymentRef").value="",e.classList.add("active"),document.getElementById("paymentAmount").focus())},closePayment:C,recordPayment:async function(){if(!o)return;const e=parseFloat(document.getElementById("paymentAmount").value);if(!e||e<=0)return void alert("Ingresa un monto valido");const t=document.getElementById("paymentMethod").value,n=document.getElementById("paymentRef").value.trim();try{await l(`/pos/api/customers/${o.id}/payment`,{method:"POST",body:JSON.stringify({amount:e,method:t,reference:n})}),C(),f(o.id)}catch(e){alert("Error: "+e.message)}}}})(); \ No newline at end of file diff --git a/pos/static/js/fleet.min.js b/pos/static/js/fleet.min.js index 7975c8a..fce058d 100644 --- a/pos/static/js/fleet.min.js +++ b/pos/static/js/fleet.min.js @@ -1 +1 @@ -var Fleet=function(){"use strict";var e="/pos/api/fleet",t=localStorage.getItem("pos_token"),n=[],a=1,o=null;function l(){return{"Content-Type":"application/json",Authorization:"Bearer "+t}}function c(e){return null==e?"0":parseFloat(e).toLocaleString("es-MX")}function i(e){return null==e?"$0.00":"$"+parseFloat(e).toLocaleString("es-MX",{minimumFractionDigits:2,maximumFractionDigits:2})}function d(e){return e?new Date(e).toLocaleDateString("es-MX",{day:"2-digit",month:"short",year:"numeric"}):"—"}function r(e){if(!e)return"";var t=document.createElement("div");return t.textContent=e,t.innerHTML}function u(){fetch(e+"/stats",{headers:l()}).then((function(e){return e.json()})).then((function(e){document.getElementById("statTotal").textContent=c(e.total_vehicles),document.getElementById("statOverdue").textContent=c(e.overdue_count),document.getElementById("statUpcoming").textContent=c(e.upcoming_this_month),document.getElementById("statCost").textContent=i(e.total_cost_month)})).catch((function(){}))}function s(){var t=(document.getElementById("searchInput")||{}).value||"",o=e+"/vehicles?page="+a+"&per_page=50";t&&(o+="&q="+encodeURIComponent(t)),fetch(o,{headers:l()}).then((function(e){return e.json()})).then((function(e){var t;(function(e){var t=document.getElementById("vehicleGrid");if(!e.length)return void(t.innerHTML='
🚚
No hay vehiculos registrados
');var n="";e.forEach((function(e){var t=(e.make||"")+" "+(e.model||"");e.year&&(t+=" "+e.year),n+='
'+r(e.plate||"SIN PLACA")+''+(e.is_active?"Activo":"Inactivo")+'
'+r(t.trim())+"
"+(e.owner_name?"
"+r(e.owner_name)+"
":"")+(e.color?"
Color: "+r(e.color)+"
":"")+'
"})),t.innerHTML=n})(n=e.data||[]),function(e){var t=document.getElementById("vehiclePagination");if(!e||e.total_pages<=1)return void(t.innerHTML="");t.innerHTML='Pagina '+e.page+" de "+e.total_pages+" ("+e.total+' vehiculos)'}(e.pagination),t='',n.forEach((function(e){var n=(e.plate||"S/P")+" - "+(e.make||"")+" "+(e.model||"");t+='"})),["schedVehicleSelect","logVehicleSelect"].forEach((function(e){var n=document.getElementById(e);n&&(n.innerHTML=t)}))})).catch((function(){document.getElementById("vehicleGrid").innerHTML='
Error al cargar vehiculos
'}))}function m(e){var t=document.getElementById("vehicleModal"),n=document.getElementById("vehicleModalTitle");e&&e.id?(n.textContent="Editar Vehiculo",document.getElementById("vehEditId").value=e.id,document.getElementById("vehPlate").value=e.plate||"",document.getElementById("vehVin").value=e.vin||"",document.getElementById("vehMake").value=e.make||"",document.getElementById("vehModel").value=e.model||"",document.getElementById("vehYear").value=e.year||"",document.getElementById("vehMileage").value=e.current_mileage||0,document.getElementById("vehFuel").value=e.fuel_type||"gasolina",document.getElementById("vehColor").value=e.color||"",document.getElementById("vehOwner").value=e.owner_name||"",document.getElementById("vehNotes").value=e.notes||""):(n.textContent="Nuevo Vehiculo",document.getElementById("vehEditId").value="",["vehPlate","vehVin","vehMake","vehModel","vehYear","vehColor","vehOwner","vehNotes"].forEach((function(e){document.getElementById(e).value=""})),document.getElementById("vehMileage").value="0",document.getElementById("vehFuel").value="gasolina"),t.classList.add("is-open")}function v(){document.getElementById("vehicleModal").classList.remove("is-open")}function h(){fetch(e+"/vehicles?per_page=200",{headers:l()}).then((function(e){return e.json()})).then((function(t){var n=(t.data||[]).map((function(t){return fetch(e+"/vehicles/"+t.id+"/schedules",{headers:l()}).then((function(e){return e.json()})).then((function(e){return{vehicle:t,schedules:e.data||[]}}))}));return Promise.all(n)})).then((function(e){!function(e){var t=document.getElementById("maintBody"),n=[];if(e.forEach((function(e){var t=e.vehicle;e.schedules.forEach((function(e){var a=new Date,o=!1;e.next_due_at&&new Date(e.next_due_at)"+r(t.plate||"S/P")+'
'+r((t.make||"")+" "+(t.model||""))+""+r(e.maintenance_type)+''+(l||"—")+""+d(e.last_done_at)+(e.last_done_km?'
'+c(e.last_done_km)+" km":"")+""+(i||"—")+''+(o?"Vencido":"Al dia")+'")}))})),!n.length)return void(t.innerHTML='No hay programas de mantenimiento.
');t.innerHTML=n.join("")}(e)})).catch((function(){document.getElementById("maintBody").innerHTML='Error al cargar'}))}function g(){fetch(e+"/vehicles?per_page=200",{headers:l()}).then((function(e){return e.json()})).then((function(t){var n=(t.data||[]).map((function(t){return fetch(e+"/vehicles/"+t.id,{headers:l()}).then((function(e){return e.json()})).then((function(e){return{vehicle:t,logs:e.recent_logs||[]}}))}));return Promise.all(n)})).then((function(e){!function(e){var t=document.getElementById("historyBody"),n=[];if(e.forEach((function(e){e.logs.forEach((function(t){t._plate=e.vehicle.plate||"S/P",t._make=(e.vehicle.make||"")+" "+(e.vehicle.model||""),n.push(t)}))})),n.sort((function(e,t){return new Date(t.created_at)-new Date(e.created_at)})),!n.length)return void(t.innerHTML='No hay registros de mantenimiento');var a="";n.forEach((function(e){a+=""+d(e.created_at)+""+r(e._plate)+'
'+r(e._make)+""+r(e.maintenance_type)+''+c(e.mileage_at)+''+i(e.cost)+""+r(e.employee_name||"—")+''+r(e.notes||"—")+""})),t.innerHTML=a}(e)})).catch((function(){document.getElementById("historyBody").innerHTML='Error al cargar'}))}function p(){fetch(e+"/alerts",{headers:l()}).then((function(e){return e.json()})).then((function(e){!function(e){var t=document.getElementById("alertsList");if(!e.length)return void(t.innerHTML='
No hay mantenimientos vencidos
');var n="";e.forEach((function(e){var t="";e.next_due_at&&(t+="Vencio: "+d(e.next_due_at)),e.next_due_km&&(t+=(t?" | ":"")+"Limite: "+c(e.next_due_km)+" km (actual: "+c(e.current_mileage)+" km)"),n+='
'+r(e.plate||"S/P")+" — "+r((e.make||"")+" "+(e.model||""))+(e.year?" "+e.year:"")+'
'+r(e.maintenance_type)+"   "+t+'
"})),t.innerHTML=n}(e.data||[])})).catch((function(){document.getElementById("alertsList").innerHTML='
Error al cargar alertas
'}))}function y(){document.getElementById("scheduleModal").classList.remove("is-open")}function f(){var e=document.getElementById("logModal");document.getElementById("logScheduleSelect").innerHTML='',document.getElementById("logType").value="",document.getElementById("logMileage").value="",document.getElementById("logCost").value="",document.getElementById("logParts").value="",document.getElementById("logNotes").value="",e.classList.add("is-open")}function _(){document.getElementById("logModal").classList.remove("is-open")}return document.addEventListener("DOMContentLoaded",(function(){document.querySelectorAll(".tab-btn").forEach((function(e){e.addEventListener("click",(function(){var e=this.getAttribute("data-tab");document.querySelectorAll(".tab-btn").forEach((function(e){e.classList.remove("is-active")})),document.querySelectorAll(".tab-panel").forEach((function(e){e.classList.remove("is-active")})),this.classList.add("is-active"),document.getElementById("tab-"+e).classList.add("is-active"),"maintenance"===e&&h(),"history"===e&&g(),"alerts"===e&&p()}))}));var e=document.getElementById("searchInput");e&&e.addEventListener("input",(function(){clearTimeout(o),o=setTimeout((function(){a=1,s()}),300)})),document.getElementById("btnNewVehicle").addEventListener("click",(function(){m()})),u(),s()})),{openVehicleModal:m,closeVehicleModal:v,saveVehicle:function(){var t=document.getElementById("vehEditId").value,n={plate:document.getElementById("vehPlate").value.trim(),vin:document.getElementById("vehVin").value.trim(),make:document.getElementById("vehMake").value.trim(),model:document.getElementById("vehModel").value.trim(),year:parseInt(document.getElementById("vehYear").value)||null,current_mileage:parseInt(document.getElementById("vehMileage").value)||0,fuel_type:document.getElementById("vehFuel").value,color:document.getElementById("vehColor").value.trim(),owner_name:document.getElementById("vehOwner").value.trim(),notes:document.getElementById("vehNotes").value.trim()};if(n.plate||n.vin){var a=e+"/vehicles",o="POST";t&&(a+="/"+t,o="PUT"),fetch(a,{method:o,headers:l(),body:JSON.stringify(n)}).then((function(e){return e.json()})).then((function(e){e.error?alert(e.error):(v(),s(),u())})).catch((function(e){alert("Error: "+e.message)}))}else alert("Se requiere placa o VIN")},viewVehicle:function(t){fetch(e+"/vehicles/"+t,{headers:l()}).then((function(e){return e.json()})).then((function(e){m(e)}))},goPage:function(e){a=e,s()},openScheduleModal:function(e){var t=document.getElementById("scheduleModal");document.getElementById("schedType").value="",document.getElementById("schedIntervalKm").value="",document.getElementById("schedIntervalMonths").value="",document.getElementById("schedNextDate").value="",document.getElementById("schedNextKm").value="",document.getElementById("schedNotes").value="",e&&(document.getElementById("schedVehicleSelect").value=e),t.classList.add("is-open")},closeScheduleModal:y,saveSchedule:function(){var t=document.getElementById("schedVehicleSelect").value;if(t){var n=document.getElementById("schedType").value.trim();if(n){var a={maintenance_type:n,interval_km:parseInt(document.getElementById("schedIntervalKm").value)||null,interval_months:parseInt(document.getElementById("schedIntervalMonths").value)||null,next_due_at:document.getElementById("schedNextDate").value||null,next_due_km:parseInt(document.getElementById("schedNextKm").value)||null,notes:document.getElementById("schedNotes").value.trim()};fetch(e+"/vehicles/"+t+"/schedules",{method:"POST",headers:l(),body:JSON.stringify(a)}).then((function(e){return e.json()})).then((function(e){e.error?alert(e.error):(y(),h(),u())})).catch((function(e){alert("Error: "+e.message)}))}else alert("Ingrese el tipo de mantenimiento")}else alert("Seleccione un vehiculo")},openLogModal:f,openLogModalFor:function(t,a,o){f(),document.getElementById("logVehicleSelect").value=t,o&&(document.getElementById("logType").value=o),fetch(e+"/vehicles/"+t+"/schedules",{headers:l()}).then((function(e){return e.json()})).then((function(e){var t='';(e.data||[]).forEach((function(e){var n=e.id==a?" selected":"";t+='"})),document.getElementById("logScheduleSelect").innerHTML=t}));var c=n.find((function(e){return e.id==t}));c&&(document.getElementById("logMileage").value=c.current_mileage||"")},closeLogModal:_,saveLog:function(){var t=document.getElementById("logVehicleSelect").value;if(t){var n=document.getElementById("logType").value.trim();if(n){var a={schedule_id:parseInt(document.getElementById("logScheduleSelect").value)||null,maintenance_type:n,mileage_at:parseInt(document.getElementById("logMileage").value)||null,cost:parseFloat(document.getElementById("logCost").value)||0,parts_used:document.getElementById("logParts").value.trim(),notes:document.getElementById("logNotes").value.trim()};fetch(e+"/vehicles/"+t+"/log",{method:"POST",headers:l(),body:JSON.stringify(a)}).then((function(e){return e.json()})).then((function(e){if(e.error)alert(e.error);else{_(),u();var t=document.querySelector(".tab-btn.is-active");if(t){var n=t.getAttribute("data-tab");"maintenance"===n&&h(),"history"===n&&g(),"alerts"===n&&p(),"vehicles"===n&&s()}}})).catch((function(e){alert("Error: "+e.message)}))}else alert("Ingrese el tipo de mantenimiento")}else alert("Seleccione un vehiculo")}}}(); \ No newline at end of file +var Fleet=function(){"use strict";var e="/pos/api/fleet",t=localStorage.getItem("pos_token"),n=[],a=1,o=null;function l(){return{"Content-Type":"application/json",Authorization:"Bearer "+t}}function c(e){return null==e?"0":parseFloat(e).toLocaleString("es-MX")}function i(e){return null==e?"$0.00":"$"+parseFloat(e).toLocaleString("es-MX",{minimumFractionDigits:2,maximumFractionDigits:2})}function r(e){return e?new Date(e).toLocaleDateString("es-MX",{day:"2-digit",month:"short",year:"numeric"}):"—"}function d(e){if(!e)return"";var t=document.createElement("div");return t.textContent=e,t.innerHTML}function u(){fetch(e+"/stats",{headers:l()}).then((function(e){return e.json()})).then((function(e){document.getElementById("statTotal").textContent=c(e.total_vehicles),document.getElementById("statOverdue").textContent=c(e.overdue_count),document.getElementById("statUpcoming").textContent=c(e.upcoming_this_month),document.getElementById("statCost").textContent=i(e.total_cost_month)})).catch((function(){}))}function s(){var t=(document.getElementById("searchInput")||{}).value||"",o=e+"/vehicles?page="+a+"&per_page=50";t&&(o+="&q="+encodeURIComponent(t)),fetch(o,{headers:l()}).then((function(e){return e.json()})).then((function(e){var t;(function(e){var t=document.getElementById("vehicleGrid");if(!e.length)return void(t.innerHTML='
🚚
No hay vehiculos registrados
');var n="";e.forEach((function(e){var t=(e.make||"")+" "+(e.model||"");e.year&&(t+=" "+e.year),n+='
'+d(e.plate||"SIN PLACA")+''+(e.is_active?"Activo":"Inactivo")+'
'+d(t.trim())+"
"+(e.owner_name?"
"+d(e.owner_name)+"
":"")+(e.color?"
Color: "+d(e.color)+"
":"")+'
"})),t.innerHTML=n})(n=e.data||[]),function(e){var t=document.getElementById("vehiclePagination");if(!e||e.total_pages<=1)return void(t.innerHTML="");t.innerHTML='Pagina '+e.page+" de "+e.total_pages+" ("+e.total+' vehiculos)'}(e.pagination),t='',n.forEach((function(e){var n=(e.plate||"S/P")+" - "+(e.make||"")+" "+(e.model||"");t+='"})),["schedVehicleSelect","logVehicleSelect"].forEach((function(e){var n=document.getElementById(e);n&&(n.innerHTML=t)}))})).catch((function(){document.getElementById("vehicleGrid").innerHTML='
Error al cargar vehiculos
'}))}function m(e){var t=document.getElementById("vehicleModal"),n=document.getElementById("vehicleModalTitle");e&&e.id?(n.textContent="Editar Vehiculo",document.getElementById("vehEditId").value=e.id,document.getElementById("vehPlate").value=e.plate||"",document.getElementById("vehVin").value=e.vin||"",document.getElementById("vehMake").value=e.make||"",document.getElementById("vehModel").value=e.model||"",document.getElementById("vehYear").value=e.year||"",document.getElementById("vehMileage").value=e.current_mileage||0,document.getElementById("vehFuel").value=e.fuel_type||"gasolina",document.getElementById("vehColor").value=e.color||"",document.getElementById("vehOwner").value=e.owner_name||"",document.getElementById("vehNotes").value=e.notes||""):(n.textContent="Nuevo Vehiculo",document.getElementById("vehEditId").value="",["vehPlate","vehVin","vehMake","vehModel","vehYear","vehColor","vehOwner","vehNotes"].forEach((function(e){document.getElementById(e).value=""})),document.getElementById("vehMileage").value="0",document.getElementById("vehFuel").value="gasolina"),t.classList.add("is-open")}function v(){document.getElementById("vehicleModal").classList.remove("is-open")}function h(){fetch(e+"/vehicles?per_page=200",{headers:l()}).then((function(e){return e.json()})).then((function(t){var n=(t.data||[]).map((function(t){return fetch(e+"/vehicles/"+t.id+"/schedules",{headers:l()}).then((function(e){return e.json()})).then((function(e){return{vehicle:t,schedules:e.data||[]}}))}));return Promise.all(n)})).then((function(e){!function(e){var t=document.getElementById("maintBody"),n=[];if(e.forEach((function(e){e.schedules.forEach((function(t){n.push({vehicle:e.vehicle,schedule:t})}))})),!n.length)return void(t.innerHTML='No hay programas de mantenimiento.
');p||(p=new VirtualScroll({container:t,rowHeight:64,buffer:3,renderRow:g,emptyHtml:'No hay programas de mantenimiento.'}));p.setData(n)}(e)})).catch((function(){document.getElementById("maintBody").innerHTML='Error al cargar'}))}function g(e){var t=e.vehicle,n=e.schedule,a=new Date,o=!1;n.next_due_at&&new Date(n.next_due_at)"+d(t.plate||"S/P")+'
'+d((t.make||"")+" "+(t.model||""))+""+d(n.maintenance_type)+''+(l||"—")+""+r(n.last_done_at)+(n.last_done_km?'
'+c(n.last_done_km)+" km":"")+""+(i||"—")+''+(o?"Vencido":"Al dia")+'"}var p=null;function y(){fetch(e+"/vehicles?per_page=200",{headers:l()}).then((function(e){return e.json()})).then((function(t){var n=(t.data||[]).map((function(t){return fetch(e+"/vehicles/"+t.id,{headers:l()}).then((function(e){return e.json()})).then((function(e){return{vehicle:t,logs:e.recent_logs||[]}}))}));return Promise.all(n)})).then((function(e){!function(e){var t=document.getElementById("historyBody"),n=[];if(e.forEach((function(e){e.logs.forEach((function(t){t._plate=e.vehicle.plate||"S/P",t._make=(e.vehicle.make||"")+" "+(e.vehicle.model||""),n.push(t)}))})),n.sort((function(e,t){return new Date(t.created_at)-new Date(e.created_at)})),!n.length)return void(t.innerHTML='No hay registros de mantenimiento');_||(_=new VirtualScroll({container:t,rowHeight:48,buffer:3,renderRow:f,emptyHtml:'No hay registros de mantenimiento'}));_.setData(n)}(e)})).catch((function(){document.getElementById("historyBody").innerHTML='Error al cargar'}))}function f(e){return""+r(e.created_at)+""+d(e._plate)+'
'+d(e._make)+""+d(e.maintenance_type)+''+c(e.mileage_at)+''+i(e.cost)+""+d(e.employee_name||"—")+''+d(e.notes||"—")+""}var _=null;function E(){fetch(e+"/alerts",{headers:l()}).then((function(e){return e.json()})).then((function(e){!function(e){var t=document.getElementById("alertsList");if(!e.length)return void(t.innerHTML='
No hay mantenimientos vencidos
');var n="";e.forEach((function(e){var t="";e.next_due_at&&(t+="Vencio: "+r(e.next_due_at)),e.next_due_km&&(t+=(t?" | ":"")+"Limite: "+c(e.next_due_km)+" km (actual: "+c(e.current_mileage)+" km)"),n+='
'+d(e.plate||"S/P")+" — "+d((e.make||"")+" "+(e.model||""))+(e.year?" "+e.year:"")+'
'+d(e.maintenance_type)+"   "+t+'
"})),t.innerHTML=n}(e.data||[])})).catch((function(){document.getElementById("alertsList").innerHTML='
Error al cargar alertas
'}))}function I(){document.getElementById("scheduleModal").classList.remove("is-open")}function B(){var e=document.getElementById("logModal");document.getElementById("logScheduleSelect").innerHTML='',document.getElementById("logType").value="",document.getElementById("logMileage").value="",document.getElementById("logCost").value="",document.getElementById("logParts").value="",document.getElementById("logNotes").value="",e.classList.add("is-open")}function b(){document.getElementById("logModal").classList.remove("is-open")}return document.addEventListener("DOMContentLoaded",(function(){document.querySelectorAll(".tab-btn").forEach((function(e){e.addEventListener("click",(function(){var e=this.getAttribute("data-tab");document.querySelectorAll(".tab-btn").forEach((function(e){e.classList.remove("is-active")})),document.querySelectorAll(".tab-panel").forEach((function(e){e.classList.remove("is-active")})),this.classList.add("is-active"),document.getElementById("tab-"+e).classList.add("is-active"),"maintenance"===e&&h(),"history"===e&&y(),"alerts"===e&&E()}))}));var e=document.getElementById("searchInput");e&&e.addEventListener("input",(function(){clearTimeout(o),o=setTimeout((function(){a=1,s()}),300)})),document.getElementById("btnNewVehicle").addEventListener("click",(function(){m()})),u(),s()})),{openVehicleModal:m,closeVehicleModal:v,saveVehicle:function(){var t=document.getElementById("vehEditId").value,n={plate:document.getElementById("vehPlate").value.trim(),vin:document.getElementById("vehVin").value.trim(),make:document.getElementById("vehMake").value.trim(),model:document.getElementById("vehModel").value.trim(),year:parseInt(document.getElementById("vehYear").value)||null,current_mileage:parseInt(document.getElementById("vehMileage").value)||0,fuel_type:document.getElementById("vehFuel").value,color:document.getElementById("vehColor").value.trim(),owner_name:document.getElementById("vehOwner").value.trim(),notes:document.getElementById("vehNotes").value.trim()};if(n.plate||n.vin){var a=e+"/vehicles",o="POST";t&&(a+="/"+t,o="PUT"),fetch(a,{method:o,headers:l(),body:JSON.stringify(n)}).then((function(e){return e.json()})).then((function(e){e.error?alert(e.error):(v(),s(),u())})).catch((function(e){alert("Error: "+e.message)}))}else alert("Se requiere placa o VIN")},viewVehicle:function(t){fetch(e+"/vehicles/"+t,{headers:l()}).then((function(e){return e.json()})).then((function(e){m(e)}))},goPage:function(e){a=e,s()},openScheduleModal:function(e){var t=document.getElementById("scheduleModal");document.getElementById("schedType").value="",document.getElementById("schedIntervalKm").value="",document.getElementById("schedIntervalMonths").value="",document.getElementById("schedNextDate").value="",document.getElementById("schedNextKm").value="",document.getElementById("schedNotes").value="",e&&(document.getElementById("schedVehicleSelect").value=e),t.classList.add("is-open")},closeScheduleModal:I,saveSchedule:function(){var t=document.getElementById("schedVehicleSelect").value;if(t){var n=document.getElementById("schedType").value.trim();if(n){var a={maintenance_type:n,interval_km:parseInt(document.getElementById("schedIntervalKm").value)||null,interval_months:parseInt(document.getElementById("schedIntervalMonths").value)||null,next_due_at:document.getElementById("schedNextDate").value||null,next_due_km:parseInt(document.getElementById("schedNextKm").value)||null,notes:document.getElementById("schedNotes").value.trim()};fetch(e+"/vehicles/"+t+"/schedules",{method:"POST",headers:l(),body:JSON.stringify(a)}).then((function(e){return e.json()})).then((function(e){e.error?alert(e.error):(I(),h(),u())})).catch((function(e){alert("Error: "+e.message)}))}else alert("Ingrese el tipo de mantenimiento")}else alert("Seleccione un vehiculo")},openLogModal:B,openLogModalFor:function(t,a,o){B(),document.getElementById("logVehicleSelect").value=t,o&&(document.getElementById("logType").value=o),fetch(e+"/vehicles/"+t+"/schedules",{headers:l()}).then((function(e){return e.json()})).then((function(e){var t='';(e.data||[]).forEach((function(e){var n=e.id==a?" selected":"";t+='"})),document.getElementById("logScheduleSelect").innerHTML=t}));var c=n.find((function(e){return e.id==t}));c&&(document.getElementById("logMileage").value=c.current_mileage||"")},closeLogModal:b,saveLog:function(){var t=document.getElementById("logVehicleSelect").value;if(t){var n=document.getElementById("logType").value.trim();if(n){var a={schedule_id:parseInt(document.getElementById("logScheduleSelect").value)||null,maintenance_type:n,mileage_at:parseInt(document.getElementById("logMileage").value)||null,cost:parseFloat(document.getElementById("logCost").value)||0,parts_used:document.getElementById("logParts").value.trim(),notes:document.getElementById("logNotes").value.trim()};fetch(e+"/vehicles/"+t+"/log",{method:"POST",headers:l(),body:JSON.stringify(a)}).then((function(e){return e.json()})).then((function(e){if(e.error)alert(e.error);else{b(),u();var t=document.querySelector(".tab-btn.is-active");if(t){var n=t.getAttribute("data-tab");"maintenance"===n&&h(),"history"===n&&y(),"alerts"===n&&E(),"vehicles"===n&&s()}}})).catch((function(e){alert("Error: "+e.message)}))}else alert("Ingrese el tipo de mantenimiento")}else alert("Seleccione un vehiculo")}}}(); \ No newline at end of file diff --git a/pos/static/js/inventory.min.js b/pos/static/js/inventory.min.js index d5d87ea..1f7d01a 100644 --- a/pos/static/js/inventory.min.js +++ b/pos/static/js/inventory.min.js @@ -1 +1 @@ -!function(){"use strict";var t="/pos/api/inventory",e=localStorage.getItem("pos_token");if(e){var o={Authorization:"Bearer "+e,"Content-Type":"application/json"},n=1,a="",r=null,i=window.switchTab;window.switchTab=function(t){"function"==typeof i&&i(t),"alertas"===t&&v(),"stock"===t&&m(n)};var s,d=document.getElementById("productSearch");d&&d.addEventListener("input",(function(){clearTimeout(s),s=setTimeout((function(){m(1,d.value.trim())}),350)})),window._loadItems=function(t){m(t)},window.loadItems=function(t,e){m(t,e)},window.viewHistory=function(e){c(t+"/items/"+e+"/history").then((function(t){if(t){var e=t.data||[],o="";e.length?(o='',e.forEach((function(t){var e=t.quantity>0?"var(--color-success)":"var(--color-error)";o+='"})),o+="
FechaTipoCantidadCostoEmpleadoNotas
'+u(t.date)+""+u(t.type)+''+(t.quantity>0?"+":"")+t.quantity+''+(t.cost?"$"+l(t.cost):"—")+""+u(t.employee)+''+u(t.notes)+"
"):o='

Sin movimientos

',document.getElementById("historyContent").innerHTML=o,document.getElementById("historyModal").classList.add("is-open")}}))},window.viewProductDetail=g,window.uploadItemImage=function(o){var n=document.createElement("input");n.type="file",n.accept="image/jpeg,image/png,image/webp",n.onchange=function(){if(n.files&&n.files[0]){var a=n.files[0];if(a.size>5242880)alert("Imagen demasiado grande (max 5 MB)");else{var r=new FormData;r.append("file",a);var i=document.getElementById("imgUploadStatus");i&&(i.textContent="Subiendo..."),fetch(t+"/items/"+o+"/image",{method:"POST",headers:{Authorization:"Bearer "+e},body:r}).then((function(t){return t.json()})).then((function(t){t.image_url?g(o):i&&(i.textContent=t.error||"Error")})).catch((function(){i&&(i.textContent="Error de red")}))}}},n.click()},window.deleteItemImage=function(o){confirm("Eliminar imagen de este producto?")&&fetch(t+"/items/"+o+"/image",{method:"DELETE",headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){t.message?g(o):alert(t.error||"Error")})).catch((function(){alert("Error de red")}))},window.closeHistoryModal=function(){document.getElementById("historyModal").classList.remove("is-open")},window.showCreateModal=function(){document.getElementById("createModal").classList.add("is-open");var e=document.getElementById("newPartNumber");e&&!e._classifyBound&&(e._classifyBound=!0,e.addEventListener("blur",(function(){var e=this.value.trim();if(!(e.length<3)){var o,n,a=document.getElementById("newName");if(!a||!a.value.trim())o=e,(n=document.getElementById("createResult")).innerHTML='Consultando IA...',c(t+"/classify/"+encodeURIComponent(o)).then((function(t){if(t){t.name&&(document.getElementById("newName").value=t.name),t.brand&&(document.getElementById("newBrand").value=t.brand);var e=[];t.name&&e.push(t.name),t.brand&&e.push(t.brand),t.vehicle&&e.push(t.vehicle),t.category&&e.push(t.category),e.length>0?n.innerHTML='Sugerido por IA: '+u(e.join(" | "))+"":n.innerHTML='IA no pudo identificar este numero de parte'}})).catch((function(){n.innerHTML=""}))}})))},window.closeCreateModal=function(){document.getElementById("createModal").classList.remove("is-open"),document.getElementById("createResult").innerHTML=""},window.createItem=function(){var e={part_number:document.getElementById("newPartNumber").value.trim(),name:document.getElementById("newName").value.trim(),brand:document.getElementById("newBrand").value.trim(),barcode:document.getElementById("newBarcode").value.trim()||void 0,cost:parseFloat(document.getElementById("newCost").value)||0,price_1:parseFloat(document.getElementById("newPrice1").value)||0,price_2:parseFloat(document.getElementById("newPrice2").value)||0,price_3:parseFloat(document.getElementById("newPrice3").value)||0,min_stock:parseInt(document.getElementById("newMinStock").value)||0,initial_stock:parseInt(document.getElementById("newInitialStock").value)||0,location:document.getElementById("newLocation").value.trim()};e.part_number&&e.name?c(t+"/items",{method:"POST",body:JSON.stringify(e)}).then((function(t){t&&t.id?(document.getElementById("createResult").innerHTML='Creado ID '+t.id+" | Barcode: "+t.barcode+"",m(n)):document.getElementById("createResult").innerHTML=''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("createResult").innerHTML='Numero de parte y nombre son obligatorios'},window.showPurchaseModal=function(){document.getElementById("purchaseModal").classList.add("is-open")},window.closePurchaseModal=function(){document.getElementById("purchaseModal").classList.remove("is-open"),document.getElementById("purchaseResult").innerHTML=""},window.recordPurchase=function(){var e={inventory_id:parseInt(document.getElementById("purchaseItemId").value),quantity:parseInt(document.getElementById("purchaseQty").value),unit_cost:parseFloat(document.getElementById("purchaseCost").value),supplier_invoice:document.getElementById("purchaseInvoice").value.trim(),notes:document.getElementById("purchaseNotes").value.trim()};e.inventory_id&&e.quantity&&e.unit_cost?c(t+"/purchase",{method:"POST",body:JSON.stringify(e)}).then((function(t){document.getElementById("purchaseResult").innerHTML=t&&t.operation_id?'Compra registrada (op #'+t.operation_id+")":''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("purchaseResult").innerHTML='Complete todos los campos obligatorios'},window.showAdjustmentModal=function(){document.getElementById("adjustmentModal").classList.add("is-open")},window.closeAdjustmentModal=function(){document.getElementById("adjustmentModal").classList.remove("is-open"),document.getElementById("adjustResult").innerHTML=""},window.recordAdjustment=function(){var e={inventory_id:parseInt(document.getElementById("adjustItemId").value),quantity:parseInt(document.getElementById("adjustQty").value),reason:document.getElementById("adjustReason").value.trim()};e.inventory_id&&void 0!==e.quantity&&e.reason?c(t+"/adjustment",{method:"POST",body:JSON.stringify(e)}).then((function(t){document.getElementById("adjustResult").innerHTML=t&&t.operation_id?'Ajuste registrado (op #'+t.operation_id+")":''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("adjustResult").innerHTML='Complete todos los campos (razon obligatoria)'},window.showTransferModal=function(){document.getElementById("transferModal").classList.add("is-open")},window.closeTransferModal=function(){document.getElementById("transferModal").classList.remove("is-open"),document.getElementById("transferResult").innerHTML=""},window.recordTransfer=function(){var e={inventory_id:parseInt(document.getElementById("transferItemId").value),from_branch_id:parseInt(document.getElementById("transferFrom").value),to_branch_id:parseInt(document.getElementById("transferTo").value),quantity:parseInt(document.getElementById("transferQty").value),notes:document.getElementById("transferNotes").value.trim()};e.inventory_id&&e.from_branch_id&&e.to_branch_id&&e.quantity?c(t+"/transfer",{method:"POST",body:JSON.stringify(e)}).then((function(t){document.getElementById("transferResult").innerHTML=t&&t.out_operation_id?'Transferencia registrada':''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("transferResult").innerHTML='Complete todos los campos'},window.showCountModal=function(){document.getElementById("countModal").classList.add("is-open"),document.querySelectorAll("#countLines .count-row").length||p()},window.closeCountModal=function(){document.getElementById("countModal").classList.remove("is-open")},window.addCountLine=p,window.startPhysicalCount=function(){var e=document.querySelectorAll("#countLines .count-row"),o=[];e.forEach((function(t){var e=parseInt(t.querySelector(".count-inv-id").value),n=parseInt(t.querySelector(".count-qty").value);e&&!isNaN(n)&&o.push({inventory_id:e,counted_quantity:n})})),o.length?c(t+"/physical-count/start",{method:"POST",body:JSON.stringify({items:o})}).then((function(t){if(t&&t.count_id){r=t.count_id;var e='

Borrador #'+t.count_id+" — "+u(t.message)+"

";e+='',(t.results||[]).forEach((function(t){var o=0===t.difference?"var(--color-success)":t.difference<0?"var(--color-error)":"var(--color-warning)";e+=""})),e+="
IDEsperadoContadoDiferencia
"+t.inventory_id+""+t.expected+""+t.counted+''+(t.difference>0?"+":"")+t.difference+"
",e+='
',e+='',e+='',e+="
",document.getElementById("countResults").innerHTML=e}else document.getElementById("countResults").innerHTML=''+(t?t.error||"Error":"Error de red")+""})):alert("Agregue al menos una linea")},window.approvePhysicalCount=function(){r?c(t+"/physical-count/approve",{method:"POST",body:JSON.stringify({count_id:r})}).then((function(t){t&&"approved"===t.status?(document.getElementById("countResults").innerHTML=''+u(t.message)+"",r=null):document.getElementById("countResults").innerHTML+='
'+(t?t.error||"Error":"Error de red")+""})):alert("No hay borrador activo")},window.cancelDraft=function(){r=null,document.getElementById("countResults").innerHTML='Borrador cancelado'},window.loadAlerts=v,window.printBarcode=function(t,e,o){var n=window.open("","_blank","width=400,height=250");n.document.write("Etiqueta"),n.document.write("

"+t+"

"),n.document.write("

"+e+"

"),n.document.write('

'+o+"

"),n.document.write(""),n.document.close(),n.print()},m(1)}else window.location.href="/pos/login";function c(t,e){return fetch(t,Object.assign({headers:o},e||{})).then((function(t){return 401===t.status?(localStorage.removeItem("pos_token"),window.location.href="/pos/login",null):t.json()}))}function l(t){return(parseFloat(t)||0).toFixed(2)}function u(t){if(!t)return"";var e=document.createElement("div");return e.textContent=t,e.innerHTML}function m(e,o){n=e||1,a=void 0!==o?o:a;var r=new URLSearchParams({page:n,per_page:50});a&&r.set("q",a),c(t+"/items?"+r.toString()).then((function(t){if(t){var e=document.getElementById("productTableBody"),o=t.data||[];if(!o.length)return e.innerHTML='Sin productos',void(document.getElementById("productPagination").innerHTML="");e.innerHTML=o.map((function(t){return''+u(t.barcode)+''+u(t.part_number)+''+u(t.name)+""+u(t.brand)+''+t.stock+'$'+l(t.cost)+'$'+l(t.price_1)+'$'+l(t.price_2)+'$'+l(t.price_3)+""+u(t.location)+' "})).join("");var n=t.pagination||{},a=document.getElementById("productPagination");n.total_pages>1?a.innerHTML='":a.innerHTML=''+(n.total||0)+" productos"}}))}function p(){var t=document.getElementById("countLines"),e=document.createElement("div");e.className="count-row",e.innerHTML='',t.appendChild(e)}function v(){c(t+"/alerts").then((function(t){if(t){var e=t.data||[],o=document.getElementById("alertsContent");if(o)if(e.length){var n="",a=e.filter((function(t){return"critical"===t.severity})),r=e.filter((function(t){return"warning"===t.severity})),i=e.filter((function(t){return"critical"!==t.severity&&"warning"!==t.severity}));a.length&&(n+='
Criticas
'+a.length+"
",n+='
',a.forEach((function(t){var e="zero"===t.type?"AGOTADO":"low"===t.type?"BAJO":t.type.toUpperCase();n+=y(t,e,"critical")})),n+="
"),r.length&&(n+='
Advertencias
'+r.length+"
",n+='
',r.forEach((function(t){n+=y(t,"EXCESO","warning")})),n+="
"),i.length&&(n+='
Informativas
'+i.length+"
",n+='
',i.forEach((function(t){n+=y(t,"INFO","info")})),n+="
"),o.innerHTML=n}else o.innerHTML='

Sin alertas activas

'}}))}function y(t,e,o){return'
['+e+"] "+u(t.part_number)+" — "+u(t.name)+'
Stock: '+t.stock+(t.min_stock?" (min: "+t.min_stock+")":"")+(t.max_stock?" (max: "+t.max_stock+")":"")+" · Sucursal "+t.branch_id+"
"}function g(o){c(t+"/items/"+o).then((function(t){if(t&&!t.error){var n=t.history||[],a="";a+='
',t.image_url?(a+=''+u(t.name)+'',a+='
',a+='',a+='',a+="
"):(a+='
',a+='',a+='
Sin imagen
',a+="
",a+=''),a+='',a+="
",a+='
',a+='
No. Parte'+u(t.part_number)+"
",a+='
Nombre'+u(t.name)+"
",a+='
Marca'+u(t.brand)+"
",a+='
Codigo de Barras'+u(t.barcode)+"
",a+='
Ubicacion'+u(t.location||"-")+"
",a+='
Stock'+(t.stock||0)+"
",a+="
",a+='
',a+='
Costo$'+l(t.cost)+"
",a+='
Precio 1$'+l(t.price_1)+"
",a+='
Precio 2$'+l(t.price_2)+"
",a+='
Precio 3$'+l(t.price_3)+"
",a+="
",a+='
Cross-References / Equivalencias
',a+='
',a+='

Cargando equivalencias...

',a+="
";var r,i=t.part_number,s=t.catalog_part_id;r=s?"/pos/api/catalog/part/"+s:"/pos/api/catalog/search?q="+encodeURIComponent(i),fetch(r,{headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){var o=document.getElementById("crossRefContent");if(o){var n=t.alternatives||[],a=t.bodegas||[];!s&&t.data&&t.data.length>0?fetch("/pos/api/catalog/part/"+t.data[0].id_part,{headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){d(o,t.alternatives||[],t.bodegas||[])})).catch((function(){o.innerHTML='

Sin conexion al catalogo.

'})):d(o,n,a)}})).catch((function(){var t=document.getElementById("crossRefContent");t&&(t.innerHTML='

Sin conexion al catalogo central.

')})),a+='
Vehiculos Compatibles
',a+='
',a+='

Cargando compatibilidades...

',a+="
",fetch("/pos/api/inventory/items/"+o+"/vehicles",{headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){var e=document.getElementById("compatContent");if(e){var n=t.vehicles||[],a="";n.length>0?(a+='',n.forEach((function(t){a+="",a+=''})),a+="
MarcaModeloAnoMotorOrigen
"+u(t.brand||"")+""+u(t.model||"")+""+u(t.year||"")+""+u(t.engine||"")+""+u(t.source||"")+"
"):a+='

Sin vehiculos vinculados.

',a+='
Busca en catalogo central y vincula automaticamente
',e.innerHTML=a}})).catch((function(){var t=document.getElementById("compatContent");t&&(t.innerHTML='

Error al cargar compatibilidades.

')})),a+='
Historial de Movimientos
',n.length?(a+='',n.forEach((function(t){var e=t.quantity>0?"var(--color-success)":"var(--color-error)";a+='"})),a+="
FechaTipoCantidadCostoEmpleadoNotas
'+u(t.date)+""+u(t.type)+''+(t.quantity>0?"+":"")+t.quantity+''+(t.cost?"$"+l(t.cost):"—")+""+u(t.employee)+''+u(t.notes)+"
"):a+='

Sin movimientos

',document.getElementById("historyContent").innerHTML=a,document.getElementById("historyModal").classList.add("is-open")}else alert(t?t.error:"Error de red");function d(t,e,o){var n="";o&&o.length>0&&(n+='
Disponible en Bodegas:
',n+='',o.forEach((function(t){n+=""})),n+="
BodegaStockPrecioUbicacion
"+u(t.business_name||t.bodega||"")+""+(t.stock||t.stock_quantity||0)+'$'+l(t.price||0)+""+u(t.location||t.warehouse_location||"")+"
"),e&&e.length>0&&(n+='
Partes Equivalentes (Aftermarket):
',n+='',e.forEach((function(t){n+='"})),n+="
No. ParteFabricanteNombre
'+u(t.part_number||t.cross_reference_number||"")+""+u(t.manufacturer||t.source_ref||"")+""+u(t.name||t.name_aftermarket_parts||"")+"
"),n||(n='

No se encontraron equivalencias para esta parte.

'),t.innerHTML=n}}))}}(); \ No newline at end of file +!function(){"use strict";var t="/pos/api/inventory",e=localStorage.getItem("pos_token");if(e){var o={Authorization:"Bearer "+e,"Content-Type":"application/json"},n=1,a="",r=null,i=null,s=window.switchTab;window.switchTab=function(t){"function"==typeof s&&s(t),"alertas"===t&&g(),"stock"===t&&v(n)};var d,c=document.getElementById("productSearch");c&&c.addEventListener("input",(function(){clearTimeout(d),d=setTimeout((function(){v(1,c.value.trim())}),350)})),window._loadItems=function(t){v(t)},window.loadItems=function(t,e){v(t,e)},window.viewHistory=function(e){l(t+"/items/"+e+"/history").then((function(t){if(t){var e=t.data||[],o="";e.length?(o='',e.forEach((function(t){var e=t.quantity>0?"var(--color-success)":"var(--color-error)";o+='"})),o+="
FechaTipoCantidadCostoEmpleadoNotas
'+m(t.date)+""+m(t.type)+''+(t.quantity>0?"+":"")+t.quantity+''+(t.cost?"$"+u(t.cost):"—")+""+m(t.employee)+''+m(t.notes)+"
"):o='

Sin movimientos

',document.getElementById("historyContent").innerHTML=o,document.getElementById("historyModal").classList.add("is-open")}}))},window.viewProductDetail=f,window.uploadItemImage=function(o){var n=document.createElement("input");n.type="file",n.accept="image/jpeg,image/png,image/webp",n.onchange=function(){if(n.files&&n.files[0]){var a=n.files[0];if(a.size>5242880)alert("Imagen demasiado grande (max 5 MB)");else{var r=new FormData;r.append("file",a);var i=document.getElementById("imgUploadStatus");i&&(i.textContent="Subiendo..."),fetch(t+"/items/"+o+"/image",{method:"POST",headers:{Authorization:"Bearer "+e},body:r}).then((function(t){return t.json()})).then((function(t){t.image_url?f(o):i&&(i.textContent=t.error||"Error")})).catch((function(){i&&(i.textContent="Error de red")}))}}},n.click()},window.deleteItemImage=function(o){confirm("Eliminar imagen de este producto?")&&fetch(t+"/items/"+o+"/image",{method:"DELETE",headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){t.message?f(o):alert(t.error||"Error")})).catch((function(){alert("Error de red")}))},window.closeHistoryModal=function(){document.getElementById("historyModal").classList.remove("is-open")},window.showCreateModal=function(){document.getElementById("createModal").classList.add("is-open");var e=document.getElementById("newPartNumber");e&&!e._classifyBound&&(e._classifyBound=!0,e.addEventListener("blur",(function(){var e=this.value.trim();if(!(e.length<3)){var o,n,a=document.getElementById("newName");if(!a||!a.value.trim())o=e,(n=document.getElementById("createResult")).innerHTML='Consultando IA...',l(t+"/classify/"+encodeURIComponent(o)).then((function(t){if(t){t.name&&(document.getElementById("newName").value=t.name),t.brand&&(document.getElementById("newBrand").value=t.brand);var e=[];t.name&&e.push(t.name),t.brand&&e.push(t.brand),t.vehicle&&e.push(t.vehicle),t.category&&e.push(t.category),e.length>0?n.innerHTML='Sugerido por IA: '+m(e.join(" | "))+"":n.innerHTML='IA no pudo identificar este numero de parte'}})).catch((function(){n.innerHTML=""}))}})))},window.closeCreateModal=function(){document.getElementById("createModal").classList.remove("is-open"),document.getElementById("createResult").innerHTML=""},window.createItem=function(){var e={part_number:document.getElementById("newPartNumber").value.trim(),name:document.getElementById("newName").value.trim(),brand:document.getElementById("newBrand").value.trim(),barcode:document.getElementById("newBarcode").value.trim()||void 0,cost:parseFloat(document.getElementById("newCost").value)||0,price_1:parseFloat(document.getElementById("newPrice1").value)||0,price_2:parseFloat(document.getElementById("newPrice2").value)||0,price_3:parseFloat(document.getElementById("newPrice3").value)||0,min_stock:parseInt(document.getElementById("newMinStock").value)||0,initial_stock:parseInt(document.getElementById("newInitialStock").value)||0,location:document.getElementById("newLocation").value.trim()};e.part_number&&e.name?l(t+"/items",{method:"POST",body:JSON.stringify(e)}).then((function(t){t&&t.id?(document.getElementById("createResult").innerHTML='Creado ID '+t.id+" | Barcode: "+t.barcode+"",v(n)):document.getElementById("createResult").innerHTML=''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("createResult").innerHTML='Numero de parte y nombre son obligatorios'},window.showPurchaseModal=function(){document.getElementById("purchaseModal").classList.add("is-open")},window.closePurchaseModal=function(){document.getElementById("purchaseModal").classList.remove("is-open"),document.getElementById("purchaseResult").innerHTML=""},window.recordPurchase=function(){var e={inventory_id:parseInt(document.getElementById("purchaseItemId").value),quantity:parseInt(document.getElementById("purchaseQty").value),unit_cost:parseFloat(document.getElementById("purchaseCost").value),supplier_invoice:document.getElementById("purchaseInvoice").value.trim(),notes:document.getElementById("purchaseNotes").value.trim()};e.inventory_id&&e.quantity&&e.unit_cost?l(t+"/purchase",{method:"POST",body:JSON.stringify(e)}).then((function(t){document.getElementById("purchaseResult").innerHTML=t&&t.operation_id?'Compra registrada (op #'+t.operation_id+")":''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("purchaseResult").innerHTML='Complete todos los campos obligatorios'},window.showAdjustmentModal=function(){document.getElementById("adjustmentModal").classList.add("is-open")},window.closeAdjustmentModal=function(){document.getElementById("adjustmentModal").classList.remove("is-open"),document.getElementById("adjustResult").innerHTML=""},window.recordAdjustment=function(){var e={inventory_id:parseInt(document.getElementById("adjustItemId").value),quantity:parseInt(document.getElementById("adjustQty").value),reason:document.getElementById("adjustReason").value.trim()};e.inventory_id&&void 0!==e.quantity&&e.reason?l(t+"/adjustment",{method:"POST",body:JSON.stringify(e)}).then((function(t){document.getElementById("adjustResult").innerHTML=t&&t.operation_id?'Ajuste registrado (op #'+t.operation_id+")":''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("adjustResult").innerHTML='Complete todos los campos (razon obligatoria)'},window.showTransferModal=function(){document.getElementById("transferModal").classList.add("is-open")},window.closeTransferModal=function(){document.getElementById("transferModal").classList.remove("is-open"),document.getElementById("transferResult").innerHTML=""},window.recordTransfer=function(){var e={inventory_id:parseInt(document.getElementById("transferItemId").value),from_branch_id:parseInt(document.getElementById("transferFrom").value),to_branch_id:parseInt(document.getElementById("transferTo").value),quantity:parseInt(document.getElementById("transferQty").value),notes:document.getElementById("transferNotes").value.trim()};e.inventory_id&&e.from_branch_id&&e.to_branch_id&&e.quantity?l(t+"/transfer",{method:"POST",body:JSON.stringify(e)}).then((function(t){document.getElementById("transferResult").innerHTML=t&&t.out_operation_id?'Transferencia registrada':''+(t?t.error||"Error":"Error de red")+""})):document.getElementById("transferResult").innerHTML='Complete todos los campos'},window.showCountModal=function(){document.getElementById("countModal").classList.add("is-open"),document.querySelectorAll("#countLines .count-row").length||y()},window.closeCountModal=function(){document.getElementById("countModal").classList.remove("is-open")},window.addCountLine=y,window.startPhysicalCount=function(){var e=document.querySelectorAll("#countLines .count-row"),o=[];e.forEach((function(t){var e=parseInt(t.querySelector(".count-inv-id").value),n=parseInt(t.querySelector(".count-qty").value);e&&!isNaN(n)&&o.push({inventory_id:e,counted_quantity:n})})),o.length?l(t+"/physical-count/start",{method:"POST",body:JSON.stringify({items:o})}).then((function(t){if(t&&t.count_id){r=t.count_id;var e='

Borrador #'+t.count_id+" — "+m(t.message)+"

";e+='',(t.results||[]).forEach((function(t){var o=0===t.difference?"var(--color-success)":t.difference<0?"var(--color-error)":"var(--color-warning)";e+=""})),e+="
IDEsperadoContadoDiferencia
"+t.inventory_id+""+t.expected+""+t.counted+''+(t.difference>0?"+":"")+t.difference+"
",e+='
',e+='',e+='',e+="
",document.getElementById("countResults").innerHTML=e}else document.getElementById("countResults").innerHTML=''+(t?t.error||"Error":"Error de red")+""})):alert("Agregue al menos una linea")},window.approvePhysicalCount=function(){r?l(t+"/physical-count/approve",{method:"POST",body:JSON.stringify({count_id:r})}).then((function(t){t&&"approved"===t.status?(document.getElementById("countResults").innerHTML=''+m(t.message)+"",r=null):document.getElementById("countResults").innerHTML+='
'+(t?t.error||"Error":"Error de red")+""})):alert("No hay borrador activo")},window.cancelDraft=function(){r=null,document.getElementById("countResults").innerHTML='Borrador cancelado'},window.loadAlerts=g,window.printBarcode=function(t,e,o){var n=window.open("","_blank","width=400,height=250");n.document.write("Etiqueta"),n.document.write("

"+t+"

"),n.document.write("

"+e+"

"),n.document.write('

'+o+"

"),n.document.write(""),n.document.close(),n.print()},v(1)}else window.location.href="/pos/login";function l(t,e){return fetch(t,Object.assign({headers:o},e||{})).then((function(t){return 401===t.status?(localStorage.removeItem("pos_token"),window.location.href="/pos/login",null):t.json()}))}function u(t){return(parseFloat(t)||0).toFixed(2)}function m(t){if(!t)return"";var e=document.createElement("div");return e.textContent=t,e.innerHTML}function p(t){return''+m(t.barcode)+''+m(t.part_number)+''+m(t.name)+""+m(t.brand)+''+t.stock+'$'+u(t.cost)+'$'+u(t.price_1)+'$'+u(t.price_2)+'$'+u(t.price_3)+""+m(t.location)+' "}function v(e,o){n=e||1,a=void 0!==o?o:a;var r=new URLSearchParams({page:n,per_page:50});a&&r.set("q",a),l(t+"/items?"+r.toString()).then((function(t){if(t){var e=document.getElementById("productTableBody"),o=t.data||[];if(!o.length)return e.innerHTML='Sin productos',void(document.getElementById("productPagination").innerHTML="");i||(i=new VirtualScroll({container:e,rowHeight:48,buffer:3,renderRow:p,emptyHtml:'Sin productos'})),i.setData(o);var n=t.pagination||{},a=document.getElementById("productPagination");n.total_pages>1?a.innerHTML='":a.innerHTML=''+(n.total||0)+" productos"}}))}function y(){var t=document.getElementById("countLines"),e=document.createElement("div");e.className="count-row",e.innerHTML='',t.appendChild(e)}function g(){l(t+"/alerts").then((function(t){if(t){var e=t.data||[],o=document.getElementById("alertsContent");if(o)if(e.length){var n="",a=e.filter((function(t){return"critical"===t.severity})),r=e.filter((function(t){return"warning"===t.severity})),i=e.filter((function(t){return"critical"!==t.severity&&"warning"!==t.severity}));a.length&&(n+='
Criticas
'+a.length+"
",n+='
',a.forEach((function(t){var e="zero"===t.type?"AGOTADO":"low"===t.type?"BAJO":t.type.toUpperCase();n+=h(t,e,"critical")})),n+="
"),r.length&&(n+='
Advertencias
'+r.length+"
",n+='
',r.forEach((function(t){n+=h(t,"EXCESO","warning")})),n+="
"),i.length&&(n+='
Informativas
'+i.length+"
",n+='
',i.forEach((function(t){n+=h(t,"INFO","info")})),n+="
"),o.innerHTML=n}else o.innerHTML='

Sin alertas activas

'}}))}function h(t,e,o){return'
['+e+"] "+m(t.part_number)+" — "+m(t.name)+'
Stock: '+t.stock+(t.min_stock?" (min: "+t.min_stock+")":"")+(t.max_stock?" (max: "+t.max_stock+")":"")+" · Sucursal "+t.branch_id+"
"}function f(o){l(t+"/items/"+o).then((function(t){if(t&&!t.error){var n=t.history||[],a="";a+='
',t.image_url?(a+=''+m(t.name)+'',a+='
',a+='',a+='',a+="
"):(a+='
',a+='',a+='
Sin imagen
',a+="
",a+=''),a+='',a+="
",a+='
',a+='
No. Parte'+m(t.part_number)+"
",a+='
Nombre'+m(t.name)+"
",a+='
Marca'+m(t.brand)+"
",a+='
Codigo de Barras'+m(t.barcode)+"
",a+='
Ubicacion'+m(t.location||"-")+"
",a+='
Stock'+(t.stock||0)+"
",a+="
",a+='
',a+='
Costo$'+u(t.cost)+"
",a+='
Precio 1$'+u(t.price_1)+"
",a+='
Precio 2$'+u(t.price_2)+"
",a+='
Precio 3$'+u(t.price_3)+"
",a+="
",a+='
Cross-References / Equivalencias
',a+='
',a+='

Cargando equivalencias...

',a+="
";var r,i=t.part_number,s=t.catalog_part_id;r=s?"/pos/api/catalog/part/"+s:"/pos/api/catalog/search?q="+encodeURIComponent(i),fetch(r,{headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){var o=document.getElementById("crossRefContent");if(o){var n=t.alternatives||[],a=t.bodegas||[];!s&&t.data&&t.data.length>0?fetch("/pos/api/catalog/part/"+t.data[0].id_part,{headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){d(o,t.alternatives||[],t.bodegas||[])})).catch((function(){o.innerHTML='

Sin conexion al catalogo.

'})):d(o,n,a)}})).catch((function(){var t=document.getElementById("crossRefContent");t&&(t.innerHTML='

Sin conexion al catalogo central.

')})),a+='
Vehiculos Compatibles
',a+='
',a+='

Cargando compatibilidades...

',a+="
",fetch("/pos/api/inventory/items/"+o+"/vehicles",{headers:{Authorization:"Bearer "+e}}).then((function(t){return t.json()})).then((function(t){var e=document.getElementById("compatContent");if(e){var n=t.vehicles||[],a="";n.length>0?(a+='',n.forEach((function(t){a+="",a+=''})),a+="
MarcaModeloAnoMotorOrigen
"+m(t.brand||"")+""+m(t.model||"")+""+m(t.year||"")+""+m(t.engine||"")+""+m(t.source||"")+"
"):a+='

Sin vehiculos vinculados.

',a+='
Busca en catalogo central y vincula automaticamente
',e.innerHTML=a}})).catch((function(){var t=document.getElementById("compatContent");t&&(t.innerHTML='

Error al cargar compatibilidades.

')})),a+='
Historial de Movimientos
',n.length?(a+='',n.forEach((function(t){var e=t.quantity>0?"var(--color-success)":"var(--color-error)";a+='"})),a+="
FechaTipoCantidadCostoEmpleadoNotas
'+m(t.date)+""+m(t.type)+''+(t.quantity>0?"+":"")+t.quantity+''+(t.cost?"$"+u(t.cost):"—")+""+m(t.employee)+''+m(t.notes)+"
"):a+='

Sin movimientos

',document.getElementById("historyContent").innerHTML=a,document.getElementById("historyModal").classList.add("is-open")}else alert(t?t.error:"Error de red");function d(t,e,o){var n="";o&&o.length>0&&(n+='
Disponible en Bodegas:
',n+='',o.forEach((function(t){n+=""})),n+="
BodegaStockPrecioUbicacion
"+m(t.business_name||t.bodega||"")+""+(t.stock||t.stock_quantity||0)+'$'+u(t.price||0)+""+m(t.location||t.warehouse_location||"")+"
"),e&&e.length>0&&(n+='
Partes Equivalentes (Aftermarket):
',n+='',e.forEach((function(t){n+='"})),n+="
No. ParteFabricanteNombre
'+m(t.part_number||t.cross_reference_number||"")+""+m(t.manufacturer||t.source_ref||"")+""+m(t.name||t.name_aftermarket_parts||"")+"
"),n||(n='

No se encontraron equivalencias para esta parte.

'),t.innerHTML=n}}))}}(); \ No newline at end of file diff --git a/pos/static/js/pos-utils.min.js b/pos/static/js/pos-utils.min.js index 27e954f..cb2b595 100644 --- a/pos/static/js/pos-utils.min.js +++ b/pos/static/js/pos-utils.min.js @@ -1 +1 @@ -!function(){"use strict";window.exportVisibleTableCSV=function(t){t=t||"datos";for(var e=document.querySelectorAll("table"),o=null,n=0;n✕',r.appendChild(a),n.forEach((function(t){var o=document.createElement("div"),n=document.createElement("label");n.style.cssText="display:block;font-size:12px;color:var(--color-text-muted);margin-bottom:4px;text-transform:uppercase;letter-spacing:0.05em;",n.textContent=t.label,o.appendChild(n);var a=document.createElement("select");a.style.cssText="width:100%;padding:8px 10px;background:var(--glass-bg,#222);border:1px solid var(--glass-border,#444);border-radius:6px;color:var(--color-text-primary,#fff);font-size:13px;",a.dataset.filterColumn=t.column;var i=document.createElement("option");i.value="",i.textContent=t.allLabel||"Todos",a.appendChild(i),(t.values||[]).forEach((function(t){if(t){var e=document.createElement("option");e.value=t,e.textContent=t,a.appendChild(e)}})),a.addEventListener("change",(function(){e(r)})),o.appendChild(a),r.appendChild(o)}));var i=document.createElement("button");i.style.cssText="padding:8px;background:transparent;border:1px dashed var(--glass-border,#444);border-radius:6px;color:var(--color-text-muted);cursor:pointer;font-size:12px;",i.textContent="Limpiar filtros",i.addEventListener("click",(function(){r.querySelectorAll("select").forEach((function(t){t.value=""})),e(r)})),r.appendChild(i);var l=o.parentElement;l&&(l.style.position="relative"),(l||document.body).appendChild(r),t=r,setTimeout((function(){document.addEventListener("click",(function t(e){r.contains(e.target)||e.target===o||(closeFilterPanel(),document.removeEventListener("click",t))}))}),100)},window.closeFilterPanel=function(){t&&(t.remove(),t=null)},window.getUniqueColumnValues=function(t,e,o){o=o||30;var n={};return t?(t.querySelectorAll("tbody tr").forEach((function(t){var o=t.querySelectorAll("td");if(o[e]){var r=o[e].textContent.trim();r&&"-"!==r&&""!==r&&(n[r]=(n[r]||0)+1)}})),Object.keys(n).sort((function(t,e){return n[e]-n[t]})).slice(0,o)):[]};var o=null;function n(t,e){fetch("/pos/api/quotations/"+t+"/print",{method:"POST",headers:{Authorization:"Bearer "+e,"Content-Type":"application/json"},body:JSON.stringify({printer_type:"browser"})}).then((function(t){return t.json()})).then((function(o){var n="Cotización #"+o.id+"";n+="",n+="

COTIZACIÓN

",n+='

COT-'+o.id+"

",n+="

Fecha: "+(o.created_at||"").substring(0,10)+"

",o.customer_name&&(n+="

Cliente: "+o.customer_name+"

"),o.wa_phone&&(n+="

WhatsApp: "+o.wa_phone+"

"),n+="
",(o.items||[]).forEach((function(t){n+="",t.part_number&&(n+='")})),n+="
"+t.quantity+"x "+t.name+'$'+t.subtotal.toFixed(2)+"
#'+t.part_number+"

",n+='

Subtotal: $'+o.subtotal.toFixed(2)+"

",n+='

IVA: $'+o.tax_total.toFixed(2)+"

",n+='

TOTAL: $'+o.total.toFixed(2)+"

",n+='

Esta cotización no es comprobante fiscal
Precios sujetos a disponibilidad

',n+="";var a=window.open("","_blank","width=400,height=600");a.document.write(n),a.document.close(),setTimeout((function(){a.print()}),500),r(t,e)})).catch((function(t){console.error("[auto-print] Browser print failed:",t)}))}function r(t,e){fetch("/pos/api/quotations/"+t+"/mark-printed",{method:"POST",headers:{Authorization:"Bearer "+e}}).catch((function(){}))}(window.startAutoPrint=function(){if(!o){0;var t=localStorage.getItem("pos_token");t&&(o=setInterval((function(){fetch("/pos/api/quotations/print-queue",{headers:{Authorization:"Bearer "+t}}).then((function(t){return t.json()})).then((function(e){e.data&&e.data.length&&e.data.forEach((function(e){console.log("[auto-print] Cotización #"+e.id+" confirmada por WhatsApp — imprimiendo..."),showToast("🖨️ Imprimiendo cotización #"+e.id+" (WhatsApp)","ok"),function(t,e){"undefined"!=typeof NexusPrinter&&NexusPrinter.isConnected&&NexusPrinter.isConnected()?fetch("/pos/api/quotations/"+t+"/print",{method:"POST",headers:{Authorization:"Bearer "+e,"Content-Type":"application/json"},body:JSON.stringify({printer_type:"escpos_raw",width:80})}).then((function(t){return t.arrayBuffer()})).then((function(o){NexusPrinter.sendRaw(new Uint8Array(o)),r(t,e)})).catch((function(o){console.error("[auto-print] Thermal print failed:",o),n(t,e)})):n(t,e)}(e.id,t)}))})).catch((function(){}))}),15e3),console.log("[auto-print] Enabled — polling every 15s"))}},window.stopAutoPrint=function(){o&&(clearInterval(o),o=null)},-1!==window.location.pathname.indexOf("/pos/sale")||-1!==window.location.pathname.indexOf("/pos/quotation")||-1!==window.location.pathname.indexOf("/pos/dashboard"))&&(localStorage.getItem("pos_token")&&setTimeout((function(){startAutoPrint()}),3e3));if(!document.getElementById("pos-utils-styles")){var a=document.createElement("style");a.id="pos-utils-styles",a.textContent="@keyframes slideInRight{from{transform:translateX(100%);opacity:0}to{transform:translateX(0);opacity:1}}.filter-panel select:focus{outline:none;border-color:var(--color-primary,#F5A623);box-shadow:0 0 0 2px var(--glow-color-soft,rgba(245,166,35,0.15));}",document.head.appendChild(a)}}(); \ No newline at end of file +!function(){"use strict";window.exportVisibleTableCSV=function(t){t=t||"datos";for(var e=document.querySelectorAll("table"),o=null,n=0;n✕',r.appendChild(a),n.forEach((function(t){var o=document.createElement("div"),n=document.createElement("label");n.style.cssText="display:block;font-size:12px;color:var(--color-text-muted);margin-bottom:4px;text-transform:uppercase;letter-spacing:0.05em;",n.textContent=t.label,o.appendChild(n);var a=document.createElement("select");a.style.cssText="width:100%;padding:8px 10px;background:var(--glass-bg,#222);border:1px solid var(--glass-border,#444);border-radius:6px;color:var(--color-text-primary,#fff);font-size:13px;",a.dataset.filterColumn=t.column;var i=document.createElement("option");i.value="",i.textContent=t.allLabel||"Todos",a.appendChild(i),(t.values||[]).forEach((function(t){if(t){var e=document.createElement("option");e.value=t,e.textContent=t,a.appendChild(e)}})),a.addEventListener("change",(function(){e(r)})),o.appendChild(a),r.appendChild(o)}));var i=document.createElement("button");i.style.cssText="padding:8px;background:transparent;border:1px dashed var(--glass-border,#444);border-radius:6px;color:var(--color-text-muted);cursor:pointer;font-size:12px;",i.textContent="Limpiar filtros",i.addEventListener("click",(function(){r.querySelectorAll("select").forEach((function(t){t.value=""})),e(r)})),r.appendChild(i);var l=o.parentElement;l&&(l.style.position="relative"),(l||document.body).appendChild(r),t=r,setTimeout((function(){document.addEventListener("click",(function t(e){r.contains(e.target)||e.target===o||(closeFilterPanel(),document.removeEventListener("click",t))}))}),100)},window.closeFilterPanel=function(){t&&(t.remove(),t=null)},window.getUniqueColumnValues=function(t,e,o){o=o||30;var n={};return t?(t.querySelectorAll("tbody tr").forEach((function(t){var o=t.querySelectorAll("td");if(o[e]){var r=o[e].textContent.trim();r&&"-"!==r&&""!==r&&(n[r]=(n[r]||0)+1)}})),Object.keys(n).sort((function(t,e){return n[e]-n[t]})).slice(0,o)):[]};var o=null;function n(t,e){fetch("/pos/api/quotations/"+t+"/print",{method:"POST",headers:{Authorization:"Bearer "+e,"Content-Type":"application/json"},body:JSON.stringify({printer_type:"browser"})}).then((function(t){return t.json()})).then((function(o){var n="Cotización #"+o.id+"";n+="",n+="

COTIZACIÓN

",n+='

COT-'+o.id+"

",n+="

Fecha: "+(o.created_at||"").substring(0,10)+"

",o.customer_name&&(n+="

Cliente: "+o.customer_name+"

"),o.wa_phone&&(n+="

WhatsApp: "+o.wa_phone+"

"),n+="
",(o.items||[]).forEach((function(t){n+="",t.part_number&&(n+='")})),n+="
"+t.quantity+"x "+t.name+'$'+t.subtotal.toFixed(2)+"
#'+t.part_number+"

",n+='

Subtotal: $'+o.subtotal.toFixed(2)+"

",n+='

IVA: $'+o.tax_total.toFixed(2)+"

",n+='

TOTAL: $'+o.total.toFixed(2)+"

",n+='

Esta cotización no es comprobante fiscal
Precios sujetos a disponibilidad

',n+="";var a=window.open("","_blank","width=400,height=600");a.document.write(n),a.document.close(),setTimeout((function(){a.print()}),500),r(t,e)})).catch((function(t){console.error("[auto-print] Browser print failed:",t)}))}function r(t,e){fetch("/pos/api/quotations/"+t+"/mark-printed",{method:"POST",headers:{Authorization:"Bearer "+e}}).catch((function(){}))}(window.startAutoPrint=function(){if(!o){0;var t=localStorage.getItem("pos_token");t&&(o=setInterval((function(){fetch("/pos/api/quotations/print-queue",{headers:{Authorization:"Bearer "+t}}).then((function(t){return t.json()})).then((function(e){e.data&&e.data.length&&e.data.forEach((function(e){console.log("[auto-print] Cotización #"+e.id+" confirmada por WhatsApp — imprimiendo..."),showToast("🖨️ Imprimiendo cotización #"+e.id+" (WhatsApp)","ok"),function(t,e){"undefined"!=typeof NexusPrinter&&NexusPrinter.isConnected&&NexusPrinter.isConnected()?fetch("/pos/api/quotations/"+t+"/print",{method:"POST",headers:{Authorization:"Bearer "+e,"Content-Type":"application/json"},body:JSON.stringify({printer_type:"escpos_raw",width:80})}).then((function(t){return t.arrayBuffer()})).then((function(o){NexusPrinter.sendRaw(new Uint8Array(o)),r(t,e)})).catch((function(o){console.error("[auto-print] Thermal print failed:",o),n(t,e)})):n(t,e)}(e.id,t)}))})).catch((function(){}))}),15e3),console.log("[auto-print] Enabled — polling every 15s"))}},window.stopAutoPrint=function(){o&&(clearInterval(o),o=null)},-1!==window.location.pathname.indexOf("/pos/sale")||-1!==window.location.pathname.indexOf("/pos/quotation")||-1!==window.location.pathname.indexOf("/pos/dashboard"))&&(localStorage.getItem("pos_token")&&setTimeout((function(){startAutoPrint()}),3e3))}(); \ No newline at end of file diff --git a/pos/static/js/sidebar.min.js b/pos/static/js/sidebar.min.js index 40c7d88..9bfafbd 100644 --- a/pos/static/js/sidebar.min.js +++ b/pos/static/js/sidebar.min.js @@ -1 +1 @@ -!function(){"use strict";var e="function"==typeof window.t?window.t:function(e){return e},r=window.POS_USER||{},a=r.name||"Usuario",t=r.roleLabel||"",o=r.initials||"?",i=window.location.pathname,n=localStorage.getItem("pos_theme")||"industrial",s=localStorage.getItem("pos_lang")||"es",l=[{label:e("nav_main"),items:[{name:e("dashboard"),href:"/pos/dashboard",icon:''},{name:e("pos"),href:"/pos/sale",icon:''},{name:e("catalog"),href:"/pos/catalog",icon:''},{name:e("inventory"),href:"/pos/inventory",icon:''}]},{label:e("nav_management"),items:[{name:e("customers"),href:"/pos/customers",icon:''},{name:"Cotizaciones",href:"/pos/quotations",icon:''},{name:"Marketplace",href:"/pos/marketplace",icon:''},{name:e("invoicing"),href:"/pos/invoicing",icon:''},{name:e("accounting"),href:"/pos/accounting",icon:''},{name:e("reports"),href:"/pos/reports",icon:''},{name:e("fleet"),href:"/pos/fleet",icon:''},{name:e("whatsapp"),href:"/pos/whatsapp",icon:''}]},{label:e("nav_system"),items:[{name:e("config"),href:"/pos/config",icon:''}]}];var d="";l.forEach((function(e){d+='",e.items.forEach((function(e){var r=i===e.href;d+='"+(''+e.icon+"")+e.name+""}))}));var c='',p='';window.updateThemeButtons=function(){var e=localStorage.getItem("pos_theme")||"industrial";document.querySelectorAll(".theme-toggle-btn").forEach((function(r,a){r.classList.toggle("is-active",0===a?"industrial"===e:"modern"===e)}))};var g='"+c+p+'',m=document.createElement("style");m.textContent=[".pos-sidebar{position:fixed;top:0;left:0;bottom:0;width:260px;display:flex;flex-direction:column;background:var(--color-bg-elevated);border-right:1px solid var(--color-border);z-index:100;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--scrollbar-thumb,#444) var(--scrollbar-track,#222);font-family:var(--font-body)}",".pos-sidebar::-webkit-scrollbar{width:4px}",".pos-sidebar::-webkit-scrollbar-track{background:var(--scrollbar-track,#222)}",".pos-sidebar::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb,#444);border-radius:99px}",".sidebar__brand{display:flex;align-items:center;gap:var(--space-3,12px);padding:var(--space-4,16px) var(--space-4,16px) var(--space-3,12px);border-bottom:1px solid var(--color-border);flex-shrink:0}",".brand-logo{width:36px;height:36px;display:flex;align-items:center;justify-content:center;background:var(--color-primary);color:var(--color-text-inverse,#fff);font-family:var(--font-heading);font-weight:800;font-size:1rem;letter-spacing:-0.04em;flex-shrink:0}",'[data-theme="industrial"] .brand-logo{clip-path:polygon(0 0,calc(100% - 9px) 0,100% 9px,100% 100%,0 100%)}','[data-theme="modern"] .brand-logo{border-radius:var(--radius-md,8px)}',".brand-name__primary{font-family:var(--font-heading);font-weight:800;font-size:0.9375rem;letter-spacing:var(--tracking-wide,0.02em);text-transform:uppercase;color:var(--color-text-primary);line-height:1}",".brand-name__sub{font-size:var(--text-caption,0.75rem);color:var(--color-text-muted);letter-spacing:var(--tracking-wider,0.04em);text-transform:uppercase;margin-top:2px}",".sidebar__nav{flex:1;padding:var(--space-3,12px) 0}",".nav-section-label{padding:var(--space-3,12px) var(--space-4,16px) var(--space-1,4px);font-size:0.6875rem;font-weight:600;letter-spacing:var(--tracking-widest,0.08em);text-transform:uppercase;color:var(--color-text-muted)}",".nav-item{display:flex;align-items:center;gap:var(--space-3,12px);padding:var(--space-2,8px) var(--space-4,16px);color:var(--color-text-secondary);text-decoration:none;font-size:var(--text-body-sm,0.875rem);font-weight:400;border-left:3px solid transparent;transition:all 0.15s;cursor:pointer}",".nav-item:hover{background:var(--color-surface-2,rgba(255,255,255,0.04));color:var(--color-text-primary)}",".nav-item.is-active{background:var(--color-primary-muted,rgba(245,166,35,0.12));color:var(--color-primary);border-left-color:var(--color-primary);font-weight:600}",".nav-item__icon{width:18px;height:18px;flex-shrink:0;opacity:0.7}",".nav-item.is-active .nav-item__icon{opacity:1}",".sidebar__theme-toggle,.sidebar__lang-toggle{display:flex;gap:4px;padding:8px 16px;border-top:1px solid var(--color-border)}",".theme-toggle-btn,.lang-toggle-btn{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;padding:6px;border:1px solid var(--color-border);border-radius:var(--radius-sm,4px);background:none;color:var(--color-text-muted);cursor:pointer;transition:all 0.15s;font-size:0.75rem}",".theme-toggle-btn:hover,.lang-toggle-btn:hover{color:var(--color-text-primary);background:var(--color-surface-2,rgba(255,255,255,0.04))}",".theme-toggle-btn.is-active,.lang-toggle-btn.is-active{background:var(--color-primary-muted,rgba(245,166,35,0.12));color:var(--color-primary);border-color:var(--color-primary)}",".lang-flag{font-weight:700;font-size:0.625rem;letter-spacing:0.04em}",".sidebar__footer{padding:var(--space-3,12px) var(--space-4,16px);border-top:1px solid var(--color-border);display:flex;align-items:center;gap:var(--space-2,8px)}",".sidebar__user-avatar{width:28px;height:28px;border-radius:50%;background:var(--color-primary);color:var(--color-text-inverse,#fff);display:flex;align-items:center;justify-content:center;font-size:0.6875rem;font-weight:700;flex-shrink:0}",".sidebar__user-info{flex:1;overflow:hidden}",".sidebar__user-name{font-size:var(--text-body-sm,0.875rem);font-weight:600;color:var(--color-text-primary);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}",".sidebar__user-role{font-size:var(--text-caption,0.75rem);color:var(--color-text-muted)}",".sidebar__logout-btn{background:none;border:1px solid var(--color-border);border-radius:var(--radius-sm,4px);padding:4px 6px;cursor:pointer;color:var(--color-text-muted);transition:all 0.15s;display:flex;align-items:center}",".sidebar__logout-btn:hover{color:var(--color-error,#F85149);border-color:var(--color-error,#F85149)}",".pos-main-offset{margin-left:260px}","@media(max-width:768px){.pos-sidebar{width:56px}.brand-name,.nav-item span,.sidebar__user-info,.nav-section-label,.sidebar__theme-toggle,.sidebar__lang-toggle{display:none}.sidebar__brand{justify-content:center;padding:12px 8px}.sidebar__footer{flex-direction:column;padding:8px}.pos-main-offset{margin-left:56px}}"].join("\n"),document.head.appendChild(m);var v=document.querySelector("aside.sidebar, .sidebar, #sidebar");if(v)v.className="pos-sidebar",v.innerHTML=g,v.removeAttribute("style");else{var b=document.createElement("aside");b.className="pos-sidebar",b.innerHTML=g,document.body.insertBefore(b,document.body.firstChild)}var x=document.querySelector("main, .main-content, #mainContent, .main, .page-content");x&&x.classList.add("pos-main-offset");var h=document.querySelector(".pos-sidebar, .sidebar, #sidebar"),u=document.getElementById("sidebar-overlay");!u&&h&&((u=document.createElement("div")).id="sidebar-overlay",u.className="sidebar-overlay",u.addEventListener("click",(function(){_()})),h.parentNode.insertBefore(u,h));var f=document.getElementById("hamburger-btn");function y(){if(h){var e=h.classList.contains("open");h.classList.toggle("open",!e),u&&u.classList.toggle("open",!e),document.body.style.overflow=e?"":"hidden"}}function _(){h&&h.classList.remove("open"),u&&u.classList.remove("open"),document.body.style.overflow=""}f||((f=document.createElement("button")).id="hamburger-btn",f.className="hamburger-btn",f.setAttribute("aria-label","Menú"),f.innerHTML='',f.style.cssText="display:none;position:fixed;top:10px;left:10px;z-index:"+(parseInt(getComputedStyle(document.documentElement).getPropertyValue("--z-modal")||1050)+2)+";background:var(--glass-bg-strong);backdrop-filter:blur(12px);border:1px solid var(--glass-border);border-radius:var(--radius-md);padding:8px;cursor:pointer;color:var(--color-text-primary);box-shadow:0 2px 8px rgba(0,0,0,0.2);",f.addEventListener("click",(function(){y()})),document.body.appendChild(f)),window.addEventListener("resize",(function(){window.innerWidth>=1024&&_()})),window.toggleSidebar=y,window.closeSidebar=_}(); \ No newline at end of file +!function(){"use strict";var e="function"==typeof window.t?window.t:function(e){return e},t=window.POS_USER||{},n=t.name||"Usuario",a=t.roleLabel||"",i=t.initials||"?",o=window.location.pathname,s=localStorage.getItem("pos_theme")||"industrial",r=localStorage.getItem("pos_lang")||"es",l=[{label:e("nav_main"),items:[{name:e("dashboard"),href:"/pos/dashboard",icon:''},{name:e("pos"),href:"/pos/sale",icon:''},{name:e("catalog"),href:"/pos/catalog",icon:''},{name:e("inventory"),href:"/pos/inventory",icon:''}]},{label:e("nav_management"),items:[{name:e("customers"),href:"/pos/customers",icon:''},{name:"Cotizaciones",href:"/pos/quotations",icon:''},{name:"Marketplace",href:"/pos/marketplace",icon:''},{name:e("invoicing"),href:"/pos/invoicing",icon:''},{name:e("accounting"),href:"/pos/accounting",icon:''},{name:e("reports"),href:"/pos/reports",icon:''},{name:e("fleet"),href:"/pos/fleet",icon:''},{name:e("whatsapp"),href:"/pos/whatsapp",icon:''}]},{label:e("nav_system"),items:[{name:e("config"),href:"/pos/config",icon:''}]}];var c="";l.forEach((function(e){c+='",e.items.forEach((function(e){var t=o===e.href;c+='"+(''+e.icon+"")+e.name+""}))}));var d='',h='';window.updateThemeButtons=function(){var e=localStorage.getItem("pos_theme")||"industrial";document.querySelectorAll(".theme-toggle-btn").forEach((function(t,n){t.classList.toggle("is-active",0===n?"industrial"===e:"modern"===e)}))};var p='"+d+h+'',m=document.querySelector("aside.sidebar, .sidebar, #sidebar");if(m)m.className="pos-sidebar",m.innerHTML=p,m.removeAttribute("style");else{var u=document.createElement("aside");u.className="pos-sidebar",u.innerHTML=p,document.body.insertBefore(u,document.body.firstChild)}var v=document.querySelector("main, .main-content, #mainContent, .main, .page-content");v&&v.classList.add("pos-main-offset");var g=document.querySelector(".pos-sidebar, .sidebar, #sidebar"),y=document.getElementById("sidebar-overlay");!y&&g&&((y=document.createElement("div")).id="sidebar-overlay",y.className="sidebar-overlay",y.addEventListener("click",(function(){f()})),g.parentNode.insertBefore(y,g));var b=document.getElementById("hamburger-btn");function x(){if(g){var e=g.classList.contains("open");g.classList.toggle("open",!e),y&&y.classList.toggle("open",!e),document.body.style.overflow=e?"":"hidden"}}function f(){g&&g.classList.remove("open"),y&&y.classList.remove("open"),document.body.style.overflow=""}b||((b=document.createElement("button")).id="hamburger-btn",b.className="hamburger-btn",b.setAttribute("aria-label","Menú"),b.innerHTML='',b.style.cssText="display:none;position:fixed;top:10px;left:10px;z-index:"+(parseInt(getComputedStyle(document.documentElement).getPropertyValue("--z-modal")||1050)+2)+";background:var(--glass-bg-strong);backdrop-filter:blur(12px);border:1px solid var(--glass-border);border-radius:var(--radius-md);padding:8px;cursor:pointer;color:var(--color-text-primary);box-shadow:0 2px 8px rgba(0,0,0,0.2);",b.addEventListener("click",(function(){x()})),document.body.appendChild(b)),window.addEventListener("resize",(function(){window.innerWidth>=1024&&f()})),window.toggleSidebar=x,window.closeSidebar=f}(); \ No newline at end of file diff --git a/pos/static/js/virtual-scroll.min.js b/pos/static/js/virtual-scroll.min.js new file mode 100644 index 0000000..7fad6c6 --- /dev/null +++ b/pos/static/js/virtual-scroll.min.js @@ -0,0 +1 @@ +!function(t){"use strict";function e(t){this.container=t.container,this.rowHeight=t.rowHeight||48,this.buffer=t.buffer||5,this.renderRow=t.renderRow||function(){return""},this.emptyHtml=t.emptyHtml||"",this.data=[],this._scrollHandler=this._onScroll.bind(this),this._resizeHandler=this._onResize.bind(this),this._isTbody="TBODY"===this.container.tagName,this._init()}e.prototype._init=function(){var e=this.container;if(this._isTbody){var i=e.closest("table");if(i){var r=i.parentElement;r&&r.classList.contains("vs-container")&&r.addEventListener("scroll",this._scrollHandler,{passive:!0})}}else e.style.overflowY="auto",e.style.position="relative",e.style.maxHeight||e.style.height||(e.style.maxHeight="60vh");t.addEventListener("resize",this._resizeHandler,{passive:!0})},e.prototype.setData=function(t){this.data=t||[],this._render()},e.prototype.refresh=function(){this._render()},e.prototype._onScroll=function(){this._render()},e.prototype._onResize=function(){this._render()},e.prototype._getScrollTop=function(){if(this._isTbody){var t=this.container.closest("table");if(t){var e=t.parentElement;if(e&&e.classList.contains("vs-container"))return e.scrollTop}return 0}return this.container.scrollTop},e.prototype._getContainerHeight=function(){if(this._isTbody){var t=this.container.closest("table");if(t){var e=t.parentElement;if(e&&e.classList.contains("vs-container"))return e.clientHeight}return 600}return this.container.clientHeight},e.prototype._render=function(){var t=this.data,e=this.rowHeight,i=this.buffer;if(!t.length)return this._isTbody,void(this.container.innerHTML=this.emptyHtml);var r=this._getScrollTop(),n=this._getContainerHeight(),s=Math.max(0,Math.floor(r/e)-i),o=Math.min(t.length,Math.ceil((r+n)/e)+i),a="";if(this._isTbody){var l=s*e;l>0&&(a+='');for(var h=s;h0&&(a+='')}else for(var d=s;d