SGL avec une premiere implementation de SSO

This commit is contained in:
2026-08-03 14:31:48 +00:00
parent 76b9422d4c
commit 1e477287da
358 changed files with 798 additions and 745 deletions

9
.gitignore vendored
View File

@@ -1,4 +1,11 @@
.ruff_cache/
.coverage
db.sqlite3
__pycache__/*.pyc
db.sqlite3
venv/
media/
staticfiles/
.env
migrations/
*.pyc
db.sqlite3

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -12,6 +12,7 @@ https://docs.djangoproject.com/en/5.2/ref/settings/
from pathlib import Path
from os.path import join
from decouple import config
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -21,13 +22,12 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-3mmf81^pt+k6-^dj$n2&*kvf6m09n5i%*+ajv70(ynaxifj5fg"
SECRET_KEY = config("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
DEBUG = config("DEBUG", cast=bool)
ALLOWED_HOSTS = config("ALLOWED_HOSTS", default=[]).split(",")
# Application definition
@@ -44,6 +44,18 @@ INSTALLED_APPS = [
"authentification",
]
# LOGIN_URL = '/client/'
LOGIN_URL = 'simple-sso-login'
SIMPLE_SSO_SECRET = config("SIMPLE_SSO_SECRET")
SIMPLE_SSO_KEY = config("SIMPLE_SSO_KEY")
SIMPLE_SSO_SERVER = config("SIMPLE_SSO_SERVER")
#SSO_LOGOUT_URL =
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
@@ -52,6 +64,8 @@ MIDDLEWARE = [
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
#'simple_sso.sso_client.middleware.PostAuthenticationMiddleware',
]
ROOT_URLCONF = "SGL.urls"
@@ -78,13 +92,16 @@ WSGI_APPLICATION = "SGL.wsgi.application"
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': config("DB_NAME"),
'USER': config("DB_USER"),
'PASSWORD': config("DB_PASSWORD"),
'HOST': config("DB_HOST"),
'PORT': config("DB_PORT", default=3306, cast=int),
}
}
# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
@@ -134,14 +151,12 @@ MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
# Gestion de l'envoi des mails
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "ssl0.ovh.net"
EMAIL_PORT = 465
EMAIL_USE_SSL = False
EMAIL_USE_TLS = False
EMAIL_HOST_USER = "support.it@cerfig.org"
EMAIL_HOST_PASSWORD = "Cerfig2025"
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
EMAIL_TIMEOUT = 10
# ALLOWED_HOSTS = ['support.cerfig.org', '41.223.50.187', 'localhost', '127.0.0.1']
# EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
# EMAIL_HOST = "ssl0.ovh.net"
# EMAIL_PORT = 465
# EMAIL_USE_SSL = False
# EMAIL_USE_TLS = False
# EMAIL_HOST_USER = "support.it@cerfig.org"
# EMAIL_HOST_PASSWORD = "Cerfig2025"
# DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
# EMAIL_TIMEOUT = 10

Binary file not shown.

34
SGL/sso.py Normal file
View File

@@ -0,0 +1,34 @@
# SGL/sso.py
from authentification.models import Profile, Departement
from simple_sso.sso_client.client import Client
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group
User = get_user_model()
class SGLClient(Client):
def build_user(self, user_data):
"""Crée le User et son Profile avec les infos reçues du serveur."""
user_data_copy = user_data.copy()
user_data.pop("departement")
user_data.pop("chef_departement")
user_data.pop("groups")
user = super().build_user(user_data)
departement = Departement.objects.get_or_create(
nom_departement=user_data_copy.get("departement", "")
)[0]
Profile.objects.update_or_create(
user=user,
defaults={
"departement": departement,
"chef_departement": user_data_copy.get("chef_departement", ""),
}
)
for group_name in user_data_copy.get("groups", []):
group, _ = Group.objects.get_or_create(name=group_name)
user.groups.add(group)
return user

View File

@@ -14,95 +14,11 @@
</head>
<body>
<div class="container-fluid">
<div class="row vh-100">
<div class="col-3 bg-danger d-none d-lg-flex flex-column">
{% if user|has_group:"Administration" %}
<a href="{% url 'index' %}" class="btn btn-danger py-3 mt-4 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-file-bar-graph d-block" style="width: 50px;"></i>
Tableau de bord
</a>
{% endif %}
{% if user|has_group:"Employe" %}
<a href="{% url 'gestion_produit:index' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-backpack4 d-block" style="width: 50px;"></i>
Gestion des produits
</a>
{% endif %}
{% if user|has_group:"Administration" %}
<a href="{% url 'gestion_fournisseur:index' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-truck d-block" style="width: 50px;"></i>
Gestion des fournisseurs
</a>
{% endif %}
{% if user|has_group:"Employe" %}
<a href="{% url 'gestion_vehicule:index' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-car-front-fill d-block" style="width: 50px;"></i>
Gestion des véhicules
</a>
{% endif %}
<a href="{% url 'authentification:deconnexion' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-person-dash d-block" style="width: 50px;"></i>
Deconnexion
</a>
</div>
<div class="col-12 col-lg-9" style="overflow-y: auto;">
<!-- --------------------------------------------------- Navigation mobile -->
<nav class="navbar navbar-danger bg-danger d-lg-none">
<div class="container-fluid">
<a class="navbar-brand" href="#">CERFIG</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<!-- <a class="navbar-brand" href="#">Hidden brand</a> -->
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
{% if user|has_group:"Administration" %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" aria-current="page" href="{% url 'index' %}">
<i class="bi bi-backpack4 d-block" style="width: 50px;"></i>
Tableau de bord
</a>
</li>
{% endif %}
{% if user|has_group:"Employe" %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'gestion_produit:index' %}">
<i class="bi bi-backpack4 d-block" style="width: 50px;"></i>
Gestion des produits
</a>
</li>
{% endif %}
{% if user|has_group:"Administration" %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'gestion_fournisseur:index' %}" tabindex="-1" aria-disabled="true">
<i class="bi bi-truck d-block" style="width: 50px;"></i>
Gestion des fournisseurs
</a>
</li>
{% endif %}
{% if user|has_group:"Employe" %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'gestion_vehicule:index' %}" tabindex="-1" aria-disabled="true">
<i class="bi bi-truck d-block" style="width: 50px;"></i>
Gestion des véhicules
</a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'authentification:deconnexion' %}" tabindex="-1" aria-disabled="true">
<i class="bi bi-person-dash d-block" style="width: 50px;"></i>
Deconnexion
</a>
</li>
</ul>
</div>
</div>
</nav>
<!-- ------------------------------------------------------ -->
<div class="row flex-nowrap">
{% include "parts/menu_application.html" %}
{% include "parts/navigation-ordinateur.html" %}
{% comment %} {% include "parts/navigation-mobile.html" %} {% endcomment %}
<div class="col">
{% block "contenu" %} {% endblock %}
</div>
</div>

View File

@@ -44,161 +44,10 @@
</div>
</div>
<!-- ------------- Modal pour la liste des demandes en cours ---------------------- -->
<div class="modal fade" id="listeDemandesModal" tabindex="-1" aria-labelledby="listeDemandesModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="listeDemandesModalLabel">Demande de produit</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="">
<div class="mb-3">
<label for="produit" class="form-label">Demandeur :</label>
<input type="text" class="form-control" id="demandeur" readonly>
</div>
<div class="mb-3">
<label for="produit" class="form-label">Produit</label>
<input type="text" class="form-control" id="produit" readonly>
</div>
<div class="mb-3">
<label for="quantite" class="form-label">Quantité</label>
<input type="number" class="form-control" id="quantite" readonly>
</div>
<div class="mb-3">
<label for="motifs" class="form-label">Motifs</label>
<textarea class="form-control" id="motifs" rows="3" readonly></textarea>
</div>
<div class="mb-3">
<label for="date_demande" class="form-label">Date de mise à disposition souhaitée :</label>
<input type="date" class="form-control" id="date_demande" readonly>
</div>
<div class="mb-3">
<label for="a_rendre" class="form-label">À rendre ?</label>
<input type="checkbox" class="form-check-input" id="a_rendre" disabled>
</div>
<div class="mb-3">
<label for="">Valider par le supérieur hiérarchique</label>
<input type="checkbox" class="form-check-input" id="valider_par_chef" disabled>
</div>
<hr>
<h6 class="text-center">Décision de la logistique</h6>
<div class="d-flex justify-content-around mb-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="radioDefault" id="radioValider">
<label class="form-check-label" for="radioValider">
Valider la demande
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="radioDefault" id="radioRefuser" data-url="{% url 'gestion_produit:update-demande' %}">
<label class="form-check-label" for="radioRefuser">
Refuser la demande
</label>
</div>
</div>
<div class="mb-3 d-none" id="box-motif-refus">
<label for="motifs_refus" class="form-label">Motifs de refus</label>
<textarea class="form-control" id="motifs_refus" rows="3"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="enregistrerModifs">Enregistrer les modifications</button>
</div>
</div>
</div>
</div>
<!-- ------------- Modal pour la liste des commandes en cours ---------------------- -->
<div class="modal fade" id="listeCommandesModal" tabindex="-1" aria-labelledby="listeCommandesModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="listeCommandesModalLabel">Commande de produit</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="">
{% csrf_token %}
<div class="mb-3">
<label for="produit" class="form-label">Produit</label>
<input type="text" class="form-control" id="produitCommande" readonly>
</div>
<div class="mb-3">
<label for="quantite" class="form-label">Fournisseur :</label>
<input type="text" class="form-control" id="fournisseur" readonly>
</div>
<div class="mb-3">
<label for="motifs" class="form-label">Quantité</label>
<input class="form-control" id="quantiteCommande" readonly></input>
</div>
<div class="mb-3">
<label for="date_commande" class="form-label">Date de commande</label>
<input type="date" class="form-control" id="date_commande" readonly>
</div>
<div class="mb-3">
<label for="date_livraison" class="form-label">Date de Livraison</label>
<input type="date" class="form-control" id="date_livraison" readonly>
</div>
<hr>
<h6 class="text-center">Confirmation de la livraison du produit</h6>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="produit_livre">
<label class="form-check-label" for="produit_livre">Le produit a été livré</label>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="enregistrerModifsCommande" data-url="{% url 'enregistrer_livraison_produit' %}">Enregistrer les modifications</button>
</div>
</div>
</div>
</div>
<!-- ------------------------------------- Modal pour stock en rupture ------------------------------ -->
<div class="modal fade" id="produitRuptureModal" tabindex="-1" aria-labelledby="produitRuptureModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="produitRuptureModalLabel">Produit en rupture</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="tableau-produit-rupture" data-url="{% url 'listeProduitRupture' %}"></div>
</div>
</div>
</div>
</div>
<!-- ----------------------------------- Modal équipement à rendre -------------------------------- -->
<div class="modal fade" id="aRendreModal" tabindex="-1" aria-labelledby="aRendreModalLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="aRendreModalLabel">
Equipement à rendre
</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="tableau-equipement-rendre" data-url="{% url 'equipement-a-rendre' %}"></div>
</div>
{% if user|has_group:"Logisticien" %}
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="equipementARendreEnregistrer" data-url="{% url 'update-equipement-a-rendre' %}">Enregistrer</button>
</div>
{% endif %}
</div>
</div>
</div>
{% include "parts/modal_stock_rupture.html" %}-
{% include "parts/modal_liste_demandes.html" %}-
{% include "parts/modal_liste_commandes.html" %}-
{% include "parts/modal_equipement_a_rendre.html" %}
{% endblock %}

View File

@@ -0,0 +1,8 @@
<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">
<i class="bi bi-people-fill fs-1 d-block"></i>SIRH
</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">
<i class="bi bi-building-gear fs-1 d-block"></i> SGL
</a>
</div>

View File

@@ -0,0 +1,22 @@
<!-- ----------------------------------- Modal équipement à rendre -------------------------------- -->
<div class="modal fade" id="aRendreModal" tabindex="-1" aria-labelledby="aRendreModalLabel">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="aRendreModalLabel">
Equipement à rendre
</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="tableau-equipement-rendre" data-url="{% url 'equipement-a-rendre' %}"></div>
</div>
{% if user|has_group:"logistique" %}
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="equipementARendreEnregistrer" data-url="{% url 'update-equipement-a-rendre' %}">Enregistrer</button>
</div>
{% endif %}
</div>
</div>
</div>

View File

@@ -0,0 +1,47 @@
<!-- ------------- Modal pour la liste des commandes en cours ---------------------- -->
<div class="modal fade" id="listeCommandesModal" tabindex="-1" aria-labelledby="listeCommandesModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="listeCommandesModalLabel">Commande de produit</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="">
{% csrf_token %}
<div class="mb-3">
<label for="produit" class="form-label">Produit</label>
<input type="text" class="form-control" id="produitCommande" readonly>
</div>
<div class="mb-3">
<label for="quantite" class="form-label">Fournisseur :</label>
<input type="text" class="form-control" id="fournisseur" readonly>
</div>
<div class="mb-3">
<label for="motifs" class="form-label">Quantité</label>
<input class="form-control" id="quantiteCommande" readonly></input>
</div>
<div class="mb-3">
<label for="date_commande" class="form-label">Date de commande</label>
<input type="date" class="form-control" id="date_commande" readonly>
</div>
<div class="mb-3">
<label for="date_livraison" class="form-label">Date de Livraison</label>
<input type="date" class="form-control" id="date_livraison" readonly>
</div>
<hr>
<h6 class="text-center">Confirmation de la livraison du produit</h6>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" role="switch" id="produit_livre">
<label class="form-check-label" for="produit_livre">Le produit a été livré</label>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="enregistrerModifsCommande" data-url="{% url 'enregistrer_livraison_produit' %}">Enregistrer les modifications</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,68 @@
<!-- ------------- Modal pour la liste des demandes en cours ---------------------- -->
<div class="modal fade" id="listeDemandesModal" tabindex="-1" aria-labelledby="listeDemandesModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="listeDemandesModalLabel">Demande de produit</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="">
<div class="mb-3">
<label for="produit" class="form-label">Demandeur :</label>
<input type="text" class="form-control" id="demandeur" readonly>
</div>
<div class="mb-3">
<label for="produit" class="form-label">Produit</label>
<input type="text" class="form-control" id="produit" readonly>
</div>
<div class="mb-3">
<label for="quantite" class="form-label">Quantité</label>
<input type="number" class="form-control" id="quantite" readonly>
</div>
<div class="mb-3">
<label for="motifs" class="form-label">Motifs</label>
<textarea class="form-control" id="motifs" rows="3" readonly></textarea>
</div>
<div class="mb-3">
<label for="date_demande" class="form-label">Date de mise à disposition souhaitée :</label>
<input type="date" class="form-control" id="date_demande" readonly>
</div>
<div class="mb-3">
<label for="a_rendre" class="form-label">À rendre ?</label>
<input type="checkbox" class="form-check-input" id="a_rendre" disabled>
</div>
<div class="mb-3">
<label for="">Valider par le supérieur hiérarchique</label>
<input type="checkbox" class="form-check-input" id="valider_par_chef" disabled>
</div>
<hr>
<h6 class="text-center">Décision de la logistique</h6>
<div class="d-flex justify-content-around mb-3">
<div class="form-check">
<input class="form-check-input" type="radio" name="radioDefault" id="radioValider">
<label class="form-check-label" for="radioValider">
Valider la demande
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="radioDefault" id="radioRefuser" data-url="{% url 'gestion_produit:update-demande' %}">
<label class="form-check-label" for="radioRefuser">
Refuser la demande
</label>
</div>
</div>
<div class="mb-3 d-none" id="box-motif-refus">
<label for="motifs_refus" class="form-label">Motifs de refus</label>
<textarea class="form-control" id="motifs_refus" rows="3"></textarea>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="button" class="btn btn-primary" id="enregistrerModifs">Enregistrer les modifications</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,15 @@
<!-- ------------------------------------- Modal pour stock en rupture ------------------------------ -->
<div class="modal fade" id="produitRuptureModal" tabindex="-1" aria-labelledby="produitRuptureModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="produitRuptureModalLabel">Produit en rupture</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div id="tableau-produit-rupture" data-url="{% url 'listeProduitRupture' %}"></div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,51 @@
{% load tags_personnaliser %}
<div class="col-12 col-lg-9" style="overflow-y: auto;">
<nav class="navbar navbar-danger bg-danger d-lg-none">
<div class="container-fluid">
<a class="navbar-brand" href="#">CERFIG</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<!-- <a class="navbar-brand" href="#">Hidden brand</a> -->
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
{% if user|has_group:"Administration" %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" aria-current="page" href="{% url 'index' %}">
<i class="bi bi-backpack4 d-block" style="width: 50px;"></i>
Tableau de bord
</a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'gestion_produit:index' %}">
<i class="bi bi-backpack4 d-block" style="width: 50px;"></i>
Gestion des produits
</a>
</li>
{% if user|has_group:"Administration" %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'gestion_fournisseur:index' %}" tabindex="-1" aria-disabled="true">
<i class="bi bi-truck d-block" style="width: 50px;"></i>
Gestion des fournisseurs
</a>
</li>
{% endif %}
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'gestion_vehicule:index' %}" tabindex="-1" aria-disabled="true">
<i class="bi bi-truck d-block" style="width: 50px;"></i>
Gestion des véhicules
</a>
</li>
<li class="nav-item">
<a class="nav-link d-flex text-white fw-bold" href="{% url 'authentification:deconnexion' %}" tabindex="-1" aria-disabled="true">
<i class="bi bi-person-dash d-block" style="width: 50px;"></i>
Deconnexion
</a>
</li>
</ul>
</div>
</div>
</nav>
</div>

View File

@@ -0,0 +1,31 @@
{% load tags_personnaliser %}
<div class="col-3 bg-danger d-none d-lg-flex flex-column">
{% if user|has_group:"ressource_humaine" or user|has_group:"direction" %}
<a href="{% url 'index' %}" class="btn btn-danger py-3 mt-4 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-file-bar-graph d-block" style="width: 50px;"></i>
Tableau de bord
</a>
{% endif %}
<a href="{% url 'gestion_produit:index' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-backpack4 d-block" style="width: 50px;"></i>
Gestion des produits
</a>
{% if user|has_group:"ressource_humaine" or user|has_group:"direction" or user|has_group:"logistique" %}
<a href="{% url 'gestion_fournisseur:index' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-truck d-block" style="width: 50px;"></i>
Gestion des fournisseurs
</a>
{% endif %}
<a href="{% url 'gestion_vehicule:index' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-car-front-fill d-block" style="width: 50px;"></i>
Gestion des véhicules
</a>
<a href="{% url 'authentification:deconnexion' %}" class="btn btn-danger py-3 mt-1 fw-bold d-flex" style="font-size: 1.2em;">
<i class="bi bi-person-dash d-block" style="width: 50px;"></i>
Deconnexion
</a>
</div>

View File

@@ -21,10 +21,18 @@ from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
# from simple_sso.sso_client.client import Client
from .sso import SGLClient
from . import views
my_client_1 = SGLClient(
settings.SIMPLE_SSO_SERVER,
settings.SIMPLE_SSO_KEY,
settings.SIMPLE_SSO_SECRET
)
urlpatterns = [
path(
"",
@@ -81,4 +89,6 @@ urlpatterns = [
views.produit_a_rendre_update,
name="update-equipement-a-rendre",
),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
path("client/", include(my_client_1.get_urls())),
]
# + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Binary file not shown.

View File

@@ -6,14 +6,12 @@ Principales fonctionnalités couvertes :
3- Affichage des demandes en cours et validations des dites demandes.
"""
import json
from django.shortcuts import render, redirect
from django.http import JsonResponse
from gestion_produit.models import Commander, Demander, Produit
# from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.decorators import login_required
import json
from gestion_produit.views import calcul_stock_produit
@@ -53,7 +51,7 @@ def dashboard_quantite_produit():
}
@login_required(login_url="authentification:login")
@login_required
def index(request):
"""Retournez la page d'accueil du dashboard.
@@ -68,10 +66,10 @@ def index(request):
La réponse HTTP contenant la page d'accueil du dashboard.
"""
if request.user.groups.filter(name="Chauffeur").exists():
if request.user.groups.filter(name="chauffeur").exists():
return redirect("gestion_vehicule:index")
if not request.user.groups.filter(name="Administration").exists():
if not request.user.groups.filter(name="direction").exists():
return redirect("gestion_produit:index")
commandes_en_cours = Commander.objects.filter(livrer=False)
@@ -97,7 +95,7 @@ def index(request):
},
)
@login_required(login_url="login")
@login_required
def produit_a_rendre(_request):
"""Retournez la liste des équipements à rendre.
@@ -132,7 +130,7 @@ def produit_a_rendre(_request):
return JsonResponse(liste_equipement, safe=False)
@login_required(login_url="login")
@login_required
def produit_a_rendre_update(request):
"""Mettez à jour le statut des équipements à rendre.
@@ -165,7 +163,7 @@ def produit_a_rendre_update(request):
{"status": "success", "message": "Produits mis à jour"}
)
@login_required(login_url="login")
@login_required
def liste_produit_rupture(request):
"""Vue pour obtenir la liste des produits en fonction de leur type.
@@ -202,7 +200,7 @@ def liste_produit_rupture(request):
return JsonResponse(donnees_charger, safe=False)
@login_required(login_url="login")
@login_required
def liste_produit_commander(request):
"""Listez des produits commandés non encore livrés.
@@ -238,7 +236,7 @@ def liste_produit_commander(request):
return JsonResponse(ma_liste_commandes, safe=False)
@login_required(login_url="login")
@login_required
def enregistrer_livraison_produit(request):
"""Enregistrez la livraison d'un produit commandé.
@@ -280,7 +278,7 @@ def enregistrer_livraison_produit(request):
)
@login_required(login_url="login")
@login_required
def liste_demandes(request):
"""Listez des demandes en cours de validation.

Binary file not shown.

Binary file not shown.

View File

@@ -3,8 +3,6 @@
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Departement(models.Model):
"""Modèle représentant un département."""
@@ -14,7 +12,6 @@ class Departement(models.Model):
"""Retourne une représentation en chaîne de caractères du dép."""
return self.nom_departement
class Profile(models.Model):
"""Modèle représentant le profil utilisateur.

View File

@@ -5,7 +5,6 @@ la gestion de l'accès des utilisateurs aux différentes pages.
"""
from django import template
# from authentification.models import Profile
register = template.Library()
@@ -13,24 +12,3 @@ register = template.Library()
def has_group(user, group_name):
"""Vérifiez si un utilisateur appartient à un groupe spécifique."""
return user.groups.filter(name=group_name).exists()
# On recupère l'utilisateur et le produit
## Si l'utilisateur n'est pas le chef d'un département, afficher simplement ses
# demandes
## Si l'utilisateur est un chef de département
### Afficher la liste de ses demandes
### Verifier pour chaque demande que l'utilisateur appartient à son departement
#### Si oui, afficher le produit
#### Si non, ne pas afficher le produit
# @register.filter
# def affichage_demande(user, demande):
# if user.profile.chef_departement:
# chef_profile = Profile.objects.get(id=user.profile)
# departement = chef_profile.departement
# ids_profils_departement = Profile.objects.filter(departement=departement)["id"]
# return demande.user_id in ids_profils_departement
# return user.profile.id == demande.user_id

View File

@@ -1,32 +1,18 @@
"""Vues pour l'authentification des utilisateurs."""
from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.contrib.auth import logout
from django.shortcuts import redirect
from django.urls import reverse_lazy
from SGL.views import index
from django.conf import settings
def connexion(request):
"""Gérez la connexion des utilisateurs."""
if request.method == "POST":
username = request.POST["username"]
password = request.POST["password"]
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect(index)
messages.error(request, "Nom d'utilisateur ou mot de passe incorrect.")
return render(
request,
"authentification/login.html",
)
"""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("authentification:login")
return redirect(settings.SSO_LOGOUT_URL)

View File

@@ -9,7 +9,7 @@
<div class="row p-2">
<div class="col d-flex justify-content-between">
<h3>LISTE DES FOURNISSEURS </h3>
{% if user|has_group:"Logisticien" %}
{% if user|has_group:"logistique" %}
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#enregistrerFournisseur">
<i class="bi bi-person-plus-fill"></i>
Ajouter un fournisseur
@@ -35,27 +35,8 @@
<!-- Conteneur pour le tableau d'affichage de la liste des fournisseurs utilisé par tabulatorjs -->
<div id="liste_fournisseur" data-url="{% url 'gestion_fournisseur:liste_fournisseur' %}"></div>
<!-- Modal d'enregistrement d'un nouveau fournisseur -->
<div class="modal fade" id="enregistrerFournisseur" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="informationFournisseurModalLabel">Information sur le fournisseur</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="{% url 'gestion_fournisseur:index' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="submit" class="btn btn-primary">Enregistrer</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% include "gestion_fournisseur/parts/modal_enregistrement_nouveau_fournisseur.html" %}
{% endblock %}
{% block "js" %}

View File

@@ -0,0 +1,21 @@
<!-- Modal d'enregistrement d'un nouveau fournisseur -->
<div class="modal fade" id="enregistrerFournisseur" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="informationFournisseurModalLabel">Information sur le fournisseur</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="{% url 'gestion_fournisseur:index' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="submit" class="btn btn-primary">Enregistrer</button>
</div>
</form>
</div>
</div>
</div>
</div>

View File

@@ -1,3 +1,13 @@
from django.contrib import admin # noqa: F401
from .models import Categorie, Produit
# Register your models here.
@admin.register(Categorie)
class CategorieAdmin(admin.ModelAdmin):
list_display = ('categorie',)
search_fields = ('categorie',)
@admin.register(Produit)
class ProduitAdmin(admin.ModelAdmin):
list_display = ('libelle', 'quantite_stock', 'conditionnement', 'seuil_pre_rupture', 'categorie')
list_filter = ('categorie', 'conditionnement')
search_fields = ('libelle',)

Some files were not shown because too many files have changed in this diff Show More