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); } }
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 })); } }
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 })); } }