Using the product configurator in integration scenarios

Product configuration in D365FO must happen through the user interface, as the product configuration form is the only piece of code that communicates with the solver, wrapped in a dll outside D365. The communication happens through JavaScript of a designated form control. This is not great if you want to create a configuration in integration scenarios.

In AX 2012 R3 CU8 a class was introduced to allow you to pass a set of attributes and values for these, and then get the solver to return the XML needed for processing in the backend engine. The class is named PCRuntimeSynchronousConfigurator and you can read a bit about it here.
Even though the solver dll basically is the same between AX 2012 and D365FO, this class didn't make it to D365FO. Well until now, where the class is included in 10.0.12.

So here is an example of how to generate configuration XML for the backend engine:
public static void main(Args _args)
{
PCProductConfigurationModel productConfigurationModel =
PCProductConfigurationModel::findByName('High End Speaker (D0004)');

str modelXML = productConfigurationModel.getXML();

System.String values;
values = '<Assignments>' +
'<Assignment xPath="CabinetFinish" value="Black"' +
'<Assignment xPath="SpeakerHeight" value="12"' +
'<Assignment xPath="FrontGrill" value="Metal"' +
'<Assignment xPath="CornerProtection" value="true"' +
'</Assignments>';

PCRuntimeSynchronousConfigurator configurator = PCRuntimeSynchronousConfigurator::construct();
configurator.parmSolverStrategy(productConfigurationModel.getSolverStrategy());

Microsoft.Dynamics.Ax.Frameworks.Controls.ProductConfiguration.IsConfigurationComplete isConfigurationComplete;

isConfigurationComplete = configurator.configure(modelXML, values);

if (isConfigurationComplete ==
Microsoft.Dynamics.Ax.Frameworks.Controls.ProductConfiguration.IsConfigurationComplete::Complete)
{
str configuredProductXML = configurator.getAllAssignedValues();
}
}
Of course you could also previously do what the "new" class does, but it would have been an unsupported and undocumented call to the solver dll and Microsoft could change the dll without any prior notice.

In the class, the attributes are loaded this way:
    ...
configuratordll.LoadAttributeValuesByXPath(values)
...
There are a couple of other ways to pass the attributes and values to the solver dll, but they are not supported as no standard X++ code uses these:
    ...
configuratordll.AssignAttributeValueByXPath('CabinetFinish', 'Black');
configuratordll.AssignAttributeValueByXPath('SpeakerHeight', '12');
configuratordll.AssignAttributeValueByXPath('FrontGrill', 'Metal');
configuratordll.AssignAttributeValueByXPath('CornerProtection', 'true');
...
And
    ...
configuratordll.AssignAttributeValueById(2, 'Black'); // Cabinet finish
configuratordll.AssignAttributeValueById(5, '14'); // Speaker height
configuratordll.AssignAttributeValueById(3, 'Metal'); // Front grill
configuratordll.AssignAttributeValueById(4, 'true'); // Corner protection
...

If you need to implement something like this, I encourage you to check out this flow diagram on docs:
https://docs.microsoft.com/en-us/dynamics365/supply-chain/pim/build-product-configuration-model#pcadaptor-class
It would be nice if more things were documented with flow diagrams like this.
Comment List
Related
Recommended