Files
2022-11-08 21:19:51 +01:00

406 lines
25 KiB
Python

from datetime import datetime
import time
import datetime
from django.http import Http404
from rest_framework.exceptions import APIException
from rest_framework.permissions import IsAdminUser, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
import datetime
from ..models import Administre, PAM
from ..models import StatutPamChoices as StatutPam
from ..serializers import AlimentationSerializer
from ..utils.alimentation_decorators import (data_perf_logger_factory,
get_data_logger)
from ..utils.decorators import execution_time, query_count
from ..utils.extraction.administre import (to_table_administres_bo)
from ..utils.insertion.administre import (insert_administre_bo,
update_administre_fmob)
from ..utils_extraction import (DataFrameTypes, FileTypes, read_files_by_type,
to_table_administre_notation,
to_table_affectation, to_table_diplome,
to_table_domaines, to_table_fe,
to_table_filieres, to_table_fmob_femp,
to_table_fmob_fmob,
to_table_fonctions, to_table_fud,
to_table_garnisons, to_table_groupesMarques,
to_table_marques, to_table_pam, to_table_postes,
to_table_ref_gest, to_table_ref_org,
to_table_ref_sv_fil, to_table_reo_ocv,
to_table_sous_vivier,
to_table_zone_geographique)
from ..utils_insertion import (insert_PAM, insert_administre_notation, insert_Affectation,
insert_Diplome, insert_Filiere,
insert_FMOB_femp, insert_FMOB_fmob,
insert_Fonction,
insert_FormationEmploi, insert_Fud,
insert_Garnison, insert_Grade, insert_Marque,
insert_MarquesGroupe, insert_Poste,
insert_RefFeMere, insert_RefGest, insert_RefOrg,
insert_RefSvFil, insert_SousVivier,
insert_SousVivier_instances,
insert_ZoneGeographique, update_domaine,
update_m2m_links_gestionnaire, update_poste_ocv, insert_delta)
import pandas as pd
class AlimentationView(APIView):
"""
Cette page est l'alimentation principale d'Ogure.
Elle permet à l'administrateur de charger un ensemble de fichiers pour alimenter ou mettre à jour la base de données.
"""
permission_classes = [IsAuthenticated, IsAdminUser]
serializer_class = AlimentationSerializer
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.logger = get_data_logger(self)
def get(self, request):
"""La fonction get renvoie une reponse contenant Formulaire d'alimentation d'OGURE NG
:type request: rest_framework.request.Request
:param request: Request
:return: - **return** (*json*): json contenant "Formulaire d'alimentation d'OGURE NG".
"""
return Response("Formulaire d'alimentation d'OGURE NG")
@execution_time(logger_factory=data_perf_logger_factory)
@query_count(logger_factory=data_perf_logger_factory)
def post(self, request):
"""La fonction post charge les fichiers.
:type request: rest_framework.request.Request
:param request: Request contenant les fichiers
:return: - **Response** (*Response*): Reponse contient les erreurs de chargement des données .
"""
try:
# TODO: préparer une variable qui renvoie les erreurs sous 3 axes : données référentielles, administrés, postes
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
self.logger.info('---------------------Upload begining---------------------------')
start_time = time.time()
file_donnees_bo = serializer.validated_data.get('Donnees_BO_ADT')
file_reo = serializer.validated_data.get('REO')
file_reo_suivant = serializer.validated_data.get('REO_PAM_SUIVANT')
file_reo_ocv = serializer.validated_data.get('REO_OCV')
file_ref_gest = serializer.validated_data.get('referentiel_gestionnaire')
file_ref_org = serializer.validated_data.get('referentiel_organique')
file_ref_sv_fil = serializer.validated_data.get('refeferentiel_sous_vivier_filiere')
file_ref_fe = serializer.validated_data.get('referentiel_fe')
file_fmob = serializer.validated_data.get('FMOB')
file_fmob_suivant = serializer.validated_data.get('FMOB_PAM_SUIVANT')
file_filiere_domaine = serializer.validated_data.get('domaine_filiere')
file_insee = serializer.validated_data.get('insee_maping')
file_diplomes = serializer.validated_data.get('diplomes')
file_fud = serializer.validated_data.get('FUD')
file_ref_zones_geo = serializer.validated_data.get('ref_zones_geo')
self.logger.info('---------------------Upload ending-----------------------------')
self.logger.debug("--------------upload time -- %d seconds ------------------------", time.time() - start_time)
df_by_type = read_files_by_type({
FileTypes.BO: file_donnees_bo,
FileTypes.DIPLOME: file_diplomes,
FileTypes.DOM_FIL: file_filiere_domaine,
FileTypes.FMOB_FEMP: file_fmob,
FileTypes.FMOB_FEMP_PAM_SUIVANT: file_fmob_suivant,
FileTypes.FUD: file_fud,
FileTypes.INSEE: file_insee,
FileTypes.REF_FE: file_ref_fe,
FileTypes.REF_GEO: file_ref_zones_geo,
FileTypes.REF_GEST: file_ref_gest,
FileTypes.REF_ORG: file_ref_org,
FileTypes.REF_SV_FIL: file_ref_sv_fil,
FileTypes.REO: file_reo,
FileTypes.REO_PAM_SUIVANT: file_reo_suivant,
FileTypes.REO_OCV: file_reo_ocv,
})
DF = DataFrameTypes
diplomes_df = df_by_type.get(DF.DIPLOME)
donnees_bo_df = df_by_type.get(DF.BO)
femp_df = df_by_type.get(DF.FEMP)
filiere_domaine_df = df_by_type.get(DF.DOM_FIL)
fmob_df = df_by_type.get(DF.FMOB)
fud_df = df_by_type.get(DF.FUD)
insee_df = df_by_type.get(DF.INSEE)
ref_fe_df = df_by_type.get(DF.REF_FE)
ref_gest_df = df_by_type.get(DF.REF_GEST)
ref_org_df = df_by_type.get(DF.REF_ORG)
ref_sv_fil_df = df_by_type.get(DF.REF_SV_FIL)
ref_zones_geo_df = df_by_type.get(DF.REF_GEO)
reo_df = df_by_type.get(DF.REO)
reo_ocv_df = df_by_type.get(DF.REO_OCV)
#dataframe pam + 1
femp_suivant_df = df_by_type.get(DF.FEMP_PAM_SUIVANT)
fmob_suivant_df = df_by_type.get(DF.FMOB_PAM_SUIVANT)
reo_suivant_df = df_by_type.get(DF.REO_PAM_SUIVANT)
self.logger.info('-------------------- Insert beginning ---------------------')
start_time_insert = time.time()
text_response = []
if ref_sv_fil_df is not None:
sv_cree, sv_modifie, sv_erreur, sv_supprime = insert_SousVivier(to_table_sous_vivier(ref_sv_fil_df))
text_response.append([f"Référentiel de sous-viviers/filières : {sv_cree} SousVivier créés, {sv_modifie} SousVivier mis à jour, {sv_erreur} SousVivier en erreur et {sv_supprime} SousVivier supprimés."])
self.logger.info('Sous-viviers ---------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : sous-viviers (nécessite %s)', DF.REF_SV_FIL.value[1])
if ref_org_df is not None:
ref_org_cree, ref_org_modifie, ref_org_erreur, ref_org_supprime = insert_RefOrg(to_table_ref_org(ref_org_df))
text_response.append([f"Référentiel organique : {ref_org_cree} RefOrg créés, {ref_org_modifie} RefOrg mis à jour, {ref_org_erreur} RefOrg en erreur et {ref_org_supprime} RefOrg supprimés."])
self.logger.info('Référentiel organique ------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : référentiel organique')
if ref_gest_df is not None:
ref_gest_cree, ref_gest_modifie, ref_gest_erreur, ref_gest_supprime, user_cree, user_modifie, user_supprime, user_ignore = insert_RefGest(to_table_ref_gest(ref_gest_df))
text_response.append([f"Référentiel de gestionnaires : {ref_gest_cree} RefGest créés, {ref_gest_modifie} RefGest mis à jour, {ref_gest_erreur} RefGest en erreur et {ref_gest_supprime} RefGest supprimés."])
text_response.append([f"Référentiel de gestionnaires : {user_cree} User créés, {user_modifie} User mis à jour, {user_supprime} User supprimés et {user_ignore} User ignorés."])
self.logger.info('Référentiel gestionnaire ---------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : référentiel de gestionnaires')
if ref_sv_fil_df is not None:
ref_sv_cree, ref_sv_delete, ref_sv_erreur, ref_sv_ignore = insert_RefSvFil(to_table_ref_sv_fil(ref_sv_fil_df))
text_response.append([f"Référentiel de sous-viviers/filières : {ref_sv_cree} RefSvFil créés, {ref_sv_delete} RefSvFil supprimés, {ref_sv_erreur} RefSvFil en erreur et {ref_sv_ignore} RefSvFil ignorés."])
self.logger.info('Référentiel sous-vivier filière --------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : référentiel de sous-viviers/filières')
if ref_gest_df is not None or ref_org_df is not None or ref_sv_fil_df is not None:
update_m2m_links_gestionnaire('SV')
self.logger.info('Liens gestionnaires/sous-viviers -------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : liens gestionnaires/sous-viviers (nécessite %s ou %s ou %s)',
DF.REF_GEST.value[1], DF.REF_ORG.value[1], DF.REF_SV_FIL.value[1])
if filiere_domaine_df is not None:
update_domaine(to_table_domaines(filiere_domaine_df))
self.logger.info('Domaine --------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : domaines (nécessite %s)', DF.DOM_FIL.value[1])
if insee_df is not None and donnees_bo_df is not None:
gar_cree, gar_maj , error = insert_Garnison(to_table_garnisons(insee_df, donnees_bo_df))
text_response.append([f"INSEE et Données BO : {gar_cree} garnisons crées, {gar_maj} garnisons mises à jour, {error} garnisons en erreur."])
self.logger.info('Garnison -------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : garnisons (nécessite %s + %s)', DF.INSEE.value[1], DF.BO.value[1])
if reo_df is not None:
reo_cree = insert_Fonction(to_table_fonctions(reo_df))
text_response.append([f"REO : {reo_cree} fonctions de postes créés."])
self.logger.info('Fonction -------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : fonctions (nécessite %s)', DF.REO.value[1])
if reo_suivant_df is not None:
reo_suivant_cree = insert_Fonction(to_table_fonctions(reo_suivant_df))
text_response.append([f"REO : {reo_suivant_cree} fonctions de postes A+1 créés."])
self.logger.info('Fonction A+1 -------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : fonctions A + 1 (nécessite %s)', DF.REO_PAM_SUIVANT.value[1])
# TODO if ....
insert_Grade()
self.logger.info('Grade ----------------------------------------------> Succès')
if filiere_domaine_df is not None:
dom_fil_cree, dom_fil_modifie, dom_fil_erreur, dom_fil_supprime = insert_Filiere(to_table_filieres(filiere_domaine_df))
text_response.append([f"Domaines - filières : {dom_fil_cree} couples domaine/filière créés, {dom_fil_modifie} couples domaine/filière mis à jour, {dom_fil_erreur} couples domaine/filière en erreur et {dom_fil_supprime} couples domaine/filière supprimés."])
self.logger.info('Filières ------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : filières (nécessite %s)', DF.DOM_FIL.value[1])
# TODO if ....
insert_MarquesGroupe(to_table_groupesMarques())
self.logger.info('MarquesGroupe -------------------------------------> Succès')
# TODO if ....
insert_Marque(to_table_marques())
self.logger.info('Marque --------------------------------------------> Succès')
if ref_fe_df is not None:
df = to_table_fe(ref_fe_df)
self.logger.debug('Extraction des données du référentiel FE ----------> Succès')
fe_cree, fe_maj, error_count = insert_FormationEmploi(df)
text_response.append([f"Référentiel FE : {fe_cree} formation d'emplois créées, {fe_maj} formation d'emplois mises à jour, {error_count} formation d'emplois en erreur."])
self.logger.info('FormationEmplois ----------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : formations-emplois (nécessite %s)', DF.REF_FE.value[1])
if ref_fe_df is not None:
insert_RefFeMere(ref_fe_df)
self.logger.info('Référentiel FE mère -------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : formations-emplois mères (nécessite %s)', DF.REF_FE.value[1])
if ref_gest_df is not None or ref_org_df is not None or ref_fe_df is not None:
update_m2m_links_gestionnaire('FE')
self.logger.info('Liens gestionnaires/formations-emplois ------------> Succès')
else:
self.logger.info('Mise à jour ignorée : liens gestionnaires/formations-emplois (nécessite %s ou %s ou %s)',
DF.REF_GEST.value[1], DF.REF_ORG.value[1], DF.REF_FE.value[1])
if donnees_bo_df is not None:
bo_adm_cree, bo_adm_modifie, bo_adm_deja_modifie, bo_adm_erreur, bo_adm_ignore, bo_dom_ignore, bo_fil_ignore = insert_administre_bo(to_table_administres_bo(donnees_bo_df))
text_response.append([f"Données BO : {bo_adm_cree} administrés créés, {bo_adm_modifie} administrés mis à jour, {bo_adm_deja_modifie} adminsitrés déjà à jour, {bo_adm_erreur} administrés en erreur, {bo_adm_ignore} administrés ignorés, {bo_dom_ignore} domaines ignorés et {bo_fil_ignore} filières ignorées."])
self.logger.info('Administre ----------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : administrés (nécessite %s)', DF.BO.value[1])
if diplomes_df is not None:
diplome_cree, diplome_maj, diplome_sup = insert_Diplome(to_table_diplome(diplomes_df))
text_response.append([f"Diplômes : {diplome_cree} diplômes créés, {diplome_maj} diplômes mis à jour, {diplome_sup} supprimés."])
self.logger.info('Diplome -------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : diplômes (nécessite %s)', DF.DIPLOME.value[1])
if donnees_bo_df is not None:
donnee_bo_cree, donnee_bo_sup = insert_Affectation(to_table_affectation(donnees_bo_df))
text_response.append([f"Données BO : {donnee_bo_cree} affectation créés, {donnee_bo_sup} affectation mis à jour."])
self.logger.info('Affectations --------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : affectations (nécessite %s)', DF.BO.value[1])
if fud_df is not None:
fud_cree, fud_sup = insert_Fud(to_table_fud(fud_df))
text_response.append([f"FUD : {fud_cree} FUD créés, {fud_sup} FUD supprimées."])
self.logger.info('FUD -----------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : FUD (nécessite %s)', DF.FUD.value[1])
if donnees_bo_df is not None:
bo_cree, bo_maj, error_count = insert_administre_notation(to_table_administre_notation(donnees_bo_df))
text_response.append([f"Données BO : {bo_cree} notations créées, {bo_maj} notations mises à jour, {error_count} notations en erreurs."])
self.logger.info('Administre Notation -------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : administrés/notations (nécessite %s)', DF.BO.value[1])
if reo_df is not None:
annee_pam = PAM.objects.get(pam_statut='PAM en cours').pam_id
reo_cree, reo_suivant_cree, reo_modifie, reo_erreur, reo_ignore = insert_Poste(to_table_postes(reo_df),annee_pam)
text_response.append([f"REO : {reo_cree} postes créés, {reo_modifie} postes mis à jour, {reo_erreur} postes en erreur et {reo_ignore} postes ignorés."])
self.logger.info('Poste ---------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : postes (nécessite %s)', DF.REO.value[1])
if reo_suivant_df is not None:
annee_pam = PAM.objects.get(pam_statut='PAM A+1').pam_id
reo_cree, reo_suivant_cree, reo_modifie, reo_erreur, reo_ignore = insert_Poste(to_table_postes(reo_suivant_df),annee_pam)
#info reo
text_response.append([f"REO A + 1 : {reo_suivant_cree} postes A+1 créés, {reo_erreur} postes A+1 en erreur et {reo_ignore} postes A+1 ignorés."])
self.logger.info('Poste A+1 ---------------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : postes A + 1 (nécessite %s)', DF.REO_PAM_SUIVANT.value[1])
if reo_suivant_df is not None:
self.logger.info('Calcul du delta de la colonne Info REO, veuillez patienter ...')
insert_delta(to_table_postes(reo_suivant_df))
text_response.append([f"Mise à jour de la colonne info REO"])
self.logger.info('Calcul du delta Info Reo ---------------------------------------------> Succès')
else:
self.logger.info('Mise à jour de la colonne "info reo" ignorée')
# TODO if ....
insert_SousVivier_instances()
self.logger.info('Sous-viviers instances ---------------------------> Succès')
if reo_ocv_df is not None:
reo_ocv_modifie, reo_ocv_erreur, reo_ocv_ignore = update_poste_ocv(to_table_reo_ocv(reo_ocv_df))
text_response.append([f"Requêtes OCV : {reo_ocv_modifie} postes-ocv mis à jour, {reo_ocv_erreur} postes-ocv en erreur et {reo_ocv_ignore} postes-ocv ignorés."])
self.logger.info('Poste-ocv -----------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : postes/administrés (nécessite %s)', DF.REO_OCV.value[1])
if ref_zones_geo_df is not None:
ref_zones_geo_df_cree, ref_zones_geo_df_sup, error_count = insert_ZoneGeographique(to_table_zone_geographique(ref_zones_geo_df))
text_response.append([f"Référentiels Zones Géographiques : {ref_zones_geo_df_cree} zones-geo créées, {ref_zones_geo_df_sup} zones-geo supprimés et {error_count} zones-geo en erreur."])
self.logger.info('Référentiel zones géographiques -------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : zones géographiques (nécessite %s)', DF.REF_GEO.value[1])
if fmob_df is not None:
fmob_cree, fmob_maj, ignore_count = insert_FMOB_fmob(to_table_fmob_fmob(fmob_df))
text_response.append([f"Formulaire de mobilité : {fmob_cree} fmob créés, {fmob_maj} fmob mis à jour et {ignore_count} fmob ignorés."])
self.logger.debug('Fichier FMOB --------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : FMOB (nécessite %s)', DF.FMOB.value[1])
if femp_df is not None:
femp_cree, femp_maj, ignore_count = insert_FMOB_femp(to_table_fmob_femp(femp_df))
text_response.append([f"Formulaire de mobilité : {femp_cree} femp créés, {femp_maj} femp mis à jour et {ignore_count} femp ignorés."])
self.logger.debug('Fichier FEMP --------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : FEMP (nécessite %s)', DF.FEMP.value[1])
if fmob_suivant_df is not None:
fmob_cree, fmob_maj, ignore_count = insert_FMOB_fmob(to_table_fmob_fmob(fmob_suivant_df))
text_response.append([f"Formulaire de mobilité A+1 : {fmob_cree} fmob A+1 créés, {fmob_maj} fmob A+1 mis à jour et {ignore_count} fmob A+1 ignorés."])
self.logger.debug('Fichier FMOB A+1--------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : FMOB A + 1(nécessite %s)', DF.FMOB_PAM_SUIVANT.value[1])
if femp_suivant_df is not None:
femp_cree, femp_maj, ignore_count = insert_FMOB_femp(to_table_fmob_femp(femp_suivant_df))
text_response.append([f"Formulaire de mobilité A+1 : {femp_cree} femp A+1 créés, {femp_maj} femp A+1 mis à jour et {ignore_count} femp A+1 ignorés."])
self.logger.debug('Fichier FEMP A+1 --------------------------------------> Succès')
else:
self.logger.info('Mise à jour ignorée : FEMP A + 1(nécessite %s)', DF.FEMP_PAM_SUIVANT.value[1])
if fmob_df is not None:
a_maintenir, a_traiter = update_administre_fmob(to_table_fmob_fmob(fmob_df))
text_response.append([f"Formulaire de mobilité : {a_maintenir} administrés mis à jour en 'A maintenir' car FMOB annulé, {a_traiter} administrés mis à jour en 'A muter' car ils ont un FMOB."])
self.logger.debug('Mise à jour du statut PAM si annulation FMOB et si FMOB existe------> Succès')
else:
self.logger.info('Mise à jour ignorée : statut PAM si annulation FMOB (nécessite %s ou %s)', DF.BO.value[1], DF.FMOB.value[1])
if fmob_suivant_df is not None:
a_maintenir, a_traiter = update_administre_fmob(to_table_fmob_fmob(fmob_suivant_df))
text_response.append([f"Formulaire de mobilité A+1 : {a_maintenir} administrés A+1 mis à jour en 'A maintenir' car FMOB annulé, {a_traiter} administrés A+1 mis à jour en 'A muter' car ils ont un FMOB A+1."])
self.logger.debug('Mise à jour du statut PAM A+1 si annulation FMOB et si FMOB existe ------> Succès')
else:
self.logger.info('Mise à jour ignorée : statut PAM A+1 si annulation FMOB (nécessite %s ou %s)', DF.BO.value[1], DF.FMOB_PAM_SUIVANT.value[1])
self.logger.debug('Administres Pams -------------------------> Success')
self.logger.debug('--------------- Insert time : %d seconds -----------------', time.time() - start_time_insert)
self.logger.info('---------------------- Insert ending ----------------------')
text_response_df = pd.DataFrame(text_response)
if text_response_df.empty:
return Response(text_response_df)
else:
return Response(text_response_df[0])
except (Http404, APIException):
raise
except BaseException:
message = "Impossible d'alimenter le(s) référentiel(s)"
self.logger.exception(message)
raise APIException(message)