public void Can_convert_shippingOption_to_string_and_back()
        {
            var shippingOptionInput = new ShippingOption()
            {
                Name = "1",
                Description = "2",
                Rate = 3.57M,
                ShippingRateComputationMethodSystemName = "4"
            };
            var converter = TypeDescriptor.GetConverter(shippingOptionInput.GetType());
            var result = converter.ConvertTo(shippingOptionInput, typeof(string)) as string;

            var shippingOptionOutput = converter.ConvertFrom(result) as ShippingOption;
            shippingOptionOutput.ShouldNotBeNull();
            shippingOptionOutput.Name.ShouldEqual("1");
            shippingOptionOutput.Description.ShouldEqual("2");
            shippingOptionOutput.Rate.ShouldEqual(3.57M);
            shippingOptionOutput.ShippingRateComputationMethodSystemName.ShouldEqual("4");
        }
        private ShippingOption RequestShippingOption(string zipPostalCodeFrom,
            string zipPostalCodeTo, string countryCode, string serviceType,
            int weight, int length, int width, int height, int quantity)
        {
            var shippingOption = new ShippingOption();
            var sb = new StringBuilder();

            sb.AppendFormat(GetGatewayUrl());
            sb.AppendFormat("?Pickup_Postcode={0}&", zipPostalCodeFrom);
            sb.AppendFormat("Destination_Postcode={0}&", zipPostalCodeTo);
            sb.AppendFormat("Country={0}&", countryCode);
            sb.AppendFormat("Service_Type={0}&", serviceType);
            sb.AppendFormat("Weight={0}&", weight);
            sb.AppendFormat("Length={0}&", length);
            sb.AppendFormat("Width={0}&", width);
            sb.AppendFormat("Height={0}&", height);
            sb.AppendFormat("Quantity={0}", quantity);

            HttpWebRequest request = WebRequest.Create(sb.ToString()) as HttpWebRequest;
            request.Method = "GET";
            //request.ContentType = "application/x-www-form-urlencoded";
            //byte[] reqContent = Encoding.ASCII.GetBytes(sb.ToString());
            //request.ContentLength = reqContent.Length;
            //using (Stream newStream = request.GetRequestStream())
            //{
            //    newStream.Write(reqContent, 0, reqContent.Length);
            //}

            WebResponse response = request.GetResponse();
            string rspContent;
            using (StreamReader reader = new StreamReader(response.GetResponseStream()))
            {
                rspContent = reader.ReadToEnd();
            }

            string[] tmp = rspContent.Split(new char[] { '\n' }, 3);
            if (tmp.Length != 3)
            {
                throw new NasException("Response is not valid.");
            }

            var rspParams = new NameValueCollection();
            foreach (string s in tmp)
            {
                string[] tmp2 = s.Split(new char[] { '=' });
                if (tmp2.Length != 2)
                {
                    throw new NasException("Response is not valid.");
                }
                rspParams.Add(tmp2[0].Trim(), tmp2[1].Trim());
            }

            string err_msg = rspParams["err_msg"];
            if (!err_msg.ToUpperInvariant().StartsWith("OK"))
            {
                throw new NasException(err_msg);
            }

            var serviceName = GetServiceNameByType(serviceType);
            if (serviceName != null && !serviceName.StartsWith("Australia Post.", StringComparison.InvariantCultureIgnoreCase))
                serviceName = string.Format("Australia Post. {0}", serviceName);
            shippingOption.Name = serviceName;
            shippingOption.Description = String.Format("{0} Days", rspParams["days"]);
            shippingOption.Rate = Decimal.Parse(rspParams["charge"]);

            return shippingOption;
        }
        private List<ShippingOption> ParseResponse(string response, bool isDomestic, ref string error)
        {
            var shippingOptions = new List<ShippingOption>();

            string postageStr = isDomestic ? "Postage" : "Service";
            string mailServiceStr = isDomestic ? "MailService" : "SvcDescription";
            string rateStr = isDomestic ? "Rate" : "Postage";
            string classStr = isDomestic ? "CLASSID" : "ID";
            string carrierServicesOffered = isDomestic ? _uspsSettings.CarrierServicesOfferedDomestic : _uspsSettings.CarrierServicesOfferedInternational;

            using (var sr = new StringReader(response))
            using (var tr = new XmlTextReader(sr))
            {
                do
                {
                    tr.Read();

                    if ((tr.Name == "Error") && (tr.NodeType == XmlNodeType.Element))
                    {
                        string errorText = "";
                        while (tr.Read())
                        {
                            if ((tr.Name == "Description") && (tr.NodeType == XmlNodeType.Element))
                                errorText += "Error Desc: " + tr.ReadString();
                            if ((tr.Name == "HelpContext") && (tr.NodeType == XmlNodeType.Element))
                                errorText += "USPS Help Context: " + tr.ReadString() + ". ";
                        }
                        error = "USPS Error returned: " + errorText;
                    }

                    if ((tr.Name == postageStr) && (tr.NodeType == XmlNodeType.Element))
                    {
                        string serviceId = string.Empty;

                        // Find the ID for the service
                        if (tr.HasAttributes)
                        {
                            for (int i = 0; i < tr.AttributeCount; i++)
                            {
                                tr.MoveToAttribute(i);
                                if (tr.Name.Equals(classStr))
                                {
                                    // Add delimiters [] so that single digit IDs aren't found in mutli-digit IDs
                                    serviceId = String.Format("[{0}]", tr.Value);
                                    break;
                                }
                            }
                        }

                        // Go to the next rate if the service ID is not in the list of services to offer
                        if (!String.IsNullOrEmpty(serviceId) &&
                            !String.IsNullOrEmpty(carrierServicesOffered) &&
                            !carrierServicesOffered.Contains(serviceId))
                        {
                            continue;
                        }

                        string serviceCode = string.Empty;
                        string postalRate = string.Empty;

                        do
                        {

                            tr.Read();

                            if ((tr.Name == mailServiceStr) && (tr.NodeType == XmlNodeType.Element))
                            {
                                serviceCode = tr.ReadString();

                                tr.ReadEndElement();
                                if ((tr.Name == mailServiceStr) && (tr.NodeType == XmlNodeType.EndElement))
                                    break;
                            }

                            if ((tr.Name == rateStr) && (tr.NodeType == XmlNodeType.Element))
                            {
                                postalRate = tr.ReadString();
                                tr.ReadEndElement();
                                if ((tr.Name == rateStr) && (tr.NodeType == XmlNodeType.EndElement))
                                    break;
                            }

                        }
                        while (!((tr.Name == postageStr) && (tr.NodeType == XmlNodeType.EndElement)));

                        //USPS issue fixed
                        char reg = (char)174; // registered sign "\u00AE"
                        string tm = "\u2122"; // trademark sign
                        serviceCode = serviceCode.Replace("&lt;sup&gt;&amp;reg;&lt;/sup&gt;", reg.ToString());
                        serviceCode = serviceCode.Replace("&lt;sup&gt;&amp;trade;&lt;/sup&gt;", tm);

                        ShippingOption shippingOption = shippingOptions.Find((s) => s.Name == serviceCode);
                        if (shippingOption == null)
                        {
                            shippingOption = new ShippingOption();
                            shippingOption.Name = serviceCode;
                            shippingOptions.Add(shippingOption);
                        }
                        shippingOption.Rate += Convert.ToDecimal(postalRate, new CultureInfo("en-US"));
                    }
                }
                while (!tr.EOF);
            }
            return shippingOptions;
        }
        private List<ShippingOption> ParseResponse(RateReply reply, Currency requestedShipmentCurrency)
        {
            var result = new List<ShippingOption>();

            Debug.WriteLine("RateReply details:");
            Debug.WriteLine("**********************************************************");
            foreach (var rateDetail in reply.RateReplyDetails)
            {
                var shippingOption = new ShippingOption();
                string serviceName = FedexServices.GetServiceName(rateDetail.ServiceType.ToString());

                // Skip the current service if services are selected and this service hasn't been selected
                if (!String.IsNullOrEmpty(_fedexSettings.CarrierServicesOffered) && !_fedexSettings.CarrierServicesOffered.Contains(rateDetail.ServiceType.ToString()))
                {
                    continue;
                }

                Debug.WriteLine("ServiceType: " + rateDetail.ServiceType);
                if (!serviceName.Equals("UNKNOWN"))
                {
                    shippingOption.Name = serviceName;

                    foreach (RatedShipmentDetail shipmentDetail in rateDetail.RatedShipmentDetails)
                    {
                        Debug.WriteLine("RateType : " + shipmentDetail.ShipmentRateDetail.RateType);
                        Debug.WriteLine("Total Billing Weight : " + shipmentDetail.ShipmentRateDetail.TotalBillingWeight.Value);
                        Debug.WriteLine("Total Base Charge : " + shipmentDetail.ShipmentRateDetail.TotalBaseCharge.Amount);
                        Debug.WriteLine("Total Discount : " + shipmentDetail.ShipmentRateDetail.TotalFreightDiscounts.Amount);
                        Debug.WriteLine("Total Surcharges : " + shipmentDetail.ShipmentRateDetail.TotalSurcharges.Amount);
                        Debug.WriteLine("Net Charge : " + shipmentDetail.ShipmentRateDetail.TotalNetCharge.Amount + "(" + shipmentDetail.ShipmentRateDetail.TotalNetCharge.Currency + ")");
                        Debug.WriteLine("*********");

                        // Get discounted rates if option is selected
                        if (_fedexSettings.ApplyDiscounts & shipmentDetail.ShipmentRateDetail.RateType == ReturnedRateType.PAYOR_ACCOUNT)
                        {
                            decimal amount = ConvertChargeToPrimaryCurrency(shipmentDetail.ShipmentRateDetail.TotalNetCharge, requestedShipmentCurrency);
                            shippingOption.Rate = amount + _fedexSettings.AdditionalHandlingCharge;
                            break;
                        }
                        else if (shipmentDetail.ShipmentRateDetail.RateType == ReturnedRateType.PAYOR_LIST) // Get List Rates (not discount rates)
                        {
                            decimal amount = ConvertChargeToPrimaryCurrency(shipmentDetail.ShipmentRateDetail.TotalNetCharge, requestedShipmentCurrency);
                            shippingOption.Rate = amount + _fedexSettings.AdditionalHandlingCharge;
                            break;
                        }
                        else // Skip the rate (RATED_ACCOUNT, PAYOR_MULTIWEIGHT, or RATED_LIST)
                        {
                            continue;
                        }
                    }
                    result.Add(shippingOption);
                }
                Debug.WriteLine("**********************************************************");
            }

            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;
            }

            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.GetShoppingCartTotalWeight(getShippingOptionRequest.Items);

            var shippingMethods = _shippingService.GetAllShippingMethods(countryId);
            foreach (var shippingMethod in shippingMethods)
            {
                decimal? rate = GetRate(subTotal, weight, shippingMethod.Id, 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;
        }
        private List<ShippingOption> ParseResponse(string response, ref string error)
        {
            var shippingOptions = new List<ShippingOption>();

            string carrierServicesOffered = _upsSettings.CarrierServicesOffered;

            using (var sr = new StringReader(response))
            using (var tr = new XmlTextReader(sr))
                while (tr.Read())
                {
                    if ((tr.Name == "Error") && (tr.NodeType == XmlNodeType.Element))
                    {
                        string errorText = "";
                        while (tr.Read())
                        {
                            if ((tr.Name == "ErrorCode") && (tr.NodeType == XmlNodeType.Element))
                            {
                                errorText += "UPS Rating Error, Error Code: " + tr.ReadString() + ", ";
                            }
                            if ((tr.Name == "ErrorDescription") && (tr.NodeType == XmlNodeType.Element))
                            {
                                errorText += "Error Desc: " + tr.ReadString();
                            }
                        }
                        error = "UPS Error returned: " + errorText;
                    }
                    if ((tr.Name == "RatedShipment") && (tr.NodeType == XmlNodeType.Element))
                    {
                        string serviceCode = "";
                        string monetaryValue = "";
                        while (tr.Read())
                        {
                            if ((tr.Name == "Service") && (tr.NodeType == XmlNodeType.Element))
                            {
                                while (tr.Read())
                                {
                                    if ((tr.Name == "Code") && (tr.NodeType == XmlNodeType.Element))
                                    {
                                        serviceCode = tr.ReadString();
                                        tr.ReadEndElement();
                                    }
                                    if ((tr.Name == "Service") && (tr.NodeType == XmlNodeType.EndElement))
                                    {
                                        break;
                                    }
                                }
                            }
                            if (((tr.Name == "RatedShipment") && (tr.NodeType == XmlNodeType.EndElement)) || ((tr.Name == "RatedPackage") && (tr.NodeType == XmlNodeType.Element)))
                            {
                                break;
                            }
                            if ((tr.Name == "TotalCharges") && (tr.NodeType == XmlNodeType.Element))
                            {
                                while (tr.Read())
                                {
                                    if ((tr.Name == "MonetaryValue") && (tr.NodeType == XmlNodeType.Element))
                                    {
                                        monetaryValue = tr.ReadString();
                                        tr.ReadEndElement();
                                    }
                                    if ((tr.Name == "TotalCharges") && (tr.NodeType == XmlNodeType.EndElement))
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                        string service = GetServiceName(serviceCode);
                        string serviceId = String.Format("[{0}]", serviceCode);

                        // Go to the next rate if the service ID is not in the list of services to offer
                        if (!String.IsNullOrEmpty(carrierServicesOffered) && !carrierServicesOffered.Contains(serviceId))
                        {
                            continue;
                        }

                        //Weed out unwanted or unkown service rates
                        if (service.ToUpper() != "UNKNOWN")
                        {
                            var shippingOption = new ShippingOption();
                            shippingOption.Rate = Convert.ToDecimal(monetaryValue, new CultureInfo("en-US"));
                            shippingOption.Name = service;
                            shippingOptions.Add(shippingOption);
                        }

                    }
                }

            return shippingOptions;
        }
        private void ProcessNewOrderNotification(string xmlData)
        {
            try
            {
                var newOrderNotification = (NewOrderNotification)EncodeHelper.Deserialize(xmlData, typeof(NewOrderNotification));
                string googleOrderNumber = newOrderNotification.googleordernumber;

                XmlNode customerInfo = newOrderNotification.shoppingcart.merchantprivatedata.Any[0];
                int customerId = Convert.ToInt32(customerInfo.Attributes["CustomerID"].Value);
                //int customerLanguageId = Convert.ToInt32(customerInfo.Attributes["CustomerLanguageID"].Value);
                //int customerCurrencyId = Convert.ToInt32(customerInfo.Attributes["CustomerCurrencyID"].Value);
                var customer = _customerService.GetCustomerById(customerId);

                if (customer == null)
                {
                    LogMessage("Could not load a customer");
                    return;
                }

                var cart = customer.ShoppingCartItems
                    .Where(sci => sci.ShoppingCartType == ShoppingCartType.ShoppingCart)
                    .Where(sci => sci.StoreId == _storeContext.CurrentStore.Id)
                    .ToList();

                _workContext.CurrentCustomer = customer;

                if (cart.Count == 0)
                {
                    LogMessage("Cart is empty");
                    return;
                }

                //validate cart
                foreach (var sci in cart)
                {
                    bool ok = false;
                    foreach (Item item in newOrderNotification.shoppingcart.items)
                    {
                        if (!String.IsNullOrEmpty(item.merchantitemid))
                        {
                            if ((Convert.ToInt32(item.merchantitemid) == sci.Id) && (item.quantity == sci.Quantity))
                            {
                                ok = true;
                                break;
                            }
                        }
                    }

                    if (!ok)
                    {
                        LogMessage(string.Format("Shopping Cart item has been changed. {0}. {1}", sci.Id, sci.Quantity));
                        return;
                    }
                }

                string[] billingFullname = newOrderNotification.buyerbillingaddress.contactname.Trim().Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                string billingFirstName = billingFullname[0];
                string billingLastName = string.Empty;
                if (billingFullname.Length > 1)
                    billingLastName = billingFullname[1];
                string billingEmail = newOrderNotification.buyerbillingaddress.email.Trim();
                string billingAddress1 = newOrderNotification.buyerbillingaddress.address1.Trim();
                string billingAddress2 = newOrderNotification.buyerbillingaddress.address2.Trim();
                string billingPhoneNumber = newOrderNotification.buyerbillingaddress.phone.Trim();
                string billingCity = newOrderNotification.buyerbillingaddress.city.Trim();
                int? billingStateProvinceId = null;
                var billingStateProvince = _stateProvinceService.GetStateProvinceByAbbreviation(newOrderNotification.buyerbillingaddress.region.Trim());
                if (billingStateProvince != null)
                    billingStateProvinceId = billingStateProvince.Id;
                string billingZipPostalCode = newOrderNotification.buyerbillingaddress.postalcode.Trim();
                int? billingCountryId = null;
                var billingCountry = _countryService.GetCountryByTwoLetterIsoCode(newOrderNotification.buyerbillingaddress.countrycode.Trim());
                if (billingCountry != null)
                    billingCountryId = billingCountry.Id;

                var billingAddress = customer.Addresses.ToList().FindAddress(
                    billingFirstName, billingLastName, billingPhoneNumber,
                    billingEmail, string.Empty, string.Empty, billingAddress1, billingAddress2, billingCity,
                    billingStateProvinceId, billingZipPostalCode, billingCountryId);

                if (billingAddress == null)
                {
                    billingAddress = new Core.Domain.Common.Address()
                    {
                        FirstName = billingFirstName,
                        LastName = billingLastName,
                        PhoneNumber = billingPhoneNumber,
                        Email = billingEmail,
                        Address1 = billingAddress1,
                        Address2 = billingAddress2,
                        City = billingCity,
                        StateProvinceId = billingStateProvinceId,
                        ZipPostalCode = billingZipPostalCode,
                        CountryId = billingCountryId,
                        CreatedOnUtc = DateTime.UtcNow,
                    };
                    customer.Addresses.Add(billingAddress);
                }
                //set default billing address
                customer.BillingAddress = billingAddress;
                _customerService.UpdateCustomer(customer);

                _genericAttributeService.SaveAttribute<ShippingOption>(customer, SystemCustomerAttributeNames.SelectedShippingOption, null, _storeContext.CurrentStore.Id);

                bool shoppingCartRequiresShipping = cart.RequiresShipping();
                if (shoppingCartRequiresShipping)
                {
                    string[] shippingFullname = newOrderNotification.buyershippingaddress.contactname.Trim().Split(new char[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries);
                    string shippingFirstName = shippingFullname[0];
                    string shippingLastName = string.Empty;
                    if (shippingFullname.Length > 1)
                        shippingLastName = shippingFullname[1];
                    string shippingEmail = newOrderNotification.buyershippingaddress.email.Trim();
                    string shippingAddress1 = newOrderNotification.buyershippingaddress.address1.Trim();
                    string shippingAddress2 = newOrderNotification.buyershippingaddress.address2.Trim();
                    string shippingPhoneNumber = newOrderNotification.buyershippingaddress.phone.Trim();
                    string shippingCity = newOrderNotification.buyershippingaddress.city.Trim();
                    int? shippingStateProvinceId = null;
                    var shippingStateProvince = _stateProvinceService.GetStateProvinceByAbbreviation(newOrderNotification.buyershippingaddress.region.Trim());
                    if (shippingStateProvince != null)
                        shippingStateProvinceId = shippingStateProvince.Id;
                    int? shippingCountryId = null;
                    string shippingZipPostalCode = newOrderNotification.buyershippingaddress.postalcode.Trim();
                    var shippingCountry = _countryService.GetCountryByTwoLetterIsoCode(newOrderNotification.buyershippingaddress.countrycode.Trim());
                    if (shippingCountry != null)
                        shippingCountryId = shippingCountry.Id;

                    var shippingAddress = customer.Addresses.ToList().FindAddress(
                        shippingFirstName, shippingLastName, shippingPhoneNumber,
                        shippingEmail, string.Empty, string.Empty,
                        shippingAddress1, shippingAddress2, shippingCity,
                        shippingStateProvinceId, shippingZipPostalCode, shippingCountryId);
                    if (shippingAddress == null)
                    {
                        shippingAddress = new Core.Domain.Common.Address()
                        {
                            FirstName = shippingFirstName,
                            LastName = shippingLastName,
                            PhoneNumber = shippingPhoneNumber,
                            Email = shippingEmail,
                            Address1 = shippingAddress1,
                            Address2 = shippingAddress2,
                            City = shippingCity,
                            StateProvinceId = shippingStateProvinceId,
                            ZipPostalCode = shippingZipPostalCode,
                            CountryId = shippingCountryId,
                            CreatedOnUtc = DateTime.UtcNow,
                        };
                        customer.Addresses.Add(shippingAddress);
                    }
                    //set default shipping address
                    customer.ShippingAddress = shippingAddress;
                    _customerService.UpdateCustomer(customer);

                    if (newOrderNotification.orderadjustment != null &&
                        newOrderNotification.orderadjustment.shipping != null &&
                        newOrderNotification.orderadjustment.shipping.Item != null)
                    {
                        var shippingMethod = (FlatRateShippingAdjustment)newOrderNotification.orderadjustment.shipping.Item;
                        var shippingOption = new ShippingOption();
                        shippingOption.Name = shippingMethod.shippingname;
                        shippingOption.Rate = shippingMethod.shippingcost.Value;
                        _genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.SelectedShippingOption, shippingOption, _storeContext.CurrentStore.Id);
                    }
                }

                //customer.LastCalculatedTax = decimal.Zero;

                var paymentInfo = new ProcessPaymentRequest()
                {
                    StoreId = _storeContext.CurrentStore.Id,
                    PaymentMethodSystemName = "Payments.GoogleCheckout",
                    CustomerId = customer.Id,
                    GoogleOrderNumber = googleOrderNumber
                };
                //TODO set customer language and currency
                //paymentInfo.CustomerLanguage = IoC.Resolve<ILanguageService>().GetLanguageById(CustomerLanguageID);
                //paymentInfo.CustomerCurrency = IoC.Resolve<ICurrencyService>().GetCurrencyById(CustomerCurrencyID);
                var result = _orderProcessingService.PlaceOrder(paymentInfo);
                if (!result.Success)
                {
                    LogMessage("new-order-notification received. CreateOrder() error: Order Number " + googleOrderNumber + ". " + result);
                    return;
                }

                var order = result.PlacedOrder;
                if (order != null)
                {
                    LogMessage("new-order-notification received and saved: Order Number " + order.Id);
                }
            }
            catch (Exception exc)
            {
                LogMessage("processNewOrderNotification Exception: " + exc.Message + ": " + exc.StackTrace);
            }
        }
        /// <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 || 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;
        }