public async Task <ISingleResponse <Order> > CreateOrderAsync(Order header, OrderDetail[] details)
        {
            Logger?.LogDebug("{0} has been invoked", nameof(CreateOrderAsync));

            var response = new SingleResponse <Order>();

            try
            {
                // Begin transaction
                using (var transaction = await DbContext.Database.BeginTransactionAsync())
                {
                    // Retrieve warehouses
                    var warehouses = await ProductionRepository
                                     .GetWarehouses()
                                     .ToListAsync();

                    try
                    {
                        foreach (var detail in details)
                        {
                            // Retrieve product by id
                            var product = await ProductionRepository
                                          .GetProductAsync(new Product(detail.ProductID));

                            if (product == null)
                            {
                                // Throw exception if product no exists
                                throw new NonExistingProductException(String.Format(SalesDisplays.NonExistingProductExceptionMessage, detail.ProductID));
                            }
                            else
                            {
                                // Set product name from existing entity
                                detail.ProductName = product.ProductName;
                            }

                            if (product.Discontinued == true)
                            {
                                // Throw exception if product is discontinued
                                throw new AddOrderWithDiscontinuedProductException(String.Format(SalesDisplays.AddOrderWithDiscontinuedProductExceptionMessage, product.ProductID));
                            }

                            // Set unit price and total for product detail
                            detail.UnitPrice = product.UnitPrice;
                            detail.Total     = product.UnitPrice * detail.Quantity;
                        }

                        // Calculate total for order header from order's details
                        header.Total = details.Sum(item => item.Total);

                        // Save order header
                        await SalesRepository.AddOrderAsync(header);

                        foreach (var detail in details)
                        {
                            // Set order id for order detail
                            detail.OrderID = header.OrderID;

                            // Add order detail
                            await SalesRepository.AddOrderDetailAsync(detail);

                            // Get last inventory for product
                            var lastInventory = ProductionRepository
                                                .GetProductInventories()
                                                .Where(item => item.ProductID == detail.ProductID)
                                                .OrderByDescending(item => item.CreationDateTime)
                                                .FirstOrDefault();

                            // Calculate stocks for product
                            var stocks = lastInventory == null ? 0 : lastInventory.Stocks - detail.Quantity;

                            // Create product inventory instance
                            var productInventory = new ProductInventory
                            {
                                ProductID        = detail.ProductID,
                                WarehouseID      = warehouses.First().WarehouseID,
                                CreationDateTime = DateTime.Now,
                                Quantity         = detail.Quantity * -1,
                                Stocks           = stocks
                            };

                            // Save product inventory
                            await ProductionRepository.AddProductInventoryAsync(productInventory);
                        }

                        response.Model = header;

                        // Commit transaction
                        transaction.Commit();

                        Logger.LogInformation(SalesDisplays.CreateOrderMessage);
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();

                        throw ex;
                    }
                }
            }
            catch (Exception ex)
            {
                response.SetError(ex, Logger);
            }

            return(response);
        }
Exemplo n.º 2
0
        public async Task <ISingleModelResponse <Order> > CreateOrderAsync(Order header, OrderDetail[] details)
        {
            Logger?.LogInformation("{0} has been invoked", nameof(CreateOrderAsync));

            var response = new SingleModelResponse <Order>();

            try
            {
                using (var transaction = await DbContext.Database.BeginTransactionAsync())
                {
                    var warehouses = await ProductionRepository.GetWarehouses().ToListAsync();

                    try
                    {
                        foreach (var detail in details)
                        {
                            var product = await ProductionRepository.GetProductAsync(new Product { ProductID = detail.ProductID });

                            if (product == null)
                            {
                                throw new NonExistingProductException(
                                          String.Format("Sent order has a non existing product with ID: '{0}', order has been cancelled.", detail.ProductID)
                                          );
                            }
                            else
                            {
                                detail.ProductName = product.ProductName;
                            }

                            if (product.Discontinued == true)
                            {
                                throw new AddOrderWithDiscontinuedProductException(
                                          String.Format("Product with ID: '{0}' is discontinued, order has been cancelled.", product.ProductID)
                                          );
                            }

                            detail.UnitPrice = product.UnitPrice;
                            detail.Total     = product.UnitPrice * detail.Quantity;
                        }

                        header.Total = details.Sum(item => item.Total);

                        await SalesRepository.AddOrderAsync(header);

                        foreach (var detail in details)
                        {
                            detail.OrderID = header.OrderID;

                            await SalesRepository.AddOrderDetailAsync(detail);

                            var lastInventory = ProductionRepository
                                                .GetProductInventories()
                                                .Where(item => item.ProductID == detail.ProductID)
                                                .OrderByDescending(item => item.CreationDateTime)
                                                .FirstOrDefault();

                            var stocks = lastInventory == null ? 0 : lastInventory.Stocks - detail.Quantity;

                            var productInventory = new ProductInventory
                            {
                                ProductID        = detail.ProductID,
                                WarehouseID      = warehouses.First().WarehouseID,
                                CreationDateTime = DateTime.Now,
                                Quantity         = detail.Quantity * -1,
                                Stocks           = stocks
                            };

                            await ProductionRepository.AddProductInventoryAsync(productInventory);
                        }

                        response.Model = header;

                        transaction.Commit();
                    }
                    catch (Exception ex)
                    {
                        transaction.Rollback();

                        throw ex;
                    }
                }
            }
            catch (Exception ex)
            {
                response.SetError(ex, Logger);
            }

            return(response);
        }