예제 #1
0
        // v7.x legacy overload
        public void UPS2GetRates(Shipments AllShipments, out string RTShipRequest, out string RTShipResponse, Decimal MarkupPercent, decimal ShipmentValue, decimal ShippingTaxRate, ref ShippingMethodCollection shippingMethods)
        {
            RTShipRequest  = String.Empty;
            RTShipResponse = String.Empty;

            ups2.ShippingSection ShippingConfig = new ups2.ShippingSection();
            ShippingConfig.CallForShippingPrompt = AppConfigProvider.GetAppConfigValue("RTShipping.CallForShippingPrompt", StoreId, true);
            ShippingConfig.Currency = AppConfigProvider.GetAppConfigValue("Localization.StoreCurrency", StoreId, true);
            ShippingConfig.ExtraFee = AppConfigProvider.GetAppConfigValueUsCulture <decimal>("ShippingHandlingExtraFee", StoreId, true);
            ShippingConfig.FilterOutShippingMethodsThatHave0Cost = AppConfigProvider.GetAppConfigValue <bool>("FilterOutShippingMethodsThatHave0Cost", StoreId, true);
            ShippingConfig.MarkupPercent  = AppConfigProvider.GetAppConfigValueUsCulture <decimal>("RTShipping.MarkupPercent", StoreId, true);
            ShippingConfig.OriginAddress  = AppConfigProvider.GetAppConfigValue("RTShipping.OriginAddress", StoreId, true);
            ShippingConfig.OriginAddress2 = AppConfigProvider.GetAppConfigValue("RTShipping.OriginAddress2", StoreId, true);
            ShippingConfig.OriginCity     = AppConfigProvider.GetAppConfigValue("RTShipping.OriginCity", StoreId, true);
            ShippingConfig.OriginCountry  = AppConfigProvider.GetAppConfigValue("RTShipping.OriginCountry", StoreId, true);
            ShippingConfig.OriginState    = AppConfigProvider.GetAppConfigValue("RTShipping.OriginState", StoreId, true);
            ShippingConfig.OriginZip      = AppConfigProvider.GetAppConfigValue("RTShipping.OriginZip", StoreId, true);
            ShippingConfig.UseTestRates   = AppConfigProvider.GetAppConfigValue <bool>("RTShipping.UseTestRates", StoreId, true);
            ShippingConfig.WeightUnits    = AppConfigProvider.GetAppConfigValue("Localization.WeightUnits", StoreId, true);

            ups2.UPSSection UPSConfig = new ups2.UPSSection();
            UPSConfig.AccountNumber          = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.AccountNumber", StoreId, true);
            UPSConfig.AddressTypeBehavior    = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.AddressTypeBehavior", StoreId, true);
            UPSConfig.CustomerClassification = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.CustomerClassification", StoreId, true);
            if (!AllShipments.IsInternational)
            {
                UPSConfig.DeliveryConfirmation = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.DeliveryConfirmation", StoreId, true);
            }
            UPSConfig.GetNegotiatedRates = AppConfigProvider.GetAppConfigValue <bool>("RTShipping.UPS.GetNegotiatedRates", StoreId, true);
            UPSConfig.License            = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.License", StoreId, true);
            UPSConfig.MaxWeight          = AppConfigProvider.GetAppConfigValueUsCulture <decimal>("RTShipping.UPS.MaxWeight", StoreId, true);
            UPSConfig.PackagingType      = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.PackagingType", StoreId, true);
            UPSConfig.Password           = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.Password", StoreId, true);
            UPSConfig.PickupType         = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.UPSPickupType", StoreId, true);
            UPSConfig.Server             = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.Server", StoreId, true);
            UPSConfig.Services           = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.Services", StoreId, true);
            UPSConfig.TestServer         = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.TestServer", StoreId, true);
            UPSConfig.UserName           = AppConfigProvider.GetAppConfigValue("RTShipping.UPS.Username", StoreId, true);

            ShippingMethodCollection UPS2Methods = GetRates(
                AllShipments,
                ShipmentWeight,
                ShipmentValue,
                ShippingTaxRate,
                out RTShipRequest,
                out RTShipResponse,
                ref ShippingConfig,
                ref UPSConfig);

            foreach (ShippingMethod UPS2Method in UPS2Methods)
            {
                shippingMethods.Add(UPS2Method);
            }
            shippingMethods.ErrorMsg = UPS2Methods.ErrorMsg;
        }
예제 #2
0
        static public ShippingMethodCollection GetRates(Shipments AllShipments, decimal ShipmentWeight, decimal ShipmentValue,
                                                        decimal ShippingTaxRate, out string RTShipRequest, out string RTShipResponse, ref ups2.ShippingSection ShippingConfig, ref ups2.UPSSection UPSConfig)
        {
            // instantiate return variables
            ShippingMethodCollection UPS2ShipMethods = new ShippingMethodCollection();

            RTShipRequest  = String.Empty;
            RTShipResponse = String.Empty;

            // is weight within shippable limit?
            if (ShipmentWeight > UPSConfig.MaxWeight)
            {
                UPS2ShipMethods.ErrorMsg = "UPS " + ShippingConfig.CallForShippingPrompt;
                return(UPS2ShipMethods);
            }

            // check for required configuration variables
            if (UPSConfig.UserName.Length < 3)
            {
                throw new Exception("UPS Error: RTShipping.UPS.UserName must contain the User ID used to signin to ups.com.");
            }

            if (UPSConfig.Password.Length < 3)
            {
                throw new Exception("UPS Error: RTShipping.UPS.Password must contain the Password used to signin to ups.com.");
            }

            if (UPSConfig.License.Length < 7)
            {
                throw new Exception("UPS Error: RTShipping.UPS.License must contain the Access Key assigned by UPS to access UPS OnLine Tools API's.");
            }

            // for negotiated rates, do we have the UPS account number?
            if (UPSConfig.GetNegotiatedRates && UPSConfig.AccountNumber.Length != 6)
            {
                throw new Exception("UPS Error: RTShipping.UPS.GetNegotiatedRates is 'true', but a six-character UPS account number " +
                                    "is not specified in RTShipping.UPS.AccountNumber. The account number is required to retrieve negotiated rates.");
            }

            // retrieve correct UPS Server URL
            string UPSServer;

            if (ShippingConfig.UseTestRates)
            {
                UPSServer = UPSConfig.TestServer;
            }
            else
            {
                UPSServer = UPSConfig.Server;
            }


            foreach (Packages Shipment in AllShipments)
            {
                // createUPS OnLine Tools access credentials
                ups2.AccessRequest accessCredentials = new ups2.AccessRequest();
                accessCredentials.AccessLicenseNumber = UPSConfig.License;
                accessCredentials.UserId   = UPSConfig.UserName;
                accessCredentials.Password = UPSConfig.Password;

                // create a rate request
                ups2.RatingRequest rateRequest = new ups2.RatingRequest();

                // shipment details
                rateRequest.Shipment.Shipper = new ups2.RequestShipmentShipper();
                rateRequest.Shipment.Shipper.ShipperNumber = UPSConfig.AccountNumber;
                rateRequest.Shipment.RateInformation       = new ups2.ShipmentRateInformation();
                rateRequest.Shipment.RateInformation.NegotiatedRatesIndicator = String.Empty;

                // UPS PickupType
                try
                {
                    rateRequest.PickupType.Code = Enum.Format(typeof(ups2.RequestPickupTypeCode),
                                                              Enum.Parse(typeof(ups2.RequestPickupTypeCode), UPSConfig.PickupType, true), "d").PadLeft(2, '0');
                }
                catch (ArgumentException)
                {
                    throw new Exception("UPS Error: RTShipping.UPS.UPSPickupType == '" + UPSConfig.PickupType + "'. Legal values are UPSDailyPickup, " +
                                        "UPSCustomerCounter, UPSOneTimePickup, UPSOnCallAir, UPSSuggestedRetailRates, UPSLetterCenter, or UPSAirServiceCenter.");
                }

                // UPS CustomerClassification
                if (UPSConfig.CustomerClassification != string.Empty)
                {
                    rateRequest.CustomerClassification.Code = UPSConfig.CustomerClassification;  // default is Wholesale, '01'
                }
                // shipment origin
                ups2.UPSAddress Origin = new ups2.UPSAddress();

                // check Shipment for Origin address
                if (Shipment.OriginZipPostalCode != string.Empty)
                {
                    Origin.AddressLine1      = Shipment.OriginAddress1;
                    Origin.AddressLine2      = Shipment.OriginAddress2;
                    Origin.City              = Shipment.OriginCity;
                    Origin.StateProvinceCode = Shipment.OriginStateProvince;
                    Origin.PostalCode        = Shipment.OriginZipPostalCode;
                    Origin.CountryCode       = Shipment.OriginCountryCode;
                }
                else  // shipment didn't have origin address, so use default address from appConfigs.
                {
                    Origin.AddressLine1      = ShippingConfig.OriginAddress;
                    Origin.AddressLine2      = ShippingConfig.OriginAddress2;
                    Origin.City              = ShippingConfig.OriginCity;
                    Origin.StateProvinceCode = ShippingConfig.OriginState;
                    Origin.PostalCode        = ShippingConfig.OriginZip;
                    Origin.CountryCode       = ShippingConfig.OriginCountry;
                }

                // for UK, verify the Origin Country is set to GB
                if (Origin.CountryCode == "UK")
                {
                    Origin.CountryCode = "GB";
                }

                rateRequest.Shipment.Shipper.Address = Origin;

                // ship-to address
                ups2.UPSAddress Dest = new ups2.UPSAddress();

                Dest.AddressLine1      = Shipment.DestinationAddress1;
                Dest.AddressLine2      = Shipment.DestinationAddress2;
                Dest.City              = Shipment.DestinationCity;
                Dest.StateProvinceCode = Shipment.DestinationStateProvince;
                Dest.PostalCode        = Shipment.DestinationZipPostalCode;
                Dest.CountryCode       = Shipment.DestinationCountryCode;

                // residential address indicator
                if ((UPSConfig.AddressTypeBehavior.ToLower() == "forceallresidential" ||
                     Shipment.DestinationResidenceType == ResidenceTypes.Residential ||
                     Shipment.DestinationResidenceType == ResidenceTypes.Unknown && UPSConfig.AddressTypeBehavior.ToLower() != "unknownsarecommercial") &&
                    UPSConfig.AddressTypeBehavior.ToLower() != "forceallcommercial")
                {
                    Dest.ResidentialAddressIndicator = "";  // the mere presence of this tag indicates Residential
                }
                // for UK, verify the Destination Country is set to GB
                if (Dest.CountryCode == "UK")
                {
                    Dest.CountryCode = "GB";
                }

                rateRequest.Shipment.ShipTo.Address = Dest;  // add destination address to request

                // create one package per package in shipment
                rateRequest.Shipment.Package = new ups2.ShipmentPackage[Shipment.Count];

                int pIndex = 0;

                int  PackageQuantity = 1;
                bool HasFreeItems    = false;

                foreach (Package p in Shipment)
                {
                    rateRequest.Shipment.Package[pIndex] = new ups2.ShipmentPackage();
                    ups2.ShipmentPackage upsPackage = rateRequest.Shipment.Package[pIndex];

                    // shipment details
                    // UPS packaging type
                    if (UPSConfig.PackagingType != string.Empty)
                    {
                        upsPackage.PackagingType.Code = UPSConfig.PackagingType;  // default is CustomerSuppliedPackage, '02'
                    }
                    // package weight
                    upsPackage.PackageWeight.Weight            = p.Weight;
                    upsPackage.PackageWeight.UnitOfMeasurement = new ups2.UPSShipmentWeightUnitOfMeasurement();
                    if (ShippingConfig.WeightUnits.ToLower().Contains("kg") || ShippingConfig.WeightUnits.ToLower().Contains("kilo"))  // default is pounds
                    {
                        upsPackage.PackageWeight.UnitOfMeasurement.Code = ups2.UPSShipmentWeightUnitOfMeasurementCode.Kilograms;
                    }

                    // insurance
                    if (p.Insured && p.InsuredValue != 0)
                    {
                        upsPackage.PackageServiceOptions = new ups2.ShipmentPackageServiceOptions();
                        upsPackage.PackageServiceOptions.InsuredValue = new ups2.UPSMoney();
                        upsPackage.PackageServiceOptions.InsuredValue.MonetaryValue = p.InsuredValue.ToString();
                        upsPackage.PackageServiceOptions.InsuredValue.CurrencyCode  = ShippingConfig.Currency.ToUpper();
                    }

                    // delivery confirmation
                    if (UPSConfig.DeliveryConfirmation != string.Empty)
                    {
                        if (upsPackage.PackageServiceOptions == null)
                        {
                            upsPackage.PackageServiceOptions = new ups2.ShipmentPackageServiceOptions();
                        }
                        upsPackage.PackageServiceOptions.DeliveryConfirmation = new ups2.ShipmentDeliveryConfirmation();

                        try
                        {
                            upsPackage.PackageServiceOptions.DeliveryConfirmation.DCISType = Enum.Format(typeof(ups2.DCISTypeCode),
                                                                                                         Enum.Parse(typeof(ups2.DCISTypeCode), UPSConfig.DeliveryConfirmation, true), "d");
                        }
                        catch (ArgumentException)
                        {
                            throw new Exception("UPS Error: RTShipping.UPS.DeliveryConfirmation == '" + UPSConfig.DeliveryConfirmation + "'. " +
                                                "Legal values are DeliveryConfirmation, SignatureRequired, or AdultSignatureRequired.");
                        }
                    }

                    // dimensions
                    if (p.Length + p.Width + p.Height != 0)  // if package has no dimensions, do not include them
                    {
                        upsPackage.Dimensions        = new ups2.ShipmentPackageDimensions();
                        upsPackage.Dimensions.Length = p.Length;
                        upsPackage.Dimensions.Width  = p.Width;
                        upsPackage.Dimensions.Height = p.Height;

                        // if weight is kg, UPS requires size to be cm.
                        if (upsPackage.PackageWeight.UnitOfMeasurement.Code == ups2.UPSShipmentWeightUnitOfMeasurementCode.Kilograms)
                        {
                            upsPackage.Dimensions.UnitOfMeasurement.Code = ups2.DimensionsUnitOfMeasurementCode.Centimeters; // default is inches
                        }
                    }

                    if (p.IsShipSeparately)
                    {
                        PackageQuantity = p.Quantity;
                    }

                    if (p.IsFreeShipping)
                    {
                        HasFreeItems = true;
                    }

                    pIndex++;
                }

                // serialize AccessRequest class
                XmlSerializer serAccessRequest = new XmlSerializer(typeof(ups2.AccessRequest));
                StringWriter  swAccessRequest  = new StringWriter();

                serAccessRequest.Serialize(swAccessRequest, accessCredentials);
                string req = swAccessRequest.ToString();

                // serialize RatingRequest class
                XmlSerializer serRatingRequest = new XmlSerializer(typeof(ups2.RatingRequest));
                StringWriter  swRatingRequest  = new StringWriter();

                serRatingRequest.Serialize(swRatingRequest, rateRequest);
                req += swRatingRequest.ToString(); // append RatingRequest to AccessRequest

                // Send xml rate request to UPS server
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(UPSServer);
                webRequest.Method = "POST";

                // Transmit the request to UPS
                byte[] data = System.Text.Encoding.ASCII.GetBytes(req);
                webRequest.ContentLength = data.Length;
                Stream requestStream;

                try
                {
                    requestStream = webRequest.GetRequestStream();
                }
                catch (WebException e)  // could not connect to UPS endpoint
                {
                    RTShipResponse += "Tried to reach UPS Server (" + UPSServer + "): " + e.Message;
                    return(UPS2ShipMethods);
                }

                requestStream.Write(data, 0, data.Length);
                requestStream.Close();

                // get the response from UPS
                WebResponse webResponse = null;
                string      resp;
                try
                {
                    webResponse = webRequest.GetResponse();
                }
                catch (WebException e)  // could not receive a response from UPS endpoint
                {
                    RTShipResponse += "No response from UPS Server (" + UPSServer + "): " + e.Message;
                    return(UPS2ShipMethods);
                }

                using (StreamReader sr = new StreamReader(webResponse.GetResponseStream()))
                {
                    resp = sr.ReadToEnd();
                    sr.Close();
                }
                webResponse.Close();

                // deserialize the xml response into a RatingResponse object
                ups2.RatingResponse response    = new ups2.RatingResponse();
                XmlSerializer       serResponse = new XmlSerializer(typeof(ups2.RatingResponse));
                StringReader        srResponse  = new StringReader(resp);

                try
                {
                    response = (ups2.RatingResponse)serResponse.Deserialize(srResponse);
                }
                catch (InvalidOperationException e)  // invalid xml, or no reply received from UPS
                {
                    RTShipResponse += "Could not parse response from UPS server: " + e.Message + " Response received: " + resp;
                    return(UPS2ShipMethods);
                }

                srResponse.Close();

                // Check the response object for Faults
                if (response.Response.Error != null)
                {
                    RTShipResponse += "UPS Error: " + response.Response.Error.ErrorDescription;
                    if (response.Response.Error.ErrorLocation != null)
                    {
                        RTShipResponse += " " + response.Response.Error.ErrorLocation.ErrorLocationElementName;
                    }
                    return(UPS2ShipMethods);
                }

                // Check the response object for RatedShipments
                if (response.RatedShipment == null)
                {
                    RTShipResponse += "UPS Error: No rating responses returned from UPS.";
                    return(UPS2ShipMethods);
                }

                // walk the services list, looking for matches in the returned rates
                foreach (string service in UPSConfig.Services.Split(','))
                {
                    // interate the returned rates, matching with the service from the UPSServices list
                    foreach (ups2.ResponseRatedShipment ratedShipment in response.RatedShipment)
                    {
                        string serviceDescription = string.Empty;

                        // check for a match between the returned rate and the current service
                        if (ratedShipment.Service.Code == service.Split(';')[0])
                        {
                            serviceDescription = service.Split(';')[1];
                        }

                        // verify the quoted rate is in the same currency as the store
                        if (ratedShipment.TotalCharges.CurrencyCode != ShippingConfig.Currency.ToUpper())
                        {
                            RTShipResponse += "UPS Error: Received rates with currency code " + ratedShipment.TotalCharges.CurrencyCode +
                                              ", but store is configured for " + ShippingConfig.Currency + ".";
                            return(UPS2ShipMethods);
                        }

                        decimal total;

                        // use either negotiated rates or regular rates
                        if (UPSConfig.GetNegotiatedRates)
                        {
                            if (ratedShipment.NegotiatedRates != null)
                            {
                                total = Convert.ToDecimal(ratedShipment.NegotiatedRates.NetSummaryCharges.GrandTotal.MonetaryValue);
                            }
                            else  // no negotiated rates found
                            {
                                throw new Exception("UPS Error: GetNegotiatedRates is 'true', but no negotiated rates were returned. " +
                                                    "Cantact UPS to ensure that you are authorized to receive negotiated rates.");
                            }
                        }
                        else
                        {
                            total = Convert.ToDecimal(ratedShipment.TotalCharges.MonetaryValue);
                        }

                        // ignore zero-cost methods, and methods not allowed
                        if (total == 0 || serviceDescription == string.Empty || !RTShipping.ShippingMethodIsAllowed(serviceDescription, RTShipping.UpsName))
                        {
                            continue;
                        }

                        total = total * PackageQuantity * (1.00M + (ShippingConfig.MarkupPercent / 100.0M)) + ShippingConfig.ExtraFee;
                        decimal vat = Decimal.Round(total * ShippingTaxRate);

                        // add or update method in UPS2ShipMethods shipping methods collection
                        if (!UPS2ShipMethods.MethodExists(serviceDescription))
                        {
                            ShippingMethod s_method = new ShippingMethod();
                            s_method.Carrier    = RTShipping.UpsName;
                            s_method.Name       = serviceDescription;
                            s_method.Freight    = total;
                            s_method.VatRate    = vat;
                            s_method.IsRealTime = true;
                            s_method.Id         = Shipping.GetShippingMethodID(s_method.Name);

                            if (HasFreeItems)
                            {
                                s_method.FreeItemsRate = total;
                            }

                            UPS2ShipMethods.Add(s_method);
                        }
                        else
                        {
                            int            IndexOf  = UPS2ShipMethods.GetIndex(serviceDescription);
                            ShippingMethod s_method = UPS2ShipMethods[IndexOf];

                            s_method.Freight += total;
                            s_method.VatRate += vat;

                            if (HasFreeItems)
                            {
                                s_method.FreeItemsRate += total;
                            }

                            UPS2ShipMethods[IndexOf] = s_method;
                        }
                    }
                }
                RTShipRequest  += req; // stash request & response for this shipment
                RTShipResponse += resp;
            }
            return(UPS2ShipMethods);
        }