Product Configuration: Performance with Z3

Introduction

In the spring release of 2018 for Microsoft Dynamics 365 for Finance & Operations a significant investment in improving performance of the constraint evaluation has been made.

The result of this investment is the introduction of the Z3 sovler strategy. Z3 is a theorem prover from Microsoft Research, that has won several awards and has an active open source community.

The Microsoft Dynamics 365 for Finance & Operations team, teamed up with the Microsoft researches to develop new algorithms targeted at the Product configuration scenarios for Microsoft Dynamics 365 for Finance & Operations.

Microsoft Dynamics AX 2012 R3

The Z3 solver strategy is also available for Microsoft Dynamics AX 2012 R3 with the following KB article numbers:

  • 4341629 - Additional performance improvement of loading models
  • 4046549 - Performance improvement of loading models
  • 4034024 - Fix to support customization related to system defined table constraints
  • 4012892 - Introduction of the Z3 Solver strategy

Usage

The applied solver strategy for a product configuration model is selected by accessing the Model properties form.

From the Model properties form the Z3 solver strategy can be selected as illustrated below:

The Z3 solver strategy will currently not have a functional impact, the impact will be on performance.

 

 

 

Product Configuration: Multi-column dialog layout

In the spring release of 2018 for Microsoft Dynamics 365 for Finance & Operations, Multi-column layout is now available for the Product configurator’s runtime dialog.

To enable this functionality, select a model and open the Model properties form.

In the Model properties form, there is now a new field Maximum number of columns. This field allows you to specify how many columns should be used display the attribute groups of each component of the selected product configuration model.

Now, when the model is loaded in the configuration dialog in Test or via any of the order forms (Sales, Purchase etc.) it will look like this:

With this feature more of the user interface real estate is being put to use, to providing a better overview of the attributes of the selected component.

 

I hope you find this useful

 

 

Microsoft Dynamics AX 2012 Product Configuration : Enterprise Portal

In this blog post I will explain how on user interactions are handled by the product configuration module for Microsoft Dynamics AX 2012 on the Enterprise portal.

EP_1

 

 

The figure above, is a high level illustration of how user interactions in general are processed on the Enterprise Portal (EP) for Microsoft Dynamics AX 2012. The clients access the AOS through EP, which is a web implementation built on top of Microsoft Sharepoint, hosted on a web server (IIS). The communication between EP and the AOS is synchronous using the .NET Business Connector RPC call. Each RPC call must be completed and returned, before http request timeout is exceed on the IIS.

To understand what implications the above has, when using the Product configuration module, we will go through the sequence of events, which take place when the user loads a configuration model and assigns a value to an attribute.SequenceDiagram_EP

The above illustrates the sequence of loading a configuration model and assigning an attribute a value on the Enterprise portal.

 

Loading a configuration model

 

When the user wants to configure a product, e.g. from a sales order, the requests will be handled by EP.  The EPPCConfigurator web control will be loaded, inside the web control a proxy Instance of the PCEnterprisePortalMain class is created. This proxy is used to interact with the AOS Product configuration logic.

On the AOS, the XML representation for the specific configuration model is retrieved from the database. Then the XML string is passed as argument to Product Configuration Server API, which unlike the Client API is design to support synchronous execution. In the creation of the ProductConfigurationServer instance, the XML is parsed and supporting data structures are created, just like on the Windows client implementation.

 

Once the data structures have been created, the configurator instance can start processing the constraints and calculations of the configuration model. Unlike the Windows client however, the processing on EP needs to respect a fixed time limit, in order not to cause a timeout on the web server.

 

Another difference between the Windows client an EP is the way the model is being processed. The EP implementation will attempt populate all visible enumeration and Boolean attributes. This is the equivalent of opening all the visible attribute controls on the active component in the form, and letting the configurator deduce feasibility of the values of each attribute.

The more attributes that are visible, the less time that is available to process each attribute. For components with over 20 enumeration and boolean attributes, it can happen that there is not enough time to process the feasibility of all values within the domain of the attribute.

 

Assigning values to attributes

When the user   makes an assignment to an attribute, the web form is then posted back to EP and  a request to assign the attribute is made on to the AOS. On the AOS, each call from EP executes in its own context, this implies that a new instance of the configurator is created. This instance must again parse the XML representation of the configuration model, before being able to process the user assignment. After this, the instance is disposed and a new one is created to process the assignment , same as before.

 

The main problem can be seen from the diagram in Figure 2, is the activation line of the ProductConfigurationServer object. Unlike the Windows client implementation , the configurator instance is not kept alive throughout the configuration session. The synchronous execution combined with the time limitation is the main limiting factor, which forces us to create and dispose instances of the configurator for each request.

 

The consequence of this is that the EP implementation of the configuration module, is not able to deliver a user experience which is similar to that of the Windows client for models of medium to high complexity.

 

Please keep this in mind when considering implementations of the Product Configuration module on Enterprise Portal for Microsoft Dynamics AX 2012.

 

 

 

 

Support for BOMs that includes items with different product dimensions of the same item

This blog post describes new functionality released with the Microsoft Knowledge base (KB) in article 3089402.
 
When using one or multiple of the product dimensions in production, you can have situations where you would like to produce an item, based on a different variant of the same item.
There are many scenarios where this can be useful, e.g.
•  A Green variant of a specific item that is produced using a white variant of the same item.
•  An item variant produced using a different configuration of the same item.
•  Large item variant cut into multiple smaller variants of the same item.
 
Until now it has been mandatory to use different items for the parent and child product respectively. If this was not the case, the user would get a warning from the BOM check that circular reference is not allowed. If the warning was ignored MRP might fail. This warning was caused by the fact that the level check and the BOM level calculation was done per item.
 
With KB3089402 you can use the same item as both parent and child in a BOM – as long as minimum one product dimension differs.

This means that an item can now have multiple levels. In this case:
•  Item A Config 1 is level 0
•  Item A Config 2 is level 1
•  Item A Config 3 is level 2

Required setup
Inventory model: To ensure correct costing, items with BOMs including variants of the same item must use standard cost.
BOM check: Circularity check strategy have to be set to ‘Optimize for high complexity’. The other option ‘Optimize for low complexity’ has not been updated, and will detect circularity for item variants produced from the same item.

High level KB changes
•  Update BOM level calculation for planning: Will include any used product dimensions (Configuration, Size, Color, Style).
•  A correct configured BOM will need to have at least one product dimension that differs. Blank is not a value. The product dimension that differ must be set on both parent and child item in the BOM structure.
•  MRP, Predetermine cost calculation, and Actual cost calculation (inventory closing) is updated to use item and product dimensions with the new BOM levels.

Important implementation note
Ensure that the reqItemLevel table is empty before the first MRP (Master Schedule) run. Any change, like creating or modifying an item, will generate entries to the table and as a result it will not be empty.
The simplest way to do this is to truncate the reqItemLevel table, and then run a full MRP (regenerative with no filters). Otherwise MRP will not generate any planned orders!

 
Q&A
Q: What dimensions are supported?
A: The Product dimensions: Configuration, Size, Color & Style
Q: Will this require additional setup?
A: Only adding the relevant product dimensions to the BOMs, and ensuring to use Standard cost as well as the Circularity check strategy Optimize for high complexity. Also notice the implementation note regarding reqItemLevel.
Q: Will BOM circularity be checked for local changes on Production and Batch orders?
A: No, this KB is not changing what triggers the circularity check, as this is beyond the scope of the KB.
Q: Will this KB address issues related to rework scenarios, where exactly the same item and product dimensions are both input and output of production/batch order?
A: No, rework is outside the scope of this KB.
Q: What is the impact on performance?
A: Impact is none or minimal for both circularity check and MRP. There is a bit more data to process, but information is now stored outside InventTable. MRP tasks are per Product and BOM level, so multi thread of products with variants on different BOM levels is possible and can give minor performance improvements. Our tests have shown less than 5% change in performance based on this KB.
Q: Can I produce a specific variant from “any variant” – e.g. a Red variant from any (Blank) variant of the same item?
A: No, blank is not a value. The product dimension that differs must be set on both parent and child item in the BOM structure. So in this example you will have to choose a color for the used component.
Q: Will the BOM level calculation be stored in the same location for both Planning and Costing?
A: No, that changed with this KB. Costing will continue to use the current BOM level calculation stored in the InventTable. For planning (MRP) a new table is created to store the BOM levels with both Item and Product dimension information. This design will make it possible in the future to differentiate the processed data for Planning vs costing, e.g. ensuring that ended production orders are not included in BOM level calculation for MRP planning.
Q: Will the BOM consistency check uptake support for product dimensions as well?
A: Yes, with Circularity check strategy set to Optimize for high complexity.
Q: Does this mean that we now have the same options for product dimensions as for items?
A: No, but this is a step on the road to full variant support in AX – and a very important step 🙂

T-Shirt example with screenshots
A Green variant of a T-Shirt item is produced, using a white variant of the same item.

First we set the Circularity check strategy to Optimize for high complexity. Optimize for low complexity does not support BOMs that includes items with different product dimensions of the same item.

Create new T-Shirt item with Product dimension for Size and Color, using standard cost

Define size and colors for the product

Create all the variants for the product. We now have 9 variants of the T-Shirt:
 – Size: Small, Medium and Large
 – Each size in the Color: White, Red, Green

We can now create a BOM for producing a medium green T-Shirt, using a medium white T-shirt

The Circularity check will pass, since the color dimension differ

Say we made a mistake and tried to produce a medium green T-shirt from the same medium green. Then we would get an error, indicating that we have a circularity loop in our BOM:

Let’s modify the item coverage to ensure that the white T-Shirt is purchased. The green T-Shirt is produced and with a minimum of 3 to trigger a supply when running MRP

Now let’s run MRP and look at the planned orders generated for the T-Shirt

Notice that we get planned orders to produce 3 medium green T-Shirts, and purchase 3 medium white T-Shirts. Also, looking at the Explosion, you can see that the two colors have different levels

Product Configuration Synchronous Execution

This blog post describes an new way of interacting synchronously from code with the
Constraint-Based Product Configurator which has been introduced in Microsoft
Dynamics AX 2012 R3 CU8.

 

Scenario

The scenario that drove the introduction of this feature can be described as follows:

 

An external 3rd party sales configurator outside of Microsoft Dynamics AX 2012 is used to
assign values to a subset of attributes(a partially configured order), from
which the remaining mandatory attributes can have their values deduced using
the Microsoft Dynamics AX 2012 Configurator, thereby completing the order.

 

 

Once the all the values have been deduced, assuming all values are valid, they can be passed on
to the back end configuration module, which will create the BOM and potentially
the Route (if the model has a Route).

 

Implementation

Included in Microsoft Dynamics AX 2012 R3 CU 8 is a new derived version of the PCRuntimeConfigurator class, named PCRuntimeSynchronousConfigurator.

This class is designed, as the name indicates, for synchronous interaction with the .NET
Configurator component.

 

The configure method on the class is the method
which exposes the new functionality added to the .NET Configurator to Xpp. The
method takes three arguments; the model as xml, the attribute assignments as
xml and a the number of milliseconds which can be used before a timeout occur.
The return of the method is a IsConfigurationComplete enum value, from which
result of the configuration can be determined;

 

  • Complete
    • The configuration is complete
  • Incomplete
    • One or more mandatory attributes does not have a value
  • Timeout
    • The configurator was not able to complete the configuration within the given timeout limit
  • Contradiction
    • One or more constraints have been violated

 

Note:

The PCRuntimeSynchronuosConfigurator class exposes
the functionality required by the .NET configurator component to support the
above scenario but it is not yet integrated with any order (sales, production
etc) or product variant creation nor is it integrated with the BOM and Route
generation.

 

KB Article with number 3028719 should be Applied on top of R3 CU 8 as it addresses a stability issue in the solution.

 Example

 In this example values are passed from the simulated 3rd party configurator into Dynamics AX 2012 through a web service, as illustrated below:

 

 

To expose the PCRuntimeSynchronousConfigurator class through
a web service, we start by introducing a new class
PCTechDemoService
which implements a method with the SysEntryPointAttribute code attribute, which is
needed for a method to be exposed as a web service.

 

In this simple implementation the example method looks like this:

 

[SysEntryPointAttribute(true)]

public boolean configure(PCName _modelName, str _xmlValues)

{

    boolean ret;

    str values;

 

    PCRuntimeSynchronousConfigurator configurator  = PCRuntimeSynchronousConfigurator::construct();

    PCProductConfigurationModel productConfigurationModel  =  PCProductConfigurationModel::findByName(_modelName);

    values = ‘<Assignments>’ + _xmlValues  + ‘</Assignments>’;

   
if(configurator.configure(productConfigurationModel.getXML(), values,120000) == Microsoft.Dynamics.Ax.Frameworks.Controls.ProductConfiguration.IsConfigurationComplete::Complete)

    {

        ret = true;

    }

 

    return ret;

}

Now we can create a Service in the AOT which uses the PCTechDemoService
class and its configure method as an operation. To use this service, it needs
to be put in a service group, which can then be deployed.

 

 

To test the service, navigate to System administration > Services and Application Integration Framework > Inbound ports. Here we find our new PCTechDemoServiceGroup, copy the WSDL URI value.

 

 

 

Open Visual Studio Command prompt and type:

Wcftestclient <Your WSDL URI>

 

This will open the WCF test client where we can now see our web service.

 

For the demo data set I have used, I will use the following argument values

 

_modelName : 20001

_xmlValues : <Assignment xPath=”powerCableLength” value=”10″/><Assignment xPath=”videoSystem/television/size” value=”42″ />

 

Note: the xPath mechanism used to identify the attributes in model.

 

 

If you are familiar with the 20001(Home theater system) model, you will know that it has just two
mandatory attributes which are not assigned by defaults; the powerCableLength
on the root component and the size on the television component.

 

Attached you will find an Xpp project with code used for the example.

 

Enjoy

 

 

 

Demo.zip

Product Configuration Performance : Solver strategy

This post is part of the series of posts explaining performance improvements introduced in
Constraint-Based Product Configuration in Microsoft Dynamics AX 2012 R3 CU8.

The Solver strategy concept was first introduced in Cumulative update 7 for Dynamics AX 2012 R2 and has been extended in Cumulative
update 8 for Dynamics AX 2012 R3. It now includes the following strategies:

  • Default
  • Minimal domains first
  • Top-down

What is a solver strategy?

Imagine you were given the task of solving a 100 piece jigsaw puzzle. How would you start?

A common solving strategy is to start with the edges and move towards the middle, most of us
will either have done this ourselves or if not it should be pretty simple to
convince yourself that this strategy is sound.

 

Now, what if the puzzle you have to solve does not have straight line edges (often referred to
as impossible puzzles)? Suddenly our edge-first strategy will be dramatically less efficient as the edges are much more difficult to identify.

 

For the Solver, a configuration model is a bit like a jigsaw puzzle which needs to be solved.
With the Solver strategy concept, we have enabled you to set the strategy which
the solver will use when it solves the model. Configuration models can however
be very different in nature and the strategy for solving one model efficiently
may prove to be inefficient to solve a different model.

What is the impact?

The impact of response times has been shown on real customer models, to go from minutes to
milliseconds. For this reason it is really worth your time to spend a few
seconds to change this one setting, to see if a change in Solver strategy could
have this impact on your configuration model.

You can change the Solver strategy setting in the model properties form.

Which strategy to choose

Currently there is no build in logic which automatically detects which solver strategy will be most efficient, so for now, you will have to try them out.

Default

What can be said about the different solver strategies is that the default Solver strategy has been optimized so solve models which rely on table constraints. On all the customer models we have seen which use table constraints to a large extend this
solver strategy has proved to be the most efficient.

Minimal domain first and Top-down

These two strategies are closely related. The Top-down strategy, which has been introduced with CU 8 has shown to outperform Minimal domain first in all of our studies, but for
backwards compatibility we have decided to keep the minimal domain first strategy
in the product. Both of these strategies have shown to be more efficient for
solving models which contain several arithmetic expressions and where table constraints are not used. However, there are still examples where the default solver strategy will out perform these, so remember to try each.

Product Configuration: Setting values based on system variables – example, current user ID

In this blog post we will describe how you can  set values
based on the current user ID by leveraging system-defined table constraints
together with the build-in query range methods.

 

If you are familiar with the Product Builder configurator,
you may by familiar with the User Profile
feature where you can associate a collection of default values with a given
user. Use the following description to achieve a similar behavior using the
Product Configurator.

Creating the System Table

 

The table we create for this example should look like this and have two columns, that is, one for
the User ID (uses the  UserID EDT) and one for our user-specific value (an Integer to keep it simple).

 

 

 

Once the table is created, we can add the user specific data.

 

As seen above, we have added the value 42 for the Admin
user ID. The intention is that when the table constraint is created and used in
model, the attribute, which will be bound to the UserSpecificIntegerValue
column, will be assigned the value that corresponds to the current user ID.

 

Creating the Table Constraint

Now that the System Table is created, we can create the actual table constraint. This is done by
opening the Table constraint definition
form, under Product information management -> Common -> Product configuration models.

Create a new table constraint by clicking the new button.

 

Select System defined, and enter the name of the table created previously.

 

Add a column for the user-specific integer value and choose an integer attribute type with ranges.

  

Now comes the part which gives the attribute a user-specific value. This can be accomplished by
opening the Select query (SysQuery) form and entering the range specified
below. The content of the table will be filtered to just return the records
associated with the current user ID.

 

Click OK to complete the table constraint creation, click Next in the Wizard, and then click OK again.

Using the system-defined table constraint in a Product configuration model

Having just created our system-defined table constraint, we are now ready to use it in a Product
configuration model. Below I have create a very simple model with 3 attributes:

  1. One integer attribute to hold
         the user-specific value
  2. Two boolean attributes for
         each of which I will be using the Hidden modifier with a condition
         expressing that the attribute is only to be shown if the user-specific
         value matches that of the current user. 
         The “Only Admin” attribute will be hidden if the user
         specific value is different from 42.

 

 

Similarly, I have added an attribute named “Only Dmitry”, which only will be
visible if the user log on to Dynamics AX is associated with User ID Dmitry.

 

Once the attributes have been defined, it’s time to attach the table constraint to the
model. This is done by creating a new constraint in the constraints section and
selecting Table constraint in the opened dialog.

Then select the new table constraint and associate the user-specific value attribute with
the user-specific value column, as shown below.

 

Launching the model and understanding the results

We are now ready to launch the model we created with the attached table constraint. As can be seen
below, once the model is loaded, the User Specific Value is assigned the value 42 by the configurator. The “Only
Admin” attribute is shown and the”Only Dmitry” attribute is hidden.

 

 

This example can be extended to include several other concepts like hiding subcomponents and
grouping user specific value into table constraints. An obvious use case would
be that you hide some parts of the Product configuration model from the order
takers (Susan persona). This could be engineering-specific details and the
product designer (Emil persona) would still be able to see them.

 

Furthermore, the above pattern can be used together with other of the build-in query range
methods.

 

  • currentCompany
  • currentLanguageId
  • currentUserLanguage
  • currentLegalEntity
  • currentParty

 

Note:

It you are running
on a build that has a performance fix to run the XML generation in IL, you will
need to generate IL for the SysQueryRangeUtil class.

 

I hope you find this useful 

 

 

 

PrivateProject_MyUserSpecificValuesDemo.xpo

Supply chain excellence in manufacturing

Today I had the opportunity to take part at a Master Class on Supply chain management with Professor Martin Christopher from Cranfield University, Bedford, UK. The master class was hosted by Implement Consulting and the attendants were coming from all Industries in Denmark.

 

Professor Christopher succeeded to draw a relevant picture of the future trends and challenges to global supply chain management and to manufacturing in particular, and I would like to share a couple of quotes and thoughts.

 

  • Move from forecast driven to demand driven – Instead of planning to replenish inventory, establish supply chains that allow you to fulfill demand as a single event.
  • For products, where individuality and responsiveness are relevant, the agile supply chain – and the agile manufacturing process – must be designed for responsiveness,      not for the lowest cost. Responsiveness has to be built in the process and comes with a certain cost.
  • Substitute information for inventory – sharing information on demand and supply chain execution across the supply chain helps reducing or even eliminating inventory.
  • Flexible capacity – Move from static capacity to flexible capacity models, that allow to scale according to actual demand. Instead of acquiring manufacturing and distribution capacity based on forecast before the fact, a now model of
         acquiring capacity options that can be used on specific actual demand is emerging in the markets.
  • Economics of scale vs. Economics of scope – Instead of the volume of products, the bandwidth of products that can be delivered out of a supply chain drives the economic success.

 

It was an inspiring morning, leaving me with a lot of thoughts and ideas.

If you are inspired as well about these topics, join Roxana, Sverre and me at our session on Mass customization in a distributed supply chain in Microsoft Dynamics AX 2012 R2 at Convergence EMEA in Barcelona next
week, where we will share our vision on how the combination of product configuration, intercompany planning and lean manufacturing can bring you to the next level of supply chain excellence.

 

Understanding the default configuration concept for constraint-based products

Introduction

The default configuration concept enables users to start the product configuration process when the main product master data are available within a legal entity. You can learn more of the details of this concept in this post.

The default configuration concept

You must use the configuration technology Constraint-based when you configure product masters and the product masters must be configured with only one active product dimension, the Configuration dimension. We refer to the products masters as constraint-based products throughout this post.

To create a constraint-based product you must specify a valid product dimensions group which complies with this requirement.

image

Figure 1 Error message when the wrong dimension group is selected

You use the Configuration dimension to capture the final product configuration of a certain product model. The product model is represented in the system as a new product variant with a specific configuration dimension value. This is how Dynamics AX distinguishes between different results of the final product configuration. This allows you to complete a lot of tasks, such as:

  • Record and view on-hand inventory for individual configurations.
  • Run master planning against specific customer requirements (and across different legal entities).
  • Reuse existing product definitions in order to create products that are identical to existing products. You can also apply existing product definitions across legal entities.

Once you have released a constraint-based product to a legal entity, you can kick off a product configuration process from the following source document lines:

  • Sales order line
  • Sales quotation line
  • Project order line
  • Production order line
  • Purchase order line

The product dimension Configuration must have a value before you can start the product configuration process for a selected constraint-based product on an order line. Also, all active product dimensions must be specified before you can save an order line. These requirements are based on a series of technical solutions which are consistent with the experience that many users have from the Product Builder functionality.

Note – This is always the case for stocked products .For non-stocked products, you can specify a product category instead of defining the particular SKU.

The default product configuration concept is dedicated to solve the above described issue. It enables end users to proceed with the product configuration as soon as the product has been released to the legal entity.

clip_image003

Figure 2 The Default configuration is just there, after the product release

When a constraint-based product is released to a legal entity, the system automatically creates and releases a default product variant with the configuration value Default. The Default parameter is derived from the Default configuration ID field on the Constraint-Based product configuration models tab in the Product information management parameters form. This form is located under Product information management > Setup. The Default configuration ID value is set automatically during system installation. It references the SYS Label @SYS331038, but you can always change the value.

clip_image004

Figure 3 Product Parameters form

The process to create and release the default product variant is completely transparent and once the Default configuration ID parameter is set, no further action is required. If the product is released to multiple legal entities, the same default product variant will automatically be released to all of those legal entities.

Once the default product variant is released to the legal entity, the system will also update the default product variant fields on the released product. The default configuration dimension value is provided when you enter the item number on the order line. Any end user can change this setup in order to, for example, always have a basic configuration of a specific product suggested on all order lines

clip_image005

Figure 4 The default product variant dimensions are set to match the Default Configuration ID

Summary

The default configuration concept makes it possible to start the product configuration process at the point where the main product master data are available within a given legal entity. In order words, it facilitates the first step in the overall process of configuring an order line and it goes without saying that the first step is a prerequisite to move on in the process. Thanks for reading.

Product Configuration – Physical data model for user selected values

A constraint-based configurator was shipped with Microsoft
Dynamics AX 2012. In this post, we will provide an overview of the data model
that is used to persist the values that you can select when you configure a
product using the constraint-based configurator.

 

 

 

 

At first glance, you will notice that there are several
tables involved. If you are not familiar with previous versions of Dynamics AX
and the Product Builder configurator, this might not surprise you. However, if
you are familiar with the Product Builder, you will know that the old
configurator persisted all user selections in one table, namely the
PBATableInstance Table. This implies that retrieving the user selected values
is not as simple as writing a select statement against a single table. In the
following, I will use a report as an example and show you how you can retrieve user
selections in tables.Building a report

The report** that we use as an example displays all the user
selected values that are related to the configurations for a given product configuration
model.

**Disclaimer:
The report is not performance optimized. The purpose of the report is solely to
illustrate traversal of the data structure.

 

In the report, each element is indented to show the
parent-child relationship between, for example, the HomeTheaterSystem root
component and the “Color” attribute. The “Color” attribute can be assigned
other values, such as “Red”, but in the data on which the report was executed
no such configuration existed.

Note: I have used the Contoso dataset.

Data requirements

The data required to build the report can be broken down
into three parts:

  1. Get the instances of the root component from a
    given product configuration model. Here we only want the instances that are
    created for product variants and not the ones that are created for configuration
    templates.
  2. Get the attributes and their user selected
    values for a component instance.
  3. Traverse the subcomponent instances recursively
    and repeat part 2.

 

Let’s take a look at how to retrieve the data requirements to
build the report. The following statements will meet the data requirements and you
can also see the table involved:

Get the instances of the root component from a product configuration model

 

 protected void
  provideDataForModel(PCProductConfigurationModel _productConfigurationModel)

{

   PCVariantConfiguration              variantConfiguration;

   PCComponentInstance                 componentInstance;

   PCComponentInstanceRootComponent    rootComponentInstance;

   PCClass                             rootComponent;

   // get all
  configurations made for the given product configuration model

   while select componentInstance

   // only get instances which belong to a variant configuration, not a configuration template

  join TableId from variantConfiguration

  where variantConfiguration.RecId == componentInstance.ProductConfiguration

  // find the
  root component instances of the selected model

  join TableId from rootComponentInstance

  where rootComponentInstance.ComponentInstance == componentInstance.RecId

  join  rootComponent

  where   rootComponent.RecId ==  rootComponentInstance.RootComponentClass

        &&      rootComponent.RecId == _productConfigurationModel.RootComponentClass

    {

        //  handle data for component

        …

    }

}

 

Get the attributes and their user selected values for a component instance

 

    PCComponentInstanceValue    componentInstanceValue;

    EcoResAttribute             attribute;

    EcoResAttributeValue        attributeValue;

    EcoResValue                 value;

    

    // get all attribute value assignments
  related to the component instance

    while select  value

        join TableId from attributeValue

        where  value.RecId == attributeValue.Value

        join TableId from componentInstanceValue

        where componentInstanceValue.RecId  == attributeValue.InstanceValue

        &&    componentInstanceValue.ComponentInstance  == _componentInstance.RecId

        join attribute

        where attribute.RecId == attributeValue.Attribute

    {

   // handle data for attribute and attribute value

    …

    }

 

The values as such are sub-typed to model their respective data type.

Traverse the subcomponent instances

 

   

    PCComponentInstance    componentInstance;

    PCComponentInstanceSubComponent  subComponentInstance;

 
    PCSubComponent  subcomponent;

    PCClass                  childComponent;

 

// get all the subcomponents that have been associated with values

while select component

        join TableId from subcomponent

        where  subcomponent.ParentComponentClass == _parentComponent.RecId

        &&    subcomponent.ChildComponentClass  == childComponent.RecId

        join TableId from subComponentInstance

        where subComponentInstance.SubComponent == subcomponent.RecId

        &&  subcomponentInstance.ParentComponentInstance == _componentInstance.RecId

        join componentInstance

        where componentInstance.RecId == subComponentInstance.ChildComponentInstance

    {

   // handle data for component

    …       

    }

 

 

Implementation of the report

 

The data in the report is hierarchical in nature because of
the relationship between components and subcomponents.

The report that we build includes the parent-child
relationship between a component and a subcomponent and it also includes the parent-child
relationships between, for example,  an
attribute and an attribute value. This data cannot be retrieved from Dynamics
AX using a single query[1]
so we will use a data provider to populate a temporary table. The table has the
following structure:



[1]
This is not completely true because in Dynamics AX 2012, each component is
brought about as a reference to the configured variant. Thus, you could
retrieve all the data and then resolve the parent/child relations once the data
is retrieved.

 

A quick explanation of why the fields are required:

  • ID : this is used because the report framework
    will not expose the RecId field of the temporary table
  • Name : this is the name, such as Color, that we choose to display for the
    element
  • Parent : this is a reference to the parent
    record ID that helps grouping the SSRS report hierarchically
  • UniquePath : this is used to distinguish the
    attributes that belong to subcomponents of the same type. The path will be
    unique since it describes the path from the root component to each element in
    the model.

 

For more information about how to build a simple
hierarchical report in SSRS, go to:

http://technet.microsoft.com/en-us/library/dd255243(v=sql.105).aspx

For details on the implementation, take a look at the
attached X++ project.

Enjoy

PrivateProject_PCSessionValues.xpo