/// <summary>
        /// Sends and process an order to the database.
        /// </summary>
        /// <param name="order">The order to process</param>
        public async Task SendOrderTransaction(IOrder order)
        {
            using var context = new DigitalStoreContext(Options);

            if (order.ShoppingCartQuantity.Count == 0)
            {
                throw new OrderException("Cannot submit order with no products in cart.");
            }

            var productIds    = order.ShoppingCartQuantity.Keys.Select(s => s.Id).ToList();
            var foundProducts = await context.Products.Where(p => productIds.Contains(p.Id)).ToListAsync();

            if (productIds.Count != foundProducts.Count)
            {
                throw new OrderException("One or more Products in cart did not exist in the database.");
            }

            PurchaseOrder purchaseOrder = new PurchaseOrder()
            {
                // TODO: Replace with proper authentication and unique identification using a Login System
                CustomerId      = order.Customer.Id,
                DateProcessed   = DateTime.Now,
                OrderLines      = new List <OrderLine>(),
                StoreLocationId = order.StoreLocation.Id
            };

            await AddProductsToOrder(order, context, foundProducts, purchaseOrder);

            await context.PurchaseOrders.AddAsync(purchaseOrder);

            await context.SaveChangesAsync();
        }
        /// <summary>
        /// Gets the location by a given name.
        /// </summary>
        /// <param name="name">The name of the location.</param>
        /// <returns>Returns the location with the given name.</returns>
        public async Task <Library.Model.ILocation> LookUpLocationByNameAsync(string name)
        {
            using var context = new DigitalStoreContext(Options);

            var storeLocation = await context.StoreLocations
                                .Include(s => s.Inventories)
                                .ThenInclude(i => i.Product)
                                .Include(s => s.Address)
                                .FirstOrDefaultAsync(s => s.Name == name);

            if (storeLocation is null)
            {
                return(null);
            }

            var inventoryPairs = storeLocation.Inventories.Select(
                i => new KeyValuePair <Library.Model.IProduct, int>(
                    new Library.Model.Product(i.Product.Name, i.Product.Category, i.Product.UnitPrice, i.ProductId),
                    i.Quantity)).ToList();

            var inventoryDictionary = inventoryPairs.ToDictionary((keyItem) => (keyItem).Key, (valueItem) => valueItem.Value);

            Library.Model.ILocation location = new Library.Model.Location(
                name: storeLocation.Name,
                address: storeLocation.Address.Print(),
                inventory: inventoryDictionary,
                id: storeLocation.Id
                );

            return(location);
        }
示例#3
0
        private static IQueryable <Customer> GetCustomersFromName(DigitalStoreContext context, string firstName, string lastName)
        {
            string trimmedFirst = firstName.Trim();
            string trimmedLast  = string.IsNullOrWhiteSpace(lastName) ? null : lastName.Trim();

            var customerQuery = context.Customers.Where(c => c.FirstName == trimmedFirst && c.LastName == trimmedLast);

            return(customerQuery);
        }
示例#4
0
        /// <summary>
        /// Creates and sends a request to the server to get the customer entry with the specified first and last name
        /// </summary>
        /// <param name="firstName">The first name of the customer</param>
        /// <param name="lastName">The last name of the customer</param>
        /// <returns>Returns a list of customers as some customers may have the same name</returns>
        public async Task <List <Library.Model.Customer> > LookUpCustomersByNameAsync(string firstName, string lastName)
        {
            using var context = new DigitalStoreContext(Options);

            var query = GetCustomersFromName(context, firstName, lastName);

            var customers = await query.ToListAsync();

            return(customers.Select(c => new Library.Model.Customer(c.FirstName, c.LastName, c.Id)).ToList());
        }
示例#5
0
        /// <summary>
        /// Searches the database for customers that have either their first or last name contain the search query
        /// </summary>
        /// <param name="nameQuery">The query to search for in the customers' full names</param>
        /// <returns>Returns a list of customers as some customers contain the query</returns>
        public async Task <List <Library.Model.ICustomer> > SearchCustomersAsync(string nameQuery)
        {
            using var context = new DigitalStoreContext(Options);

            if (string.IsNullOrWhiteSpace(nameQuery))
            {
                throw new ArgumentException("Search query cannot be empty or null");
            }

            var customers = await context.Customers.Where(c => c.FirstName.Contains(nameQuery) || (!string.IsNullOrWhiteSpace(c.LastName) && c.LastName.Contains(nameQuery))).ToListAsync();

            return(customers.Select(c => (Library.Model.ICustomer) new Library.Model.Customer(c.FirstName, c.LastName, c.Id)).ToList());
        }
示例#6
0
        /// <summary>
        /// Creates a customer and adds it into the database. It does not check for duplicates before creating it.
        /// </summary>
        /// <param name="firstName">The first name of the customer.</param>
        /// <param name="lastName">The last name of the customer.</param>
        public async Task CreateCustomerAsync(Library.Model.INewCustomer customer)
        {
            using var context = new DigitalStoreContext(Options);

            bool lastNameIsEmpty = string.IsNullOrWhiteSpace(customer.LastName);

            await context.Customers.AddAsync(new Customer()
            {
                FirstName = customer.FirstName,
                LastName  = lastNameIsEmpty ? null : customer.LastName
            });

            await context.SaveChangesAsync();
        }
        /// <summary>
        /// Looks up a product by its name and returns it.
        /// </summary>
        /// <param name="name">The name of the product.</param>
        /// <returns>Returns a single product with the specified name.</returns>
        public async Task <IProduct> LookupProductFromName(string name)
        {
            using var context = new DigitalStoreContext(Options);

            var product = await context.Products.Where(c => c.Name == name).FirstOrDefaultAsync();

            if (product is not null)
            {
                return(new Library.Model.Product(product.Name, product.Category, product.UnitPrice, product.Id));
            }
            else
            {
                return(null);
            }
        }
        /// <summary>
        /// Retrieves a list of all of the orders from a specified location.
        /// </summary>
        /// <param name="locationName">The name of the location.</param>
        /// <returns>Returns a list of all of the orders found.</returns>
        public async Task <List <IReadOnlyOrder> > GetOrdersFromLocation(string locationName)
        {
            using var context = new DigitalStoreContext(Options);

            var purchaseOrders = await context.PurchaseOrders
                                 .Include(p => p.Customer)
                                 .Include(p => p.OrderLines)
                                 .ThenInclude(o => o.Product)
                                 .Include(p => p.StoreLocation)
                                 .ThenInclude(s => s.Address)
                                 .Where(p => p.StoreLocation.Name == locationName).ToListAsync();

            var orderList = ConvertPurchaseOrderToIOrders(purchaseOrders);

            return(orderList);
        }
        private static async Task AddProductsToOrder(IOrder order, DigitalStoreContext context, List <Product> foundProducts, PurchaseOrder purchaseOrder)
        {
            var inventories = await context.Inventories
                              .Where(i => i.StoreId == purchaseOrder.StoreLocationId).ToListAsync();

            foreach (var productQuantity in order.ShoppingCartQuantity)
            {
                var product  = productQuantity.Key;
                int quantity = productQuantity.Value;

                if (quantity <= 0)
                {
                    throw new OrderException("Cannot order products with a quantity less than or equal to 0.");
                }

                Product foundProduct = foundProducts.Find(p => p.Name == product.Name);

                var inventory = inventories.Where(i => i.ProductId == foundProduct.Id).FirstOrDefault();

                if (inventory is null)
                {
                    throw new OrderException($"Store location does not contain the product '{product.Name}' in its inventory.");
                }

                if (inventory.Quantity >= quantity)
                {
                    inventory.Quantity -= quantity;
                }
                else
                {
                    throw new OrderException($"The store location only has {inventory.Quantity} of '{inventory.Product.Name}' in stock, but the order is requesting to order {quantity} of the product.");
                }

                purchaseOrder.OrderLines.Add(new OrderLine()
                {
                    Quantity          = quantity,
                    Product           = foundProduct,
                    PurchaseOrder     = purchaseOrder,
                    PurchaseUnitPrice = product.UnitPrice
                });
            }
        }