public async Task HandleAsync(RemoveStocksCommand command, CancellationToken cancellationToken)
        {
            using (var context = dbContextFactory.CreateDbContext())
            {
                var productIds = command.Items.Select(i => i.ProductId).ToList();

                var productLookup = await GetProductLookupAsync(context, productIds, cancellationToken).ConfigureAwait(false);

                var availableCountLookup = await GetAvailabileCountLookupAsync(context, productIds, cancellationToken).ConfigureAwait(false);

                requestValidator.ValidateAndThrow(command, productLookup, availableCountLookup);

                // This is for idempotence. We check only the TransactionId because we assume that if stocks for one product in a transaction is removed then so are the others.
                var stocksAlreadyRemoved = await context.ProductStockRemovedEvents.AnyAsync(evt => evt.TransactionId == command.TransactionId, cancellationToken).ConfigureAwait(false);

                if (stocksAlreadyRemoved)
                {
                    return;
                }

                foreach (var removedStock in command.Items)
                {
                    context.ProductStockRemovedEvents.Add(new ProductStockRemovedEvent
                    {
                        ProductId     = removedStock.ProductId,
                        Quantity      = removedStock.Quantity,
                        TransactionId = command.TransactionId
                    });
                }

                await context.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
            }
        }
Пример #2
0
 public ActionResult <StockLevel> Remove(int productId, [FromBody] RemoveStocksCommand command)
 {
     try
     {
         var quantityInStock = _stockService.RemoveStock(productId, command.Amount);
         var stockLevel      = new StockLevel(quantityInStock);
         return(Ok(stockLevel));
     }
     catch (NotEnoughStockException ex)
     {
         return(Conflict(new
         {
             ex.Message,
             ex.AmountToRemove,
             ex.QuantityInStock
         }));
     }
 }
Пример #3
0
 public ActionResult <StockLevel> Remove(
     int productId,
     [FromBody] RemoveStocksCommand command,
     [FromServices] RemoveStocks useCase
     )
 {
     try
     {
         var product    = useCase.Handle(productId, command.Amount);
         var stockLevel = _mappingService.Map <Product, StockLevel>(product);
         return(Ok(stockLevel));
     }
     catch (NotEnoughStockException ex)
     {
         return(Conflict(new
         {
             ex.Message,
             ex.AmountToRemove,
             ex.QuantityInStock
         }));
     }
 }