Verified Commit 60b113ba authored by Robin Trioux's avatar Robin Trioux Committed by Sli
Browse files

status bar

parent 20220937
......@@ -16,3 +16,5 @@ transactionHistory.json
*.zip
data
venv/
*.svg
*.dot
......@@ -152,13 +152,11 @@ class QInfoNFC(QGroupBox):
observer = QCardObserver()
if observer.hasCard() is True:
cardUID = observer.cardUID
response = requestUserHistory(toHexString(cardUID), -1) # Ask for the 10 last user transactions
response = requestUserHistory(toHexString(cardUID), -1) # Ask for the whole user's history
self.userInfoTree = QUserHistory(["ID", "Prix"], response)
self.userInfoTree.show()
center(self.userInfoTree)
print(response)
class QSearchBar(QWidget):
"""Fast Search Bar"""
......@@ -632,31 +630,6 @@ class QCounter(QWidget):
QTimer.singleShot(10, self.searchBar.clearText) # The timer is helpfull here because it ensure the text is set BEFORE clearing it
self.basketTree.updateBasket()
# OBSOLETE
def __getItemList(self):
itemList = []
self.__parseDictionary(self.__getItemDictionary(self.jsonFileName), itemList)
return itemList
# OBSOLETE
def __getItemDictionary(self, jsonFileName):
try:
with open(jsonFileName, "r") as file:
return json.load(file)
except:
# rise some error:
print("ERROR: Can't read the file", jsonFileName)
# OBSOLETE
def __parseDictionary(self, data, itemList):
if isFinalNode(data) is False:
for i in data:
if isFinalNode(data[i]) is True:
data[i]["name"] = i
self.__parseDictionary(data[i], itemList)
else:
itemList.append(data["uid"])
def OpenNFCDialog(self):
if self.basketTree.basket != {}:
cardHandler = QCardObserver()
......@@ -695,6 +668,7 @@ class QCounter(QWidget):
response = requestBuy(cardUID, config.counterID, MAC, self.basketTree.basket)
if response:
print("Paiement effectué avec succès")
connector.statusBarshowMessage("Paiement effectué")
transaction = {"cardUID": cardUID, "basket": self.basketTree.basket, "price": self.basketTree.totalPrice, "time": datetime.datetime.now().strftime("%H:%M:%S")}
self.historyTree.addTransaction(response["transaction_id"], transaction)
connector.updateBalanceInfo(response["user_balance"])
......@@ -702,12 +676,14 @@ class QCounter(QWidget):
self.basketTree.clearBasket()
else:
print("Paiement refusé")
connector.statusBarshowMessage("Solde insuffisant")
self.warningDialog = QMessageBox(QMessageBox.Warning, "Solde insuffisant", "Veuillez recharger la carte", QMessageBox.Ok)
self.warningDialog.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxWarning))
self.warningDialog.show()
center(self.warningDialog)
else:
print("Empty basket")
connector.statusBarshowMessage("Panier vide")
self.warningDialog = QMessageBox(QMessageBox.Warning, "Panier vide", "Veuillez sélectionner des articles avant de valider la commande", QMessageBox.Ok)
self.warningDialog.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxWarning))
self.warningDialog.show()
......@@ -724,6 +700,7 @@ class QCounter(QWidget):
response = requestBuy(toHexString(cardUID), config.counterID, MAC, self.basketTree.basket)
if response:
print("Paiement effectué avec succès")
connector.statusBarshowMessage("Paiement effectué")
transaction = {"cardUID": toHexString(cardUID), "basket": self.basketTree.basket, "price": self.basketTree.totalPrice, "time": datetime.datetime.now().strftime("%H:%M:%S")}
self.historyTree.addTransaction(response["transaction_id"], transaction)
connector.updateBalanceInfo(response["user_balance"])
......@@ -731,12 +708,14 @@ class QCounter(QWidget):
self.basketTree.clearBasket()
else:
print("Paiement refusé")
connector.statusBarshowMessage("Solde insuffisant")
self.warningDialog = QMessageBox(QMessageBox.Warning, "Solde insuffisant", "Veuillez recharger la carte", QMessageBox.Ok)
self.warningDialog.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxWarning))
self.warningDialog.show()
center(self.warningDialog)
else:
print("Empty basket")
connector.statusBarshowMessage("Panier vide")
self.warningDialog = QMessageBox(QMessageBox.Warning, "Panier vide", "Veuillez sélectionner des articles avant de valider la commande", QMessageBox.Ok)
self.warningDialog.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxWarning))
self.warningDialog.show()
......@@ -1303,9 +1282,14 @@ class QMainMenu(QMainWindow):
# Toolbar
self.statusBar() # Built in function that show menu bar
connector = QConnector()
connector.statusBar = self.statusBar()
self.counterLabel = QLabel()
self.counterLabel.setText(self.counterActionGroup.checkedAction().text())
try:
self.counterLabel.setText(self.counterActionGroup.checkedAction().text())
except:
print("No counter found")
self.statusBar().addPermanentWidget(self.counterLabel)
def ForceHistoryRefresh(self):
......@@ -1340,7 +1324,8 @@ class QMainMenu(QMainWindow):
print("Local item file not found")
self.MainTab.TabCounter.productTree.treeModel.updateModel(itemRegister.itemTree)
self.statusBar().showMessage("Comptoir: " + self.counterActionGroup.checkedAction().text())
connector = QConnector()
connector.statusBarshowMessage("Comptoir: " + self.counterActionGroup.checkedAction().text())
# self.MainTab.TabCounter.productTree.treeModel.layoutChanged.emit()
......
......@@ -34,24 +34,33 @@ class QUserHistoryModel(QTreeModel):
self.itemList = []
buyItem = Item(["Achats", ""], self.rootItem)
transactionItem = Item(["Transactions", ""], self.rootItem)
transactionItem = Item(["Rechargements", ""], self.rootItem)
self.rootItem.appendChild(buyItem)
self.rootItem.appendChild(transactionItem)
try:
for i in data:
i["transactionUID"] = i["id"]
for i in data: # for each transaction in user's history
i["transactionUID"] = i["id"] # TODO : Basicly this kind of shit should be avoided
i["cardUID"] = i["user_UID"]
i["basket"] = {"Objet": 1}
# Should also be avoided, this happen because
# the response is formated {["product_code":XXX,"quantity":YYY]}
# but my programm excpect {"product_code":quantity}
dico = {}
for j in i["shopping_cart"]:
dico[j["product_code"]] = j["quantity"]
if i["shopping_cart"] == []: # It's a transaction
i["text"] = [str(i["id"]), euro(i["amount"])]
i["price"] = i["amount"]
i["basket"] = {"Rechargement": 1}
child = Item(i, transactionItem)
transactionItem.appendChild(child)
else: # It's a buy
i["text"] = [str(i["id"]), euro(-i["amount"])]
i["price"] = -i["amount"]
i["basket"] = dico
child = Item(i, buyItem)
buyItem.appendChild(child)
# self.transactionList[i["id"]] = i
......
......@@ -64,7 +64,6 @@ class QBasket(QWidget):
self.treeModel.priceChanged.connect(self.updateBasket)
def clearBasket(self):
buttonList = copy.copy(self.delButtonList)
......@@ -124,12 +123,8 @@ class QBasket(QWidget):
def selectItem(self, item):
data = item.internalPointer().getText()
if len(data) > 1:
if len(data) > 1: # If that's an end node (category don't have price)
if data[1] != "":
# errorDialog=QErrorDialog("WTF ?")
# center(errorDialog)
# errorDialog.exec()
# index = self.treeView.selectionModel().currentIndex()
model = self.treeModel
if self.hasProductUID(item.internalPointer().data["uid"]) == -1: # if the selected item already exist in the basket
......@@ -217,7 +212,7 @@ class QBasket(QWidget):
def keyPressEvent(self, event):
try:
#TODO: Set multiple selection/deletion possible
# TODO: Set multiple selection/deletion possible
if event.key() == Qt.Key_Delete:
row = self.treeView.selectedIndexes()[0].row()
button = self.delButtonList[row]
......@@ -231,7 +226,6 @@ class QAbstractHistory(QWidget):
super().__init__(parent)
# Definitions
config = MachineConfig()
self.transactionInfo = QBuyInfoDialog # Not instancied on purpose
......@@ -242,8 +236,6 @@ class QAbstractHistory(QWidget):
self.transactionList = {}
self.historyFileName = "defaultHistory.json"
# print(response)
self.recoverHistory()
# Settings
......@@ -263,14 +255,13 @@ class QAbstractHistory(QWidget):
self.treeView.doubleClicked[QModelIndex].connect(self.showTransactionInfo)
def showTransactionInfo(self, modelIndex):
if modelIndex.internalPointer().childCount() == 0:
observer = QCardObserver()
self.transactionInfo = QBuyInfoDialog(modelIndex)
self.transactionInfo.cancelButton.clicked.connect(self.removeSelectedTransaction)
self.transactionInfo.setWindowTitle("Information transaction")
# self.transactionInfo.setWindowTitle("Information transaction")
self.transactionInfo.forceRefresh()
self.transactionInfo.show()
......@@ -280,6 +271,7 @@ class QAbstractHistory(QWidget):
model = self.treeModel
index = self.transactionInfo.selectedIndex
connector = QConnector()
try:
if self.transactionInfo.cancelTransaction() is False:
return
......@@ -291,9 +283,14 @@ class QAbstractHistory(QWidget):
except:
pass
if not model.removeRows(index.row(), 1, index.parent()):
pass
connector.statusBarshowMessage("Échec de suppression de la transaction")
else:
connector.statusBarshowMessage("Suppression de la transaction")
except:
popUp = QErrorDialog("Échec de l'opération", "Transaction introuvable", "Il semble que cette transaction ait déjà été annulée")
center(popUp)
popUp.exec()
print("ERROR: Unable to remove transaction")
def forceRefresh(self):
......@@ -309,14 +306,42 @@ class QAbstractHistory(QWidget):
class QUserHistory(QAbstractHistory):
def __init__(self, headers, data=None, parent=None):
self.treeModel = QUserHistoryModel(headers,data)
super().__init__(headers, data,parent)
self.treeModel = QUserHistoryModel(headers, data)
super().__init__(headers, data, parent)
self.treeView.expandAll()
self.forceRefresh()
self.setWindowTitle("Historique utilisateur")
self.setWindowIcon(self.style().standardIcon(QStyle.SP_MessageBoxInformation))
def recoverHistory(self):
pass
def showTransactionInfo(self, modelIndex):
if modelIndex.internalPointer().childCount() == 0:
if modelIndex.parent().row() == 0: # If it's in the buy section
self.transactionInfo = QBuyInfoDialog(modelIndex)
self.transactionInfo.cancelButton.clicked.connect(self.removeSelectedTransaction)
self.transactionInfo.forceRefresh()
self.transactionInfo.setWindowTitle("Information transaction")
self.transactionInfo.show()
center(self.transactionInfo)
elif modelIndex.parent().row() == 1: # If it's a transaction (refilling)
self.transactionInfo = QTransactionInfoDialog(modelIndex)
self.transactionInfo.cancelButton.clicked.connect(self.removeSelectedTransaction)
self.transactionInfo.setWindowTitle("Information transaction")
if self.transactionInfo.treeModel:
self.transactionInfo.forceRefresh()
self.transactionInfo.show()
center(self.transactionInfo)
class QBarHistory(QAbstractHistory):
def __init__(self, headers, data=None, parent=None):
......@@ -354,9 +379,9 @@ class QBarHistory(QAbstractHistory):
for j in i["shopping_cart"]:
basket[j["product_code"]] = j["quantity"]
#TODO: Serialize the time on the SERVER OR use the standard function for parse string-> datetime parsing
# TODO: Serialize the time on the SERVER OR use the standard function for parse string-> datetime parsing
# Please close your eyes here ...
time=i["time"].split(' ')[4]
time = i["time"].split(" ")[4]
history[i["id"]] = {"cardUID": i["user_UID"], "basket": basket, "price": -i["amount"], "time": time}
else: # if it's a refilling
pass
......@@ -394,8 +419,8 @@ class QBarHistory(QAbstractHistory):
child.internalPointer().data["cardUID"] = cardUID
child.internalPointer().data["transactionUID"] = uid
child.internalPointer().data["price"] = price
#TODO: Ask the transaction time to the server, else if the client has to reboot, the printed time will be wrong
h,m,s= QTime.currentTime().hour(), QTime.currentTime().minute(), QTime.currentTime().second()
# TODO: Ask the transaction time to the server, else if the client has to reboot, the printed time will be wrong
h, m, s = QTime.currentTime().hour(), QTime.currentTime().minute(), QTime.currentTime().second()
child.internalPointer().data["time"] = transaction["time"]
child.internalPointer().data["text"] = [cardUID.replace(" ", ""), euro(price), ""]
self.forceRefresh()
......
......@@ -22,6 +22,10 @@ from smartcard.System import readers as rd
from smartcard.scard import SCardReleaseContext
# ReaderObserver
from smartcard.ReaderMonitoring import ReaderMonitor, ReaderObserver
class NFC_Reader_Error(Exception):
pass
......@@ -120,3 +124,24 @@ class QCardObserver(QObject, CardObserver, metaclass=QCardObserverSingleton):
self.cardUID = [0, 0, 0, 0]
self.__hasCard = False
self.cardRemoved.emit()
# Allow the user to connect and disconect the reader whenerver he wants
class printobserver(ReaderObserver):
"""A simple reader observer that is notified
when readers are added/removed from the system and
prints the list of readers
"""
def update(self, observable, actions):
(addedreaders, removedreaders) = actions
cardObserver = QCardObserver()
cardObserver.cardReader = getReader()
print("Added readers", addedreaders)
print("Removed readers", removedreaders)
# TODO: Make something more "standard" regarding the rest of the code
readermonitor = ReaderMonitor()
readerobserver = printobserver()
readermonitor.addObserver(readerobserver)
......@@ -264,10 +264,14 @@ class QConnector(QObject, metaclass=QConnectorSingleton):
def __init__(self):
QObject.__init__(self)
self.statusBar = None
def updateBalanceInfo(self, newBalance):
self.balanceInfoUpdated.emit(newBalance)
def statusBarshowMessage(self, message, timeout=3000):
self.statusBar.showMessage(message, timeout)
class QAbstractInputDialog(QWidget):
def __init__(self, questionText, parent=None):
......
from IHM import *
# TODO: ENSURE BALANCE CAN'T HAVE ABSURDS VALUES (eg: 16.33333...)
# TODO: FIX MULTI-USER PANEL
# TODO: UNIFY KEY NAME BITWEEN THE SERVER AND THE CLIENT
# TODO: MAKE AUTOMATIC GRAPH
# TODO: FIND A EASIER WAY TO HANDLE TREEMODELS AND STUFF...
# TODO: ADD WARNING WHEN ADD HUGE AMOUNT ON CARDS
# TODO: HANDLE TRANSLATION
# TODO: ADD A TOOLBAR STATUS SINGLETON HANDLER [OK VIA QCONNECTOR]
# TODO: HANDLE CARD READER PLUG/UNPLUG [OK]
if __name__ == "__main__":
# Première étape : création d'une application Qt avec QApplication
# afin d'avoir un fonctionnement correct avec IDLE ou Spyder
# on vérifie s'il existe déjà une instance de QApplication
app = QApplication.instance()
if not app: # sinon on crée une instance de QApplication
if not app:
app = QApplication(sys.argv)
MainWindow = QMainMenu()
# FakeCard = QFakeCard()
# FakeCard.LinkWidget(MainWindow.MainTab.TabCounter.NFCDialog)
# W.Layout.addStretch(1)
# la fenêtre est rendue visible
# MainWindow.showMaximized()
MainWindow.show()
# FakeCard.show()
# exécution de l'application, l'exécution permet de gérer les événements
app.exec_()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment