Exemplo n.º 1
0
def run_add_order_grpc(stub):
    for i in range(0, AMOUNT_TO_TEST):
        order = inventory_system_pb2.Order(destination="test",
                                           date="test",
                                           products=[],
                                           is_paid=False,
                                           is_shipped=False)
        stub.AddOrder(order)
Exemplo n.º 2
0
def init_order(order):
    '''
    Turns an order object into an Order message for sending on gRPC.
    '''
    product_amounts = []
    for product in order.products:
        product_id = inventory_system_pb2.ProductIdentifier(name=product[0],
                                                            id=product[1])
        product_amounts.append(
            inventory_system_pb2.ProductAmount(product_identifier=product_id,
                                               amount=product[2]))
    return inventory_system_pb2.Order(id=order.id,
                                      destination=order.destination,
                                      date=order.date,
                                      products=product_amounts,
                                      is_paid=order.is_paid,
                                      is_shipped=order.is_shipped)
Exemplo n.º 3
0
def prepare_database_for_timing(stub):
    # Empty the database
    stub.ClearDatabase(inventory_system_pb2.Empty())

    # Add products to the database
    products = [inventory_system_pb2.Product(name='Product' + str(i), description='A product that carries the number ' + str(i),
                        manufacturer='Riley Kirkpatrick', wholesale_cost=i, sale_cost=i/2.5, amount=i)
                        for i in range(NUMBER_OF_PRODUCTS)]
    product_ids = stub.AddProducts(inventory_system_pb2.Products(products=products)).ids

    # Add orders to the database
    date = inventory_system_pb2.Date(year=2020, month=4, day=20)
    orders = []
    for i in range(NUMBER_OF_ORDERS):
        # Since amount=i//2, Product0 and Product1 should not be added to the first order
        products = [inventory_system_pb2.Product(name='Product' + str(i), amount=i//2) for i in range(i*UNIQUE_PRODUCTS_PER_ORDER, (i+1)*UNIQUE_PRODUCTS_PER_ORDER)]
        orders.append(inventory_system_pb2.Order(destination=str(i) + ' Main St, Bethlehem, PA 18018', date=date,
                                             products=products, is_paid=i % 2 == 0, is_shipped=i % 2 != 0))
    
    return product_ids, stub.CreateOrders(inventory_system_pb2.Orders(orders=orders)).ids
Exemplo n.º 4
0
def to_inventory_system_orders(orders):
    """Converts a list of orders to a list of inventory_system_pb2.Order objects.
    """
    _orders = []
    for order in orders:
        if order.date == '':
            order.date = inventory_system_pb2.Date(month=-1, day=-1, year=-1)
        products = [
            inventory_system_pb2.Product(id=product.id,
                                         name=product.name,
                                         amount=product.amount)
            for product in order.products
        ]
        _orders.append(
            inventory_system_pb2.Order(id=order.id,
                                       destination=order.destination,
                                       date=order.date,
                                       is_paid=order.is_paid,
                                       is_shipped=order.is_shipped,
                                       products=products))
    return _orders
Exemplo n.º 5
0
def run_timing(stub, number_of_run=None):
    # The number of the timing run
    run_number = ''
    if not number_of_run is None:
        run_number = ' (%s)' % number_of_run

    grpc_times = []
    product_ids, order_ids = prepare_database_for_timing(stub)

    # Timing for GetProductsByID
    start_time = time.monotonic() # The start of the timing

    products = stub.GetProductsByID(inventory_system_pb2.IDs(ids=product_ids)).products

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing GetProductsByID%s...' % run_number)


    # Timing for GetProductsByName
    start_time = time.monotonic() # The start of the timing

    names = ['Product' + str(i) for i in range(NUMBER_OF_PRODUCTS)]
    products = stub.GetProductsByName(inventory_system_pb2.Names(names=names)).products

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing GetProductsByName%s...' % run_number)


    # Timing for GetProductsByManufacturer
    start_time = time.monotonic() # The start of the timing

    products = stub.GetProductsByManufacturer(inventory_system_pb2.Manufacturer(manufacturer='Riley Kirkpatrick')).products

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing GetProductsByManufacturer%s...' % run_number)


    # Timing for GetOrdersByID
    start_time = time.monotonic() # The start of the timing

    orders = stub.GetOrdersByID(inventory_system_pb2.IDs(ids=order_ids)).orders

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing GetOrdersByID%s...' % run_number)
    

    # Timing for GetOrdersByStatus
    start_time = time.monotonic() # The start of the timing

    orders = stub.GetOrdersByStatus(inventory_system_pb2.OrderStatus(paid=False, shipped=False)).orders
    orders = stub.GetOrdersByStatus(inventory_system_pb2.OrderStatus(paid=False, shipped=True)).orders
    orders = stub.GetOrdersByStatus(inventory_system_pb2.OrderStatus(paid=True, shipped=False)).orders
    orders = stub.GetOrdersByStatus(inventory_system_pb2.OrderStatus(paid=True, shipped=True)).orders

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing GetOrdersByStatus%s...' % run_number)


    # Timing for GetProductsInStock
    start_time = time.monotonic() # The start of the timing

    products = stub.GetProductsInStock(inventory_system_pb2.Empty()).products

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing GetProductsInStock%s...' % run_number)


    # Timing for UpdateProducts
    start_time = time.monotonic() # The start of the timing
    
    products = [inventory_system_pb2.Product(id=id, wholesale_cost=random.random()*10000, sale_cost=random.random()*2500,
                                            amount=int(random.random()*100)) for id in product_ids]
    stub.UpdateProducts(inventory_system_pb2.Products(products=products))

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing UpdateProducts%s...' % run_number)


    # Timing for UpdateOrders
    _, order_ids = prepare_database_for_timing(stub)
    start_time = time.monotonic() # The start of the timing

    products = [inventory_system_pb2.Product(name='Product' + str(i), amount=1) for i in range(2*NUMBER_OF_ORDERS, 2*NUMBER_OF_ORDERS+1)]
    orders = [inventory_system_pb2.Order(id=id, is_paid=random.random() > 0.5, is_shipped=random.random() <= 0.5, products=products) for id in order_ids]
    stub.UpdateOrders(inventory_system_pb2.Orders(orders=orders))

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing UpdateOrders%s...' % run_number)


    # Timing for AddProducts
    prepare_database_for_timing(stub)
    start_time = time.monotonic() # The start of the timing

    products = [inventory_system_pb2.Product(name=str(i), description='A product of the number ' + str(i),
                            manufacturer='Toys R Us', wholesale_cost=i, sale_cost=i/2.5, amount=100)
                            for i in range(NUMBER_OF_PRODUCTS)]
    ids = stub.AddProducts(inventory_system_pb2.Products(products=products)).ids

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing AddProducts%s...' % run_number)


    # Timing for CreateOrders
    prepare_database_for_timing(stub)
    start_time = time.monotonic() # The start of the timing

    date = inventory_system_pb2.Date(year=2020, month=4, day=20)
    orders = []
    for i in range(NUMBER_OF_ORDERS):
        products = [inventory_system_pb2.Product(name='Product' + str(i), amount=1) for i in range(2*NUMBER_OF_ORDERS, 2*NUMBER_OF_ORDERS+1)]
        orders.append(inventory_system_pb2.Order(destination="Elmo's World", date=date, products=products,
                                                is_paid=i % 2 == 0, is_shipped=i % 2 != 0))
    ids = stub.CreateOrders(inventory_system_pb2.Orders(orders=orders)).ids

    grpc_times.append(time.monotonic() - start_time)
    print('Finished timing CreateOrders%s...\n\n' % run_number)

    return grpc_times
def main():
    parser = argparse.ArgumentParser()
    # Argument to take IP and port that you wish to connect to, default is localhost at port 50051
    parser.add_argument('ip', type=str, help="IP and port that you want to connect to", default="localhost:50051")
    # Argument which defines which protocol you want to use, default is gRPC.
    parser.add_argument('protocol', type=str, help="Protocol of using gRPC or XML-RPC", default="gRPC")

    # Added a subparser for the commands that can be run.
    subparsers = parser.add_subparsers(title="command", dest="cmd", required=True)

    # Get product command which takes either the name or id of a product, defaulting the other argument to a null value.
    get_product_cmd = subparsers.add_parser(name="get_product", description="Get a product from the database")
    get_product_cmd.add_argument("--name", help="The name of the product", type=str, default="null", required=False)
    get_product_cmd.add_argument("--id", help="The id of the product", type=str, default="-1", required=False)

    # Add product command which takes all attributes of a product except for ID as arguments.
    add_product_cmd = subparsers.add_parser(name="add_product", description="Add a product to the database")
    add_product_cmd.add_argument("name", help="The name of the product", type=str)
    add_product_cmd.add_argument("amount", help="The amount of the product", type=int)
    add_product_cmd.add_argument("description", help="The description of the product", type=str)
    add_product_cmd.add_argument("manufacturer", help="The manufacturer of the product", type=str)
    add_product_cmd.add_argument("sale_cost", help="The sale cost of the product", type=float)
    add_product_cmd.add_argument("wholesale_cost", help="The wholesale cost of the product", type=float)

    # Get products by manufacturer command which takes a manufacturer as a string.
    get_products_by_manufacturer_cmd = subparsers.add_parser(name="get_products_by_manufacturer",
                                                             description="Get a list of products by manufacturer")
    get_products_by_manufacturer_cmd.add_argument("manufacturer", help="The manufacturer you want to filter by")

    # Get products in stock command which takes no arguments.
    get_products_in_stock_cmd = subparsers.add_parser(name="get_products_in_stock",
                                                      description="Get a list of products in stock")

    # Update product description command which takes the description as a string, and either the name or id as strings.
    update_product_description_cmd = subparsers.add_parser(name="update_product_description",
                                                           description="Update the description of a product")
    update_product_description_cmd.add_argument("description", help="The description you want to update to", type=str)
    update_product_description_cmd.add_argument("--name", help="The name of the product", default="null", type=str,
                                                required=False)
    update_product_description_cmd.add_argument("--id", help="The id of the product", default="-1", type=str,
                                                required=False)

    # Update product manufacturer command which takes the manufacturer as a string, and either the name or id as strings.
    update_product_manufacturer_cmd = subparsers.add_parser(name="update_product_manufacturer",
                                                            description="Update the manufacturer of a product")
    update_product_manufacturer_cmd.add_argument("manufacturer", help="The manufacturer you want to update to",
                                                 type=str)
    update_product_manufacturer_cmd.add_argument("--name", help="The name of the product", type=str, required=False)
    update_product_manufacturer_cmd.add_argument("--id", help="The id of the product", type=str, required=False)

    # Update product wholesale cost command which takes the wholesale cost as a float,
    # and either the name or id of the product as strings.
    update_product_wholesalecost_cmd = subparsers.add_parser(name="update_product_wholesalecost",
                                                             description="Update the wholesale cost of a product")
    update_product_wholesalecost_cmd.add_argument("wholesale_cost", help="The price of whole sale cost", type=float)
    update_product_wholesalecost_cmd.add_argument("--name", help="The name of the product", type=str, required=False)
    update_product_wholesalecost_cmd.add_argument("--id", help="The id of the product", type=str, required=False)

    # Update product sale cost command which takes the sale cost as a float,
    # and either the name or id of the product as strings.
    update_product_salecost_cmd = subparsers.add_parser("update_product_salecost",
                                                        description="Update the sale cost of a product")
    update_product_salecost_cmd.add_argument("sale_cost", help="The price of sale cost", type=float)
    update_product_salecost_cmd.add_argument("--name", help="The name of the product", type=str, required=False)
    update_product_salecost_cmd.add_argument("--id", help="The id of the product", type=str, required=False)

    # Increase product amount command which takes the amount as an integer,
    # and either the name or id of the product as strings.
    increase_product_amount_cmd = subparsers.add_parser(name="increase_product_amount",
                                                        description="Increase the amount of a product's stock")
    increase_product_amount_cmd.add_argument("amount", help="Amount you want to increase stock by", type=int)
    increase_product_amount_cmd.add_argument("--name", help="The name of the product", type=str, required=False)
    increase_product_amount_cmd.add_argument("--id", help="The id of the product", type=str)

    # Decrease product amount command which takes the amount as an integer,
    # and either the name or id of the product as strings.
    decrease_product_amount_cmd = subparsers.add_parser(name="decrease_product_amount",
                                                        description="Decrease the amount of a proudct's stock")
    decrease_product_amount_cmd.add_argument("amount", help="Amount you want to decrease stock by", type=int)
    decrease_product_amount_cmd.add_argument("--name", help="The name of the product", type=str, required=False)
    decrease_product_amount_cmd.add_argument("--id", help="The id of the product", type=str, required=False)

    # Add order command which takes the destination, date, and list of products as arguments.
    add_order_cmd = subparsers.add_parser(name="add_order", description="Add an order to the database")
    add_order_cmd.add_argument("destination", help="The destination of the order")
    add_order_cmd.add_argument("date", help="The date on which the order was placed.")
    add_order_cmd.add_argument("--products", help="The products that should be added to the order.")

    # Get order command which takes an id as a string.
    get_order_cmd = subparsers.add_parser(name="get_order", description="Get an order from the database")
    get_order_cmd.add_argument("id", help="The id of the order", type=str)

    # Add product to order command which takes the id of an order as a string and
    # the product you wish to add as a string.
    add_product_to_order_cmd = subparsers.add_parser(name="add_product_to_order",
                                                     description="Add a product to an order")
    add_product_to_order_cmd.add_argument("id", help="The id of the order", type=str)
    add_product_to_order_cmd.add_argument("product",
                                          help="The product you want to add,, in the form of \"id, name ,amount\"",
                                          type=str)

    # Remove product from order command which takes the id of an order as a string and
    # the product you wish to add as a string.
    remove_product_from_order_cmd = subparsers.add_parser(name="remove_product_from_order",
                                                          description="Remove a product from an order")
    remove_product_from_order_cmd.add_argument("id", help="The id of the order", type=str)
    remove_product_from_order_cmd.add_argument("product",
                                               help="The product you want to remove, in the form of \"id, name ,amount\"",
                                               type=str)

    # Update order destination command which takes id of the order and destination of the order as a string.
    update_order_destination_cmd = subparsers.add_parser(name="update_order_destination",
                                                         description="Update the destination of an order")
    update_order_destination_cmd.add_argument("id", help="The id of the order", type=str)
    update_order_destination_cmd.add_argument("destination", help="The new destination of the order")

    # Update order date command which takes id of the order and date of the order as a string.
    update_order_date_cmd = subparsers.add_parser(name="update_order_date", description="Update the date of an order")
    update_order_date_cmd.add_argument("id", help="The id of the order", type=str)
    update_order_date_cmd.add_argument("date", help="The new date of the order")

    # Update order paid status command which takes the paid status of the order as a string which gets
    # interpreted as a boolean and the id of the order as a string.
    update_order_paid_cmd = subparsers.add_parser(name="update_order_paid",
                                                  description="Update if an order is paid or not")
    update_order_paid_cmd.add_argument("id", help="The id of the order", type=str)
    update_order_paid_cmd.add_argument("is_paid", help="Whether or not the order is paid for", nargs='?',
                                       type=str_to_bool, const=True)

    update_order_shipped_cmd = subparsers.add_parser(name="update_order_shipped",
                                                     description="Update if an order has been shipped")
    update_order_shipped_cmd.add_argument("id", help="The id of the order", type=str)
    update_order_shipped_cmd.add_argument("is_shipped", help="Whether or not the order is shipped", nargs='?',
                                          type=str_to_bool, const=True)

    # Get unshipped orders command which takes no arguments.
    get_unshipped_orders_cmd = subparsers.add_parser(name="get_unshipped_orders",
                                                     description="Get all unshipped orders")

    # Get unpaid orders command which takes no arguments.
    get_unpaid_orders_cmd = subparsers.add_parser(name="get_unpaid_orders", description="Get all unpaid orders")

    args = parser.parse_args()
    # Both protocols are handled differently as to call correct functions with respect to gRPC or XML-RPC
    if args.protocol == "gRPC":
        with grpc.insecure_channel(args.ip) as channel:
            stub = inventory_system_pb2_grpc.InventorySystemStub(channel)
            if args.cmd == "get_product":
                response = stub.GetProduct(inventory_system_pb2.ProductIdentifier(name=args.name, id=args.id))
                if response.id == -1:
                    print("Failed to get a product by that identifier.")
                else:
                    print(response)
            elif args.cmd == "add_product":
                response = stub.AddProduct(
                    inventory_system_pb2.Product(name=args.name, amount=args.amount, description=args.description,
                                                 manufacturer=args.manufacturer, sale_cost=args.sale_cost,
                                                 wholesale_cost=args.wholesale_cost))
                if response.product_identifier.id == -1:
                    print("Failed to add the product.")
                else:
                    print(response)
            elif args.cmd == "get_products_by_manufacturer":
                response = stub.GetProductsByManufacturer(
                    inventory_system_pb2.Manufacturer(manufacturer=args.manufacturer))
                for i in response:
                    if (i.id == "-1"):
                        print("There are no products by that manufacturer.")
                        break
                    print(i)
            elif args.cmd == "get_products_in_stock":
                response = stub.GetProductsInStock(inventory_system_pb2.Empty())
                for i in response:
                    if (i.id == "-1"):
                        print("There are no products in stock.")
                        break
                    print(i)
            elif args.cmd == "update_product_description":
                response = stub.UpdateProductDescription(inventory_system_pb2.ProductDescription(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=args.name, id=args.id),
                    description=args.description))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "update_product_manufacturer":
                response = stub.UpdateProductManufacturer(inventory_system_pb2.ProductManufacturer(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=args.name, id=args.id),
                    manufacturer=args.manufacturer))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "update_product_wholesalecost":
                response = stub.UpdateProductWholesaleCost(inventory_system_pb2.ProductWholesaleCost(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=args.name, id=args.id),
                    wholesale_cost=args.wholesale_cost))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "update_product_salecost":
                response = stub.UpdateProductSaleCost(inventory_system_pb2.ProductSaleCost(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=args.name, id=args.id),
                    sale_cost=args.sale_cost))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "increase_product_amount":
                response = stub.IncreaseProductAmount(inventory_system_pb2.ProductAmount(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=args.name, id=args.id),
                    amount=args.amount))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "decrease_product_amount":
                response = stub.DecreaseProductAmount(inventory_system_pb2.ProductAmount(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=args.name, id=args.id),
                    amount=args.amount))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "add_order":
                order = inventory_system_pb2.Order(destination=args.destination, date=args.date, products=[],
                                                   is_paid=False, is_shipped=False)
                response = stub.AddOrder(order)
                if response.id == -1:
                    print("Failed to add the order")
                else:
                    print(response)
            elif args.cmd == "get_order":
                response = stub.GetOrder(inventory_system_pb2.OrderID(id=args.id))
                if response.id == -1:
                    print("Failed to get an order by that id.")
                else:
                    print(response)
            elif args.cmd == "add_product_to_order":
                product = args.product.split(",")
                product_amt = inventory_system_pb2.ProductAmount(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=product[0], id=product[1]),
                    amount=int(product[2]))
                response = stub.AddProductToOrder(
                    inventory_system_pb2.OrderProduct(id=args.id, product_amount=product_amt))
                if response.success:
                    print("Added successfully")
                else:
                    print("Failed to add product to order")
            elif args.cmd == "remove_product_from_order":
                product = args.product.split(",")
                product_amt = inventory_system_pb2.ProductAmount(
                    product_identifier=inventory_system_pb2.ProductIdentifier(name=product[0], id=product[1]),
                    amount=int(product[2]))
                response = stub.RemoveProductFromOrder(
                    inventory_system_pb2.OrderProduct(id=args.id, product_amount=product_amt))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "update_order_destination":
                response = stub.UpdateOrderDestination(
                    inventory_system_pb2.OrderDestination(id=args.id, destination=args.destination))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "update_order_date":
                response = stub.UpdateOrderDate(inventory_system_pb2.OrderDate(id=args.id, date=args.date))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "update_order_paid":
                response = stub.UpdateOrderPaid(inventory_system_pb2.OrderPaid(id=args.id, is_paid=args.is_paid))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "update_order_shipped":
                response = stub.UpdateOrderShipped(
                    inventory_system_pb2.OrderShipped(id=args.id, is_shipped=args.is_shipped))
                if response.success:
                    print("Updated successfully")
                else:
                    print("Failed to update")
            elif args.cmd == "get_unpaid_orders":
                response = stub.GetUnpaidOrders(inventory_system_pb2.Empty())
                for i in response:
                    if (i.id == "-1"):
                        print("There are no unpaid orders.")
                        break
                    print(i)
            elif args.cmd == "get_unshipped_orders":
                response = stub.GetUnshippedOrders(inventory_system_pb2.Empty())
                for i in response:
                    if (i.id == "-1"):
                        print("There are no unshipped orders.")
                        break
                    print(i)
    elif args.protocol == "XML":
        try:
            with ServerProxy("http://" + args.ip + "/") as proxy:
                if args.cmd == "get_product":
                    response = proxy.get_product_summary(args.name, args.id)
                    if response != -1:
                        name, id_, description, manufacturer, amount = response
                        new_line = "\n"
                        summary = "Name: {1}{0}ID: {2}{0}Manufacturer: {3}{0}Amount {4}{0}Description: {5}{0}".format(
                            new_line, name, id_, manufacturer, amount, description)
                        print(summary)
                    else:
                        print("Product not in inventory")
                elif args.cmd == "get_order":
                    response = proxy.get_order_summary(args.id)
                    if response != -1:
                        id_, destination, date, is_shipped, is_paid, products = response
                        new_line = "\n"
                        summary = "ID: {1}{0}Destination: {2}{0}Date: {3}{0}shipped: {4}{0}Paid: ".format(
                            new_line, id_, destination, date, is_shipped, is_paid)
                        print(summary)
                        for product in products:
                            Name, ID, Amount = product[0], product[1], product[2]
                            print("product Name: {1}{0}ID: {2}{0}Amount: {3}{0}".format(new_line, Name, ID, Amount))
                elif args.cmd == "add_product":
                    response = proxy.add_product(args.name, args.description, args.manufacturer, args.sale_cost,
                                                args.whole_sale_cost, args.amount)
                    if response[1] == -1:
                        print("Failed to get a product by that identifier.")
                    else:
                        print(response)
                elif args.cmd == "get_products_by_manufacturer":
                    response = proxy.list_products_by_manufacturer(args.manufacturer)
                    if response == -1:
                        print("there are not products under that manufacturer")
                    else:
                        for i in response:
                            print(i)
                elif args.cmd == "get_products_in_stock":
                    response = proxy.list_products()
                    if response == -1:
                        print("there are no products in the inventory")
                    else:
                        for product in response:
                            print(product)
                elif args.cmd == "update_product_description":
                    response = proxy.update_description(args.name, args.id, args.description)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "update_product_manufacturer":
                    response = proxy.update_manufacturer(args.name, args.id, args.manufacturer)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "update_product_wholesalecost":
                    response = proxy.update_wholesale_cost(args.name, args.id, args.wholesale_cost)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "update_product_salecost":
                    response = proxy.update_sale_cost(args.name, args.id, args.sale_cost)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "increase_product_amount":
                    response = proxy.increase_product_amount(args.name, args.id, args.amount)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "decrease_product_amount":
                    response = proxy.decrease_product_amount(args.name, args.id_, args.amount)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "add_order":
                    response = proxy.add_order(args.products, args.destination, args.date)
                    if response[1] == -1:
                        print("Failed to add the order")
                    else:
                        print(response)
                elif args.cmd == "add_product_to_order":
                    product = args.product.split(",")
                    response = proxy.add_product_to_order(args.id, product[0], product[1], int(product[2]))
                    if response:
                        print("Added successfully")
                    else:
                        print("Failed to add product to order")
                elif args.cmd == "remove_product_from_order":
                    product = args.product.split(",")
                    response = proxy.remove_product_from_order(args.id, product[0], product[1], int(product[2]))
                    if response:
                        print("Added successfully")
                    else:
                        print("Failed to add product to order")
                elif args.cmd == "update_order_destination":
                    response = proxy.update_order_destination(args.id, args.destination)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "update_order_date":
                    response = proxy.update_order_date(args.id, args.date)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "update_order_paid":
                    response = proxy.update_order_paid(args.id, args.is_paid)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "update_order_shipped":
                    response = proxy.update_order_shipped(args.id, args.is_shipped)
                    if response:
                        print("Updated successfully")
                    else:
                        print("Failed to update")
                elif args.cmd == "get_unpaid_orders":
                    response = proxy.list_unpaid()
                    if response == []:
                        print("There are no orders")
                    else:
                        for orderID in response:
                            print(orderID)
                elif args.cmd == "get_unshipped_orders":
                    response = proxy.list_unshipped()
                    print("hi")
                    if not response:
                        print("There are no orders")
                    else:
                        for orderID in response:
                            print(orderID)



        except Exception as ex:
            print(ex)
 def to_inventory_system_order(self, order):
   date = inventory_system_pb2.Date(year=order.date.year, month=order.date.month, day=order.date.day)
   products = [inventory_system_pb2.Product(id=product.id, name=product.name, amount=product.amount) for product in order.products]
   return inventory_system_pb2.Order(id=order.id, destination=order.destination, date=date, is_paid=order.is_paid,
                                 is_shipped=order.is_shipped, products=products)
class InventorySystem(inventory_system_pb2_grpc.InventorySystemServicer):
    # null_product is a product which has all attributes null so that we can tell the client that a product
    # was not found.
    null_product = inventory_system_pb2.Product(name="null",
                                                id="-1",
                                                amount=-1,
                                                description="null",
                                                manufacturer="null",
                                                sale_cost=0,
                                                wholesale_cost=0)
    # null_identifier is a product identifier which has all attributes null so that we can tell the client that a product
    # was not found.
    null_identifier = inventory_system_pb2.ProductIdentifier(name="null",
                                                             id="-1")
    # null_order is an order which has all attributes null so that we can tell the client that an order
    # was not found.
    null_order = inventory_system_pb2.Order(id="-1",
                                            destination="N/A",
                                            date="1/1/1970",
                                            products=[],
                                            is_paid=False,
                                            is_shipped=False)

    def __init__(self, inventory):
        self.inventory = inventory

    def GetProduct(self, request, context):
        name = request.name
        id_ = request.id
        if self.inventory.is_product(name, id_):
            return init_product(self.inventory.get_product(name, id_))
        else:
            return self.null_product

    def AddProduct(self, request, context):
        new_product = retrieve_product(request)
        name, id_ = self.inventory.add_product(new_product)
        return inventory_system_pb2.ProductIdentifier(name=name, id=id_)

    def GetProductsByManufacturer(self, request, context):
        """
        This method was done seperate from the helper file due to the yielding of products in gRPC.
        This method searches through the list and yields any products that have a matching manufacturer.
        If no products are ever found, we return a null product
        """
        found_one = False
        manufacturer = request.manufacturer
        for product in self.inventory.products_by_id.values():
            if product.manufacturer == manufacturer:
                found_one = True
                yield init_product(product)
        if not found_one:
            yield self.null_product

    def GetProductsInStock(self, request, context):
        """
        This method is very similar to the previous GetProductsByManufacturer, and not contained in the helper
        file. Searches through all products and returns any that are in stock.
        """
        found_one = False
        for product in self.inventory.products_by_id.values():
            if product.amount > 0:
                found_one = True
                yield init_product(product)
        if not found_one:
            yield self.null_product

    def UpdateProductDescription(self, request, context):
        product_identifier = request.product_identifier
        name = product_identifier.name
        id_ = product_identifier.id
        description = request.description
        if self.inventory.update_description(name, id_, description):
            return inventory_system_pb2.Success(success=True)
        return inventory_system_pb2.Success(success=False)

    def UpdateProductManufacturer(self, request, context):
        product_identifier = request.product_identifier
        name = product_identifier.name
        id_ = product_identifier.id
        manufacturer = request.manufacturer
        if self.inventory.update_manufacturer(name, id_, manufacturer):
            return inventory_system_pb2.Success(success=True)
        return inventory_system_pb2.Success(success=False)

    def UpdateProductSaleCost(self, request, context):
        product_identifier = request.product_identifier
        name = product_identifier.name
        id_ = product_identifier.id
        sale_cost = request.sale_cost
        if self.inventory.update_sale_cost(name, id_, sale_cost):
            return inventory_system_pb2.Success(success=True)
        return inventory_system_pb2.Success(success=False)

    def UpdateProductWholesaleCost(self, request, context):
        product_identifier = request.product_identifier
        name = product_identifier.name
        id_ = product_identifier.id
        wholesale_cost = request.wholesale_cost
        if self.inventory.update_wholesale_cost(name, id_, wholesale_cost):
            return inventory_system_pb2.Success(success=True)
        return inventory_system_pb2.Success(success=False)

    def IncreaseProductAmount(self, request, context):
        product_identifier = request.product_identifier
        name = product_identifier.name
        id_ = product_identifier.id
        amount = request.amount
        if self.inventory.increase_product_amount(name, id_, amount):
            return inventory_system_pb2.Success(success=True)
        return inventory_system_pb2.Success(success=False)

    def DecreaseProductAmount(self, request, context):
        product_identifier = request.product_identifier
        name = product_identifier.name
        id_ = product_identifier.id
        amount = request.amount
        if self.inventory.decrease_product_amount(name, id_, amount):
            return inventory_system_pb2.Success(success=True)
        return inventory_system_pb2.Success(success=False)

    def AddOrder(self, request, context):
        order_id = self.inventory.add_order(retrieve_order(request))
        return inventory_system_pb2.OrderID(id=order_id)

    def GetOrder(self, request, context):
        id_ = request.id
        if self.inventory.is_order(id_):
            return init_order(self.inventory.get_order(id_))
        else:
            return self.null_order

    def AddProductToOrder(self, request, context):
        product_amount = request.product_amount
        product_identifier = product_amount.product_identifier
        product_name = product_identifier.name
        product_id = product_identifier.id
        product_amount = product_amount.amount
        order_id = request.id
        if self.inventory.add_product_to_order(order_id, product_name,
                                               product_id, product_amount):
            return inventory_system_pb2.Success(success=True)
        else:
            return inventory_system_pb2.Success(success=False)

    def RemoveProductFromOrder(self, request, context):
        product_amount = request.product_amount
        product_identifier = product_amount.product_identifier
        product_name = product_identifier.name
        product_id = product_identifier.id
        product_amount = product_amount.amount
        order_id = request.id
        if self.inventory.remove_product_from_order(order_id, product_name,
                                                    product_id,
                                                    product_amount):
            return inventory_system_pb2.Success(success=True)
        else:
            return inventory_system_pb2.Success(success=False)

    def UpdateOrderDestination(self, request, context):
        order_id = request.id
        destination = request.destination
        if self.inventory.update_order_destination(order_id, destination):
            return inventory_system_pb2.Success(success=True)
        else:
            return inventory_system_pb2.Success(success=False)

    def UpdateOrderDate(self, request, context):
        order_id = request.id
        date = request.date
        if self.inventory.update_order_date(order_id, date):
            return inventory_system_pb2.Success(success=True)
        else:
            return inventory_system_pb2.Success(success=False)

    def UpdateOrderPaid(self, request, context):
        order_id = request.id
        is_paid = request.is_paid
        if self.inventory.update_order_paid(order_id, is_paid):
            return inventory_system_pb2.Success(success=True)
        else:
            return inventory_system_pb2.Success(success=False)

    def UpdateOrderShipped(self, request, context):
        order_id = request.id
        is_shipped = request.is_shipped
        if self.inventory.update_order_shipped(order_id, is_shipped):
            return inventory_system_pb2.Success(success=True)
        else:
            return inventory_system_pb2.Success(success=False)

    def GetUnshippedOrders(self, request, context):
        """
        This method was not included in the helper file as it has different implementation in gRPC.
        Searches through orders finding orders which have not been shipped.
        If none are found, a null order is returned.
        """
        found_one = False
        for order in self.inventory.orders.values():
            if not order.is_shipped:
                found_one = True
                yield init_order(order)
        if not found_one:
            yield self.null_order

    def GetUnpaidOrders(self, request, context):
        """
        Similar to GetUnshippedOrders, returns a null order if none are found
        """
        found_one = False
        for order in self.inventory.orders.values():
            if not order.is_paid:
                found_one = True
                yield init_order(order)
        if not found_one:
            yield self.null_order