public OutboundOrderTrucksResponse Post([FromBody] OutboundOrderRequestModel request) { log.Info(String.Format("Processing outbound order: {0}", request)); var gtins = new List <String>(); foreach (var orderLine in request.OrderLines) { if (gtins.Contains(orderLine.gtin)) { throw new ValidationException( String.Format("Outbound order request contains duplicate product gtin: {0}", orderLine.gtin)); } gtins.Add(orderLine.gtin); } var productDataModels = productRepository.GetProductsByGtin(gtins); var products = productDataModels.ToDictionary(p => p.Gtin, p => new Product(p)); 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 newTrucks = new TruckService(productRepository); var trucks = newTrucks.GetTrucks(lineItems); var response = new OutboundOrderTrucksResponse { Trucks = trucks, NumberOfTrucks = trucks.Count }; return(response); }