Products with missing attributes

Last year I was creating an interface for products and their attributes. The funny thing was that the attributes did not appear in the interface, but on opening the form, all the attributes were there. So one begins to think what is going on! Where are my missing attributes?

To get to the bottom of this I used the view EcoResProductAttributeValue which is the default view in Ax (365). To my surprise, the data was also not there in this view.  Once one opens the form EcoResAttributeValue, the values will show up in the view EcoResProductAttributeValue.

It took me some time to understand what was going on. The first issue was that the data (conversion from AX 2009) did not have a EcoResProductInstanceValue record for every product. This one was easy to solve, by looping through the EcoResDistinctProduct and simply create the required EcoResProductInstanceValue.

EcoResProductInstanceValue EcoResProductInstanceValue;
EcoResProduct EcoResProduct;while select EcoResProduct notexists join EcoResProductInstanceValue
where EcoResProductInstanceValue.Product == EcoResProduct.recid
{
EcoResProductInstanceValue::findOrCreateByProduct(EcoResProduct.recid);
}

 

But this still did not solve my attribute issue. I investigated the EcoResAttributeValue form, and, ‘oh dear’…. this form generates data on opening.

I did not expect this kind of horrible code standards in AX7! On this form, the methods attributeChanged and createValue are used to generate the missing data. My first attempt was the below code, which I snatched from the form and added to my class

EcoResAttribute ecoResAttribute;
EcoResDistinctProduct callerMasterOrDistinctProduct;while select callerMasterOrDistinctProduct
{
while select ecoResAttribute
{
this.attributeChanged();
}
}

 

So whilst I was happy, the consultant and the customer were not L.

All the different types of attributes appear on my product.

So the next question is how can this be filtered, meaning how does AX (365) know which attribute there should be created.

Investigating this one, it could be seen that the attributes to be created are related to the category to which my product is allocated. Looking at table EcoResCategoryAttribute, resulted in finding a lot of missing records a majority of the products.

This means we have a product, we have a category and we know the category has attributes but there is no EcoResCategoryAttribute. There is a simple call to get data for this one

EcoResCategory EcoResCategory;

while select EcoResCategory
{
EcoResCategoryAttributeLookup::synchronizeWithCategoryAttribute(EcoResCategory);
}

 

This EcoResCategoryAttributeLookup table is used on a lot of places in AX (365), which we can assume is the case for performance reasons.

So finally I was able to create the attributes. Be careful to get the attributes with the default values!

final code

EcoResCategory EcoResCategory;
EcoResProductCategory EcoResProductCategory;
EcoResCategoryAttributeLookup EcoResCategoryAttributeLookup;while select EcoResCategory
{
EcoResCategoryAttributeLookup::synchronizeWithCategoryAttribute(EcoResCategory);
}

while select callerMasterOrDistinctProduct
{
while select ecoResAttribute exists join EcoResCategoryAttributeLookup where
EcoResCategoryAttributeLookup.Attribute == ecoResAttribute.RecId
exists join EcoResProductCategory where
EcoResProductCategory.Category ==  EcoResCategoryAttributeLookup.Category &&
EcoResProductCategory.Product == callerMasterOrDistinctProduct.RecId
{
this.attributeChanged();
}
}

 

Comments1

Leave a Comment!

Your email address will not be published. Required fields are marked *