O relatório é gerado no fechamento do dia — informe a data do fechamento (normalmente hoje).
2. Envie o PDF "Relatório de Vendas"
Pedidos analíticos do lote — a leitura acontece no seu navegador.
Clique para escolher o PDF ou arraste aqui
Formato esperado: pedidos analíticos por lote/vendedor
ou cole o texto extraído manualmente
3. Envie o PDF "Relatório de Itens Cortados"
A leitura acontece no seu navegador — o PDF não é enviado a nenhum servidor.
Clique para escolher o PDF ou arraste aqui
Formato esperado: relatório de itens cortados (SLD INSUFIC)
ou cole o texto extraído manualmente
Sugestão de Pedido — Danone
R$ 0,00
Sugestão de Pedido — Tirolez
R$ 0,00
Itens não identificados
Não localizei o código de marca (Danone=60 / Tirolez=98) nestas linhas. Classifique manualmente antes de salvar.
Lojas afetadas
Ordenado da maior para a menor perda em R$.
Extrato de falta por loja
Itens que faltaram em cada loja, separados por fornecedor — igual ao relatório original, porém já organizado por cliente.
Produtos fora do catálogo
Esses itens venderam, mas o código não está cadastrado como Danone ou Tirolez ainda — por isso não entram no comparativo por fornecedor. Me diga o fornecedor de cada um pra eu incluir no catálogo.
Pedidos bloqueados
Pedidos lançados mas travados por crédito — não vão faturar até liberação. Valor abaixo é potencial, não confirmado.
Ranking de clientes
Ordenado da maior para a menor venda em R$. Barra cinza = valor bloqueado dentro do total do cliente.
Ranking de produtos
Itens mais vendidos no lote (inclui pedidos bloqueados).
Evolução de vendas
Valor total do lote (R$) por dia salvo — inclui pedidos bloqueados.
Relatórios salvos
Período
Filtra todos os indicadores abaixo por data. Por padrão mostra tudo que está salvo no histórico.
Liberado x Bloqueado x Perdido por ruptura
O quanto foi vendido de fato, o quanto ficou travado por crédito, e o quanto se deixou de vender por falta de estoque — dia a dia.
Potencial de faturamento por dia
Potencial = vendas liberadas + valor perdido por ruptura. É o que poderia ter sido faturado sem os problemas de estoque.
Top 20 clientes do período
Maiores clientes por valor vendido no período selecionado, do maior para o menor.
Produtos mais vendidos do período
Os 20% de produtos com maior valor vendido no período, do maior para o menor.
Danone x Tirolez — desempenho de vendas do período
Comparativo do valor total vendido de cada fornecedor no período selecionado.
Evolução da perda por ruptura
Valor total perdido (R$) por dia salvo.
Relatórios salvos
(e||0).toLocaleString("pt-BR",{style:"currency",currency:"BRL"}),fmtNum=e=>(e||0).toLocaleString("pt-BR");let currentParsed=null,perfil=null;async function initPerfil(){await loadUserCatalogOverrides();try{const e=await window.storage.get("perfil",!1);perfil=e?JSON.parse(e.value):null}catch(e){perfil=null}perfil?renderProfileBar():showPerfilModal()}function askMergeChoice(e,o){return new Promise(t=>{const a=document.createElement("div");a.className="modal-backdrop",a.innerHTML=`\n
\n
Já existe um relatório salvo em ${e}
\n
${o?"O que você quer fazer com os dados que acabou de processar?":"Esse relatório foi salvo por uma versão anterior do sistema. A soma ainda funciona, mas de forma agregada (por cliente/produto já totalizado, em vez de item a item)."}
Isso ajuda a identificar quem gerou cada relatório no histórico.
\n
\n \n \n
\n
Qual sua rota e nome?
\n
Seu nome/código fica salvo nesta conta e identifica seu histórico de relatórios.
\n
\n \n \n
\n \n
',document.body.appendChild(e),e.querySelector("#perfilSalvar").onclick=async()=>{const o=e.querySelector("#perfilFuncao").value,t=e.querySelector("#perfilNome").value.trim();o&&t&&(perfil={funcao:o,nome:t},await window.storage.set("perfil",JSON.stringify(perfil),!1),document.body.removeChild(e),renderProfileBar())}}function renderProfileBar(){document.getElementById("profileBar").innerHTML=`${escapeHtml(perfil.funcao||"Vendedor")}: ${escapeHtml(perfil.nome)} `,document.getElementById("trocarPerfil").onclick=showPerfilModal}function escapeHtml(e){return String(e).replace(/[&<>"']/g,e=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[e]))}document.querySelectorAll(".tab").forEach(e=>{e.onclick=()=>{document.querySelectorAll(".tab").forEach(e=>e.classList.remove("active")),document.querySelectorAll(".view").forEach(e=>e.classList.remove("active")),e.classList.add("active"),document.getElementById("view-"+e.dataset.view).classList.add("active"),"historico"===e.dataset.view&&renderHistorico(),"vendas-historico"===e.dataset.view&&renderHistoricoVendas(),"dashboard"===e.dataset.view&&renderDashboard()}}),document.getElementById("refDate").value=(new Date).toISOString().slice(0,10);const dropzone=document.getElementById("dropzone"),fileInput=document.getElementById("fileInput"),pasteArea=document.getElementById("pasteArea"),togglePaste=document.getElementById("togglePaste"),btnParse=document.getElementById("btnParse"),uploadStatus=document.getElementById("uploadStatus");let pendingFile=null,pendingPastedText=null,pendingLines=null;function handleFile(e){pendingFile=null,pendingPastedText=null,pendingLines=null,btnParse.disabled=!0,dropzone.querySelector(".big").textContent="Lendo "+e.name+"...",setStatus(uploadStatus,"ok","Lendo arquivo..."),extractPdfLines(e).then(o=>{pendingLines=o,dropzone.querySelector(".big").textContent="Arquivo selecionado: "+e.name,btnParse.disabled=!1,setStatus(uploadStatus,"ok","PDF lido, pronto para processar.")}).catch(e=>{dropzone.querySelector(".big").textContent="Clique para escolher o PDF ou arraste aqui",setStatus(uploadStatus,"err","Não consegui ler o PDF ("+e.message+"). Selecione o arquivo novamente (se ele estiver no OneDrive/Desktop sincronizado, abra-o uma vez fora daqui primeiro) ou cole o texto manualmente.")})}function setStatus(e,o,t){e.className="status show "+o,e.textContent=t}async function extractPdfLines(e){const o=await e.arrayBuffer(),t=await pdfjsLib.getDocument({data:o}).promise,a=[];for(let e=1;e<=t.numPages;e++){const o=await t.getPage(e),n=await o.getTextContent(),r=new Map;n.items.forEach(e=>{const o=Math.round(e.transform[5]);r.has(o)||r.set(o,[]),r.get(o).push(e)});Array.from(r.keys()).sort((e,o)=>o-e).forEach(e=>{const o=r.get(e).sort((e,o)=>e.transform[4]-o.transform[4]);let t="",n=null;o.forEach(e=>{const o=e.transform[4];null!==n&&o-n>1.2&&(t+=" "),t+=e.str,n=o+(e.width||0)}),t.trim()&&a.push(t.replace(/\s+/g," ").trim())})}return a}dropzone.onclick=()=>fileInput.click(),dropzone.ondragover=e=>{e.preventDefault(),dropzone.classList.add("drag")},dropzone.ondragleave=()=>dropzone.classList.remove("drag"),dropzone.ondrop=e=>{e.preventDefault(),dropzone.classList.remove("drag"),e.dataTransfer.files[0]&&handleFile(e.dataTransfer.files[0])},fileInput.onchange=()=>{fileInput.files[0]&&handleFile(fileInput.files[0])},togglePaste.onclick=()=>{pasteArea.style.display="none"===pasteArea.style.display?"block":"none"},pasteArea.oninput=()=>{pasteArea.value.trim().length>20&&(pendingPastedText=pasteArea.value,pendingFile=null,pendingLines=null,btnParse.disabled=!1)};const LINE_RE=/^(\S+-\S+)\s+(.+?)\s+(\d{9,10})\s+(.+?)\s+(\d{3})\s+(\d+)\s+(\d+)\s+(\d+)\s+([\d.,]+)\s+([\d.,]+)\s+(\d+)\s+PREPD\s+(\d+)\s+(.+)$/,META_RE=/grp:\s*(\d+)\s+cat:\s*(\d+)\s+mar:\s*(\d+)/;function toNumber(e){return e&&parseFloat(e.replace(/\./g,"").replace(",","."))||0}function parseReport(e){const o=[];for(let t=0;t{const n=o[e.prodCod]||e.fornecedor,r=t[n]||t.outros;r.has(e.prodCod)||r.set(e.prodCod,{prodCod:e.prodCod,prodDesc:e.prodDesc,qtd:0,vlTotal:0,lojas:new Set});const d=r.get(e.prodCod);d.qtd+=e.qtd,d.vlTotal+=e.vlTotal,d.lojas.add(e.clienteCod+"|"+e.clienteNome);const l=e.clienteCod+"|"+e.clienteNome;a.has(l)||a.set(l,{cod:e.clienteCod,nome:e.clienteNome,vlTotal:0,itens:0});const s=a.get(l);s.vlTotal+=e.vlTotal,s.itens+=1});const n=e=>Array.from(e.values()).map(e=>({...e,precoMedio:e.qtd?e.vlTotal/e.qtd:0,nLojas:e.lojas.size})).sort((e,o)=>o.vlTotal-e.vlTotal),r=Array.from(a.values()).sort((e,o)=>o.vlTotal-e.vlTotal);return{danone:n(t.danone),tirolez:n(t.tirolez),outros:n(t.outros),stores:r}}let manualOverrides={};async function processInput(){let e;if(pendingLines)e=pendingLines;else{if(!pendingPastedText)return void setStatus(uploadStatus,"err","Selecione um PDF ou cole o texto primeiro.");e=pendingPastedText.split("\n").map(e=>e.trim()).filter(Boolean)}const{records:o}=parseReport(e);0!==o.length?(manualOverrides={},currentParsed={records:o,date:document.getElementById("refDate").value},renderResults(),setStatus(uploadStatus,"ok",o.length+" linhas de ruptura reconhecidas.")):setStatus(uploadStatus,"err",'Nenhuma linha de ruptura (SLD INSUFIC) reconhecida. Verifique o arquivo ou use "colar texto".')}function renderResults(){let e;currentParsed.records?(e=consolidate(currentParsed.records,manualOverrides),currentParsed.consolidated=e):e=currentParsed.consolidated,document.getElementById("results").style.display="block",document.getElementById("btnSave").disabled=!1,document.getElementById("btnPrint").disabled=!1;const o=e.danone.reduce((e,o)=>e+o.vlTotal,0),t=e.tirolez.reduce((e,o)=>e+o.vlTotal,0),a=o+t+e.outros.reduce((e,o)=>e+o.vlTotal,0),n=e.danone.length+e.tirolez.length+e.outros.length,r=e.stores.length;document.getElementById("kpiRow").innerHTML=`\n
`).join("")}function buildSupplierText(e){const o=currentParsed.consolidated[e],t=FORNECEDOR_LABEL[e],a=currentParsed.date.split("-").reverse().join("/"),n="danone"===e?"danoneTableWrap":"tirolezTableWrap",r=document.getElementById(n),d={};r&&r.querySelectorAll("input.qty-edit").forEach(e=>{d[e.dataset.cod]=parseInt(e.value,10)});let l=`SUGESTAO DE PEDIDO - ${t.toUpperCase()}\n`;l+=`Vendedor: ${perfil?perfil.nome:"-"} Data da falta: ${a}\n`,l+="-".repeat(70)+"\n",l+="COD. DESCRICAO QTD PEDIDO PERDA(R$)\n",o.forEach(e=>{const o=Number.isFinite(d[e.prodCod])?d[e.prodCod]:e.qtd,t=e.prodCod.padEnd(11),a=e.prodDesc.slice(0,34).padEnd(35),n=String(o).padStart(6),r=fmtBRL(e.vlTotal).padStart(14);l+=`${t} ${a}${n} ${r}\n`});const s=o.reduce((e,o)=>e+o.vlTotal,0);return l+="-".repeat(70)+"\n",l+=`TOTAL PERDIDO ${t}: ${fmtBRL(s)}\n`,l}function copySupplierText(e){const o=buildSupplierText(e);navigator.clipboard.writeText(o).then(()=>{setStatus(uploadStatus,"ok","Sugestão de pedido ("+FORNECEDOR_LABEL[e]+") copiada. Cole no e-mail/WhatsApp para compras.")}).catch(()=>{alert(o)})}function fitKpiFontSize(e,o,t,a,n){let r=a;for(e.setFont("courier","bold");r>n&&(e.setFontSize(r),!(e.getTextWidth(o)<=t));)r-=.5;return e.setFontSize(r),r}function generatePdfBlob(){const{jsPDF:e}=window.jspdf,o=new e({unit:"mm",format:"a4"}),t=currentParsed.consolidated,a=currentParsed.date.split("-").reverse().join("/"),n=t.danone.reduce((e,o)=>e+o.vlTotal,0),r=t.tirolez.reduce((e,o)=>e+o.vlTotal,0),d=n+r+t.outros.reduce((e,o)=>e+o.vlTotal,0),l=[16,24,32],s=[90,101,112],i=[223,228,226],c=[11,95,165],u=[198,40,40],m=[244,246,245],v=12,f=186;let p=14,g=null,h=1;function C(e){p+e>279&&(P(),o.addPage(),h++,p=14,g&&g())}function P(){o.setFont("helvetica","normal"),o.setFontSize(7.5),o.setTextColor(160),o.text("Sistema em desenvolvimento · FacilPedirB2B",105,289,{align:"center"}),o.text(`Pg-${String(h).padStart(2,"0")}`,198,289,{align:"right"})}try{o.addImage(LOGO_BASE64,"PNG",v,p,9,9,void 0,"FAST")}catch(E){o.setFillColor(...l),o.roundedRect(v,p,9,9,1,1,"F"),o.setFont("courier","bold"),o.setFontSize(8),o.setTextColor(255,255,255),o.text("LA",16.5,p+6,{align:"center"})}o.setFont("helvetica","bold"),o.setFontSize(13.5),o.setTextColor(...l),o.text("Análise de Venda - Ruptura - Sugestão de Compra",24,p+5),o.setFont("helvetica","normal"),o.setFontSize(8.5),o.setTextColor(...s),o.text("Lago Azul · Danone & Tirolez",24,p+9.5),o.setFont("helvetica","normal"),o.setFontSize(8.5),o.setTextColor(...s),o.text(`${perfil&&perfil.funcao||"Vendedor"}: ${perfil?perfil.nome:"-"}`,198,p+5,{align:"right"}),o.text(`Data da falta: ${a}`,198,p+9.5,{align:"right"}),p+=13,o.setDrawColor(...l),o.setLineWidth(.6),o.line(v,p,198,p),o.setLineWidth(.2),p+=8;const L=[{label:"TOTAL PERDIDO",value:fmtBRL(d),color:l},{label:"PRODUTOS EM RUPTURA",value:fmtNum(t.danone.length+t.tirolez.length+t.outros.length),color:l},{label:"LOJAS AFETADAS",value:fmtNum(t.stores.length),color:l},{label:"DANONE",value:fmtBRL(n),color:c},{label:"TIROLEZ",value:fmtBRL(r),color:u}],b=(f-3*(L.length-1))/L.length;function T(e,t,a,n,r){if(C(t.length?14+6.4*Math.min(t.length,3):18),o.setFillColor(...n),o.rect(v,p,f,8,"F"),o.setFont("helvetica","bold"),o.setFontSize(9.5),o.setTextColor(255,255,255),o.text(`Sugestão de Pedido — ${e}`,15,p+5.5),o.setFont("courier","bold"),o.setFontSize(9.5),o.text(fmtBRL(a),195,p+5.5,{align:"right"}),p+=8,!t.length)return o.setFillColor(255,255,255),o.setDrawColor(...i),o.rect(v,p,f,10,"FD"),o.setFont("helvetica","italic"),o.setFontSize(8.5),o.setTextColor(...s),o.text("Nenhum item deste fornecedor neste relatório.",15,p+6.5),void(p+=10);const d=[{key:"prodCod",label:"Código",w:22,align:"left",mono:!0},{key:"prodDesc",label:"Descrição",w:62,align:"left",mono:!1},{key:"qtd",label:"Qtd",w:16,align:"right",mono:!0},{key:"nLojas",label:"Lojas",w:16,align:"right",mono:!0},{key:"precoMedio",label:"Preço médio",w:24,align:"right",mono:!0,fmt:fmtBRL},{key:"vlTotal",label:"Valor perdido",w:0,align:"right",mono:!0,fmt:fmtBRL}];function c(){o.setFillColor(...r),o.rect(v,p,f,6,"F");let e=v;o.setFont("helvetica","bold"),o.setFontSize(6.8),o.setTextColor(...s),d.forEach(t=>{const a="right"===t.align?e+t.w-2:e+2;o.text(t.label.toUpperCase(),a,p+4,{align:"right"===t.align?"right":"left"}),e+=t.w}),p+=6}d[d.length-1].w=f-d.slice(0,-1).reduce((e,o)=>e+o.w,0),c(),g=c,t.forEach((e,t)=>{C(6.4),t%2==1&&(o.setFillColor(...m),o.rect(v,p,f,6.4,"F"));let a=v;d.forEach(t=>{let n="prodDesc"===t.key?e[t.key].slice(0,40):e[t.key];const r=t.fmt?t.fmt(n):String(n);o.setFont(t.mono?"courier":"helvetica","normal"),o.setFontSize(7.6),o.setTextColor(...l);const d="right"===t.align?a+t.w-2:a+2;o.text(r,d,p+4.3,{align:"right"===t.align?"right":"left"}),a+=t.w}),o.setDrawColor(...i),o.line(v,p+6.4,198,p+6.4),p+=6.4}),g=null,p+=6}if(L.forEach((e,t)=>{const a=v+t*(b+3);o.setFillColor(255,255,255),o.setDrawColor(...i),o.roundedRect(a,p,b,18,1.2,1.2,"FD"),o.setFont("helvetica","bold"),o.setFontSize(6.3),o.setTextColor(...s),o.text(e.label,a+3,p+6),o.setTextColor(...e.color),fitKpiFontSize(o,e.value,b-6,11,6),o.text(e.value,a+3,p+14)}),p+=27,T("Danone",t.danone,n,c,[232,241,250]),T("Tirolez",t.tirolez,r,u,[251,234,234]),t.stores.length){const A=[{key:"cod",label:"Código",w:24,align:"left"},{key:"nome",label:"Loja",w:56,align:"left"},{key:"itens",label:"Itens",w:16,align:"right"},{key:"bar",label:"",w:34,align:"left"},{key:"vlTotal",label:"Valor perdido",w:0,align:"right",fmt:fmtBRL},{key:"pct",label:"% total",w:22,align:"right"}];A[A.length-2].w=f-A.reduce((e,o,t)=>t===A.length-2?e:e+o.w,0);function S(){o.setFillColor(...m),o.rect(v,p,f,6,"F");let e=v;o.setFont("helvetica","bold"),o.setFontSize(6.8),o.setTextColor(...s),A.forEach(t=>{if(t.label){const a="right"===t.align?e+t.w-2:e+2;o.text(t.label.toUpperCase(),a,p+4,{align:"right"===t.align?"right":"left"})}e+=t.w}),p+=6}C(19+6.4*Math.min(t.stores.length,3)),o.setFont("helvetica","bold"),o.setFontSize(10.5),o.setTextColor(...l),o.text("Lojas afetadas",v,p+5),p+=6,o.setFont("helvetica","normal"),o.setFontSize(7.5),o.setTextColor(...s),o.text("Ordenado da maior para a menor perda em R$.",v,p+3),p+=7,S(),g=S;const x=t.stores[0].vlTotal||1;t.stores.forEach((e,t)=>{C(6.4),t%2==1&&(o.setFillColor(...m),o.rect(v,p,f,6.4,"F"));let a=v;o.setFont("courier","normal"),o.setFontSize(7.6),o.setTextColor(...l),o.text(e.cod,a+2,p+4.3),a+=A[0].w,o.setFont("helvetica","normal"),o.text(e.nome.slice(0,32),a+2,p+4.3),a+=A[1].w,o.setFont("courier","normal"),o.text(String(e.itens),a+A[2].w-2,p+4.3,{align:"right"}),a+=A[2].w;const n=A[3].w-4,r=Math.max(1,e.vlTotal/x*n);o.setFillColor(...i),o.roundedRect(a+2,p+2,n,2,.5,.5,"F"),o.setFillColor(...l),o.roundedRect(a+2,p+2,r,2,.5,.5,"F"),a+=A[3].w,o.setFont("courier","bold"),o.text(fmtBRL(e.vlTotal),a+A[4].w-2,p+4.3,{align:"right"}),a+=A[4].w,o.setFont("courier","normal"),o.setTextColor(...s),o.text((e.vlTotal/d*100).toFixed(1)+"%",a+A[5].w-2,p+4.3,{align:"right"}),o.setDrawColor(...i),o.line(v,p+6.4,198,p+6.4),p+=6.4}),g=null}const y=currentParsed.storeExtract||[];if(y.length){p+=5,C(20),o.setFont("helvetica","bold"),o.setFontSize(10.5),o.setTextColor(...l),o.text("Extrato de falta por loja",v,p+5),p+=6,o.setFont("helvetica","normal"),o.setFontSize(7.5),o.setTextColor(...s),o.text("Itens que faltaram em cada loja, por fornecedor.",v,p+3),p+=8;const z=18,I=44,B=164,M=194;function D(e,t,a){if(!a.length)return;C(6),o.setFont("helvetica","bold"),o.setFontSize(7.6),o.setTextColor(...t),o.text(e.toUpperCase(),16,p+4),p+=5;let n=0;a.forEach(e=>{C(4.6),o.setFont("courier","normal"),o.setFontSize(7.4),o.setTextColor(...s),o.text(e.prodCod,z,p+3.3),o.setTextColor(...l),o.text(e.prodDesc.slice(0,34),I,p+3.3),o.text(String(e.qtd),B,p+3.3,{align:"right"}),o.text(fmtBRL(e.vlTotal),M,p+3.3,{align:"right"}),n+=e.vlTotal,p+=4.6}),C(5),o.setFont("helvetica","bold"),o.setFontSize(7.4),o.setTextColor(...s),o.text(`Subtotal ${e}: ${fmtBRL(n)}`,M,p+3.3,{align:"right"}),p+=5.5}y.forEach(e=>{const t=function(e){let o=9;return["danone","tirolez","outros"].forEach(t=>{const a=e[t]||[];a.length&&(o+=5+4.6*a.length+5.5)}),o+2}(e);C(t<=265?t:16),g=function(){o.setFont("helvetica","italic"),o.setFontSize(7.5),o.setTextColor(...s),o.text(`${e.nome} (continuação)`,v,p+4),p+=7},o.setFillColor(...m),o.rect(v,p,f,7,"F"),o.setFont("helvetica","bold"),o.setFontSize(8.5),o.setTextColor(...l);const a=e.nome.length>34?e.nome.slice(0,34)+"…":e.nome;o.text(a,15,p+4.8);const n=o.getTextWidth(a);o.setFont("courier","normal"),o.setFontSize(7.5),o.setTextColor(...s),o.text(e.cod,15+n+4,p+4.8),o.setFont("courier","bold"),o.setFontSize(8.5),o.setTextColor(...l),o.text(fmtBRL(e.vlTotal),195,p+4.8,{align:"right"}),p+=9,D("Danone",c,e.danone),D("Tirolez",u,e.tirolez),e.outros&&e.outros.length&&D("Outros",s,e.outros),g=null,p+=2})}return P(),o}async function renderHistorico(){const e=document.getElementById("histList"),o=document.getElementById("chartWrap");e.innerHTML='
`).join(""),e.querySelectorAll(".hist-main").forEach(e=>{e.onclick=()=>loadHistoricoDay(e.dataset.date)}),e.querySelectorAll(".hist-delete").forEach(e=>{e.onclick=o=>{o.stopPropagation(),deleteHistoricoDay(e.dataset.date)}})}async function deleteHistoricoDay(e){const o=e.split("-").reverse().join("/");if(confirm(`Excluir o relatório de ${o} do histórico? Essa ação não pode ser desfeita.`))try{await window.storage.delete("relatorio:"+e,!1);let o=[];try{const e=await window.storage.get("relatorios_index",!1);o=e?JSON.parse(e.value):[]}catch(e){o=[]}o=o.filter(o=>o.date!==e),await window.storage.set("relatorios_index",JSON.stringify(o),!1),renderHistorico()}catch(e){alert("Não foi possível excluir: "+e.message)}}async function loadHistoricoDay(e){try{const o=await window.storage.get("relatorio:"+e,!1);if(!o)return;const t=JSON.parse(o.value);currentParsed={date:e,consolidated:t.cons,storeExtract:t.storeExtract||[],records:t.records||null},manualOverrides={},document.getElementById("refDate").value=e,document.querySelector('.tab[data-view="novo"]').click(),renderResults(),setStatus(uploadStatus,"ok","Exibindo relatório salvo de "+e.split("-").reverse().join("/")+". Pode reclassificar produtos ou enviar outro PDF pra somar a este dia.")}catch(e){}}btnParse.onclick=processInput,document.getElementById("btnPrint").onclick=()=>{if(!currentParsed||!currentParsed.consolidated)return;const e=document.getElementById("saveStatus");try{if(!window.jspdf)return void setStatus(e,"err","Biblioteca de PDF não carregou. Verifique sua conexão e recarregue a página.");const o=generatePdfBlob(),t=`sugestao-pedidos-${currentParsed.date}.pdf`;o.save(t),setStatus(e,"ok","PDF baixado: "+t)}catch(o){setStatus(e,"err","Não consegui gerar o PDF ("+o.message+'). Use "Copiar para compras" como alternativa.')}},document.getElementById("btnSave").onclick=async()=>{if(!currentParsed||!perfil)return;const e=document.getElementById("saveStatus");try{let o=(currentParsed.records||[]).map(e=>({...e,fornecedor:manualOverrides[e.prodCod]||e.fornecedor})),t=null,a=null,n=null;try{const e=await window.storage.get("relatorio:"+currentParsed.date,!1);n=e?JSON.parse(e.value):null}catch(e){n=null}if(n){const r=currentParsed.date.split("-").reverse().join("/"),d=!!(n.records&&n.records.length&&o.length),l=await askMergeChoice(r,d);if("cancelar"===l)return void setStatus(e,"warn","Nada foi salvo.");if("somar"===l)if(d)o=n.records.concat(o);else{const e=o.length?consolidate(o,{}):currentParsed.consolidated;t=mergeConsolidatedRuptura(n.cons,e),a=mergeStoreExtract(n.storeExtract||[],currentParsed.storeExtract||[]),o=null}}t||(t=consolidate(o,{}),a=buildStoreExtract(o,{}));const r=t.danone.reduce((e,o)=>e+o.vlTotal,0),d=t.tirolez.reduce((e,o)=>e+o.vlTotal,0),l=t.outros.reduce((e,o)=>e+o.vlTotal,0),s=r+d+l,i={date:currentParsed.date,savedAt:(new Date).toISOString(),totalDanone:r,totalTirolez:d,totalOutros:l,totalGeral:s,nProdutos:t.danone.length+t.tirolez.length+t.outros.length,nLojas:t.stores.length,cons:t,storeExtract:a,records:o};await window.storage.set("relatorio:"+currentParsed.date,JSON.stringify(i),!1);let c=[];try{const e=await window.storage.get("relatorios_index",!1);c=e?JSON.parse(e.value):[]}catch(e){c=[]}c=c.filter(e=>e.date!==currentParsed.date),c.push({date:currentParsed.date,totalGeral:s,totalDanone:r,totalTirolez:d,nProdutos:i.nProdutos,nLojas:i.nLojas}),c.sort((e,o)=>e.date.localeCompare(o.date)),await window.storage.set("relatorios_index",JSON.stringify(c),!1),currentParsed.records=o,currentParsed.consolidated=t,currentParsed.storeExtract=a,manualOverrides={},renderResults(),setStatus(e,"ok","Relatório de "+currentParsed.date.split("-").reverse().join("/")+" salvo no seu histórico.")}catch(o){setStatus(e,"err","Erro ao salvar: "+o.message)}};const PEDIDO_RE=/^(\d+)\s+(\d{4}-\d{4})\s+(.+?)\s+TC-CP:([\d-]+)\s+<\s*(\d+)\s*DIAS\s*>\s+VCTO:(\d{2}\/\d{2}\/\d{2})/,ITEM_VENDA_RE=/^\s*(\d+)\s+(.+?)\s+(\d{3})\s+(\d+)\s+(?:[\d.,]+\s+)+?(20\d{2})\s+(\d{2})\s+(\d{2})\s+([\d.,]+)\s+([\d.,]+)\s+([\d.,]+)\s*$/,TOTAIS_RE=/PEDIDOS\/PESO:\s*(\d+)\/\s*([\d.,]+)\s+TOTAIS:\s*([\d.,]+)\s+([\d.,]+)/,TOTAIS2_RE=/TOTAL\/ITENS\s*:\s*(\d+)\s+TOTAL\/VL\.DESCONTO\s*:\s*([\d.,]+)\s+TOTAL\/PEDS\.BLOQ\.:\s*(\d+)\s+TOTAL\/PEDS\.BAN\.PRECO:\s*(\d+)/,DATA_RELATORIO_RE=/DATA\s*:\s*(\d{2})\/(\d{2})\/(\d{4})/;function parseVendasReport(e){const o=[];let t=null,a=null,n=null;for(let r=0;r{const r=catalogLookup(e.prodCod);r?"danone"===r.f?o+=e.valorTotal:"tirolez"===r.f&&(t+=e.valorTotal):(a+=e.valorTotal,n++)}),{totalDanone:o,totalTirolez:t,totalSemCatalogo:a,nProdutosSemCatalogo:n}}function consolidateVendas(e){const o=new Map,t=new Map,a=new Map;e.forEach(e=>{const n=e.cliCod+"|"+e.cliNome;o.has(n)||o.set(n,{cod:e.cliCod,nome:e.cliNome,valorTotal:0,valorLiberado:0,valorBloqueado:0,pedidos:new Set,pedidosBloqueados:new Set,itens:0});const r=o.get(n);r.valorTotal+=e.valorTotal,e.bloqueado?(r.valorBloqueado+=e.valorTotal,r.pedidosBloqueados.add(e.pedido)):r.valorLiberado+=e.valorTotal,r.pedidos.add(e.pedido),r.itens+=1,t.has(e.prodCod)||t.set(e.prodCod,{prodCod:e.prodCod,prodDesc:e.prodDesc,qtd:0,valorTotal:0,clientes:new Set});const d=t.get(e.prodCod);d.qtd+=e.qtd,d.valorTotal+=e.valorTotal,d.clientes.add(e.cliCod),a.set(e.pedido,e.bloqueado)});const n=Array.from(o.values()).map(e=>({...e,nPedidos:e.pedidos.size,nPedidosBloqueados:e.pedidosBloqueados.size})).sort((e,o)=>o.valorTotal-e.valorTotal),r=Array.from(t.values()).map(e=>({...e,nClientes:e.clientes.size})).sort((e,o)=>o.valorTotal-e.valorTotal),d=e.reduce((e,o)=>e+o.valorTotal,0),l=e.filter(e=>!e.bloqueado).reduce((e,o)=>e+o.valorTotal,0),s=d-l,i=a.size,c=Array.from(a.values()).filter(Boolean).length,{totalDanone:u,totalTirolez:m,totalSemCatalogo:v,nProdutosSemCatalogo:f}=computeFornecedorSplit(r);return{clientes:n,produtos:r,totalGeral:d,totalLiberado:l,totalBloqueado:s,totalDanone:u,totalTirolez:m,totalSemCatalogo:v,nProdutosSemCatalogo:f,nPedidos:i,nPedidosBloqueados:c,nClientes:n.length,nProdutos:r.length,qtdTotal:e.reduce((e,o)=>e+o.qtd,0)}}let currentVendas=null;const dropzoneVendas=document.getElementById("dropzoneVendas"),fileInputVendas=document.getElementById("fileInputVendas"),pasteAreaVendas=document.getElementById("pasteAreaVendas"),togglePasteVendas=document.getElementById("togglePasteVendas"),btnParseVendas=document.getElementById("btnParseVendas"),uploadStatusVendas=document.getElementById("uploadStatusVendas");let pendingFileVendas=null,pendingPastedTextVendas=null,pendingLinesVendas=null;function handleFileVendas(e){pendingFileVendas=null,pendingPastedTextVendas=null,pendingLinesVendas=null,btnParseVendas.disabled=!0,dropzoneVendas.querySelector(".big").textContent="Lendo "+e.name+"...",setStatus(uploadStatusVendas,"ok","Lendo arquivo..."),extractPdfLines(e).then(o=>{pendingLinesVendas=o,dropzoneVendas.querySelector(".big").textContent="Arquivo selecionado: "+e.name,btnParseVendas.disabled=!1,setStatus(uploadStatusVendas,"ok","PDF lido, pronto para processar.")}).catch(e=>{dropzoneVendas.querySelector(".big").textContent="Clique para escolher o PDF ou arraste aqui",setStatus(uploadStatusVendas,"err","Não consegui ler o PDF ("+e.message+"). Selecione o arquivo novamente (se ele estiver no OneDrive/Desktop sincronizado, abra-o uma vez fora daqui primeiro) ou cole o texto manualmente.")})}async function processVendasInput(){let e;if(pendingLinesVendas)e=pendingLinesVendas;else{if(!pendingPastedTextVendas)return void setStatus(uploadStatusVendas,"err","Selecione um PDF ou cole o texto primeiro.");e=pendingPastedTextVendas.split("\n").map(e=>e.trim()).filter(Boolean)}const{records:o,footer:t,reportDate:a}=parseVendasReport(e);0!==o.length?(currentVendas={records:o,footer:t,date:a||document.getElementById("refDate").value},renderVendasResults(),setStatus(uploadStatusVendas,"ok",o.length+" linhas de venda reconhecidas.")):setStatus(uploadStatusVendas,"err",'Nenhum item de venda reconhecido. Verifique o arquivo ou use "colar texto".')}function renderVendasResults(){let e;if(currentVendas.records)e=consolidateVendas(currentVendas.records),currentVendas.consolidated=e;else{e=currentVendas.consolidated;const o=computeFornecedorSplit(e.produtos);e={...e,...o}}document.getElementById("resultsVendas").style.display="block",document.getElementById("btnSaveVendas").disabled=!1,document.getElementById("btnPrintVendas").disabled=!1,document.getElementById("kpiRowVendas").innerHTML=`\n
Valor total do lote
${fmtBRL(e.totalGeral)}
\n
Valor liberado
${fmtBRL(e.totalLiberado)}
\n
Valor bloqueado
${fmtBRL(e.totalBloqueado)}
\n
Danone
${fmtBRL(e.totalDanone)}
\n
Tirolez
${fmtBRL(e.totalTirolez)}
\n
Pedidos (bloqueados)
${e.nPedidos} (${e.nPedidosBloqueados})
\n
Clientes atendidos
${e.nClientes}
\n
Produtos diferentes
${e.nProdutos}
\n `;const o=document.getElementById("vendasCheckHint");if(currentVendas.footer&¤tVendas.footer.valorTotal){Math.abs(currentVendas.footer.valorTotal-e.totalGeral)<.5?(o.textContent=`Conferido com o rodapé do relatório (${fmtBRL(currentVendas.footer.valorTotal)}, ${currentVendas.footer.nPedidos} pedidos, ${currentVendas.footer.nBloqueados} bloqueados) — bateu certinho.`,o.style.color="var(--success-1)"):(o.textContent=`Atenção: o total calculado (${fmtBRL(e.totalGeral)}) diverge do rodapé do relatório (${fmtBRL(currentVendas.footer.valorTotal)}). Confira o arquivo.`,o.style.color="var(--amber)")}else o.textContent="";const t=document.getElementById("semCatalogoCard"),a=e.produtos.filter(e=>!catalogLookup(e.prodCod)).sort((e,o)=>o.valorTotal-e.valorTotal);a.length?(t.style.display="block",document.getElementById("semCatalogoWrap").innerHTML=`\n
`).join(""),e.querySelectorAll(".hist-main").forEach(e=>{e.onclick=()=>loadHistoricoVendasDay(e.dataset.date)}),e.querySelectorAll(".hist-delete").forEach(e=>{e.onclick=o=>{o.stopPropagation(),deleteHistoricoVendasDay(e.dataset.date)}})}async function deleteHistoricoVendasDay(e){const o=e.split("-").reverse().join("/");if(confirm(`Excluir o relatório de vendas de ${o} do histórico? Essa ação não pode ser desfeita.`))try{await window.storage.delete("vendas:"+e,!1);let o=[];try{const e=await window.storage.get("vendas_index",!1);o=e?JSON.parse(e.value):[]}catch(e){o=[]}o=o.filter(o=>o.date!==e),await window.storage.set("vendas_index",JSON.stringify(o),!1),renderHistoricoVendas()}catch(e){alert("Não foi possível excluir: "+e.message)}}async function loadHistoricoVendasDay(e){try{const o=await window.storage.get("vendas:"+e,!1);if(!o)return;const t=JSON.parse(o.value);currentVendas={date:e,consolidated:t.cons,footer:null,records:t.records||null},document.querySelector('.tab[data-view="novo"]').click(),renderVendasResults(),setStatus(uploadStatusVendas,"ok","Exibindo relatório de vendas salvo de "+e.split("-").reverse().join("/")+". Pode reclassificar produtos ou enviar outro PDF pra somar a este dia.")}catch(e){}}function generateVendasPdfBlob(){const{jsPDF:e}=window.jspdf,o=new e({unit:"mm",format:"a4"}),t=currentVendas.consolidated,a=currentVendas.date.split("-").reverse().join("/"),n=[16,24,32],r=[90,101,112],d=[223,228,226],l=[168,98,27],s=[253,241,227],i=[244,246,245],c=12,u=186;let m=14,v=null,f=1;function p(e){m+e>279&&(g(),o.addPage(),f++,m=14,v&&v())}function g(){o.setFont("helvetica","normal"),o.setFontSize(7.5),o.setTextColor(160),o.text("Sistema em desenvolvimento · FacilPedirB2B",105,289,{align:"center"}),o.text(`Pg-${String(f).padStart(2,"0")}`,198,289,{align:"right"})}try{o.addImage(LOGO_BASE64,"PNG",c,m,9,9,void 0,"FAST")}catch(e){}o.setFont("helvetica","bold"),o.setFontSize(13.5),o.setTextColor(...n),o.text("Relatório de Vendas — Pedidos Analíticos",24,m+5),o.setFont("helvetica","normal"),o.setFontSize(8.5),o.setTextColor(...r),o.text("Lago Azul",24,m+9.5),o.setFont("helvetica","normal"),o.setFontSize(8.5),o.setTextColor(...r),o.text(`${perfil&&perfil.funcao||"Vendedor"}: ${perfil?perfil.nome:"-"}`,198,m+5,{align:"right"}),o.text(`Data: ${a}`,198,m+9.5,{align:"right"}),m+=13,o.setDrawColor(...n),o.setLineWidth(.6),o.line(c,m,198,m),o.setLineWidth(.2),m+=8;const h=[{label:"VALOR TOTAL",value:fmtBRL(t.totalGeral),color:n},{label:"LIBERADO",value:fmtBRL(t.totalLiberado),color:[20,108,67]},{label:"BLOQUEADO",value:fmtBRL(t.totalBloqueado),color:l},{label:"DANONE",value:fmtBRL(t.totalDanone),color:[11,95,165]},{label:"TIROLEZ",value:fmtBRL(t.totalTirolez),color:[198,40,40]},{label:"PEDIDOS (BLOQ.)",value:`${t.nPedidos} (${t.nPedidosBloqueados})`,color:n},{label:"CLIENTES",value:fmtNum(t.nClientes),color:n}],C=(u-2.5*(h.length-1))/h.length;function P(e,t,a,l,s,f){if(!l.length)return;function g(){o.setFillColor(...a),o.rect(c,m,u,6,"F");let e=c;o.setFont("helvetica","bold"),o.setFontSize(6.8),o.setTextColor(...r),s.forEach(t=>{const a="right"===t.align?e+t.w-2:e+2;o.text(t.label.toUpperCase(),a,m+4,{align:"right"===t.align?"right":"left"}),e+=t.w}),m+=6}p(14+6.4*Math.min(l.length,f||3)),o.setFillColor(...t),o.rect(c,m,u,8,"F"),o.setFont("helvetica","bold"),o.setFontSize(9.5),o.setTextColor(255,255,255),o.text(e,15,m+5.5),m+=8,s[s.length-1].w=u-s.slice(0,-1).reduce((e,o)=>e+o.w,0),g(),v=g,l.forEach((e,t)=>{p(6.4),t%2==1&&(o.setFillColor(...i),o.rect(c,m,u,6.4,"F"));let a=c;s.forEach(t=>{let r=e[t.key];t.slice&&(r=String(r).slice(0,t.slice));const d=t.fmt?t.fmt(r):String(r);o.setFont(t.mono?"courier":"helvetica","normal"),o.setFontSize(7.6),o.setTextColor(...n);const l="right"===t.align?a+t.w-2:a+2;o.text(d,l,m+4.3,{align:"right"===t.align?"right":"left"}),a+=t.w}),o.setDrawColor(...d),o.line(c,m+6.4,198,m+6.4),m+=6.4}),v=null,m+=6}h.forEach((e,t)=>{const a=c+t*(C+2.5);o.setFillColor(255,255,255),o.setDrawColor(...d),o.roundedRect(a,m,C,18,1.2,1.2,"FD"),o.setFont("helvetica","bold"),o.setFontSize(5.7),o.setTextColor(...r),o.text(e.label,a+2.5,m+6),o.setTextColor(...e.color),fitKpiFontSize(o,e.value,C-5,0===e.label.indexOf("PEDIDOS")?8:9.5,5.5),o.text(e.value,a+2.5,m+14)}),m+=27;P("Pedidos bloqueados",l,s,t.clientes.filter(e=>e.nPedidosBloqueados>0).sort((e,o)=>o.valorBloqueado-e.valorBloqueado),[{key:"cod",label:"Código",w:24,align:"left",mono:!0},{key:"nome",label:"Cliente",w:86,align:"left",slice:50},{key:"nPedidosBloqueados",label:"Pedidos",w:26,align:"right"},{key:"valorBloqueado",label:"Valor bloqueado",w:0,align:"right",fmt:fmtBRL}]),P("Ranking de clientes",n,i,t.clientes,[{key:"cod",label:"Código",w:22,align:"left",mono:!0},{key:"nome",label:"Cliente",w:64,align:"left",slice:38},{key:"nPedidos",label:"Pedidos",w:20,align:"right"},{key:"valorLiberado",label:"Liberado",w:30,align:"right",fmt:fmtBRL},{key:"valorBloqueado",label:"Bloqueado",w:0,align:"right",fmt:fmtBRL}]),P("Ranking de produtos",n,i,t.produtos,[{key:"prodCod",label:"Código",w:22,align:"left",mono:!0},{key:"prodDesc",label:"Descrição",w:80,align:"left",slice:46},{key:"qtd",label:"Qtd",w:20,align:"right"},{key:"valorTotal",label:"Valor total",w:0,align:"right",fmt:fmtBRL}]);const L=t.produtos.filter(e=>!catalogLookup(e.prodCod)).sort((e,o)=>o.valorTotal-e.valorTotal);return P(`Produtos fora do catálogo (${fmtBRL(t.totalSemCatalogo)})`,l,s,L,[{key:"prodCod",label:"Código",w:22,align:"left",mono:!0},{key:"prodDesc",label:"Descrição",w:80,align:"left",slice:46},{key:"qtd",label:"Qtd",w:20,align:"right"},{key:"valorTotal",label:"Valor vendido",w:0,align:"right",fmt:fmtBRL}]),g(),o}dropzoneVendas.onclick=()=>fileInputVendas.click(),dropzoneVendas.ondragover=e=>{e.preventDefault(),dropzoneVendas.classList.add("drag")},dropzoneVendas.ondragleave=()=>dropzoneVendas.classList.remove("drag"),dropzoneVendas.ondrop=e=>{e.preventDefault(),dropzoneVendas.classList.remove("drag"),e.dataTransfer.files[0]&&handleFileVendas(e.dataTransfer.files[0])},fileInputVendas.onchange=()=>{fileInputVendas.files[0]&&handleFileVendas(fileInputVendas.files[0])},togglePasteVendas.onclick=()=>{pasteAreaVendas.style.display="none"===pasteAreaVendas.style.display?"block":"none"},pasteAreaVendas.oninput=()=>{pasteAreaVendas.value.trim().length>20&&(pendingPastedTextVendas=pasteAreaVendas.value,pendingFileVendas=null,pendingLinesVendas=null,btnParseVendas.disabled=!1)},btnParseVendas.onclick=processVendasInput,document.getElementById("btnSaveVendas").onclick=async()=>{if(!currentVendas||!perfil)return;const e=document.getElementById("saveStatusVendas");try{let o=currentVendas.records||[],t=null,a=null;try{const e=await window.storage.get("vendas:"+currentVendas.date,!1);a=e?JSON.parse(e.value):null}catch(e){a=null}if(a){const n=currentVendas.date.split("-").reverse().join("/"),r=!!(a.records&&a.records.length&&o.length),d=await askMergeChoice(n,r);if("cancelar"===d)return void setStatus(e,"warn","Nada foi salvo.");if("somar"===d)if(r)o=a.records.concat(o);else{const e=currentVendas.consolidated||consolidateVendas(o);t=mergeConsolidatedVendas(a.cons,e),o=null}}t||(t=consolidateVendas(o||[]));const n={date:currentVendas.date,savedAt:(new Date).toISOString(),totalGeral:t.totalGeral,totalLiberado:t.totalLiberado,totalBloqueado:t.totalBloqueado,nPedidos:t.nPedidos,nPedidosBloqueados:t.nPedidosBloqueados,nClientes:t.nClientes,nProdutos:t.nProdutos,cons:t,records:o||void 0};await window.storage.set("vendas:"+currentVendas.date,JSON.stringify(n),!1);let r=[];try{const e=await window.storage.get("vendas_index",!1);r=e?JSON.parse(e.value):[]}catch(e){r=[]}r=r.filter(e=>e.date!==currentVendas.date),r.push({date:currentVendas.date,totalGeral:t.totalGeral,totalLiberado:t.totalLiberado,totalBloqueado:t.totalBloqueado,nPedidos:t.nPedidos,nPedidosBloqueados:t.nPedidosBloqueados,nClientes:t.nClientes}),r.sort((e,o)=>e.date.localeCompare(o.date)),await window.storage.set("vendas_index",JSON.stringify(r),!1),currentVendas.records=o||null,currentVendas.consolidated=t,renderVendasResults(),setStatus(e,"ok","Relatório de vendas de "+currentVendas.date.split("-").reverse().join("/")+" salvo no seu histórico.")}catch(o){setStatus(e,"err","Erro ao salvar: "+o.message)}},document.getElementById("btnPrintVendas").onclick=()=>{if(!currentVendas||!currentVendas.consolidated)return;const e=document.getElementById("saveStatusVendas");try{if(!window.jspdf)return void setStatus(e,"err","Biblioteca de PDF não carregou. Verifique sua conexão e recarregue a página.");const o=generateVendasPdfBlob(),t=`relatorio-vendas-${currentVendas.date}.pdf`;o.save(t),setStatus(e,"ok","PDF baixado: "+t)}catch(o){setStatus(e,"err","Não consegui gerar o PDF ("+o.message+").")}};let dashboardDateStart=null,dashboardDateEnd=null,dashboardDatesFilterWired=!1;async function loadVendasPayloads(e){return(await Promise.all(e.map(async e=>{try{const o=await window.storage.get("vendas:"+e,!1);return o?JSON.parse(o.value):null}catch(e){return null}}))).filter(Boolean)}function aggregateVendasPeriodo(e){const o=new Map,t=new Map;e.forEach(e=>{(e.cons&&e.cons.clientes||[]).forEach(e=>{o.has(e.cod)||o.set(e.cod,{cod:e.cod,nome:e.nome,valorTotal:0}),o.get(e.cod).valorTotal+=e.valorTotal}),(e.cons&&e.cons.produtos||[]).forEach(e=>{t.has(e.prodCod)||t.set(e.prodCod,{prodCod:e.prodCod,prodDesc:e.prodDesc,qtd:0,valorTotal:0});const o=t.get(e.prodCod);o.qtd+=e.qtd,o.valorTotal+=e.valorTotal})});const a=Array.from(o.values()).sort((e,o)=>o.valorTotal-e.valorTotal),n=Array.from(t.values()).sort((e,o)=>o.valorTotal-e.valorTotal),{totalDanone:r,totalTirolez:d,totalSemCatalogo:l,nProdutosSemCatalogo:s}=computeFornecedorSplit(n);return{clientesArr:a,produtosArr:n,totalDanone:r,totalTirolez:d,totalSemCatalogo:l,nProdutosSemCatalogo:s}}function wireDashboardDateFilter(){if(dashboardDatesFilterWired)return;dashboardDatesFilterWired=!0;const e=document.getElementById("dashboardDateStart"),o=document.getElementById("dashboardDateEnd");e.onchange=()=>{dashboardDateStart=e.value||null,renderDashboard()},o.onchange=()=>{dashboardDateEnd=o.value||null,renderDashboard()}}async function renderDashboard(){wireDashboardDateFilter();const e=document.getElementById("dashboardKpis"),o=document.getElementById("dashboardChartWrap"),t=document.getElementById("dashboardTableWrap"),a=document.getElementById("dashboardVendasExtraKpis"),n=document.getElementById("dashboardTopClientesWrap"),r=document.getElementById("dashboardTopProdutosWrap"),d=document.getElementById("dashboardFornecedorChartWrap");t.innerHTML='