UPS Real time GetServices

kuntesh thakker asked on March 30, 2015 15:06

https://devnet.kentico.com/questions/ups-real-time-shipping-carrier-service. As per this i will calculate price . Before calculating price i need to show the real time available methods for UPS . So how GetServices will give the available methods . I need to configure Carrier with only one option like "Standard".

Recent Answers


Suneel Jhangiani answered on March 30, 2015 15:18

You would do this by allowing for multiple services:

    public List<KeyValuePair<string, string>> GetServices()
    {
        var services = new SortedDictionary<string, string>
                              {
                                    {"STANDARD", "{ups_standard.services.standard}"},
                                    {"EXPRESS", "{ups_express.services.standard}"},
                              };

        return services.ToList();
    }



    public decimal GetPrice(Delivery delivery, string currencyCode)
    {
        //check if we have selected a shipping option
        if (delivery.ShippingOption != null)
        {
            switch (delivery.ShippingOption.ShippingOptionCarrierServiceName)
            {
                case "STANDARD":
                    // calculate the standard service rate here
                    break;
                case "EXPRESS":
                    // calculate the express service rate here
                    break;
            }
        }
    }
0 votesVote for this answer Mark as a Correct answer

kuntesh thakker answered on March 30, 2015 15:24

Hi Suneel Jhangiani , Thanks for sharing the info , I got the way you telling but if we see aspdotnetstorefront , We dont give any hardcode methods available . They are just filled up by the UPS service only according to Ship Address . Thats the question coming up in my mind.

0 votesVote for this answer Mark as a Correct answer

Suneel Jhangiani answered on March 30, 2015 16:22

Kentico does allow for this since you can implement the CanDeliver method in your customer carrier provider method. Therefore, what you would have is something like this:

public class UPSCarrier : ICarrierProvider
{
    public const string SERVICE_STANDADRD = "standard";
    public const string SERVICE_EXPRESS = "express";

    public bool CanDeliver(Delivery delivery)
    {
        //check if we have selected a shipping option
        if (delivery.ShippingOption != null)
        {
            switch (delivery.ShippingOption.ShippingOptionCarrierServiceName)
            {
                case SERVICE_STANDARD:
                    // check if standard service can be used
                    break;
                case EXPRESS_SERVICE:
                    // check if express service can be used
                    break;
            }
        }
    }

    public decimal GetPrice(Delivery delivery, string currencyCode)
    {
        //check if we have selected a shipping option
        if (delivery.ShippingOption != null)
        {
            switch (delivery.ShippingOption.ShippingOptionCarrierServiceName)
            {
                case SERVICE_STANDARD:
                    // calculate the standard service price here
                    break;
                case EXPRESS_SERVICE:
                    // check the express service price here
                    break;
            }
        }    
    }

    public List<KeyValuePair<string, string>> GetServices()
    {
        var services = new SortedDictionary<string, string>
                              {
                                    {SERVICE_STANDARD, "{ups_standard.services.standard}"},
                                    {UPS_EXPRESS, "{ups_standard.services.standard}"}
                              };

        return services.ToList();
    }

    public string CarrierProviderName
    {
        get { return "UPS Shipping Provider"; }
    }


    public Guid GetServiceConfigurationUIElementGUID(string serviceName)
    {
        return Guid.Empty;;
    }

    public Guid GetConfigurationUIElementGUID()
    {
        return Guid.Empty;
    }
}

I had a quick look at the ShippingSelector form controls source, and can see that it checks if the ShippingOption is applicable once the Enabled Shipping Options are retrieved from the database. It then adds the price when each ShippingOption is added to the drop down list.

You could possibly make this more dynamic by trying to get a list of Shipping Options in the GetServices() function, however, each one would need to be added to Kentico through the store administrator as these are stored in a table within the Kentico database. You could automate this in a few ways, one such being a scheduled task that runs periodically to pull down all the available services on a periodic basis and add any new services to the shipping options (you can disable unused services or even delete, just ensure you check that no orders have used the service).

0 votesVote for this answer Mark as a Correct answer

kuntesh thakker answered on March 31, 2015 09:59

Thanks for giving your time to reply my Queries. So Does it mean we need to add hardcode methods of UPS in GetServicves and update at the time of Check out Shipping. Then what is the use of Module we added as per kentico documentation. We can directly modify the Select Shipping webpart

0 votesVote for this answer Mark as a Correct answer

Suneel Jhangiani answered on March 31, 2015 11:51

You don't actually need to hard code the values in GetServices, however, that routine is used in the UI to configure available shipping services. The available shipping services are created as ShippingOptionInfo objects. So, some how, you would need to create all the possible ShippingInfoObjects. As I mentioned, this could be done by a periodic Scheduled Task that will connect to the UPS service and pull down all available shipping services and merge them with the existing ShippingOptionInfo objects.

Personally I feel that it is better to have the GetServices routine return all available shipping services and have a store admin enable the ones they wish to offer. This is simple in the current design and pseudo code would look like:

public class UPSCarrier : ICarrierProvider { public bool CanDeliver(Delivery delivery) { //check if we have selected a shipping option if (delivery.ShippingOption != null) { // look up if shipping option is available for the currently selected // shipping option using delivery.ShippingOption.ShippingOptionCarrierServiceName

        // delivery.ShippingOption.ShippingOptionCarrierServiceName should be the unique name
        // returned in the GetServices routine (perhaps a UPS ServiceID?)
    }
}

public decimal GetPrice(Delivery delivery, string currencyCode)
{
    //check if we have selected a shipping option
    if (delivery.ShippingOption != null)
    {
        // look up the price for shipping through the UPS API
        // shipping option using delivery.ShippingOption.ShippingOptionCarrierServiceName

        // delivery.ShippingOption.ShippingOptionCarrierServiceName should be the unique name
        // returned in the GetServices routine (perhaps a UPS ServiceID?)
    }    
}

public List<KeyValuePair<string, string>> GetServices()
{
    // get a list of UPS shipping services and add them to a list
    // the Key should be unique and will be used to identify the different services
    // offered by UPS.
    var services = new SortedDictionary<string, string>
                          {
                                {SOME_UNIQUE_SERVICE_NAME, DESCRIPTION},
                                {SOME_UNIQUE_SERVICE_NAME, DESCRIPTION}
                          };

    return services.ToList();
}

public string CarrierProviderName
{
    get { return "UPS Shipping Provider"; }
}


public Guid GetServiceConfigurationUIElementGUID(string serviceName)
{
    return Guid.Empty;;
}

public Guid GetConfigurationUIElementGUID()
{
    return Guid.Empty;
}

}

On a side note here, having tried to find out a bit more detail about the UPS API I noticed that you do need a Key. You can do this by creating a Configuration UI and returning the GUID of that in GetConfigurationUIElementGUID() function.

The key thing behind implementing this as a Carrier is that module becomes portable. Kentico allows for it to be packaged using Nuget which can then be imported into another instance. It provides some protection for your module as it cannot be customized once installed. It's a great way for developers to create their own modules that can be imported as and when needed.

0 votesVote for this answer Mark as a Correct answer

Delford Chaffin answered on February 9, 2016 16:51 (last edited on February 9, 2016 23:28)

On a related not, if I return false from the CanDeliver() method, should that not remove the option from the shipping method drop-down in my checkout process? Thanks for your help.

EDIT: It actually seems CanDeliver is not even being called. FYI - Kentico 9.0.8

SOLVED: Conflict with a CustomShippingOptionInfoProvider

0 votesVote for this answer Mark as a Correct answer

   Please, sign in to be able to submit a new answer.