Wednesday 30 September 2015

How to add Filter functionality to Display method in dynamics AX

Normally filters will work only in table fields but we can't do filters to display method.

This below code will work for filters to display method also.

Step 1:
Go to the form design right click on particular control properties Auto Declaration No to Yes.



Step 2:
Override the context() method on the display method .

public void context()
{
    int             selectedMenu;
    formrun         fr;
    Args            ag;
    Name            strtext;
    querybuilddataSource qb1;
    queryrun    qr;
    query       q;
    PopupMenu menu = new PopupMenu(element.hWnd());
    int a = menu.insertItem('Filter By Field');
    int b = menu.insertItem('Filter By Selection');
    int c = menu.insertItem('Remove Filter');
    ;
q   = ItemControl_ds.query();
qb1 = q.dataSourceTable(tablenum(ItemControl));
qb1 = qb1.addDataSource(TableNum(SalesTable));
qb1.addLink(FieldNum(ItemControl,PO),FieldNum(SalesTable,PurchOrderFormNum));  

selectedMenu = menu.draw();
    switch (selectedMenu)
    {
    case -1: //Filter by field
            break;
    case a:
            ag = new args('SysformSearch');
            fr = new formrun(ag);
            fr.run();
            fr.wait();
//Reading User entered value for filter process
            strtext = fr.design().controlName('FindEdit').valueStr();
            if(strtext)
            {
//Creating a query for filter
                
                qb1.addRange(FieldNum(SalesTable,SearchName)).value(strtext);
                ItemControl_ds.query(Q);
                ItemControl_ds.executeQuery();
            }
            break;

    case b:                                      // Filter By Selection
           
            qb1.addRange(FieldNum(SalesTable,SearchName)).value(ProjName.valueStr());
            ItemControl_ds.query(Q);
            ItemControl_ds.executeQuery();
            break;

    case c :                                      // Remove Filter
            q   = new Query();
            qb1 = q.addDataSource(tablenum(ItemControl));
            qb1.clearLinks();
            qb1.clearRanges();
            ItemControl_ds.query(Q);
            ItemControl_ds.removeFilter();
            break;

    Default:
            break;
    }

}
After adding the above code we are getting menus like 



Monday 28 September 2015

Cube

A cube is defined by its measures and dimensions. 
A measure is a column in a table/ view that contains quantifiable data, usually numeric that can be aggregated
- like total no. of items sold/ profit/ revenue. A cube contains 1 or more measure.

Attributes are fields on table/ view .Dimensions are group of attributes.

The cube we create will allow us to analyze the data in Table format .


Prerequisites
  • Dynamics AX 2012
  • Dynamics AX 2012 Analysis Services
  • SQL Server 2012
Once you have identified the tables and views which contain the relevant data for your BI report, you can begin creating perspectives (cubes) in the AOT. Let’s suppose we have to develop a sales report for which the following tables/views contain the relevant data:
CUSTTRANSTOTALSALES view
CUSTTABLECUBE view
CUSTPAYMMODETABLE table

Creating Cube

Follow these steps to create a new perspective in the AOT:    Perspective Node
1. Expand Data Dictionary/Perspectives node
2. Create a new perspective and give it a suitable name
3. Set the USAGE property to OLAP
4. Drag the relevant tables and views

Defining Measures and Dimensions

Next step is to define measures and dimensions. Expand CUSTTRANSTOTALSALES view and set the field properties in the AOT as follows:
Untitled
Repeat the above step to specify measures and dimensions for other tables/views in your perspective as per your report requirements.

Generate Project

Click Tools > Business Intelligence (BI) tools > SQL Server Analysis Services project wizard. Create a new project and give a suitable name as shown below:
Untitled
On the next screen, select your newly created perspective:
Untitled
The next couple of screens offer optional features which include adding financial, date dimensions, language selection and currency conversion. The wizard will generate the project:
Untitled
Its up to you whether you save the project on disk or in the AOT.

Deploy cube

Next, the wizard will prompt you to choose the partitions to deploy the cube in if multiple partitions exist in the database environment. You can either to choose to process the cube using this wizard by ticking the checkbox or process the cube later in the SQL Server Management Studio.

Below screen - you can find based on no. of partitions of your DB . 
Go to >> System Administrator >> Setup >> Business intelligence>> Analysis servers >> Analysis server 
based on no. of records ( Partition keys) we get the same no.of records here.
Untitled

Process cube

Open SQL Server Management Studio, connect to Analysis Services. In the Object Explorer, you should be seeing now your newly created cube:
Right click your cube and click Process. Make sure the user has sufficient rights to process the cube otherwise you would have to provide Impersonation information in the Security settings of the database properties of your cube. The wizard will successfully process the cube.
Untitled
This ends the process of creating cubes! Now you can make MDX queries, build reports on top of your cubes. One such report that I created using SQL Server 2012 Power View plugin looks like below in the role center:
Untitled

Wednesday 9 September 2015

Check access rights for menu item and call through code

public void jumpRef()
{
    MenuFunction    menuFunction;
    ;

    menuFunction = new MenuFunction(menuitemdisplaystr(smmProcessSalesDefinition), MenuItemType::Display);

    // Check access rights
    if (!menuFunction || !menuFunction.checkAccessRights())
    {
        // Access rights are not sufficient to use this function.
        throw error("@SYS81158");
    }

    menuFunction.run();
}

Tuesday 1 September 2015

WorkFlow Automated Task

I have got the Workflow task of creating 4 Approvals based on amounts.

For Ex:  SalesTable Total Amount ( Get all line amounts total)

If   Sales Total Amount < 1000  - Get one approval
      Sales Total Amount < 2500  - Get 2 approval
      Sales Total Amount >25000 - 50000  - Get 3 approvals
      Sales Total Amount >50000  - Get 4 approvals

I created one approval Task and configured in Workflow, by creating conditional approval using same Approval class. The issue is with the code of Approval Complete Event - Changed the table Workflow field to approval.

Issue :  Even the amount is 2600, which needs 3 approvals, but when it pass through first approval the Table workflow field is getting Approved through code.

Resolved :  The issue is resolved by creating Automated Task event, And written below code in  "Executed " method .

public void execute(WorkflowElementEventArgs _workflowElementEventArgs)
{
    SalesTable  salesTable;
    WorkflowTrackingStatusTable workflowTrackingStatusTable;
    salesTable = SalesTable::findRecId(_workflowElementEventArgs.parmWorkflowContext().parmRecId());
    if(salesTable)
    {
        //workflowTrackingStatusTable = WorkflowTrackingStatusTable::findByCorrelation(_workflowElementEventArgs.parmWorkflowContext().parmWorkflowCorrelationId());
       // if(workflowTrackingStatusTable.TrackingStatus == WorkflowTrackingStatus::Completed)
        {
            ttsBegin;
            salesTable.selectForUpdate(true);
            salesTable.SalesCreditNoterWorkFlowStatus = SalesReturnOrderWorkFlowStatus::Approved;
            salesTable.update();
            ttsCommit;
        }
    }
    info("automated task is executed");
}

Configured the Automated Task  in Workflow before End...

So The flow comes from any of the approval needs to go from Automated Task and the workflow gets approved

Below code to get Total Line amount for a sales order :
    SalesTotals salesTotals;
    SalesTable salestblUpd;
    salestblUpd  =   SalesTable::find(Custinvoicejour.SalesId);
    if(salestblUpd)
    {
        salesTotals = SalesTotals::construct(salestblUpd, SalesUpdate::All);
        salesTotals.calc();
        salestblUpd.selectForUpdate(true);
        ttsBegin;
        salestblUpd.SalesCreditLineTotalAmount  =  salesTotals.totalAmount();
        salestblUpd.update();
        ttsCommit;
    }