Saturday, 21 June 2014

Quick Tip: AX 2012 InfoPart Properties

So this post seems a bit basic. I am not going to show you how to make info parts, but there is a property I want to point out. In the List Page once you add the display menu item that points to the info part (Figure 1), go to the properties of that part and change the IsLinked to Auto and Data Source Relation to SelfLink (Figure 2). These properties help the info part update according to the selected record.
Figure 1   
Figure 2

Wednesday, 18 June 2014

AX 2012 R3 Demand Forecasting Basics

The two big features of the R3 release has clearly been the TMS and the new WAX. Unfortunately, Demand Forecasting a requirement for supply chain planning has also been added to  R3  . It is the first time we are seeing Demand Forecasting in any Microsoft Product, with a clear shift in the ideology to focus on the Supply Chain. In this post first i want to discuss the practice demand forecasting in the the supply chain, and then compare this with the functionality in AX 2012 R3. This will serve two purposes, not only will the rather hazy subject of forecasting be clarified, it will also shed light on how functional consultants can customise the module to make it more advanced.

Demand Forecasts the result of taking historical demand data from the company in forming the future plans for true predicted demand. To this effect the levels which forecasts can be made can determine the accuracy of the forecasts. The requirement is also dependent on company policy and at what level procurement is done.
  • Customer Level
  • Product Level
  • Product Group 
  • Territory
  • Region
  • Corporate Level

Before we look at the techniques of forecasting from a academic perspective, let me first discuss how to setup the demand forecasting module in AX 2012 R3.

Within the Master Planning Module traverse down to setup and Demand Forecasting Parameters. The form you should see can be seen in Figure 1.

As you see the Demand Forecast Unit is the first field that has to be defined. It is the unit in which the AX will calculate the forecast. The next two cubes are the Demand Forecast Intitial, and Demand Forecast Initial Accuracy cubes that have to be deployed to the Analysis Server. The deployment is a prerequisite for the Demand Forecasting. Demand Forecasting is AX is based upon the SSAS Forecasting algorithm that has been around for years within SQL Server but only now being introduced in R3.

Fourthly a path has to be defined where AX can output the excel file of forecasted values.

The next selection allows the user to define from what type of historical data should the forecast be based on. The options include almost all the modules in AX where items can be consumed.

The Forecasting algorithm section is the most important. There are two options to use the copy from historical data and SSAS Time Series forecasting models.

Copy from historical data only creates the forecast baseline from historical data, while the SSAS options does the same using the SSAS time series algorithm.

For more information on the SSAS Time Series Algorithm check out visit MSDN . In the event that this SSAS method is chosen then the user has the opportunity customising it by adding and removing features, but it is optional. Furthermore it requires thorough understanding of the algorithm .

The next setup is to define the detail of the forecast, as mentioned in the first list of this tutorial.

As you see the available dimensions in AX 2012 are unto the best practices of Demand Forecasting, thus finding a connection between academia and industry. The next and final stage of the setup is to define the Item Allocation Keys; to set up the items for which the forecast will work. Again you can define the algorithm parameters and transaction types for each allocation key group if necessary. Stay tuned for more on Item Allocation Groups.

Item selection is critical to demand forecasting. Practically it is not feasible to forecast and plan the supply of all the items. Thus the general practice is to use Pareto Analysis and ABC classification to determine which products are worth forecasting. It is a fact that forecasting is very time consuming and generally considered to be incorrect. In this regard AX is lacking. There is no functionality that is in built that can maintain ABC classification of products. Using the historical demand a simple functionality can be developed to update the ABC classification on a periodic basis. This will help reduce the time that is required by forecasters or planners. Another addition that can be made to AX is the use of Mean Average Deviation (MAD) to further classify products. After generating the baseline forecast, the forecast accuracy feature in Master Planning will calculate the Mean Absolute Deviation (MAD) for the historical demand and forecasts. With a little customisations it is possible to use this data to then reclassify products according to ABC to pinpoint the items which have the most deviation and then subsequently find a solution.

Hypothetical Solution

  1. Import the MAD figures into a table in AX 
  2. Run a activity to reclassify the ABC of specific products according to MAD (This can be a bi weekly or monthly activity)

Items with the most deviation will require tighter control on the ordering policies so they could potentially be promoted to the higher category.

Note Another perquisite to any of the features in the Master Planning Modules is to first set up the Intracompany Planning Groups.

Monday, 26 May 2014

AX 2012 R3 Installation Tips

Hello Everyone

I have not been active on this post for almost 9 months now but now I am back.

So let's jump into AX 2012 R3.

I started the installation today on  a brand new virtual machine.

Windows Server 2008 R2 SP1
SQL Server 2012 SP1
SharePoint 2013

One point I want to add is that Windows Server 2012 RTM is not compatible with SharePoint 2013. For that you need slip stream version SharePoint 2013 SP1 available on MSDN.

I made one rookie mistake that i want to make sure everyone else avoids because it is a huge pain. When installing the database do not select the the foundations upgrade model without also selecting the check box "that makes t the AOS and Database also ready for upgrade"

If you make this mistake the application will not synchronise.

I simply uninstalled the Database, AOS, and Client and started over.

The next step is to import the Demo Data in Microsoft has again thrown a curve bowl by making developer download the Import Export Data transfer tool from information source.

The next post will be on importing demo data into the AX system so stay updated with me.

Saturday, 7 September 2013

AX 2012 Operations and Job Scheduling Discrete Manufacturing

In AX 2012  there are two types of scheduling.

  1. Operations Scheduling - Long Term scheduling a resource group level.
  2. Job Scheduling - Specified at resource level, used for short term scheduling. The operations are split into their specific jobs, and the resources for the operations are planned.

Both types of scheduling enable you to schedule multiple production ions in the order of their assigned priority. 

Before Scheduling a production, the organization has to determine wether production should be scheduled backwards or forwards. Production Scheduling parameters can be found on the job scheduling or operations scheduling form. That can be found under Periodic  or under the production order list page action pane under the Scheduling Tab.

Forward from Scheduling Date

This direction of scheduling will schedule the production from the earliest start date and scheduled to the earliest possible end date.

Backward Scheduling from Date

AX 2012 will schedule the production as late as possible keeping in mind the delivery date of the production order. It is based on the latest end date the date the production order must be completed then the start date is calculated going backwards.

Factors that influecne scheduling

Infinite / Finite Capacity 

If you remember when we were setting up resources in a previous post there was a parameter for Finite Capacity.  This parameters comes into play when scheduling is run. Infinite capacity does not take into account any of the previous capacity reserved for existing production orders.

Finite capacity dictates that the total load on the resource should not be greater than the capacity of the resource

Efficiency on Resources

Efficiency of a resource will determine the scheduling of the production order. Efficiency is set on the Calendar or directly on the resource.  The efficiency is factored into the available capacity of the organization.

Scheduling Time = Time * 100/Efficiency%

Common Confusion

I want to touch on something that can be confusing for beginner at production in AX 2012.

Under the general tab in the resources form we see the Finite Capacity property under the scheduling tab and the Capacity Unit field under the capacity group. 

These two fields are not related. 

Finite Capacity is related to the available time as per the calendar that is attached on the resource. 

Capacity is unit is used for the costing purposes for the operation.

Back to the Topic at hand.....

Finite Material

Using this tab the production is scheduled according to how much material availbale.

Tuesday, 3 September 2013

Traverese through Set with SetIterator - X++ AX 2012

Today we are going to go over the Set Class in AX 2012.

The MSDN definition is "The Set class is used for the storage and retrieval of data from a collection in which the values of the elements contained are unique and serve as the key values according to which the data is automatically ordered."

Scenario : We are going to Set with grids. So whenever the record is selected in a grid a record is added to the set. Set, Lists, and Maps are all similar, because they all are used for storage and retrieval of data. The benefit of using sets, is that we can avoid duplicate values in sets.

Further we are going to use the Set Iterator to traverse through the Set.

Since we are going to use a grid with a set let us start with the form's class declaration.

Prerequisites - Design a form with a grid and add any table you want as the data source and one button.

Step 1 Declare the Set and the Set Iterator

 public class FormRun extends ObjectRun  
   Set               DispatchSelectedRecords;  
   SetIterator       DispatchSelectedRecordsSI;  

Step 2 Initialize the Set

Override the Form's init method

 public void init()  
    if (!element.args().menuItemName())  
    throw error("@SYS22539");  
    Dispatchselectedrecords = new Set(Types::Integer);  

Now you might ask yourself how do we define what type of data will be adding to set. When initializing the set we have to set the type, DispatchSelectedRecords = new Set(Types::Integer);. There are set types for all of the available data types in AX 2012. 

In our case I have chosen to store integer values in my Set. Essentially these will be the Rec Id Values of the data source in my form grid.

Step 3 Override the MarkChanged Method on the Data Source.

 public void markChanged()  


In this method we are checking if the particular "RecId" is in the set and adding "RecIds" not in the set. We are basically checking for duplicates and adding the new items to the set.

Step 4 Traverse through the list.

Override the Clicked Method of the button your created

 void clicked()  
   OutsourcedPOprocessingTable OutsourcedPOprocessingTableLoc ;  
   TmpOutsourcedPOprocessingTable TmpOutsourcedPOprocessingTableloc ;  
   Dispatchselectedrecordsse = new SetIterator(Dispatchselectedrecords);  
   ttsBegin ;  
   while (Dispatchselectedrecordsse.more())  
     TmpOutsourcedPOprocessingTableloc  = TmpOutsourcedPOprocessingTable::find(Dispatchselectedrecordsse.value(),TmpOutsourcedPOprocessingTable) ;  
     OutsourcedPOprocessingTableLoc    =  OutsourcedPOprocessingTable::find(TmpOutsourcedPOprocessingTableloc.BarCodeNo , TmpOutsourcedPOprocessingTableloc.TestCode , TmpOutsourcedPOprocessingTableloc.SalesId);  
     OutsourcedPOprocessingTableLoc.DispatchStatus = NoYes::Yes ;  
     OutsourcedPOprocessingTableLoc.DispatchDateTime = DateTimeUtil::utcNow();  
   ttsCommit ;  
   delete_from TmpOutsourcedPOprocessingTable ;  

First initialize the SetIterator and pass the set in the Iterator. Then  use the "More" and "Next" Methods of the iterator to actually traverse though the Set.

In this method we are simply updating a table which has no bearing on the Set, but i am showing it to you because it aides in portraying a practical use of a set.

Thursday, 29 August 2013

Passing Data Data to Form with a Temporary Data Source X++ AX 2012

Scenario - Let us suppose we wanted to pass some data to a form, but the requirement mandates that this data source be a temporary table.

I developed this for a vertical I was built for AX 2012. Take a look at the data flow diagram below.

Once we have that data into the temp table we can process it, for example if we are dealing with financial entries we can post the entries as  JV.

Lets begin with a temporary table.

Step 1 - Create a new table and specify the table type property to "Temp DB". Remember this should be a replica of the table you want to query.

Step 2 Create a query of the original table.

From the AOT go to "Queries" and create a new query. Add the original table as the data source.

Step 3 Create the Form

 Create a simple grid form and add the temp table as the data source.

Next Override the following methods.

 //Override the form's init method  
 public void init()  
 //Override the datasources's init method  
 public void init()  

Step 4 Create the Class

Now in the class we are going to need a dialog to open up so we can query the original data source.

Basically we want the dialog to look like this.

The yellow box are normal dialog fields that i haves added to the dialog box, but let us focus on ht green box. The green box is highlighting the query that we created.

Class Declarations 

In order to use a query on a dialog box we the class has to extend "RunBase". If you want to add a batch to the dialog the class has to extend "RunBaseBatch" Along with extending "RunBase" there are a few other required methods, for adding a query to a dialog.

  1. Dialog
  2. GetFromDialog
  3. New
  4. Pack 
  5. Unpack
  6. QueryRun
  7. showQueryValues
  8. runImpersonated
  9. Description

 Public class ITLPDCSelectionPost extends RunBase  
   DialogField         dlgFieldFromDate;  
   DialogField         dlgFieldToDate;  
   DialogRunbase      dialog;  
   QueryRun          qr;  
   Query             q;  
   PDCDetails         PDCDetail ;  
   PDCDetailsTmp  PDCDetailTmp;;  
   ITLARNTable         ITLARNTable;  
   TransDate          FromDate;  
   TransDate          ToDate;  
   Form              form;  
   Args               args;  

Dialog Method

 /// <summary>  
 ///  Returns a class that contains the methods that are described by the <c>RunBaseDialogable</c>  
 ///  interface.  
 /// </summary>  
 /// <returns>  
 ///  A class that contains the methods that are described by the <c>RunBaseDialogable</c> interface.  
 /// </returns>  
 /// <remarks>  
 ///  A dialog can be either built by using the <c>Dialog</c> class or by using a class that is created  
 ///  in the Application Object Tree (AOT).  
 /// </remarks>  
 public Object dialog()  
   dialog     = super();  
   dlgFieldFromDate  = dialog.addField(extendedTypeStr(TransDate), "From Date");  
   dlgFieldToDate   = dialog.addField(extendedTypeStr(ToDate),"To Date");  
   return dialog;  

GetFromDialog Method

 public boolean getFromDialog()  
   fromDate = dlgFieldFromDate.value();  
   ToDate  = dlgFieldToDate.value();  
   return super();  

  New Method

 public void new()  
   qr = new QueryRun(querystr(PDCDetailsQuery));  

Pack  Method

 public container pack()  
    return [#CurrentVersion,qr.pack()];  

Unpack Method

 public boolean unpack(container packedClass)  
   Integer   version   = conpeek(packedClass,1);  
   container  packedQuery;  
   switch (version)  
     case #CurrentVersion :  
       [version,packedQuery] = packedClass;  
       if (packedQuery)  
         qr = new QueryRun(packedQuery);  
     default :  
       return false;  
   return true;  

QueryRun Method

 /// <summary>  
 ///  Retrieves the instance of the <c>QueryRun</c> class, which is used by the <c>queryPrompt</c> method.  
 /// </summary>  
 /// <returns>  
 ///  The instance of the <c>QueryRun</c> class, which is used by the <c>queryPrompt</c> method.  
 /// </returns>  
 /// <remarks>  
 ///  This method is used if a query prompt is the dialog and if a select menu item is added to a dialog.  
 ///  Do not create the instance of the <c>QueryRun</c> class when this method is called. Do it in the  
 ///  <c>unpack</c> method and the <c>initParmDefault</c> method, or in the <c>init</c> method.  
 /// </remarks>  
 public QueryRun queryRun()  
   return qr;  

showQueryValues Method

 /// <summary>  
 ///  Determines whether to add a select button to the dialog.  
 /// </summary>  
 /// <returns>  
 ///  Always returns true.  
 /// </returns>  
 /// <remarks>  
 ///  If you click this button, it will show the query form. Therefore, the <c>queryRun</c> method has to  
 ///  return a valid <c>queryRun</c> .If you change the return value to false the button will no longer  
 ///  be added.  
 /// </remarks>  
 boolean showQueryValues()  
   return true;  

runImpersonated Method

 /// <summary>  
 ///  Determines whether the batch task is run on the server or on a client.  
 /// </summary>  
 /// <returns>  
 ///  Always returns true.  
 /// </returns>  
 /// <remarks>  
 ///  Your classes that extend the this class must override the <c>runsImpersonated</c> method and return  
 ///  false, if you want those tasks to run on a client.  
 /// </remarks>  
 public boolean runsImpersonated()  
   return true;  

Description Method

 client server static ClassDescription description()  
   return "Select PDC Booking";  

Now create a new method that will be used to populate the records form your "original table" and insert them into your "temp table".

Populate Records - Queries and Inserts the records in to the temp table

PDCDetailsTmp PopulateRecords()  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, PDCdate)).value(strFmt('%1..%2', FromDate, ToDate));  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, PDCStatus)).value(enum2str(ITL_PDCStatus::Open));  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, PDCStatus)).value(enum2str(PDCStatus::Bounced));  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, isGenerated)).value(enum2str(NOYes::Yes));  
   while (  
     PDCDetail = qr.get(tableNum(PDCDetails));  
       _PDCDetailTmp.CustAccount = _PDCDetail.CustAccount;  
       _PDCDetailTmp.PDCAmount = _PDCDetail.PDCAmount;  
       _PDCDetailTmp.PDCDate = _PDCDetail.PDCDate;  
       _PDCDetailTmp.PDCStatus = _PDCDetail.PDCStatus;  
       _PDCDetailTmp.PDCNumber = _PDCDetail.PDCNumber;  
       _PDCDetailTmp.RecRefId = _PDCDetail.Recid;  
       _PDCDetailTmp.DueDate = _PDCDetail.DueDate;  
       _PDCDetailTmp.InstallmentNumber = _PDCDetail.InstallmentNumber;  
       _PDCDetailTmp.BankAccountNum = _PDCDetail.BankAccountNum;  
       _PDCDetailTmp.CustBankAccountId = _PDCDetail.CustBankAccountId;  
       _PDCDetailTmp.ITLSARDAte = _PDCDetail.SARDate;  
       _PDCDetailTmp.ITLSARID = _PDCDetail.SARID;  
       _PDCDetailTmp.toPost = NoYes::Yes;  
   return _PDCDetailTmp;

Now we have our run method which will open our form. So in the run method our task will be to pass the TempTable we inserted data into to the forms datasource.

Run Method

 /// <summary>  
 ///  Contains the code that does the actual job of the class.  
 /// </summary>  
 public void run()  
   //Call the Populate Records Method  
   args = new Args();  
   //Set the Args Record to the Temp Table we Inserted Data into)  
   //Open the form and pass args  
   new MenuFunction(menuitemDisplayStr(PDCPostingSelection), MenuItemType::Display).run(args);  

Main Method

 static void main(Args _args)  
   PDCSelectionPOSt  PDCSelectionPOSt;  
   if (PDCSelectionPOSt.prompt());  


Tuesday, 27 August 2013

Production Control Training 2 - BOM, Routes, & Operations - Discrete Manufacturing AX 2012 R2

In the last part we have set up everything from production units to calendars, and resources. So now lets move on to creating our BOM, Routes and Operations. Before we start let me give you a brief on the items I have created for the BOM.

Step 1 - Create the Products

Product ID
Product Dimensions
Storage Dimensions
Tracking Dimensions
Tanjore Painting
Size and Style

In the last part we have set up everything from production units to calendars, and resources. So now lets move on to creating our BOM, Routes and Operations.

Before we start let me give you a brief on the items I have created for the BOM.

Manufactured Item

Product ID
Product Dimensions
Storage Dimensions
Tracking Dimensions
Tanjore Painting
Size and Style

Create different sizes and styles I created three sizes and 3 styles


Product ID
Product Dimensions
Storage Dimensions
Tracking Dimensions

The glass and frame will have the same 3 sizes and variants. For the paint create as many variants of colors as you want. I created 5.

Next Release the products and continue with the basic item setup such as

·      Item Group
·      Item Model Group
·      Dimensions
·      BOM Unit
·      Purchase Unit
·      Sales Unit
·      Inventory Unit

For the sake of simplicity we are going to keep all four types of unit the same as in the tables above.

We will also have to set up the cost group for each item. Do not enter any values in the prices group because this will get updated when we create the item prices from the costing version. I have gone over cost groups in my last post.

Step 3 - Set up Item Cost Prices

Lets set up the item cost prices for all of "ingredients" we created.

First lets add the overhead for our items.

(If you are new to AX skip the following brief on Costing Sheet Setup)

Costing Sheet

This is only for "purchase prices", in this post we will be setting up the "cost price" so if u skip the costing sheet setup that is fine. I will be going much further in depth on the topic of costing so do not get nervous if you do not understand it fully yet.

Indirect Cost can only be set up for the price type "purchase price" and cannot be set up of price type of "cost" in this training we are using the price type of "cost". So this is just a step I want to introduce but will not be applicable for this lesson.

So go to the costing sheet form. Inventory Warehouse Management > Setup > Costing > Costing Sheet

Now if you see there is Overhead tab under "Cost of Purchase". Click on that then from the grid on the side go to the calculation tab.

On the bottom half of the form create a new line and select the costing version and then site. I chose site 5 because all of the items in my BOM are tagged with site 5. And i have gone ahead  and select "ALL" in the Valid For field because i want it applicable for all the items. Then set the percentage. Save the record and Activate it.

Cost Price

Now for setting the actual price for the item.

Go to the Costing Versions form.

Inventory and Warehouse Management > Setup > Costing > Costing Versions

From the action pane click on prices and then item price. Create a new line for our item and set the price.

I have set this up again with site 5. This is our paint so in the Price Quantity field I set a value for 5. because i want the price to be applicable for 5ml of paint.

In this post we are only going over "COST" price type.

There are three price type in AX 2012
  • Cost
  • Purchase Price
  • Sales Price
Do this for all the items and then activate the prices.

Step 4 - Create the BOM

Go to the Released Products List Page and select TANJ0001.

From the action pane go to the Engineer Tab and click on Lines.

Go ahead and add all of "Ingredients" to the BOM Lines.

Now i only have only created one BOM Version for one of the sizes, but you free to experiment and create more than one BOM Version.

Now that this done let us move on to creating a Route.

Step 5 - Create the Route Version

Go to the Route List Page.

Production Control > Common > Routes > All Routes.

Go ahead a create a new Route.

When you click New the Route Version forms comes up. Route Versions are similar to BOM Versions where we can create different routes according, to a date range, quantity, site, and product variants.

Again in this case we re only going to create one Route Version.

Step 6 - Create Operation Relations

In the last post the following operations were created.

  1. Sketching
  2. Outlining
  3. Painting
  4. Decorations
If you are catching up quickly create them so we can start with attaching relations to out operations.

Go to Production Control > Setup > Routes >Operations

First select the Sketching operations and from the action pane click on relations.

We have to set up the relations on all four of the operations before we can proceed to adding the operations in the route.

On the overview tab select New.

We have to first create a relation to the Item. Select the "Table" option in the item code field and then select the item. In our case we will be creating a relation to our manufactured item which is "TANJ0001".

Second let us create a relation with the route we created earlier. Under Route Code select the "Route" option and then select the appropriate route as the route relation. 

In the General Tab

Specify the Site and Route Group. Route Group specify what costs are used during a production. For example we can specify if the setup, run time, or quantity costs should be calculated for any production run.

The property field is connected to the resource through the calendar we have assigned to the resource is used for scheduling similar operations together. We will talk about scheduling and the property field later on.

Skip the setup tab and lets move on the "Times" tab. Again we will be going over the exact meaning of each of these times coming up after we finish the tutorial.

Operation Setup 

The "formula" field  specifies how Run time for the operation should be calculated. You can select the following options: 
  • Standard: the manually entered values for Run time are used. 
For capacity there is no need to manually enter a run time in the times tab of the operations relations form.

For Example if we choose the capacity the as the formula and the capacity for my operation is 2 units per hour and production is for 10 units. The Calculated run time would be 5 hours. The added advantage with capacity is that in certain situations it is required that the capacity be calculated with a factor.
  • Capacity: the process time is calculated on the basis of Capacity that is specified in Resources form, the factor.
The other two formulas batch and resource batch are for process manufacturing so we will not be looking at those options today.

Operation Times

Please read up on the different times from MSDN.

I want to mention that "Hour/Time" is used to convert hours in to decimals.

Finally in the "Resource Requirements", click new in the grid action pane and select the resource you created for the sketching operation.

Do this for all of the 4 operations.

Now we will make the add the operations to out Route we made earlier.

Go back to

Production Control > Common > Routes > All Routes

Select the Route we made earlier and double click on it or click on Edit from the Action Pane.

You will get a blank form with two grids.

In the top grid create a new record and start adding your operations in order. Refer to the example on the bottom.

After adding these routes we have to go ahead and update the route. So from the action pane click on functions and select route updating.

By updating the route we can go ahead and link the operations to specific bom lines from the bom lines designer or BOM lines form.

That is about it for this training. We have gone over a lot. Please practice this and if you have any questions do not hesitate to ask.

Some of the next few posts will be a little more in depth on the costing side of production once a run is completed.