1

I am reading data from the ActivityPointer entity in Dynamics 365 via the API and I want to link the activitytypecode field value to the activitypointer_activitytypecode global option set, which I believe is the correct one. However the values don't seem to match. In the ActivityPointer.activitytypecode field I have values such as:

phonecall
bulkoperation
email
appointment
task

But those values don't appear in the option set definition, using this query: GlobalOptionSetDefinitions(Name='activitypointer_activitytypecode')

The option set has the code values (e.g. 4202 for Email) and the different descriptions in all languages, but nothing matches back to the values on ActivityPointer

2 Answers 2

1

Optionset is just key value pairs (4202: Email and so on), If you want to get the formatted text value of optionset (Email, Fax, etc) from your web api query results - then you have to use [email protected] to get it. Read more

I recommend this article for complete understanding of CRM activities.

If you are looking for the code integer value in your resultset, that seems to be an issue and the result is not the expected one - old SO thread

0

The problem is that if you are reading activitytypecode in code, then you will know that you get a string value. This is the logical name of the activity entity, e.g. "email", "phonecall" etc.

If you look at the definition of activitytypecode in Power Apps then it shows it as "Entity name" (i.e. text) but using the classic solution editor it shows as the global activitypointer_activitytypecode option set, which contains values for "Email", "Phone Call" etc.

I am sure that there should be a simple way of converting from activitytypecode (i.e. entity name) to activitypointer_activitytypecode (i.e. option set), but I've yet to find it.

What I am doing is retrieving the global activitypointer_activitytypecode option set, so I have access to all of the text values. Then retrieve details about the entity indicated by activitytypecode, specifically what is of interesting is the display name. Then loop through the option set looking for a case-insensitive match on display name.

This is my C# code:

public int? GetActivityType(IOrganizationService service, string activityTypeCode)
{
    // Get all activity types.
    var optionSetRequest = new RetrieveOptionSetRequest()
    {
        Name = "activitypointer_activitytypecode"
    };
    var optionSetResponse = (RetrieveOptionSetResponse)service.Execute(optionSetRequest);
    var optionSetMetadata = (OptionSetMetadata)optionSetResponse.OptionSetMetadata;
    var optionValues = new Dictionary<string, int?>(StringComparer.OrdinalIgnoreCase);
    foreach (var option in optionSetMetadata.Options)
    {
        foreach (var optionLabel in option.Label.LocalizedLabels)
        {
            optionValues[optionLabel.Label] = option.Value;
        }
    }
    // Get the display name for the activity.
    var retrieveEntityRequest = new RetrieveEntityRequest
    {
        EntityFilters = EntityFilters.Entity,
        LogicalName = activityTypeCode
    };
    var retrieveEntityResponse = (RetrieveEntityResponse)service.Execute(retrieveEntityRequest);
    LocalizedLabelCollection entityLabels = retrieveEntityResponse.EntityMetadata.DisplayName.LocalizedLabels;
    // Look up the display name in the option set values.
    foreach (var entityLabel in entityLabels)
    {
        if (optionValues.TryGetValue(entityLabel.Label, out int? value))
        {
            return (Schema.GlobalOptionSet.ActivityType?)value;
        }
    }
    // If we get here then we've failed.
    return null;
}

That is making two API calls, so best avoided in any situations where performance might be an issue. I'm not saying the code is perfect, but it hasn't let me down yet. Even so, I would recommend making do with the logical names provided by activitytypecode if you can.

Not the answer you're looking for? Browse other questions tagged or ask your own question.