const csvUrl = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTo1OuOkL2wllvOpDo-K4N-iywod_RnQ4lG191_VbmpWn0TsppEuESFkGeZQYgFnUKM--epHEx_YRxx/pub?gid=0&single=true&output=csv";
let dadosOriginais = [];
let dadosFiltrados = [];
let chartPizza, chartBarras;
function carregar() {
Papa.parse(csvUrl, {
download: true,
header: true,
skipEmptyLines: true,
complete: function(results) {
console.log("Dados brutos recebidos:", results.data[0]); // Para debug no F12
dadosOriginais = results.data.map(item => {
// Criar uma versão do objeto com chaves em maiúsculo para evitar erro de digitação
const row = {};
for (let key in item) {
row[key.trim().toUpperCase()] = item[key];
}
if (!row["FORNECEDOR"]) return null;
const fat = parseNum(row["FAT. TRI"] || row["FAT TRI"] || row["FATURAMENTO"] || 0);
const est = parseNum(row["ESTOQUE"] || 0);
const orc = parseNum(row["META DE COMPRA"] || row["ORÇAMENTO COMPRA"] || row["META"] || 0);
const vendaMensal = fat / 3;
const diasEstoque = vendaMensal > 0 ? (est / vendaMensal) * 30 : 0;
return {
comp: (row["COMPRADOR"] || "N/D").toUpperCase().trim(),
forn: row["FORNECEDOR"].toUpperCase().trim(),
fat: fat,
est: est,
dias: diasEstoque,
orc: orc
};
}).filter(i => i !== null);
if(dadosOriginais.length === 0) {
document.getElementById("status_msg").innerText = "Aviso: Nenhuma linha com 'FORNECEDOR' encontrada.";
}
filtrar();
},
error: function(err) {
document.getElementById("status_msg").innerText = "Erro ao conectar com a planilha.";
console.error(err);
}
});
}
function parseNum(v) {
if (!v || v === "") return 0;
// Remove R$, espaços e pontos de milhar, depois troca vírgula por ponto
let n = v.toString()
.replace(/R\$/g, '')
.replace(/\s/g, '')
.replace(/\./g, '')
.replace(',', '.');
return parseFloat(n) || 0;
}
function filtrar() {
const termo = document.getElementById("busca").value.toUpperCase();
const comprador = document.getElementById("filtro_comprador").value;
dadosFiltrados = dadosOriginais.filter(i => {
const bateNome = i.forn.includes(termo);
const bateComprador = comprador === "" || i.comp === comprador;
return bateNome && bateComprador;
});
render(dadosFiltrados);
atualizarGraficos(dadosFiltrados);
}
function render(lista) {
let f=0, e=0, o=0;
let html = `
| Comprador | Fornecedor | Faturamento | Estoque | Dias Estoque | Meta de Compra |
`;
if (lista.length === 0) {
document.getElementById("tabela_area").innerHTML = 'Nenhum dado encontrado. Verifique os nomes das colunas na planilha.
';
return;
}
lista.forEach(i => {
f += i.fat; e += i.est; o += i.orc;
const classeAlerta = (i.dias > 45 || i.dias < 30) ? 'alerta-estoque' : '';
html += `
| ${i.comp} |
${i.forn} |
R$ ${i.fat.toLocaleString('pt-BR', {minimumFractionDigits:2, maximumFractionDigits:2})} |
R$ ${i.est.toLocaleString('pt-BR', {minimumFractionDigits:2, maximumFractionDigits:2})} |
${Math.round(i.dias)} dias |
R$ ${i.orc.toLocaleString('pt-BR', {minimumFractionDigits:2, maximumFractionDigits:2})} |
`;
});
document.getElementById("tabela_area").innerHTML = html + `
`;
document.getElementById("kpi_fat").innerText = "R$ " + f.toLocaleString('pt-BR', {minimumFractionDigits:2});
document.getElementById("kpi_est").innerText = "R$ " + e.toLocaleString('pt-BR', {minimumFractionDigits:2});
document.getElementById("kpi_orc").innerText = "R$ " + o.toLocaleString('pt-BR', {minimumFractionDigits:2});
document.getElementById("kpi_orc").className = "kpi " + (o < 0 ? "negativo" : "positivo");
}
function atualizarGraficos(lista) {
const resumo = lista.reduce((acc, i) => {
if(!acc[i.comp]) acc[i.comp] = { fat: 0, orc: 0 };
acc[i.comp].fat += i.fat;
acc[i.comp].orc += i.orc;
return acc;
}, {});
const labels = Object.keys(resumo);
const fatData = labels.map(l => resumo[l].fat);
const orcData = labels.map(l => resumo[l].orc);
if (chartPizza) chartPizza.destroy();
if (chartBarras) chartBarras.destroy();
const ctxP = document.getElementById('chartPizza').getContext('2d');
chartPizza = new Chart(ctxP, {
type: 'doughnut',
data: {
labels: labels,
datasets: [{ data: orcData, backgroundColor: ['#0b57d0', '#fbbc04', '#34a853', '#ea4335'] }]
},
options: { plugins: { legend: { position: 'bottom' } }, maintainAspectRatio: false }
});
const ctxB = document.getElementById('chartBarras').getContext('2d');
chartBarras = new Chart(ctxB, {
type: 'bar',
data: {
labels: labels,
datasets: [{ label: 'Faturamento', data: fatData, backgroundColor: '#0b57d0' }]
},
options: { scales: { y: { beginAtZero: true } }, maintainAspectRatio: false }
});
}
function exportarExcel() {
const ws = XLSX.utils.json_to_sheet(dadosFiltrados.map(i => ({
"COMPRADOR": i.comp, "FORNECEDOR": i.forn, "FATURAMENTO": i.fat, "ESTOQUE": i.est, "DIAS ESTOQUE": Math.round(i.dias), "META DE COMPRA": i.orc
})));
const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, ws, "Dados");
XLSX.writeFile(wb, "Painel_Compras_Lucas_Wellida.xlsx");
}
function exportarPDF() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF('l', 'mm', 'a4');
doc.text("Relatório de Planejamento - Meta de Compras", 14, 15);
doc.autoTable({
head: [["Comprador", "Fornecedor", "Faturamento", "Estoque", "Dias Est.", "Meta Compra"]],
body: dadosFiltrados.map(i => [i.comp, i.forn, i.fat.toFixed(2), i.est.toFixed(2), Math.round(i.dias), i.orc.toFixed(2)]),
startY: 20, theme: 'grid'
});
doc.save("Relatorio_Compras.pdf");
}
carregar();