2021-11-28 12:43:05 +01:00
# Tkinter
2021-11-28 12:06:41 +01:00
from tkinter import IntVar , Checkbutton , LabelFrame , PhotoImage , Scrollbar , Listbox , Entry , Button , Label , Frame , Tk , Toplevel
2021-11-28 11:48:31 +01:00
from tkinter . ttk import Combobox
2021-11-28 12:06:41 +01:00
from tkinter . messagebox import showerror , showinfo , showwarning , askyesno
2021-11-28 12:28:03 +01:00
from tkinter . filedialog import askopenfile
2021-11-28 12:43:05 +01:00
# Regex
2021-11-19 11:41:37 +01:00
from re import sub
2021-11-28 14:36:28 +01:00
# Date
from datetime import date
2021-11-19 11:41:37 +01:00
2021-11-28 12:43:05 +01:00
# Import des fichiers pour gérer la base de donnée
from users import Utilisateurs
2021-11-24 17:53:17 +01:00
from stock import Stock
2021-11-18 20:41:58 +01:00
class GesMag :
2021-11-19 18:52:58 +01:00
""" Programme de Gestion d ' une caise de magasin. """
2021-11-28 12:43:05 +01:00
def __init__ ( self , presentation : bool = False ) - > None :
2021-11-19 21:37:48 +01:00
""" Instancie quelques variables pour plus de clareté. """
2021-11-28 12:43:05 +01:00
Utilisateurs ( ) . creationTable ( presentation ) # on créer la table utilisateurs si elle n'existe pas déjà
Stock ( ) . creationTable ( presentation ) # on créer la table du stock si elle n'existe pas déjà
2021-11-20 00:11:59 +01:00
self . parent = Tk ( ) # fenêtre affiché à l'utilisateur
self . parent . resizable ( False , False ) # empêche la fenêtre d'être redimensionnée
self . f = Frame ( self . parent ) # `Frame` affiché à l'écran
2021-11-25 23:21:36 +01:00
self . imagesStock = [ ] # liste qui va contenir nos images pour l'affichage du stock
2021-11-28 12:28:03 +01:00
self . dossierImage = PhotoImage ( file = " img/dossier.gif " ) # image pour l'icone de selection
2021-11-28 14:36:28 +01:00
self . panier = [ ] # liste des éléments "dans le panier"
2021-11-19 21:37:48 +01:00
2021-11-18 20:41:58 +01:00
def demarrer ( self ) - > None :
""" Lance le programme GesMag. """
2021-11-19 11:41:37 +01:00
self . font = ( " Comfortaa " , 14 ) # police par défaut
self . _interfaceConnexion ( ) # on créer la variable `self.f` qui est la frame a affiché
self . f . grid ( ) # on affiche la frame
2021-11-19 00:47:01 +01:00
2021-11-19 11:41:37 +01:00
self . parent . mainloop ( ) # on affiche la fenêtre
2021-11-19 00:47:01 +01:00
2021-11-19 11:41:37 +01:00
def motDePasseCorrect ( self , motDPasse : str ) - > tuple :
""" Détermine si un mot de passe suit la politique du programme ou non. """
if len ( motDPasse ) == 0 : # si le champs est vide
return ( False , " Mot de passe incorrect. " )
if len ( motDPasse ) < 8 : # si le mot de passe est plus petit que 8 caractères
return ( False , " Un mot de passe doit faire 8 caractères minimum. " )
"""
2021-11-20 19:47:13 +01:00
- Pour le regex , la fonction ` sub ` élimine tout ce qui est donné en fonction
du pattern renseigné , alors si la fonction ` sub ` renvoie pas exactement
la même chaîne de charactère alors c ' est qu ' il y avait un charactère interdit .
- J ' utilises pas `match` parce que je suis plus à l ' aise avec ` sub ` .
2021-11-19 11:41:37 +01:00
"""
if not sub ( r " [A-Z] " , ' ' , motDPasse ) != motDPasse :
return ( False , " Un mot de passe doit au moins contenir une lettre majuscule. " )
if not sub ( r " [a-z] " , ' ' , motDPasse ) != motDPasse :
return ( False , " Un mot de passe doit au moins contenir une lettre minuscule. " )
if not sub ( r " *?[^ \ w \ s]+ " , ' ' , motDPasse ) != motDPasse :
return ( False , " Un mot de passe doit au moins contenir un caractère spécial. " )
return ( True , ) # si aucun des tests précédents n'est valide, alors le mot de passe est valide
2021-11-18 20:41:58 +01:00
2021-11-20 19:47:13 +01:00
def utilisateurCorrect ( self , utilisateur : str ) - > tuple :
""" Détermine si un nom d ' utilisateur suit la politique du programme ou non. """
"""
Pour le nom d ' utilisateur on vérifie si le champs n ' est pas vide
et si il y a bien que des lettres et des chiffres .
"""
if len ( utilisateur ) == 0 :
return ( False , " Utilisateur incorrect. " )
if sub ( r " *?[^ \ w \ s]+ " , ' ' , utilisateur ) != utilisateur :
return ( False , " Un nom d ' utilisateur ne doit pas contenir de caractère spécial. " )
return ( True , )
2021-11-21 02:29:24 +01:00
def nomCorrect ( self , nom : str ) - > bool :
""" Détermine si un nom suit la politique du programme ou non. """
if len ( nom ) == 0 :
return False
if sub ( r " *?[^ \ w \ s]+ " , ' ' , nom ) != nom : # pas de caractères spéciaux dans un nom
return False
return True
def prenomCorrect ( self , prenom : str ) - > bool :
""" Détermine si un prénom suit la politique du programme ou non. """
if len ( prenom ) == 0 :
return False
if sub ( r " *?[^ \ w \ s]+ " , ' ' , prenom ) != prenom : # pas de caractères spéciaux dans un prénom
return False
return True
def naissanceCorrect ( self , naissance : str ) - > bool :
""" Détermine si une date de naissance suit la politique du programme ou non. """
if len ( naissance ) == 0 :
return False
2021-11-21 12:40:03 +01:00
# lien pour mieux comprendre ce qui se passe : https://www.debuggex.com/r/hSD-6BfSqDD1It5Z
if sub ( r " [0-9] {4} \ /(0[1-9]|1[0-2]) \ /(0[1-9]|[1-2][0-9]|3[0-1]) " , ' ' , naissance ) != ' ' :
2021-11-21 02:29:24 +01:00
return False
return True
def adresseCorrect ( self , adresse : str ) - > bool :
""" Détermine si une adresse suit la politique du programme ou non. """
if len ( adresse ) == 0 :
return False
return True
def postalCorrect ( self , code : str ) - > bool :
""" Détermine si un code postal suit la politique du programme ou non. """
if len ( code ) == 0 :
return False
if sub ( r " \ d {5} " , ' ' , code ) != ' ' :
return False
return True
2021-11-18 20:41:58 +01:00
def connexion ( self , utilisateur : str , motDePasse : str ) :
2021-11-19 00:47:01 +01:00
""" Gère la connexion aux différentes interfaces de l ' application. """
2021-11-19 11:41:37 +01:00
"""
Vérification nom d ' utilisateur / mot de passe correctement entré
2021-11-20 19:47:13 +01:00
avec leurs fonctions respectives .
2021-11-19 11:41:37 +01:00
"""
2021-11-20 19:47:13 +01:00
pseudoOk = self . utilisateurCorrect ( utilisateur )
if not pseudoOk [ 0 ] :
2021-11-28 12:06:41 +01:00
showerror ( " Erreur " , pseudoOk [ 1 ] )
2021-11-19 11:41:37 +01:00
return
mdpOk = self . motDePasseCorrect ( motDePasse )
if not mdpOk [ 0 ] :
2021-11-28 12:06:41 +01:00
showerror ( " Erreur " , mdpOk [ 1 ] )
2021-11-18 20:41:58 +01:00
return
2021-11-19 00:47:01 +01:00
# Redirection vers la bonne interface
2021-11-21 02:29:24 +01:00
utilisateurBaseDeDonnee = Utilisateurs ( ) . verificationIdentifiants ( utilisateur , motDePasse )
2021-11-19 23:57:11 +01:00
if utilisateurBaseDeDonnee [ 0 ] > 0 :
if utilisateurBaseDeDonnee [ 1 ] == 0 : # si le métier est "Manager"
self . _interfaceManager ( utilisateurBaseDeDonnee [ 0 ] )
elif utilisateurBaseDeDonnee [ 1 ] == 1 : # si le métier est "Caissier"
self . _interfaceCaissier ( utilisateurBaseDeDonnee [ 0 ] )
else :
2021-11-28 12:06:41 +01:00
showerror ( " Erreur " , " Une erreur est survenue : métier inconnue. " )
2021-11-18 20:41:58 +01:00
else :
2021-11-28 12:06:41 +01:00
showerror ( " Erreur " , " Utilisateur ou mot de passe incorrect. " )
2021-11-18 20:41:58 +01:00
2021-11-20 11:39:16 +01:00
def dimensionsFenetre ( self , fenetre , nouveauX : int , nouveauY : int ) :
2021-11-19 20:14:41 +01:00
""" Permet de changer les dimensions de la fenêtre parent et la place au centre de l ' écran. """
2021-11-20 11:39:16 +01:00
largeur = fenetre . winfo_screenwidth ( )
hauteur = fenetre . winfo_screenheight ( )
2021-11-19 20:12:06 +01:00
2021-11-19 20:13:53 +01:00
x = ( largeur / / 2 ) - ( nouveauX / / 2 )
y = ( hauteur / / 2 ) - ( nouveauY / / 2 )
2021-11-19 20:12:06 +01:00
2021-11-20 11:39:16 +01:00
fenetre . geometry ( f " { nouveauX } x { nouveauY } + { x } + { y } " )
2021-11-19 20:12:06 +01:00
2021-11-19 00:47:01 +01:00
def _interfaceConnexion ( self ) :
2021-11-19 23:57:11 +01:00
""" Affiche l ' interface de connexion. """
2021-11-18 20:41:58 +01:00
# Paramètres de la fenêtre
2021-11-20 11:39:16 +01:00
self . dimensionsFenetre ( self . parent , 400 , 600 )
2021-11-19 00:47:01 +01:00
self . parent . title ( " Fenêtre de connexion " )
2021-11-19 23:57:11 +01:00
# Suppresssion de la dernière Frame
self . f . destroy ( )
# Instanciation d'une nouvelle Frame, on va donc ajouter tout nos widgets à cet Frame
2021-11-19 00:47:01 +01:00
self . f = Frame ( self . parent )
2021-11-20 02:40:02 +01:00
self . f . grid ( )
2021-11-18 20:41:58 +01:00
# Affichage des labels et boutons
2021-11-19 00:47:01 +01:00
tentativeDeConnexion = lambda _ = None : self . connexion ( utilisateur . get ( ) , motDpasse . get ( ) ) # lambda pour envoyer les informations entrés dans le formulaire
2021-11-19 11:41:37 +01:00
ecart = 80 # écart pour avoir un affichage centré
2021-11-19 00:47:01 +01:00
Label ( self . f ) . grid ( row = 0 , pady = 50 ) # utilisé pour du padding (meilleur affichage)
2021-11-18 20:41:58 +01:00
2021-11-20 02:40:02 +01:00
Label ( self . f , text = " Utilisateur " , font = self . font ) . grid ( column = 0 , row = 1 , columnspan = 2 , padx = ecart - 20 , pady = 20 , sticky = ' w ' )
2021-11-19 00:47:01 +01:00
utilisateur = Entry ( self . f , font = self . font , width = 18 )
2021-11-18 20:41:58 +01:00
utilisateur . grid ( column = 1 , row = 2 , columnspan = 2 , padx = ecart )
2021-11-20 02:40:02 +01:00
Label ( self . f , text = " Mot de passe " , font = self . font ) . grid ( column = 0 , row = 3 , columnspan = 2 , padx = ecart - 20 , pady = 20 , sticky = ' w ' )
2021-11-19 00:47:01 +01:00
motDpasse = Entry ( self . f , font = self . font , show = ' ⁎ ' , width = 18 )
motDpasse . grid ( column = 1 , row = 4 , columnspan = 2 , padx = ecart )
motDpasse . bind ( " <Return> " , tentativeDeConnexion )
2021-11-19 00:08:48 +01:00
def __afficherMDP ( self ) :
""" Permet de gérer l ' affichage du mot de passe dans le champs sur la page de connexion. """
if self . mdpVisible == False : # si mot de passe caché, alors on l'affiche
self . mdpVisible = True
motDpasse . config ( show = ' ' )
bouttonAffichageMDP . config ( font = ( " Arial " , 10 , " overstrike " ) )
else : # inversement
self . mdpVisible = False
motDpasse . config ( show = ' ⁎ ' )
bouttonAffichageMDP . config ( font = ( " Arial " , 10 ) )
2021-11-19 00:47:01 +01:00
bouttonAffichageMDP = Button ( self . f , text = ' 👁 ' , command = lambda : __afficherMDP ( self ) )
2021-11-19 00:08:48 +01:00
bouttonAffichageMDP . grid ( column = 2 , row = 4 , columnspan = 2 )
self . mdpVisible = False
2021-11-19 00:47:01 +01:00
bouton = Button ( self . f , text = " Se connecter " , font = self . font , command = tentativeDeConnexion )
2021-11-18 20:41:58 +01:00
bouton . grid ( column = 0 , row = 5 , columnspan = 3 , padx = ecart , pady = 20 )
2021-11-19 00:47:01 +01:00
bouton . bind ( " <Return> " , tentativeDeConnexion )
2021-11-18 20:41:58 +01:00
2021-11-19 17:14:15 +01:00
Button ( self . f , text = " Quitter " , font = self . font , command = quit ) . grid ( column = 0 , row = 6 , columnspan = 4 , pady = 20 )
2021-11-18 20:41:58 +01:00
2021-11-24 16:47:54 +01:00
self . _interfaceCaissier ( 1 ) # DEBUG: affiche directement l'interface du Caissier
2021-11-20 00:11:59 +01:00
2021-11-19 23:57:11 +01:00
def _interfaceCaissier ( self , id : int ) :
""" Affiche l ' interface du caissier. """
2021-11-24 16:12:35 +01:00
caissier = Utilisateurs ( ) . recuperationUtilisateur ( id = id )
self . parent . title ( f " Caissier { caissier [ ' nom ' ] } { caissier [ ' prenom ' ] } " )
2021-11-28 14:36:28 +01:00
self . dimensionsFenetre ( self . parent , 940 , 690 )
2021-11-19 23:57:11 +01:00
# Suppresssion de la dernière Frame
self . f . destroy ( )
# Instanciation d'une nouvelle Frame, on va donc ajouter tout nos widgets à cet Frame
self . f = Frame ( self . parent )
2021-11-20 02:40:02 +01:00
self . f . grid ( )
2021-11-19 23:57:11 +01:00
2021-11-24 16:12:35 +01:00
Label ( self . f , text = " Interface Caissier " , font = ( self . font [ 0 ] , 20 ) ) . grid ( column = 0 , row = 0 ) # titre de l'interface
2021-11-25 18:01:05 +01:00
# Partie affichage du Stock
stock = LabelFrame ( self . f , text = " Stock " )
2021-11-25 23:21:36 +01:00
stock . grid ( column = 0 , row = 1 , sticky = ' n ' , padx = 5 )
2021-11-24 16:12:35 +01:00
2021-11-26 13:18:12 +01:00
# Variables pour les filtres du tableau
stockDisponibleVerif = IntVar ( stock ) # controle si on affiche que les éléments en stocks ou non
# Cache un certain type de produit
fruitsLegumesVerif = IntVar ( stock )
boulangerieVerif = IntVar ( stock )
boucheriePoissonnerieVerif = IntVar ( stock )
entretienVerif = IntVar ( stock )
2021-11-28 14:36:28 +01:00
def __formatPrix ( prix : str ) - > str :
return f " { float ( prix ) : .2f } € " . replace ( ' . ' , ' , ' )
2021-11-26 13:18:12 +01:00
def __affichageTableau ( parent : Frame , page : int = 1 ) :
""" Fonction qui va actualiser le tableau avec une page donnée (par défaut affiche la première page). """
2021-11-25 18:01:05 +01:00
# On supprime et refais la frame qui va stocker notre tableau
parent . destroy ( )
parent = Frame ( stock )
parent . grid ( column = 0 , row = 1 , columnspan = 6 )
2021-11-26 13:18:12 +01:00
# Filtre pour le tableau
filtres = Frame ( stock ) # Morceau qui va contenir nos checkbutton
ecartFiltre = 10 # écart entre les champs des filtres
Label ( filtres , text = " Filtre " , font = self . font ) . grid ( column = 0 , row = 0 ) # titre
Checkbutton ( filtres , text = " Stock disponible \n uniquement " , variable = stockDisponibleVerif , command = lambda : __affichageTableau ( parent ) ) . grid ( sticky = ' w ' , pady = ecartFiltre )
Checkbutton ( filtres , text = " Cacher les \n fruits & légumes " , variable = fruitsLegumesVerif , command = lambda : __affichageTableau ( parent ) ) . grid ( sticky = ' w ' , pady = ecartFiltre )
Checkbutton ( filtres , text = " Cacher les produits de \n la boulangerie " , variable = boulangerieVerif , command = lambda : __affichageTableau ( parent ) ) . grid ( sticky = ' w ' , pady = ecartFiltre )
Checkbutton ( filtres , text = " Cacher les produits de \n la boucherie \n et poissonnerie " , variable = boucheriePoissonnerieVerif , command = lambda : __affichageTableau ( parent ) ) . grid ( sticky = ' w ' )
Checkbutton ( filtres , text = " Cacher les produits \n d ' entretien " , variable = entretienVerif , command = lambda : __affichageTableau ( parent ) ) . grid ( sticky = ' w ' , pady = ecartFiltre )
filtres . grid ( column = 7 , row = 1 , sticky = ' w ' )
stockListe = Stock ( ) . listeStocks ( ) # stock récupéré de la base de données
for i in range ( 0 , len ( stockListe ) ) : # on retire les éléments plus présent dans la liste
if stockDisponibleVerif . get ( ) == 1 and stockListe [ i ] [ " quantite " ] < 1 :
stockListe [ i ] = None
elif fruitsLegumesVerif . get ( ) == 1 and stockListe [ i ] [ " type " ] == " fruits legumes " :
stockListe [ i ] = None
elif boulangerieVerif . get ( ) == 1 and stockListe [ i ] [ " type " ] == " boulangerie " :
stockListe [ i ] = None
elif boucheriePoissonnerieVerif . get ( ) == 1 and stockListe [ i ] [ " type " ] == " boucherie poissonnerie " :
stockListe [ i ] = None
elif entretienVerif . get ( ) == 1 and stockListe [ i ] [ " type " ] == " entretien " :
stockListe [ i ] = None
# Supprime toutes les valeurs `None` de la liste
stockListe = list ( filter ( None , stockListe ) )
2021-11-25 18:01:05 +01:00
ecart = 10 # écart entre les champs
elementsParPage = 10 # on définit combien d'élément une page peut afficher au maximum
pageMax = - ( - len ( stockListe ) / / elementsParPage ) # on définit combien de page il y au maximum
if pageMax < = 1 :
page = 1 # on force la page à être à 1 si il n'y a qu'une page, peut importe l'argument donnée à la fonction
limiteIndex = elementsParPage * page # on définit une limite pour ne pas afficher plus d'éléments qu'il n'en faut par page
if len ( stockListe ) > 0 : # si stock non vide
# Définition des colonnes
Label ( parent , text = " ID " ) . grid ( column = 0 , row = 0 , padx = ecart )
Label ( parent , text = " Image " ) . grid ( column = 1 , row = 0 , padx = ecart )
Label ( parent , text = " Type " ) . grid ( column = 2 , row = 0 , padx = ecart )
Label ( parent , text = " Nom " ) . grid ( column = 3 , row = 0 , padx = ecart )
Label ( parent , text = " Quantité " ) . grid ( column = 4 , row = 0 , padx = ecart )
2021-11-25 23:21:36 +01:00
Label ( parent , text = " Prix unité " ) . grid ( column = 5 , row = 0 , padx = ecart )
2021-11-25 18:01:05 +01:00
curseur = limiteIndex - elementsParPage # on commence à partir du curseur
i = 1 # on commence à 1 car il y a déjà le nom des colonnes en position 0
2021-11-26 00:26:59 +01:00
self . imagesStock = [ ] # on vide la liste si elle contient déjà des images
2021-11-25 18:01:05 +01:00
for element in stockListe [ curseur : limiteIndex ] : # on ignore les éléments avant le curseur et après la limite
2021-11-28 11:48:31 +01:00
Label ( parent , text = element [ " id " ] ) . grid ( column = 0 , row = i , padx = ecart )
2021-11-25 18:01:05 +01:00
"""
L ' idée est que on a une liste `images` qui permet de stocker toutes nos images
( c ' est une limitation de tkinter que de garder nos images en mémoire)
Une fois ajouté à la liste , on l ' affiche dans notre Label
"""
2021-11-28 11:48:31 +01:00
if Stock ( ) . fichierExiste ( element [ " image_url " ] ) : # si l'image existe, utilisation de la fonction de `db.py`
2021-11-25 23:21:36 +01:00
self . imagesStock . append ( PhotoImage ( file = element [ " image_url " ] ) )
2021-11-28 11:48:31 +01:00
else : # si l'image n'existe pas
2021-11-26 00:26:59 +01:00
self . imagesStock . append ( PhotoImage ( file = " img/defaut.gif " ) ) # image par défaut
2021-11-28 11:48:31 +01:00
Label ( parent , image = self . imagesStock [ i - 1 ] ) . grid ( column = 1 , row = i , padx = ecart )
2021-11-25 18:01:05 +01:00
2021-11-28 11:48:31 +01:00
Label ( parent , text = element [ " type " ] . capitalize ( ) ) . grid ( column = 2 , row = i , padx = ecart )
Label ( parent , text = element [ " nom " ] . capitalize ( ) ) . grid ( column = 3 , row = i , padx = ecart )
Label ( parent , text = element [ " quantite " ] ) . grid ( column = 4 , row = i , padx = ecart )
2021-11-28 14:36:28 +01:00
Label ( parent , text = __formatPrix ( element [ " prix " ] ) ) . grid ( column = 5 , row = i , padx = ecart )
2021-11-25 18:01:05 +01:00
curseur + = 1
i + = 1
# Information sur la page actuelle
Label ( parent , text = f " Page { page } / { pageMax } " ) . grid ( column = 2 , row = i , columnspan = 2 )
# Boutons
2021-11-26 13:18:12 +01:00
precedent = Button ( parent , text = " Page précédente " , command = lambda : __affichageTableau ( parent , page - 1 ) )
2021-11-26 10:57:37 +01:00
precedent . grid ( column = 0 , row = i , columnspan = 2 , sticky = ' w ' )
2021-11-26 13:18:12 +01:00
suivant = Button ( parent , text = " Page suivante " , command = lambda : __affichageTableau ( parent , page + 1 ) )
2021-11-26 10:57:37 +01:00
suivant . grid ( column = 4 , row = i , columnspan = 2 , sticky = ' e ' )
2021-11-25 18:01:05 +01:00
if page == 1 : # si on est a la première page on désactive le boutton précédent
precedent . config ( state = " disabled " )
if page == pageMax : # si on est a la dernière page on désactive le boutton suivant
suivant . config ( state = " disabled " )
else :
2021-11-26 13:18:12 +01:00
Label ( parent , text = " Il n ' y a rien en stock \n Essayez de réduire les critères dans le filtre. " ) . grid ( column = 0 , row = 0 , columnspan = 6 )
2021-11-25 18:01:05 +01:00
tableau = Frame ( stock )
2021-11-26 13:18:12 +01:00
__affichageTableau ( tableau ) # affichage du tableau
2021-11-25 18:01:05 +01:00
# Partie affichage du ticket de caisse
2021-11-28 14:36:28 +01:00
ecart = 10
2021-11-25 18:01:05 +01:00
ticket = LabelFrame ( self . f , text = " Ticket de caisse " )
2021-11-25 23:21:36 +01:00
ticket . grid ( column = 1 , row = 1 , sticky = ' n ' , padx = 5 )
2021-11-28 14:36:28 +01:00
Label ( ticket , text = f " Date de vente : { date . today ( ) . strftime ( ' % Y/ % m/ %d ' ) } " ) . grid ( column = 0 , row = 0 , pady = ecart )
Label ( ticket , text = f " Éléments achetés ( { len ( self . panier ) } ) : " ) . grid ( column = 0 , row = 1 , pady = ecart )
i = 2
prixTotal = 0
for element in self . panier :
Label ( ticket , text = element ) . grid ( column = 0 , row = i )
prixTotal + = 0 # ajout du prix
i + = 1
Label ( ticket , text = f " Prix total : { __formatPrix ( prixTotal ) } " ) . grid ( column = 0 , row = i , pady = ecart )
Button ( ticket , text = " Valider le \n ticket de caisse " , font = self . font ) . grid ( column = 0 , row = i + 1 , pady = ecart )
#.grid(column=1, row=1, sticky='s')
2021-11-24 16:12:35 +01:00
2021-11-28 11:48:31 +01:00
# Partie ajout élément au stock
def __ajouterElementStock ( ) :
""" Ouvre une fenêtre qui permet d ' ajouter un nouvel élément à la base de donnée. """
"""
L ' enfant (`TopLevel`) dépend de la `Frame` et non du parent (`Tk`)
pour éviter de resté ouverte meme lorsque le caissier se déconnecte .
"""
enfant = Toplevel ( self . f )
enfant . title ( f " Ajouter un élément au stock " )
def ___verification ( ) :
""" Vérifie si les champs renseignées sont valides. """
"""
La variable ` ok ` sert à savoir si la vérification est passée
si elle vaut ` True ` alors tout est bon ,
Par contre si elle vaut ` False ` alors il y a eu une erreur .
Les valeurs ` Entry ` qui ne sont pas passés seront dans
la liste ` mauvaisChamps ` .
"""
ok = True
mauvaisChamps = [ ]
# vérification pour l'image, on utilise la fonction du fichier `db.py`
if Stock ( ) . fichierExiste ( image . get ( ) ) == False :
ok = False
mauvaisChamps . append ( image )
# vérification pour le type
2021-11-28 12:33:57 +01:00
if typeElement . get ( ) not in Stock ( ) . listeTypes ( ) :
2021-11-28 11:48:31 +01:00
ok = False
# Pas de coloration orange si le type est mauvais parce que on ne peut pas changé la couleur de fond d'une ComboBox
# vérification pour le nom
2021-11-28 12:03:15 +01:00
def ___nomValide ( nom : str ) - > bool :
if len ( nom ) < = 0 :
return False
if Stock ( ) . stockExistant ( nom ) == True :
return False
return True
if ___nomValide ( nom . get ( ) ) == False :
2021-11-28 11:48:31 +01:00
ok = False
mauvaisChamps . append ( nom )
# vérification pour la quantité
try :
int ( quantite . get ( ) ) # conversion en int
except : # si la conversion a échoué
ok = False
mauvaisChamps . append ( quantite )
# vérification pour le prix
try :
float ( prix . get ( ) ) # conversion en float
except : # si la conversion a échoué
ok = False
mauvaisChamps . append ( prix )
if ok == False :
"""
Tous les champs qui n ' ont pas réunies les conditions nécéssaires
sont mis en orange pendant 3 secondes pour bien comprendre quelles champs
sont à modifié .
La fonction lambda ` remettreCouleur ` permet de remettre la couleur initial
après les 3 secondes .
"""
remettreCouleur = lambda widget , ancienneCouleur : widget . configure ( bg = ancienneCouleur )
for champs in mauvaisChamps :
couleur = champs [ " background " ] # couleur d'avant changement
champs . configure ( bg = " orange " ) # on change la couleur du champs en orange
# dans 3 secondes on fait : `remettreCouleur(champs, couleur)`
champs . after ( 3000 , remettreCouleur , champs , couleur )
else :
"""
Tous les tests sont passés , on peut ajouter l ' utilisateur à la base de donnée
Pas besoin de gérer les erreurs lors des casts car on a déjà vérifié que c ' était bien les bons types avant
"""
Stock ( ) . ajoutStock (
2021-11-28 12:33:57 +01:00
typeElement . get ( ) ,
2021-11-28 11:48:31 +01:00
nom . get ( ) ,
int ( quantite . get ( ) ) ,
float ( prix . get ( ) ) ,
image . get ( )
)
__affichageTableau ( tableau ) # met à jour le tableau
# Champs de saisie
# Image
Label ( enfant , text = " Image : " ) . grid ( column = 0 , row = 0 , sticky = ' e ' )
image = Entry ( enfant )
image . grid ( column = 1 , row = 0 , sticky = ' w ' )
2021-11-28 12:28:03 +01:00
def ___selectionImage ( ) :
""" Fonction qui permet de choisir une image dans l ' arborescence de fichiers de l ' utilisateur. """
try :
chemin = askopenfile ( title = " Choisir une image " , filetypes = [ ( " Image GIF " , " .gif " ) ] )
image . delete ( 0 , " end " )
image . insert ( 0 , chemin . name )
except :
pass
Button ( enfant , image = self . dossierImage , command = ___selectionImage ) . grid ( column = 1 , row = 0 , sticky = ' e ' )
2021-11-28 11:48:31 +01:00
# Type (ComboBox)
Label ( enfant , text = " Type : " ) . grid ( column = 0 , row = 1 , sticky = ' e ' )
2021-11-28 12:33:57 +01:00
typeElement = Combobox ( enfant , values = Stock ( ) . listeTypes ( ) )
# typeElement.current(0) # valeur 0 par défaut
typeElement . grid ( column = 1 , row = 1 , sticky = ' w ' )
2021-11-28 11:48:31 +01:00
# Nom
Label ( enfant , text = " Nom : " ) . grid ( column = 0 , row = 2 , sticky = ' e ' )
nom = Entry ( enfant )
nom . grid ( column = 1 , row = 2 , sticky = ' w ' )
# Quantité
Label ( enfant , text = " Quantité : " ) . grid ( column = 0 , row = 3 , sticky = ' e ' )
quantite = Entry ( enfant )
quantite . grid ( column = 1 , row = 3 , sticky = ' w ' )
# Prix à l'unité
Label ( enfant , text = " Prix à l ' unité : " ) . grid ( column = 0 , row = 4 , sticky = ' e ' )
prix = Entry ( enfant )
prix . grid ( column = 1 , row = 4 , sticky = ' w ' )
def ___viderChamps ( ) :
""" Vide tout les champs de leur contenu """
# On récupère toutes les `Entry` de la fenêtre et on change leur contenu
2021-11-28 12:33:57 +01:00
for champ in [ widget for typeElement , widget in enfant . children . items ( ) if " entry " in typeElement ] :
2021-11-28 11:48:31 +01:00
champ . delete ( 0 , " end " )
champ . update ( )
# Boutons
Button ( enfant , text = " Valider " , command = ___verification ) . grid ( column = 0 , row = 8 , columnspan = 3 , sticky = ' w ' )
Button ( enfant , text = " Vider les champs " , command = ___viderChamps ) . grid ( column = 0 , row = 8 , columnspan = 3 )
Button ( enfant , text = " Quitter " , command = enfant . destroy ) . grid ( column = 0 , row = 8 , columnspan = 3 , sticky = ' e ' )
2021-11-28 14:36:28 +01:00
Button ( self . f , text = " Ajouter un élément \n au stock " , font = self . font , command = __ajouterElementStock ) . grid ( column = 1 , row = 2 )
2021-11-28 11:48:31 +01:00
2021-11-24 16:47:54 +01:00
# Boutton pour passer en mode manager si la personne est un manager
if caissier [ " metier " ] == 0 :
2021-11-28 14:36:28 +01:00
Button ( self . f , text = " Passer en mode Manager " , font = self . font , command = lambda : self . _interfaceManager ( id ) ) . grid ( column = 0 , row = 2 )
2021-11-24 16:47:54 +01:00
2021-11-24 16:12:35 +01:00
2021-11-19 23:57:11 +01:00
def _interfaceManager ( self , id : int ) :
""" Affiche l ' interface du manager. """
2021-11-20 02:40:02 +01:00
manager = Utilisateurs ( ) . recuperationUtilisateur ( id = id )
2021-11-23 14:41:11 +01:00
# Dans le cas où un utilisateur réussi à trouvé cette interface alors qu'il n'a pas le droit, il sera bloqué
if manager [ " metier " ] != 0 :
2021-11-28 12:06:41 +01:00
showerror ( " Erreur " , " Vous ne pouvez pas accéder à cette interface. " )
2021-11-23 14:41:11 +01:00
return
2021-11-20 00:57:56 +01:00
self . parent . title ( f " Manager { manager [ ' nom ' ] } { manager [ ' prenom ' ] } " )
2021-11-21 12:40:03 +01:00
self . dimensionsFenetre ( self . parent , 580 , 310 )
2021-11-19 23:57:11 +01:00
# Suppresssion de la dernière Frame
self . f . destroy ( )
# Instanciation d'une nouvelle Frame, on va donc ajouter tout nos widgets à cet Frame
self . f = Frame ( self . parent )
2021-11-20 02:40:02 +01:00
self . f . grid ( )
Label ( self . f , text = " Interface Manager " , font = ( self . font [ 0 ] , 20 ) ) . grid ( column = 0 , row = 0 )
Button ( self . f , text = " Se déconnecter " , font = self . font , command = self . _interfaceConnexion ) . grid ( column = 1 , row = 0 , padx = 50 )
Label ( self . f ) . grid ( row = 1 , pady = 10 ) # séparateur
def __ajouterUtilisateur ( metier : int ) :
""" Permet de créer un nouvel utilisateur, manager (`metier = 0`) et caissier (`metier = 1`). """
2021-11-20 19:47:13 +01:00
"""
L ' enfant (`TopLevel`) dépend de la `Frame` et non du parent (`Tk`)
pour éviter de resté ouverte meme lorsque le manager se déconnecte .
"""
enfant = Toplevel ( self . f )
enfant . title ( f " Ajouter un { ' manager ' if metier == 0 else ' caissier ' } " )
def ___verification ( ) :
""" Vérifie si les champs renseignées sont valides. """
2021-11-21 02:29:24 +01:00
"""
Les valeurs ` Entry ` qui ne sont pas passés seront dans
la liste ` mauvaisChamps ` .
2021-11-28 11:48:31 +01:00
Si la liste ` mauvaisChamps ` contient un élément alors un test n ' est pas ok.
2021-11-21 02:29:24 +01:00
"""
mauvaisChamps = [ ]
2021-11-20 19:47:13 +01:00
# vérification pour le nom d'utilisateur
2021-11-21 02:29:24 +01:00
if self . utilisateurCorrect ( pseudo . get ( ) ) [ 0 ] == False or Utilisateurs ( ) . utilisateurExistant ( pseudo . get ( ) ) == True :
mauvaisChamps . append ( pseudo )
2021-11-20 19:47:13 +01:00
# vérification pour le mot de passe
2021-11-21 02:29:24 +01:00
if self . motDePasseCorrect ( passe . get ( ) ) [ 0 ] == False :
mauvaisChamps . append ( passe )
2021-11-20 19:47:13 +01:00
# vérification pour le nom
2021-11-21 02:29:24 +01:00
if self . nomCorrect ( nom . get ( ) ) == False :
mauvaisChamps . append ( nom )
2021-11-20 19:47:13 +01:00
# vérification pour le prénom
2021-11-21 02:29:24 +01:00
if self . prenomCorrect ( prenom . get ( ) ) == False :
mauvaisChamps . append ( prenom )
2021-11-20 19:47:13 +01:00
# vérification pour la date de naissance
2021-11-21 02:29:24 +01:00
if self . naissanceCorrect ( naissance . get ( ) ) == False :
mauvaisChamps . append ( naissance )
2021-11-20 19:47:13 +01:00
# vérification pour l'adresse
2021-11-21 02:29:24 +01:00
if self . adresseCorrect ( adresse . get ( ) ) == False :
mauvaisChamps . append ( adresse )
2021-11-20 19:47:13 +01:00
# vérification pour le code postal
2021-11-21 02:29:24 +01:00
if self . postalCorrect ( postal . get ( ) ) == False :
mauvaisChamps . append ( postal )
2021-11-28 11:48:31 +01:00
if len ( mauvaisChamps ) != 0 :
2021-11-21 02:29:24 +01:00
"""
Tous les champs qui n ' ont pas réunies les conditions nécéssaires
sont mis en orange pendant 3 secondes pour bien comprendre quelles champs
sont à modifié .
La fonction lambda ` remettreCouleur ` permet de remettre la couleur initial
après les 3 secondes .
"""
remettreCouleur = lambda widget , ancienneCouleur : widget . configure ( bg = ancienneCouleur )
for champs in mauvaisChamps :
couleur = champs [ " background " ] # couleur d'avant changement
champs . configure ( bg = " orange " ) # on change la couleur du champs en orange
# dans 3 secondes on fait : `remettreCouleur(champs, couleur)`
champs . after ( 3000 , remettreCouleur , champs , couleur )
else :
# Tous les tests sont passés, on peut ajouter l'utilisateur à la base de donnée
Utilisateurs ( ) . ajoutUtilisateur (
pseudo . get ( ) ,
passe . get ( ) . strip ( ) ,
metier ,
nom . get ( ) ,
prenom . get ( ) ,
naissance . get ( ) ,
adresse . get ( ) ,
int ( postal . get ( ) ) , # pas besoin de gérer d'erreur lors du cast car on a vérifié avant que c'était bien une suite de chiffre
)
2021-11-21 11:52:35 +01:00
__ajouterUtilisateursListe ( listeUtilisateurs ) # met à jour la liste
2021-11-21 02:29:24 +01:00
# Champs de saisie
# Nom d'utilisateurs
2021-11-20 19:47:13 +01:00
Label ( enfant , text = " Nom d ' utilisateur : " ) . grid ( column = 0 , row = 0 , sticky = ' e ' )
2021-11-21 02:29:24 +01:00
Label ( enfant , text = " Pas de caractères spéciaux " , font = ( " Arial " , 10 , " italic " ) ) . grid ( column = 2 , row = 0 , sticky = ' w ' )
2021-11-20 19:47:13 +01:00
pseudo = Entry ( enfant )
pseudo . grid ( column = 1 , row = 0 , sticky = ' w ' )
2021-11-21 02:29:24 +01:00
# Mot de passe
2021-11-20 19:47:13 +01:00
Label ( enfant , text = " Mot de passe : " ) . grid ( column = 0 , row = 1 , sticky = ' e ' )
2021-11-21 02:29:24 +01:00
Label ( enfant , text = " 1 majuscule, miniscule et caractère spécial minimum " , font = ( " Arial " , 10 , " italic " ) ) . grid ( column = 2 , row = 1 , sticky = ' w ' )
2021-11-20 19:47:13 +01:00
passe = Entry ( enfant )
passe . grid ( column = 1 , row = 1 , sticky = ' w ' )
2021-11-21 02:29:24 +01:00
# Nom
Label ( enfant , text = " Nom : " ) . grid ( column = 0 , row = 2 , sticky = ' e ' )
Label ( enfant , text = " Pas de caractères spéciaux " , font = ( " Arial " , 10 , " italic " ) ) . grid ( column = 2 , row = 2 , sticky = ' w ' )
2021-11-20 19:47:13 +01:00
nom = Entry ( enfant )
2021-11-21 02:29:24 +01:00
nom . grid ( column = 1 , row = 2 , sticky = ' w ' )
# Prénom
Label ( enfant , text = " Prénom : " ) . grid ( column = 0 , row = 3 , sticky = ' e ' )
Label ( enfant , text = " Pas de caractères spéciaux " , font = ( " Arial " , 10 , " italic " ) ) . grid ( column = 2 , row = 3 , sticky = ' w ' )
2021-11-20 19:47:13 +01:00
prenom = Entry ( enfant )
2021-11-21 02:29:24 +01:00
prenom . grid ( column = 1 , row = 3 , sticky = ' w ' )
# Date de naissance
Label ( enfant , text = " Date de naissance : " ) . grid ( column = 0 , row = 4 , sticky = ' e ' )
Label ( enfant , text = " Format : AAAA/MM/JJ " , font = ( " Arial " , 10 , " italic " ) ) . grid ( column = 2 , row = 4 , sticky = ' w ' )
2021-11-20 19:47:13 +01:00
naissance = Entry ( enfant )
2021-11-21 02:29:24 +01:00
naissance . grid ( column = 1 , row = 4 , sticky = ' w ' )
# Adresse
Label ( enfant , text = " Adresse " ) . grid ( column = 0 , row = 5 , sticky = ' e ' )
2021-11-20 19:47:13 +01:00
adresse = Entry ( enfant )
2021-11-21 02:29:24 +01:00
adresse . grid ( column = 1 , row = 5 , sticky = ' w ' )
# Code postal
Label ( enfant , text = " Code postal : " ) . grid ( column = 0 , row = 6 , sticky = ' e ' )
Label ( enfant , text = " 5 chiffres " , font = ( " Arial " , 10 , " italic " ) ) . grid ( column = 2 , row = 6 , sticky = ' w ' )
2021-11-20 19:47:13 +01:00
postal = Entry ( enfant )
2021-11-21 02:29:24 +01:00
postal . grid ( column = 1 , row = 6 , sticky = ' w ' )
2021-11-20 19:47:13 +01:00
def ___viderChamps ( ) :
""" Vide tout les champs de leur contenu """
# On récupère toutes les `Entry` de la fenêtre et on change leur contenu
2021-11-28 12:33:57 +01:00
for champ in [ widget for typeElement , widget in enfant . children . items ( ) if " entry " in typeElement ] :
2021-11-20 19:47:13 +01:00
champ . delete ( 0 , " end " )
champ . update ( )
# Boutons
Button ( enfant , text = " Valider " , command = ___verification ) . grid ( column = 0 , row = 8 , columnspan = 3 , sticky = ' w ' )
Button ( enfant , text = " Vider les champs " , command = ___viderChamps ) . grid ( column = 0 , row = 8 , columnspan = 3 )
Button ( enfant , text = " Quitter " , command = enfant . destroy ) . grid ( column = 0 , row = 8 , columnspan = 3 , sticky = ' e ' )
2021-11-20 02:40:02 +01:00
def __retirerUtilisateur ( metier : int ) :
""" Permet de supprimer un utilisateur existant, manager (`metier = 0`) et caissier (`metier = 1`). """
2021-11-20 19:47:13 +01:00
enfant = Toplevel ( self . f ) # cf. l'explication dans `__ajouterUtilisateur`
enfant . title ( f " Retirer un { ' manager ' if metier == 0 else ' caissier ' } " )
2021-11-21 11:52:35 +01:00
# Liste des utilisateurs
Label ( enfant , text = f " Liste des { ' manager ' if metier == 0 else ' caissier ' } " , font = self . font ) . grid ( column = 0 , row = 0 ) # titre
# On définit une barre pour pouvoir scroller dans la liste
2021-11-25 18:01:05 +01:00
scroll_retirer = Scrollbar ( enfant )
2021-11-21 11:52:35 +01:00
scroll_retirer . grid ( column = 1 , row = 1 , sticky = " nse " )
# On définit notre liste et on la lie à notre `Scrollbar`
listeUtilisateurs_retirer = Listbox ( enfant , width = 25 , height = 4 , yscrollcommand = scroll_retirer . set )
2021-11-25 18:01:05 +01:00
scroll_retirer . config ( command = listeUtilisateurs_retirer . yview ) # scroll à la verticale dans notre liste
2021-11-21 11:52:35 +01:00
# On ajoute nos utilisateurs à notre liste
__ajouterUtilisateursListe ( listeUtilisateurs_retirer , metier )
listeUtilisateurs_retirer . grid ( column = 0 , row = 1 )
# On affiche l'utilisateur quand on double-clique dessus
def ___suppressionUtilisateur ( ) :
""" Supprime l ' utilisateur actuellement sélectionné dans la liste """
element = listeUtilisateurs_retirer . curselection ( )
if len ( element ) == 0 : # si aucun élément n'est selectionné
2021-11-28 12:06:41 +01:00
showwarning ( " Attention " , " Aucun utilisateur n ' a été selectionné. " )
2021-11-21 11:52:35 +01:00
else :
utilisateur = listeUtilisateurs_retirer . get ( listeUtilisateurs_retirer . curselection ( ) [ 0 ] ) . split ( ' ( ' ) [ 0 ] [ : - 1 ]
2021-11-28 12:06:41 +01:00
reponse = askyesno ( " Confirmation " , f " Voulez vous supprimer { utilisateur } ? " )
2021-11-21 11:52:35 +01:00
if reponse == True :
Utilisateurs ( ) . suppressionUtilisateurs ( utilisateur )
__ajouterUtilisateursListe ( listeUtilisateurs_retirer ) # met à jour la liste dans la fenêtre de suppression
__ajouterUtilisateursListe ( listeUtilisateurs ) # met à jour la liste dans l'interface principale
2021-11-28 12:06:41 +01:00
showinfo ( " Information " , f " Utilisateur { utilisateur } supprimé. " )
2021-11-21 11:52:35 +01:00
# Boutons
Button ( enfant , text = " Supprimer " , command = ___suppressionUtilisateur ) . grid ( column = 0 , row = 8 , columnspan = 3 , sticky = ' w ' )
Button ( enfant , text = " Quitter " , command = enfant . destroy ) . grid ( column = 0 , row = 8 , columnspan = 3 , sticky = ' e ' )
2021-11-20 02:40:02 +01:00
def __afficherInformationsUtilisateur ( _ ) :
""" Permet d ' afficher les informations d ' un utilisateur """
element = listeUtilisateurs . curselection ( )
if len ( element ) == 0 : # si aucun élément n'est selectionné
return
2021-11-20 18:22:04 +01:00
"""
On split le champs car dans la liste on affiche le métier entre
parenthèses et on doit donner que le nom d ' utilisateur à
la fonction ` recuperationUtilisateur ` , aussi on retire le dernièr
charactère avec [ : - 1 ] car c ' est un espace.
"""
utilisateur = Utilisateurs ( ) . recuperationUtilisateur ( pseudo = listeUtilisateurs . get ( element [ 0 ] ) . split ( ' ( ' ) [ 0 ] [ : - 1 ] )
2021-11-20 19:47:13 +01:00
enfant = Toplevel ( self . f ) # cf. l'explication dans `__ajouterUtilisateur`
2021-11-20 11:39:16 +01:00
enfant . title ( f " { utilisateur [ ' nom ' ] } { utilisateur [ ' prenom ' ] } " )
2021-11-21 12:40:03 +01:00
# Informations sur l'utilisateur
frameInfos = LabelFrame ( enfant , text = " Informations utilisateur " , font = self . font )
frameInfos . grid ( column = 0 , row = 0 , sticky = ' n ' , padx = 5 )
2021-11-20 11:39:16 +01:00
utilisateur [ " metier " ] = " Manager " if utilisateur [ " metier " ] == 0 else " Caissier "
2021-11-20 12:02:48 +01:00
del utilisateur [ " passe " ] # le manager ne doit pas connaître le mot de passe de l'utilisateur
2021-11-20 11:39:16 +01:00
for idx , cle in enumerate ( utilisateur ) :
2021-11-28 14:36:28 +01:00
if cle == " stats_journaliere " :
cleAffichage = cle . replace ( ' _ ' , ' ' ) . title ( ) # remplace le `_` en espace et met une majuscule à tous les mots
else :
cleAffichage = cle . capitalize ( )
if cle == " date " :
continue
Label ( frameInfos , text = f " { cleAffichage } : " ) . grid ( column = 0 , row = idx + 1 , sticky = ' e ' )
2021-11-21 12:40:03 +01:00
Label ( frameInfos , text = utilisateur [ cle ] ) . grid ( column = 1 , row = idx + 1 , sticky = ' w ' )
frameSuivi = LabelFrame ( enfant , text = " Suivi des ventes " , font = self . font )
frameSuivi . grid ( column = 1 , row = 0 , sticky = ' n ' , padx = 5 )
Label ( frameSuivi , text = " Aucun résultat récemment enrengistré " ) . grid ( )
Button ( enfant , text = " Quitter " , command = enfant . destroy ) . grid ( column = 0 , row = 1 , columnspan = 2 )
2021-11-20 02:40:02 +01:00
Button ( self . f , text = " Ajouter un caissier " , font = self . font , command = lambda : __ajouterUtilisateur ( 1 ) ) . grid ( column = 0 , row = 2 )
Button ( self . f , text = " Retirer un caissier " , font = self . font , command = lambda : __retirerUtilisateur ( 1 ) ) . grid ( column = 1 , row = 2 )
Label ( self . f ) . grid ( row = 3 , pady = 10 ) # séparateur
# Liste des utilisateurs
2021-11-20 18:09:34 +01:00
managerVerif = IntVar ( self . f ) # filtre pour afficher ou non les managers dans la liste
caissierVerif = IntVar ( self . f ) # filtre pour afficher ou non les caissiers ou non dans la liste
caissierVerif . set ( 1 ) # par défaut on affiche que les caissiers
2021-11-21 11:52:35 +01:00
def __ajouterUtilisateursListe ( liste : Listbox , force : int = None ) :
2021-11-20 18:09:34 +01:00
"""
Ajoute des utilisateurs à la liste du Manager .
- > metier = 0 : manager uniquement
- > metier = 1 : caissier uniquement
- > metier = 2 : manager et caissier
"""
2021-11-21 11:52:35 +01:00
liste . delete ( 0 , " end " ) # vidé la liste des utilisateurs
if force : # si `force` n'est pas `None`, alors on force l'utilisation d'un métier
metier = force
else : # sinon on fait une vérification normale en fonction des filtres de l'interface manager
if managerVerif . get ( ) == 1 :
if caissierVerif . get ( ) == 1 :
metier = None # on affiche les 2
else :
metier = 0 # on affiche seulement les managers
2021-11-20 18:09:34 +01:00
else :
2021-11-21 11:52:35 +01:00
metier = 1 # on affiche les caissiers
if caissierVerif . get ( ) == 0 : # rien est coché, on revient à la configuration par défaut (caissiers uniquement)
metier = 1
caissierVerif . set ( 1 )
2021-11-21 02:38:01 +01:00
if metier == None : # on ajoute tous les utilisateurs
2021-11-20 18:09:34 +01:00
for idx , utilisateur in enumerate ( Utilisateurs ( ) . listUtilisateurs ( ) ) :
2021-11-21 11:52:35 +01:00
liste . insert ( idx , f " { utilisateur [ 0 ] } ( { ' manager ' if utilisateur [ 1 ] == 0 else ' caissier ' } ) " )
2021-11-20 18:09:34 +01:00
elif metier == 0 : # on ajoute que les managers
for idx , utilisateur in enumerate ( Utilisateurs ( ) . listUtilisateurs ( ) ) :
if utilisateur [ 1 ] == metier :
2021-11-21 11:52:35 +01:00
liste . insert ( idx , f " { utilisateur [ 0 ] } ( { ' manager ' if utilisateur [ 1 ] == 0 else ' caissier ' } ) " )
2021-11-20 18:09:34 +01:00
elif metier == 1 : # on ajoute que les caissiers
for idx , utilisateur in enumerate ( Utilisateurs ( ) . listUtilisateurs ( ) ) :
if utilisateur [ 1 ] == metier :
2021-11-21 11:52:35 +01:00
liste . insert ( idx , f " { utilisateur [ 0 ] } ( { ' manager ' if utilisateur [ 1 ] == 0 else ' caissier ' } ) " )
2021-11-20 18:09:34 +01:00
else : # ce cas est là au cas où mais n'est pas sensé être appellé
raise NameError ( " Métier inconnu. " )
2021-11-21 12:40:03 +01:00
# Label d'information
Label ( self . f , text = """
Double - cliquez sur un
utilisateur de la liste
pour obtenir des informations
2021-11-24 16:47:54 +01:00
supplémentaire à son sujet .
2021-11-21 12:40:03 +01:00
""" , justify= " right " ).grid(column=1, row=4, rowspan=2, sticky= " e " )
2021-11-20 02:40:02 +01:00
Label ( self . f , text = " Liste des utilisateurs " , font = self . font ) . grid ( column = 0 , row = 4 ) # titre
# On définit une barre pour pouvoir scroller dans la liste
2021-11-25 18:01:05 +01:00
scroll = Scrollbar ( self . f )
2021-11-20 02:40:02 +01:00
scroll . grid ( column = 0 , row = 5 , sticky = " nse " )
# On définit notre liste et on la lie à notre `Scrollbar`
listeUtilisateurs = Listbox ( self . f , width = 25 , height = 4 , yscrollcommand = scroll . set )
2021-11-25 18:01:05 +01:00
scroll . config ( command = listeUtilisateurs . yview ) # scroll à la verticale dans notre liste
2021-11-20 02:40:02 +01:00
# On ajoute nos utilisateurs à notre liste
2021-11-21 11:52:35 +01:00
__ajouterUtilisateursListe ( listeUtilisateurs )
2021-11-20 02:40:02 +01:00
listeUtilisateurs . grid ( column = 0 , row = 5 )
listeUtilisateurs . bind ( ' <Double-Button> ' , __afficherInformationsUtilisateur ) # on affiche l'utilisateur quand on double-clique dessus
2021-11-20 00:11:59 +01:00
2021-11-20 18:09:34 +01:00
# Filtre pour la liste
Label ( self . f , text = " Filtre " , font = self . font ) . grid ( column = 1 , row = 4 , sticky = ' w ' , padx = 10 ) # titre
filtres = Frame ( self . f ) # Morceau qui va contenir nos checkbutton
filtres . grid ( column = 1 , row = 4 , rowspan = 2 , sticky = ' w ' )
2021-11-21 11:52:35 +01:00
Checkbutton ( filtres , text = " Manager " , variable = managerVerif , command = lambda : __ajouterUtilisateursListe ( listeUtilisateurs ) ) . grid ( sticky = ' w ' )
Checkbutton ( filtres , text = " Caissier " , variable = caissierVerif , command = lambda : __ajouterUtilisateursListe ( listeUtilisateurs ) ) . grid ( sticky = ' w ' )
2021-11-20 18:09:34 +01:00
2021-11-24 16:47:54 +01:00
Button ( self . f , text = " Passer en mode caissier " , font = self . font , command = lambda : self . _interfaceCaissier ( id ) ) . grid ( column = 0 , row = 6 , columnspan = 3 , pady = 10 )
2021-11-21 12:40:03 +01:00
2021-11-18 20:41:58 +01:00
if __name__ == " __main__ " :
2021-11-20 00:11:59 +01:00
""" Application " GesMag " pour le module de Programmation d ' interfaces (2021-2022) """
2021-11-28 12:43:05 +01:00
"""
2021-11-28 12:46:57 +01:00
Si presentation = True alors une base de donnée par défaut sera généré .
Si presentation = False ou n ' est même pas mentionné, alors aucune base de donnée par défaut ne sera généré.
2021-11-28 12:43:05 +01:00
"""
GesMag ( presentation = True ) . demarrer ( )