"""Regras operacionais de disponibilidade, qualificação e progressão.""" from __future__ import annotations from datetime import date import pandas as pd from .utils import normalizar_texto def piloto_disponivel(tripulante: str, data_missao: date, indisponibilidades: pd.DataFrame) -> bool: trip = normalizar_texto(tripulante) conflitos = indisponibilidades[ (indisponibilidades["tripulante"] == trip) & (indisponibilidades["inicio"] <= data_missao) & (indisponibilidades["fim"] >= data_missao) ] return conflitos.empty def classe_principal(qualificacao: str) -> str: qual = normalizar_texto(qualificacao) for classe in ["IN", "PO", "PB", "AL"]: if classe in qual.split("/"): return classe if classe in qual.split(): return classe return "OUTRO" def qualificacao_base_aeronave(tripulante: str, aeronave: str, cadastro: pd.DataFrame) -> str: linha = cadastro[cadastro["tripulante"] == normalizar_texto(tripulante)] if linha.empty: return "OUTRO" qt = [x for x in normalizar_texto(linha.iloc[0]["qt"]).split("/") if x] quals = [x for x in normalizar_texto(linha.iloc[0]["qualificacao"]).split("/") if x] if len(qt) == len(quals) and aeronave in qt: return classe_principal(quals[qt.index(aeronave)]) return classe_principal(linha.iloc[0]["qualificacao"]) def subprograma_concluido(progresso: pd.DataFrame, tripulante: str, aeronave: str, subprograma: str, catalogo: pd.DataFrame) -> bool: necessarias = set(catalogo[(catalogo["aeronave"] == aeronave) & (catalogo["subprograma"] == subprograma)]["oi"]) if not necessarias: return False concluidas = set( progresso[ (progresso["tripulante"] == normalizar_texto(tripulante)) & (progresso["aeronave"] == aeronave) & (progresso["subprograma"] == subprograma) & (progresso["concluida"] == True) ]["oi"] ) return necessarias.issubset(concluidas) def qualificacao_operacional(tripulante: str, aeronave: str, cadastro: pd.DataFrame, progresso: pd.DataFrame, catalogo: pd.DataFrame) -> str: rank = {"OUTRO": 0, "AL": 1, "PB": 2, "PO": 3, "IN": 4}[qualificacao_base_aeronave(tripulante, aeronave, cadastro)] if subprograma_concluido(progresso, tripulante, aeronave, "SPFO-1", catalogo): rank = max(rank, 2) if subprograma_concluido(progresso, tripulante, aeronave, "SPFO-2", catalogo): rank = max(rank, 3) if aeronave == "C98" and subprograma_concluido(progresso, tripulante, aeronave, "SPQE-3", catalogo): rank = max(rank, 4) if aeronave == "C97" and subprograma_concluido(progresso, tripulante, aeronave, "SPQE-4", catalogo): rank = max(rank, 4) return {0: "OUTRO", 1: "AL", 2: "PB", 3: "PO", 4: "IN"}[rank] def concluiu_ois(progresso: pd.DataFrame, tripulante: str, aeronave: str, ois: list[str]) -> bool: concluidas = set( progresso[ (progresso["tripulante"] == normalizar_texto(tripulante)) & (progresso["aeronave"] == aeronave) & (progresso["concluida"] == True) ]["oi"] ) return set(ois).issubset(concluidas) def eh_instrutor_adaptado(tripulante: str, aeronave: str, cadastro: pd.DataFrame, progresso: pd.DataFrame, catalogo: pd.DataFrame) -> bool: trip = normalizar_texto(tripulante) instrutores_base = { "C95": {"MES", "BRI"}, "C97": {"AEU", "MAT"}, "C98": {"BRI", "FIA", "MDO", "SLS", "CFF"}, } if trip in instrutores_base.get(aeronave, set()): return True if aeronave == "C97" and trip in {"SEI", "LPS"}: return concluiu_ois(progresso, trip, aeronave, ["01TL01D41", "04TL01N42"]) if aeronave == "C98" and trip in {"MCH", "DOG"}: return concluiu_ois(progresso, trip, aeronave, ["01TL01D31", "04TL01N32"]) return qualificacao_operacional(trip, aeronave, cadastro, progresso, catalogo) == "IN" def combinar_progresso_com_historico(progresso: pd.DataFrame, historico: pd.DataFrame, catalogo: pd.DataFrame) -> pd.DataFrame: if historico.empty: return progresso voadas = historico[(historico["oi"] != "") & (historico["horas_voadas"] > 0)] if voadas.empty: return progresso hist = voadas.merge(catalogo[["aeronave", "subprograma", "oi"]].drop_duplicates(), on=["aeronave", "oi"], how="left") hist = hist.dropna(subset=["subprograma"]) hist = hist[["tripulante", "aeronave", "subprograma", "oi", "horas_voadas"]].rename(columns={"horas_voadas": "horas_realizadas"}) hist["concluida"] = True return pd.concat([progresso, hist], ignore_index=True).drop_duplicates(["tripulante", "aeronave", "subprograma", "oi"])