Friday 26 December 2014

How to add Attachment button on a new form in DAX 2012

Hi Friends,

Here is another post to share with you all.
In this post, will demonstrate how to add a button for document handling on a new AX Form. To add this functionality you may need to perform following steps.

Step 1. Open your form in AOT and Go to from Design node.

Step 2. Add new button group under ActivePanTab.

Step 3. Add new command button under this new button group.

clip_image001

Step 4. Set following properties of this button

clip_image002

Now you need to do one functional setup for this new customization

Step 5: Open below from
 Organization administration/SetUp-> Document Management -> Active Document Table

Step 6: Add your table details here and click on Always enable.

clip_image003

Step 7: So its done now.
Open your form and click on Attachment button , below form must open.

clip_image006
Enjoy……
Happy New Year 2015 to all of you.

Wednesday 17 December 2014

Controller Class for the current Record SSRS Report in Ax 2012

Controller Class for the current Record

Controller Class :
class ProjHourUtilisationController extends SrsReportRunController
{
#define.ReportName('ProjHourUtilisation.PrecisionDesign1')
ProjHourUtilisationContract projHourUtilisationContract;
ProjTable projTable ;
}
____________________________________________________________________
protected void prePromptModifyContract()
{
if (this.parmArgs() &&this.parmArgs().record() && this.parmArgs().dataset() == tableNum(ProjTable))
{
projTable = this.parmArgs().record();
}
if (!projHourUtilisationContract)
{
projHourUtilisationContract = this.parmReportContract().parmRdpContract();
}
projHourUtilisationContract.parmProjectId(projTable.ProjId);
super();
}
___________________________________________________________________
public void setRange(Args _args, Query _query)
{
QueryBuildDataSource qbds;
QueryBuildRange qbr;
if (_args && _args.dataset())
{
switch(_args.dataset())
{
case tableNum(ProjTable) :
projTable = _args.record();
break;
}
}
qbds = _query.dataSourceTable(tableNum(ProjTable));
qbds.clearRanges();
//qbr = qbds.findRange(fieldName2id(tableNum(ProjTable),fieldStr(ProjTable, ProjId)));
if (!qbr)
{
qbr = qbds.addRange(fieldNum(ProjTable, ProjId));
}
if(ProjTable)
{
qbr.value(projTable.ProjId);
}
}
___________________________________________________________________
public boolean showQueryValues(str parameterName)
{
return true;
}
____________________________________________________________________
public static ProjHourUtilisationController construct(Args _args)
{
ProjHourUtilisationController controller=new ProjHourUtilisationController();
controller.parmArgs(_args);
return controller;
}
_____________________________________________________________________
public static void main(Args _args)
{
ProjHourUtilisationController controller = new ProjHourUtilisationController();
controller.parmReportName(#ReportName);
controller.parmArgs(_args);
controller.setRange(_args, controller.parmReportContract().parmQueryContracts().lookup(controller.getFirstQueryContractKey()));
controller.parmShowDialog(true);
controller.startOperation();
}

How to Copy Sales Quote in AX 2009

Hi,

The default functionality of Microsoft Dynamics Ax 2009 does not allow to copy a quote when a quote's status is either Lost, Sent, Confirmed, or Canceled.

Today I was asked to allow the users to copy a quote when its status is Sent or Lost. 

To copy a quote go to Sales Quotation Details, choose a record and then go to the header level buttons and click Function > CopyFromAll



The following are the steps to accomplish this very quick:



1- Go to the SalesQuotationTable Form > Designs > Design GroupTable> ButtonGroup:ButtonHeader> MenuButton:ButtonHeaderFunction>method>clicked:

You will see the following code:

void  clicked()
{
    ;
    // Set price simulation buttons

    salesQuotationPriceSimHeader.enabled(!salesQuotationTable.isTemplate());

    salesQuotationTableForm.enableFunctionButtons(salesQuotationTable,
                                                  buttonConvert2Customer,
                                                  buttonAlternativeQuotations,
                                                  buttonCopyAllHeader,
                                                  salesQuotationChangeReasonCode);

    smmDocuments.enabled(!salesQuotationTable.isTemplate());
    super();
}

2- Go to the definition of enableFunctionButtons method (right click > Go To Definition. 

Look for the following line of code:


enableCopyAllHeaderButton           = salesQuotationTableType.mayQuotationBeCopied();

   
3- Go to the definition of the salesQuotationTableType.mayQuotationBeCopied() method, and then make the following changes:

ok = (//salesQuotationTable.QuotationStatus   != SalesQuotationStatus::Sent &&
            salesQuotationTable.QuotationStatus != SalesQuotationStatus::Confirmed &&
            //salesQuotationTable.QuotationStatus != SalesQuotationStatus::Lost &&
            salesQuotationTable.QuotationStatus != SalesQuotationStatus::Cancelled);

Comment the lines in green.

Form Method calling Sequence in Dynamics AX

Form Method calling Sequence in Dynamics AX

This gives the information of method calls in the form level while
          1. Opening the Form.
          2. Creating/Updating/Deleting the record in the Form.
          3. Closing the Form.
Sequence of Methods calls while opening the Form
Form — init ()
Form — Datasource — init ()
Form — run () 
Form — Datasource — execute Query ()
Form — Datasource — active ()
Sequence of Methods calls while closing the Form
Form — canClose ()
Form — close ()
Sequence of Methods calls while creating the record in the Form
Form — Datasource — create ()
Form — Datasource — initValue ()
Table — initValue ()
Form — Datasource — active ()
Sequence of Method calls while saving the record in the Form
Form — Datasource — ValidateWrite ()
Table — ValidateWrite ()
Form — Datasource — write ()
Table — insert ()      
Sequence of Method calls while deleting the record in the Form
Form — Datasource — validatedelete ()
Table — validatedelete ()
Table — delete ()
Form — Datasource — active ()
Sequence of Methods calls while modifying the fields in the Form
Table — validateField ()

Table — modifiedField ()

Tuesday 16 December 2014

Sample: Step by step: How to develop a RDP auto design report

Topics- are being covered
ØStep by step: How to develop a RDP auto design report
a.Table types while creating new Temp table and differentiate each type
b.All about Contract Class
c.Overview of Attributes used in SSRS
d.All about Report Data Provider (RDP) class 
Steps:
In our previous discussion, We knew how we can build a simple report using just the AOT queries.
Why RDP report: Now what if we have some logic that needs to be implemented and can not be achieved using AOT queries? This is where Report Data Providers plays a significant roles. Most of the more complex AX2012 reports are built using a report data provider.

Let us take the example of displaying the Customer Id, Name and Balance.
Step 1: Create a Temp table HS_CustBalanceTableTMP
Create a new table, name HS_CustBalanceTableTMP and set table type property to InMemory or TempDB. Differences between InMemory and TempDB are as:
S. No. In Memory TempDB
1 Holds data temporarily in client or server Holds data temporarily in database
2 These tables can't store in the database These tables can store in the database
3 Can't apply security Can apply security


Add the following fields in HS_CustBalanceTableTMP
  AccountNum
  Name
  Balance
Step 2: Create a Query HS_CustBalance (optional)
Step 3: Create a Data Contract class
A data contract is an X++ class that has getters, setters and the DataContractAttribute attribute. The Data contract class defines the parameters in your report. A data contract class has methods with the DataMemberAttribute attribute. The name that follows the attribute is the parameter name that displays in Visual Studio when you bind a report data set to the RDP class.
A report parameter provides a way to choose report data, connect related reports together, and vary the report presentation. It is used when generating the report data set. The parameters that an RDP class will reference are defined in a data contract class.

The following example illustrates the code to declare a data contract class.
Add a method named parmAccountNum in code editor
/// <summary>
/// The <c> HS_CustBalanceContract</c> class is the data contract class for the HS_CustBalanceReport report.
/// </summary>
/// <remarks>
/// This is a sample class. Created by Vimal on Nov 18, 2014
/// </remarks>
[ DataContractAttribute ]
public class HS_CustBalanceContract
{
   AccountNum accountNum;
}

Add a method named parmAccountNum in code editor
[
  DataMemberAttribute("AccountNum"),
  sysOperationLabelAttribute(literalStr(“@SYS1996)),
  sysOperationHelpTextAttribute(literalStr(“@SYS….”))
]
public AccountNum parmAccountNum(AccountNum _accountNum = accountNum)
{
  accountNum = _accountNum;
  return accountNum;
}

Attributes- Overview
§The first thing is to note that the class needs to be decorated with DataContractAttribute – this tells Dynamics AX that it is a Data Contract.
[ DataContractAttribute ]
public class HS_CustBalanceContract

§After that decoration, you can see that we have two SysOperationGroupAttribute decorations. These are completely optional, but they allow you to group your parameters together.
§Next comes each of my accessor methods. They need to be decorated with DataMemberAttribute.
§The group membership is done with SysOperationGroupMemberAttribute which takes the identifier of the group – which we defined in the SysOperationGroupAttribute in the class declaration
§The display order is done with SysOperationDisplayOrderAttribute  – it takes a string by which to sort the parameters; this gets evaluated after group membership, so you don’t have to be globally sorted, just within the group.
§There are 2 other decorations that you can use on the data members: SysOperationLabelAttribute- for specifying label of the particular parameter and SysOperationHelpTextAttribute – for specifying help text for the particular parameter
§SRSReportQueryAttribute- It creates link with Query which is used and helps to set additional filters. Query is not mandatory component of RDP report
§SRSReportParameterAttribute – It creates link between Data Contract class and RDP class and helps to create parameters in RDP report
§SRSReportDataSetAttribute – It creates link between temporary table and RDP class for processing report data
§This SysEntryPointAttribute plays a very important role while accessing a RDP report. The SysEntryPointAttribute class is used to decorate the class methods that require authorization checks and it is extended by SysAttribute class.

Step 4: Create a Report Data Provider (RDP) class
A report data provider (RDP) class is an X++ class that is used to access and process data for a report.  An RDP class extends the SRSReportDataProviderBase class.
The following example illustrates the code to declare a RDP class.
/// <summary>
/// The <c> HS_CustBalanceDP</c> class is the report data provider class for the HS_CustBalanceReport report.
/// </summary>
/// <remarks>
/// This is a sample class. Created by Vimal on Nov 18, 2014
/// </remarks>
[
  SRSReportQueryAttribute(querystr(HS_CustBalance)),
  SRSReportParameterAttribute(classStr(HS_CustBalanceContract))
]
class HS_CustBalanceDP extends SRSReportDataProviderBase
//class HS_CustBalanceDP extends SRSReportDataProviderPreProcess
{
   HS_CustBalanceTableTMP  custBalanceTableTMP;
   AccountNum      accountNum ;’
}
The class declaration contains one attribute “SRSReportQueryAttribute”. This attribute specifies the query that will be used for this report. In case no query is required, this attribute can be removed.
There is one other attribute that can be specified on the RDP class and that is SRSReportParameterAttribute. This attribute defines the contract class that will be used to display report parameters.

Add getHS_CustBalanceTableTMP method (This method is mandatory as it returns the table buffer that contains the processed report data. The Dataset uses this buffer to bind the table to the dataset.)
/// <summary>
/// This method returns the table buffer that contains processed data
/// </summary>
[
   SRSReportDataSetAttribute(tableStr(“HS_CustBalanceTableTMP”))
]
public HS_CustBalanceTableTMP getHS_CustBalanceTableTMP()
{
   select * from custBalanceTableTMP;
  return custBalanceTableTMP;
}

Add getReportParameter method
/// <summary>
/// This method processes the report parameters
/// </summary>
Private void getReportParameter()
{
  HS_CustBalanceContract contract = this.parmDataContract(); 
  if (contract)
  {
    accountNum = contract.parmAccountNum();
  }
}

Add insertHS_CustBalanceTableTMP method (This is a private method that uses the report query to insert data into the temporary table)
/// <summary>
/// This method processes the report query and inserts data into the HS_CustBalanceTableTMP table
/// </summary>
Private void insertHS_CustBalanceTableTMP()
{
  QueryRun queryRun = new QueryRun(this.parmQuery());
  CustTable custTable;
 
  while (queryRun.next())
  {
    custTable = queryRun.get(tableNum(CustTable));
   
    custBalanceTableTMP.AccountNum = custTable.AccountNum;
    custBalanceTableTMP.Name            = custTable.Name();
    custBalanceTableTMP.Balance         = custTable.openBalanceMST();
    custBalanceTableTMP..insert();
 
}

Add processReport method (The processReport method is the entry point for calculating the report data for dataset. Here is the method for our sample class)
/// <summary>
/// This method processes the business logic and executes first while accessing SSRS report
/// </summary>
[ SysEntryPointAttribute(false) ]
Public void processReport()
{
  this. getReportParameter();
  this. insertHS_CustBalanceTableTMP(); 
}

Step 5: Create a Report Model in Visual Studio
üGo to File menu and select New project (new project window will get appear)
üSelect Microsoft Dynamics AX under Installed templates
üSelect Report Model in the right pane
üName the project as HS_CustBalanceReport and press OK (Solution explorer will get appear with newly created project)
üRight click on the project and go to Add and select Report
üA report will be added to the project with the name “Report1″. Rename the report HS_CustBalanceReport
üExpand the report and need to add report dataset
üRight click on the dataset and select Add Dataset and name the dataset
üIn the dataset properties window select Data Source Type “Report Data Provider” then select Query field an ellipse button appears
üClick on ellipse button and select a Microsoft Dynamics AX Report Data Provider
üClick on Next and select the fields you want to display in the report and press OK (Only the selected fields will be shown in the report dataset)
üGo to Design node, right click and Add Auto Design
üDrag the dataset and drop into Auto Design node, A table will be created which contain all the fields present in the data set. These fields will appear in the same order in the report. So if you want to arrange the fields, right click the field and select either move up or move down.
üset the formatting in Properties window. Once report is done then follow these steps
üIn Solution explorer, Right click on project and select Add HS_CustBalanceReport to AOT (VS Project and report will be added in AX AOT)
üIn the Solution Explorer, right-click the project, and select Build
üIn the Solution Explorer, right-click the project, and select Deploy
üCross check- Project: Go to AOT-> Visual Studio Projects-> Dynamics AX Model projects and expand, search your project
üCross check- Report: Go to AOT-> SSRS Reports-> Reports and expand, search your report
Step 6: Create an Output type menu item “HS_CustBalanceReport” set the menu item’s basic properties
Step 7: Run the report through this menu item

Enjoy coding with MS