cotas_consorcio_VF / scripts.js
victormottatz's picture
Upload 12 files
0565191 verified
Raw
History Blame Contribute Delete
21.6 kB
document.addEventListener('DOMContentLoaded', function() {
// Configurações
const API_BASE_URL = window.location.origin;
const WHATSAPP_NUMBER = '5516997311100';
// Elementos do DOM
const filterForm = document.getElementById('filter-form');
const cotasTableBody = document.getElementById('cotas-table-body');
const btnSomar = document.getElementById('btn-somar');
const btnCompartilhar = document.getElementById('btn-compartilhar');
const limparFiltrosBtn = document.getElementById('limpar-filtros');
// Estado
let cotasSelecionadas = [];
// Funções auxiliares
function formatCurrency(value) {
return parseFloat(value || 0).toLocaleString('pt-BR', {
style: 'currency',
currency: 'BRL'
});
}
function formatPercentage(value) {
return parseFloat(value || 0).toLocaleString('pt-BR', {
minimumFractionDigits: 2,
maximumFractionDigits: 2
}) + '%';
}
function showError(message) {
cotasTableBody.innerHTML = `
<tr>
<td colspan="9" class="text-center text-danger py-4">
<i class="bi bi-exclamation-triangle-fill"></i> ${message}
</td>
</tr>
`;
Swal.fire({
icon: 'error',
title: 'Erro',
text: message,
confirmButtonColor: '#3085d6'
});
}
// Carregar cotas ao iniciar
carregarCotas();
// Event Listeners
filterForm.addEventListener('submit', function(e) {
e.preventDefault();
carregarCotas();
});
limparFiltrosBtn.addEventListener('click', function() {
filterForm.reset();
carregarCotas();
});
// Adiciona os listeners para os botões de somar e compartilhar
btnSomar.addEventListener('click', function() {
somarCotasSelecionadas();
});
btnCompartilhar.addEventListener('click', function() {
compartilharCotas();
});
// Função principal para carregar cotas
async function carregarCotas() {
try {
// Mostrar loading
cotasTableBody.innerHTML = `
<tr>
<td colspan="9" class="text-center py-4">
<div class="spinner-border text-primary" role="status">
<span class="visually-hidden">Carregando...</span>
</div>
<p class="mt-2">Buscando cotas...</p>
</td>
</tr>
`;
// Preparar dados do formulário
const formData = new FormData(filterForm);
const filters = {};
// Ajuste: envia os nomes esperados pelo backend
for (const [key, value] of formData.entries()) {
if (value) {
if (key === 'credito') filters['valor_credito'] = value;
else if (key === 'entrada') filters['valor_entrada'] = value;
else if (key === 'parcela') filters['valor_parcela'] = value;
else filters[key] = value;
}
}
// Fazer requisição
const response = await fetch(`${API_BASE_URL}/api/cotas`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(filters)
});
// Verificar resposta
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || `Erro na requisição: ${response.status}`);
}
const data = await response.json();
// Renderizar tabela
renderizarTabela(data);
} catch (error) {
showError(error.message);
}
}
// Função para renderizar a tabela
function renderizarTabela(cotas) {
cotasTableBody.innerHTML = '';
cotasSelecionadas = [];
if (!Array.isArray(cotas)) {
throw new Error('Formato de dados inválido');
}
if (cotas.length === 0) {
cotasTableBody.innerHTML = `
<tr>
<td colspan="9" class="text-center py-4">Nenhuma cota encontrada</td>
</tr>
`;
return;
}
cotas.forEach(cota => {
const row = document.createElement('tr');
row.dataset.id = cota.id;
// Determinar categoria e disponibilidade
const categoria = cota.categoria === 'veiculo' ? 'Auto' : 'Imóvel';
const disponivel = cota.reserva !== 'reservado';
const comissao = (parseFloat(cota.valor_credito) * 0.085) + parseFloat(cota.entrada);
row.innerHTML = `
<td class="select-area">
<input type="checkbox" class="cota-select" id="cota-${cota.id}">
<label for="cota-${cota.id}"><i class="bi bi-check-lg"></i></label>
</td>
<td class="icon-cat">${categoria}</td>
<td>${cota.codigo || 'N/A'}</td>
<td>${formatCurrency(cota.valor_credito)}</td>
<td>${formatCurrency(comissao)}</td>
<td>${cota.parcelas}x ${formatCurrency(cota.valor_parcela)}</td>
<td class="adm-logo">${cota.admin || 'N/A'}</td>
<td class="view-cota">
<span class="ver-cota" data-id="${cota.id}">
<i class="bi bi-eye"></i>
</span>
</td>
<td>
${disponivel ? `
<a href="https://wa.me/${WHATSAPP_NUMBER}?text=Interesse na cota ${cota.codigo} - ${categoria} - Crédito: ${formatCurrency(cota.valor_credito)}"
class="btn-reserva btn-reservar" target="_blank">
<i class="bi bi-whatsapp"></i> Negociar
</a>
` : `
<span class="btn-reserva btn-reservado">Reservado</span>
`}
</td>
`;
cotasTableBody.appendChild(row);
});
// Adicionar eventos após renderização
adicionarEventosTabela();
atualizarBotoes();
}
function adicionarEventosTabela() {
// Eventos para seleção de cotas
document.querySelectorAll('.cota-select').forEach(checkbox => {
checkbox.addEventListener('change', function() {
const row = this.closest('tr');
const cotaId = row.dataset.id;
if (this.checked) {
row.classList.add('selected');
if (!cotasSelecionadas.includes(cotaId)) {
cotasSelecionadas.push(cotaId);
}
} else {
row.classList.remove('selected');
cotasSelecionadas = cotasSelecionadas.filter(id => id !== cotaId);
}
atualizarBotoes();
});
});
// Eventos para visualização de detalhes
document.querySelectorAll('.ver-cota').forEach(btn => {
btn.addEventListener('click', function() {
const cotaId = this.dataset.id;
mostrarDetalhesCota(cotaId);
});
});
}
function atualizarBotoes() {
btnSomar.disabled = cotasSelecionadas.length === 0;
btnCompartilhar.disabled = cotasSelecionadas.length === 0;
}
async function mostrarDetalhesCota(cotaId) {
try {
const response = await fetch(`${API_BASE_URL}/api/detalhes_cota/${cotaId}`);
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || `Erro na requisição: ${response.status}`);
}
const data = await response.json();
if (data.error) {
throw new Error(data.error);
}
const cota = data.cota;
const categoria = cota.categoria === 'veiculo' ? 'Auto' : 'Imóvel';
const reserva = cota.reserva === 'reservado' ? 'Reservado' : 'Disponível';
const modalBody = document.getElementById('detalhes-cota-body');
modalBody.innerHTML = `
<div class="body-modal">
<p><strong>Administradora:</strong> ${cota.admin || 'Não informado'}</p>
<p><strong>Código:</strong> ${cota.codigo}</p>
<p><strong>Nome:</strong> ${categoria}</p>
<p><strong>Crédito:</strong> ${formatCurrency(cota.valor_credito)}</p>
<p><strong>Entrada:</strong> ${formatCurrency(data.comissao)} (${formatPercentage(data.entradaporcem)})</p>
<p><strong>Prazo:</strong> ${cota.parcelas}x</p>
<p><strong>Parcelas:</strong> ${formatCurrency(cota.valor_parcela)}</p>
<p><strong>Data Próx. Parcela:</strong> ${data.data_prox_parcela}</p>
<p><strong>Saldo Devedor:</strong> ${formatCurrency(cota.saldo)}</p>
${categoria === 'Imóvel' ? `
<p><strong>Fundo Comum:</strong> À consultar</p>
<p><strong>Avaliação do Imóvel:</strong> À consultar</p>
` : ''}
<p><strong>Transferência:</strong> À consultar</p>
<p><strong>Seguro de Vida:</strong> À consultar</p>
<br>
<p><strong>Situação:</strong> ${reserva}</p>
<br>
<p><strong>-- Condições de contratação --</strong><p>
<p><small>Crédito Real: ${formatCurrency(data.credito_real)}</small></p>
<p><small>Valor Final: ${formatCurrency(data.valor_final)}</small></p>
<p><small>Valor da Taxa: ${formatCurrency(data.taxa)}</small></p>
<p><small>Porcentagem da Taxa: ${formatPercentage(data.taxaporcem)}</small></p>
<p><small>Juros ao Mês: ${formatPercentage(data.JMensal)}</small></p>
<p><small>Juros ao Ano: ${formatPercentage(data.JAnual)}</small></p>
</div>
<div class="footer-modal">
<div class="d-flex align-items-center justify-content-between">
<a href="https://api.whatsapp.com/send?text=Lista%20de%20Cartas%20Contempladas%3A%0ACR%C3%89DITO%3A%20${formatCurrency(cota.valor_credito)}%0AENTRADA%3A%20${formatCurrency(cota.entrada)}%0APARCELAS%3A%20${cota.parcelas}x%20${formatCurrency(cota.valor_parcela)}%0A${cota.admin || 'Não informado'}%0ATAXA%20DE%20TRANSFER%C3%8ANCIA%3A%20À%20consultar%0ASEGURO%20DE%20VIDA%3A%20À%20consultar"
target="_blank" class="compartilhar-cota d-flex align-items-center" type="button">
<i class="bi bi-share-fill"></i> Compartilhar
</a>
${reserva === 'Disponível' ? `
<a href="https://wa.me/${WHATSAPP_NUMBER}?text=Interesse na cota ${cota.codigo} - ${categoria} - Crédito: ${formatCurrency(cota.valor_credito)}"
target="_blank" class="negociar-cota d-flex align-items-center" type="button">
<i class="bi bi-whatsapp"></i> Negociar
</a>
` : ''}
</div>
</div>
`;
// Abrir modal
const detalhesModal = new bootstrap.Modal(document.getElementById('detalhesModal'));
detalhesModal.show();
} catch (error) {
showError('Erro ao carregar detalhes da cota');
}
}
async function somarCotasSelecionadas() {
if (cotasSelecionadas.length === 0) return;
try {
const response = await fetch(`${API_BASE_URL}/api/somar_cotas`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ cotas_ids: cotasSelecionadas })
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.error || `Erro na requisição: ${response.status}`);
}
const data = await response.json();
if (data.error) {
throw new Error(data.error);
}
// Preencher modal de soma
const modalBody = document.getElementById('somar-cotas-body');
modalBody.innerHTML = `
<div class="soma-container">
<div class="soma-header">
<h5>Resumo da Soma das Cotas</h5>
<p class="text-muted">${data.categoria} - ${data.admin}</p>
</div>
<div class="soma-valores">
<div class="soma-item">
<span>Crédito Total:</span>
<strong>${formatCurrency(data.total_credito)}</strong>
</div>
<div class="soma-item">
<span>Entrada Total:</span>
<strong>${formatCurrency(data.total_comissao)} (${formatPercentage(data.total_entradaporcem)})</strong>
</div>
<div class="soma-item">
<span>Parcelas Totais:</span>
<strong>${data.total_parcelas}x</strong>
</div>
<div class="soma-item">
<span>Valor Médio da Parcela:</span>
<strong>${formatCurrency(data.media_valor_parcela)}</strong>
</div>
<div class="soma-item">
<span>Saldo Devedor Total:</span>
<strong>${formatCurrency(data.total_saldo)}</strong>
</div>
<div class="soma-item">
<span>Dia do Vencimento:</span>
<strong>${data.menor_vencimento}</strong>
</div>
</div>
<div class="soma-detalhes">
<p class="open-cartas d-flex align-items-center justify-content-between">
Condições de Contratação <i class="bi bi-chevron-down"></i>
</p>
<div class="detalhes-cotas" style="display:none;">
<div class="detalhe-cota">
<div class="d-flex align-items-center justify-content-between tp2">
<small>Crédito Real: ${formatCurrency(data.credito_real)}</small>
</div>
<div class="d-flex align-items-center justify-content-between tp2">
<small>Valor Final: ${formatCurrency(data.valor_final)}</small>
</div>
<div class="d-flex align-items-center justify-content-between tp2">
<small>Valor da Taxa: ${formatCurrency(data.taxa)}</small>
</div>
<div class="d-flex align-items-center justify-content-between tp2">
<small>Porcentagem da Taxa: ${formatPercentage(data.taxaporcem)}</small>
</div>
<div class="d-flex align-items-center justify-content-between tp2">
<small>Juros ao mês: ${formatPercentage(data.JMensal)}</small>
</div>
<div class="d-flex align-items-center justify-content-between tp2">
<small>Juros ao ano: ${formatPercentage(data.JAnual)}</small>
</div>
</div>
</div>
<p class="open-cartas d-flex align-items-center justify-content-between mt-3">
Cartas Selecionadas (${data.detalhes.length}) <i class="bi bi-chevron-down"></i>
</p>
<div class="detalhes-cotas" style="display:none;">
${data.detalhes.map(detalhe => `
<div class="detalhe-cota mb-2">
<div class="d-flex align-items-center justify-content-between tp1">
<small>#${detalhe.codigo}</small>
<span>${formatCurrency(detalhe.credito)}</span>
</div>
<div class="d-flex align-items-center justify-content-between tp2">
<small><strong>${detalhe.categoria}</strong></small>
<small>${detalhe.parcelas}X de ${formatCurrency(detalhe.valor_parcela)}</small>
</div>
<div class="d-flex align-items-center justify-content-between tp2">
<small>Entrada: ${formatCurrency(detalhe.entrada)}</small>
<small>Saldo: ${formatCurrency(detalhe.saldo)}</small>
</div>
</div>
`).join('')}
</div>
</div>
<div class="soma-actions mt-3">
<button class="btn btn-primary" onclick="navigator.clipboard.writeText('${data.link_share}'); Swal.fire('Sucesso', 'Texto copiado para a área de transferência!', 'success')">
<i class="bi bi-clipboard"></i> Copiar Resumo
</button>
</div>
</div>
`;
// Abrir modal
const somarModal = new bootstrap.Modal(document.getElementById('somarModal'));
somarModal.show();
// Eventos para abrir/fechar seções
document.querySelectorAll('.open-cartas').forEach(item => {
item.addEventListener('click', function() {
const detalhes = this.nextElementSibling;
const icon = this.querySelector('i');
if (detalhes.style.display === 'none') {
detalhes.style.display = 'block';
icon.classList.remove('bi-chevron-down');
icon.classList.add('bi-chevron-up');
} else {
detalhes.style.display = 'none';
icon.classList.remove('bi-chevron-up');
icon.classList.add('bi-chevron-down');
}
});
});
} catch (error) {
showError('Erro ao somar as cotas selecionadas');
}
}
function compartilharCotas() {
if (cotasSelecionadas.length === 0) return;
// Montar link do WhatsApp
let texto = "Lista de Cartas Contempladas:\n";
// Obter detalhes das cotas selecionadas
cotasSelecionadas.forEach(id => {
const row = document.querySelector(`tr[data-id="${id}"]`);
if (row) {
const codigo = row.querySelector('td:nth-child(3)').textContent;
const categoria = row.querySelector('td:nth-child(2)').textContent;
const credito = row.querySelector('td:nth-child(4)').textContent;
texto += `\n${categoria} - Código: ${codigo} - Crédito: ${credito}`;
}
});
const whatsappUrl = `https://wa.me/${WHATSAPP_NUMBER}?text=${encodeURIComponent(texto)}`;
window.open(whatsappUrl, '_blank');
}
});