portal-modumfiscal-web/src/composables/useExtratoPagamentosPortal.js
GUILHERME e4c468e61e
All checks were successful
Dev Build & Deploy Portal / build-deploy (push) Successful in 2m58s
feat(portal): extratos reais, certidão dinâmica e filtros self-scoped
Integra débitos, pagamentos e guias emitidas com API via composables e modais de extrato. Simplifica filtros do portal ao escopo do contribuinte logado. Refatora emissão pública de certidão com modelos dinâmicos e contrato idModelo. Corrige status de taxas (2=Paga, 3=Cancelada) e melhorias no proxy BFF/Keycloak.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 16:21:59 -03:00

198 lines
6.7 KiB
JavaScript

import { ref, computed } from 'vue'
import { portalService } from '@/services/portalService'
import { formatDateISO, baixarPdf } from '@/utils/formatador'
function formatDateForDisplay(date, monthOnly = false) {
if (!date) return '-'
const d = new Date(date)
if (isNaN(d.getTime())) return '-'
if (monthOnly) {
return `${String(d.getMonth() + 1).padStart(2, '0')}/${d.getFullYear()}`
}
return `${String(d.getDate()).padStart(2, '0')}/${String(d.getMonth() + 1).padStart(2, '0')}/${d.getFullYear()}`
}
function montarParametrosTributoConta(lista) {
if (!lista?.length) {
return {
codTributo: '-',
descricaoTributo: '-',
codContaTributo: '-',
descricaoContaTributo: '-',
}
}
const chaves = new Map()
for (const item of lista) {
const key = `${item.idTributo ?? ''}_${item.idContaTributo ?? ''}`
if (!chaves.has(key)) chaves.set(key, item)
}
if (chaves.size === 1) {
const t = [...chaves.values()][0]
return {
codTributo: t.idTributo != null ? String(t.idTributo) : (t.identificador ?? '-'),
descricaoTributo: t.descricaoTributo || '-',
codContaTributo: t.idContaTributo != null ? String(t.idContaTributo) : '-',
descricaoContaTributo: t.descricaoContaTributo || '-',
}
}
const tributos = [...new Set(lista.map(t => t.descricaoTributo).filter(Boolean))]
return {
codTributo: 'Diversos',
descricaoTributo: tributos.length ? tributos.join(', ') : 'Diversos tributos',
codContaTributo: '-',
descricaoContaTributo: '-',
}
}
export function useExtratoPagamentosPortal() {
const tributos = ref([])
const isLoading = ref(false)
const isLoadingPdf = ref(false)
const mensagemErro = ref('')
const filtro = ref({
debitosInicio: null,
debitosFim: null,
pagInicio: null,
pagFim: null,
})
const totais = computed(() => {
let principal = 0, multa = 0, juros = 0, desconto = 0, total = 0
for (const t of tributos.value) {
for (const p of t.pagamentos || []) {
principal += p.lancado ?? 0
multa += p.multa ?? 0
juros += p.juros ?? 0
desconto += p.desconto ?? 0
total += p.total ?? 0
}
}
return { principal, multa, juros, desconto, total }
})
async function consultar() {
isLoading.value = true
mensagemErro.value = ''
tributos.value = []
try {
const params = {
pagInicio: formatDateISO(filtro.value.pagInicio) || undefined,
pagFim: formatDateISO(filtro.value.pagFim) || undefined,
periodoIni: formatDateISO(filtro.value.debitosInicio) || undefined,
periodoFim: formatDateISO(filtro.value.debitosFim) || undefined,
}
const res = await portalService.getPagamentosExtrato(params)
const dados = res.data ?? []
tributos.value = dados.map((item, idx) => ({
idTributo: item.idTributo,
idContaTributo: item.idContaTributo,
identificador: item.identificador,
descricaoTributo: item.descricaoTributo,
descricaoContaTributo: item.descricaoContaTributo,
totalPagamentos: item.totalPagamentos ?? 0,
pagamentos: (item.pagamentos || []).map((p, i) => ({
id: `${item.idContaTributo}_${i}_${p.idContaCorrente ?? i}`,
idContaCorrente: p.idContaCorrente,
ndoc: p.numDoc,
nguia: p.numGuia,
vencimento: p.dataVencimento,
pagamento: p.dataPagamento,
refer: p.periodoRef,
lancado: p.valorPrincipal ?? 0,
multa: p.valorMulta ?? 0,
juros: p.valorJuros ?? 0,
desconto: p.valorDesconto ?? 0,
total: p.valorTotal ?? 0,
})),
}))
} catch (e) {
mensagemErro.value = e?.data?.description ?? 'Erro ao consultar pagamentos.'
} finally {
isLoading.value = false
}
}
function limparFiltros() {
filtro.value = {
debitosInicio: null,
debitosFim: null,
pagInicio: null,
pagFim: null,
}
tributos.value = []
}
async function gerarPdf() {
if (!tributos.value.length) {
mensagemErro.value = 'Consulte os pagamentos antes de gerar o PDF.'
return
}
const listaPagamentos = tributos.value.map(t => ({
idTributo: t.idTributo,
identificador: t.identificador,
descricaoTributo: t.descricaoTributo,
siglaTributo: t.siglaTributo,
idContaTributo: t.idContaTributo,
descricaoContaTributo: t.descricaoContaTributo,
totalPagamentos: t.totalPagamentos,
pagamentos: (t.pagamentos || []).map(p => ({
numDoc: p.ndoc,
numGuia: p.nguia,
dataVencimento: p.vencimento,
dataPagamento: p.pagamento,
periodoRef: p.refer,
valorPrincipal: p.lancado,
valorJuros: p.juros,
valorMulta: p.multa,
valorDesconto: p.desconto,
valorTotal: p.total,
})),
}))
const dto = {
listaPagamentos,
...montarParametrosTributoConta(tributos.value),
periodoDebitosInicio: formatDateForDisplay(filtro.value.debitosInicio, true),
periodoDebitosFim: formatDateForDisplay(filtro.value.debitosFim, true),
periodoPagamentosInicio: formatDateForDisplay(filtro.value.pagInicio),
periodoPagamentosFim: formatDateForDisplay(filtro.value.pagFim),
}
isLoadingPdf.value = true
try {
const buf = await portalService.gerarExtratoPagamentosPdf(dto)
baixarPdf(buf, 'extrato-pagamentos.pdf')
} catch (e) {
mensagemErro.value = e?.data?.description ?? 'Erro ao gerar PDF.'
} finally {
isLoadingPdf.value = false
}
}
async function baixarComprovante(pag) {
if (!pag.idContaCorrente) return null
try {
return await portalService.getComprovante(pag.idContaCorrente)
} catch {
return null
}
}
return {
tributos,
isLoading,
isLoadingPdf,
mensagemErro,
filtro,
totais,
consultar,
limparFiltros,
gerarPdf,
baixarComprovante,
}
}