Exemple #1
0
 public OrderRessource getOrderRessource()
 {
     if (this.orderRessource == null)
     {
         this.orderRessource = new OrderRessource(this.client);
     }
     return(this.orderRessource);
 }
        public async Task <ActionResult <OrderRessource> > PostOrderAsync(OrderRessource orderRessource)
        {
            // TODO: Reduce Stock


            using (var transaction = await _context.Database.BeginTransactionAsync())
            {
                // Check if the customer already exists.
                Customer customer = _context.Customer.Find(orderRessource.Customer.Id);
                if (customer == null)
                {
                    return(BadRequest("The customer does not exist."));
                }

                // Check if the address already exists.

                Address address = _context.Address.Find(customer.Address.Id);
                if (address == null)
                {
                    return(BadRequest("The address does not exist."));
                }

                #region Backup Address
                var backupedAddress = _context.OrderedAddress.Where(x => x.City == address.City && x.Street == address.Street && x.Zip == address.Zip).FirstOrDefault();

                // Create "ghost/copy/backup"-Address
                if (backupedAddress == null)
                {
                    backupedAddress    = _mapper.Map <OrderedAddress>(address);
                    backupedAddress.Id = 0; // Let EF Core set it from database
                    await _context.OrderedAddress.AddAsync(backupedAddress);
                }

                #endregion

                #region Backup Customer
                OrderedCustomer newOrderedCustomer = _context.OrderedCustomer.Where(x => x.Firstname == customer.Firstname && x.Lastname == customer.Lastname && x.OrderedAddressId == backupedAddress.Id).FirstOrDefault();

                // Create "ghost/copy/backup"-Customer
                if (newOrderedCustomer == null)
                {
                    newOrderedCustomer = new OrderedCustomer()
                    {
                        Firstname      = customer.Firstname,
                        Lastname       = customer.Lastname,
                        OrderedAddress = backupedAddress
                    };
                    await _context.OrderedCustomer.AddAsync(newOrderedCustomer);
                }
                #endregion

                // Check if state is provided.
                uint stateId = 1;
                if (orderRessource.State != null)
                {
                    stateId = orderRessource.State.Id;
                }

                Order newOrder = new Order
                {
                    CreatedAt       = DateTime.Now.ToUniversalTime(),
                    Customer        = customer,
                    State           = await _context.State.FindAsync(stateId),
                    OrderedCustomer = newOrderedCustomer
                };

                await _context.Order.AddAsync(newOrder);

                OrderedProductRessource[] array = orderRessource.OrderedProducts.ToArray();

                for (int i = 0; i < array.Length; i++)
                {
                    OrderedProductRessource orderedProductRessource = array[i];
                    OrderedProduct          orderedProduct          = _mapper.Map <OrderedProduct>(orderedProductRessource);

                    // check if the product exists.
                    Product product = _context.Product.Find(orderedProductRessource.Id);
                    if (product == null)
                    {
                        return(NotFound($"The ordered product with the ID={orderedProductRessource.Id} was not found."));
                    }

                    #region Backup Product
                    // Add "ghost/copy/backup"-Product if no entry exists.
                    uint           orderedProductId = 0;
                    OrderedProduct ordProd          = _context.OrderedProduct.Where(ordProd => ordProd.ProductId == orderedProduct.Id).FirstOrDefault();

                    if (ordProd != null)
                    {
                        orderedProductId = _context.OrderedProduct.Where(ordProd => ordProd.ProductId == orderedProduct.Id).FirstOrDefault().Id;
                    }

                    if (orderedProductId == 0)
                    {
                        // TODO: Check values, sanitize.
                        ordProd = new OrderedProduct()
                        {
                            Name    = product.Name,
                            Price   = product.Price,
                            Sku     = product.Sku,
                            Product = product
                        };
                        await _context.OrderedProduct.AddAsync(ordProd);

                        orderedProduct = ordProd;
                    }
                    #endregion

                    #region Add ordered product to OrderedProductTable
                    // Add orderedProduct to OrderedProductOrder-Table if no entry exists.
                    // BUG: id is always 0
                    var ordProdOrd = _context.OrderedProductOrder.Find(ordProd.Id, newOrder.Id);
                    if (ordProdOrd == null || ordProdOrd.Quantity != orderedProductRessource.Quantity)
                    {
                        OrderedProductOrder opo = new OrderedProductOrder()
                        {
                            OrderedProduct = ordProd,
                            Order          = newOrder,
                            Quantity       = orderedProductRessource.Quantity
                        };
                        await _context.OrderedProductOrder.AddAsync(opo);
                    }
                    #endregion

                    #region Reduce Stock
                    // Reduce the stock of the item on the location with the highest quantity.
                    var productsAtLocation = _context.LocationProduct.OrderByDescending(x => x.Quantity).Where(x => x.ProductId == product.Id).ToList();
                    if (productsAtLocation == null)
                    {
                        return(BadRequest($"Not enough quantity for productId: {product.Id}"));
                    }

                    // Check if enough products in stock and reduce.
                    uint reduced = ReduceStock(orderedProductRessource, productsAtLocation);

                    // still items to be reduced, but nothing in stock.
                    if (reduced > 0)
                    {
                        return(BadRequest($"Not enough quantity for productId: {product.Id}"));
                    }
                    #endregion
                }

                var result = await TryContextSaveAsync();

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

                await transaction.CommitAsync();

                return(CreatedAtAction(nameof(GetOrderAsync), new { id = newOrder.Id }, newOrder));
            }
        }