public override List <ShippingOption> GetShippingOptionEstimates(AddressInfo origin, AddressInfo destination, List <vCartItemProductInfo> cartProducts)
        {
            ErrorMessages.Clear();

            List <ShippingOption> options = new List <ShippingOption>();

            WA.Shipping.AddressInfo fedExOrigin = StoreAddressToFedExAddress(origin);

            WA.Shipping.AddressInfo fedExDestination = StoreAddressToFedExAddress(destination);
            if (string.IsNullOrEmpty(fedExDestination.CountryCode))
            {
                fedExDestination.CountryCode = origin.Country;
            }

            List <PackageInfo> fedExPackages = StoreCartToPackageList(cartProducts);

            options.AddRange(GetAvailableRates(fedExApi, fedExOrigin, fedExDestination, fedExPackages));
            if (isSmartPostEnabled && fedExApiNoSmartPost != null)
            {
                // call FedEx API again WITHOUT the SmartPost Hub ID to append the regular rates too...
                options.AddRange(GetAvailableRates(fedExApiNoSmartPost, fedExOrigin, fedExDestination, fedExPackages));
            }
            options.Sort((left, right) => left.Cost.Value.CompareTo(right.Cost.Value));

            return(options);
        }
        private List <ShippingOption> GetAvailableRates(FedExApi api, WA.Shipping.AddressInfo fedExOrigin, WA.Shipping.AddressInfo fedExDestination, List <PackageInfo> fedExPackages)
        {
            List <ShippingOption> options = new List <ShippingOption>();

            RateReply reply = api.GetAvailableRates(fedExOrigin, fedExDestination, fedExPackages);

            if (reply.HighestSeverity == NotificationSeverityType.SUCCESS || reply.HighestSeverity == NotificationSeverityType.NOTE) // || reply.HighestSeverity == NotificationSeverityType.WARNING) // check if the call was successful
            {
                if (reply.RateReplyDetails.Length > 0)
                {
                    foreach (RateReplyDetail rateDetail in reply.RateReplyDetails)
                    {
                        //Console.WriteLine("ServiceType: " + rateDetail.ServiceType);
                        foreach (RatedShipmentDetail shipmentDetail in rateDetail.RatedShipmentDetails)
                        {
                            //Console.WriteLine("RateType : " + shipmentDetail.ShipmentRateDetail.RateType);
                            //Console.WriteLine("Total Billing Weight : " + shipmentDetail.ShipmentRateDetail.TotalBillingWeight.Value);
                            //Console.WriteLine("Total Base Charge : " + shipmentDetail.ShipmentRateDetail.TotalBaseCharge.Amount);
                            //Console.WriteLine("Total Discount : " + shipmentDetail.ShipmentRateDetail.TotalFreightDiscounts.Amount);
                            //Console.WriteLine("Total Surcharges : " + shipmentDetail.ShipmentRateDetail.TotalSurcharges.Amount);
                            //Console.WriteLine("Net Charge : " + shipmentDetail.ShipmentRateDetail.TotalNetCharge.Amount);
                            //Console.WriteLine("*********");

                            if (shipmentDetail.ShipmentRateDetail.RateType == ReturnedRateType.PAYOR_ACCOUNT_PACKAGE)
                            {
                                options.Add(new ShippingOption()
                                {
                                    ProviderType = providerType,
                                    Name         = rateDetail.ServiceType.ToString(),
                                    DisplayName  = ServiceTypeToDisplayName(rateDetail.ServiceType),
                                    Cost         = shipmentDetail.ShipmentRateDetail.TotalNetCharge.Amount
                                });
                            }
                        }
                        //if (rateDetail.DeliveryTimestampSpecified)
                        //{
                        //    Console.WriteLine("Delivery timestamp " + rateDetail.DeliveryTimestamp.ToString());
                        //}
                        //Console.WriteLine("Transit Time: " + rateDetail.TransitTime);
                    }
                }
            }
            else
            {
                foreach (var error in reply.Notifications)
                {
                    if (error.Severity == NotificationSeverityType.ERROR || error.Severity == NotificationSeverityType.FAILURE || error.Severity == NotificationSeverityType.WARNING)
                    {
                        ErrorMessages.Add(string.Format(@"Code: {0}, Error: {1}", error.Code, error.Message));
                    }
                }
            }

            return(options);
        }
        private WA.Shipping.AddressInfo StoreAddressToFedExAddress(AddressInfo address)
        {
            var a = new WA.Shipping.AddressInfo()
            {
                City        = address.City,
                CountryCode = address.Country,
                PostalCode  = address.PostalCode,
                RegionCode  = address.Region,
                StreetLines = new List <string>()
            };

            if (!string.IsNullOrEmpty(address.BusinessName))
            {
                a.StreetLines.Add(address.BusinessName);
            }
            a.StreetLines.Add(address.Address1);
            if (!string.IsNullOrEmpty(address.Address2))
            {
                a.StreetLines.Add(address.Address2);
            }
            return(a);
        }