import logging import numpy as np import pandas as pd from backend.models.administre import Administre from backend.models.administre import StatutPamChoices as StatutPam from backend.models.domaine import Domaine from backend.models.filiere import Filiere from backend.models.fonction import Fonction from backend.models.formation_emploi import FormationEmploi from backend.models.grade import Grade from ..alimentation import BOCols from ..alimentation_decorators import data_perf_logger_factory, get_data_logger from ..decorators import execution_time logger = get_data_logger(__name__) @execution_time(logger_factory=data_perf_logger_factory) def to_table_administres_bo(bo: pd.DataFrame) -> pd.DataFrame: """ Création de la table Administrés à partir du fichier de données BO. Sélection et renommage des champs. :param bo: table BO :type bo: class:`pandas.DataFrame` :return: data frame contenant les information des administrés :rtype: class:`pandas.DataFrame` """ Cols = Administre.Cols # import des tables contenant les clés étrangères fonctions = pd.DataFrame.from_records(Fonction.objects.all().values()) domaines = pd.DataFrame.from_records(Domaine.objects.all().values()) filieres = pd.DataFrame.from_records(Filiere.objects.all().values()) grades = pd.DataFrame.from_records(Grade.objects.all().values()) fe = pd.DataFrame.from_records(FormationEmploi.objects.all().values()) # sélection des attributs nécessaires à la table administres col_adm = BOCols.columns( BOCols.ID_SAP, BOCols.CREDO_FE, BOCols.FONCTION, BOCols.GRADE, BOCols.DATE_DEBUT_GRADE, BOCols.NOM, BOCols.PRENOM, BOCols.SEXE, BOCols.ID_DEF, BOCols.EIP, BOCols.EIS, BOCols.DOMAINE, BOCols.FILIERE, BOCols.NF, BOCols.DOMAINE_GESTION, BOCols.DATE_ENTREE_SERVICE, BOCols.ARME, BOCols.REGROUPEMENT_ORIGINE_RECRUTEMENT, BOCols.DATE_NAISSANCE, BOCols.DIPLOME_PLUS_HAUT_NIVEAU, BOCols.DATE_RDC, BOCols.DATE_DERNIER_ACR, BOCols.DERNIER_DIPLOME, BOCols.DATE_ARRIVEE_FE, BOCols.POSITION_STATUTAIRE, BOCols.DATE_POSITION_STATUAIRE, BOCols.INTERRUPTION_SERVICE, BOCols.SITUATION_FAMILIALE, BOCols.DATE_MARIAGE, BOCols.NOMBRE_ENFANTS, BOCols.ENFANTS, BOCols.ID_DEF_CONJOINT, BOCols.FONCTION_1, BOCols.FONCTION_2, BOCols.FONCTION_3, BOCols.FONCTION_4, BOCols.FONCTION_5, BOCols.FONCTION_6, BOCols.FONCTION_7, BOCols.FONCTION_8, BOCols.FONCTION_9, BOCols.DATE_FONCTION_1, BOCols.DATE_FONCTION_2, BOCols.DATE_FONCTION_3, BOCols.DATE_FONCTION_4, BOCols.DATE_FONCTION_5, BOCols.DATE_FONCTION_6, BOCols.DATE_FONCTION_7, BOCols.DATE_FONCTION_8, BOCols.DATE_FONCTION_9, BOCols.NF_POSTE, BOCols.DOMAINE_POSTE, BOCols.FILIERE_POSTE, BOCols.PLS_GB_MAX, BOCols.MARQUEUR_PN, BOCols.PROFESSION_CONJOINT, BOCols.ID_SAP_CONJOINT, BOCols.SEXE_CONJOINT, BOCols.ORIGINE_RECRUTEMENT, BOCols.DATE_LIEN_SERVICE, BOCols.AGE_ANNEES, BOCols.STATUT_CONCERTO, BOCols.DATE_STATUT_CONCERTO, BOCols.STATUT_CONCERTO_FUTUR, BOCols.DATE_STATUT_CONCERTO_FUTUR, BOCols.FUD, BOCols.DATE_FUD ) administres = bo[col_adm] # jointure avec les tables contenant les clés étrangères # mapping avec les postes administres = administres.merge(fonctions, how='left', left_on=BOCols.FONCTION.value, right_on='fon_libelle') logger.debug("Nombre d'administrés dans le fichier") logger.debug('total administres : %s', administres.shape[0]) administres = administres.merge(grades, how='inner', left_on=BOCols.GRADE.value, right_on='gr_code') logger.debug("Filtrage par grade reconnu") logger.debug("Nombre d'administres : %s", administres.shape[0]) administres = administres.merge(fe, how='inner', left_on=BOCols.CREDO_FE.value, right_on='fe_code') logger.debug("Filtrage par FE reconnue") logger.debug("Nombre d'administres : %s", administres.shape[0]) # sélection et renommage des champs (BIEN FAIRE LE MAPPING DES COLONNES QU'ON VEUT GARDER) adm_mapping = BOCols.col_mapping({ BOCols.ID_SAP: Cols.PK, 'fe_code': f'{Cols.REL_FORMATION_EMPLOI}_id', 'fon_id': "a_code_fonction", BOCols.GRADE: f'{Cols.REL_GRADE}_id', BOCols.DATE_DEBUT_GRADE: "a_grade_date_debut", BOCols.FONCTION: "a_fonction", BOCols.NOM: "a_nom", BOCols.PRENOM: "a_prenom", BOCols.SEXE: "a_sexe", BOCols.ID_DEF: "a_id_def", BOCols.EIP: "a_eip", BOCols.EIP: "a_eip_fiche_detaille", BOCols.EIS: "a_eis", BOCols.DOMAINE: Cols.REL_DOMAINE, BOCols.FILIERE: Cols.REL_FILIERE, BOCols.NF: 'a_nf', BOCols.DOMAINE_GESTION: "a_domaine_gestion", BOCols.DATE_ENTREE_SERVICE: "a_date_entree_service", BOCols.ARME: "a_arme", BOCols.REGROUPEMENT_ORIGINE_RECRUTEMENT: "a_rg_origine_recrutement", BOCols.DATE_RDC: 'a_date_rdc', BOCols.DATE_DERNIER_ACR: 'a_date_dernier_acr', BOCols.DATE_NAISSANCE: "a_date_naissance", BOCols.DIPLOME_PLUS_HAUT_NIVEAU: "a_diplome_hl", BOCols.DERNIER_DIPLOME: "a_dernier_diplome", BOCols.CREDO_FE: "a_credo_fe", BOCols.DATE_ARRIVEE_FE: "a_date_arrivee_fe", BOCols.POSITION_STATUTAIRE: "a_pos_statuaire", BOCols.DATE_POSITION_STATUAIRE: "a_date_pos_statuaire", BOCols.INTERRUPTION_SERVICE: "a_interruption_service", BOCols.SITUATION_FAMILIALE: "a_situation_fam", BOCols.DATE_MARIAGE: "a_date_mariage", BOCols.NOMBRE_ENFANTS: "a_nombre_enfants", BOCols.ENFANTS: "a_enfants", BOCols.ID_SAP_CONJOINT: "a_sap_conjoint", BOCols.FONCTION_1: "a_fonction1", BOCols.FONCTION_2: "a_fonction2", BOCols.FONCTION_3: "a_fonction3", BOCols.FONCTION_4: "a_fonction4", BOCols.FONCTION_5: "a_fonction5", BOCols.FONCTION_6: "a_fonction6", BOCols.FONCTION_7: "a_fonction7", BOCols.FONCTION_8: "a_fonction8", BOCols.FONCTION_9: "a_fonction9", BOCols.DATE_FONCTION_1: "a_date_fonction1", BOCols.DATE_FONCTION_2: "a_date_fonction2", BOCols.DATE_FONCTION_3: "a_date_fonction3", BOCols.DATE_FONCTION_4: "a_date_fonction4", BOCols.DATE_FONCTION_5: "a_date_fonction5", BOCols.DATE_FONCTION_6: "a_date_fonction6", BOCols.DATE_FONCTION_7: "a_date_fonction7", BOCols.DATE_FONCTION_8: "a_date_fonction8", BOCols.DATE_FONCTION_9: "a_date_fonction9", BOCols.NF_POSTE: "a_nf_poste", BOCols.DOMAINE_POSTE: "a_domaine_poste", BOCols.FILIERE_POSTE: "a_filiere_poste", BOCols.PLS_GB_MAX: "a_pls_gb_max", BOCols.MARQUEUR_PN: "a_marqueur_pn", BOCols.PROFESSION_CONJOINT: "a_profession_conjoint", BOCols.ID_DEF_CONJOINT: "a_id_def_conjoint", BOCols.SEXE_CONJOINT: "a_sexe_conjoint", BOCols.ORIGINE_RECRUTEMENT: "a_origine_recrutement", BOCols.STATUT_CONCERTO: Cols.STATUT_CONCERTO, BOCols.DATE_STATUT_CONCERTO: Cols.DATE_STATUT_CONCERTO, BOCols.STATUT_CONCERTO_FUTUR: Cols.STATUT_CONCERTO_FUTUR, BOCols.DATE_STATUT_CONCERTO_FUTUR: Cols.DATE_STATUT_CONCERTO_FUTUR, BOCols.FUD: 'a_fud', BOCols.DATE_FUD: 'a_date_fud', BOCols.DATE_LIEN_SERVICE: "a_lien_service", BOCols.AGE_ANNEES: "a_age_en_annees" }) administres = administres.rename(columns=adm_mapping, errors='raise') # initialisation des colonnes vides adm_col_vides = { 'a_liste_id_marques': '', 'a_notes_gestionnaire': '', 'a_notes_partagees': '', 'a_flag_particulier': 0 } for k, v in adm_col_vides.items(): administres[k] = v administres = administres[list(adm_mapping.values()) + list(adm_col_vides.keys())] administres_dom = administres.merge(domaines, how='inner', left_on=Cols.REL_DOMAINE, right_on='d_code') df = pd.merge(administres, administres_dom, on=[Cols.PK, Cols.REL_DOMAINE], how="left", indicator=True) df = df[df['_merge'] == 'left_only'] domaines_not_found = df[Cols.REL_DOMAINE].drop_duplicates().tolist() administres_excluded_by_dom = df[Cols.PK].tolist() logger.debug("Filtrage par domaine actuel reconnu") logger.debug("Nombre d'administres : %s", administres_dom.shape[0]) logger.debug('Domaines non retrouvés : %s', domaines_not_found) logger.debug('****************') logger.debug(administres_excluded_by_dom) logger.debug('****************') administres_fil = administres_dom.merge(filieres, how='inner', left_on=Cols.REL_FILIERE, right_on='f_code') # administres.merge(administres_fil, how='') df = pd.merge(administres_dom, administres_fil, on=[Cols.PK, Cols.REL_FILIERE], how="left", indicator=True) df = df[df['_merge'] == 'left_only'] filieres_not_found = df[Cols.REL_FILIERE].drop_duplicates().tolist() administres_excluded_by_fil = df[Cols.PK].tolist() logger.debug("Filtrage par filière reconnue") logger.debug("Nombre d'administres restant : %s", administres_fil.shape[0]) logger.debug('Filières non retrouvées : %s', filieres_not_found) logger.debug('****************') logger.debug(administres_excluded_by_fil) logger.debug('****************') administres = administres_fil administres = administres.merge(domaines, how='left', left_on='a_domaine_poste', right_on='d_code', indicator=True) administres.loc[administres['_merge'] == 'left_only', 'a_domaine_poste'] = None administres.drop(columns='_merge', inplace=True) administres = administres.merge(filieres, how='left', left_on='a_filiere_poste', right_on='f_code', indicator=True) administres.loc[administres['_merge'] == 'left_only', 'a_filiere_poste'] = None # administres = administres.merge(filieres, how='inner', left_on='a_filiere_poste', right_on='f_code') administres['a_categorie'] = administres["a_nf"].replace( {'1A': 'MDR', '1B': 'MDR', '1C': 'MDR', '2.': 'SOFF', '3A': 'SOFF', '3B': 'SOFF', '3B NFS': 'SOFF', '4.': 'OFF', '5A': 'OFF', '5B': 'OFF', '5C': 'OFF', '6A': 'OGX', '6B': 'OGX'}, inplace=False) # administres["a_nom_prenom"].fillna('NOM Prenom', inplace=True) # # administres["a_nom_prenom"].replace('', 'NOM Prenom', inplace=True) # nom_prenom_split = administres['a_nom_prenom'].str.split(r" +", n=1).str # administres["a_nom"] = nom_prenom_split.get(0).fillna('') # administres["a_prenom"] = nom_prenom_split.get(1).fillna('') # administres.drop("a_nom_prenom", inplace=True, axis=1) administres['a_nom'] = administres['a_nom'].fillna('NOM') administres['a_prenom'] = administres['a_prenom'].fillna('Prénom') administres[f'{Cols.REL_FORMATION_EMPLOI}_id'] = administres[f'{Cols.REL_FORMATION_EMPLOI}_id'].replace({np.nan: None}) administres[f'{Cols.REL_GRADE}_id'] = administres[f'{Cols.REL_GRADE}_id'].replace({np.nan: None}) administres = administres.drop_duplicates(subset=[Cols.PK]) logger.debug('Retrait des doublons') logger.debug("Nombre d'administres restants : %s", administres.shape[0]) administres = administres.reset_index(drop=True) administres['a_sap_conjoint'] = administres['a_sap_conjoint'].replace({np.nan: None}) administres['a_nf_poste'] = (administres['a_nf_poste'].replace({np.nan, None}) .apply(lambda x: str(x)[1:]) .str.upper()) administres['a_nf'] = administres['a_nf'].str.upper() administres['a_eip'] = administres[Cols.REL_DOMAINE] + administres[Cols.REL_FILIERE] + administres['a_nf'] administres['a_marqueur_pn'] = administres['a_marqueur_pn'].apply(lambda x: True if x == 'X' else False) administres = (administres.fillna(np.nan) .replace([np.nan], [None])) logger.debug("Nombre d'administres extrait : %s", administres.shape[0]) return administres