refactor: Implementa arquitetura MVC limpa
- Separa modelos em entidades individuais - Cria camada de serviços para acesso a dados - Implementa controladores para lógica de negócio - Organiza rotas em blueprints por funcionalidade - Adiciona documentação de arquitetura no README - Cria script para preparação da estrutura 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
270
controllers/militante_controller.py
Normal file
270
controllers/militante_controller.py
Normal file
@@ -0,0 +1,270 @@
|
||||
from flask import request, jsonify, flash
|
||||
from datetime import datetime
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
||||
from services.militante_service import MilitanteService
|
||||
from models.entities.militante import Militante, EstadoMilitante
|
||||
from models.entities.endereco import Endereco
|
||||
from models.entities.email_militante import EmailMilitante
|
||||
from utils.date_utils import validar_data, converter_data, validar_sequencia_datas, calcular_idade
|
||||
|
||||
class MilitanteController:
|
||||
"""Controlador para operações com militantes"""
|
||||
|
||||
@staticmethod
|
||||
def listar_militantes():
|
||||
"""Lista todos os militantes"""
|
||||
return MilitanteService.listar_militantes()
|
||||
|
||||
@staticmethod
|
||||
def buscar_militante(militante_id):
|
||||
"""Busca um militante pelo ID"""
|
||||
militante = MilitanteService.buscar_militante(militante_id)
|
||||
if not militante:
|
||||
raise NotFound(f"Militante com ID {militante_id} não encontrado")
|
||||
return militante
|
||||
|
||||
@staticmethod
|
||||
def criar_militante(form_data):
|
||||
"""Cria um novo militante"""
|
||||
# Validar CPF
|
||||
from functions.validations import validar_cpf
|
||||
cpf = form_data.get('cpf')
|
||||
if not validar_cpf(cpf):
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'CPF inválido'
|
||||
}), 400
|
||||
|
||||
# Verificar se já existe militante com este CPF
|
||||
if MilitanteService.buscar_por_cpf(cpf):
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'CPF já cadastrado'
|
||||
}), 400
|
||||
|
||||
try:
|
||||
# Criar endereço
|
||||
endereco = Endereco(
|
||||
cep=form_data.get('cep'),
|
||||
estado=form_data.get('estado'),
|
||||
cidade=form_data.get('cidade'),
|
||||
bairro=form_data.get('bairro'),
|
||||
rua=form_data.get('logradouro'),
|
||||
numero=form_data.get('numero'),
|
||||
complemento=form_data.get('complemento')
|
||||
)
|
||||
|
||||
# Salvar endereço para obter ID
|
||||
endereco_id = MilitanteService.salvar_endereco(endereco)
|
||||
|
||||
# Processar datas
|
||||
data_nascimento = datetime.strptime(form_data.get('data_nascimento'), '%Y-%m-%d') if form_data.get('data_nascimento') else None
|
||||
data_entrada_oci = datetime.strptime(form_data.get('data_entrada_oci'), '%Y-%m-%d') if form_data.get('data_entrada_oci') else None
|
||||
data_efetivacao_oci = datetime.strptime(form_data.get('data_efetivacao_oci'), '%Y-%m-%d') if form_data.get('data_efetivacao_oci') else None
|
||||
|
||||
# Criar militante
|
||||
militante = Militante(
|
||||
# Dados Básicos
|
||||
nome=form_data.get('nome'),
|
||||
cpf=cpf,
|
||||
titulo_eleitoral=form_data.get('titulo_eleitoral'),
|
||||
data_nascimento=data_nascimento,
|
||||
data_entrada_oci=data_entrada_oci,
|
||||
data_efetivacao_oci=data_efetivacao_oci,
|
||||
|
||||
# Contato
|
||||
telefone1=form_data.get('telefone1'),
|
||||
telefone2=form_data.get('telefone2'),
|
||||
endereco_id=endereco_id,
|
||||
|
||||
# Profissional
|
||||
profissao=form_data.get('profissao'),
|
||||
regime_trabalho=form_data.get('regime_trabalho'),
|
||||
empresa=form_data.get('empresa'),
|
||||
contratante=form_data.get('contratante'),
|
||||
|
||||
# Acadêmico
|
||||
instituicao_ensino=form_data.get('instituicao_ensino'),
|
||||
tipo_instituicao=form_data.get('tipo_instituicao'),
|
||||
|
||||
# Sindical
|
||||
sindicato=form_data.get('sindicato'),
|
||||
cargo_sindical=form_data.get('cargo_sindical'),
|
||||
central_sindical=form_data.get('central_sindical'),
|
||||
dirigente_sindical=form_data.get('dirigente_sindical') == 'on',
|
||||
|
||||
# Organização
|
||||
estado=EstadoMilitante(form_data.get('estado', 'ATIVO')),
|
||||
celula_id=form_data.get('celula_id', type=int),
|
||||
responsabilidades=form_data.get('responsabilidades', type=int, default=0),
|
||||
|
||||
# Por padrão, todo novo militante é aspirante
|
||||
aspirante=True,
|
||||
data_inicio_aspirante=datetime.now()
|
||||
)
|
||||
|
||||
# Salvar militante para obter ID
|
||||
militante_id = MilitanteService.salvar_militante(militante)
|
||||
|
||||
# Adicionar email principal se fornecido
|
||||
email = form_data.get('email')
|
||||
if email:
|
||||
email_militante = EmailMilitante(
|
||||
endereco_email=email,
|
||||
militante_id=militante_id
|
||||
)
|
||||
MilitanteService.salvar_email_militante(email_militante)
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'message': 'Militante criado com sucesso!',
|
||||
'id': militante_id
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Erro ao criar militante: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@staticmethod
|
||||
def atualizar_militante(militante_id, form_data):
|
||||
"""Atualiza um militante existente"""
|
||||
try:
|
||||
militante = MilitanteService.buscar_militante(militante_id)
|
||||
if not militante:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Militante não encontrado'
|
||||
}), 404
|
||||
|
||||
# Obter dados do formulário
|
||||
nome = form_data.get('nome')
|
||||
cpf = form_data.get('cpf')
|
||||
titulo_eleitoral = form_data.get('titulo_eleitoral')
|
||||
data_nascimento = form_data.get('data_nascimento')
|
||||
data_entrada_oci = form_data.get('data_entrada_oci')
|
||||
data_efetivacao_oci = form_data.get('data_efetivacao_oci')
|
||||
telefone1 = form_data.get('telefone1')
|
||||
telefone2 = form_data.get('telefone2')
|
||||
email = form_data.get('email')
|
||||
|
||||
# Validar e converter datas
|
||||
try:
|
||||
data_nascimento = converter_data(data_nascimento) if data_nascimento else None
|
||||
data_entrada_oci = converter_data(data_entrada_oci) if data_entrada_oci else None
|
||||
data_efetivacao_oci = converter_data(data_efetivacao_oci) if data_efetivacao_oci else None
|
||||
|
||||
# Validar sequência lógica das datas
|
||||
validar_sequencia_datas(
|
||||
data_nascimento=data_nascimento,
|
||||
data_entrada=data_entrada_oci,
|
||||
data_efetivacao=data_efetivacao_oci
|
||||
)
|
||||
|
||||
except ValueError as e:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': str(e)
|
||||
}), 400
|
||||
|
||||
# Atualizar dados básicos
|
||||
if nome: militante.nome = nome
|
||||
if cpf: militante.cpf = cpf
|
||||
if titulo_eleitoral: 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
|
||||
|
||||
# Calcular idade
|
||||
if data_nascimento:
|
||||
militante.idade = calcular_idade(data_nascimento)
|
||||
|
||||
# Atualizar ou criar email
|
||||
if email:
|
||||
MilitanteService.atualizar_email_militante(militante_id, email)
|
||||
|
||||
# Salvar alterações
|
||||
MilitanteService.salvar_militante(militante)
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'message': 'Militante atualizado com sucesso',
|
||||
'data': {
|
||||
'nome': militante.nome,
|
||||
'cpf': militante.cpf,
|
||||
'idade': militante.idade if hasattr(militante, 'idade') else None,
|
||||
'emails': [e.endereco_email for e in militante.emails],
|
||||
'telefone1': militante.telefone1,
|
||||
'celula_id': str(militante.celula_id) if militante.celula_id else None,
|
||||
'responsabilidades_valor': militante.responsabilidades
|
||||
}
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': f'Erro ao atualizar militante: {str(e)}'
|
||||
}), 500
|
||||
|
||||
@staticmethod
|
||||
def excluir_militante(militante_id):
|
||||
"""Exclui um militante"""
|
||||
try:
|
||||
if MilitanteService.excluir_militante(militante_id):
|
||||
flash('Militante excluído com sucesso!', 'success')
|
||||
return True
|
||||
else:
|
||||
flash('Militante não encontrado', 'danger')
|
||||
return False
|
||||
except Exception as e:
|
||||
flash(f'Erro ao excluir militante: {str(e)}', 'danger')
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def buscar_dados_militante(militante_id):
|
||||
"""Busca os dados de um militante específico"""
|
||||
militante = MilitanteService.buscar_militante(militante_id)
|
||||
if not militante:
|
||||
return jsonify({
|
||||
'status': 'error',
|
||||
'message': 'Militante não encontrado'
|
||||
}), 404
|
||||
|
||||
# Função auxiliar para formatar data com validação
|
||||
def formatar_data_segura(data):
|
||||
try:
|
||||
if not data:
|
||||
return None
|
||||
return data.strftime('%Y-%m-%d')
|
||||
except Exception as e:
|
||||
print(f"Erro ao formatar data: {str(e)}, valor: {data}")
|
||||
return None
|
||||
|
||||
# Formatar datas com validação
|
||||
data_nascimento = formatar_data_segura(militante.data_nascimento)
|
||||
data_entrada_oci = formatar_data_segura(militante.data_entrada_oci)
|
||||
data_efetivacao_oci = formatar_data_segura(militante.data_efetivacao_oci)
|
||||
|
||||
return jsonify({
|
||||
'status': 'success',
|
||||
'id': militante.id,
|
||||
'nome': militante.nome,
|
||||
'cpf': militante.cpf,
|
||||
'titulo_eleitoral': militante.titulo_eleitoral,
|
||||
'data_nascimento': data_nascimento,
|
||||
'data_entrada_oci': data_entrada_oci,
|
||||
'data_efetivacao_oci': data_efetivacao_oci,
|
||||
'emails': [email.endereco_email for email in militante.emails] if militante.emails else [],
|
||||
'telefone1': militante.telefone1,
|
||||
'telefone2': militante.telefone2,
|
||||
'celula_id': militante.celula_id,
|
||||
'responsabilidades_valor': militante.responsabilidades,
|
||||
'sindicato': militante.sindicato,
|
||||
'cargo_sindical': militante.cargo_sindical,
|
||||
'central_sindical': militante.central_sindical,
|
||||
'dirigente_sindical': militante.dirigente_sindical
|
||||
})
|
||||
Reference in New Issue
Block a user