fix: corrige edição de cotas - Ajusta exibição do militante e valores no modal de edição
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
<th data-sort="valor_novo">Valor Novo <i class="fas fa-sort"></i></th>
|
||||
<th data-sort="data_alteracao">Data de Alteração <i class="fas fa-sort"></i></th>
|
||||
<th data-sort="data_vencimento">Data de Vencimento <i class="fas fa-sort"></i></th>
|
||||
<th data-sort="status">Status <i class="fas fa-sort"></i></th>
|
||||
<th class="text-end">Ações</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -54,6 +55,15 @@
|
||||
<td data-valor_novo="{{ cota.valor_novo }}">R$ {{ "%.2f"|format(cota.valor_novo) }}</td>
|
||||
<td data-data_alteracao="{{ cota.data_alteracao }}">{{ cota.data_alteracao.strftime('%d/%m/%Y') }}</td>
|
||||
<td data-data_vencimento="{{ cota.data_vencimento }}">{{ cota.data_vencimento.strftime('%d/%m/%Y') }}</td>
|
||||
<td data-status="{{ cota.status }}">
|
||||
{% if cota.status == 'paga' %}
|
||||
<span class="badge bg-success">Paga</span>
|
||||
{% elif cota.status == 'atrasada' %}
|
||||
<span class="badge bg-danger">Atrasada</span>
|
||||
{% else %}
|
||||
<span class="badge bg-warning text-dark">Pendente</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group">
|
||||
<button type="button"
|
||||
@@ -66,6 +76,7 @@
|
||||
data-cota-valor-novo="{{ cota.valor_novo }}"
|
||||
data-cota-data-alteracao="{{ cota.data_alteracao.strftime('%Y-%m-%d') }}"
|
||||
data-cota-data-vencimento="{{ cota.data_vencimento.strftime('%Y-%m-%d') }}"
|
||||
data-cota-pago="{{ 'true' if cota.pago else 'false' }}"
|
||||
title="Editar">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
@@ -150,13 +161,9 @@
|
||||
<div class="modal-body">
|
||||
<form id="formEditarCota" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="editMilitante" class="form-label">Militante:</label>
|
||||
<select class="form-select" id="editMilitante" name="militante_id" required>
|
||||
<option value="">Selecione um militante</option>
|
||||
{% for militante in militantes %}
|
||||
<option value="{{ militante.id }}">{{ militante.nome }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<label for="editMilitanteNome" class="form-label">Militante:</label>
|
||||
<input type="text" class="form-control bg-light" id="editMilitanteNome" readonly>
|
||||
<input type="hidden" id="editMilitante" name="militante_id">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="editValorAntigo" class="form-label">Valor Antigo:</label>
|
||||
@@ -174,6 +181,10 @@
|
||||
<label for="editDataVencimento" class="form-label">Data de Vencimento:</label>
|
||||
<input type="date" class="form-control" id="editDataVencimento" name="data_vencimento" required>
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" id="editPago" name="pago">
|
||||
<label class="form-check-label" for="editPago">Pago</label>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@@ -211,206 +222,8 @@
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Configuração do modal de exclusão
|
||||
const deleteModal = document.getElementById('deleteModal');
|
||||
deleteModal.addEventListener('show.bs.modal', function(event) {
|
||||
const button = event.relatedTarget;
|
||||
const cotaId = button.getAttribute('data-cota-id');
|
||||
const cotaInfo = button.getAttribute('data-cota-info');
|
||||
|
||||
document.getElementById('cotaInfo').textContent = cotaInfo;
|
||||
document.getElementById('deleteForm').action = `/cotas/excluir/${cotaId}`;
|
||||
});
|
||||
|
||||
// Envio do formulário de nova cota via AJAX
|
||||
const formNovaCota = document.getElementById('formNovaCota');
|
||||
formNovaCota.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(this);
|
||||
|
||||
fetch(this.action, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.status === 'success') {
|
||||
// Fechar o modal
|
||||
bootstrap.Modal.getInstance(document.getElementById('modalNovaCota')).hide();
|
||||
|
||||
// Atualizar a lista
|
||||
location.reload();
|
||||
|
||||
// Mostrar mensagem de sucesso
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = 'alert alert-success alert-dismissible fade show';
|
||||
alertDiv.innerHTML = `
|
||||
${data.message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
document.querySelector('.container').insertBefore(alertDiv, document.querySelector('.container').firstChild);
|
||||
} else {
|
||||
// Mostrar erro
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = 'alert alert-danger alert-dismissible fade show';
|
||||
alertDiv.innerHTML = `
|
||||
${data.message}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
document.querySelector('.modal-body').insertBefore(alertDiv, formNovaCota);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro:', error);
|
||||
const alertDiv = document.createElement('div');
|
||||
alertDiv.className = 'alert alert-danger alert-dismissible fade show';
|
||||
alertDiv.innerHTML = `
|
||||
Erro ao cadastrar cota. Tente novamente.
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
`;
|
||||
document.querySelector('.modal-body').insertBefore(alertDiv, formNovaCota);
|
||||
});
|
||||
});
|
||||
|
||||
// Configuração do modal de edição
|
||||
const modalEditarCota = document.getElementById('modalEditarCota');
|
||||
modalEditarCota.addEventListener('show.bs.modal', function(event) {
|
||||
const button = event.relatedTarget;
|
||||
const cotaId = button.getAttribute('data-cota-id');
|
||||
const militanteId = button.getAttribute('data-cota-militante');
|
||||
const valorAntigo = button.getAttribute('data-cota-valor-antigo');
|
||||
const valorNovo = button.getAttribute('data-cota-valor-novo');
|
||||
const dataAlteracao = button.getAttribute('data-cota-data-alteracao');
|
||||
const dataVencimento = button.getAttribute('data-cota-data-vencimento');
|
||||
|
||||
const form = document.getElementById('formEditarCota');
|
||||
form.action = `/cotas/editar/${cotaId}`;
|
||||
|
||||
document.getElementById('editMilitante').value = militanteId;
|
||||
document.getElementById('editValorAntigo').value = valorAntigo;
|
||||
document.getElementById('editValorNovo').value = valorNovo;
|
||||
document.getElementById('editDataAlteracao').value = dataAlteracao;
|
||||
document.getElementById('editDataVencimento').value = dataVencimento;
|
||||
});
|
||||
|
||||
// Envio do formulário de edição via AJAX
|
||||
const formEditarCota = document.getElementById('formEditarCota');
|
||||
formEditarCota.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const formData = new FormData(this);
|
||||
|
||||
fetch(this.action, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest'
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.status === 'success') {
|
||||
// Fechar o modal
|
||||
bootstrap.Modal.getInstance(document.getElementById('modalEditarCota')).hide();
|
||||
|
||||
// Atualizar a lista
|
||||
location.reload();
|
||||
} else {
|
||||
alert(data.message || 'Erro ao editar cota');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro:', error);
|
||||
alert('Erro ao editar cota');
|
||||
});
|
||||
});
|
||||
|
||||
// Limpar alertas quando os modais forem fechados
|
||||
[modalEditarCota, document.getElementById('modalNovaCota')].forEach(modal => {
|
||||
modal.addEventListener('hidden.bs.modal', function () {
|
||||
const alerts = this.querySelectorAll('.alert');
|
||||
alerts.forEach(alert => alert.remove());
|
||||
});
|
||||
});
|
||||
|
||||
// Pesquisa em tempo real
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
searchInput.addEventListener('input', function() {
|
||||
const searchTerm = this.value.toLowerCase();
|
||||
const rows = document.querySelectorAll('#cotasTable tbody tr');
|
||||
|
||||
rows.forEach(row => {
|
||||
const text = row.textContent.toLowerCase();
|
||||
row.style.display = text.includes(searchTerm) ? '' : 'none';
|
||||
});
|
||||
});
|
||||
|
||||
// Ordenação
|
||||
const headers = document.querySelectorAll('#cotasTable th[data-sort]');
|
||||
headers.forEach(header => {
|
||||
header.addEventListener('click', function() {
|
||||
const column = this.getAttribute('data-sort');
|
||||
const tbody = document.querySelector('#cotasTable tbody');
|
||||
const rows = Array.from(tbody.querySelectorAll('tr'));
|
||||
const isAsc = !this.classList.contains('sort-asc');
|
||||
|
||||
// Remover classes de ordenação de todos os headers
|
||||
headers.forEach(h => {
|
||||
h.classList.remove('sort-asc', 'sort-desc');
|
||||
h.querySelector('i').className = 'fas fa-sort';
|
||||
});
|
||||
|
||||
// Adicionar classe de ordenação ao header clicado
|
||||
this.classList.add(isAsc ? 'sort-asc' : 'sort-desc');
|
||||
this.querySelector('i').className = `fas fa-sort-${isAsc ? 'up' : 'down'}`;
|
||||
|
||||
// Ordenar linhas
|
||||
rows.sort((a, b) => {
|
||||
const aVal = a.querySelector(`td[data-${column}]`).getAttribute(`data-${column}`);
|
||||
const bVal = b.querySelector(`td[data-${column}]`).getAttribute(`data-${column}`);
|
||||
return isAsc ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal);
|
||||
});
|
||||
|
||||
// Reposicionar linhas
|
||||
rows.forEach(row => tbody.appendChild(row));
|
||||
});
|
||||
});
|
||||
|
||||
// Exportar para CSV
|
||||
document.getElementById('btnExportar').addEventListener('click', function() {
|
||||
const rows = document.querySelectorAll('#cotasTable tbody tr:not([style*="display: none"])');
|
||||
const headers = ['Militante', 'Valor Antigo', 'Valor Novo', 'Data de Alteração', 'Data de Vencimento'];
|
||||
let csv = headers.join(',') + '\n';
|
||||
|
||||
rows.forEach(row => {
|
||||
const cols = row.querySelectorAll('td');
|
||||
const values = [
|
||||
cols[0].textContent,
|
||||
cols[1].textContent,
|
||||
cols[2].textContent,
|
||||
cols[3].textContent,
|
||||
cols[4].textContent
|
||||
].map(val => `"${val}"`);
|
||||
csv += values.join(',') + '\n';
|
||||
});
|
||||
|
||||
const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
|
||||
const link = document.createElement('a');
|
||||
link.href = URL.createObjectURL(blob);
|
||||
link.setAttribute('download', 'cotas.csv');
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static', filename='js/cotas.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
|
||||
Reference in New Issue
Block a user