Saturday, 15 June 2013

AX2012 R2 : Creating product variants based on generic product model using X++

Hi Friends,
In one of my recent tasks, I was required to automatically create the product variants for a product master as per all the suggested product variants by the system based on generic product model. So I need to automate the below shown process which if done manually for all items will consume lot of time:

These variant suggestions are based on the defined product variants ( refer to my previous post to get technical understanding of tables storing this information here).

So I did some technical analysis and found the following:
  • The class used by standard AX to create variant suggestion is EcoResProductVariantCreationMgr.
  • It populates a temperory table to store all the variant suggestions, but by default is keeps the selected field as false.
  • The function filling this temperoary table is a buildVariantSuggestion() is a protected function, so I cannot call it directly from my code.
So there were few challenges in directly using this class from my job but with few simple customizations in this class, I was able to utilize this class for creating the product variants in a much simple way rather then re writing all the logic inside the class in my job. So I did the following changes:
1. Added a new boolean variable in class declartion and created a parm method for it. This is to initialize this variable when it is called from my custom code and tweak the way temperory table is created:
2. Changed to access modifier of the buildVariantSuggestion() 

3. In case the class is called from custom code then we need to mark the records as selected:

So with the above three modifications in standard AX class, I was ready to use this class in my job and I created the below sampe piece of job:

We assigned the EcoResProductMaster record in the args and used that to initialize the class, used the RecId of the productMaster to find the record.
Then we called the parmCalledFromJob method and set it as true to tell system that this class is trigerred from my custom code.
We called the buildVariantSuggestions() , as this is no longer protected I can directly call from my job [This design can be improved by creating a child class instead of changing the access modifier].

So now I ran the job  for the same product which I have shown in the first screenshot:

and then when we look at product variants, we see that system has created the product variants :)

P.S --> Before modifying EcoResProductVariantCreationMgr class, please check if this is not conflicting with any other modifications in your system. Especially modifiyng the access modifier is not a recommened thing to do always, however I did this as it was a one time job which we need to run and then reverted back the changes.

Sometimes it is much easy to tweak the standard AX objects and leverage the existing code instead of rewriting the whole logic.

Till my next post.....take care friends and keep sharing.


  1. Thanks...In my case, the job is creating product variants in the tables but is not showing on the product variant form..Any suggestions?

    1. Hi! Thank you for the blog!! I have the same problem...Fama, have you found a solution?

    2. Hi ,
      If you see that data is getting created in tables but not getting displayed on the form then probably check the records in table EcoResProductTransalation as this table is joined on product variants form. Sometimes records exists with different language Id. Hope this helps.

      Rachit Garg

    3. Hi,
      the variante is created ( show EcoResDistinctProductVariant) but not released
      - Go to : Product information management/Common/Products/All products and product masters
      - go to your product and Release your product in your Companie
      ( select all variants )
      And now you can use your new created variant

      if you want to release product by Code use this :
      EcoResDistinctProductVariant ecoResDistinctProductVariant;
      EcoResProductReleaseManagerBase releaseManager;

      //Get variant id
      ecoResDistinctProductVariant = ecoResDistinctProductVariant::find(ecoResDistinctProductVariantRecId);
      // Release Variant
      releaseManager = EcoResProductReleaseManagerBase::newFromProduct(ecoResDistinctProductVariant);

      Good luck

  2. Hi Fama,

    Check that the records in the tables EcoResDistinctProductVariant and other product dimension related tables like EcoResProductVariantSize, EcoResProductVariantColor and EcoResProductVariantConfiguration are having correct values in the fields which are used to relate them on the form. Also check that records exists in EcoResProdcutIdentifer and ecoResProductTranslation for the product with correct language ID.


  3. HI Priyanka,

    I have same problem of data. Data is available in all table which are mentioned by you.
    language is also same as"en-us" but still data is not displayed on form.

    Please suggest solution

    Thanks ,

    1. Hi Swapnil,

      I am having the same problem as yours i.e. no data on form though all data mentioned above are available in all tables.

      Did you find a solution?



  4. This post has vigence, today I test it and the result was very well.

    Well done Priyanka.

    1. Thanks Felix. Appreciate your words. Have a good day.

  5. Hi Priyanka,

    Is it a good idea to just replicate the buildVariantSuggestions() method? I don't want to change the access modifier of the standard method to prevent any conflicts from other standard classes who uses this method also.

    Great post by the way!


    1. Thanks Arnel, appreciate your feedback. I agree that changing access modifiers can have conflicts and have mentioned the word of caution in the article.
      Have a great day.