Mon commit initial
This commit is contained in:
522
gestion_produit/views.py
Normal file
522
gestion_produit/views.py
Normal file
@@ -0,0 +1,522 @@
|
||||
"""Views pour la gestion des produits."""
|
||||
|
||||
from django.shortcuts import render, redirect
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Sum
|
||||
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.contrib.auth.decorators import login_required
|
||||
|
||||
from django.http import JsonResponse
|
||||
|
||||
from .models import (
|
||||
Categorie,
|
||||
Produit,
|
||||
Demander,
|
||||
Fournisseur,
|
||||
Commander
|
||||
)
|
||||
|
||||
from .forms import (
|
||||
EnregistrementProduit,
|
||||
EnregistrementCategorie,
|
||||
CommanderProduit,
|
||||
DemanderProduit,
|
||||
)
|
||||
|
||||
PRODUIT_NON_A__RENDRE = False
|
||||
PRODUIT_NON_RENDU = False
|
||||
|
||||
|
||||
def gestion_affichage_demande(
|
||||
request,
|
||||
option_validation_chef,
|
||||
ordre_inverse=False
|
||||
):
|
||||
"""Affichez les demandes de produit selon le profil de l'utilisateur.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
option_validation_chef : bool or None
|
||||
Filtre pour la validation par le chef de département.
|
||||
1- True : demandes validées par le chef.
|
||||
2- False : demandes non validées par le chef.
|
||||
3- None : demandes en attentes.
|
||||
ordre_inverse : bool, optional
|
||||
Si True, les demandes sont triées par ordre décroissant,
|
||||
par défaut False.
|
||||
|
||||
Returns
|
||||
-------
|
||||
QuerySet:
|
||||
Ensemble des demandes filtrées selon les critères spécifiés.
|
||||
|
||||
"""
|
||||
mes_demandes = Demander.objects.filter(
|
||||
valider_par_chef=option_validation_chef, user=request.user.profile
|
||||
)
|
||||
demandes_departement = None
|
||||
|
||||
if request.user.profile.chef_departement:
|
||||
demandes_departement = Demander.objects.filter(
|
||||
valider_par_chef=option_validation_chef,
|
||||
user__departement=request.user.profile.departement,
|
||||
)
|
||||
|
||||
if ordre_inverse:
|
||||
return (
|
||||
(mes_demandes | demandes_departement).order_by("-id")
|
||||
if demandes_departement
|
||||
else mes_demandes
|
||||
)
|
||||
return (
|
||||
(mes_demandes | demandes_departement)
|
||||
if demandes_departement
|
||||
else mes_demandes
|
||||
)
|
||||
|
||||
|
||||
@login_required(login_url="login")
|
||||
def index(request):
|
||||
"""Gérer le rendu de la page d'accueil de la gestion des produits.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
|
||||
Returns
|
||||
-------
|
||||
HttpResponse
|
||||
La réponse HTTP contenant la page rendue.
|
||||
|
||||
"""
|
||||
liste_produit = Produit.objects.all().order_by("-id")
|
||||
|
||||
liste_categorie = Categorie.objects.all().order_by("categorie")
|
||||
|
||||
liste_produit_finale = [
|
||||
calcul_stock_produit(produit) for produit in liste_produit
|
||||
]
|
||||
|
||||
pagination = Paginator(liste_produit_finale, 8)
|
||||
|
||||
page_number = request.GET.get("page")
|
||||
page_obj = pagination.get_page(page_number)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"gestion_produit/index.html",
|
||||
{
|
||||
"formulaireEnregistrementCategorie": EnregistrementCategorie,
|
||||
"formulaireEnregistrementProduit": EnregistrementProduit,
|
||||
"formulaireCommanderProduit": CommanderProduit,
|
||||
"formulaireDemanderProduit": DemanderProduit,
|
||||
"mes_demandes": gestion_affichage_demande(
|
||||
request, option_validation_chef=None
|
||||
),
|
||||
"page_obj": page_obj,
|
||||
"liste_categorie": liste_categorie,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def liste_categories(request): # noqa: ARG001
|
||||
"""Récupère et renvoie la liste des catégories de produits au format JSON.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON contenant la liste des catégories de produits.
|
||||
|
||||
"""
|
||||
mes_categories = [
|
||||
{"categorie": categorie.categorie}
|
||||
for categorie in Categorie.objects.all()
|
||||
]
|
||||
|
||||
return JsonResponse(mes_categories, safe=False)
|
||||
|
||||
@login_required(login_url="login")
|
||||
@csrf_exempt
|
||||
def enregistrer_produit(request):
|
||||
"""Enregistre un nouveau produit à partir des données POST.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON indiquant le succès ou l'échec de l'enregistrement.
|
||||
|
||||
"""
|
||||
if request.method == "POST":
|
||||
p = EnregistrementProduit(request.POST, request.FILES)
|
||||
if p.is_valid():
|
||||
p.save()
|
||||
return JsonResponse(
|
||||
{"success": True, "message": "Produit enregistré avec succès"}
|
||||
)
|
||||
return JsonResponse(
|
||||
{
|
||||
"success": False,
|
||||
"message": "L'enregistrement du produit a échoué",
|
||||
}
|
||||
)
|
||||
|
||||
return redirect(index)
|
||||
|
||||
|
||||
@login_required(login_url="login")
|
||||
def enregistrer_commande(request):
|
||||
"""Enregistrez une nouvelle commande de produit."""
|
||||
if request.method == "POST":
|
||||
form = CommanderProduit(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
|
||||
return redirect("gestion_produit:index")
|
||||
|
||||
|
||||
@login_required(login_url="login")
|
||||
def enregistrer_demande(request):
|
||||
"""Enregistrez une nouvelle demande de produit."""
|
||||
if request.method == "POST":
|
||||
form = DemanderProduit(request.POST)
|
||||
if form.is_valid():
|
||||
ma_demande = form.save(commit=False)
|
||||
ma_demande.user = request.user.profile
|
||||
if request.user.profile.chef_departement:
|
||||
ma_demande.valider_par_chef = True
|
||||
|
||||
ma_demande.save()
|
||||
return redirect("gestion_produit:index")
|
||||
|
||||
|
||||
@login_required(login_url="login")
|
||||
def liste_demandes(request):
|
||||
"""Retournez la liste des demandes de produits au format JSON."""
|
||||
liste_demandes = gestion_affichage_demande(
|
||||
request, option_validation_chef=True, ordre_inverse=True
|
||||
)
|
||||
les_demandes = [
|
||||
{
|
||||
"dateDemande": demande.date_de_mise_a_dispo_souhaite,
|
||||
"produit": demande.produit.libelle,
|
||||
"motifs": demande.motifs,
|
||||
"a_rendre": demande.a_rendre,
|
||||
"dateDeMiseADispoSouhaite": demande.date_de_mise_a_dispo_souhaite,
|
||||
"valider_par_chef": demande.valider_par_chef,
|
||||
"valider_par_logisticien": demande.valider_par_logisticien,
|
||||
"motifs_refus": demande.motif_refus,
|
||||
}
|
||||
for demande in liste_demandes
|
||||
]
|
||||
|
||||
return JsonResponse(les_demandes, safe=False)
|
||||
|
||||
@login_required(login_url="login")
|
||||
def detail_demande(request, id_demande):
|
||||
"""Renvoyez les détails d'une demande spécifique de produit."""
|
||||
detail_demande = Demander.objects.get(id=id_demande)
|
||||
|
||||
demande = {
|
||||
# "image": detail_demande.produit.image.url,
|
||||
"detailNom": detail_demande.produit.libelle,
|
||||
"detailCategorie": detail_demande.produit.categorie.categorie,
|
||||
"detailmotif": detail_demande.motifs,
|
||||
"detailDeMiseADispo": detail_demande.date_de_mise_a_dispo_souhaite,
|
||||
"detailARendre": detail_demande.a_rendre,
|
||||
"chef_departement": request.user.profile.chef_departement,
|
||||
}
|
||||
|
||||
return JsonResponse(demande)
|
||||
|
||||
@login_required(login_url="login")
|
||||
@csrf_exempt
|
||||
def update_statut(request):
|
||||
"""Met à jour le statut d'une demande de produit.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
request.id : int
|
||||
L'ID de la demande à mettre à jour.
|
||||
request.action : str
|
||||
L'action à effectuer ('confirmer' ou 'refuser').
|
||||
request.emetteur : str
|
||||
L'émetteur de la demande ('chef' ou 'logisticien').
|
||||
request.motif_refus : str
|
||||
Le motif de refus (si applicable).
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON indiquant le succès ou l'échec de la mise à jour.
|
||||
|
||||
"""
|
||||
if request.method == "POST":
|
||||
produit_id = request.POST.get("id")
|
||||
action = request.POST.get("action")
|
||||
emetteur = request.POST.get("emetteur")
|
||||
motifs = request.POST.get("motif_refus")
|
||||
|
||||
try:
|
||||
demande = Demander.objects.get(id=produit_id)
|
||||
except Demander.DoesNotExist:
|
||||
return JsonResponse(
|
||||
{
|
||||
"success": False,
|
||||
"message": "Demande introuvable"
|
||||
},
|
||||
status=404
|
||||
)
|
||||
|
||||
if action == "1":
|
||||
if emetteur == "chef":
|
||||
demande.valider_par_chef = True
|
||||
elif emetteur == "logisticien":
|
||||
demande.valider_par_logisticien = True
|
||||
elif action == "0":
|
||||
if emetteur == "chef":
|
||||
demande.valider_par_chef = False
|
||||
elif emetteur == "logisticien":
|
||||
demande.valider_par_logisticien = False
|
||||
demande.motif_refus = motifs
|
||||
|
||||
else:
|
||||
return JsonResponse(
|
||||
{"success": False, "message": "Action invalide"}, status=400
|
||||
)
|
||||
|
||||
demande.save()
|
||||
return JsonResponse({"success": True, "message": "Statut mis à jour"})
|
||||
return JsonResponse(
|
||||
{"success": False, "message": "Méthode non autorisée"}, status=405
|
||||
)
|
||||
|
||||
|
||||
@login_required(login_url="login")
|
||||
def recuperer_liste_produit(request):
|
||||
"""Récupèrez et renvoyez la liste des produits paginée.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
|
||||
Returns
|
||||
-------
|
||||
HttpResponse
|
||||
La réponse HTTP contenant la page rendue avec la liste des produits.
|
||||
|
||||
"""
|
||||
liste_produit = Produit.objects.all().order_by("-id")
|
||||
pagination = Paginator(liste_produit, 8)
|
||||
|
||||
page_number = request.GET.get("page")
|
||||
page_obj = pagination.get_page(page_number)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"gestion_produit/index.html",
|
||||
{"page_obj": page_obj}
|
||||
)
|
||||
|
||||
@login_required(login_url="login")
|
||||
@csrf_exempt
|
||||
def enregistrer_categorie(request):
|
||||
"""Enregistrez une nouvelle catégorie de produit.
|
||||
|
||||
Cette vue est appelée via une requête AJAX avec la méthode POST et
|
||||
enregistre une nouvelle.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON indiquant le succès ou l'échec de l'enregistrement.
|
||||
|
||||
"""
|
||||
if request.method == "POST":
|
||||
categories = EnregistrementCategorie(request.POST)
|
||||
if categories.is_valid():
|
||||
categories.save()
|
||||
return JsonResponse({"success": True})
|
||||
return JsonResponse({"success": False})
|
||||
return None
|
||||
|
||||
@login_required(login_url="login")
|
||||
def recuperer_fournisseur_par_categorie(request, id_produit): # noqa: ARG001
|
||||
"""Récupèrez les fournisseurs associés à la catégorie d'un produit donné.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
id_produit : int
|
||||
L'ID du produit dont on veut récupérer les fournisseurs.
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON contenant la liste des fournisseurs associés à la
|
||||
catégorie du produit.
|
||||
|
||||
"""
|
||||
produit = Produit.objects.get(id=id_produit)
|
||||
fournisseur = Fournisseur.objects.filter(categorie=produit.categorie)
|
||||
|
||||
produit_founisseur = [
|
||||
{
|
||||
"id": fournisseur_produit.id,
|
||||
"nom_fournisseur": fournisseur_produit.nom_entreprise,
|
||||
}
|
||||
for fournisseur_produit in fournisseur
|
||||
]
|
||||
|
||||
return JsonResponse(produit_founisseur, safe=False)
|
||||
|
||||
|
||||
# @login_required(login_url="login")
|
||||
def calcul_stock_produit(produit):
|
||||
"""Calculez le stock actuel d'un produit donné.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
produit : Produit
|
||||
L'instance du produit pour lequel calculer le stock.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
Dictionnaire contenant les détails du produit et son stock actuel.
|
||||
|
||||
"""
|
||||
quantite_livrer = (
|
||||
Commander.objects.filter(livrer=True, produit=produit).aggregate(
|
||||
Sum("quantite_commander")
|
||||
)["quantite_commander__sum"]
|
||||
or 0
|
||||
)
|
||||
produit_demander_a_rendre = Demander.objects.filter(
|
||||
produit=produit,
|
||||
valider_par_logisticien=True,
|
||||
)
|
||||
|
||||
quantite_produit_sortis = 0
|
||||
|
||||
for produit_demander in produit_demander_a_rendre:
|
||||
if (
|
||||
(produit_demander.a_rendre and produit_demander.rendu is False)
|
||||
or produit_demander.a_rendre is False
|
||||
):
|
||||
quantite_produit_sortis += produit_demander.quantite
|
||||
|
||||
## Stock actuel = Quantite initiale + total livrer - quantiteSorties
|
||||
stock_actuel = (produit.quantite_stock
|
||||
+ quantite_livrer
|
||||
- quantite_produit_sortis)
|
||||
return {
|
||||
"id": produit.id,
|
||||
"libelle": produit.libelle,
|
||||
"quantite_stock": produit.quantite_stock,
|
||||
"conditionnement": produit.conditionnement,
|
||||
"seuil_pre_rupture": produit.seuil_pre_rupture,
|
||||
"image": produit.image,
|
||||
"categorie_id": produit.categorie_id,
|
||||
"stockActuel": stock_actuel,
|
||||
}
|
||||
|
||||
@login_required(login_url="login")
|
||||
def mouvement_stock(request):
|
||||
"""Rendez la page de mouvement de stock.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
|
||||
Returns
|
||||
-------
|
||||
HttpResponse
|
||||
La réponse HTTP contenant la page rendue.
|
||||
|
||||
"""
|
||||
return render(request, "gestion_produit/mouvement_stock.html")
|
||||
|
||||
@login_required(login_url="login")
|
||||
def rapport_mouvement_stock(request):
|
||||
"""Générez un rapport de mouvement de stock basé sur les filtres donnés.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
request.GET["dateFiltre"] : str
|
||||
La date de filtre au format "YYYY-MM".
|
||||
request.GET["typeFiltre"] : str
|
||||
Le type de filtre ("entree" ou "sortie").
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON contenant le rapport de mouvement de stock.
|
||||
|
||||
"""
|
||||
mes_commandes = []
|
||||
date_filtre = request.GET["dateFiltre"]
|
||||
annee, mois = date_filtre.split("-")
|
||||
type_filtre = request.GET["typeFiltre"]
|
||||
|
||||
if type_filtre == "entree":
|
||||
mes_commandes.extend([
|
||||
{
|
||||
"produit": commande.produit.libelle,
|
||||
"categorie": commande.produit.categorie.categorie,
|
||||
"conditionnement": commande.produit.conditionnement,
|
||||
"fournisseur": commande.fournisseur.nom_entreprise,
|
||||
"date_commande": commande.date_commande,
|
||||
"date_livraison": commande.date_livraison,
|
||||
"quantite_commander": commande.quantite_commander,
|
||||
}
|
||||
for commande in Commander.objects.filter(
|
||||
date_livraison__year=annee,
|
||||
date_livraison__month=mois,
|
||||
livrer=True
|
||||
)
|
||||
])
|
||||
|
||||
elif type_filtre == "sortie":
|
||||
mes_commandes.extend([
|
||||
{
|
||||
"produit": demande.produit.libelle,
|
||||
"categorie": demande.produit.categorie.categorie,
|
||||
"conditionnement": demande.produit.conditionnement,
|
||||
"date_demande": demande.dateDemande,
|
||||
# "date_mise_a_dispo": commande.date_commande,
|
||||
"quantite_demander": demande.quantite,
|
||||
}
|
||||
for demande in Demander.objects.filter(
|
||||
dateDemande__year=annee,
|
||||
dateDemande__month=mois,
|
||||
valider_par_logisticien=True,
|
||||
)
|
||||
])
|
||||
|
||||
return JsonResponse(mes_commandes, safe=False)
|
||||
Reference in New Issue
Block a user