Samvel Petrosov
Samvel Petrosov

Reputation: 7706

Getting Combo-box values set from REST API

I am working with Contacts via REST API and I am trying to add an input field in my application for specifying the Source of the Contact. The problem is that the Source field is a combo box, which means that its values can be modified by Automation Steps (SM205000). For example, below is the list of the default values for the Source:

enter image description here

which corresponds to the CRMSourcesAttribute of that field

// Token: 0x020003D3 RID: 979
public class CRMSourcesAttribute : PXStringListAttribute
{
    // Token: 0x06004052 RID: 16466 RVA: 0x000FD4A4 File Offset: 0x000FB6A4
    public CRMSourcesAttribute() : base(new string[]
    {
        "W",
        "H",
        "R",
        "L",
        "O"
    }, new string[]
    {
        "Web",
        "Phone Inquiry",
        "Referral",
        "Purchased List",
        "Other"
    })
    {
    }

    // Token: 0x04002158 RID: 8536
    public const string _WEB = "W";

    // Token: 0x04002159 RID: 8537
    public const string _PHONE_INQ = "H";

    // Token: 0x0400215A RID: 8538
    public const string _REFERRAL = "R";

    // Token: 0x0400215B RID: 8539
    public const string _PURCHASED_LIST = "L";

    // Token: 0x0400215C RID: 8540
    public const string _OTHER = "O";
}

Should I go through the Automation Steps tables to get the final values of the combo-box or there is a way to get it by REST API specifying, for example, the DAC.FIELD?

Upvotes: 3

Views: 501

Answers (1)

Yuriy Zaletskyy
Yuriy Zaletskyy

Reputation: 5151

For tasks like these, I'd suggest to use reflection. Below goes example of reading Attributes with sample of usage:

    protected IEnumerable records()
    {
        //var row = new ClassFilter { ClassName = "PX.Objects.CR.CRMSourcesAttribute" };
        var row = Filter.Current;
        if (row != null && !string.IsNullOrWhiteSpace(row.ClassName))
        {
            var type = Type.GetType(row.ClassName) ??
                        Type.GetType(row.ClassName + ", PX.Objects");

            if (type != null)
                switch (type.BaseType.Name)
                {
                    case "PXIntListAttribute":
                        {
                            int[] values;
                            string[] labels;
                            GetRecords(type, out values, out labels);

                            for (int i = 0; i < values.Length; i++)
                                yield return new KeyValueRecord { Key = values[i].ToString(), UiValue = labels[i] };
                            break;
                        }
                    case "PXStringListAttribute":
                        {
                            string[] values, labels;
                            GetRecords(type, out values, out labels);

                            for (int i = 0; i < values.Length; i++)
                                yield return new KeyValueRecord { Key = values[i], UiValue = labels[i] };
                            break;
                        }
                }
        }
    }

    private void GetRecords<T>(Type type, out T[] values, out string[] labels)
    {
        var obj = Activator.CreateInstance(type);
        var flags = BindingFlags.NonPublic | BindingFlags.Instance;

        values = type.GetField("_AllowedValues", flags).GetValue(obj) as T[];
        labels = type.GetField("_AllowedLabels", flags).GetValue(obj) as string[];
    }

and picture:

enter image description here

After that you can just add graph and DAC to endpoint and expose it.

Full source code with comments is available here.

Upvotes: 2

Related Questions