Modification produit

This commit is contained in:
2026-01-21 16:33:01 +00:00
parent 1f523e61b5
commit 76b9422d4c
6 changed files with 202 additions and 11 deletions

View File

@@ -69,18 +69,18 @@
<div class="row p-2 justify-content-around">
{% for produit in page_obj %}
<div class="card p-2 mt-2" style="width: 13rem;">
{% if produit.image %}
<img class="card-img-top m-auto d-block" src="{{ produit.image.url }}" style="width: 160px; height: 120px;" alt="{{ produit.libelle }}">
{% else %}
<img class="card-img-top m-auto d-block" src="https://placehold.co/600x400" style="width: 160px; height: 120px;" alt="Image par défaut">
{% endif %}
<div class="card-body">
<h5 class="card-title text-center">{{ produit.libelle }}</h5>
<div class="col-3">
<div class="card p-2 mt-2" style="width: 13rem;">
{% if produit.image %}
<img class="card-img-top m-auto d-block" src="{{ produit.image.url }}" style="width: 160px; height: 120px;" alt="{{ produit.libelle }}">
{% else %}
<img class="card-img-top m-auto d-block" src="https://placehold.co/600x400" style="width: 160px; height: 120px;" alt="Image par défaut">
{% endif %}
<div class="card-body">
<h5 class="card-title text-center produitModifTitre" style="cursor: pointer;" data-idproduit={{ produit.id }}>{{ produit.libelle }}</h5>
<p class="categorie-produit" style="display: none;">{{ produit.categorie_id }} </p>
{% if user|has_group:"Logisticien" %}
<p class="card-text text-center">
<!-- <small>Soriba SYLLA</small> <br> -->
<small>Quantite en stock: {{ produit.stockActuel }}</small>
</p>
<button class="btn btn-warning d-block listeCommanderButton w-100" data-id="{{ produit.id }}">
@@ -92,7 +92,8 @@
<i class="bi bi-archive"></i>
Demander
</button>
</div>
</div>
</div>
</div>
{% empty %}
<p class="text-center">Aucun produit disponible.</p>
@@ -150,6 +151,54 @@
</div>
</div>
<!-- Modal pour la modification des informations des produits -->
<div class="modal fade" id="modifierProduitModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5" id="modifierProduitTitre">Modifier un produit</h1>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div id="messageZone"></div>
<div class="modal-body">
<form id="modification-produit" data-url="{% url 'gestion_produit:enregistrement_modification_produit' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="hidden" id="modifIdProduit" name="id_produit">
<div class="form-group mb-2">
<label for="" class="form-label">Libellé :</label>
<input type="text" class="form-control" id="modifLibelle" name="libelle">
</div>
<div class="form-group mb-2">
<label for="" class="form-label">Quantité stock :</label>
<input type="number" class="form-control" id="modifQuantiteStock" name="quantite_stock">
</div>
<div class="form-group mb-2">
<label for="" class="form-label">Conditionnement :</label>
<select id="modifCondi" class="form-select" name="conditionnement">
<option value="boite">Boite</option>
<option value="paquet">Paquet</option>
<option value="piece">Pièce</option>
<option value="rouleau">Rouleau</option>
<option value="carton">Carton</option>
</select>
</div>
<div class="form-group mb-2">
<label for="" class="form-label">Seuil de pré-rupture :</label>
<input type="number" class="form-control" id="modifSeuilPreRupture" name="seuil_pre_rupture">
</div>
<div class="form-group mb-2">
<label for="" class="form-label">Catégorie :</label>
<select id="modifCategorie" class="form-select" name="categorie"></select>
</div>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
<button type="submit" class="btn btn-outline-primary">Enregistrer</button>
</form>
</div>
</div>
</div>
</div>
<!-- Modal pour la création des catégories -->
<div class="modal fade" id="enregistrerCategorie" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">

View File

@@ -21,6 +21,16 @@ urlpatterns = [
views.enregistrer_produit,
name="enregistrement_produit"
),
path(
"detailProduit/<int:id_produit>/",
views.detail_produit,
name="detail_produit"
),
path(
"enregistrer-modification-produit",
views.enregistrer_modification_produit,
name="enregistrement_modification_produit"
),
path(
"enregistrerCommande",
views.enregistrer_commande,

View File

@@ -168,7 +168,78 @@ def enregistrer_produit(request):
}
)
return redirect(index)
return redirect("gestion_produit:index")
@login_required(login_url="login")
def detail_produit(request, id_produit):
"""Renvoyez les détails d'un produit spécifique au format JSON.
Parameters
----------
request : HttpRequest
La requête HTTP entrante.
id_produit : int
L'ID du produit dont on veut récupérer les détails.
Returns
-------
JsonResponse
Réponse JSON contenant les détails du produit.
"""
detail_produit = calcul_stock_produit(Produit.objects.get(id=id_produit))
categories = Categorie.objects.all()
produit = {
"detailId": detail_produit["id"],
"detailLibelle": detail_produit["libelle"],
"detailCategorie": detail_produit["categorie_id"],
"detailConditionnement": detail_produit["conditionnement"],
"detailSeuilPreRupture": detail_produit["seuil_pre_rupture"],
"detailQuantiteStock": detail_produit["stockActuel"],
"detailImage": detail_produit["image"].url if detail_produit["image"] else "",
"listeCategorie": [
{"id": categorie.id, "categorie": categorie.categorie}
for categorie in categories
],
}
return JsonResponse(produit)
@login_required(login_url="login")
def enregistrer_modification_produit(request):
"""Enregistrez les modifications apportées au 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":
id_produit = request.POST.get("id_produit")
produit_instance = Produit.objects.get(id=id_produit)
produit_instance.libelle = request.POST.get("libelle")
produit_instance.conditionnement = request.POST.get("conditionnement")
produit_instance.seuil_pre_rupture = request.POST.get("seuil_pre_rupture")
categorie_id = request.POST.get("categorie")
produit_instance.categorie = Categorie.objects.get(id=categorie_id)
produit_instance.quantite_stock = request.POST.get("quantite_stock")
produit_instance.save()
return JsonResponse(
{"success": True, "message": "Produit modifié avec succès"}
)
return redirect("gestion_produit:index")
@login_required(login_url="login")
def enregistrer_commande(request):

View File

@@ -197,6 +197,67 @@ document.addEventListener('DOMContentLoaded', function () {
location.reload()
})
// --------------------------- Modification produit --------------------------
const produitModifTitles = document.querySelectorAll(".produitModifTitre");
const modalModifProduit = new bootstrap.Modal($("modifierProduitModal"));
produitModifTitles.forEach(title => {
title.addEventListener("click", function () {
const idProduit = this.dataset.idproduit;
fetch(`/gestion-produit/detailProduit/${idProduit}/`)
.then(response => response.json())
.then(data => {
$("modifIdProduit").value = data.detailId;
$("modifLibelle").value = data.detailLibelle;
$("modifQuantiteStock").value = data.detailQuantiteStock;
$("modifSeuilPreRupture").value = data.detailSeuilPreRupture;
$("modifCondi").value = data.detailConditionnement;
$("modifCategorie").innerHTML = "";
data.listeCategorie.forEach(categorie => {
const option = document.createElement("option");
option.value = categorie.id;
option.text = categorie.categorie;
if(categorie.id === data.detailCategorie){
option.selected = true;
}
$("modifCategorie").appendChild(option);
});
modalModifProduit.show();
});
});
});
$("modification-produit").addEventListener("submit", function (e) {
e.preventDefault();
const form = this;
const url = this.dataset.url;
const csrf = document.querySelector('[name=csrfmiddlewaretoken]').value;
fetch(url, {
method: "POST",
headers:{
"X-Requested-With": "XMLHttpResponse",
"X-CSRFToken": csrf
},
body: new FormData(form)
})
.then(response => response.json())
.then(data => {
if(data.success){
const messageBox = $("messageZone");
messageBox.innerHTML = `
<div class="alert alert-success">
Produit modifié avec succès
</div>
`;
modalModifProduit.hide();
location.reload();
}
})
})
// --------------------------- Gestion des categories -------------------------
const url_liste_categorie = $("listecategorie").dataset.url;
const tableau_categorie = new Tabulator("#listecategorie", {