From 574e3eb3574ce050d389f550b184598efc1760f4 Mon Sep 17 00:00:00 2001 From: Mylloon Date: Thu, 2 Dec 2021 16:59:51 +0100 Subject: [PATCH] add global histogram who show the addition of all the sells of all the cashier on the main manager page --- documentation/img/manager.png | 4 +- main.py | 99 ++++++++++++++++++----------------- stats.py | 25 +++++++-- 3 files changed, 72 insertions(+), 56 deletions(-) diff --git a/documentation/img/manager.png b/documentation/img/manager.png index 6a49e72..15e8309 100644 --- a/documentation/img/manager.png +++ b/documentation/img/manager.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dd23d4007c9fa97713217344883078d94499e893e6bf6cee3b0a12d244c1dae9 -size 34864 +oid sha256:7c41fef2a394c4abed4b26fe678dc518027893f143896c305dcc440df6e4039e +size 45442 diff --git a/main.py b/main.py index 1d5617c..f8a0763 100644 --- a/main.py +++ b/main.py @@ -599,7 +599,7 @@ class GesMag: showerror(f"Erreur – {self.nomApp}", "Vous ne pouvez pas accéder à cette interface.") return self.parent.title(f"Manager {manager['nom']} {manager['prenom']} – {self.nomApp}") - self.dimensionsFenetre(self.parent, 580, 310) + self.dimensionsFenetre(self.parent, 580, 530) # Suppresssion de la dernière Frame self.f.destroy() @@ -767,6 +767,44 @@ class GesMag: 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') + def __actualisationCanvas(canvas: Canvas, donnees: dict) -> None: + """Affiche l'histogramme des vente d'un utilisateur dans un canvas.""" + if len(donnees) <= 0: + canvas.create_text(10, 10, anchor='w', text="Aucun résultat récemment enregistré") + else: + # Les dates dans le fichier CSV ne sont pas dans l'ordre + # On retire l'ID et le pseudo du dictionnaire si présent dedans + donnees.pop("id", None) + donnees.pop("pseudo", None) + ecart = 10 + couleurs = [ + "CadetBlue3", + "HotPink2", + "IndianRed1", + "MediumPurple2", + "burlywood2", + "brown3", + "chocolate1", + "goldenrod2" + ] + # On récupère la plus grosse vente + maxVente = 0 # par défaut la meilleur vente est de 0 + for prix in donnees.values(): + prix = float(prix) + if prix > maxVente: # si on trouve une valeure plus grande + maxVente = prix + canvas.create_text(3, 190, anchor='w', text="€", font=("Arial", 7)) # affichage de la devise + for date in sorted(donnees.keys()): # on regarde les dates dans l'ordre + # Affichage de la date + canvas.create_text(ecart + 10, 60, anchor='w', text=date, font=("Arial", 8), angle=90) + # Affichage de la barre + hauteur = 190 - (float(donnees[date]) * 100) / maxVente # calcul de la hauteur en fonction de la plus grosse vente + # On fait `- 20` au résultat pour allonger la barre, aussi on met une barre de `2` pixel quand valeur petite + canvas.create_rectangle(ecart, 180, ecart + 15, hauteur - 20 if hauteur < 180 else 178, fill=couleurs.pop()) + # Affichage du montant + canvas.create_text(ecart, 190, anchor='w', text=str(donnees[date]).replace('.', ','), font=("Arial", 7)) + ecart += 33 + def __afficherInformationsUtilisateur(_) -> None: """Permet d'afficher les informations d'un utilisateur""" element = listeUtilisateurs.curselection() @@ -798,55 +836,11 @@ class GesMag: frameSuivi = LabelFrame(enfant, text="Histogramme des ventes", font=self.font) frameSuivi.grid(column=1, row=0, sticky="ns", padx=5) - def ___actualisationCanvas() -> None: - """Affiche l'histogramme des vente d'un utilisateur dans un canvas.""" - donnees = Stats().recuperationDonneesCSV(utilisateur['id']) - if len(donnees) <= 0: - histogramme.create_text(10, 10, anchor='w', text="Aucun résultat récemment enregistré") - else: - # Les dates dans le fichier CSV ne sont pas dans l'ordre - # On retire l'ID et le pseudo du dictionnaire - donnees.pop("id") - donnees.pop("pseudo") - ecart = 10 - couleurs = [ - "CadetBlue3", - "HotPink2", - "IndianRed1", - "MediumPurple2", - "burlywood2", - "brown3", - "chocolate1", - "goldenrod2" - ] + histogrammeUtilisateur = Canvas(frameSuivi, width=270, height=200) + histogrammeUtilisateur.grid() - # On remplace tous les prix `None` par `0.` (au cas où il y est des valeurs vide dans le `CSV`) - for date, prix in donnees.items(): - if prix == None: - donnees[date] = 0. - - # On récupère la plus grosse vente - maxVente = 0 # par défaut la meilleur vente est de 0 - for prix in donnees.values(): - prix = float(prix) - if prix > maxVente: # si on trouve une valeure plus grande - maxVente = prix - - for date in sorted(donnees.keys()): # on regarde les dates dans l'ordre - # Affichage de la date - histogramme.create_text(ecart + 10, 60, anchor='w', text=date, font=("Arial", 8), angle=90) - # Affichage de la barre - hauteur = 190 - (float(donnees[date]) * 100) / maxVente # calcul de la hauteur en fonction de la plus grosse vente - # On fait `- 20` au résultat pour allonger la barre, aussi on met une barre de `2` pixel quand valeur petite - histogramme.create_rectangle(ecart, 180, ecart + 15, hauteur - 20 if hauteur < 180 else 178, fill=couleurs.pop()) - # Affichage du montant - histogramme.create_text(ecart, 190, anchor='w', text=donnees[date], font=("Arial", 7)) - ecart += 33 - - histogramme = Canvas(frameSuivi, width=270, height=200) - histogramme.grid() - - ___actualisationCanvas() + donneesUtilisateur = Stats().recuperationDonneesCSV(utilisateur['id']) + __actualisationCanvas(histogrammeUtilisateur, donneesUtilisateur) Button(enfant, text="Quitter", command=enfant.destroy).grid(column=0, row=1, columnspan=2) @@ -926,6 +920,13 @@ class GesMag: 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) + # Histogramme global + histogrammeUtilisateur = Canvas(self.f, width=270, height=200) + histogrammeUtilisateur.grid(column=0, row=7, columnspan=3) + + donneesGlobales = Stats().recuperationDonneesCSV() + __actualisationCanvas(histogrammeUtilisateur, donneesGlobales) + if __name__ == "__main__": """Application "GesMag" pour le module de Programmation d'interfaces (2021-2022)""" """ diff --git a/stats.py b/stats.py index 5975e35..eb6cc57 100644 --- a/stats.py +++ b/stats.py @@ -99,14 +99,29 @@ class Stats(): else: fichier.writerow([utilisateurID, "Aucune ventes enregistrée"]) - def recuperationDonneesCSV(self, utilisateurID: int) -> dict: - """Renvoie les informations contenu dans le fichier `CSV` globale.""" + def recuperationDonneesCSV(self, utilisateurID: int = None) -> dict: + """ + Renvoie les informations contenu dans le fichier `CSV` globale. + + Si un argument est renseignée pour `utilisateurID` alors seul l'utilisateur + renseigné sera renvoyé. + """ self.miseAJourDatesCSV() # met à jour les dates du fichier `CSV` + with open("stats.csv", 'r') as f: fichier = list(csv.DictReader(f)) # lecture du fichier sous forme d'une liste de dictionnaire - for utilisateur in fichier: # on regarde tous les utilisateurs stockés dans le fichier - if utilisateur["id"] == str(utilisateurID): # si utilisateur trouvé - return utilisateur # renvoie des infos de l'utilisateur + if utilisateurID == None: # si on renvoie les stats globales + dates = dict.fromkeys(self.datesDisponibles(), 0.) + for date in dates: + for utilisateur in fichier: + if utilisateur[date] == None: # On remplace tous les prix `None` par `0.` + utilisateur[date] = 0. + dates[date] += float(utilisateur[date]) + return dates + else: # si on renvoie les stats spécifique à un utilisateur + for utilisateur in fichier: # on regarde tous les utilisateurs stockés dans le fichier + if utilisateur["id"] == str(utilisateurID): # si utilisateur trouvé + return utilisateur # renvoie des infos de l'utilisateur return {} # ne retourne rien si l'utilisateur n'était pas présent dans le fichier def miseAJourDatesCSV(self) -> None: