Source code for src.dieta_especial.tasks.utils.logs

import datetime
from collections import Counter

from dateutil.relativedelta import relativedelta
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q

from src.dados_comuns.utils import quantidade_meses
from src.dieta_especial.constants import ETAPA_INFANTIL
from src.dieta_especial.logs_models.models import (
    LogQuantidadeDietasAutorizadas,
    LogQuantidadeDietasAutorizadasCEI,
    LogQuantidadeDietasAutorizadasRecreioNasFerias,
    LogQuantidadeDietasAutorizadasRecreioNasFeriasCEI,
)
from src.dieta_especial.solicitacao_dieta_especial.models import (
    ClassificacaoDieta,
)
from src.escola.models import FaixaEtaria, PeriodoEscolar
from src.medicao_inicial.models import SolicitacaoMedicaoInicial


[docs] def cria_logs_totais_cei_por_faixa_etaria(logs_escola, ontem, escola): logs = [log for log in logs_escola if log.periodo_escolar.nome == "INTEGRAL"] if not logs: return logs_escola for classificacao in ClassificacaoDieta.objects.all(): quantidade_total = sum( [log.quantidade for log in logs if log.classificacao == classificacao] ) log_total = LogQuantidadeDietasAutorizadasCEI( data=ontem, escola=escola, quantidade=quantidade_total, classificacao=classificacao, periodo_escolar=logs[0].periodo_escolar, faixa_etaria=None, ) logs_escola.append(log_total) return logs_escola
[docs] def get_quantidade_nao_matriculados_entre_4_e_6_anos(dietas, data_referencia): return dietas.filter( tipo_solicitacao="ALUNO_NAO_MATRICULADO", aluno__data_nascimento__lte=data_referencia - relativedelta(years=4), aluno__data_nascimento__gte=data_referencia - relativedelta(years=6), ).count()
[docs] def get_quantidade_nao_matriculados_maior_6_anos(dietas, data_referencia): return dietas.filter( tipo_solicitacao="ALUNO_NAO_MATRICULADO", aluno__data_nascimento__lte=data_referencia - relativedelta(years=6), ).count()
[docs] def get_quantidade_dietas_emebs(each, dietas, data_referencia): dietas_sem_alunos_nao_matriculados = dietas.exclude( tipo_solicitacao="ALUNO_NAO_MATRICULADO" ) if each == "INFANTIL": quantidade = dietas_sem_alunos_nao_matriculados.filter( aluno__etapa=ETAPA_INFANTIL ).count() quantidade += get_quantidade_nao_matriculados_entre_4_e_6_anos( dietas, data_referencia ) elif each == "FUNDAMENTAL": quantidade = dietas_sem_alunos_nao_matriculados.exclude( aluno__etapa=ETAPA_INFANTIL ).count() quantidade += get_quantidade_nao_matriculados_maior_6_anos( dietas, data_referencia ) else: quantidade = dietas_sem_alunos_nao_matriculados.count() quantidade += get_quantidade_nao_matriculados_maior_6_anos( dietas, data_referencia ) quantidade += get_quantidade_nao_matriculados_entre_4_e_6_anos( dietas, data_referencia ) return quantidade
[docs] def logs_a_criar_sem_periodo_escolar( logs_a_criar, escola, dietas_filtradas, ontem, classificacao ): if escola.eh_emebs: for each in ["INFANTIL", "FUNDAMENTAL", "N/A"]: quantidade = get_quantidade_dietas_emebs(each, dietas_filtradas, ontem) log = LogQuantidadeDietasAutorizadas( quantidade=quantidade, escola=escola, data=ontem, classificacao=classificacao, infantil_ou_fundamental=each, ) logs_a_criar.append(log) else: log = LogQuantidadeDietasAutorizadas( quantidade=dietas_filtradas.count(), escola=escola, data=ontem, classificacao=classificacao, ) logs_a_criar.append(log) return logs_a_criar
[docs] def logs_periodo_integral_cei_ou_emei_escola_cemei( logs_a_criar, dietas_autorizadas, classificacao, escola, periodo_escolar_nome, dict_periodos, ontem, ): dietas = dietas_autorizadas.filter( classificacao=classificacao, escola_destino=escola ).filter( Q(aluno__periodo_escolar__nome=periodo_escolar_nome) | Q(tipo_solicitacao="ALUNO_NAO_MATRICULADO") ) quantidade_cei = 0 quantidade_emei = 0 for dieta in dietas: if not dieta.aluno.serie: quantidade_cei += 1 quantidade_emei += 1 elif dieta.aluno.ciclo == dieta.aluno.CICLO_ALUNO_CEI: quantidade_cei += 1 else: quantidade_emei += 1 log_cei = LogQuantidadeDietasAutorizadas( quantidade=quantidade_cei, escola=escola, data=ontem, periodo_escolar=dict_periodos[periodo_escolar_nome], classificacao=classificacao, cei_ou_emei="CEI", ) log_emei = LogQuantidadeDietasAutorizadas( quantidade=quantidade_emei, escola=escola, data=ontem, periodo_escolar=dict_periodos[periodo_escolar_nome], classificacao=classificacao, cei_ou_emei="EMEI", ) return logs_a_criar + [log_cei] + [log_emei]
[docs] def gera_logs_dietas_escolas_comuns(escola, dietas_autorizadas, ontem): logs_a_criar = [] dict_periodos = PeriodoEscolar.dict_periodos() for classificacao in ClassificacaoDieta.objects.all(): dietas_filtradas = dietas_autorizadas.filter( classificacao=classificacao, escola_destino=escola ) logs_a_criar = logs_a_criar_sem_periodo_escolar( logs_a_criar, escola, dietas_filtradas, ontem, classificacao ) for periodo_escolar_nome in escola.periodos_escolares_com_alunos: dietas_filtradas_periodo = dietas_autorizadas.filter( classificacao=classificacao, escola_destino=escola ).filter( Q(aluno__periodo_escolar__nome=periodo_escolar_nome) | Q(tipo_solicitacao="ALUNO_NAO_MATRICULADO") ) if escola.eh_cemei and periodo_escolar_nome == "INTEGRAL": logs_a_criar = logs_periodo_integral_cei_ou_emei_escola_cemei( logs_a_criar, dietas_autorizadas, classificacao, escola, periodo_escolar_nome, dict_periodos, ontem, ) if escola.eh_emebs: for each in ["INFANTIL", "FUNDAMENTAL"]: quantidade = get_quantidade_dietas_emebs( each, dietas_filtradas_periodo, ontem ) log = LogQuantidadeDietasAutorizadas( quantidade=quantidade, escola=escola, data=ontem, periodo_escolar=dict_periodos[periodo_escolar_nome], classificacao=classificacao, infantil_ou_fundamental=each, ) logs_a_criar.append(log) else: log = LogQuantidadeDietasAutorizadas( quantidade=dietas_filtradas_periodo.count(), escola=escola, data=ontem, periodo_escolar=dict_periodos[periodo_escolar_nome], classificacao=classificacao, ) logs_a_criar.append(log) return logs_a_criar
[docs] def append_periodo_parcial(periodos, solicitacao_medicao): if solicitacao_medicao.ue_possui_alunos_periodo_parcial: periodos.append("PARCIAL") return periodos
[docs] def append_faixas_dietas(dietas, escola, data_referencia): faixas = [] for dieta_periodo in dietas: faixa = _faixa_etaria_para_aluno(dieta_periodo.aluno, data_referencia) if not faixa: continue if ( escola.eh_cemei and dieta_periodo.aluno.ciclo != dieta_periodo.aluno.CICLO_ALUNO_CEI ): continue faixas.append(faixa) return faixas
[docs] def criar_logs_integral_parcial( eh_integral, dietas, solicitacao_medicao, escola, ontem, classificacao, periodo, faixas, ): logs = [] dict_periodos = PeriodoEscolar.dict_periodos() faixas_alunos_parciais = [] for dieta in dietas: if dieta.aluno.nome in solicitacao_medicao.alunos_periodo_parcial.values_list( "aluno__nome", flat=True ): faixa = _faixa_etaria_para_aluno(dieta.aluno, ontem) if not faixa: continue faixas_alunos_parciais.append(faixa) faixas = faixas if eh_integral else faixas_alunos_parciais for faixa, quantidade in Counter(faixas).items(): if eh_integral and faixa in Counter(faixas_alunos_parciais).keys(): quantidade = quantidade - Counter(faixas_alunos_parciais).get(faixa) log = LogQuantidadeDietasAutorizadasCEI( quantidade=quantidade, escola=escola, data=ontem, classificacao=classificacao, periodo_escolar=dict_periodos[periodo], faixa_etaria=faixa, ) logs.append(log) return logs
[docs] def faixas_por_periodo_e_faixa_etaria(escola, periodo, ontem): try: return escola.matriculados_por_periodo_e_faixa_etaria(data=ontem)[periodo] except KeyError: return escola.matriculados_por_periodo_e_faixa_etaria(data=ontem)["INTEGRAL"]
[docs] def condicoes(log, escola, ontem, classificacao, periodo, faixa): resultado = ( log.escola == escola and log.data == ontem and log.classificacao == classificacao and log.periodo_escolar.nome == periodo and str(log.faixa_etaria.uuid) == faixa ) return resultado
[docs] def existe_log(logs_a_criar, escola, ontem, classificacao, periodo, faixa): resultado = list( filter( lambda log: condicoes(log, escola, ontem, classificacao, periodo, faixa), logs_a_criar, ) ) return resultado
[docs] def append_logs_a_criar_de_quantidade_zero(logs_a_criar, periodos, escola, ontem): dict_periodos = PeriodoEscolar.dict_periodos() for periodo in periodos: faixas = faixas_por_periodo_e_faixa_etaria(escola, periodo, ontem) for faixa, _ in faixas.items(): if faixa in [ str(f) for f in FaixaEtaria.objects.filter(ativo=True).values_list( "uuid", flat=True ) ]: for classificacao in ClassificacaoDieta.objects.all(): if not existe_log( logs_a_criar, escola, ontem, classificacao, periodo, faixa ): log = LogQuantidadeDietasAutorizadasCEI( quantidade=0, escola=escola, data=ontem, classificacao=classificacao, periodo_escolar=dict_periodos[periodo], faixa_etaria=FaixaEtaria.objects.get(uuid=faixa), ) logs_a_criar.append(log) return logs_a_criar
[docs] def adicionar_logs_a_criar_integral_parcial( periodos, periodo, dietas, solicitacao_medicao, escola, ontem, classificacao, faixas, logs_a_criar, dict_periodos, ): if periodo == "INTEGRAL" and "PARCIAL" in periodos: logs_a_criar.extend( criar_logs_integral_parcial( True, dietas, solicitacao_medicao, escola, ontem, classificacao, periodo, faixas, ) ) elif periodo == "PARCIAL": logs_a_criar.extend( criar_logs_integral_parcial( False, dietas, solicitacao_medicao, escola, ontem, classificacao, periodo, None, ) ) else: for faixa, quantidade in Counter(faixas).items(): logs_a_criar.append( LogQuantidadeDietasAutorizadasCEI( quantidade=quantidade, escola=escola, data=ontem, classificacao=classificacao, periodo_escolar=dict_periodos[periodo], faixa_etaria=faixa, ) ) return logs_a_criar
[docs] def logs_a_criar_existe_solicitacao_medicao(escola, dietas_autorizadas, ontem): solicitacao_medicao = SolicitacaoMedicaoInicial.objects.filter( escola__codigo_eol=escola.codigo_eol, mes=f"{datetime.date.today().month:02d}", ano=datetime.date.today().year, recreio_nas_ferias=None, ).first() if not solicitacao_medicao: raise ObjectDoesNotExist("Solicitação de Medição Inicial não encontrada.") logs_a_criar = [] periodos = escola.periodos_escolares_com_alunos periodos = append_periodo_parcial(periodos, solicitacao_medicao) periodos = list(set(periodos)) dict_periodos = PeriodoEscolar.dict_periodos() for periodo in periodos: for classificacao in ClassificacaoDieta.objects.all(): dietas = dietas_autorizadas.filter( classificacao=classificacao, escola_destino=escola ) dietas_filtradas_periodo = dietas.filter( aluno__periodo_escolar__nome=periodo ) dietas_nao_matriculados = dietas.filter( tipo_solicitacao="ALUNO_NAO_MATRICULADO" ) faixas = [] faixas += append_faixas_dietas(dietas_filtradas_periodo, escola, ontem) faixas += append_faixas_dietas(dietas_nao_matriculados, escola, ontem) adicionar_logs_a_criar_integral_parcial( periodos, periodo, dietas, solicitacao_medicao, escola, ontem, classificacao, faixas, logs_a_criar, dict_periodos, ) logs_a_criar = append_logs_a_criar_de_quantidade_zero( logs_a_criar, periodos, escola, ontem ) return logs_a_criar
[docs] def logs_a_criar_nao_existe_solicitacao_medicao(escola, dietas_autorizadas, ontem): logs_a_criar = [] periodos = escola.periodos_escolares_com_alunos dict_periodos = PeriodoEscolar.dict_periodos() for periodo in periodos: for classificacao in ClassificacaoDieta.objects.all(): dietas = dietas_autorizadas.filter( classificacao=classificacao, escola_destino=escola ) dietas_filtradas_periodo = dietas.filter( aluno__periodo_escolar__nome=periodo ) dietas_nao_matriculados = dietas.filter( tipo_solicitacao="ALUNO_NAO_MATRICULADO" ) faixas = [] faixas += append_faixas_dietas(dietas_filtradas_periodo, escola, ontem) faixas += append_faixas_dietas(dietas_nao_matriculados, escola, ontem) for faixa, quantidade in Counter(faixas).items(): log = LogQuantidadeDietasAutorizadasCEI( quantidade=quantidade, escola=escola, data=ontem, classificacao=classificacao, periodo_escolar=dict_periodos[periodo], faixa_etaria=faixa, ) logs_a_criar.append(log) logs_a_criar = append_logs_a_criar_de_quantidade_zero( logs_a_criar, periodos, escola, ontem ) return logs_a_criar
[docs] def gera_logs_dietas_escolas_cei(escola, dietas_autorizadas, ontem): try: return logs_a_criar_existe_solicitacao_medicao( escola, dietas_autorizadas, ontem ) except ObjectDoesNotExist: return logs_a_criar_nao_existe_solicitacao_medicao( escola, dietas_autorizadas, ontem )
[docs] def gera_logs_dietas_recreio_ferias_escolas_comuns(escola, dietas_recreio, data_log): logs_a_criar = [] for classificacao in ClassificacaoDieta.objects.all(): dietas_filtradas = dietas_recreio.filter( classificacao=classificacao, escola_destino=escola, ) quantidade = dietas_filtradas.count() log = LogQuantidadeDietasAutorizadasRecreioNasFerias( quantidade=quantidade, escola=escola, data=data_log, classificacao=classificacao, ) logs_a_criar.append(log) return logs_a_criar
[docs] def gera_logs_dietas_recreio_ferias_parte_sem_faixa_cemei( escola, dietas_recreio, data_log ): """ - alunos >= 4 anos OU ciclo != CICLO_ALUNO_CEI - alunos não matriculados com idade >= 4 anos. """ logs_a_criar = [] for classificacao in ClassificacaoDieta.objects.all(): dietas_filtradas = dietas_recreio.filter( classificacao=classificacao, escola_destino=escola, ) cont = _contar_dietas_sem_faixa(dietas_filtradas, data_log) log = LogQuantidadeDietasAutorizadasRecreioNasFerias( quantidade=cont, escola=escola, data=data_log, classificacao=classificacao, ) logs_a_criar.append(log) return logs_a_criar
def _contar_dietas_sem_faixa(dietas_filtradas, data_referencia): """Conta dietas que atendem aos critérios sem faixa etária.""" cont = 0 for dieta in dietas_filtradas: aluno = getattr(dieta, "aluno", None) if not aluno: continue if _deve_contar_aluno_sem_faixa(dieta, aluno, data_referencia): cont += 1 return cont def _deve_contar_aluno_sem_faixa(dieta, aluno, data_referencia): """Verifica se aluno deve ser contado (>= 4 anos ou ciclo != CEI).""" if dieta.tipo_solicitacao == "ALUNO_NAO_MATRICULADO": return _aluno_nao_matriculado_tem_4_anos_ou_mais(aluno, data_referencia) return aluno.ciclo != aluno.CICLO_ALUNO_CEI def _aluno_nao_matriculado_tem_4_anos_ou_mais(aluno, data_referencia): """Verifica se aluno não matriculado tem 4 anos ou mais.""" if not aluno.data_nascimento: return False idade_meses = quantidade_meses(data_referencia, aluno.data_nascimento) return idade_meses >= 48 # 4 anos * 12 meses def _faixa_etaria_para_aluno(aluno, data_referencia): if not aluno.data_nascimento: return None meses = quantidade_meses(data_referencia, aluno.data_nascimento) ultima_faixa = FaixaEtaria.objects.filter(ativo=True).order_by("fim").last() if not ultima_faixa: return None if meses >= ultima_faixa.fim: return ultima_faixa return FaixaEtaria.objects.filter( ativo=True, inicio__lte=meses, fim__gt=meses ).first()
[docs] def gera_logs_dietas_recreio_ferias_escolas_cei(escola, dietas_recreio, data_log): """ - alunos NÃO MATRICULADOS com idade <= 3a11m entram - alunos MATRICULADOS ciclo 1 entram """ logs_a_criar = [] for classificacao in ClassificacaoDieta.objects.all(): dietas_filtradas = dietas_recreio.filter( classificacao=classificacao, escola_destino=escola, ) contador_faixas = _contar_dietas_por_faixa(escola, dietas_filtradas, data_log) logs_a_criar.extend( _criar_logs_com_quantidade(escola, data_log, classificacao, contador_faixas) ) logs_a_criar.extend( _criar_logs_faixas_sem_alunos(escola, data_log, classificacao, logs_a_criar) ) return logs_a_criar
def _contar_dietas_por_faixa(escola, dietas_filtradas, data_referencia): contador_faixas = Counter() for dieta in dietas_filtradas: aluno = getattr(dieta, "aluno", None) if not aluno: continue faixa = _obter_faixa_etaria_dieta(escola, dieta, aluno, data_referencia) if faixa: contador_faixas[faixa] += 1 return contador_faixas def _obter_faixa_etaria_dieta(escola, dieta, aluno, data_referencia): """Obtém faixa etária do aluno se ele atender aos critérios.""" if escola.eh_cemei: return _obter_faixa_cemei(dieta, aluno, data_referencia) return _faixa_etaria_para_aluno(aluno, data_referencia) def _obter_faixa_cemei(dieta, aluno, data_referencia): """Obtém faixa etária para alunos de CEMEI.""" if dieta.tipo_solicitacao == "ALUNO_NAO_MATRICULADO": return _obter_faixa_nao_matriculado_cemei(aluno, data_referencia) if aluno.ciclo == aluno.CICLO_ALUNO_CEI: return _faixa_etaria_para_aluno(aluno, data_referencia) return None def _obter_faixa_nao_matriculado_cemei(aluno, data_referencia): """Obtém faixa para aluno não matriculado em CEMEI (até 3a11m).""" if not aluno.data_nascimento: return None meses = quantidade_meses(data_referencia, aluno.data_nascimento) if meses <= 47: # até 3a11m return _faixa_etaria_para_aluno(aluno, data_referencia) return None def _criar_logs_com_quantidade(escola, data_log, classificacao, contador_faixas): logs = [] for faixa, qtd in contador_faixas.items(): log = LogQuantidadeDietasAutorizadasRecreioNasFeriasCEI( quantidade=qtd, escola=escola, data=data_log, classificacao=classificacao, faixa_etaria=faixa, ) logs.append(log) return logs def _criar_logs_faixas_sem_alunos(escola, data_log, classificacao, logs_existentes): faixas_atuais = set(FaixaEtaria.objects.filter(ativo=True)) faixas_com_log = { log.faixa_etaria for log in logs_existentes if log.escola == escola and log.classificacao == classificacao } faixas_sem_log = faixas_atuais - faixas_com_log logs = [] for faixa in faixas_sem_log: log_zero = LogQuantidadeDietasAutorizadasRecreioNasFeriasCEI( quantidade=0, escola=escola, data=data_log, classificacao=classificacao, faixa_etaria=faixa, ) logs.append(log_zero) return logs
[docs] def filtrar_logs_comuns_ja_existentes(logs): chaves_existentes = set( LogQuantidadeDietasAutorizadas.objects.filter( data__in={log.data for log in logs} ).values_list( "escola_id", "data", "classificacao_id", "periodo_escolar_id", "cei_ou_emei", "infantil_ou_fundamental", ) ) logs_filtrados = [] for log in logs: chave = ( log.escola_id, log.data, log.classificacao_id, log.periodo_escolar_id, log.cei_ou_emei, log.infantil_ou_fundamental, ) if chave not in chaves_existentes: logs_filtrados.append(log) chaves_existentes.add(chave) return logs_filtrados
[docs] def filtrar_logs_cei_ja_existentes(logs): chaves_existentes = set( LogQuantidadeDietasAutorizadasCEI.objects.filter( data__in={log.data for log in logs} ).values_list( "escola_id", "data", "classificacao_id", "periodo_escolar_id", "faixa_etaria_id", ) ) logs_filtrados = [] for log in logs: chave = ( log.escola_id, log.data, log.classificacao_id, log.periodo_escolar_id, log.faixa_etaria_id, ) if chave not in chaves_existentes: logs_filtrados.append(log) chaves_existentes.add(chave) return logs_filtrados
[docs] def filtrar_logs_recreio_ferias_ja_existentes(logs): chaves_existentes = set( LogQuantidadeDietasAutorizadasRecreioNasFerias.objects.filter( data__in={log.data for log in logs} ).values_list( "escola_id", "data", "classificacao_id", ) ) logs_filtrados = [] for log in logs: chave = ( log.escola_id, log.data, log.classificacao_id, ) if chave not in chaves_existentes: logs_filtrados.append(log) chaves_existentes.add(chave) return logs_filtrados
[docs] def filtrar_logs_recreio_ferias_cei_ja_existentes(logs): chaves_existentes = set( LogQuantidadeDietasAutorizadasRecreioNasFeriasCEI.objects.filter( data__in={log.data for log in logs} ).values_list( "escola_id", "data", "classificacao_id", "faixa_etaria_id", ) ) logs_filtrados = [] for log in logs: chave = ( log.escola_id, log.data, log.classificacao_id, log.faixa_etaria_id, ) if chave not in chaves_existentes: logs_filtrados.append(log) chaves_existentes.add(chave) return logs_filtrados