Fix: Integration de la pagination dans le filtre de produit
This commit is contained in:
51
Jenkinsfile
vendored
51
Jenkinsfile
vendored
@@ -1,51 +0,0 @@
|
||||
pipeline
|
||||
{
|
||||
agent any
|
||||
options {
|
||||
skipDefaultCheckout(true)
|
||||
}
|
||||
|
||||
environment
|
||||
{
|
||||
SUDO_PASSWORD = credentials('sudo-password')
|
||||
}
|
||||
|
||||
stages
|
||||
{
|
||||
stage ( 'checkout' )
|
||||
{
|
||||
steps
|
||||
{
|
||||
sh 'echo "Debut du pipeline"'
|
||||
cleanWs()
|
||||
checkout scm
|
||||
}
|
||||
}
|
||||
stage ( 'Deploiement' )
|
||||
{
|
||||
when { branch 'main' }
|
||||
steps {
|
||||
sh '''
|
||||
cd /var/www/sgl
|
||||
echo $SUDO_PASSWORD | sudo -S chown -R jenkins:jenkins /var/www/sgl
|
||||
|
||||
git fetch origin main
|
||||
git reset --hard origin/main
|
||||
|
||||
python3 -m venv venv
|
||||
. venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
|
||||
python manage.py makemigrations
|
||||
python manage.py migrate
|
||||
echo $SUDO_PASSWORD | sudo -S rm -r staticfiles
|
||||
python manage.py collectstatic --noinput
|
||||
|
||||
echo $SUDO_PASSWORD | sudo -S chown -R www-data:www-data /var/www/sgl
|
||||
echo "Deploiement reussi"
|
||||
echo $SUDO_PASSWORD | sudo -S supervisorctl restart sgl
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,9 @@
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" aria-current="page" href="{{ LIEN_SGL }}">SGL</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" aria-current="page" href="#">Laboratoire</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -54,46 +54,49 @@
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col">
|
||||
<input type="text" placeholder="Rechercher par libellé" class="form-control" id="searchInput">
|
||||
</div>
|
||||
<div class="col">
|
||||
<select name="" id="filterCategorie" class="form-select">
|
||||
<option value="">Filtre par catégorie</option>
|
||||
{% for categorie in liste_categorie %}
|
||||
<option value="{{ categorie.id }}">{{ categorie.categorie }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<form class="col d-flex flex-column flex-lg-row justify-content-between" id="searchForm" method="get" action="{% url 'gestion_produit:index' %}">
|
||||
<div class="col">
|
||||
<input type="text" id="searchInput" placeholder="Rechercher par libellé" class="form-control" name="search" value="{{ request.GET.search }}">
|
||||
</div>
|
||||
<div class="col">
|
||||
<select id="filterCategorie" name="filterCategorie" class="form-select">
|
||||
<option value="">Filtre par catégorie</option>
|
||||
{% for categorie in liste_categorie %}
|
||||
<option value="{{ categorie.id }}" {% if request.GET.filterCategorie == categorie.id|stringformat:"s" %}selected{% endif %}>{{ categorie.categorie }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<div class="col mt-2 mt-lg-0">
|
||||
<button type="submit" class="btn btn-primary"><i class="bi bi-search"></i> Rechercher</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="row p-2 justify-content-around">
|
||||
<div class="row p-2 justify-content-around" id = "cardContainer">
|
||||
{% for produit in page_obj %}
|
||||
<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:"logistique" %}
|
||||
<p class="card-text text-center">
|
||||
<small>Quantite en stock: {{ produit.stockActuel }}</small>
|
||||
</p>
|
||||
<button class="btn btn-warning d-block listeCommanderButton w-100" data-id="{{ produit.id }}">
|
||||
<i class="bi bi-caret-down-square-fill"></i>
|
||||
Commander
|
||||
</button>
|
||||
<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 %}
|
||||
<button class="btn btn-primary d-block w-100 listeDemandeButton mt-1" data-id="{{ produit.id }}">
|
||||
<i class="bi bi-archive"></i>
|
||||
Demander
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<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:"logistique" %}
|
||||
<p class="card-text text-center">
|
||||
<small>Quantite en stock: {{ produit.stockActuel }}</small>
|
||||
</p>
|
||||
<button class="btn btn-warning d-block listeCommanderButton w-100" data-id="{{ produit.id }}">
|
||||
<i class="bi bi-caret-down-square-fill"></i>Commander
|
||||
</button>
|
||||
{% endif %}
|
||||
<button class="btn btn-primary d-block w-100 listeDemandeButton mt-1" data-id="{{ produit.id }}">
|
||||
<i class="bi bi-archive"></i>Demander
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="text-center">Aucun produit disponible.</p>
|
||||
|
||||
@@ -81,4 +81,14 @@ urlpatterns = [
|
||||
views.detail_demande,
|
||||
name="detail_demande"
|
||||
),
|
||||
path(
|
||||
"filtrer-produit-par-categorie/<int:id_categorie>/",
|
||||
views.filtrer_produit_par_categorie,
|
||||
name="filtrer_produit_par_categorie"
|
||||
),
|
||||
path(
|
||||
"filtrer-par-nom-produit/",
|
||||
views.filtre_par_nom_produit,
|
||||
name="filtrer_par_nom_produit"
|
||||
),
|
||||
]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from django.shortcuts import render, redirect
|
||||
from django.core.paginator import Paginator
|
||||
from django.db.models import Sum
|
||||
from django.db.models import Sum, Q
|
||||
from authentification.models import Profile
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
@@ -90,9 +90,25 @@ def index(request):
|
||||
La réponse HTTP contenant la page rendue.
|
||||
|
||||
"""
|
||||
liste_produit = Produit.objects.all().order_by("-id")
|
||||
product_name = request.GET.get("search", "")
|
||||
categorie_name = request.GET.get("filterCategorie", "")
|
||||
liste_categorie = Categorie.objects.all().order_by("categorie")
|
||||
|
||||
if product_name == "" and categorie_name == "":
|
||||
liste_produit = Produit.objects.all().order_by("-id")
|
||||
elif product_name != "" and categorie_name == "":
|
||||
liste_produit = Produit.objects.filter(
|
||||
Q(libelle__icontains=product_name)
|
||||
).order_by("-id")
|
||||
elif product_name == "" and categorie_name != "":
|
||||
liste_produit = Produit.objects.filter(
|
||||
Q(categorie=categorie_name)
|
||||
).order_by("-id")
|
||||
else:
|
||||
liste_produit = Produit.objects.filter(
|
||||
Q(categorie=categorie_name) & Q(libelle__icontains=product_name)
|
||||
).order_by("-id")
|
||||
|
||||
liste_produit_finale = [
|
||||
calcul_stock_produit(produit) for produit in liste_produit
|
||||
]
|
||||
@@ -172,7 +188,7 @@ def enregistrer_produit(request):
|
||||
return redirect("gestion_produit:index")
|
||||
|
||||
@login_required
|
||||
def detail_produit(request, id_produit):
|
||||
def detail_produit(_request, id_produit):
|
||||
"""Renvoyez les détails d'un produit spécifique au format JSON.
|
||||
|
||||
Parameters
|
||||
@@ -422,6 +438,102 @@ def enregistrer_categorie(request):
|
||||
return JsonResponse({"success": False})
|
||||
return None
|
||||
|
||||
def filtrer_produit_par_categorie(request, id_categorie):
|
||||
"""Filtrez les produits par catégorie et renvoyez-les au format JSON.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
id_categorie : int
|
||||
L'ID de la catégorie pour laquelle filtrer les produits.
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON contenant la liste des produits filtrés par catégorie.
|
||||
|
||||
"""
|
||||
produits = Produit.objects.filter(categorie_id=id_categorie)
|
||||
produits_filtres = [
|
||||
{
|
||||
"id": produit.id,
|
||||
"libelle": produit.libelle,
|
||||
"conditionnement": produit.conditionnement,
|
||||
"quantite_stock": produit.quantite_stock,
|
||||
"seuil_pre_rupture": produit.seuil_pre_rupture,
|
||||
"image": produit.image.url if produit.image else "",
|
||||
"appartient_logistique": request.user.groups.filter(name="Logistique").exists(),
|
||||
|
||||
}
|
||||
for produit in produits
|
||||
]
|
||||
return JsonResponse(produits_filtres, safe=False)
|
||||
|
||||
def filtre_par_nom_produit(request):
|
||||
"""Filtrez les produits par nom et renvoyez-les au format JSON.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
request : HttpRequest
|
||||
La requête HTTP entrante.
|
||||
nom_produit : str
|
||||
Le nom du produit pour lequel filtrer les produits.
|
||||
|
||||
Returns
|
||||
-------
|
||||
JsonResponse
|
||||
Réponse JSON contenant la liste des produits filtrés par nom.
|
||||
|
||||
"""
|
||||
nom_produit = request.GET.get("nom", "")
|
||||
if nom_produit == "":
|
||||
liste_produit = Produit.objects.all().order_by("-id")
|
||||
else:
|
||||
liste_produit = Produit.objects.filter(libelle__icontains=nom_produit).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, 1)
|
||||
|
||||
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,
|
||||
},
|
||||
)
|
||||
# -----------------------------------------------------------
|
||||
# produits_filtres = [
|
||||
# {
|
||||
# "id": produit.id,
|
||||
# "libelle": produit.libelle,
|
||||
# "conditionnement": produit.conditionnement,
|
||||
# "quantite_stock": produit.quantite_stock,
|
||||
# "seuil_pre_rupture": produit.seuil_pre_rupture,
|
||||
# "image": produit.image.url if produit.image else "",
|
||||
# "appartient_logistique": request.user.groups.filter(name="Logistique").exists(),
|
||||
# }
|
||||
# for produit in produits
|
||||
# ]
|
||||
# return JsonResponse(produits_filtres, safe=False)
|
||||
|
||||
@login_required
|
||||
def recuperer_fournisseur_par_categorie(_request, id_produit):
|
||||
"""Récupèrez les fournisseurs associés à la catégorie d'un produit donné.
|
||||
|
||||
@@ -82,17 +82,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
})
|
||||
|
||||
// --------------------------- FILTRE PAR NOM DU PRODUIT -------------------------
|
||||
$('searchInput').addEventListener('keyup', function() {
|
||||
const filter = this.value.toLowerCase();
|
||||
const cards = document.querySelectorAll('.card');
|
||||
cards.forEach(card => {
|
||||
const title = card.querySelector('.card-title').textContent.toLowerCase();
|
||||
if (title.includes(filter)) {
|
||||
card.style.display = '';
|
||||
} else {
|
||||
card.style.display = 'none';
|
||||
}
|
||||
});
|
||||
$('searchInput').addEventListener('submit', function() {
|
||||
$('searchForm').submit();
|
||||
})
|
||||
|
||||
// Enregistrement de commande
|
||||
@@ -138,22 +129,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// Filtre des produits par categorie
|
||||
$("filterCategorie").addEventListener("change", function(){
|
||||
const card = document.querySelectorAll(".card");
|
||||
const filtre = this.value;
|
||||
if(filtre === ""){
|
||||
card.forEach(carte => {
|
||||
carte.style.display = "";
|
||||
});
|
||||
}else{
|
||||
card.forEach(carte => {
|
||||
categorie = carte.querySelector(".categorie-produit").textContent.toLowerCase();
|
||||
if(parseInt(categorie) === parseInt(filtre)){
|
||||
carte.style.display = "";
|
||||
}else{
|
||||
carte.style.display = 'none'
|
||||
}
|
||||
});
|
||||
}
|
||||
$('searchForm').submit();
|
||||
})
|
||||
|
||||
// Enregistrement de nouveau produit
|
||||
|
||||
Reference in New Issue
Block a user