This repository has been archived on 2022-03-31. You can view files and clone it, but cannot push or open issues or pull requests.
GesMag/stats.py

156 lines
8.8 KiB
Python

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) -> None:
"""
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) -> None:
"""
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] = f"{float(ancienPrix):.2f}" # 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) -> None:
"""
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."""
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
return {} # ne retourne rien si l'utilisateur n'était pas présent dans le fichier
def miseAJourDatesCSV(self) -> None:
"""
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)