autocensup/core/validation.py

205 lines
9.0 KiB
Python

from __future__ import annotations
import re
from .models import Curso, Pessoa, Vinculo
SEMESTRE_RE = re.compile(r"^(01|02)(19|20)\d{2}$")
def validate_curso(curso: Curso) -> list[str]:
issues = []
if not curso.codigo_mec:
issues.append("Curso: codigo MEC obrigatorio.")
if not curso.descricao:
issues.append("Curso: descricao obrigatoria.")
if not curso.situacao_funcionamento_curso:
issues.append("Curso: situacao de funcionamento obrigatoria.")
if curso.carga_horaria_total <= 0:
issues.append("Curso: carga horaria total deve ser maior que zero.")
if curso.ead and curso.polo_id is None:
issues.append("Curso: curso EaD deve ter polo vinculado.")
return issues
def validate_pessoa(pessoa: Pessoa) -> list[str]:
issues = []
if not pessoa.nome:
issues.append("Pessoa: nome obrigatorio.")
if not pessoa.cpf or len(pessoa.cpf) != 11 or not pessoa.cpf.isdigit():
issues.append("Pessoa: CPF deve ter 11 digitos.")
if not pessoa.data_nascimento:
issues.append("Pessoa: data de nascimento obrigatoria.")
if pessoa.cor_raca is None:
issues.append("Pessoa: cor/raca obrigatoria.")
if pessoa.nacionalidade is None:
issues.append("Pessoa: nacionalidade obrigatoria.")
if pessoa.pais_origem_id is None:
issues.append("Pessoa: pais de origem obrigatorio.")
if pessoa.aluno_com_deficiencia is None:
issues.append("Pessoa: indicador de deficiencia obrigatorio.")
if pessoa.tipo_escola_ensino_medio is None:
issues.append("Pessoa: tipo de escola do ensino medio obrigatorio.")
if pessoa.nacionalidade == Pessoa.Nacionalidade.BRASILEIRA_NATA:
if pessoa.pais_origem_id != "BRA":
issues.append("Pessoa: brasileira nata deve ter pais de origem BRA.")
if pessoa.uf_nascimento_id is None:
issues.append("Pessoa: brasileira nata deve ter UF de nascimento.")
elif pessoa.nacionalidade in {
Pessoa.Nacionalidade.BRASILEIRA_NATURALIZADA,
Pessoa.Nacionalidade.ESTRANGEIRA,
}:
if pessoa.pais_origem_id == "BRA":
issues.append("Pessoa: pais BRA e exclusivo de brasileira nata.")
if pessoa.uf_nascimento_id is not None or pessoa.municipio_nascimento_id is not None:
issues.append("Pessoa: UF/municipio de nascimento sao exclusivos de brasileira nata.")
if pessoa.municipio_nascimento_id and pessoa.uf_nascimento_id is None:
issues.append("Pessoa: municipio de nascimento exige UF de nascimento.")
if (
pessoa.municipio_nascimento_id
and pessoa.uf_nascimento_id
and pessoa.municipio_nascimento.uf_id != pessoa.uf_nascimento_id
):
issues.append("Pessoa: municipio de nascimento nao pertence a UF informada.")
disability_flags = [
pessoa.deficiencia_cegueira,
pessoa.deficiencia_baixa_visao,
pessoa.deficiencia_visao_monocular,
pessoa.deficiencia_surdez,
pessoa.deficiencia_auditiva,
pessoa.deficiencia_fisica,
pessoa.deficiencia_surdocegueira,
pessoa.deficiencia_intelectual,
pessoa.deficiencia_tea,
pessoa.deficiencia_altas_habilidades,
]
has_disability_flag = any(flag is True for flag in disability_flags)
has_blank_disability_flag = any(flag is None for flag in disability_flags)
if pessoa.aluno_com_deficiencia == Pessoa.SimNaoNaoDispoe.SIM:
if has_blank_disability_flag:
issues.append("Pessoa: todos os tipos de deficiencia devem ser informados.")
if not has_disability_flag:
issues.append("Pessoa: ao menos um tipo de deficiencia deve ser marcado.")
elif has_disability_flag:
issues.append("Pessoa: tipos de deficiencia so podem ser marcados quando indicador for Sim.")
return issues
def validate_vinculo(vinculo: Vinculo) -> list[str]:
issues = []
curso = vinculo.curso
pessoa = vinculo.pessoa
issues.extend(validate_curso(curso))
issues.extend(validate_pessoa(pessoa))
if not vinculo.ano_censo:
issues.append("Vinculo: ano do censo obrigatorio.")
if vinculo.situacao == Vinculo.Situacao.NAO_INFORMADA:
issues.append("Vinculo: situacao de vinculo obrigatoria.")
if not vinculo.semestre_ingresso or not SEMESTRE_RE.match(vinculo.semestre_ingresso):
issues.append("Vinculo: semestre de ingresso deve estar no formato 01AAAA ou 02AAAA.")
if curso.ead:
if vinculo.polo_id is None and curso.polo_id is None:
issues.append("Vinculo: curso EaD exige polo.")
elif vinculo.turno is None:
issues.append("Vinculo: curso presencial exige turno do aluno.")
if curso.licenciatura:
if vinculo.aluno_parfor is None:
issues.append("Vinculo: licenciatura exige informacao de Aluno PARFOR.")
if vinculo.segunda_licenciatura_formacao_pedagogica is None:
issues.append("Vinculo: licenciatura exige segunda licenciatura/formacao pedagogica.")
if (
vinculo.segunda_licenciatura_formacao_pedagogica is True
and vinculo.tipo_segunda_licenciatura_formacao_pedagogica is None
):
issues.append("Vinculo: segunda licenciatura/formacao pedagogica exige tipo.")
if vinculo.carga_horaria_total_aluno != curso.carga_horaria_total:
issues.append("Vinculo: carga horaria total deve vir do curso.")
if vinculo.carga_horaria_total_aluno <= 0:
issues.append("Vinculo: carga horaria total obrigatoria.")
if vinculo.carga_horaria_integralizada < 0:
issues.append("Vinculo: carga horaria integralizada invalida.")
if vinculo.carga_horaria_integralizada > 15000:
issues.append("Vinculo: carga horaria integralizada deve ser menor que 15000.")
if (
vinculo.situacao == Vinculo.Situacao.FORMADO
and vinculo.carga_horaria_integralizada < vinculo.carga_horaria_total_aluno
):
issues.append("Vinculo: formado exige carga integralizada maior ou igual a total.")
if vinculo.financiamento_estudantil is True:
financing_flags = [
vinculo.financiamento_fies,
vinculo.financiamento_governo_estadual,
vinculo.financiamento_governo_municipal,
vinculo.financiamento_ies,
vinculo.financiamento_entidades_externas,
vinculo.financiamento_prouni_integral,
vinculo.financiamento_prouni_parcial,
vinculo.financiamento_nao_reembolsavel_entidades_externas,
vinculo.financiamento_nao_reembolsavel_governo_estadual,
vinculo.financiamento_nao_reembolsavel_ies,
vinculo.financiamento_nao_reembolsavel_governo_municipal,
]
if any(flag is None for flag in financing_flags):
issues.append("Vinculo: financiamento exige preenchimento dos tipos.")
if not any(flag is True for flag in financing_flags):
issues.append("Vinculo: financiamento exige ao menos um tipo marcado.")
social_flags = [
vinculo.apoio_alimentacao,
vinculo.apoio_moradia,
vinculo.apoio_transporte,
vinculo.apoio_material_didatico,
vinculo.apoio_bolsa_trabalho,
vinculo.apoio_bolsa_permanencia,
]
if vinculo.apoio_social and (any(flag is None for flag in social_flags) or not any(social_flags)):
issues.append("Vinculo: apoio social exige tipos preenchidos e ao menos um marcado.")
if not vinculo.apoio_social and any(flag is True for flag in social_flags):
issues.append("Vinculo: tipos de apoio social exigem Apoio Social igual a Sim.")
activity_flags = [
vinculo.atividade_pesquisa,
vinculo.atividade_extensao,
vinculo.atividade_monitoria,
vinculo.atividade_estagio_nao_obrigatorio,
]
if vinculo.atividade_extracurricular and (
any(flag is None for flag in activity_flags) or not any(activity_flags)
):
issues.append("Vinculo: atividade extracurricular exige tipos preenchidos e ao menos um marcado.")
if not vinculo.atividade_extracurricular and any(flag is True for flag in activity_flags):
issues.append("Vinculo: tipos de atividade exigem Atividade extracurricular igual a Sim.")
if vinculo.ingressou_acao_afirmativa:
if vinculo.tipo_politica_acao_afirmativa is None:
issues.append("Vinculo: acao afirmativa exige tipo de politica.")
reserve_flags = [
vinculo.reserva_ppi,
vinculo.reserva_renda,
vinculo.reserva_pessoa_com_deficiencia,
vinculo.reserva_escola_publica,
vinculo.reserva_quilombola,
vinculo.reserva_transgenero_travesti,
vinculo.reserva_estudante_internacional,
vinculo.reserva_refugiado_apatrida_visto_humanitario,
vinculo.reserva_idoso,
vinculo.reserva_povos_comunidades_tradicionais,
vinculo.reserva_olimpiadas_conhecimento,
vinculo.reserva_outros,
]
if not any(flag is True for flag in reserve_flags) and vinculo.tipo_acao_afirmativa_lei_cotas is None:
issues.append("Vinculo: acao afirmativa exige ao menos um tipo.")
return issues