All right, so while trying to figure out what all of the available codes mean in Ice.Menu.OptionType and Ice.Menu.OptionSubType, since they were not all listed in the Data Dictionary Viewer, I found out that the available codes and descriptions for these fields—and every other field like them that use a seemingly hard-coded list of values and descriptions such as Customer.EntityUseCode, Customer.CustomerType, InvcHead.InvoiceType, OrderHed.PayFlag, and many many more fields in both the ERP and ICE namespaces—live in the ZDataField.CodeDescriptionList column of the row corresponding to the DataTable field we’re dealing with.
I couldn’t figure out how to split the CodeDescriptionList (nvarchar) into a two-dimensional array in the query of my updatable BAQ, so I ended up retrieving the CodeDescriptionList for the fields I wanted in a post-processing directive on the GetList method of the BAQ. The code is pretty straightforward:
// set up the CodeDesc lists
string[] OptionTypeCodes = (from zdfRow in Db.ZDataField where zdfRow.SystemCode == "ICE" && zdfRow.DataTableID == "Menu" && zdfRow.FieldName == "OptionType" select zdfRow.CodeDescriptionList).FirstOrDefault().Split('~');
string[] OptionSubTypeCodes = (from zdfRow in Db.ZDataField where zdfRow.SystemCode == "ICE" && zdfRow.DataTableID == "Menu" && zdfRow.FieldName == "OptionSubType" select zdfRow.CodeDescriptionList).FirstOrDefault().Split('~');
// loop through results table and replace codes with descriptions
foreach (var ttRow in result.Results)
{
string thisOptionTypeCode = (from codeRow in OptionTypeCodes where codeRow.StartsWith(ttRow["Menu_OptionType"].ToString() + '`') select (codeRow != null ? codeRow.Split('`')[1] : "")).FirstOrDefault();
if (!String.IsNullOrEmpty(thisOptionTypeCode)) ttRow["Menu_OptionType"] = thisOptionTypeCode;
string thisOptionSubTypeCode = (from codeRow in OptionSubTypeCodes where codeRow.StartsWith(ttRow["Menu_OptionSubType"].ToString() + '`') select (codeRow != null ? codeRow.Split('`')[1] : "")).FirstOrDefault();
if (!String.IsNullOrEmpty(thisOptionSubTypeCode)) ttRow["Menu_OptionSubType"] = thisOptionSubTypeCode;
}
Works just fine, as you can see:
Now, naturally the vast majority of these CodeDescriptionLists are going to be used by special hidden logic everywhere in Epicor and shouldn’t be touched. But it got me wondering, if one were to make an updatable BAQ for ZDataFields, can anyone think of a use case for modifying these that won’t mess anything up?
Maybe removing unused options from the EntityUseCode fields, or changing/translating descriptions in certain fields, or maybe even adding new codes to existing fields with BPMs to use them. If I had known about this table/field when we were still first implementing Epicor and migrating from Exact Macola/Synergy, and if it was possible to do so, I might’ve changed the available options for Customer.CustomerType to match the five-category system we had been using: Suspect, Lead, End User, Customer, Reseller. Would it have been advisable to do so? Probably not but it seems like it would have made the data migration easier.
Any other thoughts about Ice.ZDataField.CodeDescriptionList?