Dynamics Crm: Get metadata for statuscode/statecode mapping
Asked Answered
O

3

13

In Dynamics CRM 2011, on the Incident entity, the "Status Reason" optionset (aka statuscode) is related to the "Status" optionset (aka statecode)

e.g. see this screenshot

screenshot of CRM field options

When I use the API to retrieve the Status Reason optionset, like so:

        RetrieveAttributeRequest attributeRequest = new RetrieveAttributeRequest
        {
            EntityLogicalName = "incident",
            LogicalName = "statuscode",
            RetrieveAsIfPublished = true
        };
        RetrieveAttributeResponse attributeResponse = (RetrieveAttributeResponse)serv.Execute(attributeRequest);
        AttributeMetadata attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
        StatusAttributeMetadata statusMetadata = (StatusAttributeMetadata)attrMetadata;
        var dict = new Dictionary<int?, string>();
        foreach (OptionMetadata optionMeta in statusMetadata.OptionSet.Options)
        {
            dict.Add(optionMeta.Value, optionMeta.Label.UserLocalizedLabel.Label);
        }

It works in that I get the whole list of "Status Reason" (statuscode) options. However, I dont get any info about which "Status Reason" (statuscode) options relate to which "Status" (statecode) options.

How do I get that information?

Oriental answered 17/3, 2013 at 17:33 Comment(0)
T
14

You already have everything try insert this code inside of foreach:

 int stateOptionValue = (int)((StatusOptionMetadata)optionMeta).State;

See StatusAttributeMetaData.OptionSet.Options hierarchy can return a type called StatusOptionMetadata if you use the State property of the StatusOptionMetadata, it will return the statecode this statuscode belongs to.

Tumefy answered 18/3, 2013 at 10:11 Comment(1)
Ah, ok, so I should use StatusOptionMetadata in the foreach instead of OptionMetadata - will try it out ...Oriental
I
8

Here is how you can get it by querying the database

SELECT distinct e.LogicalName as entity,
      smState.Value AS stateCode,
      smstate.AttributeValue,
      smStatus.Value AS [statuscode/statusreason],
      smStatus.AttributeValue
FROM StatusMap sm
     JOIN Entity e ON sm.ObjectTypeCode = e.ObjectTypeCode
     JOIN StringMap smState ON smState.AttributeValue = sm.State
                           AND smState.ObjectTypeCode = e.ObjectTypeCode
                           AND smState.AttributeName = 'StateCode'
     JOIN StringMap smStatus ON smStatus.AttributeValue = sm.Status
                            AND smStatus.ObjectTypeCode = e.ObjectTypeCode
                            AND smStatus.AttributeName = 'StatusCode'
WHERE  e.LogicalName in ('lead')
ORDER BY e.LogicalName,
      smState.AttributeValue,
      smStatus.AttributeValue;
Ideal answered 8/4, 2017 at 18:2 Comment(0)
I
1

Here is working code that will output State/Status mapping for a given entity (you just need to provide the orgServiceProxy):

    var dictState = new Dictionary<int, OptionMetadata>();
    var dictStatus = new Dictionary<int, List<OptionMetadata>>();

    string entityName = "lead";
    int count=0;
    using (var orgServiceProxy = GetOrgServiceProxy(orgServiceUriOnLine))
    {
        RetrieveAttributeResponse attributeResponse = GetAttributeData(orgServiceProxy, entityName, "statecode");
        AttributeMetadata attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
        StateAttributeMetadata stateMetadata = (StateAttributeMetadata)attrMetadata;
        foreach (OptionMetadata optionMeta in stateMetadata.OptionSet.Options)
        {
            dictState.Add(optionMeta.Value.Value,optionMeta);
            dictStatus.Add(optionMeta.Value.Value,new List<OptionMetadata>());
        }

        attributeResponse = GetAttributeData(orgServiceProxy, entityName, "statuscode");
        attrMetadata = (AttributeMetadata)attributeResponse.AttributeMetadata;
        StatusAttributeMetadata statusMetadata = (StatusAttributeMetadata)attrMetadata;

        foreach (OptionMetadata optionMeta in statusMetadata.OptionSet.Options)
        {
            int stateOptionValue = ((StatusOptionMetadata)optionMeta).State.Value;
            var statusList = dictStatus[stateOptionValue];
            statusList.Add(optionMeta);
            count++;
        }
    }
    Console.WriteLine($"Number of mappings: {count}");
    foreach (var stateKvp in dictState.OrderBy(x=> x.Key))
    {
        Console.WriteLine($"State: {stateKvp.Value.Value}: {stateKvp.Value.Label.UserLocalizedLabel.Label}");
        var statusList = dictStatus[stateKvp.Key];
        Console.WriteLine($"\tStatuses");
        foreach (var status in statusList.OrderBy(s => s.Value))
        {
            Console.WriteLine($"\t\t{stateKvp.Value.Value}: {status.Label.UserLocalizedLabel.Label}");
        }
    }
Ideal answered 8/4, 2017 at 18:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.