Hi there,
I hope you are ready for a long and restful weekend. Certainly, I'm as this has been a tough week with lots of new challenges and lots of new learning, which is great.
On this post I would like to point out a very interesting post about using delegates in Microsoft Dynamics AX 2012. The post was written by Marcos Calderon, who works for Microsoft as their SDE Lead.
In his post he starts by showing us how to create a delegate in Microsoft Dynamics AX 2012, then he explains what delegates are and why they are used. He also explains what Event Handlers are and their relationship to the AX 2012 AOT.
Finally, he give us an example on how to add an event handler programmatically in X++, and how to publish the subscriber into the same tier for later use.
From the post:
"...X++ delegates expose the publisher -subscriber pattern where a delegate defines a clear contract in a publisher class. This contract is used when an event occurs where the event can be a change of state, where all interested classes receive notification that the event has occurred."
You can access his post from here.
Well folks, that's all for now and until the next post!
Hi There,
I hope that your weekend went OK and that you are ready for another interesting article about AX 2012.
Today I wanted to talk a bit about Product Attributes in AX 2012. As we all know by now, with the introduction of AX 2012 things got a little bit more complicated when dealing with Product Categories and Attributes.
Categories in AX2012 are used to classify products, customers, and other type of data for
reporting and analysis. In addition, each category must have a parent , and child elements (you can learn more about it here).
On the other hand, Product Attributes in AX 2012 focus on the details that we want to maintain for certain products. Before you can create a product attribute, you must define an Attribute Type. Now the great thing about product attributes is that we can assign them from different modules of AX 2012, and the attribute will belong to that module only and not other (you can learn more about it here).
When trying to get a Product Attribute Value for a Product in AX 2012, it is important to understand that there are three main tables involved.
EcoResProductAttributeValue
EcoResAttribute
EcoResValue
The following code will help you get the Product Attribute Value:
public static AttributeValueText getItemIdAttributeValue(RefRecId _product)
{
EcoResProductAttributeValue ecoResProductAttributeValue;
AttributeValueText attributeValueText;
InventTable InventTable;
EcoResAttribute ecoResAttribute;
EcoResValue ecoResValue;
;
//We only query a level down the inventtable and just used the InventTable.Product RecId as a reference for ecoResProductAtributeValue
while select ecoResProductAttributeValue
where ecoResProductAttributeValue.Product == _product
join Name from ecoResAttribute
where ecoResProductAttributeValue.Attribute == ecoResAttribute.RecId
join ecoResValue where ecoResValue.RecId == ecoResProductAttributeValue.Value
{
attributeValueText = ecoResValue.value();
}
return attributeValueText;
}
If you notice, the only parameter we need in the example above is the Inventory Table Product Reference in order to find the correct value within the
EcoResProductAttributeValue View.
The alternative can be to use the Inventory Table in the query as well, and it will look like this:
public AttributeValueText getItemIdAttributeValue()
{
EcoResProductAttributeValue ecoResProductAttributeValue;
AttributeValueText attributeValueText;
InventTable InventTable;
EcoResAttribute ecoResAttribute;
EcoResValue ecoResValue;
;
while select InventTable where InventTable.itemid == this.parmItemId()
join RecId from ecoResProductAttributeValue
where ecoResProductAttributeValue.Product == InventTable.Product
join Name from ecoResAttribute
where ecoResProductAttributeValue.Attribute == ecoResAttribute.RecId
join ecoResValue
where ecoResValue.RecId == ecoResProductAttributeValue.Value
{
attributeValueText = ecoResValue.value();
}
return attributeValueText;
}
In the code above I'm using an Inventory Table Item Id and referring the selected record in the EcoResProductAttributeValue View.
Until the next post and have a great week.
Hi There,
I would like to share a great article about choosing the right ERP solution.
The article was written by Jen Dorsey and she is a Marketing Manager at Microsoft. In her blog, she presents 10 point evaluation items to take into consideration when choosing and/or evaluating an ERP solution.
You can access her blog from here.
From the post:
"Choosing the right enterprise resource planning (ERP) solution is a strategic investment for your company, so it's well worth your time to carefully examine your options...
...Business solutions from Microsoft feature a consistent look and feel that your people already know and work with. If they already know and use Microsoft Outlook, Word, and Excel, they will find the Microsoft Dynamics ERP user experience familiar and adopt it faster."
Until the next post!
Hi There,
I hope everyone is having a good week so far and that you are ready for another topic on AX 2012 R2. I was reading the AX 2012 R2 upgrade guide and it seems like a lot of information to process. Therefore, I thought on creating a summary of the complete AX 2012 R2 upgrade process through pictures and just a few words. As the saying says, a picture express a thousand words.
You can download the original document here, which is a very useful guide when it comes to upgrade to AX 2012, AX 2012 Feature Pack, and AX 2012 R2.
Moving right along, An upgrade from Microsoft Dynamics AX 2012 or Microsoft Dynamics AX 2012 Feature Pack to Microsoft Dynamics AX 2012 R2 is classified as an in-place upgrade. The great thing about this type of upgrade is that it does not requires source-to-target workflow, which is when we needed to upgrade an AX 4.0 instance to AX 2009 before bringing it to AX 2012, instead the upgrade is done directly into the source AX 2012 system, so look for upgrade XPO in your AX 2012 R2 setup files.
Create a Test System
Duplicate your existing production system to create the test system. You can accomplish this by copying a virtual machine image, or, alternatively, you can build a new system by using Setup from your legacy Microsoft Dynamics AX version, and then copying over the production database
Run the Microsoft Dynamics AX 2012 R2 Setup on the Test System
By running Microsoft Dynamics AX 2012 R2 Setup on the test system, you accomplish the three numbered tasks shown in the following picture.
Back up the Test System Model Store
Create a file backup of the model store. This backup is used during code upgrade of the models in the customer layer. i.e. AxUtil.exe exportstore /file:[full path of file and file name]
Back up the Test System Model Store
Create a file backup of the model store. This backup is used during code upgrade of the models in the customer layer. i.e AxUtil.exe exportstore /file:[full path of file and file name]
Create Development System
Duplicate the Microsoft Dynamics AX 2012 R2 test system to create the development system, which is used to upgrade customer models
Upgrade Customer Models
Customer models belong to one of the customer layers. In ascending order, these layers include the ISV, VAR, CUS, and USR layers. Code upgrade is performed by layer, meaning that each customer layer is upgraded separately, starting at the lowest layer and working up through the higher layers.
Upgrade Code on the Development System and Export the Upgraded Models
All tasks on the checklist have to be completed for each layer that contains models that require upgrade.
Import the Model Store Backup to the Development System
On the development system, import the backup of the model store that you made in the procedure “Back up the test system model store.” i.e. AxUtil.exe importstore /file:[full path of file and file name] /idconflict:overwrite
Import Upgraded Models into their Layers on the Development System
Import the upgraded model or models into the appropriate customer layers. Start with models from the lowest layer, then work up through the higher layers.
Repeat Code Upgrade for Each Layer
For each remaining layer that contains customized models, repeat the upgrade procedure, moving from the lowest remaining layer to the highest layer.
Export the Upgraded Model Store
Export the fully upgraded model store that you have created on the development system to a file. This file acts as the source of the upgraded customer models that are used to prepare for data upgrade first on the test system and later on the production system. i.e. AxUtil.exe exportstore /file:[full path of file and file name]
Import the Upgraded Model Store into the Test System
On the test system, import the model store file that you made in the procedure “Export the upgraded model store.” i.e. AxUtil.exe importstore /file:[full path of file and filename] /idconflict:overwrite
Perform Data Upgrade on the Test System
Upgrade Production System
On the production system, enter single-user model. All client users other than the administrator will be disconnected form the Microsoft Dynamics AX system at this point. This action starts the downtime window during which new business transactions cannot be processed.
Upgrade the Core Production System
Upgrade on the production system requires that you run Microsoft Dynamics AX 2012 R2 Setup on each computer in your deployment.
Upgrade AOS and Other Components
Run Setup on the production system to upgrade the core server and client components.
Perform Data Upgrade on the Production System
Complete the tasks on the checklist as described earlier in this how-to in the section “Perform data upgrade on the test system.”
Upgrade Additional Server Components
When data upgrade is completed, you can complete the upgrade of server components.
Upgrade Additional Clients
Run Setup on your additional Microsoft Dynamics AX client systems to upgrade the client software.
I hope this summary can serve you well as a snapshot of the complete AX 2012 R2 in-place upgrade. There is a lot to learn with this new release and I would expect lots of customer wanting to upgrade to R2 after Convergence 2013.
Have a great rest of the week and until the next post.
Hi There!
As we all very well know by now, the release of AX 2012 R2 (You can get more informtion about AX 2012 R2 on the What's New in Microsoft Dynamics AX 2012 for Developers) came to a reality last December, and I wanted to share the four most important business benefits of this release.
You can access the original post here, which was written by the Microsoft Dynamics AX Product Team.
New functionality for Industries and Administrative Processes
- Manufacturing: Improve manufacturing operations for process manufacturing. AX 2012 R2 introduces new capability for management of potency, traceability and product batch sequencing to help process manufacturing streamline operations.
- Retail: Assorment management across channels in your retail operations. New multi- and cross-channel capabilities for retail organizations, including catalogue management, cross-channel workflows, and integrated sales channel management will include a new “out of the box” web storefront.
- Public Sector: AX 2012 R2 simplifies the financial budgeting process in public sector organizations. By combining the power of Microsoft Excel with the power of the workflow engine inside of Microsoft Dynamics AX 2012, AX 2012 R2 supports new capabilities in budget formulation with workflow approvals, flexible tracking, and reporting.
- Professional Services: AX 2012 R2 improves in the intercompany scheduling capability of project resources will specifically benefit services organization with resources and projects across multiple entities and will improve utilization of your resources.
Improve Business Insights for all Users
New and updated KPI content is offered, and updated KPIs will come with the SQL BI cubes shipped with the release. These KPIs will surface on the different role centers.
Enabling the usage of the new Power view technology (You can learn more about this from the Murray Fife's post Creating PowerView Dashboards Against Dynamics AX 2012) introduced in Microsoft SQL Server 2012. This will help users to discover new insights through a highly interactive and familiar data visualization technology.
Increase Global Reach and Simplify International Operations
AX 2012 R2 has increased the global reach of Microsoft Dynamics AX 2012 by adding localization for 11 new markets (Brazil, Czech Republic, China, Estonia, Hungary, India, Japan, Latvia, Lithuania, Poland, and Russia), extending the reach for Microsoft Dynamics AX 2012 to support 36 localizations worldwide.
Simplify the Application Lifecycle for Customers
This goes from simplifying single instance international ERP deployment scenarios up to simplifying setup and functional implementation with new and improved lifecycle services.
Also, in AX 2012R2, we’ll see:
- The Code Analyzer that will help us analyze the performance of custom code based on rules in the design phase of an extension by customers or partners.
- The Data Migration Framework will support import, export and migration of data to/from Microsoft Dynamics AX 2012 in the deployment phase. It will cover over 20 scenarios including customer, vendor, product, employee, BOM, open sales and purchase order data, which can be extended by partners and customers.
- The Diagnostics Framework will assist by analyzing data collected from the installation’s servers based on rules in the maintenance phase.
It is really exciting to see all these improvements in new release, as it will add more value to customer acros the board and it will help AX 2012 R2 to be used in other countries based on the localization improvements.
Take care and until the next post!
Hi There,
I hope everyone had a great new year and that you are ready for a new one full of challenges, and good things.
In this post I would like to discuss how to create product and product masters in AX 2012. Sometimes our requirements vary depending on the customer, and more often than not, we need to provide a dynamic option to create either a product or a product master.
So, what is the definition of these two terms?
Product: This is the simpler of the two. They do not need product dimension groups when created.
Product Master: This type must contain product dimension groups; otherwise you’ll get a run-time error at the time the EcoResService is called.
The product dimension groups can be Color, Size, Style and Configuration. In addition, you can create any other dimension group. In my example, a user created a dimension group called “Revision”, which is the chosen one for this example. This shows how flexible AX2012 is around product dimensions.
The following code takes two parameters. One is the product name (which has a custom EDT), and the product sub type (is it product or product master). Further, to achieve this we will use the following classes:
EcoResEcoResProduct_TrackingDimGroup
EcoResEcoResProduct_Product_Master
EcoResEcoResProduct_Product_Distinct
EcoResEcoResProduct_ProductDimGroup
EcoResEcoResProduct_StorageDimGroup
EcoResEcoResProduct_translation
EcoResEcoResProduct_Identifier
EcoResProductService
The EcoResEcoResProduct_Product_Master (http://msdn.microsoft.com/en-us/library/ecoresecoresproduct_product_master.aspx) class is in charge of creating the new Product Master, and the EcoResEcoResProduct_Product_Distinct (http://msdn.microsoft.com/en-us/library/ecoresecoresproduct_product_distinct.aspx) class is in charge of creating the Product. These records are going to be created in the EcoResProduct Table.
As you probably know by now, even these records exist in the EcoResProduct table, they haven’t been release to AX just yet.
Moving right along, we will be using the EcoResProductService class (http://msdn.microsoft.com/en-us/library/ecoresproductservice.aspx) to actually create the product in the EcoResProduct Table.
/// <summary>
/// Creates a new product in EcoResProduct
/// </summary>
/// <returns>
///
/// </returns>
/// <remarks>
///
/// </remarks>
/// <exception cref="Exception::Error">
/// Throws error upon Exception.
/// </exception>
public static void CreateEcoResProduct(ProductName _ecmProductName, EcoResProductSubtype prodSubType)
{
EcoResEcoResProduct_TrackingDimGroup tracDimGroup;
EcoResEcoResProduct_Product_Master productMaster;
EcoResEcoResProduct_Product_Distinct distMaster;
EcoResEcoResProduct_ProductDimGroup prodDimGroup;
EcoResEcoResProduct_StorageDimGroup storDimGroup;
EcoResEcoResProduct_translation translation;
EcoResEcoResProduct_Identifier identifier;
EcoResProductService ecoProdSvc;
EcoResProductNumber lEcoResProductNumber;
NumberSequenceTable numberSequenceTable;
EcoResEcoResProduct ecoResProd;
EcoResProductType ecoResProductType;
boolean isMaster = false;
;
try
{
// create product by initializing the Service object
ecoProdSvc = EcoResProductService::construct();
// initialize the EcoResEcoResProduct object
ecoResProd = new EcoResEcoResProduct();
numberSequenceTable = EcoResProductParameters::numRefProductNumber().numberSequenceTable();
lEcoResProductNumber = NumberSeq::newGetNumFromId(numberSequenceTable.RecId).num();
ecoResProductType = EcoResProductType::Item;
if(prodSubType == EcoResProductSubtype::ProductMaster)
{
isMaster = true;
//Create a new product master
productMaster = new EcoResEcoResProduct_Product_Master();
//initialize product master
productMaster.parmDisplayProductNumber(lEcoResProductNumber);
productMaster.parmProductType(ecoResProductType);
productMaster.parmSearchName(_ecmProductName);
productMaster.parmVariantConfigurationTechnology(EcoResVariantConfigurationTechnologyType::PredefinedVariants);
//create a product master Translation Object
translation = productMaster.createTranslation().addNew();
// create a new identifier object
Identifier = productMaster.createIdentifier().AddNew();
// Create the ProductDimensionGroup
prodDimGroup = productMaster.createProductDimGroup().addNew();
prodDimGroup.parmProduct(lEcoResProductNumber);
prodDimGroup.parmProductDimensionGroup('Revision');
// Create the StorageDimgroup object
storDimGroup = productMaster.createStorageDimGroup().addNew();
storDimGroup.parmProduct(lEcoResProductNumber);
storDimGroup.parmStorageDimensionGroup("S-W-L");
// Create the TrackingDimGroup object
tracDimGroup = productMaster.createTrackingDimGroup().addNew();
tracDimGroup.parmProduct(lEcoResProductNumber);
tracDimGroup.parmTrackingDimensionGroup("none");
}
else
{
// Create a new product distinct master
distMaster = new EcoResEcoResProduct_Product_Distinct();
// Take the newly created and initialize ProdMaster - variable and fill with product data
distMaster.parmDisplayProductNumber(lEcoResProductNumber);
distMaster.parmProductType(ecoResProductType);
distMaster.parmSearchName(_ecmProductName);
// Create a translation object
translation = distMaster.createTranslation().addNew();
// Create a new identifier object
Identifier = distMaster.createIdentifier().addNew();
// Create the StorageDimgroup object
storDimGroup = distMaster.createStorageDimGroup().addNew();
storDimGroup.parmProduct(lEcoResProductNumber);
storDimGroup.parmStorageDimensionGroup("S-W-L");
// Create the TrackingDimGroup object
tracDimGroup = distMaster.createTrackingDimGroup().addNew();
tracDimGroup.parmProduct(lEcoResProductNumber);
tracDimGroup.parmTrackingDimensionGroup("None");
}
// fill the translation object
translation.parmDescription(_ecmProductName);
translation.parmLanguageId('en-us');
//translati
translation.parmName(_ecmProductName);
// fill the identifier
identifier.parmProductNumber(lEcoResProductNumber);
// add the product to ecoResProd
if(isMaster)
ecoResProd.createProduct().add(productMaster);
else
ecoResProd.createProduct().add(distMaster);
// create the product using service
ecoProdSvc.create(ecoResProd);
}
catch(Exception::Error)
{
throw Exception::Error;
}
catch(Exception::Deadlock)
{
retry;
}
catch(Exception::UpdateConflict)
{
if(appl.ttsLevel() == 0)
{
if(xSession::currentRetryCount() >= 4)
{
throw Exception::UpdateConflictNotRecovered;
}
else
{
retry;
}
}
else
{
throw Exception::UpdateConflict;
}
}
}
Happy New Year and until the next time!