public void UpdatesSubmittedTimeWhenOrderPlaced()
        {
            var options = TestUtil.GetMemDbOptions("UpdatesSubmittedTimeWhenOrderPlaced");

            String productName;
            Guid   customerId;
            Guid   orderId;

            using (var db = new StoreContext(options))
            {
                var(customer, location, product, inventory) = SimplePopulate(db);
                customerId  = customer.CustomerId;
                productName = product.Name;

                var order = new Order(customer, location);
                orderId = order.OrderId;
                var orderLine = new OrderLineItem(order, product);
                orderLine.Quantity = 1;
                order.OrderLineItems.Add(orderLine);

                db.Add(order);
                db.SaveChanges();
            }

            Assert.Equal(PlaceOrderResult.Ok, options.PlaceOrder(orderId, StoreDbUtil.Config.MAX_ORDER_QUANTITY));

            using (var db = new StoreContext(options))
            {
                var order = db.GetOrderById(orderId);
                Assert.NotNull(order.TimeSubmitted);
            }
        }
Example #2
0
        /// <summary>
        /// Places a new <c>Order</c>.
        /// </summary>
        /// <param name="options">Options for creating a new <c>StoreContext</c>.</param>
        /// <param name="orderId">The ID of a previously saved <c>Order</c>.</param>
        /// <param name="maxQuantity">The maximum amount of <c>Product</c> that may be present in an <c>Order</c>.</param>
        /// <returns>A <c>PlaceOrderResult</c> detailing whether the operation completed successfully.</returns>
        public static PlaceOrderResult PlaceOrder(this DbContextOptions <StoreContext> options, Guid?orderId, int maxQuantity)
        {
            if (orderId == null)
            {
                throw new NullReferenceException("Missing orderId");
            }
            using (var db = new StoreContext(options))
            {
                var order = db.GetOrderById(orderId);
                if (order == null)
                {
                    return(PlaceOrderResult.OrderNotFound);
                }

                if (order.OrderLineItems.Count() == 0)
                {
                    return(PlaceOrderResult.NoLineItems);
                }

                var totalOrderPrice   = 0.0;
                var totalItemQuantity = 0;

                var location = order.Location;
                using (var transaction = db.Database.BeginTransaction())
                {
                    foreach (var lineItem in order.OrderLineItems)
                    {
                        var locationInventory = db.FindInventoryId(location, lineItem.Product);
                        if (locationInventory == null)
                        {
                            return(PlaceOrderResult.OutOfStock);
                        }
                        var newStockQuantity = locationInventory.TryAdjustQuantity(-lineItem.Quantity);
                        if (newStockQuantity == null)
                        {
                            transaction.Rollback();
                            return(PlaceOrderResult.OutOfStock);
                        }

                        var lineItemPrice = lineItem.Quantity * lineItem.Product.Price;
                        totalOrderPrice       += lineItemPrice;
                        lineItem.AmountCharged = lineItemPrice;
                        totalItemQuantity     += lineItem.Quantity;
                        db.SaveChanges();
                    }
                    if (totalItemQuantity > maxQuantity)
                    {
                        return(PlaceOrderResult.HighQuantityRejection);
                    }
                    order.AmountPaid    = totalOrderPrice;
                    order.TimeSubmitted = DateTime.Now;
                    db.SaveChanges();
                    transaction.Commit();
                }
                return(PlaceOrderResult.Ok);
            }
        }
Example #3
0
        /// <summary>
        /// Handle input.
        /// </summary>
        public void InputLoop()
        {
            var inputOptions = CliInput.GetLineOptions.TrimSpaces | CliInput.GetLineOptions.AcceptEmpty;

            do
            {
                Console.Write("\n\n");
                var line = CliInput.GetLine(inputOptions, v => true, "Sort by [D]ate / [P]rice / [S]tore\nor enter an order number to view details:");
                switch (line)
                {
                case "D":
                case "d":
                    this.SortKey = this.SortKey != OrderSortKey.DateDesc ? OrderSortKey.DateDesc : OrderSortKey.DateAsc;
                    break;

                case "P":
                case "p":
                    this.SortKey = this.SortKey != OrderSortKey.PriceDesc ? OrderSortKey.PriceDesc : OrderSortKey.PriceAsc;
                    break;

                case "S":
                case "s":
                    this.SortKey = this.SortKey != OrderSortKey.LocationAsc ? OrderSortKey.LocationAsc : OrderSortKey.LocationDesc;
                    break;

                default:
                    if (line == "" || line == null)
                    {
                        this.MenuExit();
                        return;
                    }
                    try
                    {
                        var orderNum = Int32.Parse(line);
                        if (orderNum > 0 && orderNum <= this.OrderIds.Count)
                        {
                            using (var db = new StoreContext(this.ApplicationState.DbOptions))
                            {
                                var order         = db.GetOrderById(this.OrderIds[orderNum - 1]);
                                var amountCharged = db.GetAmountCharged(order);
                                this.DisplayDetail(db, order, amountCharged);
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch (Exception) {
                        // We will just ignore parse errors and reprint the menu.
                        break;
                    }
                }
                this.PrintMenu();
            } while (true);
        }
Example #4
0
        /// <summary>
        /// Handle the input when viewing a list of all orders for a location.
        /// </summary>
        /// <returns>A <c>HandlerMsg</c> indicating what action should be taken.</returns>
        private HandlerMsg HandleViewOrderInput()
        {
            var inputOptions = CliInput.GetLineOptions.TrimSpaces | CliInput.GetLineOptions.AcceptEmpty;

            do
            {
                var line = CliInput.GetLine(inputOptions, v => true, "\nSort by [D]ate / [P]rice\nor enter an order number to view details:");
                switch (line)
                {
                case "D":
                case "d":
                    this.SortKey = this.SortKey != OrderSortKey.DateDesc ? OrderSortKey.DateDesc : OrderSortKey.DateAsc;
                    break;

                case "P":
                case "p":
                    this.SortKey = this.SortKey != OrderSortKey.PriceDesc ? OrderSortKey.PriceDesc : OrderSortKey.PriceAsc;
                    break;

                default:
                    if (line == "" || line == null)
                    {
                        this.CurrentOperatingMode = OperatingMode.SelectLocation;
                        return(HandlerMsg.Continue);
                    }
                    try
                    {
                        var orderNum = Int32.Parse(line);
                        if (orderNum > 0 && orderNum <= this.OrderIds.Count)
                        {
                            using (var db = new StoreContext(this.ApplicationState.DbOptions))
                            {
                                var order         = db.GetOrderById(this.OrderIds[orderNum - 1]);
                                var amountCharged = db.GetAmountCharged(order);
                                this.DisplayDetail(db, order, amountCharged);
                                break;
                            }
                        }
                        else
                        {
                            CliPrinter.Error("Invalid order number");
                            continue;
                        }
                    }
                    catch (Exception) {
                        // We will just ignore parse errors and reprint the menu.
                        break;
                    }
                }
                this.PrintMenu();
            } while (true);
        }
Example #5
0
        /// <summary>
        /// Print this menu.
        /// </summary>
        public void PrintMenu()
        {
            Console.Clear();
            CliPrinter.Title("Order Items");
            this.ApplicationState.UserData.RefreshCurrentOrder();

            if (this.ApplicationState.UserData.CurrentOrderId == null)
            {
                using (var db = new StoreContext(this.ApplicationState.DbOptions))
                {
                    var customer = db.GetCustomerById(this.ApplicationState.UserData.CustomerId);
                    var location = db.GetLocationById(this.ApplicationState.UserData.OperatingLocationId);
                    var order    = new Order(customer, location);
                    order.Customer = customer;
                    db.Add(order);
                    db.SaveChanges();
                    this.ApplicationState.UserData.CurrentOrderId = order.OrderId;
                }
            }

            using (var db = new StoreContext(this.ApplicationState.DbOptions))
            {
                var inventory = db.GetProductsAvailable(this.ApplicationState.UserData.OperatingLocationId);

                var order = db.GetOrderById(this.ApplicationState.UserData.CurrentOrderId);

                var i = 1;
                this.InventoryIds = inventory.Select(i => i.LocationInventoryId).ToList();
                Console.WriteLine("#\tStock\tName");
                foreach (var stock in inventory)
                {
                    var projectedQuantity = db.ProjectStockBasedOnOrder(order, stock.Product);
                    if (projectedQuantity < 0)
                    {
                        projectedQuantity = 0;
                    }
                    Console.WriteLine($"{i}.\t{projectedQuantity}\t{stock.Product.Name}");
                    i += 1;
                }
                Console.Write("\n----------------------------------------------\n");
            }
        }
        /// <summary>
        /// Print this menu.
        /// </summary>
        public void PrintMenu()
        {
            Console.Clear();
            CliPrinter.Title("Edit Order");
            this.ApplicationState.UserData.RefreshCurrentOrder();

            this.LineItemIds.Clear();

            using (var db = new StoreContext(this.ApplicationState.DbOptions))
            {
                var order = db.GetOrderById(this.ApplicationState.UserData.CurrentOrderId);
                if (order == null)
                {
                    return;
                }
                if (order.OrderLineItems.Count() == 0)
                {
                    return;
                }
                var itemNameDividerSize = order.OrderLineItems.Max(li => li.Product.Name.Length);
                Console.WriteLine("#\tQty\tEach\tTotal\tName");
                Console.WriteLine($"===\t===\t=====\t=====\t{new string('=', itemNameDividerSize)}");

                double orderTotalCost  = 0.0;
                int    orderTotalUnits = 0;
                foreach (var o in order.OrderLineItems)
                {
                    this.LineItemIds.Add(o.OrderLineItemId);
                    var lineItemTotal = o.Product.Price * o.Quantity;
                    orderTotalCost  += lineItemTotal;
                    orderTotalUnits += o.Quantity;
                    Console.WriteLine($"{this.LineItemIds.Count}\t{o.Quantity}\t${o.Product.Price}\t${lineItemTotal}\t{o.Product.Name}");
                }

                Console.WriteLine($"---\t-----\t-----\t-----\t{new string('-', itemNameDividerSize)}");
                Console.Write($"\t{orderTotalUnits}\t\t${orderTotalCost}\tTotal\n\n");
            }
        }
        /// <summary>
        /// Handle menu input.
        /// </summary>
        public void InputLoop()
        {
            if (this.ApplicationState.UserData.CurrentOrderId == null)
            {
                this.AbortThenExit("No current order on file.");
                return;
            }

            var orderTotalCost = 0.0;

            using (var db = new StoreContext(this.ApplicationState.DbOptions))
            {
                var order = db.GetOrderById(this.ApplicationState.UserData.CurrentOrderId);
                if (order.OrderLineItems.Count == 0)
                {
                    CliInput.PressAnyKey("There are no items in your order.");
                    this.MenuExit();
                    return;
                }
                Console.WriteLine("Qty\tEach\tTotal\tName");
                Console.WriteLine("===\t=====\t=====\t====");


                var totalItems = 0;
                foreach (var o in order.OrderLineItems)
                {
                    var lineItemTotalCost = o.Product.Price * o.Quantity;
                    orderTotalCost += lineItemTotalCost;
                    totalItems     += o.Quantity;
                    Console.WriteLine($"{o.Quantity}\t${o.Product.Price}\t${lineItemTotalCost}\t{o.Product.Name}");
                }
                Console.Write("---\t-----\t-----\t--------------------------\n");
                Console.Write($"{totalItems}\t\t${orderTotalCost}\n\n");
            }
            Console.WriteLine("1.  Place Order");
            Console.WriteLine("2.  Exit");

            ConsoleKeyInfo cki;

            do
            {
                cki = Console.ReadKey(true);
                if (cki.Key == ConsoleKey.D1)
                {
                    Console.WriteLine("Placing order...");

                    var orderId = this.ApplicationState.UserData.CurrentOrderId;
                    try
                    {
                        var orderResult = this.ApplicationState.DbOptions.PlaceOrder(orderId, StoreDbUtil.Config.MAX_ORDER_QUANTITY);
                        switch (orderResult)
                        {
                        case PlaceOrderResult.Ok:
                            this.AbortThenExit("Order placed successfully.");
                            return;

                        case PlaceOrderResult.OutOfStock:
                            this.AbortThenExit("Unable to place order: Some items are out of stock.");
                            return;

                        case PlaceOrderResult.NoLineItems:
                            this.AbortThenExit("Unable to place order: There are no items in the order.");
                            return;

                        case PlaceOrderResult.OrderNotFound:
                            this.AbortThenExit("Unable to place order: Unable to locate the order.");
                            return;

                        case PlaceOrderResult.HighQuantityRejection:
                            this.AbortThenExit($"Unable to place order: Item quantities too high ({StoreDbUtil.Config.MAX_ORDER_QUANTITY} max)");
                            return;
                        }
                    } catch (NullReferenceException) {
                        this.AbortThenExit("Unable to place order: Order id is missing (this is a bug).");
                        return;
                    }
                }
                else if (cki.Key == ConsoleKey.D2 || cki.Key == ConsoleKey.Enter)
                {
                    this.MenuExit();
                    return;
                }
            } while (true);
        }
        /// <summary>
        /// Handle input.
        /// </summary>
        public void InputLoop()
        {
            do
            {
                this.PrintMenu();
                if (this.ApplicationState.UserData.CurrentOrderId == null)
                {
                    CliInput.PressAnyKey("There is currently no open order.");
                    break;
                }
                using (var db = new StoreContext(this.ApplicationState.DbOptions))
                {
                    var order = db.GetOrderById(this.ApplicationState.UserData.CurrentOrderId);
                    if (order == null)
                    {
                        break;
                    }
                    if (order.OrderLineItems.Count() == 0)
                    {
                        CliInput.PressAnyKey("There are no items in your order.");
                        break;
                    }
                }

                var getLineOptions = CliInput.GetLineOptions.AcceptEmpty | CliInput.GetLineOptions.TrimSpaces;
                var option         = CliInput.GetLine(getLineOptions, v => true, "[D]elete / Change [Q]uantity: ");
                switch (option)
                {
                case null:
                case "":
                    this.MenuExit();
                    return;

                case "D":
                case "d":
                {
                    var itemNumber = CliInput.GetInt(CliInput.GetIntOptions.AllowEmpty, n => n > 0 && n <= this.LineItemIds.Count, "Select item number:");
                    if (itemNumber == null)
                    {
                        continue;
                    }

                    using (var db = new StoreContext(this.ApplicationState.DbOptions))
                    {
                        var deleted = db.DeleteLineItem(this.LineItemIds[(int)itemNumber - 1]);
                        if (!deleted)
                        {
                            CliInput.PressAnyKey("There was a problem deleting that line item. Please try again.");
                        }
                    }
                    break;
                }

                case "Q":
                case "q":
                {
                    var itemNumber = CliInput.GetInt(CliInput.GetIntOptions.AllowEmpty, n => n > 0 && n <= this.LineItemIds.Count, "Select item number:");
                    if (itemNumber == null)
                    {
                        continue;
                    }

                    using (var db = new StoreContext(this.ApplicationState.DbOptions))
                    {
                        var order = db.GetOrderById(this.ApplicationState.UserData.CurrentOrderId);

                        var lineItemId = this.LineItemIds[(int)itemNumber - 1];
                        var lineItem   = order.OrderLineItems.Where(li => li.OrderLineItemId == lineItemId);

                        var product = lineItem.First().Product;


                        var maxOrder = db.LocationInventories
                                       .Where(i => i.Location.LocationId == order.Location.LocationId)
                                       .Where(i => i.Product.ProductId == product.ProductId)
                                       .Select(i => i.Quantity).FirstOrDefault();

                        var newQuantity = CliInput.GetInt(CliInput.GetIntOptions.AllowEmpty,
                                                          q => q >= 0 && q <= maxOrder,
                                                          $"New quantity [{maxOrder} max]:");

                        if (newQuantity == null)
                        {
                            continue;
                        }

                        var adjusted = db.SetLineItemQuantity(this.LineItemIds[(int)itemNumber - 1], (int)newQuantity);
                        if (!adjusted)
                        {
                            CliInput.PressAnyKey("There was a problem adjusting the quantity for that line item. Please try again.");
                        }
                    }
                    break;
                }
                }
            } while (true);
            this.MenuExit();
        }