Files
app_faturas/app/templates/relatorios.html
ewerton.almeida 950eb2a826
All checks were successful
continuous-integration/drone/push Build is passing
Criação da tela de clientes e relatórios
2025-08-11 13:14:54 -03:00

230 lines
7.5 KiB
HTML
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "index.html" %}
{% block title %}Relatórios{% endblock %}
{% block content %}
<h1>📊 Relatórios</h1>
<div style="display:flex; gap:16px; align-items:flex-end; flex-wrap:wrap; margin: 6px 0 18px;">
<div class="combo-wrap">
<label for="relatorio-cliente" style="font-size:13px;color:#374151">Selecionar Cliente:</label>
<select id="relatorio-cliente" class="combo" style="min-width:340px;">
<option value="">Todos</option>
{% for c in clientes %}
<option value="{{ c.id }}">{{ c.nome }}</option>
{% endfor %}
</select>
</div>
<div class="combo-wrap">
<label for="tipo-relatorio" style="font-size:13px;color:#374151">Tipo de relatório:</label>
<select id="tipo-relatorio" class="combo" style="min-width:240px;">
<option value="geral">1. Geral</option>
<option value="exclusao_icms">2. Exclusão do ICMS</option>
<option value="aliquota_icms">3. Alíquota ICMS (%)</option>
</select>
</div>
<div class="combo-wrap">
<label for="page-size" style="font-size:13px;color:#374151">Itens por página:</label>
<select id="page-size" class="combo" style="width:140px;">
<option>20</option>
<option>50</option>
<option>100</option>
</select>
</div>
<div>
<a id="link-excel" class="btn btn-primary" href="/export-excel">📥 Baixar (Excel)</a>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Cliente</th>
<th>UC</th>
<th>Referência</th>
<th>Nota Fiscal</th>
<th>Valor Total</th>
<th>ICMS (%)</th>
<th>ICMS (R$)</th>
<th>PIS (R$)</th>
<th>COFINS (R$)</th>
<th>Distribuidora</th>
<th>Processado em</th>
</tr>
</thead>
<tbody id="relatorios-body">
{% for f in faturas %}
<tr>
<td>{{ f.nome }}</td>
<td class="mono">{{ f.unidade_consumidora }}</td>
<td class="mono">{{ f.referencia }}</td>
<td class="mono">{{ f.nota_fiscal }}</td>
<td>R$ {{ '%.2f'|format((f.valor_total or 0.0))|replace('.', ',') }}</td>
<td>{{ '%.2f'|format((f.icms_aliq or 0.0))|replace('.', ',') }}</td>
<td>R$ {{ '%.2f'|format((f.icms_valor or 0.0))|replace('.', ',') }}</td>
<td>R$ {{ '%.2f'|format((f.pis_valor or 0.0))|replace('.', ',') }}</td>
<td>R$ {{ '%.2f'|format((f.cofins_valor or 0.0))|replace('.', ',') }}</td>
<td>{{ f.distribuidora or '-' }}</td>
<td class="muted">{{ f.data_processamento }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div id="pager" style="display:flex; align-items:center; justify-content:space-between; gap:12px; margin-top:12px;">
<div id="range" class="muted">Mostrando 00 de 0</div>
<div style="display:flex; gap:8px;">
<button id="prev" class="btn btn-primary">◀ Anterior</button>
<button id="next" class="btn btn-primary">Próxima ▶</button>
</div>
</div>
<style>
.combo {
appearance: none;
-moz-appearance: none;
-webkit-appearance: none;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 12px 44px 12px 14px;
font-size: 14px;
line-height: 1.2;
color: #111827;
box-shadow: 0 6px 20px rgba(0,0,0,.06);
transition: box-shadow .2s ease, border-color .2s ease, transform .2s ease;
}
.combo:focus { outline: none; border-color: #2563eb; box-shadow: 0 8px 28px rgba(37,99,235,.18); }
.combo-wrap { position: relative; display: inline-flex; align-items: center; gap: 8px; }
.combo-wrap:after {
content: "▾"; position: absolute; right: 12px; pointer-events: none; color:#6b7280; font-size: 12px;
}
/* tabela no estilo “clientes” */
.table {
width: 100%;
border-collapse: collapse;
background: #fff;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 12px 34px rgba(0,0,0,.06);
}
.table thead th {
background: #2563eb;
color: #ffffff;
font-size: 12px;
text-transform: uppercase;
letter-spacing: .04em;
padding: 12px 14px;
text-align: left;
}
.table tbody td {
border-top: 1px solid #eef2f7;
padding: 12px 14px;
font-size: 14px;
color: #374151;
}
.table tbody tr:nth-child(odd){ background:#fafafa; }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace; }
.muted { color:#6b7280; }
#pager .btn[disabled]{ opacity:.5; cursor:not-allowed; }
</style>
<script>
let page = 1;
let pageSize = 20;
let total = 0;
function updateExcelLink() {
const cliente = document.getElementById('relatorio-cliente').value || '';
const tipo = document.getElementById('tipo-relatorio').value || 'geral';
const params = new URLSearchParams();
params.set('tipo', tipo);
if (cliente) params.set('cliente', cliente);
document.getElementById('link-excel').setAttribute('href', `/export-excel?${params.toString()}`);
}
async function carregarTabela() {
const cliente = document.getElementById('relatorio-cliente').value || '';
const url = new URL('/api/relatorios', window.location.origin);
url.searchParams.set('page', page);
url.searchParams.set('page_size', pageSize);
if (cliente) url.searchParams.set('cliente', cliente);
const r = await fetch(url);
const data = await r.json();
total = data.total;
renderRows(data.items);
updatePager();
updateExcelLink();
}
function renderRows(items) {
const tbody = document.getElementById('relatorios-body');
if (!items.length) {
tbody.innerHTML = `<tr><td colspan="11" style="padding:14px;">Nenhum registro encontrado.</td></tr>`;
return;
}
const fmtBRL = (v) => (v || v === 0) ? Number(v).toLocaleString('pt-BR',{style:'currency',currency:'BRL'}) : '';
const fmtNum = (v) => (v || v === 0) ? Number(v).toLocaleString('pt-BR') : '';
const fmtDate = (iso) => iso ? new Date(iso).toLocaleString('pt-BR') : '';
tbody.innerHTML = items.map(f => `
<tr>
<td>${f.nome || ''}</td>
<td class="mono">${f.unidade_consumidora || ''}</td>
<td class="mono">${f.referencia || ''}</td>
<td class="mono">${f.nota_fiscal || ''}</td>
<td>${fmtBRL(f.valor_total)}</td>
<td>${fmtNum(f.icms_aliq)}</td>
<td>${fmtBRL(f.icms_valor)}</td>
<td>${fmtBRL(f.pis_valor)}</td>
<td>${fmtBRL(f.cofins_valor)}</td>
<td>${f.distribuidora || '-'}</td>
<td class="muted">${fmtDate(f.data_processamento)}</td>
</tr>
`).join('');
}
function updatePager() {
const start = total ? (page - 1) * pageSize + 1 : 0;
const end = Math.min(page * pageSize, total);
document.getElementById('range').textContent = `Mostrando ${start}${end} de ${total}`;
document.getElementById('prev').disabled = page <= 1;
document.getElementById('next').disabled = page * pageSize >= total;
}
document.getElementById('prev').addEventListener('click', () => {
if (page > 1) { page--; carregarTabela(); }
});
document.getElementById('next').addEventListener('click', () => {
if (page * pageSize < total) { page++; carregarTabela(); }
});
document.getElementById('page-size').addEventListener('change', (e) => {
pageSize = parseInt(e.target.value, 10);
page = 1;
carregarTabela();
// não precisa alterar o link aqui
});
document.getElementById('relatorio-cliente').addEventListener('change', () => {
page = 1;
carregarTabela();
updateExcelLink();
});
window.addEventListener('DOMContentLoaded', () => {
const pre = "{{ cliente_selecionado or '' }}";
if (pre) document.getElementById('relatorio-cliente').value = pre;
updateExcelLink();
carregarTabela();
});
document.getElementById('tipo-relatorio').addEventListener('change', () => {
updateExcelLink();
});
</script>
{% endblock %}