2. Expected behavior: USPS should return services/rates
3. Actual behavior : USPS reports error "Please enter a valid weight in ounces"
4. Steps to reproduce the problem:
Create a product with a weight of 1.75 lbs (includes fraction)
The problem is that in the prior versions of the USPS plugin, the var weight was an int. Now, it's a decimal returned by function GetWeight()
Here's some LinqPad to see the issue
decimal weight = 28.0M; //weight in ounces
(weight / 16).Dump("(weight / 16)");
//old - incorrect
var pounds = Convert.ToInt32(weight / 16);
//new correct
//var pounds = Convert.ToInt32(Math.Floor(weight / 16));
var ounces = Convert.ToInt32(weight - (pounds * 16.0M));
pounds.Dump("pounds");
ounces.Dump("ounces");
(weight / 16)
1.75
--old--
pounds
2
ounces
-4
--new--
pounds
1
ounces
12
5. Modifications
\Plugins\Nop.Plugin.Shipping.USPS\Services\USPSService.cs
Option 1
Existing code:
private string CreateRequest(...
...
var weight = GetWeight(getShippingOptionRequest);
...
var pounds = Convert.ToInt32(weight / 16);
var ounces = Convert.ToInt32(weight - (pounds * 16.0M));
...
The correct expression is to use Math.Floor:
var pounds = Convert.ToInt32(Math.Floor(weight / 16));
Option 2 - better :)
Alternately, leave the above as-is, and change the function GetWeight() to return an int, ...
considering that it's returning weight in ounces as per
USPSShippingDefaults.MEASURE_WEIGHT_SYSTEM_KEYWORD = "ounce"
Old code
private decimal GetWeight(GetShippingOptionRequest shippingOptionRequest, int minRate = 1)
{
var measureWeight = _measureService.GetMeasureWeightBySystemKeyword(USPSShippingDefaults.MEASURE_WEIGHT_SYSTEM_KEYWORD)
?? throw new NopException($"USPS shipping service. Could not load \"{USPSShippingDefaults.MEASURE_WEIGHT_SYSTEM_KEYWORD}\" measure weight");
var weight = _shippingService.GetTotalWeight(shippingOptionRequest, ignoreFreeShippedItems: true);
weight = _measureService.ConvertFromPrimaryMeasureWeight(weight, measureWeight);
weight = Convert.ToInt32(Math.Ceiling(weight));
return Math.Max(weight, minRate);
}
New Code
1) return type changed to int
2) parameter
..., int minRate = 1)
renamed to
..., int minWeight = 1)
3) moved the Math.Max & Convert.ToInt32
private int GetWeight(GetShippingOptionRequest shippingOptionRequest, int minWeight = 1)
{
var measureWeight = _measureService.GetMeasureWeightBySystemKeyword(USPSShippingDefaults.MEASURE_WEIGHT_SYSTEM_KEYWORD)
?? throw new NopException($"USPS shipping service. Could not load \"{USPSShippingDefaults.MEASURE_WEIGHT_SYSTEM_KEYWORD}\" measure weight");
var weight = _shippingService.GetTotalWeight(shippingOptionRequest, ignoreFreeShippedItems: true);
weight = _measureService.ConvertFromPrimaryMeasureWeight(weight, measureWeight);
weight = Math.Max(Math.Ceiling(weight), minWeight);
return Convert.ToInt32(weight);
}
(P.S. There are warnings in the same code file:
Message IDE0051 Private member 'USPSService.GetDimensionsForSingleItem' is unused.
Message IDE0051 Private member 'USPSService.GetWeightForSingleItem' is unused.