public ParcelOrderOutput BuildOrder(ParcelOrder parcelOrder) { if (!parcelOrder.ParcelOrderItems.HaveValidParcelItems()) { throw new Exception("Invalid Process."); } var parcelOrderOutput = new ParcelOrderOutput { IsSpeedy = parcelOrder.Speedy }; var parcelBySize = parcelOrder.ParcelOrderItems.Where(p => p.CalculationType.Equals(CalculationType.BySize)); var parcelByWeight = parcelOrder.ParcelOrderItems.Where(p => p.CalculationType.Equals(CalculationType.ByWeight)); if (parcelBySize.Any()) { var(lineItems, totalCost) = ComposeLineItems(parcelBySize, ParcelBySizeSelector()); parcelOrderOutput.LineItems.AddRange(lineItems); parcelOrderOutput.TotalCost += totalCost; } if (parcelByWeight.Any()) { var(lineItems, totalCost) = ComposeLineItems(parcelByWeight, ParcelByWeightSelector()); parcelOrderOutput.LineItems.AddRange(lineItems); parcelOrderOutput.TotalCost += totalCost; } // apply discounts if (parcelOrder.DiscountToApply.Any()) { AppliedDiscount discount; if (parcelOrder.DiscountToApply.Contains(DiscountTypes.Mixed)) { discount = _discountCalculator.CalculateMixedDiscount(parcelOrderOutput.LineItems); } else { discount = _discountCalculator.CalculateDiscount(parcelOrderOutput.LineItems); } parcelOrderOutput.TotalCost = discount.TotalCost; parcelOrderOutput.TotalSaved = discount.SavedCost; } if (parcelOrder.Speedy) { parcelOrderOutput.TotalCost *= 2; } return(parcelOrderOutput); }