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. - si aucune date n'est précisé dans la base de donnée d'un utilisateur, alors il n'a jamais enregistré de statistiques et on procède normalement - si une date est déjà renseigné : - si la date correspond à la date d'aujourd'hui, on procède normalement - si la date ne correspond pas, on enregistre ce qu'il y a dans la base de donnée dans un fichier `CSV`, ensuite on écrase l'ancien prix par `0` et la date par celle d'aujourd'hui, ensuite on procède normalement Procéder normalement consiste à ajouter le prix au prix totale stocké dans la base de donné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[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`.""" 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)