/// <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.Count == 0)
            {
                response.AddError("No shipment items");
                return response;
            }

            int? restrictByCountryId = (getShippingOptionRequest.ShippingAddress != null && getShippingOptionRequest.ShippingAddress.Country != null) ? (int?)getShippingOptionRequest.ShippingAddress.Country.Id : null;
            var shippingMethods = this._shippingService.GetAllShippingMethods(restrictByCountryId);
            foreach (var shippingMethod in shippingMethods)
            {
                var shippingOption = new ShippingOption();
                shippingOption.Name = shippingMethod.GetLocalized(x => x.Name);
                shippingOption.Description = shippingMethod.GetLocalized(x => x.Description);
                shippingOption.Rate = GetRate(shippingMethod.Id);
                response.ShippingOptions.Add(shippingOption);
            }

            return response;
        }
        /// <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();
            response.ShippingOptions.Add(new ShippingOption()
                {
                    Name = "Shipping option 1",
                    Description = "",
                    Rate = GetRate()
                });
            response.ShippingOptions.Add(new ShippingOption()
                {
                    Name = "Shipping option 2",
                    Description = "",
                    Rate = GetRate()
                });

            return response;
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress.Country == null)
            {
                response.AddError("Shipping country is not set");
                return response;
            }

            if (getShippingOptionRequest.CountryFrom == null)
            {
                getShippingOptionRequest.CountryFrom = _countryService.GetAllCountries().FirstOrDefault();
            }

            try
            {
                string requestString = CreateRequest(_upsSettings.AccessKey, _upsSettings.Username, _upsSettings.Password, getShippingOptionRequest,
                    _upsSettings.CustomerClassification, _upsSettings.PickupType, _upsSettings.PackagingType);
                if (_upsSettings.Tracing)
                    _traceMessages.AppendLine("Request:").AppendLine(requestString);

                string responseXml = DoRequest(_upsSettings.Url, requestString);
                if (_upsSettings.Tracing)
                    _traceMessages.AppendLine("Response:").AppendLine(responseXml);

                string error = "";
                var shippingOptions = ParseResponse(responseXml, ref error);
                if (String.IsNullOrEmpty(error))
                {
                    foreach (var shippingOption in shippingOptions)
                    {
                        if (!shippingOption.Name.ToLower().StartsWith("ups"))
                            shippingOption.Name = string.Format("UPS {0}", shippingOption.Name);
                        shippingOption.Rate += _upsSettings.AdditionalHandlingCharge;
                        response.ShippingOptions.Add(shippingOption);
                    }
                }
                else
                {
                    response.AddError(error);
                }
            }
            finally
            {
                if (_upsSettings.Tracing && _traceMessages.Length > 0)
                {
                    string shortMessage = String.Format("UPS Get Shipping Options for customer {0}.  {1} item(s) in cart",
                        getShippingOptionRequest.Customer.Email, getShippingOptionRequest.Items.Count);
                    _logger.Information(shortMessage, new Exception(_traceMessages.ToString()), getShippingOptionRequest.Customer);
                }
            }

            return response;
        }
Exemple #4
0
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList<ShoppingCartItem> cart,
            Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "")
        {
            if (cart == null)
                throw new ArgumentNullException("cart");

            var result = new GetShippingOptionResponse();

            //create a package
            var getShippingOptionRequest = CreateShippingOptionRequest(cart, shippingAddress);
            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods();
            if (shippingRateComputationMethods.Count == 0)
                throw new NopException("Shipping rate computation method could not be loaded");

            //get shipping options
            foreach (var srcm in shippingRateComputationMethods)
            {
                if (!String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName) &&
                   !allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                    continue;

                var getShippingOptionResponse = srcm.GetShippingOptions(getShippingOptionRequest);
                foreach (var so2 in getShippingOptionResponse.ShippingOptions)
                {
                    //system name
                    so2.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    //round
                    if (_shoppingCartSettings.RoundPricesDuringCalculation)
                        so2.Rate = Math.Round(so2.Rate, 2);
                    result.ShippingOptions.Add(so2);
                }

                //log errors
                if (!getShippingOptionResponse.Success)
                {
                    foreach (string error in getShippingOptionResponse.Errors)
                    {
                        result.AddError(error);
                        _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                    }
                }
            }

            //no shipping options loaded
            if (result.ShippingOptions.Count == 0 && result.Errors.Count == 0)
                result.Errors.Add("Shipping options could not be loaded");

            return result;
        }
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList<ShoppingCartItem> cart,
            Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "")
        {
            if (cart == null)
                throw new ArgumentNullException("cart");

            var result = new GetShippingOptionResponse();

            bool isFreeShipping = IsFreeShipping(cart);

            //create a package
            var getShippingOptionRequest = CreateShippingOptionRequest(cart, shippingAddress);
            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods();
            if (shippingRateComputationMethods.Count == 0)
                throw new NopException("Shipping rate computation method could not be loaded");

            //get shipping options
            foreach (var srcm in shippingRateComputationMethods)
            {
                if (!String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName) &&
                   !allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                    continue;

                var getShippingOptionResponse = srcm.GetShippingOptions(getShippingOptionRequest);
                foreach (var so2 in getShippingOptionResponse.ShippingOptions)
                {
                    so2.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    result.ShippingOptions.Add(so2);
                }

                //log errors
                if (!getShippingOptionResponse.Success)
                {
                    foreach (string error in getShippingOptionResponse.Errors)
                    {
                        result.AddError(error);
                        _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                    }
                }
            }

            //no shipping options loaded
            if (result.ShippingOptions.Count == 0 && result.Errors.Count == 0)
                result.Errors.Add("Shipping options could not be loaded");

            //additional shipping charges
            decimal additionalShippingCharge = GetShoppingCartAdditionalShippingCharge(cart);
            foreach (var so in result.ShippingOptions)
            {
                so.Rate += additionalShippingCharge;

                //free shipping
                if (isFreeShipping)
                    so.Rate = decimal.Zero;

            }

            return result;
        }
        /// <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.Count == 0)
            {
                response.AddError("No shipment items");
                return response;
            }
            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            var 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;
            string zip = getShippingOptionRequest.ShippingAddress.ZipPostalCode;
            decimal subTotal = decimal.Zero;
            foreach (var shoppingCartItem in getShippingOptionRequest.Items)
            {
                if (shoppingCartItem.IsFreeShipping || !shoppingCartItem.IsShipEnabled)
                    continue;
                subTotal += _priceCalculationService.GetSubTotal(shoppingCartItem, true);
            }
            decimal weight = _shippingService.GetTotalWeight(getShippingOptionRequest.Items);

            var shippingMethods = _shippingService.GetAllShippingMethods(countryId);
            foreach (var shippingMethod in shippingMethods)
            {
                decimal? rate = GetRate(subTotal, weight, shippingMethod.Id, storeId, 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;
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            string zipPostalCodeFrom = _australiaPostSettings.ShippedFromZipPostalCode;
            string zipPostalCodeTo = getShippingOptionRequest.ShippingAddress.ZipPostalCode;
            int weight = GetWeight(getShippingOptionRequest);
            int length = GetLength(getShippingOptionRequest);
            int width = GetWidth(getShippingOptionRequest);
            int height = GetHeight(getShippingOptionRequest);

            var country = getShippingOptionRequest.ShippingAddress.Country;

            //estimate packaging
            int totalPackages = 1;
            int totalPackagesDims = 1;
            int totalPackagesWeights = 1;
            if (length > MAX_LENGTH || width > MAX_LENGTH || height > MAX_LENGTH)
            {
                totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)Math.Max(Math.Max(length, width), height) / MAX_LENGTH));
            }
            if (weight > MAX_WEIGHT)
            {
                totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAX_WEIGHT));
            }
            totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;
            if (totalPackages == 0)
                totalPackages = 1;
            if (totalPackages > 1)
            {
                //recalculate dims, weight
                weight = weight / totalPackages;
                height = height / totalPackages;
                width = width / totalPackages;
                length = length / totalPackages;
                if (weight < MIN_WEIGHT)
                    weight = MIN_WEIGHT;
                if (height < MIN_LENGTH)
                    height = MIN_LENGTH;
                if (width < MIN_LENGTH)
                    width = MIN_LENGTH;
                if (length < MIN_LENGTH)
                    length = MIN_LENGTH;
            }

            int girth = height + height + width + width;
            if (girth < MIN_GIRTH)
            {
                height = MIN_LENGTH;
                width = MIN_LENGTH;
            }
            if (girth > MAX_GIRTH)
            {
                height = MAX_LENGTH / 4;
                width = MAX_LENGTH / 4;
            }
            try
            {
                switch (country.ThreeLetterIsoCode)
                {
                    case "AUS":
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Standard", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Express", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "EXP_PLT", weight, length, width, height, totalPackages));
                        break;
                    default:
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Air", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Sea", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "ECI_D", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "ECI_M", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "EPI", weight, length, width, height, totalPackages));
                        break;
                }

                foreach (var shippingOption in response.ShippingOptions)
                {
                    shippingOption.Rate += _australiaPostSettings.AdditionalHandlingCharge;
                }
            }
            catch (Exception ex)
            {
                response.AddError(ex.Message);
            }
            return response;
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress.Country == null)
            {
                response.AddError("Shipping country is not set");
                return response;
            }

            Currency requestedShipmentCurrency;
            var request = CreateRateRequest(getShippingOptionRequest, out requestedShipmentCurrency);
            var service = new RateService(); // Initialize the service
            service.Url = _fedexSettings.Url;
            try
            {
                // This is the call to the web service passing in a RateRequest and returning a RateReply
                var reply = service.getRates(request); // Service call

                if (reply.HighestSeverity == RateServiceWebReference.NotificationSeverityType.SUCCESS ||
                    reply.HighestSeverity == RateServiceWebReference.NotificationSeverityType.NOTE ||
                    reply.HighestSeverity == RateServiceWebReference.NotificationSeverityType.WARNING) // check if the call was successful
                {
                    if (reply != null && reply.RateReplyDetails != null)
                    {
                        var shippingOptions = ParseResponse(reply, requestedShipmentCurrency);
                        foreach (var shippingOption in shippingOptions)
                            response.ShippingOptions.Add(shippingOption);
                    }
                    else
                    {
                        if (reply != null &&
                            reply.Notifications != null &&
                            reply.Notifications.Length > 0 &&
                            !String.IsNullOrEmpty(reply.Notifications[0].Message))
                        {
                            response.AddError(string.Format("{0} (code: {1})", reply.Notifications[0].Message, reply.Notifications[0].Code));
                            return response;
                        }
                        else
                        {
                            response.AddError("Could not get reply from shipping server");
                            return response;
                        }
                    }
                }
                else
                {
                    Debug.WriteLine(reply.Notifications[0].Message);
                    response.AddError(reply.Notifications[0].Message);
                    return response;
                }
            }
            catch (SoapException e)
            {
                Debug.WriteLine(e.Detail.InnerText);
                response.AddError(e.Detail.InnerText);
                return response;
            }
            catch (Exception e)
            {
                Debug.WriteLine(e.Message);
                response.AddError(e.Message);
                return response;
            }

            return response;
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            try
            {
                var options = RequestShippingOptions(_RussianPostSettings.GatewayUrl,
                    _RussianPostSettings.Site,
                    _RussianPostSettings.Email,
                    getShippingOptionRequest.ZipPostalCodeFrom,
                    getShippingOptionRequest.ShippingAddress.ZipPostalCode,
                    DEFAULT_WEIGHT,
                    Convert.ToInt32(_shippingService.GetTotalPrice(getShippingOptionRequest.Items)),
                    OUTPUT_FORMAT,
                    ROUND);

                foreach (var opt in options)
                {
                    response.ShippingOptions.Add(opt);
                }
            }
            catch (Exception ex)
            {
                response.AddError(ex.Message);
            }
            return response;
        }
Exemple #10
0
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList <ShoppingCartItem> cart,
                                                                    Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "")
        {
            if (cart == null)
            {
                throw new ArgumentNullException("cart");
            }

            var result = new GetShippingOptionResponse();

            //create a package
            var getShippingOptionRequest       = CreateShippingOptionRequest(cart, shippingAddress);
            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods()
                                                 .Where(srcm =>
                                                        String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName) ||
                                                        allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                                                 .ToList();

            if (shippingRateComputationMethods.Count == 0)
            {
                throw new NopException("Shipping rate computation method could not be loaded");
            }

            //get shipping options
            foreach (var srcm in shippingRateComputationMethods)
            {
                var getShippingOptionResponse = srcm.GetShippingOptions(getShippingOptionRequest);
                foreach (var so2 in getShippingOptionResponse.ShippingOptions)
                {
                    //system name
                    so2.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    //round
                    if (_shoppingCartSettings.RoundPricesDuringCalculation)
                    {
                        so2.Rate = Math.Round(so2.Rate, 2);
                    }
                    result.ShippingOptions.Add(so2);
                }

                //log errors
                if (!getShippingOptionResponse.Success)
                {
                    foreach (string error in getShippingOptionResponse.Errors)
                    {
                        result.AddError(error);
                        _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                    }
                }
            }

            if (_shippingSettings.ReturnValidOptionsIfThereAreAny)
            {
                //return valid options if there are any (no matter of the errors returned by other shipping rate compuation methods).
                if (result.ShippingOptions.Count > 0 && result.Errors.Count > 0)
                {
                    result.Errors.Clear();
                }
            }

            //no shipping options loaded
            if (result.ShippingOptions.Count == 0 && result.Errors.Count == 0)
            {
                result.Errors.Add(_localizationService.GetResource("Checkout.ShippingOptionCouldNotBeLoaded"));
            }

            return(result);
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            string zipPostalCodeFrom = getShippingOptionRequest.ZipPostalCodeFrom;
            string zipPostalCodeTo = getShippingOptionRequest.ShippingAddress.ZipPostalCode;
            int weight = GetWeight(getShippingOptionRequest);


            decimal lengthTmp, widthTmp, heightTmp;
            _shippingService.GetDimensions(getShippingOptionRequest.Items, out widthTmp, out lengthTmp, out heightTmp);
            int length = Math.Min(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(lengthTmp, this.GatewayMeasureDimension))), MIN_LENGTH);
            int width = Math.Min(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(widthTmp, this.GatewayMeasureDimension))), MIN_LENGTH);
            int height = Math.Min(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(heightTmp, this.GatewayMeasureDimension))), MIN_LENGTH);
            
            //estimate packaging
            int totalPackagesDims = 1;
            int totalPackagesWeights = 1;
            if (length > MAX_LENGTH || width > MAX_LENGTH || height > MAX_LENGTH)
            {
                totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)Math.Max(Math.Max(length, width), height) / MAX_LENGTH));
            }
            if (weight > MAX_WEIGHT)
            {
                totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAX_WEIGHT));
            }
            var totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;
            if (totalPackages == 0)
                totalPackages = 1;
            if (totalPackages > 1)
            {
                //recalculate dims, weight
                weight = weight / totalPackages;
                height = height / totalPackages;
                width = width / totalPackages;
                length = length / totalPackages;
                if (weight < MIN_WEIGHT)
                    weight = MIN_WEIGHT;
                if (height < MIN_LENGTH)
                    height = MIN_LENGTH;
                if (width < MIN_LENGTH)
                    width = MIN_LENGTH;
                if (length < MIN_LENGTH)
                    length = MIN_LENGTH;
            }

            int girth = height + height + width + width;
            if (girth < MIN_GIRTH)
            {
                height = MIN_LENGTH;
                width = MIN_LENGTH;
            }
            if (girth > MAX_GIRTH)
            {
                height = MAX_LENGTH / 4;
                width = MAX_LENGTH / 4;
            }
                var country = getShippingOptionRequest.ShippingAddress.Country;
                if (country == null)
                {
                    response.AddError("Shipping country is not specified");
                    return response;
                }
                var serviceTypes = new List<string>();
                switch (country.ThreeLetterIsoCode)
                {
                    case "AUS":
                        //domestic services
                        serviceTypes.Add("Standard");
                        serviceTypes.Add("Express");
                        //discontinued
                        serviceTypes.Add("EXP_PLT");
                        break;
                    default:
                        //international services
                        serviceTypes.Add("Air");
                        serviceTypes.Add("Sea");
                        serviceTypes.Add("ECI_D");
                        serviceTypes.Add("ECI_M");
                        serviceTypes.Add("EPI");
                        break;
                }
            foreach (var serviceType in serviceTypes)
            {
                try
                {
                    response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, 
                        zipPostalCodeTo,
                        country.TwoLetterIsoCode,
                        serviceType,
                        weight, 
                        length, 
                        width, 
                        height, 
                        totalPackages));
                }
                catch
                {
                    //If this plugin doesn't allow some method (e.g. sea freight) to the selected country (e.g. New Zealand),
                    //the AusPost API returns an err_msg.
                    //This throws an exception which results in no shipping options being offered at all.
                    //The result is that customers from NZ can't buy anything.
                    //That why we commented the code below (do not exit)
                    //and process each "RequestShippingOption" separately (in try-catch)
                    //response.AddError(ex.Message);
                }
            }
            foreach (var shippingOption in response.ShippingOptions)
            {
                shippingOption.Rate += _australiaPostSettings.AdditionalHandlingCharge;
            }
            return response;
        }
        private cResultado ProcessShipping(GetShippingOptionRequest getShippingOptionRequest, GetShippingOptionResponse getShippingOptionResponse)
        {
            var usedMeasureWeight = _measureService.GetMeasureWeightBySystemKeyword(MEASURE_WEIGHT_SYSTEM_KEYWORD);

            if (usedMeasureWeight == null)
            {
                string e = string.Format("Plugin.Shipping.Correios: Could not load \"{0}\" measure weight", MEASURE_WEIGHT_SYSTEM_KEYWORD);

                _logger.Fatal(e);

                throw new NopException(e);
            }

            var usedMeasureDimension = _measureService.GetMeasureDimensionBySystemKeyword(MEASURE_DIMENSION_SYSTEM_KEYWORD);

            if (usedMeasureDimension == null)
            {
                string e = string.Format("Plugin.Shipping.Correios: Could not load \"{0}\" measure dimension", MEASURE_DIMENSION_SYSTEM_KEYWORD);

                _logger.Fatal(e);

                throw new NopException(e);
            }

            //Na versão 2.2 o getShippingOptionRequest.ZipPostalCodeFrom retorna string.Empty, possui um TODO...

            string cepOrigem = null;

            if (this._shippingSettings.ShippingOriginAddressId > 0)
            {
                var addr = this._addressService.GetAddressById(this._shippingSettings.ShippingOriginAddressId);

                if (addr != null && !String.IsNullOrEmpty(addr.ZipPostalCode) && addr.ZipPostalCode.Length >= 8 && addr.ZipPostalCode.Length <= 9)
                {
                    cepOrigem = addr.ZipPostalCode;
                }
            }

            if (cepOrigem == null)
            {
                _logger.Fatal("Plugin.Shipping.Correios: CEP de Envio em branco ou inválido, configure nas opções de envio do NopCommerce.Em Administração > Configurações > Configurações de Envio. Formato: 00000000");

                throw new NopException("Plugin.Shipping.Correios: CEP de Envio em branco ou inválido, configure nas opções de envio do NopCommerce.Em Administração > Configurações > Configurações de Envio. Formato: 00000000");
            }

            var correiosCalculation = new CorreiosBatchCalculation(this._logger)
            {
                CodigoEmpresa = _correiosSettings.CodigoEmpresa,
                Senha = _correiosSettings.Senha,
                CepOrigem = cepOrigem,
                Servicos = _correiosSettings.CarrierServicesOffered,
                AvisoRecebimento = _correiosSettings.IncluirAvisoRecebimento,
                MaoPropria = _correiosSettings.IncluirMaoPropria,
                CepDestino = getShippingOptionRequest.ShippingAddress.ZipPostalCode
            };

            decimal subtotalBase = decimal.Zero;
            decimal orderSubTotalDiscountAmount = decimal.Zero;
            Discount orderSubTotalAppliedDiscount = null;
            decimal subTotalWithoutDiscountBase = decimal.Zero;
            decimal subTotalWithDiscountBase = decimal.Zero;

            _orderTotalCalculationService.GetShoppingCartSubTotal(getShippingOptionRequest.Items,
                out orderSubTotalDiscountAmount, out orderSubTotalAppliedDiscount,
                out subTotalWithoutDiscountBase, out subTotalWithDiscountBase);

            subtotalBase = subTotalWithDiscountBase;

            int length = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalLength(), usedMeasureDimension)) / 10);
            int height = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalHeight(), usedMeasureDimension)) / 10);
            int width = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureDimension(getShippingOptionRequest.GetTotalWidth(), usedMeasureDimension)) / 10);
            int weight = Convert.ToInt32(Math.Ceiling(_measureService.ConvertFromPrimaryMeasureWeight(_shippingService.GetShoppingCartTotalWeight(getShippingOptionRequest.Items), usedMeasureWeight)));

            if (length < 1)
                length = 1;
            if (height < 1)
                height = 1;
            if (width < 1)
                width = 1;
            if (weight < 1)
                weight = 1;

            //Altura não pode ser maior que o comprimento, para evitar erro, igualamos e a embalagem deve ser adaptada.
            if (height > length)
            {
                length = height;
            }

            if (IsPackageTooSmall(length, height, width))
            {
                length = MIN_PACKAGE_LENGTH;
                height = MIN_PACKAGE_HEIGHT;
                width = MIN_PACKAGE_WIDTH;
            }

            if ((!IsPackageTooHeavy(weight)) && (!IsPackageTooLarge(length, height, width)))
            {
                Debug.WriteLine("Plugin.Shipping.Correios: Pacote unico");

                correiosCalculation.Pacotes.Add(new CorreiosBatchCalculation.Pacote()
                {
                    Altura = height,
                    Comprimento = length,
                    Largura = width,
                    Diametro = 0,
                    FormatoPacote = true,
                    Peso = weight,
                    ValorDeclarado = (_correiosSettings.IncluirValorDeclarado ? subtotalBase : 0)
                });

                return correiosCalculation.Calculate();
            }
            else
            {
                int totalPackages = 1;
                int totalPackagesDims = 1;
                int totalPackagesWeights = 1;

                if (IsPackageTooHeavy(weight))
                {
                    totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAX_PACKAGE_WEIGHT));
                }
                if (IsPackageTooLarge(length, height, width))
                {
                    totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)TotalPackageSize(length, height, width) / (decimal)MAX_PACKAGE_TOTAL_DIMENSION));
                }
                totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;

                if (totalPackages == 0)
                    totalPackages = 1;

                int weight2 = weight / totalPackages;
                int height2 = height / totalPackages;
                int width2 = width / totalPackages;
                int length2 = length / totalPackages;

                if (weight2 < 1)
                    weight2 = 1;
                if (height2 < 1)
                    height2 = 1;
                if (width2 < 1)
                    width2 = 1;
                if (length2 < 1)
                    length2 = 1;

                //Altura não pode ser maior que o comprimento, para evitar erro, igualamos e a embalagem deve ser adaptada.
                if (height2 > width2)
                    width2 = height2;

                Debug.WriteLine("Plugin.Shipping.Correios: Multiplos pacotes");

                correiosCalculation.Pacotes.Add(new CorreiosBatchCalculation.Pacote()
                {
                    Altura = height2,
                    Comprimento = length2,
                    Largura = width2,
                    Diametro = 0,
                    FormatoPacote = true,
                    Peso = weight2,
                    ValorDeclarado = (_correiosSettings.IncluirValorDeclarado ? subtotalBase / totalPackages : 0)
                });

                var result = correiosCalculation.Calculate();

                if (result != null)
                {
                    foreach (cServico s in result.Servicos)
                    {
                        if (s.Erro == "0")
                        {
                            s.Valor = (decimal.Parse(s.Valor, correiosCalculation.PtBrCulture) * totalPackages).ToString(correiosCalculation.PtBrCulture);
                            s.ValorAvisoRecebimento = (decimal.Parse(s.ValorAvisoRecebimento, correiosCalculation.PtBrCulture) * totalPackages).ToString(correiosCalculation.PtBrCulture);
                            s.ValorMaoPropria = (decimal.Parse(s.ValorMaoPropria, correiosCalculation.PtBrCulture) * totalPackages).ToString(correiosCalculation.PtBrCulture);
                            s.ValorValorDeclarado = (decimal.Parse(s.ValorValorDeclarado, correiosCalculation.PtBrCulture) * totalPackages).ToString(correiosCalculation.PtBrCulture);
                        }
                    }
                }

                return result;
            }
        }
        /// <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)
            {
                response.AddError("Sem items para enviar");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Endereço de envio em branco");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress.ZipPostalCode == null)
            {
                response.AddError("CEP de envio em branco");
                return response;
            }

            var result = ProcessShipping(getShippingOptionRequest, response);

            if (result == null)
            {
                response.AddError("Não há serviços disponíveis no momento");
                return response;
            }
            else
            {
                List<string> group = new List<string>();

                foreach (cServico servico in result.Servicos.OrderBy(s => s.Valor))
                {
                    Debug.WriteLine("Plugin.Shipping.Correios: Retorno WS");
                    Debug.WriteLine("Codigo: " + servico.Codigo);
                    Debug.WriteLine("Valor: " + servico.Valor);
                    Debug.WriteLine("Valor Mão Própria: " + servico.ValorMaoPropria);
                    Debug.WriteLine("Valor Aviso Recebimento: " + servico.ValorAvisoRecebimento);
                    Debug.WriteLine("Valor Declarado: " + servico.ValorValorDeclarado);
                    Debug.WriteLine("Prazo Entrega: " + servico.PrazoEntrega);
                    Debug.WriteLine("Entrega Domiciliar: " + servico.EntregaDomiciliar);
                    Debug.WriteLine("Entrega Sabado: " + servico.EntregaSabado);
                    Debug.WriteLine("Erro: " + servico.Erro);
                    Debug.WriteLine("Msg Erro: " + servico.MsgErro);

                    if (servico.Erro == "0")
                    {
                        string name = CorreiosServices.GetServicePublicNameById(servico.Codigo.ToString());

                        if (!group.Contains(name))
                        {
                            ShippingOption option = new ShippingOption();
                            option.Name = name;
                            option.Description = "Prazo médio de entrega " + (servico.PrazoEntrega + _correiosSettings.DiasUteisAdicionais) + " dias úteis";
                            option.Rate = decimal.Parse(servico.Valor, CultureInfo.GetCultureInfo("pt-BR")) + _orderTotalCalculationService.GetShoppingCartAdditionalShippingCharge(getShippingOptionRequest.Items) + _correiosSettings.CustoAdicionalEnvio;
                            response.ShippingOptions.Add(option);

                            group.Add(name);
                        }
                    }
                    else
                    {
                        _logger.Error("Plugin.Shipping.Correios: erro ao calcular frete: (" + CorreiosServices.GetServiceName(servico.Codigo.ToString()) + ")( " + servico.Erro + ") " + servico.MsgErro);
                    }
                }

                return response;
            }
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            string zipPostalCodeFrom = getShippingOptionRequest.ZipPostalCodeFrom;
            string zipPostalCodeTo = getShippingOptionRequest.ShippingAddress.ZipPostalCode;
            int weight = GetWeight(getShippingOptionRequest);

            decimal lengthTmp, widthTmp, heightTmp;
            _shippingService.GetDimensions(getShippingOptionRequest.Items, out widthTmp, out lengthTmp, out heightTmp);
            int length = Math.Min(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(lengthTmp, this.GatewayMeasureDimension))), MIN_LENGTH);
            int width = Math.Min(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(widthTmp, this.GatewayMeasureDimension))), MIN_LENGTH);
            int height = Math.Min(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(heightTmp, this.GatewayMeasureDimension))), MIN_LENGTH);

            //estimate packaging
            int totalPackagesDims = 1;
            int totalPackagesWeights = 1;
            if (length > MAX_LENGTH || width > MAX_LENGTH || height > MAX_LENGTH)
            {
                totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)Math.Max(Math.Max(length, width), height) / MAX_LENGTH));
            }
            if (weight > MAX_WEIGHT)
            {
                totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)MAX_WEIGHT));
            }
            var totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;
            if (totalPackages == 0)
                totalPackages = 1;
            if (totalPackages > 1)
            {
                //recalculate dims, weight
                weight = weight / totalPackages;
                height = height / totalPackages;
                width = width / totalPackages;
                length = length / totalPackages;
                if (weight < MIN_WEIGHT)
                    weight = MIN_WEIGHT;
                if (height < MIN_LENGTH)
                    height = MIN_LENGTH;
                if (width < MIN_LENGTH)
                    width = MIN_LENGTH;
                if (length < MIN_LENGTH)
                    length = MIN_LENGTH;
            }

            int girth = height + height + width + width;
            if (girth < MIN_GIRTH)
            {
                height = MIN_LENGTH;
                width = MIN_LENGTH;
            }
            if (girth > MAX_GIRTH)
            {
                height = MAX_LENGTH / 4;
                width = MAX_LENGTH / 4;
            }
            try
            {
                var country = getShippingOptionRequest.ShippingAddress.Country;
                if (country == null)
                {
                    response.AddError("Shipping country is not specified");
                    return response;
                }
                switch (country.ThreeLetterIsoCode)
                {
                    case "AUS":
                        //domestic services
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Standard", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Express", weight, length, width, height, totalPackages));
                        //discontinued
                        //response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "EXP_PLT", weight, length, width, height, totalPackages));
                        break;
                    default:
                        //international services
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Air", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "Sea", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "ECI_D", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "ECI_M", weight, length, width, height, totalPackages));
                        response.ShippingOptions.Add(RequestShippingOption(zipPostalCodeFrom, zipPostalCodeTo, country.TwoLetterIsoCode, "EPI", weight, length, width, height, totalPackages));
                        break;
                }

                foreach (var shippingOption in response.ShippingOptions)
                {
                    shippingOption.Rate += _australiaPostSettings.AdditionalHandlingCharge;
                }
            }
            catch (Exception ex)
            {
                response.AddError(ex.Message);
            }
            return response;
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }
            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }
            if (getShippingOptionRequest.ShippingAddress.Country == null)
            {
                response.AddError("Shipping country is not set");
                return response;
            }
            if (getShippingOptionRequest.ShippingAddress.StateProvince == null)
            {
                response.AddError("Shipping state is not set");
                return response;
            }

            try
            {
                var profile = new Profile();
                profile.MerchantId = _canadaPostSettings.CustomerId;

                var destination = new Destination();
                destination.City = getShippingOptionRequest.ShippingAddress.City;
                destination.StateOrProvince = getShippingOptionRequest.ShippingAddress.StateProvince.Abbreviation;
                destination.Country = getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode;
                destination.PostalCode = getShippingOptionRequest.ShippingAddress.ZipPostalCode;

                var items = CreateItems(getShippingOptionRequest);

                var lang = CanadaPostLanguageEnum.English;
                if (_workContext.WorkingLanguage.LanguageCulture.StartsWith("fr", StringComparison.InvariantCultureIgnoreCase))
                    lang = CanadaPostLanguageEnum.French;

                var requestResult = GetShippingOptionsInternal(profile, destination, items, lang);
                if (requestResult.IsError)
                {
                    response.AddError(requestResult.StatusMessage);
                }
                else
                {
                    foreach (var dr in requestResult.AvailableRates)
                    {
                        var so = new ShippingOption();
                        so.Name = dr.Name;
                        if (!string.IsNullOrEmpty(dr.DeliveryDate))
                            so.Name += string.Format(" - {0}", dr.DeliveryDate);
                        so.Rate = dr.Amount;
                        response.ShippingOptions.Add(so);
                    }
                }

                foreach (var shippingOption in response.ShippingOptions)
                {
                    if (!shippingOption.Name.StartsWith("canada post", StringComparison.InvariantCultureIgnoreCase))
                        shippingOption.Name = string.Format("Canada Post {0}", shippingOption.Name);
                }
            }
            catch (Exception e)
            {
                response.AddError(e.Message);
            }

            return response;
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (string.IsNullOrEmpty(getShippingOptionRequest.ZipPostalCodeFrom))
            {
                response.AddError("Shipping origin zip is not set");
                return response;
            }

            var country = getShippingOptionRequest.ShippingAddress.Country;
            if (country == null)
            {
                response.AddError("Shipping country is not specified");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            if (string.IsNullOrEmpty(getShippingOptionRequest.ShippingAddress.ZipPostalCode))
            {
                response.AddError("Shipping zip (postal code) is not set");
                return response;
            }

            string zipPostalCodeFrom = getShippingOptionRequest.ZipPostalCodeFrom;
            string zipPostalCodeTo = getShippingOptionRequest.ShippingAddress.ZipPostalCode;
            int weight = GetWeight(getShippingOptionRequest);
            decimal lengthTmp, widthTmp, heightTmp;
            _shippingService.GetDimensions(getShippingOptionRequest.Items, out widthTmp, out lengthTmp, out heightTmp);
            int length = Math.Max(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(lengthTmp, this.GatewayMeasureDimension))), MIN_LENGTH);
            int width = Math.Max(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(widthTmp, this.GatewayMeasureDimension))), MIN_LENGTH);
            int height = Math.Max(Convert.ToInt32(Math.Ceiling(this._measureService.ConvertFromPrimaryMeasureDimension(heightTmp, this.GatewayMeasureDimension))), MIN_LENGTH);

            //estimate packaging
            int totalPackagesDims = 1;
            int totalPackagesWeights = 1;
            if (length > MAX_LENGTH || width > MAX_LENGTH || height > MAX_LENGTH)
            {
                totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)Math.Max(Math.Max(length, width), height) / MAX_LENGTH));
            }

            int maxWeight = country.TwoLetterIsoCode.Equals("AU") ? MAX_DOMESTIC_WEIGHT : MAX_INTERNATIONAL_WEIGHT;
            if (weight > maxWeight)
            {
                totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)weight / (decimal)maxWeight));
            }
            var totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;
            if (totalPackages == 0)
                totalPackages = 1;
            if (totalPackages > 1)
            {
                //recalculate dims, weight
                weight = weight / totalPackages;
                height = height / totalPackages;
                width = width / totalPackages;
                length = length / totalPackages;
                if (weight < MIN_WEIGHT)
                    weight = MIN_WEIGHT;
                if (height < MIN_LENGTH)
                    height = MIN_LENGTH;
                if (width < MIN_LENGTH)
                    width = MIN_LENGTH;
                if (length < MIN_LENGTH)
                    length = MIN_LENGTH;
            }

            int girth = height + height + width + width;
            if (girth < MIN_GIRTH)
            {
                height = MIN_LENGTH;
                width = MIN_LENGTH;
            }
            if (girth > MAX_GIRTH)
            {
                height = MAX_LENGTH / 4;
                width = MAX_LENGTH / 4;
            }
            // Australia post takes the dimensions in centimeters and weight in kilograms, 
            // so dimensions should be converted and rounded up from millimeters to centimeters,
            // grams should be converted to kilograms and rounded to two decimal.
            length = length / ONE_CENTIMETER + (length % ONE_CENTIMETER > 0 ? 1 : 0);
            width = width / ONE_CENTIMETER + (width % ONE_CENTIMETER > 0 ? 1 : 0);
            height = height / ONE_CENTIMETER + (height % ONE_CENTIMETER > 0 ? 1 : 0);
            var kgWeight = Math.Round(weight / (decimal)ONE_KILO, 2);

            try
            {
                var shippingOptions = RequestShippingOptions(country.TwoLetterIsoCode,
                    zipPostalCodeFrom, zipPostalCodeTo, kgWeight, length, width, height, totalPackages);

                foreach (var shippingOption in shippingOptions)
                {
                    response.ShippingOptions.Add(shippingOption);
                }
            }
            catch (NopException ex)
            {
                response.AddError(ex.Message);
                return response;
            }
            catch (Exception)
            {
                response.AddError("Australia Post Service is currently unavailable, try again later");
                return response;
            }
            
            foreach (var shippingOption in response.ShippingOptions)
            {
                shippingOption.Rate += _australiaPostSettings.AdditionalHandlingCharge;
            }
            return response;
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress.Country == null)
            {
                response.AddError("Shipping country is not set");
                return response;
            }

            if (getShippingOptionRequest.CountryFrom == null)
            {
                getShippingOptionRequest.CountryFrom = _countryService.GetCountryById(_upsSettings.DefaultShippedFromCountryId);
                if (getShippingOptionRequest.CountryFrom == null)
                    getShippingOptionRequest.CountryFrom = _countryService.GetAllCountries(true).ToList().FirstOrDefault();
            }
            if (String.IsNullOrEmpty(getShippingOptionRequest.ZipPostalCodeFrom))
                getShippingOptionRequest.ZipPostalCodeFrom = _upsSettings.DefaultShippedFromZipPostalCode;

            string requestString = CreateRequest(_upsSettings.AccessKey, _upsSettings.Username, _upsSettings.Password, getShippingOptionRequest,
                _upsSettings.CustomerClassification, _upsSettings.PickupType, _upsSettings.PackagingType);
            string responseXml = DoRequest(_upsSettings.Url, requestString);
            string error = "";
            var shippingOptions = ParseResponse(responseXml, ref error);
            if (String.IsNullOrEmpty(error))
            {
                foreach (var shippingOption in shippingOptions)
                {
                    if (!shippingOption.Name.ToLower().StartsWith("ups"))
                        shippingOption.Name = string.Format("UPS {0}", shippingOption.Name);
                    shippingOption.Rate += _upsSettings.AdditionalHandlingCharge;
                    response.ShippingOptions.Add(shippingOption);
                }
            }
            else
            {
                response.AddError(error);
            }

            return response;
        }
        /// <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");

            if (getShippingOptionRequest.Items == null)
                return new GetShippingOptionResponse { Errors = new List<string> { "No shipment items" } };

            if (getShippingOptionRequest.ShippingAddress == null)
                return new GetShippingOptionResponse { Errors = new List<string> { "Shipping address is not set" } };

            if (getShippingOptionRequest.ShippingAddress.Country == null)
                return new GetShippingOptionResponse { Errors = new List<string> { "Shipping country is not set" } };

            if (string.IsNullOrEmpty(getShippingOptionRequest.ZipPostalCodeFrom))
                return new GetShippingOptionResponse { Errors = new List<string> { "Origin postal code is not set" } };

            //get available services
            string errors;
            var availableServices = CanadaPostHelper.GetServices(getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode,
                _canadaPostSettings.ApiKey, _canadaPostSettings.UseSandbox, out errors);
            if (availableServices == null)
                return new GetShippingOptionResponse { Errors = new List<string> { errors } };

            //create object for the get rates requests
            var result = new GetShippingOptionResponse();
            object destinationCountry;
            switch (getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode.ToLowerInvariant())
            {
                case "us":
                    destinationCountry = new mailingscenarioDestinationUnitedstates
                    {
                        zipcode = getShippingOptionRequest.ShippingAddress.ZipPostalCode
                    };
                    break;
                case "ca":
                    destinationCountry = new mailingscenarioDestinationDomestic
                    {
                        postalcode = getShippingOptionRequest.ShippingAddress.ZipPostalCode
                    };
                    break;
                default:
                    destinationCountry = new mailingscenarioDestinationInternational
                    {
                        countrycode = getShippingOptionRequest.ShippingAddress.Country.TwoLetterIsoCode
                    };
                    break;
            }

            var mailingScenario = new mailingscenario
            {
                customernumber = _canadaPostSettings.CustomerNumber,
                originpostalcode = getShippingOptionRequest.ZipPostalCodeFrom,
                destination = new mailingscenarioDestination
                {
                    Item = destinationCountry
                }
            };

            //get original parcel characteristics
            decimal originalLength;
            decimal originalWidth;
            decimal originalHeight;
            decimal originalWeight;
            GetWeight(getShippingOptionRequest, out originalWeight);
            GetDimensions(getShippingOptionRequest, out originalLength, out originalWidth, out originalHeight);

            //get rate for all available services
            var errorSummary = new StringBuilder();
            foreach (var service in availableServices.service)
            {
                var currentService = CanadaPostHelper.GetServiceDetails(_canadaPostSettings.ApiKey, service.link.href, service.link.mediatype, out errors);
                if (currentService != null)
                {
                    #region parcels count calculation

                    var totalParcels = 1;

                    //parcels count by weight
                    var maxWeight = currentService.restrictions != null
                        && currentService.restrictions.weightrestriction != null
                        && currentService.restrictions.weightrestriction.maxSpecified
                        ? currentService.restrictions.weightrestriction.max : int.MaxValue;
                    if (originalWeight * 1000 > maxWeight)
                    {
                        var parcelsOnWeight = Convert.ToInt32(Math.Ceiling(originalWeight * 1000 / maxWeight));
                        if (parcelsOnWeight > totalParcels)
                            totalParcels = parcelsOnWeight;
                    }

                    //parcels count by length
                    var maxLength = currentService.restrictions != null
                        && currentService.restrictions.dimensionalrestrictions != null
                        && currentService.restrictions.dimensionalrestrictions.length != null
                        && currentService.restrictions.dimensionalrestrictions.length.maxSpecified
                        ? currentService.restrictions.dimensionalrestrictions.length.max : int.MaxValue;
                    if (originalLength > maxLength)
                    {
                        var parcelsOnLength = Convert.ToInt32(Math.Ceiling(originalLength / maxLength));
                        if (parcelsOnLength > totalParcels)
                            totalParcels = parcelsOnLength;
                    }

                    //parcels count by width
                    var maxWidth = currentService.restrictions != null
                        && currentService.restrictions.dimensionalrestrictions != null
                        && currentService.restrictions.dimensionalrestrictions.width != null
                        && currentService.restrictions.dimensionalrestrictions.width.maxSpecified
                        ? currentService.restrictions.dimensionalrestrictions.width.max : int.MaxValue;
                    if (originalWidth > maxWidth)
                    {
                        var parcelsOnWidth = Convert.ToInt32(Math.Ceiling(originalWidth / maxWidth));
                        if (parcelsOnWidth > totalParcels)
                            totalParcels = parcelsOnWidth;
                    }

                    //parcels count by height
                    var maxHeight = currentService.restrictions != null
                        && currentService.restrictions.dimensionalrestrictions != null
                        && currentService.restrictions.dimensionalrestrictions.height != null
                        && currentService.restrictions.dimensionalrestrictions.height.maxSpecified
                        ? currentService.restrictions.dimensionalrestrictions.height.max : int.MaxValue;
                    if (originalHeight > maxHeight)
                    {
                        var parcelsOnHeight = Convert.ToInt32(Math.Ceiling(originalHeight / maxHeight));
                        if (parcelsOnHeight > totalParcels)
                            totalParcels = parcelsOnHeight;
                    }

                    //parcel count by girth
                    var lengthPlusGirthMax = currentService.restrictions != null
                        && currentService.restrictions.dimensionalrestrictions != null
                        && currentService.restrictions.dimensionalrestrictions.lengthplusgirthmaxSpecified
                        ? currentService.restrictions.dimensionalrestrictions.lengthplusgirthmax : int.MaxValue;
                    var lengthPlusGirth = 2 * (originalWidth + originalHeight) + originalLength;
                    if (lengthPlusGirth > lengthPlusGirthMax)
                    {
                        var parcelsOnHeight = Convert.ToInt32(Math.Ceiling(lengthPlusGirth / lengthPlusGirthMax));
                        if (parcelsOnHeight > totalParcels)
                            totalParcels = parcelsOnHeight;
                    }

                    //parcel count by sum of length, width and height
                    var lengthWidthHeightMax = currentService.restrictions != null
                        && currentService.restrictions.dimensionalrestrictions != null
                        && currentService.restrictions.dimensionalrestrictions.lengthheightwidthsummaxSpecified
                        ? currentService.restrictions.dimensionalrestrictions.lengthheightwidthsummax : int.MaxValue;
                    var lengthWidthHeight = originalLength + originalWidth + originalHeight;
                    if (lengthWidthHeight > lengthWidthHeightMax)
                    {
                        var parcelsOnHeight = Convert.ToInt32(Math.Ceiling(lengthWidthHeight / lengthWidthHeightMax));
                        if (parcelsOnHeight > totalParcels)
                            totalParcels = parcelsOnHeight;
                    }

                    #endregion

                    //set parcel characteristics
                    mailingScenario.services = new[] { currentService.servicecode };
                    mailingScenario.parcelcharacteristics = new mailingscenarioParcelcharacteristics
                    {
                        weight = Math.Round(originalWeight / totalParcels, 3),
                        dimensions = new mailingscenarioParcelcharacteristicsDimensions
                        {
                            length = Math.Round(originalLength / totalParcels, 1),
                            width = Math.Round(originalWidth / totalParcels, 1),
                            height = Math.Round(originalHeight / totalParcels, 1)
                        }
                    };

                    //get rate
                    var priceQuotes = CanadaPostHelper.GetShippingRates(mailingScenario, _canadaPostSettings.ApiKey, _canadaPostSettings.UseSandbox, out errors);
                    if (priceQuotes != null)
                        foreach (var option in priceQuotes.pricequote)
                        {
                            result.ShippingOptions.Add(new ShippingOption
                            {
                                Name = option.servicename,
                                Rate = PriceToPrimaryStoreCurrency(option.pricedetails.due * totalParcels),
                                Description = string.Format("Delivery {0}into {1} parcels", 
                                    option.servicestandard != null && !string.IsNullOrEmpty(option.servicestandard.expectedtransittime) 
                                    ? string.Format("in {0} days ", option.servicestandard.expectedtransittime) : string.Empty, totalParcels),
                            });
                        }
                    else
                        errorSummary.AppendLine(errors);
                }
                else
                    errorSummary.AppendLine(errors);
            }

            //write errors
            var errorString = errorSummary.ToString();
            if (!string.IsNullOrEmpty(errorString))
                _logger.Error(errorString);
            if (!result.ShippingOptions.Any())
                result.AddError(errorString);

            return result;

        }
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="customer">Load records allowed only to a specified customer; pass null to ignore ACL permissions</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList <ShoppingCartItem> cart,
                                                                    Address shippingAddress, Customer customer = null, string allowedShippingRateComputationMethodSystemName = "",
                                                                    int storeId = 0)
        {
            if (cart == null)
            {
                throw new ArgumentNullException(nameof(cart));
            }

            var result = new GetShippingOptionResponse();

            //create a package
            var shippingOptionRequests = CreateShippingOptionRequests(cart, shippingAddress, storeId, out var shippingFromMultipleLocations);

            result.ShippingFromMultipleLocations = shippingFromMultipleLocations;

            var shippingRateComputationMethods = _shippingPluginManager
                                                 .LoadActivePlugins(customer, storeId, allowedShippingRateComputationMethodSystemName);

            if (!shippingRateComputationMethods.Any())
            {
                return(result);
            }

            //request shipping options from each shipping rate computation methods
            foreach (var srcm in shippingRateComputationMethods)
            {
                //request shipping options (separately for each package-request)
                IList <ShippingOption> srcmShippingOptions = null;
                foreach (var shippingOptionRequest in shippingOptionRequests)
                {
                    var getShippingOptionResponse = srcm.GetShippingOptions(shippingOptionRequest);

                    if (getShippingOptionResponse.Success)
                    {
                        //success
                        if (srcmShippingOptions == null)
                        {
                            //first shipping option request
                            srcmShippingOptions = getShippingOptionResponse.ShippingOptions;
                        }
                        else
                        {
                            //get shipping options which already exist for prior requested packages for this scrm (i.e. common options)
                            srcmShippingOptions = srcmShippingOptions
                                                  .Where(existingso => getShippingOptionResponse.ShippingOptions.Any(newso => newso.Name == existingso.Name))
                                                  .ToList();

                            //and sum the rates
                            foreach (var existingso in srcmShippingOptions)
                            {
                                existingso.Rate += getShippingOptionResponse
                                                   .ShippingOptions
                                                   .First(newso => newso.Name == existingso.Name)
                                                   .Rate;
                            }
                        }
                    }
                    else
                    {
                        //errors
                        foreach (var error in getShippingOptionResponse.Errors)
                        {
                            result.AddError(error);
                            _logger.Warning($"Shipping ({srcm.PluginDescriptor.FriendlyName}). {error}");
                        }
                        //clear the shipping options in this case
                        srcmShippingOptions = new List <ShippingOption>();
                        break;
                    }
                }

                //add this scrm's options to the result
                if (srcmShippingOptions == null)
                {
                    continue;
                }

                foreach (var so in srcmShippingOptions)
                {
                    //set system name if not set yet
                    if (string.IsNullOrEmpty(so.ShippingRateComputationMethodSystemName))
                    {
                        so.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    }
                    if (_shoppingCartSettings.RoundPricesDuringCalculation)
                    {
                        so.Rate = _priceCalculationService.RoundPrice(so.Rate);
                    }
                    result.ShippingOptions.Add(so);
                }
            }

            if (_shippingSettings.ReturnValidOptionsIfThereAreAny)
            {
                //return valid options if there are any (no matter of the errors returned by other shipping rate computation methods).
                if (result.ShippingOptions.Any() && result.Errors.Any())
                {
                    result.Errors.Clear();
                }
            }

            //no shipping options loaded
            if (!result.ShippingOptions.Any() && !result.Errors.Any())
            {
                result.Errors.Add(_localizationService.GetResource("Checkout.ShippingOptionCouldNotBeLoaded"));
            }

            return(result);
        }
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList<ShoppingCartItem> cart,
            Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "")
        {
            if (cart == null)
                throw new ArgumentNullException("cart");

            var result = new GetShippingOptionResponse();

            //create a package
            var getShippingOptionRequest = CreateShippingOptionRequest(cart, shippingAddress);
            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods()
                .Where(srcm =>
                    String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName) ||
                    allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                .ToList();
            if (shippingRateComputationMethods.Count == 0)
                throw new NopException("Shipping rate computation method could not be loaded");

            //get shipping options
            foreach (var srcm in shippingRateComputationMethods)
            {
                var getShippingOptionResponse = srcm.GetShippingOptions(getShippingOptionRequest);
                foreach (var so2 in getShippingOptionResponse.ShippingOptions)
                {
                    //system name
                    so2.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    //round
                    if (_shoppingCartSettings.RoundPricesDuringCalculation)
                        so2.Rate = Math.Round(so2.Rate, 2);
                    result.ShippingOptions.Add(so2);
                }

                //log errors
                if (!getShippingOptionResponse.Success)
                {
                    foreach (string error in getShippingOptionResponse.Errors)
                    {
                        result.AddError(error);
                        _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                    }
                }
            }

            if (_shippingSettings.ReturnValidOptionsIfThereAreAny)
            {
                //return valid options if there are any (no matter of the errors returned by other shipping rate compuation methods).
                if (result.ShippingOptions.Count > 0 && result.Errors.Count > 0)
                    result.Errors.Clear();
            }

            //no shipping options loaded
            if (result.ShippingOptions.Count == 0 && result.Errors.Count == 0)
                result.Errors.Add(_localizationService.GetResource("Checkout.ShippingOptionCouldNotBeLoaded"));

            return result;
        }
Exemple #21
0
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList <ShoppingCartItem> cart,
                                                                    Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "")
        {
            if (cart == null)
            {
                throw new ArgumentNullException("cart");
            }

            var result = new GetShippingOptionResponse();

            //create a package
            var getShippingOptionRequest       = CreateShippingOptionRequest(cart, shippingAddress);
            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods();

            if (shippingRateComputationMethods.Count == 0)
            {
                throw new NopException("Shipping rate computation method could not be loaded");
            }

            //get shipping options
            foreach (var srcm in shippingRateComputationMethods)
            {
                if (!String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName) &&
                    !allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                var getShippingOptionResponse = srcm.GetShippingOptions(getShippingOptionRequest);
                foreach (var so2 in getShippingOptionResponse.ShippingOptions)
                {
                    //system name
                    so2.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    //round
                    if (_shoppingCartSettings.RoundPricesDuringCalculation)
                    {
                        so2.Rate = Math.Round(so2.Rate, 2);
                    }
                    result.ShippingOptions.Add(so2);
                }

                //log errors
                if (!getShippingOptionResponse.Success)
                {
                    foreach (string error in getShippingOptionResponse.Errors)
                    {
                        result.AddError(error);
                        _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                    }
                }
            }


            //no shipping options loaded
            if (result.ShippingOptions.Count == 0 && result.Errors.Count == 0)
            {
                result.Errors.Add("Shipping options could not be loaded");
            }

            return(result);
        }
Exemple #22
0
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList<ShoppingCartItem> cart,
            Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "", 
            int storeId = 0)
        {
            if (cart == null)
                throw new ArgumentNullException("cart");

            var result = new GetShippingOptionResponse();
            
            //create a package
            bool shippingFromMultipleLocations;
            var shippingOptionRequests = CreateShippingOptionRequests(cart, shippingAddress, storeId, out shippingFromMultipleLocations);
            result.ShippingFromMultipleLocations = shippingFromMultipleLocations;

            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods(storeId);
            //filter by system name
            if (!String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName))
            {
                shippingRateComputationMethods = shippingRateComputationMethods
                    .Where(srcm => allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                    .ToList();
            }
            if (!shippingRateComputationMethods.Any())
                //throw new NopException("Shipping rate computation method could not be loaded");
                return result;



            //request shipping options from each shipping rate computation methods
            foreach (var srcm in shippingRateComputationMethods)
            {
                //request shipping options (separately for each package-request)
                IList<ShippingOption> srcmShippingOptions = null;
                foreach (var shippingOptionRequest in shippingOptionRequests)
                {
                    var getShippingOptionResponse = srcm.GetShippingOptions(shippingOptionRequest);

                    if (getShippingOptionResponse.Success)
                    {
                        //success
                        if (srcmShippingOptions == null)
                        {
                            //first shipping option request
                            srcmShippingOptions = getShippingOptionResponse.ShippingOptions;
                        }
                        else
                        {
                            //get shipping options which already exist for prior requested packages for this scrm (i.e. common options)
                            srcmShippingOptions = srcmShippingOptions
                                .Where(existingso => getShippingOptionResponse.ShippingOptions.Any(newso => newso.Name == existingso.Name))
                                .ToList();

                            //and sum the rates
                            foreach (var existingso in srcmShippingOptions)
                            {
                                existingso.Rate += getShippingOptionResponse
                                    .ShippingOptions
                                    .First(newso => newso.Name == existingso.Name)
                                    .Rate;
                            }
                        }
                    }
                    else
                    {
                        //errors
                        foreach (string error in getShippingOptionResponse.Errors)
                        {
                            result.AddError(error);
                            _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                        }
                        //clear the shipping options in this case
                        srcmShippingOptions = new List<ShippingOption>();
                        break;
                    }
                }

                //add this scrm's options to the result
                if (srcmShippingOptions != null)
                {
                    foreach (var so in srcmShippingOptions)
                    {
                        //set system name if not set yet
                        if (String.IsNullOrEmpty(so.ShippingRateComputationMethodSystemName))
                            so.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                        if (_shoppingCartSettings.RoundPricesDuringCalculation)
                            so.Rate = RoundingHelper.RoundPrice(so.Rate);
                        result.ShippingOptions.Add(so);
                    }
                }
            }

            if (_shippingSettings.ReturnValidOptionsIfThereAreAny)
            {
                //return valid options if there are any (no matter of the errors returned by other shipping rate compuation methods).
                if (result.ShippingOptions.Any() && result.Errors.Any())
                    result.Errors.Clear();
            }
            
            //no shipping options loaded
            if (!result.ShippingOptions.Any() && !result.Errors.Any())
                result.Errors.Add(_localizationService.GetResource("Checkout.ShippingOptionCouldNotBeLoaded"));
            
            return result;
        }
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <param name="storeId">Load records allowed only in a specified store; pass 0 to load all records</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList <ShoppingCartItem> cart,
                                                                    Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "",
                                                                    int storeId = 0)
        {
            if (cart == null)
            {
                throw new ArgumentNullException("cart");
            }

            var result = new GetShippingOptionResponse();

            //create a package
            var shippingOptionRequests         = CreateShippingOptionRequests(cart, shippingAddress);
            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods(storeId);

            //filter by system name
            if (!String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName))
            {
                shippingRateComputationMethods = shippingRateComputationMethods
                                                 .Where(srcm => allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                                                 .ToList();
            }
            if (shippingRateComputationMethods.Count == 0)
            {
                throw new NopException("Shipping rate computation method could not be loaded");
            }



            //request shipping options from each shipping rate computation methods
            foreach (var srcm in shippingRateComputationMethods)
            {
                //request shipping options (separately for each package-request)
                IList <ShippingOption> srcmShippingOptions = null;
                foreach (var shippingOptionRequest in shippingOptionRequests)
                {
                    var getShippingOptionResponse = srcm.GetShippingOptions(shippingOptionRequest);

                    if (getShippingOptionResponse.Success)
                    {
                        //success
                        if (srcmShippingOptions == null)
                        {
                            //first shipping option request
                            srcmShippingOptions = getShippingOptionResponse.ShippingOptions;
                        }
                        else
                        {
                            //get shipping options which already exist for prior requested packages for this scrm (i.e. common options)
                            srcmShippingOptions = srcmShippingOptions
                                                  .Where(existingso => getShippingOptionResponse.ShippingOptions.Any(newso => newso.Name == existingso.Name))
                                                  .ToList();

                            //and sum the rates
                            foreach (var existingso in srcmShippingOptions)
                            {
                                existingso.Rate += getShippingOptionResponse
                                                   .ShippingOptions
                                                   .First(newso => newso.Name == existingso.Name)
                                                   .Rate;
                            }
                        }
                    }
                    else
                    {
                        //errors
                        foreach (string error in getShippingOptionResponse.Errors)
                        {
                            result.AddError(error);
                            _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                        }
                        //clear the shipping options in this case
                        srcmShippingOptions = new List <ShippingOption>();
                        break;
                    }
                }

                // add this scrm's options to the result
                if (srcmShippingOptions != null)
                {
                    foreach (var so in srcmShippingOptions)
                    {
                        so.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                        if (_shoppingCartSettings.RoundPricesDuringCalculation)
                        {
                            so.Rate = RoundingHelper.RoundPrice(so.Rate);
                        }
                        result.ShippingOptions.Add(so);
                    }
                }
            }

            if (_shippingSettings.ReturnValidOptionsIfThereAreAny)
            {
                //return valid options if there are any (no matter of the errors returned by other shipping rate compuation methods).
                if (result.ShippingOptions.Count > 0 && result.Errors.Count > 0)
                {
                    result.Errors.Clear();
                }
            }

            //no shipping options loaded
            if (result.ShippingOptions.Count == 0 && result.Errors.Count == 0)
            {
                result.Errors.Add(_localizationService.GetResource("Checkout.ShippingOptionCouldNotBeLoaded"));
            }

            return(result);
        }
        /// <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)
            {
                response.AddError("No shipment items");
                return response;
            }

            if (getShippingOptionRequest.ShippingAddress == null)
            {
                response.AddError("Shipping address is not set");
                return response;
            }

            if (String.IsNullOrEmpty(getShippingOptionRequest.ZipPostalCodeFrom))
                getShippingOptionRequest.ZipPostalCodeFrom = _uspsSettings.ZipPostalCodeFrom;

            bool isDomestic = IsDomesticRequest(getShippingOptionRequest);
            string requestString = CreateRequest(_uspsSettings.Username, _uspsSettings.Password, getShippingOptionRequest);
            string responseXml = DoRequest(_uspsSettings.Url, requestString);
            string error = "";
            var shippingOptions = ParseResponse(responseXml, isDomestic, ref error);
            if (String.IsNullOrEmpty(error))
            {
                foreach (var shippingOption in shippingOptions)
                {
                    if (!shippingOption.Name.ToLower().StartsWith("usps"))
                        shippingOption.Name = string.Format("USPS {0}", shippingOption.Name);
                    shippingOption.Rate += _uspsSettings.AdditionalHandlingCharge;
                    response.ShippingOptions.Add(shippingOption);
                }
            }
            else
            {
                response.AddError(error);
            }

            return response;
        }
Exemple #25
0
        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="cart">Shopping cart</param>
        /// <param name="shippingAddress">Shipping address</param>
        /// <param name="allowedShippingRateComputationMethodSystemName">Filter by shipping rate computation method identifier; null to load shipping options of all shipping rate computation methods</param>
        /// <returns>Shipping options</returns>
        public virtual GetShippingOptionResponse GetShippingOptions(IList <ShoppingCartItem> cart,
                                                                    Address shippingAddress, string allowedShippingRateComputationMethodSystemName = "")
        {
            if (cart == null)
            {
                throw new ArgumentNullException("cart");
            }

            var result = new GetShippingOptionResponse();

            bool isFreeShipping = IsFreeShipping(cart);

            //create a package
            var getShippingOptionRequest       = CreateShippingOptionRequest(cart, shippingAddress);
            var shippingRateComputationMethods = LoadActiveShippingRateComputationMethods();

            if (shippingRateComputationMethods.Count == 0)
            {
                throw new NopException("Shipping rate computation method could not be loaded");
            }

            //get shipping options
            foreach (var srcm in shippingRateComputationMethods)
            {
                if (!String.IsNullOrWhiteSpace(allowedShippingRateComputationMethodSystemName) &&
                    !allowedShippingRateComputationMethodSystemName.Equals(srcm.PluginDescriptor.SystemName, StringComparison.InvariantCultureIgnoreCase))
                {
                    continue;
                }

                var getShippingOptionResponse = srcm.GetShippingOptions(getShippingOptionRequest);
                foreach (var so2 in getShippingOptionResponse.ShippingOptions)
                {
                    so2.ShippingRateComputationMethodSystemName = srcm.PluginDescriptor.SystemName;
                    result.ShippingOptions.Add(so2);
                }

                //log errors
                if (!getShippingOptionResponse.Success)
                {
                    foreach (string error in getShippingOptionResponse.Errors)
                    {
                        result.AddError(error);
                        _logger.Warning(string.Format("Shipping ({0}). {1}", srcm.PluginDescriptor.FriendlyName, error));
                    }
                }
            }


            //no shipping options loaded
            if (result.ShippingOptions.Count == 0 && result.Errors.Count == 0)
            {
                result.Errors.Add("Shipping options could not be loaded");
            }

            //additional shipping charges
            decimal additionalShippingCharge = GetShoppingCartAdditionalShippingCharge(cart);

            foreach (var so in result.ShippingOptions)
            {
                so.Rate += additionalShippingCharge;

                //free shipping
                if (isFreeShipping)
                {
                    so.Rate = decimal.Zero;
                }
            }

            return(result);
        }