Commit 82d2a222 authored by Robin Trioux's avatar Robin Trioux
Browse files

Buyings half completed

parent 53fff28c
......@@ -238,12 +238,11 @@ class Product(Atom):
def __eq__(self, key):
result = True
result = result and self.getId() == key.getId()
# result = result and self.getName() == key.getName()
# result = result and self.getCode() == key.getCode()
# result = result and self.getPrice() == key.getPrice()
return result
if type(self) == type(key):
return self.getId() == key.getId()
else:
return False
def __repr__(self):
return "Product({0}, {1})".format(self.id,self.name)
......@@ -287,12 +286,17 @@ class Operation(Atom):
def getDate(self):
return self.date
def __eq__(self, key):
if type(self) == type(key):
return self.getId() == key.getId()
else:
return False
class Buying(Operation):
def __init__(self):
super().__init__()
self.price = None # price the customer(s) actually paid
self.payments = None # List of all payment for this order since several users maybe concerned
self.distribution = None # List of all payment for this order since several users maybe concerned
self.basketItems = None # List of "Product", their unit price should be download from the history
self.label = None # human readable description gave by the server
......@@ -300,8 +304,8 @@ class Buying(Operation):
self.price = price
return self
def setPayment(self, payments):
self.payments = payments
def setDistribution(self, distribution):
self.distribution = distribution
return self
def setBasketItems(self, basketItems):
......@@ -311,8 +315,8 @@ class Buying(Operation):
def getPrice(self):
return self.price
def getPayments(self):
return self.payments
def getDistribution(self):
return self.distribution
def getBasketItems(self):
return self.basketItems
......@@ -366,7 +370,10 @@ class Counter(Atom):
return "{0}: {1}".format(self.id,self.name)
def __eq__(self, key):
return key.getId() == self.getId() and key.getName() == self.getName()
if type(self) == type(key):
return key.getId() == self.getId() and key.getName() == self.getName()
else:
return False
class Distribution(Atom):
def __init__(self):
......@@ -386,6 +393,10 @@ class Distribution(Atom):
def addUser(self,uid):
self.userList.append(uid)
return self
def addAmount(self, amount):
self.amount.append(amount)
return self
def removeUser(self,uid):
try:
......
......@@ -57,7 +57,38 @@ class Client(metaclass=ClientSingleton):
repeated Payment payments
repeated BasketItem basket
"""
pass
try:
payments = kwargs['payments']
basket = kwargs['basket']
newPayments = []
newBasket = []
for qProduct in basket:
product = qProduct.getAtom()
newBasket.append(packProduct(product))
kwargs['basket'] = newBasket
kwargs['payments'] = packDistribution(kwargs['payments'])
buyingRequest = com_pb2.BuyingRequest(**kwargs)
buyingReply = self.stub.Buy(buyingRequest)
self.now = unpackTime(buyingReply.now)
if buyingReply.status == com_pb2.BuyingReply.SUCCESS :
transaction = buyingReply.transaction
buying = unpackBuying(transaction)
elif buyingReply.status == com_pb2.BuyingReply.NOT_ENOUGH_MONEY:
printW("Not enough money")
return None
return buying
except RpcError:
pass
def requestRefilling(self, **kwargs):
......@@ -78,9 +109,6 @@ class Client(metaclass=ClientSingleton):
com_pb2.OTHER]
kwargs['payment_method'] = paymentMethodList[kwargs['payment_method']]
kwargs['amount'] = packMoney(kwargs['amount'])
print(kwargs)
print(type(kwargs['payment_method']))
print(type(kwargs['amount']))
refillingRequest = com_pb2.RefillingRequest(**kwargs)
refillingReply = self.stub.Refill(refillingRequest)
self.now = unpackTime(refillingReply.now)
......
......@@ -41,7 +41,7 @@ class QBuyingInfo(QWidget):
self.mainLayout.addLayout(self.buttonLayout,1,0,1,2)
self.userRowInfo.addRow("UID",)
#self.userRowInfo.addRow("UID",)
self.buttonLayout.addWidget(self.editButton)
self.buttonLayout.addWidget(self.deleteButton)
......
......@@ -113,6 +113,42 @@ class QCounterTab(QWidget):
#signals
self.itemSelector.itemSelected[Product].connect(self.basket.addProduct)
self.singleUserButton.clicked.connect(self.showNFCDialog)
def showNFCDialog(self):
nfcm = QNFCManager()
if not nfcm.hasCard():
nfcDialog = QNFCDialog()
nfcDialog.setModal(True)
nfcDialog.cardInserted.connect(self.singleUserPay)
nfcDialog.exec_()
else:
self.singleUserPay()
def singleUserPay(self):
printI("payment")
client = Client()
dm = QDataManager()
nfcm = QNFCManager()
productList = self.basket.getProductList()
totalPrice = Eur(0)
for product in productList:
totalPrice += product.getPrice()*product.getQuantity()
distribution = Distribution()
distribution.addUser(nfcm.getCardUID())
distribution.addAmount(totalPrice)
try:
response = client.requestBuy(counter_id=dm.getCounter().getId(),device_uuid=dm.getUID(),payments=distribution,basket=productList)
if response:
self.basket.clear()
else:
QWarningDialog("Solde insuffisant","Le solde utilisateur est insufisant","Veuillez recharger votre carte")
except:
printE("Something happen, transaction failed. Please try again")
......@@ -64,7 +64,7 @@ class QBasketModel(QTreeModel):
for child in childList:
productList.append(child.getData())
#if the product is already in the basket
if product in productList:
if qProduct in productList:
#I use my own reseach function because the 'match' function from Qt bases it research on the text field
#by default, I should reimplement 'match', but I prefer use my own search function
index,item,data = self.searchQAtom(qProduct)
......
......@@ -115,8 +115,6 @@ class QBasket(QItemTree):
self.mainLayout = QVBoxLayout()
self.treeView = QSuperTreeView()
self.treeModel = QBasketModel(["Article","Quantité","Prix",""])
#Layout
self.mainLayout.addWidget(self.treeView)
......@@ -132,6 +130,14 @@ class QBasket(QItemTree):
self.treeModel.addProduct(newProduct, self.treeView) #Insert the atom to the top. (No choice but give the treeview to add indexWidget...)
self.forceRefresh() #Resize column to content for each columns
def getProductList(self):
return self.treeModel.getQAtomList()
def clear(self):
n_row = self.treeModel.rowCount()
for i in range(n_row):
self.treeModel.removeRow(0)
class QHistory(QItemTree):
def __init__(self, parent = None):
......
......@@ -26,8 +26,10 @@ class QAbstractPayment(QGroupBox):
self.paymentMethod = None
self.strictPositive = True
self.inputLine = QAutoSelectLineEdit()
self.okButton = QPushButton()
self.credited.connect(self.clear)
self.inputLine.returnPressed.connect(self.setFocusOnOk)
def getPaymentMethod(self):
return self.paymentMethod
......@@ -88,7 +90,12 @@ class QAbstractPayment(QGroupBox):
def clear(self):
self.inputLine.setText(Eur(0))
def setFocusOnOk(self):
self.okButton.setFocus()
class QCreditCardPayment(QAbstractPayment):
enterPressed = pyqtSignal()
def __init__(self, parent=None):
super().__init__(parent)
self.paymentMethod = 2
......@@ -101,7 +108,6 @@ class QCreditCardPayment(QAbstractPayment):
self.mainGridLayout = QGridLayout()
self.label = QLabel()
self.okButton = QPushButton()
# Settings
......@@ -128,9 +134,11 @@ class QCreditCardPayment(QAbstractPayment):
self.inputLine.returnPressed.connect(self.formatInput)
class QCashPayment(QAbstractPayment):
def __init__(self, parent=None):
super().__init__(parent)
#Definition
self.paymentMethod = 1
self.mainGridLayout = QGridLayout()
self.mainVBoxLayout = QVBoxLayout()
......@@ -143,7 +151,6 @@ class QCashPayment(QAbstractPayment):
self.setTitle("Paiement par espèce")
self.label = QLabel()
self.okButton = QPushButton()
# Settings
......@@ -159,7 +166,7 @@ class QCashPayment(QAbstractPayment):
self.moneyIn.setAlignment(Qt.AlignCenter)
self.moneyInLabel.setText("Argent reçu:")
# Link
# Layout
self.mainGridLayout.addWidget(self.label, 0, 0, Qt.AlignLeft)
self.mainGridLayout.addWidget(self.inputLine, 0, 1, Qt.AlignLeft)
......@@ -354,6 +361,7 @@ class QRefillerTab(QWidget):
def selectOther(self):
if self.otherPaymentRadio.isChecked():
self.paymentLayout.setCurrentWidget(self.otherPayment)
def credit(self, amount):
nfcm = QNFCManager()
......
......@@ -261,8 +261,9 @@ class QTreeModel(QAbstractItemModel):
return self.createIndex(parentItem.row(), 0, parentItem)
def setupModelData(self, data):
raise NotImplementedError()
def setupModelData(self, atomList):
for atom in atomList:
self.insertAtom(0,atom)
# Mandatory functions for editable tree
......
......@@ -2,7 +2,7 @@ import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import QIcon
from PyQt5.QtGui import QIcon,QMovie
from Console import *
#copy is mandatory because of the init of path
#indeed ... A= [X,Y]
......@@ -24,9 +24,11 @@ class QUIManager(QObject, metaclass=QUIManagerSingleton):
self.themeRelPath =["ressources","themes",self.theme]
self.iconRelPath = copy.deepcopy (self.themeRelPath)
self.windowIconRelPath = copy.deepcopy(self.themeRelPath)
self.animationRelPath = copy.deepcopy(self.themeRelPath)
self.iconRelPath.append("ui-icons")
self.windowIconRelPath.append("window-icons")
self.animationRelPath.append("animation")
def getIcon(self, iconName):
"""Return the QIcon according to 'iconName'. None if no icon is found"""
......@@ -59,6 +61,20 @@ class QUIManager(QObject, metaclass=QUIManagerSingleton):
return icon
def getAnimation(self, animationName):
"""Return the QIcon according to 'iconName'. None if no icon is found"""
animationPath = self.__relPath(self.animationRelPath)
fileList = os.listdir(animationPath)
movie = None
for file in fileList:
name = file.split('.')[0] # [name, extention]
if name == animationName:
try:
movie = QMovie(animationPath+file)
except:
printE("Unable to load the ressource {}".format(file))
return movie
def __relPath(self,pathList):
#print(pathList)
......
......@@ -12,6 +12,7 @@ from Atoms import *
from Euro import Eur
from QNFCManager import QNFCManager
from QUIManager import QUIManager
from Client import Client
#def euro(price):
......@@ -26,7 +27,38 @@ def center(self):
self.move(qr.topLeft())
class QNFCDialog(QDialog):
cardInserted = pyqtSignal()
def __init__(self, parent = None):
super().__init__(parent)
uim = QUIManager()
nfcm = QNFCManager()
#Definition
self.mainLayout = QVBoxLayout()
self.label = QLabel()
self.setFixedSize(450,400)
#Layout
self.mainLayout.addWidget(self.label)
self.setLayout(self.mainLayout)
nfcm.cardInserted.connect(self.proceed)
#Setup
movie = uim.getAnimation("show-card-animation")
self.label.setMovie(movie)
movie.start()
self.setWindowTitle("Veuillez présenter une carte devant le lecteur")
self.setWindowIcon(uim.getIcon("nfc-icon"))
center(self)
def proceed(self):
self.cardInserted.emit()
self.done(0)
class QRowInfo(QWidget):
def __init__(self, parent=None):
......
......@@ -53,20 +53,13 @@ def unpackProduct(pb_product: com_pb2.Product) -> Product:
return newProduct
def packMoney(euro: Eur) -> com_pb2.Money:
strEuro = str(euro).replace('€','').replace(' ','').replace(',','.')
money = com_pb2.Money(amount = strEuro)
return money
def decimal_to_pb_money(dec: decimal.Decimal) -> com_pb2.Money:
tup = dec.as_tuple()
return com_pb2.Money(sign=tup.sign, exponent=tup.exponent, digits=tup.digits)
return decimal_to_pb_money(euro._amount)
def unpackMoney(money: com_pb2.Money) -> Eur:
def pb_money_to_decimal(money: com_pb2.Money) -> decimal.Decimal:
return decimal.Decimal(
decimal.DecimalTuple(
sign=money.sign, digits=money.digits, exponent=money.exponent
)
)
return Eur(pb_money_to_decimal(money))
return Eur(money.amount)
def packCounter(counter: Counter) -> com_pb2.CounterListReply.Counter:
pass #should not be usefull
......@@ -80,19 +73,38 @@ def unpackCounter(pb_counter: com_pb2.CounterListReply.Counter) -> Counter:
def packDistribution(distrib: Distribution) -> [com_pb2.Payment]:
paymentList = []
for user in distrib.getUserList():
amount = distrib.getUserAmount(user)
amount = packMoney(distrib.getUserAmount(user))
newPayement = com_pb2.Payment(customer_id = user, amount=amount)
paymentList.append(newPayement)
return paymentList
def unpackDistribution(payments: [com_pb2.Payment]) -> Distribution:
distribution = Distribution()
for payment in payments:
distribution.addUser(payment.customer_id)
distribution.addAmount(unpackMoney(payment.amount))
return distribution
def unpackRefilling(pb_refilling: com_pb2.Refilling) -> Refilling:
newRefilling = Refilling()
#newRefilling.setId() #Not implemented by server yet
newRefilling.setId(pb_refilling.id)
newRefilling.setCustomerId(pb_refilling.customer_id)
newRefilling.setCounterId(pb_refilling.counter_id)
newRefilling.setAmount(unpackMoney(pb_refilling.amount))
newRefilling.setRefounded(pb_refilling.cancelled)
return newRefilling
def unpackBuying(pb_buying: com_pb2.Buying) -> Buying:
buying = Buying()
buying.setId(pb_buying.id)
buying.setLabel(pb_buying.label)
buying.setPrice(unpackMoney(pb_buying.price))
buying.setRefounded(pb_buying.refounded)
buying.setCounterId(pb_buying.counter_id)
buying.setDate(unpackTime(pb_buying.date))
buying.setDistribution(unpackDistribution(pb_buying.payments))
return buying
def unpackTime(timestamp : Timestamp) -> datetime:
return Timestamp.ToDatetime(timestamp)
\ No newline at end of file
return Timestamp.ToDatetime(timestamp)
......@@ -204,7 +204,7 @@ class Buying(Model):
def generate_label(self):
self.label = ",".join(
[
"%s x %d" % (item.product.name, item.unit_price)
"%s x %d" % (item.product.name, item.quantity)
for item in self.basket_items
]
)
......
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