/// <summary> /// Gets available shipping options /// </summary> /// <param name="getShippingOptionRequest">A request for getting shipping options</param> /// <returns>Represents a response of getting shipping rate options</returns> public GetShippingOptionResponse GetShippingOptions(GetShippingOptionRequest getShippingOptionRequest) { if (getShippingOptionRequest == null) { throw new ArgumentNullException("getShippingOptionRequest"); } var response = new GetShippingOptionResponse(); if (getShippingOptionRequest.Items == null || !getShippingOptionRequest.Items.Any()) { response.AddError("No shipment items"); return(response); } if (getShippingOptionRequest.ShippingAddress == null) { response.AddError("Shipping address is not set"); return(response); } var storeId = getShippingOptionRequest.StoreId; if (storeId == 0) { storeId = _storeContext.CurrentStore.Id; } int countryId = getShippingOptionRequest.ShippingAddress.CountryId.HasValue ? getShippingOptionRequest.ShippingAddress.CountryId.Value : 0; int stateProvinceId = getShippingOptionRequest.ShippingAddress.StateProvinceId.HasValue ? getShippingOptionRequest.ShippingAddress.StateProvinceId.Value : 0; int warehouseId = getShippingOptionRequest.WarehouseFrom != null ? getShippingOptionRequest.WarehouseFrom.Id : 0; string zip = getShippingOptionRequest.ShippingAddress.ZipPostalCode; var shippingMethods = _shippingService.GetAllShippingMethods(countryId); foreach (var shippingMethod in shippingMethods) { // SPC - Calc weight per shipping method decimal subTotal = decimal.Zero; decimal weightToSubtract = decimal.Zero; foreach (var packageItem in getShippingOptionRequest.Items) { // this is the original code which is wrong, its cacluating a price total, and not the weight total. // so the weight of the free item is still part of the calculation // left here for backwards compatibility if (packageItem.ShoppingCartItem.IsFreeShipping) { continue; } //TODO we should use getShippingOptionRequest.Items.GetQuantity() method to get subtotal subTotal += _priceCalculationService.GetSubTotal(packageItem.ShoppingCartItem); // SPC - add free ship by shipping method check if (_ShippingByWeightExtendedService.ProductHasFreeShipping(packageItem.ShoppingCartItem.ProductId, shippingMethod.Id)) { // product options have weight also? weightToSubtract = weightToSubtract + (packageItem.ShoppingCartItem.Product.Weight * packageItem.ShoppingCartItem.Quantity); } } decimal weight = _shippingService.GetTotalWeight(getShippingOptionRequest); weight = weight - weightToSubtract; decimal?rate = GetRate(subTotal, weight, shippingMethod.Id, storeId, warehouseId, countryId, stateProvinceId, zip); if (rate.HasValue) { var shippingOption = new ShippingOption(); shippingOption.Name = shippingMethod.GetLocalized(x => x.Name); shippingOption.Description = shippingMethod.GetLocalized(x => x.Description); shippingOption.Rate = rate.Value; response.ShippingOptions.Add(shippingOption); } } return(response); }