Checking Country-Specific Feature Settings from Code
Filed under: #daxmusings #bizapps
Last week I posted about the country-specific features in AX 2012. We looked at creating fields that are country-specific, and how those relate to either your legal entity, or another party entity specified on another field in the table.
What prompted me to write about this feature was actually the opposite problem. I had some generic code that was looping over tables and fields, but users complained the code was showing tables and fields they had not seen before. Turned out those were country-specific fields and tables. When checking configuration keys, there are easy functions to test those (isConfigurationkeyEnabled). Unfortunately, there is no such functional to test for country-specific features… so, time to code!
The metadata classes DictTable and DictField have been updated to give you the two properties we’ve set in our previous article, namely “CountryRegionCodes” (listing the countries) and “CountryRegionContextField” (optionally listing a field for the region context).
First things first. Remembering the setup we did, the field or table specifies a list of country ISO codes. The country/region of the “context” is considered as a RecId of a DirParty (global address book) entity record. So, we’ll need a function that finds the ISO code of the primary address of a DirParty record…
public static AddressCountryRegionISOCode getEntityRegionISO(DirPartyRecId _recId)
{
DirParty party;
LogisticsLocationEntity location;
AddressCountryRegionId regionId;
party = DirParty::constructFromPartyRecId(_recId);
if (party)
location = party.getPrimaryPostalAddressLocation();
regionId = location ? location.getPostalAddress().CountryRegionId : '';
return LogisticsAddressCountryRegion::find(regionId).ISOcode;
}
This will return an empty string if the party, the party’s primary address, or the ISO code cannot be found. You could place this method on the Global class to make it a global function.
Next, we’ll create a method to check if a table is in fact enabled in our current context (this means checking the regular configuration key as well as the country-specific settings, if they are used). Since there is potential for the function needing the actual record (in case of a table specifying a context field), we require an actual table buffer as input to our function. Note that the “getCountryRegionCodes()” method of the DictTable class doesn’t return a comma-separated list as specified in the properties, but parses it out into a container of ISO codes.
public static boolean isTableCountryFeatureEnabled(Common _record)
{
DictTable dictTable = new DictTable(_record.TableId);
boolean isEnabled = false;
DirPartyRecId partyRecId;
// First make sure we found the table and it's enabled in the configuration
isEnabled = dictTable != null && isConfigurationkeyEnabled(dictTable.configurationKeyId());
// Additionally, check if there are country region codes specified
if (isEnabled && conLen(dictTable.getCountryRegionCodes()) > 0)
{
// If a context field is specified
if (dictTable.getCountryRegionContextField() != 0)
{
// Get the Party Rec Id Value from that field
// TODO: could do some defensive coding and make sure the field id is valid
partyRecId = _record.(dictTable.getCountryRegionContextField());
}
// If no context field is specified
else
{
// Get the Rec Id from the legal entity
partyRecId = CompanyInfo::find().RecId;
}
// Call our getEntityRegionISO function to find the ISO code for the entity
// and check if it is found in the container of region codes
isEnabled = conFind(dictTable.getCountryRegionCodes(), getEntityRegionISO(partyRecId)) > 0;
}
return isEnabled;
}
The function will return true if the table is enabled in the current context or if the table is not bound to a country/region. Note that this code uses the “getEntityRegionISO” function created earlier. If you are not adding these to the Global class, you will have to reference the class where that method resides (or add it as an inline function inside the method). Finally, we want a similar function that tests an individual field.
public static boolean isFieldCountryFeatureEnabled(Common _record, FieldName _fieldName)
{
DictField dictField = new DictField(_record.TableId, fieldName2id(_record.TableId, _fieldName));
boolean isEnabled = false;
DirPartyRecId partyRecId;
// First make sure the table is enabled
isEnabled = isTableCountryFeatureEnabled(_record);
// If that checks out, make sure we found the field and that is enbled in the configuration
isEnabled = isEnabled && dictField != null && isConfigurationkeyEnabled(dictField.configurationKeyId());
// Additionally, check if there are country region codes specified
if (isEnabled && conLen(dictField.getCountryRegionCodes()) > 0)
{
// If a context field is specified
if (dictField.getCountryRegionContextField() != 0)
{
// Get the Party Rec Id Value from that field
// TODO: could do some defensive coding and make sure the field id is valid
partyRecId = _record.(dictField.getCountryRegionContextField());
}
// If no context field is specified
else
{
// Get the Rec Id from the legal entity
partyRecId = CompanyInfo::find().RecId;
}
// Call our getEntityRegionISO function to find the ISO code for the entity
// and check if it is found in the container of region codes
isEnabled = conFind(dictField.getCountryRegionCodes(), getEntityRegionISO(partyRecId)) > 0;
}
return isEnabled;
}
The function behaves similarly to the table function, and in fact it calls the table function first. Note that this means the code depends on the “isTableCountryFeatureEnabled” and the “getEntityRegionISO” functions created earlier. If you are not adding these to the Global class, you will have to reference the class where that method resides (or add it as an inline function inside the method).
So now, feel free to test these methods on our previously created fields. Sure hope it works =)
There is no comment section here, but I would love to hear your thoughts! Get in touch!
Blog Links
Blog Post Collections
- The LLM Blogs
- Dynamics 365 (AX7) Dev Resources
- Dynamics AX 2012 Dev Resources
- Dynamics AX 2012 ALM/TFS
Recent Posts
-
GPT4-o1 Test Results
Read more... -
Small Language Models
Read more... -
Orchestration and Function Calling
Read more... -
From Text Prediction to Action
Read more... -
The Killer App
Read more...