def browseProducts(self):
     matchingList = self.store.getProducts()
     toBeDisplayed = [("Product Id", ("Name, Unit, Source"))]
     ids = []
     for matchingProduct in matchingList:
         tuple0 = matchingProduct.getId()
         ids.append(tuple0)
         theRest = matchingProduct.getName(
         ) + " " + matchingProduct.getUnit(
         ) + " " + matchingProduct.getSource()
         newTuple = (tuple0, theRest)
         toBeDisplayed.append(newTuple)
     UserInterface.displayList("The products are: ", toBeDisplayed, "",
                               False)
     while True:
         choice = UserInterface.displayList(
             "View Product? ", [],
             "Input the product id to view details, Q to quit.")
         if choice.upper() == "Q":
             break
         elif choice in ids:
             self.viewProductByPrice(choice)
             break
         else:
             UserInterface.writeLine("Incorrect product Id")
    def displayOrderHistory(self, uid):
        decision = ''
        if uid == 'owner':
            itemised = [(c.getId(), "Name: {}".format(c.getName()))
                        for c in self.store.getCustomers()]
            decision = UserInterface.displayList(
                "Customers", itemised,
                "Please enter the number of the customer whose orders you would like to see, or leave blank to see all"
            )
            decision = decision.lower().strip()
            if decision == '':
                orders = self.store.getOrderHistoryAsList()
            else:
                if decision in [i[0] for i in itemised]:
                    orders = self.store.getCustomerOrders(decision)
                else:
                    UserInterface.writeLine("Invalid customer ID")
                    return
        else:
            decision = uid
            orders = self.store.getCustomerOrders(uid)

        if len(orders) > 0:
            displayOrders = [
                ("Order ID: {}.{} -- {}".format(o.getCustomerId(),
                                                o.getOrderId(),
                                                str(o.transactionDate)),
                 str(o.getShoppingCart()) +
                 "Total price: {}".format(str(o.getTotalPrice())))
                for o in orders
            ]
            UserInterface.displayList("Orders", displayOrders, "", False)
        else:
            UserInterface.writeLine(
                "No orders to display for customer {}".format(decision))
    def checkOut(self):
        currentCustomer = self.store.getCustomer(self.loginDetail)
        shoppingCart = currentCustomer.getShoppingCart()
        totalPrice = shoppingCart.getTotalPrice()
        formattedSC = []
        formattedSC.append(('Index', 'product name, real price, quantity'))
        for line in shoppingCart.getProductsInCart():
            pname = self.store.getProduct(line[0]).getName()
            newLine = pname + "," + str(line[1]) + "," + str(line[2])
            formattedSC.append((line[0], newLine))
        UserInterface.displayList("Current Shopping Cart", formattedSC, '',
                                  False)

        insufficientP = []
        for eachProduct in shoppingCart.getProductsInCart():
            if not self.checkStock(eachProduct[2], eachProduct[0],
                                   eachProduct[1]):
                insufficientP.append(eachProduct)
        if len(
                insufficientP
        ) > 0:  # insufficient stock, return to shopping cart or whatever
            return insufficientP

        confirmMSG = UserInterface.displayConfirm(
            "You are about to check out. ", "Are you sure?")
        if confirmMSG == 'y' or confirmMSG == 'Y':
            if self.store.getCustomer(
                    self.loginDetail).getBalance() < totalPrice:
                UserInterface.writeLine(
                    'You do not have sufficient balance. Please go to manage account and top up.'
                )
                return None
            currentCustomer.subtractBalance(totalPrice)

            for eachProduct in shoppingCart.getProductsInCart():
                self.store.getProduct(eachProduct[0]).deductStock(
                    eachProduct[1], eachProduct[2])

            shoppingCartCopy = shoppingCart.getProductsInCart()[:]
            newOrder = self.store.addOrder(self.loginDetail, shoppingCartCopy,
                                           totalPrice)
            #translate order into list of tuples(name, everthing else)

            orderId = newOrder.getOrderId()  # str
            newShoppingCart = newOrder.getShoppingCart()
            listOfTuples = []
            for productInCart in newShoppingCart.getProductsInCart():
                name = productInCart[0]
                rest = str(productInCart[1]) + " " + str(productInCart[2])
                newTuple = (name, rest)
                listOfTuples.append(newTuple)
            UserInterface.writeLine(orderId)

            UserInterface.displayList("The new order details: ", listOfTuples,
                                      "", False)
            UserInterface.writeLine("The total price is: " +
                                    str(newShoppingCart.getTotalPrice()))
            currentCustomer.getShoppingCart().setProductsInCart([])
        else:
            pass
 def viewProductByBatch(self, productId):
     product = self.store.getProduct(productId)
     batches = product.getBatches()
     tuples = [("BatchId", "Price, Quantity, Expiry Date")]
     batchIds = []
     for batch in batches:
         batchId = batch.getBatchID()
         batchIds.append(batchId)
         theRest = str(batch.getActualPrice()) + " " + str(
             batch.getQuantity()) + " " + str(batch.getExpiryDate())
         tuples.append((batchId, theRest))
     UserInterface.displayList("Batch details: ", tuples, "", False)
     confirm = UserInterface.displayConfirm("Edit batch ",
                                            "Do you wish to edit Batch?")
     if confirm.lower() == 'y' and len(batchIds) > 0:
         while True:
             batchId = UserInterface.displayForm(
                 "Batch Id",
                 [("Please input the batchID you would like to edit.",
                   "number")])[0]
             #print(batchIds)
             if batchId in batchIds:
                 self.editBatch(productId, batchId)
                 break
             else:
                 UserInterface.writeLine("Batch Id incorrect. Try again.")
     else:  # ML added else condition so user doesn't get stuck when no batch exists.
         UserInterface.writeLine("No batches to edit.")
 def viewAllCustomerID(self):
     toBeDisplayed = []
     customerIds = []
     for customer in self.store.getCustomers():
         id = customer.getId()
         namePhoneAddressBalance = str(customer.getPhoneNumber()) + " " + \
             customer.getAddress() + " " + str(customer.getBalance())
         toBeDisplayed.append((id, namePhoneAddressBalance))
         customerIds.append(id)
     UserInterface.displayList("All customers and their IDs: ",
                               toBeDisplayed, "", False)
     return customerIds
 def viewAllProductID(self):
     toBeDisplayed = []
     productIds = []
     for product in self.store.getProducts():
         id = product.getId()
         nameUnitSource = product.getName() + " " + product.getUnit(
         ) + " " + product.getSource()
         toBeDisplayed.append((id, nameUnitSource))
         productIds.append(id)
     UserInterface.displayList("All product and their IDs: ", toBeDisplayed,
                               "", False)
     return productIds
    def viewProductByPrice(self, productId):
        product = self.store.getProduct(productId)
        tuples = [('name', product.getName())]
        tuples.append(('source', product.getSource()))
        tuples.append(('unit', product.getUnit()))
        tuples.append(('Original Price', product.getOriginalPrice()))

        UserInterface.displayList("Product details: ", tuples, "", False)
        priceGroup = product.getPriceGroups()
        if priceGroup == {}:
            UserInterface.writeLine("There is no stock of this product.")
        else:
            toBeDisplayed = []
            for everyPrice in priceGroup:
                newtuple0 = "Price: " + str(everyPrice)
                newtuple1 = "Quantity: " + str(priceGroup[everyPrice])
                toBeDisplayed.append((newtuple0, newtuple1))
            UserInterface.displayList("The available stocks are: ",
                                      toBeDisplayed, "", False)
        # menu of this product
        if self.loginDetail is None:
            pass
        elif self.loginDetail == 'owner':
            # allow owner to edit product
            valid = False
            while not valid:
                UserInterface.writeLine(
                    "Next Action: A. View by Batch  B. Edit Product  C. Discount this product Q. Quit"
                )
                ganma = UserInterface.displayList("", [], "")
                if ganma.upper().strip() == "A":
                    self.viewProductByBatch(productId)
                    valid = True
                elif ganma.upper().strip() == "B":
                    self.editProduct(productId)
                    valid = True
                elif ganma.upper().strip() == "C":
                    self.store.getProduct(productId).updateDiscount()
                    valid = True
                elif ganma.upper().strip() == "Q":
                    valid = True
                else:
                    UserInterface.writeLine("Invalid input, try again")
        elif len(priceGroup) > 0:
            self.addToCart(productId, priceGroup)
    def manageAccount(self):
        customer = self.store.getCustomer(self.loginDetail)

        # option_String = 'Edit Options: 1- Name   2- Password   3- Phone Number   4- Address   5- Balance'
        # keyboardInput = UserInterface.displayList('Account Info.', [('Name', name), ('Password', pwd), ('Phone', phoneNumber)
        #                        , ('Address', address), ('Balance', balance)], option_String)

        while True:
            option_String = 'Edit Options: N- Name   P- Password   C- Phone Number   A- Address   B- Top Up Balance  X- Exit'
            keyboardInput = UserInterface.displayList(
                'Account Info.', [('Name', customer.getName()),
                                  ('Password', customer.getPassword()),
                                  ('Phone', customer.getPhoneNumber()),
                                  ('Address', customer.getAddress()),
                                  ('Balance', customer.getBalance())],
                option_String).strip().upper()
            if keyboardInput == 'N':
                name = UserInterface.displayForm(
                    'Please give a new value for -', [('Name', 'nstring')])
                name = name[0]
                customer.setName(name)
                UserInterface.writeLine('Name updated.')
            elif keyboardInput == 'P':
                pwd = UserInterface.displayForm(
                    'Please give a new value for -', [('Password', 'nstring')])
                pwd = pwd[0]
                customer.setPassword(pwd)
                UserInterface.writeLine('Password updated.')
            elif keyboardInput == 'C':
                phoneNumber = UserInterface.displayForm(
                    'Please give a new value for -',
                    [('Phone Number', 'nstring')])
                phoneNumber = phoneNumber[0]
                customer.setPhoneNumber(phoneNumber)
                UserInterface.writeLine('Phone number updated.')
            elif keyboardInput == 'A':
                address = UserInterface.displayForm(
                    'Please give a new value for -', [('Address', 'nstring')])
                address = address[0]
                customer.setAddress(address)
                UserInterface.writeLine('Address updated.')
            elif keyboardInput == 'B':
                updated = False
                while not updated:
                    balance = UserInterface.displayForm(
                        'Please give a new value for -',
                        [('Balance', 'money')])[0]
                    if float(balance) >= 0:
                        customer.topUp(balance)
                        UserInterface.writeLine('Balance updated.')
                        updated = True
                    else:
                        print(
                            'Please enter a value greater or equal than zero.')
            elif keyboardInput == 'X':
                self.store.writeStore()
                break
 def viewShoppingCart(self):
     shoppingCart = self.store.getCustomer(
         self.loginDetail).getShoppingCart().getProductsInCart()
     listToBeDisplayed = []
     for listhaha in shoppingCart:
         pName = self.store.getProduct(listhaha[0]).getName()
         theRest = [pName]
         theRest.extend(listhaha[1:])
         listToBeDisplayed.append((listhaha[0], theRest))
     UserInterface.displayList("Products in Shopping Cart",
                               listToBeDisplayed, "", False)
     if len(listToBeDisplayed) == 0:
         UserInterface.writeLine('no product yet')
     else:
         while True:
             co = UserInterface.displayList(
                 'Next action: ', [],
                 'A to check out. B to modify shopping cart Q to quit')
             if co.upper().strip() == 'A':
                 insufficientProduct = self.checkOut()
                 if insufficientProduct != None:
                     for plist in insufficientProduct:
                         proid = plist[0]
                         pro = self.store.getProduct(proid)
                         proName = pro.getName()
                         print("Available stock: ", proName,
                               [plist[1],
                                pro.calculateStock(plist[1])])
                         print("In shopping cart: ", proName, plist[1:])
                     co = UserInterface.displayConfirm(
                         'Do you wish to modify shopping cart?', '')
                     if co in ['y', 'Y']:
                         self.modifyShoppingCart()
                 break
             elif co.upper().strip() == 'B':
                 self.modifyShoppingCart()
                 break
             elif co.upper().strip() == 'Q':
                 break
             else:
                 UserInterface.writeLine(
                     "Incorrect menu option, try again.")
 def viewExpiringProducts(self):
     products = self.store.getProducts()
     paired = []
     expIds = []
     for p in products:
         for b in p.getExpiringBatches():
             paired.append(("Name: {}, Product ID: {}, Batch ID: {}".format(
                 p.getName(), p.getId(),
                 b.getBatchID()), "Expiring: {}".format(b.getExpiryDate())))
             if p.getId() not in expIds:
                 expIds.append(p.getId())
     if len(paired) > 0:
         UserInterface.displayList("Expiring product batches", paired, "",
                                   False)
         toDiscount = UserInterface.displayConfirm(
             "Do you wish to discount these products and delete expired batches? ",
             "")
         if toDiscount in ['y', 'Y']:
             for pid in expIds:
                 self.store.getProduct(pid).updateDiscount()
                 self.store.getProduct(pid).deleteExpiredProducts()
     else:
         UserInterface.writeLine(
             "Good news! There are no expiring products")
 def editBatch(self, productId, batchId):
     valid = False
     while not valid:
         choice = UserInterface.displayList(
             "Edit options", [],
             "A. Edit Batch Price  B. Edit Batch Quantity  Q. Quit")
         if choice.upper() == 'A':
             self.editBatchPrice(productId, batchId)
             valid = True
         elif choice.upper() == 'B':
             self.editBatchQuantity(productId, batchId)
             valid = True
         elif choice.upper() == 'Q':
             valid = True
         else:
             UserInterface.writeLine("Invalid input.")
    def searchProduct(self):
        keyword = UserInterface.displayForm(
            "Search Product: Please input the product you would like to search: ",
            [('name', 'string')])
        # here keyword is a list, so the "real" keyword  is keyword[0]
        matchingList = self.store.searchProductByName(keyword[0])
        toBeDisplayed = []
        displayNumber = 0
        for matchingProduct in matchingList:
            tuple0 = displayNumber
            theRest = matchingProduct.getName(
            ) + " " + matchingProduct.getUnit(
            ) + " " + matchingProduct.getSource()
            newTuple = (tuple0, theRest)
            toBeDisplayed.append(newTuple)
            displayNumber += 1
        choice = UserInterface.displayList(
            "The matching products are: ", toBeDisplayed,
            "Which product to choose? X to go back.")

        validInput = False
        while not validInput:
            if choice == "x" or choice == "X":
                validInput = True
                return None
                # The end of this method
            else:
                matchIndex = 0
                stop = False
                while not stop and matchIndex < len(matchingList):
                    if choice == str(matchIndex):
                        stop = True
                    else:
                        matchIndex += 1
                if stop is False:
                    choice = input("Please enter a valid input.")
                else:
                    validInput = True
                    return matchingList[matchIndex].getId()
 def displayMenuReturnOption(self):
     while True:
         menuItems = OrderedDict()  #stays in input order
         menuItems['B'] = ('Browse Products',
                           'Enter B to browse the list of products')
         menuItems['S'] = ('Search Products',
                           'Enter S to search products by keyword')
         if not self.loginDetail:  #nobody logged in
             menuItems['R'] = ('Register', 'Enter R to register an account')
             menuItems['L'] = ('Login', 'Enter L to login to your account')
         else:
             menuItems['O'] = ('View Order History',
                               'Enter O to view order history')
             menuItems['T'] = ('Logout', 'Enter T to logout')
             if self.loginDetail == 'owner':
                 menuItems['EX'] = ('View Expiring Products',
                                    'Enter EX to view expiring products')
                 menuItems['A'] = ('Add Product',
                                   'Enter A to add a product')
                 menuItems['RC'] = ('Remove Customer',
                                    'Enter RC to remove a customer')
                 menuItems['RP'] = ('Remove Product',
                                    'Enter RP to remove a product')
             else:
                 menuItems['M'] = ('Manage Account',
                                   'Enter M to manage your account')
                 menuItems['UR'] = ('Unregister Account',
                                    'Enter UR to unregister your account')
                 menuItems['SC'] = ('View Shopping Cart',
                                    'Enter SC to view shopping cart')
         menuItems['X'] = ("Exit", 'Enter X to exit')
         request = UserInterface.displayList(
             "Monash Fruit and Vegetable Store", list(menuItems.values()),
             "Please enter one of the above options to continue").upper(
             ).strip()
         if request not in menuItems.keys():
             UserInterface.writeLine("Invalid input, please try again")
         else:
             return request