109 lines
4.6 KiB
Python
109 lines
4.6 KiB
Python
"""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"])
|