private async Task <bool> GenerateParcelsAsync(OrderDto order) { var orderItems = new Queue <OrderItemDto>(order.OrderItems); var parcels = new List <ParcelDto>(); var maxParcelSize = configuration.GetValue <int>("MaxParcelSize"); while (orderItems.Count > 0) { var parcel = new ParcelDto { ParcelItems = new List <ParcelItemDto>(), ParcelNo = parcelRepository.GetNextParcelNo(), }; parcels.Add(parcel); while (orderItems.TryPeek(out OrderItemDto peek) && peek.Quantity + parcel.ParcelItems.Sum(x => x.Quantity) <= maxParcelSize) { OrderItemDto orderItem = orderItems.Dequeue(); if (await stocksRepository.ReserveAsync(orderItem.ArticleNo, orderItem.Quantity).ConfigureAwait(false)) { parcel.ParcelItems.Add(new ParcelItemDto { ArticleNo = orderItem.ArticleNo, Quantity = orderItem.Quantity }); } else { await AbortOrderAsync(parcels).ConfigureAwait(false); return(false); } } } foreach (ParcelDto parcel in parcels) { await parcelRepository.InsertAsync(parcel).ConfigureAwait(false); foreach (ParcelItemDto parcelItem in parcel.ParcelItems) { await stocksRepository.ConfirmReservation(parcelItem.ArticleNo, parcelItem.Quantity).ConfigureAwait(false); } } return(true); }