def emailReceipt(): """ DESCRIPTION: This route is for emailing the order receipt to user REQUEST TYPE: POST PARAMETERS: orderID: order ID to generate receipt for email: email address tp send the email to. RETURNS: success/error message """ values = request.get_json(silent=True) print(values) #get detailed order to generate receipt for orders = Mongo_Client.GetOrdersWithDetails(values["orderId"]) menus = Mongo_Client.GetAllMenu() if orders is not None and menus is not None: #generate receipt receipt = ReceiptGenerator.generateInvoice(orders, menus) print("Receipt generated") #send email if Mailer.send_mail(values["email"], receipt): print("Mail sent") return json.dumps({"success": True}) else: print("error sending mail") return json.dumps({"error": "Error sending email!"}) else: return json.dumps({"error": "Database Error!"})
def completeOrder(): """ DESCRIPTION: This route is for completing the order/payment for a specific table/customer REQUEST TYPE: POST PARAMETERS: JSON object containing payment details RETURNS: order ID of the order just closed """ #order no is accessed from the session #if it doesn't exist then, table is empty orderNo = None values = request.get_json(silent=True) if 'orderNo' in session: orderNo = session["orderNo"] #if waitress is closing the order then the order number is sent as a parameter else: orderNo = values["orderNo"] ''' elif 'role' in session: orderNo = request.args.get('orderNo') if orderNo is None: return json.dumps({ "error": "limited arguments" }) else: return json.dumps({ "error": "Unauthorized" }) ''' # orderNo = request.args.get('orderNo') print(values) print(orderNo) #update the order status to completed if Mongo_Client.UpdateOrder(orderNo, values): print("order updated") #remove the order number for session session.pop("orderNo", None) #clear the order id from the table colectition for the resoective tabel Mongo_Client.ClearTableWithOrderNo(orderNo) return json.dumps({"success": True, "orderId": orderNo}) else: return json.dumps({"error": "Database Error"})
def startOrder(): """ DESCRIPTION: This route is for starting an order when the client accesses the link REQUEST TYPE: GET PARAMETERS: tableNo: table number to start the order RETURNS: redirects to the customer portal """ if 'orderNo' not in session: tableNo = request.args.get('tableNo') print("tableNo", tableNo) #checking if already on table orderId = Mongo_Client.GetOrderNoForTable(tableNo) print(orderId) #if table has been occupied if orderId is not None: session['orderNo'] = orderId print("Table already occupied! orderNo:", orderId) return redirect("/customer") else: #get the server from the array to track turn and set it orders = { "orders": [], "tableNo": tableNo, "status": "INITIATED", "server": "BISHAL" } orderNo = Mongo_Client.StartOrder(orders) #starting a new order and setting the table as occupied if orderNo is not None: Mongo_Client.UpdateTable(tableNo, orderNo) session['orderNo'] = orderNo print("New order", orderNo) return redirect("/customer") else: return redirect("/xx") else: print("orderNo in session") return redirect("/customer")
def updateEmployee(): """ DESCRIPTION: This route is for updating information for a specific employee REQUEST TYPE: POST PARAMETERS: JSON containing the eployee details along with the username RETURNS: success message if successful else sends and Error """ #only authorized users can do this employee = request.get_json(silent=True) username = Mongo_Client.UpdateEmployee(employee) if username is not None: return json.dumps({ "success":True }) else: return json.dumps({ "error":"Database Error!" })
def getAllOrders(): """ DESCRIPTION: This route is for getting all the orders for a specific table/customer REQUEST TYPE: GET PARAMETERS: None RETURNS: list of all the orders for the specifc table/customer """ #order no is accessed from the session #if it doesn't exist then, table is empty if 'orderNo' in session: orderNo = session['orderNo'] values = request.get_json(silent=True) orders = Mongo_Client.GetOrders(orderNo) if orders is not None: return json_util.dumps({"success": True, "orders": orders}) else: return json.dumps({"error": "Database Error"}) else: return json.dumps({"error": "Unauthorized"})
def addEmployee(): """ DESCRIPTION: This route is for adding an employee to the employee collection This route can only be called by an admin REQUEST TYPE: POST PARAMETERS: JSON containing employee details to store in the databse RETURNS: username of the added employee if successful """ #only authorized users can do this employee = request.get_json(silent=True) employee['userType'] = "STAFF" username = Mongo_Client.AddEmployee(employee) if username is not None: return json.dumps({ "success":True, "username":username, }) else: return json.dumps({ "error":"Database Error!" })
def join(data): """ DESCRIPTION: This event is to notify whenever a client or waitress logs in PARAMETERS: staff: indicates whether the user is staff or client """ print(data) if data['staff']: #if its a server add them to the server list #when login is validated, this has to be called print("staff") if request.sid not in loggedInServers: loggedInServers.append(request.sid) else: #when customer page is loaded, this has to be called #we'll store the clients using their orderId because that is what the servers will send print("client") orderNo = session['orderNo'] print(orderNo) if orderNo not in loggedInClients: loggedInClients[orderNo] = request.sid #if a client joined, # get specific order, order = json_util.dumps(Mongo_Client.GetOrdersWithDetails(orderNo)) # all the servers should be notified about the new order print(loggedInServers) for server in loggedInServers: print("Sent to", server) emit('newCustomer', order, room=server)
def getAllEmployees(): """ DESCRIPTION: This route is for getting all employees in the database REQUEST TYPE: GET PARAMETERS: None RETURNS: list of all the employees in the databse """ #only authorized users can do this employees = Mongo_Client.GetAllEmployees() if employees is not None: return json_util.dumps({ "success":True, "employees":employees }) else: return json.dumps({ "error":"Databse Error!" })
def addOrders(): """ DESCRIPTION: This route is for adding menu orders to a specific order REQUEST TYPE: POST PARAMETERS: list of menu orders to add RETURNS: redirects the page based on the login role """ #order no is accessed from the session #if it doesn't exist then, table is empty if 'orderNo' in session: orderNo = session['orderNo'] values = request.get_json(silent=True) print(values) if Mongo_Client.AddOrders(values, orderNo): return json.dumps({"success": True}) else: return json.dumps({"error": "Database Error"}) else: return json.dumps({"error": "Unauthorized"})
def deleteEmployee(): """ DESCRIPTION: This route is for deleting an employee from the database REQUEST TYPE: DELETE PARAMETERS: username for the employee to delete RETURNS: success message if successful else sends and Error """ #only authorized users can do this username = request.args.get('username') if Mongo_Client.DeleteEmployee(username): return json.dumps({ "success":True }) else: return json.dumps({ "error":"Database Error!" })
def addOrders(data): """ DESCRIPTION: This event is for adding order to a table PARAMETERS: order details """ orderNo = None clientOrder = False print(data) #client made an order if 'orderNo' in session: clientOrder = True orderNo = session['orderNo'] #waitress made an order elif 'orderNo' in data: orderNo = data["orderNo"] else: send("Unauthorized") return json.dumps({"error": "Unauthorized"}) print(loggedInClients) print(loggedInServers) if Mongo_Client.AddOrders(data["orders"], orderNo): #emit to the specific client emit("Order Added", { "success": True, "orders": data["orders"] }, json=True, room=loggedInClients[orderNo]) #emit to all the servers for server in loggedInServers: print("Sent to", server) emit("Order Added", { "success": True, "data": { "orderNo": orderNo, "orders": data["orders"] } }, json=True, room=server) else: send("Error")
def addReview(): """ DESCRIPTION: This route is for adding a customer review to a menu item REQUEST TYPE: POST PARAMETERS: JSON object containing reviews and ratings and menu id for the menu RETURNS: success/error message """ values = request.get_json(silent=True) if Mongo_Client.AddReview(values["menuId"], values["review"]): return json.dumps({"success": True}) else: return json.dumps({"error": "Database Error"})
def closeOrder(): """ DESCRIPTION: This route is for closing a specific order REQUEST TYPE: POST PARAMETERS: if its the customer, None if its the waitress, order id is passed as "orderNo" RETURNS: error/success message """ #order no is accessed from the session #if it doesn't exist then, either table is empty or the waitress is closing the order orderNo = None if 'orderNo' in session: orderNo = session["orderNo"] #if waitress is closing the order then the order number is sent as a parameter else: orderNo = request.args.get('orderNo') ''' elif 'role' in session: orderNo = request.args.get('orderNo') if orderNo is None: return json.dumps({ "error": "limited arguments" }) else: return json.dumps({ "error": "Unauthorized" }) ''' # print(orderNo) if Mongo_Client.CloseOrder(orderNo): return json.dumps({"success": True}) else: return json.dumps({"error": "Database Error"})
def getReservation(): """ DESCRIPTION: This route is for getting all the reservation after the current date REQUEST TYPE: GET PARAMETERS: None RETURNS: list of all the reservations after the current date """ timeNow = datetime.datetime.now().isoformat() reservations = Mongo_Client.GetReservations(timeNow) if reservations is not None: return json.dumps({"success": True, "reservations": reservations}) else: return json.dumps({"success": False})
def addTip(): """ DESCRIPTION: This route is for adding tip for an order REQUEST TYPE: POST PARAMETERS: JSON containing tip amount RETURNS: success/error message """ values = request.get_json(silent=True) if Mongo_Client.UpdateOrder(values["orderId"], {"tip": values["tip"]}): session.pop("orderNo", None) return json.dumps({"success": True}) else: return json.dumps({"error": "Database Error"})
def getAllActiveOrders(): """ DESCRIPTION: This route is for getting all the active orders in the restaurant REQUEST TYPE: GET PARAMETERS: None RETURNS: list of all the active orders in the restaurant """ # only authorized users are allowed to do this orders = Mongo_Client.GetActiveOrders() if orders is not None: return json_util.dumps({"success": True, "orders": orders}) else: return json.dumps({"error": "Database Error"})
def getAllMenu(): """ DESCRIPTION: This route is for getting all the menus in the database REQUEST TYPE: GET PARAMETERS: None RETURNS: list of all menus in the database """ #only authorized personnel can do this menus = Mongo_Client.GetAllMenu() if menus is not None: return json_util.dumps({"success": True, "menus": menus}) else: return json.dumps({"error": "Database Error!"})
def deleteMenu(): """ DESCRIPTION: This route is for deleting a specific menu from the database REQUEST TYPE: DELETE PARAMETERS: menu ID for the menu to delete RETURNS: success message if successful else sends and error """ #only authorized personnel can do this menuId = request.args.get('menuId') if Mongo_Client.DeleteMenu(menuId): return json.dumps({"success": True}) else: return json.dumps({"error": "Database Error!"})
def updateMenu(): """ DESCRIPTION: This route is for updating specific menu in the database REQUEST TYPE: POST PARAMETERS: JSON object including the updated data along with menu ID RETURNS: success message if successful else sends and error """ #only authorized personnel can do this menu = request.get_json(silent=True) if Mongo_Client.UpdateMenu(menu): return json.dumps({"success": True}) else: return json.dumps({"error": "Database Error!"})
def login(): """ DESCRIPTION: This route is for logging out users which is removing the username from session. REQUEST TYPE: POST PARAMETERS: { username : <username>, password: <password>} RETURNS: redirects the page based on the login role """ #getting the parameters from the request value = request.get_json(silent=True) #checking if the username exists and fetching the hashed password correctCred = Mongo_Client.GetCredentials(value['username']) print(correctCred) #checking if the password match if (correctCred is not None and Hasher.ValidatePassword( value['password'], correctCred['password'])): #storing the username and role in session to ensure logged in session['username'] = correctCred['username'] session['role'] = correctCred['userType'] #if the user is admin, redirect to admin page if correctCred['userType'] == 'ADMIN': return json.dumps({"redirect": "admin", "success": True}) else: #if the user is a server, add them to the list of available servers and redirect to the waitress portal Mongo_Client.loggedInUsers.append(correctCred['username']) return json.dumps({"redirect": "waitress", "success": True}) else: return json.dumps({"success": False})
def addMenu(): """ DESCRIPTION: This route is for adding a menu to the databse REQUEST TYPE: POST PARAMETERS: JSON containing the menu data RETURNS: menu id for the menu if successful else sends error message """ #only authorized personnel can do this menu = request.get_json(silent=True) menuID = Mongo_Client.AddMenu(menu) if menuID is not None: return json.dumps({"success": True, "id": menuID}) else: return json.dumps({"error": "Database Error!"})
def cancelOrder(): """ DESCRIPTION: This route is for canceling a specifc order for a table/customer REQUEST TYPE: POST PARAMETERS: orderId: order number from which the order to cancel cancelId: the date stamp for when the order was made RETURNS: success/error message """ # only authorized user can do this values = request.get_json(silent=True) print(values) if Mongo_Client.CancelOrder(values['orderId'], values['cancelId']): return json.dumps({"success": True}) else: return json.dumps({"error": "Database Error!"})
def addReservation(data, from_number): """ DESCRIPTION: This method is for adding a reservation to the database PARAMETERS: data: reservation data including no of people and date for reservation RETURNS: true if insertions was successful else false """ dbDocument = { "number": from_number, "date": data["resDate"].isoformat(), "people": data["people"] } if Mongo_Client.AddReservation(dbDocument): return True else: return False
app.secret_key = "POS.session" #initializing the app as a websocket application socketio = SocketIO(app) import routes.socketsEvents #registering all the blueprints for the routes app.register_blueprint(auth) app.register_blueprint(employees) app.register_blueprint(menus) app.register_blueprint(orders) app.register_blueprint(reservation) #initializing the database connection Mongo_Client.CreateConnection() Mongo_Client.InitializeDB() #specifying the session congiuration @app.before_request def make_session_permanent(): session.permanent = True app.permanent_session_lifetime = timedelta(minutes=5) #default roure for the app will server the index.html file from delegated to Angular application @app.route('/') def home(): return app.send_static_file('index.html')
def setResponseForMessage(message, data, from_number): """ DESCRIPTION: This method is for generating an appropriate resposne for the given user text PARAMETERS: message: message sent by the user data: coversation history stores in the session for the number from_number: phone number that made the reservation RETURNS: redirects the page based on the login role """ #user wants to start a nee reservation if message.lower() == 'new': data.clear() data['reservation'] = True #user wants to cancel a reservation if message.lower() == 'cancel': data.clear() #delete from the database if Mongo_Client.CancelReservations(datetime.datetime.now().isoformat(), from_number): return "Your reservation has successfully been canceled!" else: return "Failed to cancel reservation! Please try again!" #user hasn't started a reservation yet if 'reservation' not in data: if message.lower() == "reservation": data['reservation'] = True return "What date? (mm/dd/yy)" else: return "Please text 'reservation' to start your reservation or 'cancel' to cancel one " #user hasn't specifed the reservation date yet elif 'date' not in data: try: d = datetime.datetime.strptime(message, "%m/%d/%Y") data['date'] = d #time must me 30 or 00 return "What time? (24 hr and 30 mins slots" except: return "Please enter a valid date (mm/dd/yy)" #user hasn't specified the reservation time yet elif 'time' not in data: try: d = datetime.datetime.strptime(message + ":00", "%H:%M:00") if d.minute % 30 != 0: return "Time should be a multiple of 30. Please try again!" data['time'] = d resDate = datetime.datetime(data['date'].year, data['date'].month, data['date'].day, data['time'].hour, data['time'].minute) #checking if the reservation time is after the cuurent date if resDate > datetime.datetime.now() and resDate.time( ) >= openingTime.time() and resDate.time() <= closingTime.time(): #implementer has the options to set the reservation requirements and restrictions data['resDate'] = resDate return "How many people?" else: data.clear() return "The time you specified is not within our opening hours. Please start over!\nWhat date? " except Exception as e: print("Error with time", e.message) return "Please enter a valid time in 24 hr format" #user hasn't enterd no of people yet elif 'people' not in data: try: print(message) people = int(message) data["people"] = people if addReservation(data, from_number): return "Your reservation has been confirmed for " + data[ 'resDate'].strftime('%d, %b %Y %H:%M') + " for " + str( data["people"]) + " people!" else: data.clear() return "Could not make reservation! Please start over!\nWhat date?" except: return "Please enter a valid number" #user already has a reservation else: return "Your reservation has already been confirmed for " + data[ 'resDate'].strftime('%d, %b %Y %H:%M') + " for " + str( data["people"] ) + " people!" + "\nPlease send 'new' to create a new reservation or 'cance' to cancel it!"