11 Commits

Author SHA1 Message Date
Fatimac2804
e81c29a586 Affichage des détails de la réservation de salle
All checks were successful
Organisation/sirh/pipeline/head This commit looks good
Organisation/sirh/pipeline/pr-main This commit looks good
SGL/sirh/pipeline/head This commit looks good
2026-09-02 14:43:27 +02:00
Fatimac2804
d28bf85556 Affichage de la liste des departements pour la modification de l'employer
All checks were successful
Organisation/sirh/pipeline/head This commit looks good
Organisation/sirh/pipeline/pr-main This commit looks good
SGL/sirh/pipeline/head This commit looks good
2026-09-02 14:33:51 +02:00
Fatimac2804
3b587d2a1a Affichage des detait de la reservation de salle
All checks were successful
Organisation/sirh/pipeline/head This commit looks good
2026-09-02 13:46:07 +02:00
Fatimac2804
e3f0befff6 Correction sur l'afficha de la liste de departement pour la modification des informations de l'employer
All checks were successful
Organisation/sirh/pipeline/head This commit looks good
2026-09-02 12:48:35 +02:00
Soriba SYLLA
55e5a2819c Ajout du contexte processor
All checks were successful
Organisation/sirh/pipeline/head This commit looks good
2026-08-31 09:48:21 +00:00
Soriba SYLLA
7e28b25497 Merge branch 'staging' 2026-08-23 15:14:24 +00:00
f9ca539670 Supprimer gestion_salle/migrations/0001_initial.py
All checks were successful
Organisation/sirh/pipeline/head This commit looks good
2026-07-14 09:17:13 +00:00
7b4778252f Supprimer gestion_projet/migrations/0001_initial.py
Some checks failed
Organisation/sirh/pipeline/head There was a failure building this commit
2026-07-14 09:17:02 +00:00
2c086187e7 Supprimer gestion_employe/migrations/0001_initial.py
Some checks are pending
Organisation/sirh/pipeline/head Build queued...
2026-07-14 09:16:51 +00:00
5aff49600e Supprimer gestion_conge/migrations/0001_initial.py
Some checks failed
Organisation/sirh/pipeline/head There was a failure building this commit
2026-07-14 09:16:28 +00:00
8c6e59e15a Correction enregistrement profil
Some checks failed
Organisation/sirh/pipeline/head There was a failure building this commit
2026-07-14 09:03:28 +00:00
44 changed files with 116 additions and 73 deletions

View File

@@ -27,7 +27,7 @@ SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=True, cast=bool) DEBUG = config('DEBUG', default=True, cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[]).split(',') ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[]).split(',')
CSRF_TRUSTED_ORIGINS = config("CSRF_TRUSTED_ORIGINS", default=[]).split(",") #CSRF_TRUSTED_ORIGINS = config("CSRF_TRUSTED_ORIGINS", default=[]).split(",")
# Application definition # Application definition
@@ -66,6 +66,7 @@ TEMPLATES = [
'django.template.context_processors.request', 'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth', 'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages', 'django.contrib.messages.context_processors.messages',
'contexte_universel.contexte_universel',
], ],
}, },
}, },
@@ -144,9 +145,9 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# LOGIN_URL = '/client/' # LOGIN_URL = '/client/'
LOGIN_URL = 'simple-sso-login' LOGIN_URL = 'simple-sso-login'
SSO_PRIVATE_KEY = 'D2brFY3LnNDLQBBnvYPXAn185Wi9EpPvnHsUosjEZ9vZMyEtXqkcVfFWkVbN0xpG' SSO_PRIVATE_KEY = config('SSO_PRIVATE_KEY')
SSO_PUBLIC_KEY = 'm9JDP3uGPmGG9ULqPw2BY3ryBNMTGRsuukgIOhk7lIN9lT0wlr2zhoRZiNZ28UCM' SSO_PUBLIC_KEY = config('SSO_PUBLIC_KEY')
SSO_SERVER = 'http://test-authentification.cerfig.org:89/server/' SSO_SERVER = config('SSO_SERVER')
#SSO_LOGOUT_URL = 'http://test-authentification.cerfig.org:89/deconnexion' #SSO_LOGOUT_URL = 'http://test-authentification.cerfig.org:89/deconnexion'
# Configuration de l'email # Configuration de l'email

View File

@@ -10,19 +10,25 @@ class SIRHClient(Client):
def build_user(self, user_data): def build_user(self, user_data):
"""Crée le User et son Profile avec les infos reçues du serveur.""" """Crée le User et son Profile avec les infos reçues du serveur."""
user_data_copy = user_data.copy() user_data_copy = user_data.copy()
user_data.pop("departement")
user_data.pop("chef_departement") print("Un petit test", user_data_copy)
user_data.pop("groups")
user_data.pop("departement", None)
user_data.pop("chef_departement", None)
user_data.pop("groups", None)
user = super().build_user(user_data) user = super().build_user(user_data)
departement = Departement.objects.get_or_create( departement = None
nom=user_data_copy.get("departement", ""))[0]
if "departement" in user_data_copy:
departement = Departement.objects.get_or_create(
nom=user_data_copy.get("departement", ""))[0]
Employe.objects.update_or_create( Employe.objects.update_or_create(
user = user, user = user,
defaults = { defaults = {
"departement": departement, "departement": departement,
"chef": user_data_copy.get("chef_departement", ""), "chef": user_data_copy.get("chef_departement", None),
} }
) )
@@ -30,4 +36,4 @@ class SIRHClient(Client):
group, _ = Group.objects.get_or_create(name=group_name) group, _ = Group.objects.get_or_create(name=group_name)
user.groups.add(group) user.groups.add(group)
return user return user

View File

@@ -1,8 +1,8 @@
<div class="col-1 bg-danger border d-flex flex-column vh-100 pt-5 sticky-top"> <div class="col-1 bg-danger border d-flex flex-column vh-100 pt-5 sticky-top">
<a href="http://test-sirh.cerfig.org:89/" class="text-white text-center fw-bold text-decoration-none mb-4" style="font-size:1.4em"> <a href="{{ SIRH_LIEN }}" class="text-white text-center fw-bold text-decoration-none mb-4" style="font-size:1.4em">
<i class="bi bi-people-fill fs-1 d-block"></i>SIRH <i class="bi bi-people-fill fs-1 d-block"></i>SIRH
</a> </a>
<a href="http://test-sgl.cerfig.org:89/" class="text-white text-center fw-bold text-decoration-none mb-4" style="font-size:1.4em"> <a href="{{ SGL_LIEN }}" class="text-white text-center fw-bold text-decoration-none mb-4" style="font-size:1.4em">
<i class="bi bi-building-gear fs-1 d-block"></i> SGL <i class="bi bi-building-gear fs-1 d-block"></i> SGL
</a> </a>
</div> </div>

View File

@@ -42,7 +42,7 @@
<i class="bi bi-calendar-check"></i> Réservation <i class="bi bi-calendar-check"></i> Réservation
</a> </a>
{% comment %} {% url 'deconnexion' %} {% endcomment %} {% comment %} {% url 'deconnexion' %} {% endcomment %}
<a href="http://test-authentification.cerfig.org:89/deconnexion" class="text-white fw-bold text-decoration-none mb-4" style="font-size: 1.2em;"> <a href="{% url 'deconnexion' %}" class="text-white fw-bold text-decoration-none mb-4" style="font-size: 1.2em;">
<i class="bi bi-box-arrow-right"></i> Déconnexion <i class="bi bi-box-arrow-right"></i> Déconnexion
</a> </a>
</div> </div>

View File

@@ -18,7 +18,7 @@ from django.contrib import admin
from django.urls import include, path from django.urls import include, path
# from django.conf.urls.static import static # from django.conf.urls.static import static
from django.conf import settings from django.conf import settings
from . import views
from .sso import SIRHClient from .sso import SIRHClient
client_sirh = SIRHClient( client_sirh = SIRHClient(
@@ -28,15 +28,15 @@ client_sirh = SIRHClient(
) )
urlpatterns = [ urlpatterns = [
# path('login/', path('login/',
# views.login_view, views.connexion,
# name='login' name='login'
# ), ),
# path( path(
# 'deconnexion/', 'deconnexion/',
# views.deconnexion_view, views.deconnexion,
# name='deconnexion' name='deconnexion'
# ), ),
path( path(
'', '',
include("gestion_employe.urls") include("gestion_employe.urls")
@@ -59,4 +59,4 @@ urlpatterns = [
), ),
path("client/", include(client_sirh.get_urls())), path("client/", include(client_sirh.get_urls())),
] ]
# + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) # + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

View File

@@ -0,0 +1,16 @@
from django.contrib.auth import logout
from django.shortcuts import redirect
from django.urls import reverse_lazy
from django.conf import settings
def connexion(request):
"""Redirige vers le serveur SSO pour l'authentification."""
return redirect(reverse_lazy("simple-sso-login"))
def deconnexion(request):
"""Gérez la déconnexion des utilisateurs."""
logout(request)
#return redirect(settings.SSO_LOGOUT_URL)
return redirect("http://authentification.cerfig.org/login")

7
contexte_universel.py Normal file
View File

@@ -0,0 +1,7 @@
from decouple import config
def contexte_universel(request):
return {
"SIRH_LIEN": config("SIRH_LIEN"),
"SGL_LIEN": config("SGL_LIEN")
}

View File

@@ -7,7 +7,11 @@ QUOTA_CONGE_ANNUEL = 30
NOMBRE_PAGINATION = 8 NOMBRE_PAGINATION = 8
DEBUT_RAPPEL = 60 DEBUT_RAPPEL = 60
DUREE_FIN_CONTRAT = 90 DUREE_FIN_CONTRAT = 90
# EMAIL_ASSISTANTE_DE_DIRECTION = list(Employe.objects.filter(fonction="assistant_direction").values_list('user__email', flat=True))
try:
EMAIL_ASSISTANTE_DE_DIRECTION = list(Employe.objects.filter(fonction="assistant_direction").values_list('user__email', flat=True))
except:
pass
def solde_conge(employe): def solde_conge(employe):
"""Fonction de calcul du solde de congé restant l'employé""" """Fonction de calcul du solde de congé restant l'employé"""

View File

@@ -18,29 +18,34 @@ const tableau_certificat = new Tabulator("#tableau-certificat", {
}) })
const enregistrerProfil = $("enregistrerProfil"); const enregistrerProfil = $("enregistrerProfil");
enregistrerProfil.addEventListener("click", (e) => { // enregistrerProfil.addEventListener("click", (e) => {
const url = $("information-personnelles").dataset.url; // const url = $("information-personnelles").dataset.url;
const csrftoken = document.querySelector("[name='csrfmiddlewaretoken']").value; // const csrftoken = document.querySelector("[name='csrfmiddlewaretoken']").value;
const formData = new FormData(); // const formData = new FormData();
formData.append("nom", $("nom").value); // formData.append("nom", $("nom").value);
formData.append("prenom", $("prenom").value); // formData.append("prenom", $("prenom").value);
formData.append("email", $("email").value); // formData.append("email", $("email").value);
formData.append("telephone", $("telephone").value); // formData.append("telephone", $("telephone").value);
formData.append("adresse", $("adresse").value); // formData.append("adresse", $("adresse").value);
formData.append("sexe", $("sexe").value); // formData.append("sexe", $("sexe").value);
formData.append("date_naissance", $("date_naissance").value); // formData.append("date_naissance", $("date_naissance").value);
fetch(url, {
method: "POST", // console.log("---------------------------------------------")
headers: { // console.log("Données du formulaire:", url);
"X-CSRFToken": csrftoken // console.log("Données du formulaire:", formData);
},
body: formData // fetch(url, {
}) // method: "POST",
.then(response => response.json()) // headers: {
.then(data => alert(data.message)) // "X-CSRFToken": csrftoken
.catch(error => console.error("Erreur:", error)); // },
}); // body: formData
// })
// .then(response => response.json())
// .then(data => alert(data.message))
// .catch(error => console.error("Erreur:", error));
// });

View File

@@ -38,7 +38,7 @@
</h2> </h2>
<div id="collapseProfil" class="accordion-collapse" aria-labelledby="headingContrats" data-bs-parent="#accordionInformationEmploye"> <div id="collapseProfil" class="accordion-collapse" aria-labelledby="headingContrats" data-bs-parent="#accordionInformationEmploye">
<div class="accordion-body"> <div class="accordion-body">
<div class="row" id="information-personnelles" data-url="{% url 'gestion_employe:modifier-employe' %}"> <form class="row" action = "{% url 'gestion_employe:modifier-employe' %}" method = "POST" enctype = "multipart/form-data" id="information-personnelles" data-url="{% url 'gestion_employe:modifier-employe' %}">
{% csrf_token %} {% csrf_token %}
<div class="col"> <div class="col">
<div class="form-group mb-2"> <div class="form-group mb-2">
@@ -50,19 +50,19 @@
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Matricule :</label> <label>Matricule :</label>
<input type="text" class="form-control" id="matricule" value="{{ employe.matricule|default:'' }}" readonly> <input type="text" class="form-control" id="matricule" name = 'matricule' value="{{ employe.matricule|default:'' }}" readonly>
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Nom :</label> <label>Nom :</label>
<input type="text" class="form-control" id="nom" value="{{ employe.user.last_name }}"> <input type="text" class="form-control" id="nom" name = 'nom' value="{{ employe.user.last_name }}">
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Prénom :</label> <label>Prénom :</label>
<input type="text" class="form-control" id="prenom" value="{{ employe.user.first_name }}"> <input type="text" class="form-control" id="prenom" name = 'prenom' value="{{ employe.user.first_name }}">
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Sexe :</label> <label>Sexe :</label>
<select id='sexe' class="form-select"> <select id='sexe' name = 'sexe' class="form-select">
<option value='h' {% if employe.sexe == 'h' %}selected{% endif %}>Homme</option> <option value='h' {% if employe.sexe == 'h' %}selected{% endif %}>Homme</option>
<option value='f' {% if employe.sexe == 'f' %}selected{% endif %}>Femme</option> <option value='f' {% if employe.sexe == 'f' %}selected{% endif %}>Femme</option>
</select> </select>
@@ -72,27 +72,27 @@
<div class="col"> <div class="col">
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Date de naissance :</label> <label>Date de naissance :</label>
<input type="date" class="form-control" id="date_naissance" value="{{ employe.date_naissance|date:'Y-m-d' }}"> <input type="date" class="form-control" id="date_naissance" name = 'date_naissance' value="{{ employe.date_naissance|date:'Y-m-d' }}">
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Département :</label> <label>Département :</label>
<input type="text" class="form-control" id="departement" value="{{ employe.departement.nom|default:'' }}" readonly> <input type="text" class="form-control" id="departement" name = 'departement' value="{{ employe.departement.nom|default:'' }}" readonly>
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Email :</label> <label>Email :</label>
<input type="email" class="form-control" id="email" value="{{ employe.user.email|default:'' }}"> <input type="email" class="form-control" id="email" name = 'email' value="{{ employe.user.email|default:'' }}">
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Téléphone :</label> <label>Téléphone :</label>
<input type="text" class="form-control" id="telephone" value="{{ employe.telephone|default:'' }}"> <input type="text" class="form-control" id="telephone" name = 'telephone' value="{{ employe.telephone|default:'' }}">
</div> </div>
<div class="form-group mb-2"> <div class="form-group mb-2">
<label>Adresse :</label> <label>Adresse :</label>
<input type="text" class="form-control" id="adresse" value="{{ employe.adresse|default:'' }}"> <input type="text" class="form-control" id="adresse" name = 'adresse' value="{{ employe.adresse|default:'' }}">
</div> </div>
</div> </div>
</div> <button type="submit" class="btn btn-success d-block m-auto" id="enregistrerProfil">Enregistrer</button>
<button type="submit" class="btn btn-success d-block m-auto" id="enregistrerProfil">Enregistrer</button> </form>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -20,6 +20,9 @@ from fonction_utilitaire import fonctions_utilitaire
@login_required @login_required
def index(request): def index(request):
"""Vue d'index""" """Vue d'index"""
if not request.user.groups.filter(name="ressource_humaine").exists():
return redirect('gestion_employe:mon-profil')
employes = Employe.objects.all().order_by('-user__date_joined') employes = Employe.objects.all().order_by('-user__date_joined')
nombre_employes = Employe.objects.count() nombre_employes = Employe.objects.count()
nombre_cps = Contrat.objects.filter(type_contrat='contrat_prestation').count() nombre_cps = Contrat.objects.filter(type_contrat='contrat_prestation').count()
@@ -94,7 +97,7 @@ def affecter_employe_projet(request):
elif total_affectation + temps_nouveau > 100: elif total_affectation + temps_nouveau > 100:
messages.warning( messages.warning(
request, request,
f"Les pourcentages d'affectation de l'employé {employe.first_name} {employe.last_name} dépasse 100% sur les différents projets ({total_affectation + temps_nouveau}%)." f"Les pourcentages d'affectation de l'employé {employe.user.first_name} {employe.user.last_name} dépasse 100% sur les différents projets ({total_affectation + temps_nouveau}%)."
) )
return redirect('gestion_employe:index') return redirect('gestion_employe:index')
@@ -191,25 +194,26 @@ def modifier_employer(request):
except Employe.DoesNotExist: except Employe.DoesNotExist:
return JsonResponse({"message": "Employé non trouvé."}) return JsonResponse({"message": "Employé non trouvé."})
if request.method == "POST": if request.method == "POST":
data = json.loads(request.body)
user = User.objects.get(username=request.user) user = User.objects.get(username=request.user)
user.last_name = data['nom'] user.last_name = request.POST['nom']
user.first_name = data['prenom'] user.first_name = request.POST['prenom']
user.email = data['email'] user.email = request.POST['email']
employe.telephone = data['telephone'] employe.telephone = request.POST['telephone']
employe.adresse = data['adresse'] employe.adresse = request.POST['adresse']
employe.sexe = data['sexe'] employe.sexe = request.POST['sexe']
if request.FILES.get("photo"): if request.FILES.get("photo"):
employe.photo = request.FILES["photo"] employe.photo = request.FILES["photo"]
if data['date_naissance']: if request.POST['date_naissance']:
difference = relativedelta(timezone.now().date(), datetime.strptime(data['date_naissance'], "%Y-%m-%d").date()) difference = relativedelta(timezone.now().date(), datetime.strptime(request.POST['date_naissance'], "%Y-%m-%d").date())
if difference.years >= 18: if difference.years >= 18:
employe.date_naissance = data['date_naissance'] employe.date_naissance = request.POST['date_naissance']
else: else:
return JsonResponse({"message": "Veuillez entrez une date de naissance correcte."}) messages.error(request, "Veuillez entrez une date de naissance correcte.")
employe.save() employe.save()
user.save() user.save()
return JsonResponse({"message": "Profil mis à jour avec succès."}) messages.success(request, "Profil mis à jour avec succès.")
return redirect("gestion_employe:mon-profil")
def enregistrement_document(request): def enregistrement_document(request):
"""Vue pour permettre à un utilisateur de télécharger et enregistrer des documents liés à son profil""" """Vue pour permettre à un utilisateur de télécharger et enregistrer des documents liés à son profil"""