fix: corrige validação e salvamento do formulário de edição de militante - Corrige validação do email, ajusta conversão de datas, corrige CSRF token e melhora feedback visual
This commit is contained in:
164
app.py
164
app.py
@@ -940,146 +940,112 @@ def create_app():
|
||||
db.close()
|
||||
|
||||
# Rota para editar militante
|
||||
@app.route("/militantes/editar/<int:militante_id>", methods=["POST"])
|
||||
@require_login
|
||||
@app.route('/militantes/editar/<int:militante_id>', methods=['POST'])
|
||||
@login_required
|
||||
@require_permission('gerenciar_militantes')
|
||||
def editar_militante(militante_id):
|
||||
"""Edita um militante existente"""
|
||||
# Verificar token CSRF manualmente
|
||||
csrf_token = request.headers.get('X-CSRFToken') or request.form.get('csrf_token')
|
||||
if not csrf_token or not csrf.validate_csrf(csrf_token):
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Token CSRF inválido'
|
||||
}), 400
|
||||
|
||||
db = get_db_connection()
|
||||
try:
|
||||
militante = db.query(Militante).get(militante_id)
|
||||
# Verificar se o militante existe
|
||||
militante = db_session.query(Militante).get(militante_id)
|
||||
if not militante:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Militante não encontrado'
|
||||
}), 404
|
||||
|
||||
# Dados Básicos
|
||||
militante.nome = request.form.get('nome')
|
||||
militante.cpf = request.form.get('cpf')
|
||||
militante.titulo_eleitoral = request.form.get('titulo_eleitoral')
|
||||
militante.data_nascimento = datetime.strptime(request.form.get('data_nascimento'), '%Y-%m-%d') if request.form.get('data_nascimento') else None
|
||||
militante.data_entrada_oci = datetime.strptime(request.form.get('data_entrada_oci'), '%Y-%m-%d') if request.form.get('data_entrada_oci') else None
|
||||
militante.data_efetivacao_oci = datetime.strptime(request.form.get('data_efetivacao_oci'), '%Y-%m-%d') if request.form.get('data_efetivacao_oci') else None
|
||||
|
||||
# Contato
|
||||
militante.telefone1 = request.form.get('telefone1')
|
||||
militante.telefone2 = request.form.get('telefone2')
|
||||
|
||||
# Email (atualizar o principal)
|
||||
# Obter dados do formulário
|
||||
nome = request.form.get('nome')
|
||||
cpf = request.form.get('cpf')
|
||||
titulo_eleitoral = request.form.get('titulo_eleitoral')
|
||||
data_nascimento = request.form.get('data_nascimento')
|
||||
data_entrada_oci = request.form.get('data_entrada_oci')
|
||||
data_efetivacao_oci = request.form.get('data_efetivacao_oci')
|
||||
telefone1 = request.form.get('telefone1')
|
||||
telefone2 = request.form.get('telefone2')
|
||||
email = request.form.get('email')
|
||||
|
||||
# Converter datas para objetos date
|
||||
data_nascimento = datetime.strptime(data_nascimento, '%Y-%m-%d').date() if data_nascimento else None
|
||||
data_entrada_oci = datetime.strptime(data_entrada_oci, '%Y-%m-%d').date() if data_entrada_oci else None
|
||||
data_efetivacao_oci = datetime.strptime(data_efetivacao_oci, '%Y-%m-%d').date() if data_efetivacao_oci else None
|
||||
|
||||
# Atualizar dados básicos
|
||||
militante.nome = nome
|
||||
militante.cpf = cpf
|
||||
militante.titulo_eleitoral = titulo_eleitoral
|
||||
militante.data_nascimento = data_nascimento
|
||||
militante.data_entrada_oci = data_entrada_oci
|
||||
militante.data_efetivacao_oci = data_efetivacao_oci
|
||||
militante.telefone1 = telefone1
|
||||
militante.telefone2 = telefone2
|
||||
|
||||
# Atualizar email
|
||||
if email:
|
||||
if militante.emails:
|
||||
militante.emails[0].endereco_email = email
|
||||
# Verificar se já existe um email para este militante
|
||||
email_existente = db_session.query(EmailMilitante).filter_by(militante_id=militante_id).first()
|
||||
if email_existente:
|
||||
email_existente.endereco_email = email
|
||||
else:
|
||||
novo_email = EmailMilitante(
|
||||
endereco_email=email,
|
||||
militante_id=militante.id
|
||||
)
|
||||
db.add(novo_email)
|
||||
militante.emails.append(novo_email)
|
||||
novo_email = EmailMilitante(endereco_email=email, militante_id=militante_id)
|
||||
db_session.add(novo_email)
|
||||
|
||||
# Atualizar endereço
|
||||
endereco = militante.endereco or Endereco(militante_id=militante_id)
|
||||
endereco.cep = request.form.get('cep')
|
||||
endereco.estado = request.form.get('estado')
|
||||
endereco.cidade = request.form.get('cidade')
|
||||
endereco.bairro = request.form.get('bairro')
|
||||
endereco.rua = request.form.get('rua')
|
||||
endereco.numero = request.form.get('numero')
|
||||
endereco.complemento = request.form.get('complemento')
|
||||
|
||||
# Endereço
|
||||
if not militante.endereco:
|
||||
militante.endereco = Endereco()
|
||||
db.add(militante.endereco)
|
||||
militante.endereco = endereco
|
||||
db_session.add(endereco)
|
||||
|
||||
militante.endereco.cep = request.form.get('cep')
|
||||
militante.endereco.estado = request.form.get('estado')
|
||||
militante.endereco.cidade = request.form.get('cidade')
|
||||
militante.endereco.bairro = request.form.get('bairro')
|
||||
militante.endereco.rua = request.form.get('rua')
|
||||
militante.endereco.numero = request.form.get('numero')
|
||||
militante.endereco.complemento = request.form.get('complemento')
|
||||
|
||||
# Profissional
|
||||
militante.profissao = request.form.get('profissao')
|
||||
militante.regime_trabalho = request.form.get('regime_trabalho')
|
||||
# Atualizar dados profissionais
|
||||
militante.empresa = request.form.get('empresa')
|
||||
militante.contratante = request.form.get('contratante')
|
||||
|
||||
# Acadêmico
|
||||
militante.instituicao_ensino = request.form.get('instituicao_ensino')
|
||||
militante.tipo_instituicao = request.form.get('tipo_instituicao')
|
||||
|
||||
# Sindical
|
||||
# Atualizar dados sindicais
|
||||
militante.sindicato = request.form.get('sindicato')
|
||||
militante.cargo_sindical = request.form.get('cargo_sindical')
|
||||
militante.central_sindical = request.form.get('central_sindical')
|
||||
militante.dirigente_sindical = request.form.get('dirigente_sindical') == 'on'
|
||||
militante.dirigente_sindical = request.form.get('dirigente_sindical') == 'true'
|
||||
|
||||
# Organização
|
||||
estado_str = request.form.get('estado', 'ATIVO').lower()
|
||||
print(f"Estado recebido: {estado_str}")
|
||||
|
||||
# Converter o estado para o enum
|
||||
try:
|
||||
militante.estado = EstadoMilitante[estado_str.upper()]
|
||||
print(f"Estado convertido: {militante.estado}")
|
||||
except (KeyError, ValueError) as e:
|
||||
print(f"Erro ao converter estado: {str(e)}")
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Estado inválido: {estado_str}'
|
||||
}), 400
|
||||
|
||||
# Tratar celula_id corretamente
|
||||
celula_id = request.form.get('celula_id')
|
||||
if celula_id:
|
||||
try:
|
||||
militante.celula_id = int(celula_id)
|
||||
except (ValueError, TypeError):
|
||||
militante.celula_id = None
|
||||
else:
|
||||
militante.celula_id = None
|
||||
|
||||
# Tratar responsabilidades corretamente
|
||||
# Atualizar responsabilidades
|
||||
try:
|
||||
responsabilidades_valor = request.form.get('responsabilidades_valor')
|
||||
if responsabilidades_valor:
|
||||
militante.responsabilidades = int(responsabilidades_valor)
|
||||
print(f"Responsabilidades atualizadas: {militante.responsabilidades}")
|
||||
print(f"Responsabilidades atualizadas para: {militante.responsabilidades}")
|
||||
else:
|
||||
militante.responsabilidades = 0
|
||||
print("Responsabilidades zeradas")
|
||||
print("Nenhuma responsabilidade definida")
|
||||
except (ValueError, TypeError) as e:
|
||||
print(f"Erro ao processar responsabilidades: {str(e)}")
|
||||
print(f"Erro ao processar responsabilidades: {e}")
|
||||
militante.responsabilidades = 0
|
||||
|
||||
# Se o estado mudou para DESLIGADO, registrar data e motivo
|
||||
if militante.estado == EstadoMilitante.DESLIGADO:
|
||||
militante.data_desligamento = datetime.now()
|
||||
militante.motivo_desligamento = request.form.get('motivo_desligamento')
|
||||
|
||||
db.commit()
|
||||
print("Alterações salvas com sucesso")
|
||||
|
||||
# Retornar as responsabilidades atualizadas
|
||||
responsabilidades = militante.get_responsabilidades()
|
||||
# Salvar alterações
|
||||
db_session.commit()
|
||||
print("Alterações salvas com sucesso!")
|
||||
|
||||
# Retornar resposta
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'message': f'Militante {militante.nome} atualizado com sucesso!',
|
||||
'responsabilidades': responsabilidades,
|
||||
'responsabilidades_valor': militante.responsabilidades
|
||||
'message': 'Militante atualizado com sucesso!',
|
||||
'responsabilidades': militante.get_responsabilidades()
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
print(f"Erro ao atualizar militante: {str(e)}")
|
||||
db.rollback()
|
||||
db_session.rollback()
|
||||
print(f"Erro ao salvar alterações: {e}")
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Erro ao atualizar militante: {str(e)}'
|
||||
'message': str(e)
|
||||
}), 500
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
# Rota para criar um novo usuário
|
||||
@app.route("/usuarios/novo", methods=["GET", "POST"])
|
||||
|
||||
@@ -317,7 +317,7 @@ async function carregarDadosMilitante(militanteId) {
|
||||
const emailElement = document.getElementById('edit_email');
|
||||
if (emailElement) {
|
||||
if (data.emails && data.emails.length > 0) {
|
||||
emailElement.value = data.emails[0].endereco_email;
|
||||
emailElement.value = data.emails[0]; // O email já vem como string
|
||||
} else {
|
||||
emailElement.value = '';
|
||||
}
|
||||
@@ -568,7 +568,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const emailElement = document.getElementById('edit_email');
|
||||
if (emailElement) {
|
||||
if (data.emails && data.emails.length > 0) {
|
||||
emailElement.value = data.emails[0].endereco_email;
|
||||
emailElement.value = data.emails[0]; // O email já vem como string
|
||||
} else {
|
||||
emailElement.value = '';
|
||||
}
|
||||
@@ -668,9 +668,40 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
event.preventDefault();
|
||||
console.log('Formulário de edição enviado');
|
||||
|
||||
// Validar todos os campos antes do envio
|
||||
const form = this;
|
||||
form.classList.add('was-validated');
|
||||
|
||||
// Verificar se o formulário é válido
|
||||
if (!form.checkValidity()) {
|
||||
event.stopPropagation();
|
||||
|
||||
// Encontrar o primeiro campo inválido
|
||||
const invalidField = form.querySelector(':invalid');
|
||||
if (invalidField) {
|
||||
// Encontrar a aba que contém o campo inválido
|
||||
const tabPane = invalidField.closest('.tab-pane');
|
||||
if (tabPane) {
|
||||
// Ativar a aba
|
||||
const tabId = tabPane.id;
|
||||
const tab = document.querySelector(`button[data-bs-target="#${tabId}"]`);
|
||||
if (tab) {
|
||||
const bsTab = new bootstrap.Tab(tab);
|
||||
bsTab.show();
|
||||
|
||||
// Focar no campo inválido após a aba ser exibida
|
||||
setTimeout(() => {
|
||||
invalidField.focus();
|
||||
}, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Se chegou aqui, o formulário é válido
|
||||
// Obter ID do militante
|
||||
const militanteId = document.getElementById('edit_militante_id').value;
|
||||
console.log('ID do militante:', militanteId);
|
||||
|
||||
if (!militanteId) {
|
||||
console.error('ID do militante não encontrado');
|
||||
@@ -679,24 +710,21 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
// Criar FormData com todos os campos
|
||||
const formData = new FormData(this);
|
||||
const formData = new FormData(form);
|
||||
|
||||
// Garantir que o valor das responsabilidades seja enviado
|
||||
const responsabilidadesValue = document.getElementById('responsabilidades_values').value;
|
||||
formData.set('responsabilidades_valor', responsabilidadesValue);
|
||||
console.log('Valor das responsabilidades sendo enviado:', responsabilidadesValue);
|
||||
|
||||
try {
|
||||
// Construir URL
|
||||
const url = `/militantes/editar/${militanteId}`;
|
||||
console.log('URL da requisição:', url);
|
||||
const csrfToken = document.querySelector('input[name="csrf_token"]').value;
|
||||
|
||||
// Enviar requisição
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRF-Token': getCsrfToken()
|
||||
'X-CSRF-Token': csrfToken
|
||||
},
|
||||
body: formData
|
||||
});
|
||||
@@ -706,17 +734,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log('Resposta do servidor:', data);
|
||||
|
||||
if (data.status === 'success') {
|
||||
// Fechar modal
|
||||
const modal = bootstrap.Modal.getInstance(document.getElementById('modalEditarMilitante'));
|
||||
modal.hide();
|
||||
|
||||
// Mostrar mensagem de sucesso
|
||||
mostrarAlerta('Militante atualizado com sucesso!', 'success');
|
||||
|
||||
// Recarregar página após um pequeno delay para a mensagem ser vista
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 1000);
|
||||
|
||||
@@ -44,10 +44,16 @@
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_nome" class="form-label">Nome</label>
|
||||
<input type="text" class="form-control" id="edit_nome" name="nome" required>
|
||||
<div class="invalid-feedback">
|
||||
Por favor, insira o nome do militante.
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 mb-3">
|
||||
<label for="edit_cpf" class="form-label">CPF</label>
|
||||
<input type="text" class="form-control" id="edit_cpf" name="cpf" required>
|
||||
<div class="invalid-feedback">
|
||||
Por favor, insira um CPF válido.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
@@ -91,7 +97,14 @@
|
||||
<!-- Email Principal -->
|
||||
<div class="mb-3">
|
||||
<label for="edit_email" class="form-label">Email Principal</label>
|
||||
<input type="email" class="form-control" id="edit_email" name="email" required>
|
||||
<input type="email"
|
||||
class="form-control"
|
||||
id="edit_email"
|
||||
name="email"
|
||||
required>
|
||||
<div class="invalid-feedback">
|
||||
Por favor, insira um email válido.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Endereço -->
|
||||
|
||||
Reference in New Issue
Block a user