From a8b5ac27d9b710d1b27a0027eb86fc65b2c0abca Mon Sep 17 00:00:00 2001 From: Soriba SYLLA Date: Fri, 18 Sep 2026 11:03:52 +0000 Subject: [PATCH] Fix: Filtre des produits --- Jenkinsfile | 51 ----------- SGL/templates/parts/menu_application.html | 3 + .../__pycache__/models.cpython-310.pyc | Bin 4600 -> 4600 bytes .../__pycache__/urls.cpython-310.pyc | Bin 1569 -> 1779 bytes .../__pycache__/views.cpython-310.pyc | Bin 14477 -> 16254 bytes .../templates/gestion_produit/index.html | 46 +++++----- gestion_produit/urls.py | 10 +++ gestion_produit/views.py | 69 ++++++++++++++- static/js/gestion_produit.js | 79 +++++++++++++----- 9 files changed, 162 insertions(+), 96 deletions(-) delete mode 100644 Jenkinsfile diff --git a/Jenkinsfile b/Jenkinsfile deleted file mode 100644 index ee9f705..0000000 --- a/Jenkinsfile +++ /dev/null @@ -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 - ''' - } - } - } -} \ No newline at end of file diff --git a/SGL/templates/parts/menu_application.html b/SGL/templates/parts/menu_application.html index 1868637..bd72bcb 100644 --- a/SGL/templates/parts/menu_application.html +++ b/SGL/templates/parts/menu_application.html @@ -15,6 +15,9 @@ + diff --git a/gestion_produit/__pycache__/models.cpython-310.pyc b/gestion_produit/__pycache__/models.cpython-310.pyc index 0b38abe764d3df44df2bd58f8a1b86c8e4c4dc12..8b85b9927a606bad2a4822e8d8b834cd5faa0037 100644 GIT binary patch delta 19 ZcmeyN{6m>5pO=@50SIhaH*&ob1OPTl1keBg delta 19 ZcmeyN{6m>5pO=@50SI!LHgdfa1OPW%1pNR2 diff --git a/gestion_produit/__pycache__/urls.cpython-310.pyc b/gestion_produit/__pycache__/urls.cpython-310.pyc index 012669b6d824742dafa93b6c99eae32a59b8c4d8..03f22ba7cd06b315353ec1da343ce935d9a6476a 100644 GIT binary patch delta 308 zcmZ3;^O;vCpO=@50SLB9tU>d4WlB*iQ z)b#wK%v61w%)An-%#?Vzh@Ji|S*VtHsFrx37KDN-3Al+slk)O&VJ7R}5{GL9Y5>Z_ z7jQx>_0yEte3UtW(YOfYm0MyEbzpPB${?z4ahDe56eO0Eq!#5BuVg6F0IDt0n5@kj T#JFX09qYo$=UGLVIMxFIl$&BM delta 113 zcmey&yO2jGpO=@50SJ!yPtE$m&cN^(#6bqaK#l_t7yn|IsPly@oj*!6MIo3$Q*pB! z;|wNdKTWaCX)FPZVz;#X}|@6K8z zt?L7$0ZS+sUkL;%_+x(PHs&fS(Sg*cn}_S}2V zJ@?#mzI*P>PX6cc4SzbsVHeK*26DXv_M#>7<^Tw z21fqg%I~0VD^1l2b`m^5Fi0@O@2lQCd=H8DB4~bgAIU<0B}ra_8iJxp)TE%YCW3K- zJ_2%sIS@1_TSc81X(gZ;z z0Yk98iIioIjWA;@lU_)bU7{O_Xi_&=BdG~kLsEp_RlgnX~xn6W<;H`1XAmeMn(g+i2tMx)k8x$zV;jgVo5n2~fpm3rFP--?RdRc5(y z+z`Y3*|MtjMkpRFo-&cjFzlMl81c9f8WW3P$I>DkR&U|v1}}e9E9I9O-3>zLqulbv z+dQ5SJ{qvy6vHf?&kB5hp))luO-p-2GcXM?319lh-NzjGI`MU}D#DnO1YLSrij~CF zm|Mq~%)%+pyreshm(0nN7>k^fJ%r|LPhV=>Oj{(rg_za!^Qr z(Mcp?zK>~3SEHavve)^C6AHfol!Nmx<=_457s5TVkWcBs$XgG_P4WjkAbXYHN`352 zY>wi<)#n;2_hUDvOFD%_*5!Gb60FNl%B;+iV~$hKd1*#YmXI8C;fUiZ*^$~sWLJ>v zie4hfzCq1A{(o#wrVTbq7`iQ#wwPceF|yB~LB6+TWyQk&|Bv2Tp|ePD zoVdVi+kvtm9}=!SZaz-uWn{!0O(n6WCezmhiO&8a|Jf`y*kOXB1jH96a#F+=?E9)f zmUh7wkMqy#*b**yFOpWYTb>M87f4f5RPC1NBMRbm9P$=fV6T%)Zx9HVmIzaQ<0U^K zSE&^G11gk)U-lqhJj(B-rR)Un2~_4kZvGY&x^&p>R0|?56n9heVFV2{SsXcg1vxQ> z1t@8z(|CJOKmS>)292xXbxH)4LFQfIe!S9N3`e{@WI`th^AExg)m$MzO0n%P4}c=e zF6Hl1m7UIqBbNd1R<*Tzy}04%e(BZJqH``PL*YAv%u#t@!ofX!vNgPU0^7C=OR1i* z)yYgWX_=N$C?~}=1}6<&GaavqF#oc3TK3BMp|&}Y*{l5fTN-_vkPvAig=Ymjo3Cqs z&9VII6~4@qv6KAMj>hoYC}KG1!^~Fc+v0}TJ&qc@X5%!R;m0;!yrE5To#*)Zh8l%Y zK&SZ8&L{jLB21JTm348o>j?DmH@iAKmr$i&gI=wLf6?{Rp3T@~TL=aS3<8rNMvx%b zM?h7B9V9qJKo_7W9qa^2rwN(~&JtYWW!+7%hj({xD_3jPklg42b(P$XBntT9Kbr2L AWB>pF delta 1477 zcmZvcUrbw77{K{%q4dvMYAG$HE6YF%hXNL8QA^mfFA z!Tgixn47Dg(Fe1{EWRw0hvgTx^bHL}*X0S56$+aL^}$vz3gIOp@=Lxxa$tFZ@|R8g_d!$37=JikNBVKU7UCJ7nB3Boj<@+M}F zkT@p5oct)sQoorbJHbbI#)y_wKprB@6OIw+8r&qnYI!TkS$ypE!W5c)v#=o2TnkIj zGL*R*>N(PryW=EDKjeZ>puIT(IXv3@buXPK8C1;KLO!3mE>RXw=(ctF4Zc{q-v z{z+KGtNy=5K|X4^5M!h!lUO3DK=2UG2~_O)f}Wc{&9(Vbai>+4dR4>Cc#~*WIxr5S z_+{V-EaPS%Aoy?KMkCddnJZRR)8}%FsY0H=g}3*Qx9moe^^xI<6sdqs!C^Qr`?HE# z@Bpmh)1jboBe-P>${J9&E9SYZo+~U>ELvXEb*;p?j^7*%Hc^{$*FXdnl_=_Sda1}K z@z;Y_U3;1q#g(>@o$}&3;TUeT`CMxxUL?pHoyVWrF2E&Ys(lS+!?fK)=p_sYFzYkT zr%~fULMSH3`Z5@P)j#9ADau>iCpMjK7nl{L&irJb zg_n(nfnPuj($?Th{j$AO+$6Jb`8?%R$!Ab~ROIs{VT$kuo{V-w0pE=_g{0E1&Ht#2 znlSt}x}tm!Mm$!AS_a}>|1i|<_=~ParM5Nj>&DZe&rN$LO}hJpVqU?Gc)JCKC{zDA z9;~C(+whCW@uRf>Y+pN6Ddu$MBEDHL&8!$e`_> z*h(=-vTnRP@_1sHj1Lh~1eLHr$PpF^%Y;?JCBi!4GNDZ9BwQ!l!|l -
+
{% for produit in page_obj %}
-
- {% if produit.image %} - {{ produit.libelle }} - {% else %} - Image par défaut - {% endif %} -
-
{{ produit.libelle }}
- - {% if user|has_group:"logistique" %} -

- Quantite en stock: {{ produit.stockActuel }} -

- +
+ {% if produit.image %} + {{ produit.libelle }} + {% else %} + Image par défaut {% endif %} - -
-
+
+
{{ produit.libelle }}
+ + {% if user|has_group:"logistique" %} +

+ Quantite en stock: {{ produit.stockActuel }} +

+ + {% endif %} + +
+
{% empty %}

Aucun produit disponible.

diff --git a/gestion_produit/urls.py b/gestion_produit/urls.py index ac8d6c6..1f34f6b 100644 --- a/gestion_produit/urls.py +++ b/gestion_produit/urls.py @@ -81,4 +81,14 @@ urlpatterns = [ views.detail_demande, name="detail_demande" ), + path( + "filtrer-produit-par-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" + ), ] diff --git a/gestion_produit/views.py b/gestion_produit/views.py index b491173..f1a9663 100644 --- a/gestion_produit/views.py +++ b/gestion_produit/views.py @@ -172,7 +172,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 +422,73 @@ 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 == "": + produits = Produit.objects.all() + else: + produits = Produit.objects.filter(libelle__icontains=nom_produit) + 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é. diff --git a/static/js/gestion_produit.js b/static/js/gestion_produit.js index 7eecfe7..c8f1c97 100644 --- a/static/js/gestion_produit.js +++ b/static/js/gestion_produit.js @@ -84,15 +84,34 @@ 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'; - } + + fetch(`/gestion-produit/filtrer-par-nom-produit/?nom=${filter}`) + .then(response => response.json()) + .then(data => { + const cardContainer = document.querySelector("#cardContainer"); + cardContainer.innerHTML = ""; + data.forEach(produit => { + cardContainer.innerHTML += ` +
+
+ ${produit.libelle} +
+
${produit.libelle}
+ + ${produit.appartient_logistique ? `

+ Quantite en stock: ${produit.stockActuel} +

` : ""} + ${produit.appartient_logistique ? `` : ""} + +
+
+
`; }); + }) }) // Enregistrement de commande @@ -138,21 +157,41 @@ 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 = ""; - }); + location.reload(); }else{ - card.forEach(carte => { - categorie = carte.querySelector(".categorie-produit").textContent.toLowerCase(); - if(parseInt(categorie) === parseInt(filtre)){ - carte.style.display = ""; - }else{ - carte.style.display = 'none' - } - }); + fetch(`/gestion-produit/filtrer-produit-par-categorie/${filtre}/`) + .then(response => response.json()) + .then(data => { + console.log(data); + const cardContainer = document.querySelector("#cardContainer"); + cardContainer.innerHTML = ""; + data.forEach(produit => { + cardContainer.innerHTML += ` +
+
+ ${produit.libelle} +
+
${produit.libelle}
+ +

+ Quantite en stock: ${produit.stockActuel} +

+ ${produit.appartient_logistique ? `` : ""} + ${produit.appartient_logistique ? `` : ""} + +
+
+
`; + }); + }) } })