private async Task <decimal> UpdateInventoryForOrderAndReturnOrderTotalAsync(CustomerOrderFormViewModel model, int orderId)
        {
            decimal orderTotal = 0m;

            foreach (var item in model.OrderInventory)
            {
                var inventoryItem = await _dbContext.Inventory.SingleOrDefaultAsync(i => i.Id == item.InventoryId);

                var enoughInventoryAvailable = inventoryItem.AmountAvailable >= item.Quantity;

                if (enoughInventoryAvailable)
                {
                    item.OrderId = orderId;

                    await _orderRepository.AddOrderInventoryAsync(item);

                    orderTotal += (inventoryItem.PricePerUnit * item.Quantity);

                    var newAvailableAmount = inventoryItem.AmountAvailable - item.Quantity;

                    inventoryItem.AmountAvailable = newAvailableAmount;
                }
            }

            return(orderTotal);
        }
        public async Task <IActionResult> HandleCustomerOrderSubmission(CustomerOrderFormViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(RedirectToAction("Index", "Order", new { error = "You done goofed!" }));
            }

            var customerForOrder = await _dbContext.Customer.SingleOrDefaultAsync(c => c.Email == model.Email);

            var newOrder = new Order
            {
                CustomerId     = customerForOrder.Id,
                DateCreatedUTC = DateTime.UtcNow
            };

            _dbContext.Order.Add(newOrder);
            await _dbContext.SaveChangesAsync();

            decimal orderTotal = 0;

            foreach (var item in model.OrderInventory)
            {
                var inventoryItem = await _dbContext.Inventory.SingleOrDefaultAsync(i => i.Id == item.InventoryId);

                var enoughInventoryAvailable = inventoryItem.AmountAvailable >= item.Quantity;

                if (enoughInventoryAvailable)
                {
                    item.OrderId = newOrder.Id;

                    _dbContext.OrderInventory.Add(item);
                    await _dbContext.SaveChangesAsync();

                    orderTotal += (inventoryItem.PricePerUnit * item.Quantity);

                    var newAvailableAmount = inventoryItem.AmountAvailable - item.Quantity;

                    inventoryItem.AmountAvailable = newAvailableAmount;

                    _dbContext.Inventory.Update(inventoryItem);
                    await _dbContext.SaveChangesAsync();
                }
            }

            var newPayment = new Payment
            {
                CustomerId = customerForOrder.Id,
                OrderId    = newOrder.Id,
                Total      = orderTotal
            };

            _dbContext.Payment.Add(newPayment);
            await _dbContext.SaveChangesAsync();

            return(RedirectToAction("Index", "Home"));
        }
        public async Task <IActionResult> RefactoredIndex(string error)
        {
            var model = new CustomerOrderFormViewModel
            {
                InventoryList  = await _inventoryRepository.GetInventoryAsync(),
                OrderInventory = new List <OrderInventory>(),
                Error          = error
            };

            return(View(model));
        }
        private async Task <Customer> GetCustomerForOrderAsync(CustomerOrderFormViewModel model)
        {
            var customerResult = await _dbContext.Customer.SingleOrDefaultAsync(c => c.Email == model.Email);

            if (customerResult != null)
            {
                return(customerResult);
            }

            var newCustomer = model.CreateCustomerObject();

            return(await _customerRepository.CreateCustomerAsync(newCustomer));
        }
        public async Task <IActionResult> HandleCustomerOrderSubmissionRefactored(CustomerOrderFormViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(RedirectToAction("Index", "Order", new { error = "You done goofed!" }));
            }

            var customer = await GetCustomerForOrderAsync(model);

            var order = await PrepareOrderForCustomerAsync(customer.Id);

            var orderTotal = await UpdateInventoryForOrderAndReturnOrderTotalAsync(model, order.Id);

            await HandlePaymentForOrderAsync(customer.Id, order.Id, orderTotal);

            return(RedirectToAction("Index", "Home"));
        }