REALLY need help with UPS, USPS

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.
13 years ago
thanks to everyone that has posted here.
Ive been running with ALL options on usps, and needless to say its really not going well.
it is confusing for the customer, and we have already had issues with this.

Another very confusing thing, that I had not noticed until the previous post pointed out the default to 1 pound or 1 inch was this.. My site sells comic books. like 1/8 to 1/4 inch thick. The calculator charges for four comics from AZ to NY (about 2 pounds) quoted the customer at ~55$ for priority shipping. Is this because it default each item to 7x10x1 times 4, and each item weighing 1 pound?

We have alot of time into nopcommerce so far, and its truly frustrating to see that in Zencart, this is simply solved by unchecking USPS shipping options that you dont want. I cant for the life of me figure out why 1.8 is being released and this hasn't been fixed yet.

Currently trying to figure out a solution for order by weight, but this is nowhere near exact.
13 years ago
I found a post where the user is set to return ALL options, but he then only displays what is in the USPSStirngs.cs _Elements string

I am testing a fix to my USPSComputationMethod.cs and the USPSStrings.cs file that will fix the pounds/ounces issue as well as filter the ALL results.  It does not fix the size issue you have, though.  .25 inches will ship as 1 inch with this code.  The code is broken up into different posts below.  (Note, this has worked in my initial test but has NOT been fully tested).  Also, only the currently uncommented string in USPSStrings.cs work with this.  All the others coming back using the ALL method are different in some way.  I'll post again later with all the returned strings.:
13 years ago
Here are the changed methods in USPSComputationMethod
1)
        private string CreateRequest(string username, string password, ShipmentPackage shipmentPackage)
        {
            var usedMeasureWeight = MeasureManager.GetMeasureWeightBySystemKeyword(MEASUREWEIGHTSYSTEMKEYWORD);
            if (usedMeasureWeight == null)
                throw new NopException(string.Format("USPS shipping service. Could not load \"{0}\" measure weight", MEASUREWEIGHTSYSTEMKEYWORD));

            var usedMeasureDimension = MeasureManager.GetMeasureDimensionBySystemKeyword(MEASUREDIMENSIONSYSTEMKEYWORD);
            if (usedMeasureDimension == null)
                throw new NopException(string.Format("USPS shipping service. Could not load \"{0}\" measure dimension", MEASUREDIMENSIONSYSTEMKEYWORD));

            int length = Convert.ToInt32(Math.Ceiling(MeasureManager.ConvertDimension(shipmentPackage.GetTotalLength(), MeasureManager.BaseDimensionIn, usedMeasureDimension)));
            int height = Convert.ToInt32(Math.Ceiling(MeasureManager.ConvertDimension(shipmentPackage.GetTotalHeight(), MeasureManager.BaseDimensionIn, usedMeasureDimension)));
            int width = Convert.ToInt32(Math.Ceiling(MeasureManager.ConvertDimension(shipmentPackage.GetTotalWidth(), MeasureManager.BaseDimensionIn, usedMeasureDimension)));
            decimal weight = MeasureManager.ConvertWeight(ShippingManager.GetShoppingCartTotalWeigth(shipmentPackage.Items, shipmentPackage.Customer), MeasureManager.BaseWeightIn, usedMeasureWeight);
            if (length < 1)
                length = 1;
            if (height < 1)
                height = 1;
            if (width < 1)
                width = 1;
            //if (weight < 1)
            //   weight = 1;


            string zipPostalCodeFrom = shipmentPackage.ZipPostalCodeFrom;
            string zipPostalCodeTo = shipmentPackage.ShippingAddress.ZipPostalCode;

            //valid values for testing. http://testing.shippingapis.com/ShippingAPITest.dll
            //Zip to = "20008"; Zip from ="10022"; weight = 2;

            int pounds = Convert.ToInt32(weight);
            //we don't use ounce
            int ounces = Convert.ToInt32((weight - pounds) * 16.0M);
            //int ounces = 0;
            //if (pounds < 1)
            //    pounds = 1;

            string requestString = string.Empty;

            bool isDomestic = IsDomesticRequest(shipmentPackage);
            if (isDomestic)
            {
                #region domestic request
                var sb = new StringBuilder();
                sb.AppendFormat("<RateV3Request USERID=\"{0}\" PASSWORD=\"{1}\">", username, password);

                if ((!IsPackageTooHeavy(pounds, ounces)) && (!IsPackageTooLarge(length, height, width)))

                {
                    var packageSize = GetPackageSize(length, height, width);
                    // RJH get all XML strings not commented out for USPSStrings.
                    // RJH V3 USPS Service must be Express, Express SH, Express Commercial, Express SH Commercial, First Class, Priority, Priority Commercial, Parcel, Library, BPM, Media, ALL or ONLINE;
                    sb.Append("<Package ID=\"0\">");
                    sb.Append("<Service>All</Service>");
                    sb.AppendFormat("<ZipOrigination>{0}</ZipOrigination>", zipPostalCodeFrom);
                    sb.AppendFormat("<ZipDestination>{0}</ZipDestination>", zipPostalCodeTo);
                    sb.AppendFormat("<Pounds>{0}</Pounds>", pounds);
                    sb.AppendFormat("<Ounces>{0}</Ounces>", ounces);
                    sb.AppendFormat("<Size>{0}</Size>", packageSize);
                    sb.Append("<Machinable>FALSE</Machinable>");
                    sb.Append("</Package>");

                    sb.Append("</RateV3Request>");
                    return "API=RateV3&XML=" + sb.ToString();
                }
                else
                {
                    int totalPackages = 1;
                    int totalPackagesDims = 1;
                    int totalPackagesWeights = 1;
                    if (IsPackageTooHeavy(pounds, ounces))
                    {
                        decimal DecPounds = OuncesToPounds(PoundsToOunces(pounds) + ounces);
                        totalPackagesWeights = Convert.ToInt32(Math.Ceiling(DecPounds / (decimal)MAXPACKAGEWEIGHT));
                    }
                    if (IsPackageTooLarge(length, height, width))
                    {
                        totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)TotalPackageSize(length, height, width) / (decimal)108));
                    }
                    totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;
                    if (totalPackages == 0)
                        totalPackages = 1;

                    int pounds2 = pounds / totalPackages;
                    //we don't use ounces
                    int ounces2 = ounces / totalPackages;
                    int height2 = height / totalPackages;
                    int width2 = width / totalPackages;
                    int length2 = length / totalPackages;
                    if (pounds2 < 1)
                        pounds2 = 1;
                    if (height2 < 1)
                        height2 = 1;
                    if (width2 < 1)
                        width2 = 1;
                    if (length2 < 1)
                        length2 = 1;

                    var packageSize = GetPackageSize(length2, height2, width2);

                    for (int i = 0; i < totalPackages; i++)
                    {
                        sb.AppendFormat("<Package ID=\"{0}\">", i.ToString());
                        // sb.AppendFormat("<Service>{0}</Service>", USPSService.All);
                        sb.AppendFormat("<Service>ALL</Service>");
                        sb.AppendFormat("<ZipOrigination>{0}</ZipOrigination>", zipPostalCodeFrom);
                        sb.AppendFormat("<ZipDestination>{0}</ZipDestination>", zipPostalCodeTo);
                        sb.AppendFormat("<Pounds>{0}</Pounds>", pounds2);
                        sb.AppendFormat("<Ounces>{0}</Ounces>", ounces2);
                        sb.AppendFormat("<Size>{0}</Size>", packageSize);
                        sb.Append("<Machinable>FALSE</Machinable>");
                        sb.Append("</Package>");

                    }
                }

                sb.Append("</RateV3Request>");

                requestString = "API=RateV3&XML=" + sb.ToString();
                #endregion
            }
            else
            {
                #region international request
                var sb = new StringBuilder();
                sb.AppendFormat("<IntlRateRequest USERID=\"{0}\" PASSWORD=\"{1}\">", username, password);

                if ((!IsPackageTooHeavy(pounds)) && (!IsPackageTooLarge(length, height, width)))
                {
                    string mailType = "Package"; //Package, Envelope
                    sb.Append("<Package ID=\"0\">");
                    // No use of pounds in this classes
                    sb.Append("<Pounds>0</Pounds>");
                    ounces = PoundsToOunces(pounds);
                    sb.AppendFormat("<Ounces>{0}</Ounces>", ounces);
                    sb.Append("<Machinable>FALSE</Machinable>");
                    sb.AppendFormat("<MailType>{0}</MailType>", mailType);
                    sb.Append("<GXG>");
                    sb.AppendFormat("<Length>{0}</Length>", length);
                    sb.AppendFormat("<Width>{0}</Width>", width);
                    sb.AppendFormat("<Height>{0}</Height>", height);
                    sb.Append("<POBoxFlag>N</POBoxFlag>");
                    sb.Append("<GiftFlag>N</GiftFlag>");
                    sb.Append("</GXG>");
                    sb.AppendFormat("<Country>{0}</Country>", shipmentPackage.ShippingAddress.Country.Name);

                    sb.Append("</Package>");
                }
                else
                {
                    int totalPackages = 1;
                    int totalPackagesDims = 1;
                    int totalPackagesWeights = 1;
                    if (IsPackageTooHeavy(pounds))
                    {
                        totalPackagesWeights = Convert.ToInt32(Math.Ceiling((decimal)pounds / (decimal)MAXPACKAGEWEIGHT));
                    }
                    if (IsPackageTooLarge(length, height, width))
                    {
                        totalPackagesDims = Convert.ToInt32(Math.Ceiling((decimal)TotalPackageSize(length, height, width) / (decimal)108));
                    }
                    totalPackages = totalPackagesDims > totalPackagesWeights ? totalPackagesDims : totalPackagesWeights;
                    if (totalPackages == 0)
                        totalPackages = 1;

                    int pounds2 = pounds / totalPackages;
                    //we don't use ounces
                    int ounces2 = ounces / totalPackages;
                    int height2 = height / totalPackages;
                    int width2 = width / totalPackages;
                    int length2 = length / totalPackages;
                    if (pounds2 < 1)
                        pounds2 = 1;
                    if (height2 < 1)
                        height2 = 1;
                    if (width2 < 1)
                        width2 = 1;
                    if (length2 < 1)
                        length2 = 1;

                    for (int i = 0; i < totalPackages; i++)
                    {
                        string mailType = "Package"; //Package, Envelope

                        sb.AppendFormat("<Package ID=\"{0}\">", i.ToString());
                        // No use of pounds in this classes
                        sb.Append("<Pounds>0</Pounds>");
                        ounces2 = PoundsToOunces(pounds2);
                        sb.AppendFormat("<Ounces>{0}</Ounces>", ounces2);
                        sb.Append("<Machinable>FALSE</Machinable>");
                        sb.AppendFormat("<MailType>{0}</MailType>", mailType);
                        sb.Append("<GXG>");
                        sb.AppendFormat("<Length>{0}</Length>", length2);
                        sb.AppendFormat("<Width>{0}</Width>", width2);
                        sb.AppendFormat("<Height>{0}</Height>", height2);
                        sb.Append("<POBoxFlag>N</POBoxFlag>");
                        sb.Append("<GiftFlag>N</GiftFlag>");
                        sb.Append("</GXG>");
                        sb.AppendFormat("<Country>{0}</Country>", shipmentPackage.ShippingAddress.Country.Name);

                        sb.Append("</Package>");
                    }
                }

                sb.Append("</IntlRateRequest>");

                requestString = "API=IntlRate&XML=" + sb.ToString();
                #endregion
            }

            return requestString;
        }
13 years ago
Here are a couple needed to be added:
2)

        private bool IsPackageTooHeavy(int pounds, int ounces)
        {
            if (OuncesToPounds(PoundsToOunces(pounds)+ounces) > MAXPACKAGEWEIGHT)
                return true;
            else
                return false;
        }

        private decimal OuncesToPounds(int pounds)
        {
            return pounds / 16;
        }



Here is the change to GetShippingOptions:
3)

        /// <summary>
        ///  Gets available shipping options
        /// </summary>
        /// <param name="shipmentPackage">Shipment package</param>
        /// <param name="error">Error</param>
        /// <returns>Shipping options</returns>
        public ShippingOptionCollection GetShippingOptions(ShipmentPackage shipmentPackage, ref string error)
        {
            var shippingOptions = new ShippingOptionCollection();

            if (shipmentPackage == null)
                throw new ArgumentNullException("shipmentPackage");
            if (shipmentPackage.Items == null)
                throw new NopException("No shipment items");
            if (shipmentPackage.ShippingAddress == null)
            {
                error = "Shipping address is not set";
                return shippingOptions;
            }

            string url = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.URL");
            string username = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.Username");
            string password = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.Password");
            decimal additionalHandlingCharge = SettingManager.GetSettingValueDecimalNative("ShippingRateComputationMethod.USPS.AdditionalHandlingCharge");
            shipmentPackage.ZipPostalCodeFrom = SettingManager.GetSettingValue("ShippingRateComputationMethod.USPS.DefaultShippedFromZipPostalCode");


            bool isDomestic = IsDomesticRequest(shipmentPackage);
            string requestString = CreateRequest(username, password, shipmentPackage);
            string responseXML = DoRequest(url, requestString);
            //shippingOptions = ParseResponse(responseXML, isDomestic, ref error);
            // filter for allowed options and adjust rates based on total number of packages
            USPSStrings uspsStrings = new USPSStrings();
            foreach (var option in ParseResponse(responseXML, isDomestic, ref error))
            {
                if (uspsStrings.Elements.Any(service => string.Compare(service, option.Name, true) == 0))
                {
                    shippingOptions.Add(option);
                }
            }

            foreach (var shippingOption in shippingOptions)
            {
                if (!shippingOption.Name.ToLower().StartsWith("usps"))
                    shippingOption.Name = string.Format("USPS {0}", shippingOption.Name);
                shippingOption.Rate += additionalHandlingCharge;
            }

            //if (String.IsNullOrEmpty(error))
            //    error = "Shipping options could not be loaded";
            return shippingOptions;

        }
13 years ago
The Elements string in USPSStrings.cs:
4)

        string[] _elements = {  // "Express",
                                    // "Express SH",
                                    // "Express Commercial",
                                    // "Express SH Commercial",
                                     "First-Class Mail Parcel",                       /* 13 oz limit */
                                     "Priority Mail",                                   // "Priority Commercial",

                                    // "Parcel",
                                    // "Library",
                                    // "BPM",
                                    // "Media",
                                    //"ALL",
                                    // "ONLINE"
                                 };

Note:  Here are the actual strings that come back from the USPS API when ALL is used as a service.  The strings above would need to be changed to the list below for any of them to work.  If a service is not valid for a weight/size combo, it will not be returned.  This list was returned for a 6 ounce package.

"Express Mail Sunday/Holiday Guarantee"
"Express Mail Flat-Rate Envelope Sunday/Holiday Guarantee"
"Express Mail Hold For Pickup"
"Express Mail Flat Rate Envelope Hold For Pickup"
"Express Mail"
"Express Mail Flat Rate Envelope"
"Priority Mail"
"Priority Mail Flat Rate Envelope"
"Priority Mail Small Flat Rate Box"
"Priority Mail Medium Flat Rate Box"
"Priority Mail Large Flat Rate Box"
"First-Class Mail Flat"
"First-Class Mail Parcel"
"Parcel Post"
"Bound Printed Matter"
"Media Mail"
"Library Mail"
13 years ago
Is there a similar file for UPS options? I'm having a similar problem in that UPS gives me every possible option, but I only want UPS ground.


realbrandon wrote:
Thanks so much.  I found the file "USPSStrings.cs" and commented out options I don't need, compile it, upload it, and it's all good.

Something strange though, the "First Class" option will generate error from the USPS web service.


My question is, how do I limit the shipping options for USPS or UPS shipping?


You have to go into the files that correspond to the shipping service you want to use and comment out the ones that you don't want. It is pretty clear what to do once you look...
13 years ago
Anyone know if this fix has been implemented into 1.90?  I am having issues with First Class not showing up as an option for my products that are only 3.6 oz.  A little late for me to Beta test 1.9 at this point.
13 years ago
I don't this has been adressed at all in any version officially.  I think this code could be ported over, but I'm not at the point were I can even test 1.90 in VS2010 yet.
13 years ago
djcubed wrote:
Anyone know if this fix has been implemented into 1.90?  I am having issues with First Class not showing up as an option for my products that are only 3.6 oz.  A little late for me to Beta test 1.9 at this point.

There are a couple references to improvements with USPS and UPS in this topic: https://www.nopcommerce.com/boards/t/7492/nopcommerce-190-is-coming-in-14-days-beta-testers-needed.aspx for NC 1.90. I'm not sure if they address what you are referring to, but you might want to check it out.
13 years ago
I found these two mods very helpful. I think they are using them in the new version 1.9.

For version 1.8.

USPS
https://www.nopcommerce.com/boards/t/6891/usps-selectable-rates-services.aspx

UPS
https://www.nopcommerce.com/boards/t/6891/usps-selectable-rates-services.aspx
This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.