nopSolutions / nopCommerce

ASP.NET Core eCommerce software. nopCommerce is a free and open-source shopping cart.
https://www.nopcommerce.com
Other
9.09k stars 5.2k forks source link

Enable Transit time on UPS plugin #7183

Closed danFbach closed 3 weeks ago

danFbach commented 2 months ago

nopCommerce version: 4.6+

Current implementation does not return transit times for shipping quotes. I can confirm these changes allow for transit times for both US Domestic and International shipments.

UPSService.cs function private async Task<RateRequest> CreateRateRequestAsync(GetShippingOptionRequest shippingOptionRequest, bool saturdayDelivery = false):

//set request details
var request = new RateRequest
{
    Request = new RateRequest_Request
    {
        //used to define the request type
        //Shop - the server validates the shipment, and returns rates for all UPS products from the ShipFrom to the ShipTo addresses
        RequestOption = "shoptimeintransit", //change from "shop" to "shoptimeintransit"
    }
};
request.Shipment = new RateRequest_Shipment
{
    Shipper = new Shipment_Shipper
    {
        ShipperNumber = _upsSettings.AccountNumber,
        Address = addressFrom
    },
    ShipFrom = new Shipment_ShipFrom
    {
        Address = addressFromDetails
    },
    ShipTo = new Shipment_ShipTo
    {
        Address = addressToDetails
    },
 //add DeliveryTimeInformation object
    DeliveryTimeInformation = new Shipment_DeliveryTimeInformation()
    {
        PackageBillType = "03",
        Pickup = new DeliveryTimeInformation_Pickup()
        {
            Date = DateTime.UtcNow.ToLocalTime().Date.AddDays(1).ToString("yyyyMMdd"),
        }
    }
};

Add this just before return request;

        request.Shipment.ShipmentTotalWeight = new Shipment_ShipmentTotalWeight()
        {
            UnitOfMeasurement = new ShipmentTotalWeight_UnitOfMeasurement()
            {
                Code = _upsSettings.WeightType,
                Description = _upsSettings.WeightType
            },
            Weight = request.Shipment.Package.Sum(x => decimal.TryParse(x.PackageWeight.Weight, out var wt) ? wt : 0).ToString()
        };

        var currencyCode = (await _currencyService.GetCurrencyByIdAsync(_currencySettings.PrimaryStoreCurrencyId))?.CurrencyCode;
        request.Shipment.InvoiceLineTotal = new Shipment_InvoiceLineTotal()
        {
            CurrencyCode = currencyCode,
            MonetaryValue = shippingOptionRequest.Items.Sum(x => x.Product.Price * x.GetQuantity()).ToString("F2")
        };

UPSService.cs function private async Task<IEnumerable<ShippingOption>> PrepareShippingOptionsAsync(RateResponse rateResponse) (i updated this as total transit days will be more accurate than businessDays alone, but if there are no rest days, then totalDays is null, so fallback to businessDays)


            if (serviceSummary != null)
            {
                if (!string.IsNullOrWhiteSpace(serviceSummary.EstimatedArrival.TotalTransitDays) && 
                    int.TryParse(serviceSummary.EstimatedArrival.TotalTransitDays, out var totalTransitDays))
                    transitDays = totalTransitDays;
                else if(!string.IsNullOrEmpty(serviceSummary.EstimatedArrival.BusinessDaysInTransit) &&
                    int.TryParse(serviceSummary.EstimatedArrival.BusinessDaysInTransit, out var businessDaysInTransit))
                    transitDays = businessDaysInTransit;
            }

NopRateClient.cs function public async Task<RateResponse> ProcessRateAsync(RateRequest request) Change string.Empty to "timeintransit" for the additionalInfo parameter.

var response = await RateAsync(Guid.NewGuid().ToString(),
    _upsSettings.UseSandbox ? "testing" : UPSDefaults.SystemName, "timeintransit", "v2403", "Shop", new RATERequestWrapper
    {
        RateRequest = request
    });
skoshelev commented 3 weeks ago

Hi, @danFbach. I appreciate your help

Closed #7183