Modifications:
- Add dependencie `csv` in documentation - Add quantity selection when removing something from stock (now you can delete an item, but set it's quantity to 0) - Cleanup function names (`__affichagePanier`) - Disable the button who confirm a receipt when nothing is in the basket - Create the CSV file when starting the app - Add a function who update dates in the global csv file
This commit is contained in:
parent
565f5166c0
commit
2efecadfc1
4 changed files with 75 additions and 14 deletions
|
@ -130,6 +130,7 @@
|
|||
\item[\textbullet] \texttt{datetime} pour le temps
|
||||
\item[\textbullet] \texttt{sqlite3} pour la base de donnée SQLite
|
||||
\item[\textbullet] \texttt{random} pour la génération du stock (prix et quantité)
|
||||
\item[\textbullet] \texttt{csv} pour la gestion du fichier \texttt{CSV}
|
||||
\end{itemize}
|
||||
|
||||
\subsection{Cahier des charges}
|
||||
|
|
39
main.py
39
main.py
|
@ -19,6 +19,7 @@ class GesMag:
|
|||
"""Instancie quelques variables pour plus de clareté."""
|
||||
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à
|
||||
Stats().creationCSV() # on créer le fichier CSV qui stockera les statistiques des utilisateurs
|
||||
|
||||
self.nomApp = "GesMag" # nom de l'application
|
||||
self.parent = Tk() # fenêtre affiché à l'utilisateur
|
||||
|
@ -294,7 +295,7 @@ class GesMag:
|
|||
if nombreDeFoisPresentDansLePanier > 0:
|
||||
self.panier.insert(index, (element, nombreDeFoisPresentDansLePanier))
|
||||
|
||||
___affichagePanier() # met-à-jour le panier
|
||||
__affichagePanier() # met-à-jour le panier
|
||||
|
||||
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:
|
||||
|
@ -388,7 +389,7 @@ class GesMag:
|
|||
|
||||
Label(ticket, text=f"Date de vente : {date.today().strftime('%Y/%m/%d')}").grid(column=0, row=0, pady=ecart)
|
||||
|
||||
def ___affichagePanier():
|
||||
def __affichagePanier():
|
||||
"""Affiche le panier actuel dans le ticket de caisse."""
|
||||
self.panierAffichage.destroy()
|
||||
self.panierAffichage = Frame(ticket)
|
||||
|
@ -409,11 +410,39 @@ class GesMag:
|
|||
|
||||
elementsAchetes.config(text=f"Élément{'s' if compteurElements > 1 else ''} acheté{'s' if compteurElements > 1 else ''} ({compteurElements}) :")
|
||||
|
||||
try: # désactive le bouton si rien n'est dans le panier
|
||||
if len(self.panier) <= 0:
|
||||
validationTicketDeCaisseBouton.config(state="disabled")
|
||||
else:
|
||||
validationTicketDeCaisseBouton.config(state="active")
|
||||
except NameError: # si pas renseigné, alors = panier vide, déjà désactiver
|
||||
pass
|
||||
|
||||
Label(self.panierAffichage, text=f"Prix total : {__formatPrix(prixTotal)}").grid(column=0, pady=ecart, columnspan=2)
|
||||
|
||||
___affichagePanier()
|
||||
__affichagePanier()
|
||||
|
||||
Button(ticket, text="Valider le\nticket de caisse", font=self.font).grid(column=0, pady=ecart)
|
||||
def __validationTicketDeCaisse():
|
||||
"""Lance plusieurs méthodes pour valider le ticket de caisse."""
|
||||
# Met à jour la valeur dans le fichier `CSV`
|
||||
Stats().miseAJourStatsUtilisateur(id, sum([element[0]["prix"] * element[1] for element in self.panier]))
|
||||
|
||||
# Informe l'utilisateur que tout est validé
|
||||
showinfo("Validation", "Ticket de caisse validé !")
|
||||
|
||||
# Retire les éléments renseigné dans le panier du stock
|
||||
for element in self.panier:
|
||||
Stock().suppressionStocks(element[0]["id"], element[1])
|
||||
|
||||
# Remet le panier à 0
|
||||
self.panier = []
|
||||
|
||||
# Met-à-jour le panier et le tableau du stock
|
||||
__affichagePanier()
|
||||
__affichageTableau()
|
||||
|
||||
validationTicketDeCaisseBouton = Button(ticket, text="Valider le\nticket de caisse", font=self.font, command=__validationTicketDeCaisse, state="disabled")
|
||||
validationTicketDeCaisseBouton.grid(column=0, pady=ecart)
|
||||
|
||||
# -> Partie ajout élément au stock
|
||||
def __ajouterElementStock():
|
||||
|
@ -544,7 +573,7 @@ class GesMag:
|
|||
Button(self.f, text="Ajouter un élément\nau stock", font=self.font, command=__ajouterElementStock).grid(column=1, row=2)
|
||||
|
||||
# -> Partie export des statistiques
|
||||
Button(self.f, text="Exporter les statistiques", font=self.font).grid(column=0, row=2, sticky='e', padx=ecart)
|
||||
Button(self.f, text="Exporter les statistiques", font=self.font, command=lambda: Stats().exporteCSV(id, True)).grid(column=0, row=2, sticky='e', padx=ecart)
|
||||
|
||||
# -> Boutton pour passer en mode manager si la personne est un manager
|
||||
if caissier["metier"] == 0:
|
||||
|
|
31
stats.py
31
stats.py
|
@ -1,9 +1,23 @@
|
|||
import csv
|
||||
|
||||
from datetime import date, timedelta
|
||||
|
||||
from users import Utilisateurs
|
||||
|
||||
class Stats(Utilisateurs):
|
||||
"""Gère les statistiques et son export en format CSV."""
|
||||
def __init__(self):
|
||||
super().__init__(r"db.sqlite3")
|
||||
def creationCSV(self):
|
||||
"""Créer le fichier `CSV` qui stockera les statistiques pour tous les utilisateurs."""
|
||||
if not self.fichierExiste("stats.csv"):
|
||||
entete = ["id", "pseudo"]
|
||||
dateAujourdHui = date.today()
|
||||
for _ in range(0, 8):
|
||||
entete.append(dateAujourdHui)
|
||||
dateAujourdHui = dateAujourdHui - timedelta(days=1)
|
||||
|
||||
with open("stats.csv", 'w') as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow(entete)
|
||||
|
||||
def miseAJourStatsUtilisateur(self, utilisateurID: int, prix: float):
|
||||
"""
|
||||
|
@ -19,17 +33,18 @@ class Stats(Utilisateurs):
|
|||
|
||||
Procéder normalement consiste à ajouter le prix au prix totale stocké dans la base de donnée.
|
||||
"""
|
||||
print(prix)
|
||||
pass
|
||||
|
||||
def exportCSV(self, utilisateurID: int, mode: bool = False):
|
||||
def exporteCSV(self, utilisateurID: int, mode: bool = False):
|
||||
"""
|
||||
Exporte les statistiques d'un utilisateur dans un fichier `CSV`.
|
||||
|
||||
Deux modes :
|
||||
- `False` : exporte dans le fichier globale (qui contient tous les utilisateurs, utilisés
|
||||
par l'histogramme de l'interface du Manager)
|
||||
- si le fichier `CSV` ne contient aucune donnée de l'utilisateur, on créer
|
||||
le fichier (sa structure, etc.) et on y rajoute les données de l'utilisateur
|
||||
- si le fichier `CSV` ne contient aucune donnée de l'utilisateur, on y rajoute les
|
||||
données de l'utilisateur
|
||||
- ne garde qu'un historique des 7 derniers jours maximum
|
||||
- `True` : exporte dans un fichier séparé l'utilisateur choisie (demande à l'utilisateur
|
||||
où il souhaite que le fichier soit exporté) - (utilisé par le bouton d'exportation de
|
||||
|
@ -37,3 +52,9 @@ class Stats(Utilisateurs):
|
|||
- A savoir : n'exporte que l'état actuel de la base de donnée
|
||||
"""
|
||||
pass
|
||||
|
||||
def miseAJourDatesCSV(self):
|
||||
"""Mets-à-jour les dates trop anciennes du fichier globales `CSV`."""
|
||||
with open("stats.csv", 'r') as f:
|
||||
fichier = csv.DictReader(f)
|
||||
print(fichier)
|
||||
|
|
18
stock.py
18
stock.py
|
@ -91,13 +91,23 @@ class Stock(BaseDeDonnees):
|
|||
self.requete(requete, [typeElement.lower(), nom.lower(), quantite, prix, imageURL])
|
||||
return self.affichageResultat(self.requete("SELECT last_insert_rowid();"))
|
||||
|
||||
def suppressionStocks(self, id: int) -> None:
|
||||
def suppressionStocks(self, id: int, quantiteARetirer: int) -> None:
|
||||
"""Supprime un stock."""
|
||||
requete = """
|
||||
DELETE FROM stocks
|
||||
requeteA = """
|
||||
SELECT quantite FROM stocks
|
||||
WHERE id = ?
|
||||
"""
|
||||
self.requete(requete, id)
|
||||
quantiteActuelle: int = self.affichageResultat(self.requete(requeteA, id))[0][0]
|
||||
if quantiteActuelle <= quantiteARetirer: # il ne reste plus rien
|
||||
quantiteFinale = 0
|
||||
else: # il reste quelque chose
|
||||
quantiteFinale = quantiteActuelle - quantiteARetirer
|
||||
requeteB = """
|
||||
UPDATE stocks
|
||||
SET quantite = ?
|
||||
WHERE id = ?
|
||||
"""
|
||||
self.requete(requeteB, [quantiteFinale, id])
|
||||
|
||||
def listeStocks(self) -> list:
|
||||
"""Retourne la liste des éléments en stock sous forme de dictionnaire."""
|
||||
|
|
Reference in a new issue