public void Post([FromBody] OutboundOrderRequestModel request) { log.Info(String.Format("Processing outbound order: {0}", request)); var products = GetProductsFromRequest(request); var lineItems = new List <StockAlteration>(); var productIds = new List <int>(); var errors = new List <string>(); foreach (var orderLine in request.OrderLines) { if (!products.ContainsKey(orderLine.gtin)) { errors.Add(string.Format("Unknown product gtin: {0}", orderLine.gtin)); } else { var product = products[orderLine.gtin]; lineItems.Add(new StockAlteration(product.Id, orderLine.quantity)); productIds.Add(product.Id); } } if (errors.Count > 0) { throw new NoSuchEntityException(string.Join("; ", errors)); } var stock = stockRepository.GetStockByWarehouseAndProductIds(request.WarehouseId, productIds); var orderLines = request.OrderLines.ToList(); errors = new List <string>(); for (int i = 0; i < lineItems.Count; i++) { var lineItem = lineItems[i]; var orderLine = orderLines[i]; if (!stock.ContainsKey(lineItem.ProductId)) { errors.Add(string.Format("Product: {0}, no stock held", orderLine.gtin)); continue; } var item = stock[lineItem.ProductId]; if (lineItem.Quantity > item.held) { errors.Add( string.Format("Product: {0}, stock held: {1}, stock to remove: {2}", orderLine.gtin, item.held, lineItem.Quantity)); } } if (errors.Count > 0) { throw new InsufficientStockException(string.Join("; ", errors)); } stockRepository.RemoveStock(request.WarehouseId, lineItems); truckService.CreateTruckLoad(lineItems); }