from django.db.transaction import atomic from django.shortcuts import get_object_or_404 from django.utils import timezone from rest_framework import status from rest_framework.permissions import IsAuthenticated from rest_framework.request import Request from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet import datetime from ..models import Administre, Decision, DecisionChoices, Notation, Poste from ..serializers.decision import CreateDecisionSerializer, DecisionSerializer from ..utils.decorators import class_logger from .commun import (GestionnairePermission, api_exception, execution_time_viewset, query_count_viewset) @class_logger @execution_time_viewset @query_count_viewset class DecisionView(ModelViewSet): """ Cette classe est dédiée au vue des decisions. """ permission_classes = [IsAuthenticated, GestionnairePermission] serializer_class = DecisionSerializer queryset = Decision.objects.all() def get_serializer_class(self): """ Renvoie un serializer particulier pour la création """ if self.action == 'create': return CreateDecisionSerializer return self.serializer_class def list(self, request: Request, pk=None) -> Response: """Cette fonction envoie les informations du poste lié à l'administre dans une décision avec le score de l'administre et inversement. TODO: rajouter la possibilité d'envoyer les informations du poste lié à l'administré selon l'année du PAM dans lequel on se situe :type request: rest_framework.request.Request :param request: Request contenant l'administre ou le poste. :return: - **res_decision** (*Response*): Json contenant le classement. """ decision = [] q = 'poste' administre_id = None poste_id = None if 'pam_annee' in request.query_params: annee_pam = request.query_params['pam_annee'] else : annee_pam = None if 'administre_id' in request.query_params: administre_id = request.query_params['administre_id'] administre_pam_id = str(administre_id) + str(annee_pam) administres_keys = ( 'poste__p_id', 'poste__p_nf', 'poste__p_domaine', 'poste__p_filiere', 'poste__p_eip', #'poste__p_avis', TODO : Change p_avis to postesPAM 'poste__formation_emploi__fe_code', 'poste__competences', 'poste__p_notes_gestionnaire', 'poste__p_liste_id_marques', 'poste__formation_emploi__fe_libelle', 'poste__formation_emploi__fe_garnison_lieu', 'poste__p_dep', 'poste__p_code_fonction', 'poste__p_fonction', 'de_decision', 'de_date_decision', 'de_notes_gestionnaire') decision = Decision.objects.filter(administre_pam_id = administre_pam_id).select_related('poste') decision = list(decision.values(*administres_keys)) if 'poste_id' in request.query_params: q = "administre" poste_id = request.query_params['poste_id'] poste_pam_id = poste_id + str(annee_pam) postes_keys = ( 'administre__a_id_sap', 'administre__a_nom', 'administre__a_prenom', 'administre__administre__a_statut_pam_annee', 'administre__a_fonction', 'administre__a_code_fonction', 'administre__a_liste_id_competences', 'administre__grade_id', 'administre__a_liste_id_marques', 'de_decision', 'de_date_decision', 'de_notes_gestionnaire', 'administre__a_notes_gestionnaire', 'administre__a_liste_id_competences', 'administre__decision__poste_id') decision = Decision.objects.filter(poste_pam_id = poste_pam_id).select_related('administre') decision = list(decision.values(*postes_keys)) res_decision = [] if len(decision) > 0: for k in range(len(decision)): decision_unit = decision[k] try: administre_id = decision_unit.administre_id except: administre_id = None try: poste_id = decision_unit.poste_id except: poste_id = None try: res_decision_unit = {q: {}, 'no_score_administre': Notation.objects.get( administre_id=administre_id, poste_id=poste_id, pam_id = annee_pam).no_score_administre} except: res_decision_unit = {q: {}, 'no_score_administre': None} for key in decision_unit: if (q + "__") in key: res_decision_unit[q][key.replace(q + '__', '')] = decision_unit[key] else: res_decision_unit[key] = decision_unit[key] # Ajout du relevé des décisions sur le poste (cas q = "poste") if q == "poste": res_decision_unit[q]['p_nb_prepositionne'] = Decision.objects.filter( de_decision=DecisionChoices.PREPOSITIONNE).count() res_decision_unit[q]['p_nb_positionne'] = Decision.objects.filter( de_decision=DecisionChoices.POSITIONNE).count() res_decision_unit[q]['p_nb_omi_active'] = Decision.objects.filter( de_decision=DecisionChoices.OMI_ACTIVE).count() res_decision_unit[q]['p_nb_omi_en_cours'] = Decision.objects.filter( de_decision=DecisionChoices.OMI_EN_COURS).count() res_decision.append(res_decision_unit) return Response(res_decision) @atomic def perform_create(self, serializer) -> None: """Cette fonction crée une decision à partir de données validées """ data = serializer.validated_data annee_pam = self.request.query_params['pam__in'] administre_id = data.get('administre_id') administre_id_pam = str(administre_id) + annee_pam poste_id = data.get('poste_id') poste_id_pam = poste_id + annee_pam de_decision = data.get('de_decision') delete_former = data.get('delete_former') a = get_object_or_404(Administre, pk=administre_id) p = get_object_or_404(Poste, pk=poste_id) self.check_object_permissions(self.request, a) self.check_object_permissions(self.request, p) qs_former = Decision.objects.filter(pk=administre_id) if delete_former: qs_former.delete() elif qs_former.exists(): raise api_exception(status.HTTP_400_BAD_REQUEST, "une décision existe déjà pour cet administré") Decision.objects.create(administre_id=administre_id, poste_id=poste_id, de_decision=de_decision, de_date_decision=timezone.now(), administre_pam_id=administre_id_pam, poste_pam_id=poste_id_pam ) def perform_update(self, serializer) -> None: """ Met à jour la décision à partir de données validées. La date est mise à jour en même temps que le statut """ data = serializer.validated_data if hasattr(data, Decision.Cols.STATUT): setattr(data, Decision.Cols.DATE, timezone.now()) super().perform_update(serializer)