import csv from datetime import date, timedelta from users import Utilisateurs class Stats(): """Gère les statistiques et son export en format CSV.""" def __init__(self): self.formatDate = "%Y/%m/%d" def datesDisponibles(self) -> list: """Renvoie les dates disponibles pour l'entête du fichier `CSV`.""" datesPossibles = [] dateAujourdHui = date.today() - timedelta(days=7) for _ in range(0, 8): datesPossibles.append(dateAujourdHui.strftime(self.formatDate)) dateAujourdHui = dateAujourdHui + timedelta(days=1) return datesPossibles def creationCSV(self, force: bool = False): """ Créer le fichier `CSV` qui stockera les statistiques pour tous les utilisateurs. Possibilité de forcer la création (c-à-d même si le fichier existe déjà) en renseignant `force = True` """ if not Utilisateurs().fichierExiste("stats.csv") or force: with open("stats.csv", 'w') as f: fichier = csv.writer(f) fichier.writerow(["id", "pseudo"] + self.datesDisponibles()) def miseAJourStatsUtilisateur(self, utilisateurID: int, prix: float): """ Récupère le prix d'une transaction et l'ajoute au total d'un utilisateur. - s'il y a déjà une valeur dans la base de donnée correspondant à la date du jour, on met à jour cette valeur en l'additionnant avec le nouveaux prix - s'il n'avait pas de valeur à cette date: - si l'utilisateur n'est pas dans le fichier, on rajoute une ligne avec le prix - si l'utilisateur est présent mais aucun prix n'est fixé pour la date du jour, on rajoute le prix sur la ligne de l'utilisateur déjà existante On remplie les espaces vides par la valeur `0` (car aucun chiffre n'a été fait ce jour là, car aucune information n'était renseignée). """ self.miseAJourDatesCSV() # met-à-jour les dates du fichier `CSV` # Mets-à-jour le `CSV` avec le nouveau prix... aujourdHui = date.today().strftime(self.formatDate) with open("stats.csv", 'r') as f: fichier = list(csv.reader(f)) # On récupère la colonne pour aujourd'hui index = 0 locationDate = None # note l'index de la colonne de la date dans le fichier for nomColonne in fichier[0]: # on regarde l'entente if nomColonne == aujourdHui: # on regarde si la colonne correspond à la date du jour locationDate = index # on note l'entête index += 1 if locationDate == None: # ne devrait pas arrivé car on mets à jour les dates du `CSV` avant de lire le fichier raise IndexError("Date du jour non trouvé dans le fichier csv.") utilisateur = Utilisateurs().recuperationUtilisateur(utilisateurID) # on récupère les infos de l'utilisateur # Vérification si l'utilisateur est déjà présent dans le fichier `CSV` locationUtilisateur = None # note l'index de la ligne de l'utilisateur dans le fichier for idx, location in enumerate(fichier): if location[0] == str(utilisateurID): locationUtilisateur = idx if locationUtilisateur == None: # si l'utilisateur n'est pas présent dans le fichier # on rajoute la ligne fichier += [[utilisateurID, utilisateur["pseudo"]] + ['0' for _ in range(0, locationDate - 2)] + [prix]] else: # si déjà présent dans le fichier try: ancienPrix = float(fichier[locationUtilisateur][locationDate]) # on récupère l'ancien prix except IndexError: # si il n'y avait pas de prix définie avant ancienPrix = 0 # On rajoute la case fichier[locationUtilisateur] += ['0' for _ in range(0, locationDate - 1)] ancienPrix += prix # on y ajoute le nouveaux prix fichier[locationUtilisateur][locationDate] = ancienPrix # on met à jour le fichier with open("stats.csv", 'w') as f: # on applique les changements ecriture = csv.writer(f) ecriture.writerows(fichier) def exporteCSV(self, chemin: str, utilisateurID: int): """ Exporte les statistiques d'un utilisateur dans un fichier `CSV`. - N'exporte que les statistiques du jour. """ donnees = self.recuperationDonneesCSV(utilisateurID) aujourdHui = date.today().strftime(self.formatDate) with open(chemin, 'w') as f: fichier = csv.writer(f) fichier.writerow(["ID Utilisateur", f"Totales des ventes du jour ({aujourdHui})"]) if len(donnees) > 0: # si il y a des données enregistrées fichier.writerow([utilisateurID, donnees[0][aujourdHui]]) else: fichier.writerow([utilisateurID, "Aucune ventes enregistrée"]) def recuperationDonneesCSV(self, utilisateurID: int) -> dict: """Renvoie les informations contenu dans le fichier `CSV` globale.""" with open("stats.csv", 'r') as f: return list(csv.DictReader(f)) def miseAJourDatesCSV(self): """ Mets-à-jour les dates trop anciennes du fichier globales `CSV`. On remplie les espaces vides par la valeur `0` pour les jours qui remplacent les dates trop vieilles (âgées de plus d'une semaine) car soit aucun chiffre n'a été fait ce jour là, car aucune information n'était renseignée. """ besoinDeMofication = False with open("stats.csv", 'r') as f: fichier = list(csv.reader(f)) if len(fichier) == 1: # si fichier ne contient que l'entête self.creationCSV(True) # on recréer le fichier dans le doute (avec les bonnes dates) else: index = 2 # variable qui permet de savoir quel index on regarde (on commence à 2 car on ignore les 2 premières valeurs [id et pseudo]) mauvaisIndex = [] # liste qui va stocker les index trop vieux (> 1 semaine) datesPresentes = [] # liste qui stock les dates valides présentes dans le fichier (< 1 semaine) datesDisponibles = self.datesDisponibles() # liste des bonnes dates for dateFichier in fichier[0][index:]: # on regarde toutes les dates du fichier if dateFichier not in datesDisponibles: # si trop vieux mauvaisIndex.append(index) # on ajoute l'index à la liste besoinDeMofication = True else: datesPresentes.append(dateFichier) # on ajoute la date à la liste index += 1 if not besoinDeMofication: # vérification si on a besoin de rien faire return # on quitte la fonction datesARajouter = [date for date in datesDisponibles if date not in datesPresentes] # liste des dates à rajouter if len(datesARajouter) != len(mauvaisIndex): # ne devrais pas arrivé mais on sait jamais raise IndexError("Problème, pas autant de dates à rajouter que de de dates périmés dans le fichier.") for idx in mauvaisIndex: # pour tous les mauvais index for numLigne, ligne in enumerate(fichier): # on regarde toutes les lignes du fichier if idx < len(ligne): # s'il y a un élément dans la ligne à l'index donnée ou si elle est vide de toute façon if numLigne == 0: # si c'est la ligne d'entête ligne[idx] = datesARajouter[0] # on change la ligne avec la nouvelle date datesARajouter.pop(0) else: # si c'est une ligne de donnée ligne[idx] = '0' # on change la ligne avec une valeur vide fichier[numLigne] = ligne # on applique les changements if besoinDeMofication: # vérification si on a besoin de faire des changements with open("stats.csv", 'w') as f: # on applique les changements ecriture = csv.writer(f) ecriture.writerows(fichier)