Ajout de la liste des contrats d'un employé #73

Open
fatima wants to merge 1 commits from feature/liste-contrats-employe into main
6 changed files with 126 additions and 84 deletions

View File

@@ -29,6 +29,7 @@ tableau_liste_employe.on("rowClick", function (row, rowData) {
const data = rowData.getData(); const data = rowData.getData();
document.getElementById('detail-id').value = data.id; document.getElementById('detail-id').value = data.id;
document.querySelector("#modalContratsEmploye").dataset.employeId = data.id;
document.getElementById('detail-matricule').value = data.matricule; document.getElementById('detail-matricule').value = data.matricule;
document.getElementById('detail-employe').value = data.employe; document.getElementById('detail-employe').value = data.employe;
document.getElementById('detail-fonction').value = data.fonction; document.getElementById('detail-fonction').value = data.fonction;
@@ -270,40 +271,61 @@ const listeContratExpirant = new Tabulator("#listeContratExpirant", {
ajaxURL: $("boutonContratExpirants").dataset.urlexpirants, ajaxURL: $("boutonContratExpirants").dataset.urlexpirants,
}) })
/* let tabContrats = null; let tabContrats = null;
document.getElementById("modalContratsEmploye").addEventListener("show.bs.modal", function () {
const employeId = document.getElementById("detail-id").value;
$("boutonVoirContrats").addEventListener("click", function () {
const employeId = $("detail-id").value;
if (!employeId) { if (!employeId) {
alert("Aucun employé sélectionné"); $("nom-employe-contrat").textContent = "Aucun employé sélectionné.";
return; return;
} }
fetch(`/employé/employe/${employeId}/contrats/`) $("modalContratsEmploye").dataset.employeId = employeId;
const modalDetail = $("modalDetailEmploye");
modalDetail.addEventListener(
"hidden.bs.modal",
() => bootstrap.Modal.getOrCreateInstance($("modalContratsEmploye")).show(),
{once: true}
);
bootstrap.Modal.getOrCreateInstance(modalDetail).hide();
});
$("modalContratsEmploye").addEventListener("shown.bs.modal", function () {
const employeId = this.dataset.employeId;
const urlTemplate = this.dataset.urlTemplate;
const tableElement = $("table-contrats-tabulator");
if (tabContrats) {
tabContrats.destroy();
tabContrats = null;
}
if (!employeId) {
$("nom-employe-contrat").textContent = "Aucun employé sélectionné.";
return;
}
tableElement.replaceChildren();
$("nom-employe-contrat").textContent = "Chargement...";
const url = urlTemplate.replace("123456789", employeId);
fetch(url)
.then(response => { .then(response => {
if (!response.ok) { if (!response.ok) {
throw new Error("Erreur HTTP " + response.status); throw new Error(`Erreur HTTP ${response.status}`);
} }
return response.json(); return response.json();
}) })
.then(data => { .then(data => {
$("nom-employe-contrat").textContent = data.employe;
document.getElementById("nom-employe-contrat").innerText = tabContrats = new Tabulator(tableElement, {
data.employe;
if (tabContrats) {
tabContrats.destroy();
}
tabContrats = new Tabulator(
"#table-contrats-tabulator",
{
data: data.contrats, data: data.contrats,
layout: "fitColumns", layout: "fitColumns",
pagination: true,
paginationSize: 10,
placeholder: "Aucun contrat", placeholder: "Aucun contrat",
columns: [ columns: [
{title: "Numéro", field: "numero_contrat"}, {title: "Numéro", field: "numero_contrat"},
{title: "Type", field: "type_contrat"}, {title: "Type", field: "type_contrat"},
@@ -311,27 +333,24 @@ document.getElementById("modalContratsEmploye").addEventListener("show.bs.modal"
{title: "Date fin", field: "date_fin"}, {title: "Date fin", field: "date_fin"},
{title: "Salaire", field: "salaire_mensuel"}, {title: "Salaire", field: "salaire_mensuel"},
{title: "Statut", field: "statut"}, {title: "Statut", field: "statut"},
{ {
title: "Contrat", title: "Contrat",
field: "fichier", field: "fichier",
formatter: function(cell) { formatter: "link",
const url = cell.getValue(); formatterParams: {target: "_blank"},
},
if (!url) { ],
return "<span class='text-danger'>Aucun fichier</span>"; });
}
return `<a href="${url}" target="_blank" class="btn btn-sm btn-primary">
<i class="bi bi-file-earmark-pdf"></i> Ouvrir
</a>`;
}
}
]
}
);
}) })
.catch(error => { .catch(error => {
console.error("Erreur :", error); console.error("Erreur lors du chargement des contrats :", error);
$("nom-employe-contrat").textContent =
"Impossible de charger les contrats.";
tableElement.textContent =
"Une erreur est survenue lors du chargement des contrats.";
});
});
$("modalContratsEmploye").addEventListener("hidden.bs.modal", function () {
bootstrap.Modal.getOrCreateInstance($("modalDetailEmploye")).show();
}); });
}); */

View File

@@ -58,6 +58,7 @@
{% block 'modal' %} {% block 'modal' %}
{% include "gestion_employe/parts/modalDetailEmploye.html" %} {% include "gestion_employe/parts/modalDetailEmploye.html" %}
{% include "gestion_employe/parts/modalCreationContrat.html" %} {% include "gestion_employe/parts/modalCreationContrat.html" %}
{% include "gestion_employe/parts/modalContratsEmploye.html" %}
{% include "gestion_employe/parts/modalAffectationProjet.html" %} {% include "gestion_employe/parts/modalAffectationProjet.html" %}
{% include "gestion_employe/parts/modalDocument.html" %} {% include "gestion_employe/parts/modalDocument.html" %}
{% include "gestion_employe/parts/modalListeContratExpirants.html" %} {% include "gestion_employe/parts/modalListeContratExpirants.html" %}

View File

@@ -1,4 +1,4 @@
<div class="modal fade" id="modalContratsEmploye" tabindex="-1"> <div class="modal fade" id="modalContratsEmploye" data-url-template="{% url 'gestion_employe:contrats-employe' 123456789 %}" tabindex="-1">
<div class="modal-dialog modal-xl"> <div class="modal-dialog modal-xl">
<div class="modal-content"> <div class="modal-content">
@@ -14,4 +14,3 @@
</div> </div>
</div> </div>
</div> </div>

View File

@@ -97,11 +97,15 @@
<i class="bi bi-file-earmark-text me-2"></i> Liste des Contrats <i class="bi bi-file-earmark-text me-2"></i> Liste des Contrats
</h5> </h5>
{% if user|has_group:"ressource_humaine" %} {% if user|has_group:"ressource_humaine" %}
<div> <div class="d-flex gap-2">
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modalContrat{{ item.employe.id }}"> <button type="button" class="btn btn-outline-primary" id="boutonVoirContrats">
<i class="bi bi-files"></i> Voir tous les contrats
</button>
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modalContrat">
<i class="bi bi-file-earmark-text"></i> Créer contrat <i class="bi bi-file-earmark-text"></i> Créer contrat
</button> </button>
</div> </div>
{% endif %} {% endif %}
</div> </div>
{% csrf_token %} {% csrf_token %}

View File

@@ -90,5 +90,10 @@ urlpatterns = [
"liste-contrat-expirants", "liste-contrat-expirants",
views.liste_contrat_expirants, views.liste_contrat_expirants,
name='liste-contrat-expirants' name='liste-contrat-expirants'
),
path(
"liste-contrats-employe/<int:id_employe>/",
views.liste_contrats_employe,
name="liste-contrats-employe"
) )
] ]

View File

@@ -1,9 +1,8 @@
import json import json
from datetime import datetime, timedelta from datetime import datetime, timedelta
import requests
from dateutil.relativedelta import relativedelta from dateutil.relativedelta import relativedelta
from decouple import config from django.contrib.auth import update_session_auth_hash
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User from django.contrib.auth.models import User
@@ -300,6 +299,8 @@ def creation_contrat(request):
@login_required @login_required
def contrats_employe(request, employe_id): def contrats_employe(request, employe_id):
if not request.user.groups.filter(name="ressource_humaine").exists():
return JsonResponse({"error": "Accès non autorisé"}, status=403)
try: try:
employe = Employe.objects.get(id=employe_id) employe = Employe.objects.get(id=employe_id)
@@ -506,42 +507,55 @@ def supprimer_formation(request, id_formation):
def modifier_mot_passe(request): def modifier_mot_passe(request):
"""Vue pour permettre à un employé de modifier son mot de passe""" """Vue pour permettre à un employé de modifier son mot de passe"""
if request.method == "POST": if request.method == "POST":
username = request.user.username
ancien_mdp = request.POST.get("ancien-mdp") ancien_mdp = request.POST.get("ancien-mdp")
nouveau_mdp = request.POST.get("nouveau-mdp") nouveau_mdp = request.POST.get("nouveau-mdp")
confirmation_mdp = request.POST.get("confirmation-mdp") confirmation_mdp = request.POST.get("confirmation-mdp")
if not request.user.check_password(ancien_mdp):
messages.error(request, "L'ancien mot de passe est incorrect.")
return redirect("gestion_employe:mon-profil")
if nouveau_mdp != confirmation_mdp:
messages.error(request, "Les nouveaux mots de passe ne correspondent pas.")
return redirect("gestion_employe:mon-profil")
try: try:
validate_password(nouveau_mdp, user=request.user) validate_password(nouveau_mdp, user=request.user)
except ValidationError as e: except ValidationError as e:
messages.error(request, f"Erreur : {' '.join(e.messages)}") messages.error(request, f"Erreur : {' '.join(e.messages)}")
return redirect("gestion_employe:mon-profil") return redirect("gestion_employe:mon-profil")
donnees = { request.user.set_password(nouveau_mdp)
"username": username, request.user.save(update_fields=["password"])
"ancien_mdp": ancien_mdp, update_session_auth_hash(request, request.user)
"nouveau_mdp": nouveau_mdp, messages.success(request, "Mot de passe modifié avec succès.")
"confirmation_mdp": confirmation_mdp
}
headers = {
"Content-Type": "application/json",
"Accept": "application/json",
}
response = requests.post(
f"{config('SERVEUR_AUTHENTIFICATION')}modifier-mot-de-passe/",
json=donnees,
headers=headers
)
data = response.json()
cle = next(iter(data.keys()))
valeur = next(iter(data.values()))
if cle == "success":
messages.success(request, valeur)
else:
messages.error(request, valeur)
return redirect("gestion_employe:mon-profil") return redirect("gestion_employe:mon-profil")
def liste_contrats_employe(request, id_employe):
"""Vue pour retourner la liste des contrats d'un employé spécifique"""
try:
employe = Employe.objects.get(id=id_employe)
except Employe.DoesNotExist:
return JsonResponse({"error": "Employé non trouvé"}, status=404)
contrats = Contrat.objects.filter(employe=employe).order_by("-date_debut")
data = [
{
"id": contrat.id,
"numero_contrat": contrat.numero_contrat,
"type_contrat": dict(Contrat.TYPE_CONTRAT).get(contrat.type_contrat),
"date_debut": contrat.date_debut.strftime("%Y-%m-%d"),
"date_fin": contrat.date_fin.strftime("%Y-%m-%d") if contrat.date_fin else "",
"salaire_mensuel": contrat.salaire_mensuel,
"statut": dict(Contrat.STATUT_CONTRAT).get(contrat.statut),
"fichier_contrat": contrat.fichier_contrat.url if contrat.fichier_contrat else "",
}
for contrat in contrats
]
return JsonResponse({
"employe": f"{employe.user.first_name} {employe.user.last_name}",
"contrats": data
})