Tuesday, April 28, 2015

How to filter the gird based on the given input in ListPageForm

Filtering the grid based on the given purchase order in the Listpage:-

In ListPage we don't have override method. In order to filter the data based on the given input in the field and If you want to initialize some value to the field and based on that you want the grid to display.

When ever a ListPage Form is Opened, initializeQuery() method on the ListPageInteraction class is called.

In order to filter the grid based on the given input in the Listpage form you need to override the initializeQuery() method.

Scenario :- Take a input field in the PurchTableListPage form and based on the Purchase Order entered in the field it should display the grid.

 It can be achieved by adding the below code.

Add the below code in initializeQuery() method :-

/* actually we are making a range value empty so that when you open the listpage form the grid will be empty */

else
   {
       _query.dataSourceTable(tableNum(PurchTable)).addRange(fieldNum(PurchTable, PurchId)).value(SysQuery::valueEmptyString());
   }


Now add the below code to the modified method of the Field based on which you want the grid to be filter

public boolean modified()
{
    boolean ret;
    ret = super();
    PurchaseTable_ds.queryBuildDataSource().clearRanges();

   /*filtering the grid based on the given purchase order */

   if (this.valueStr() != '' )
   {
       PurchaseTable_ds.queryBuildDataSource().addRange(fieldNum(PurchTable, PurchId)).value(this.valueStr());
       PurchaseTable_ds.executeQuery();
   }

 /* if the input field is empty we are changing the range from PurchId to RecId and searching for RecId with a value "0", which is always not present. This will help you to show an empty grid whenever user enter a null value and search for the list*/  

   else
   {
       PurchaseTable_ds.queryBuildDataSource().addRange(fieldNum(PurchTable, RecId)).value("0");
       PurchaseTable_ds.executeQuery();
   }

   return ret;

}

Monday, April 27, 2015

Find and Exists Method in AX

Find :-

All tables should have at least one find method that selects and returns one record from the table that matches the unique index specified by the input parameters.

The last input parameter in a find method should be a Boolean variable called 'forupdate' or 'update' that is defaulted to false. When it is set to true, the caller object can update the record that is returned by the find method.

See the next example from the InventTable:

static InventTable find(ItemId itemId, boolean update = false --->to define how many primarykeys in table)
{
InventTable inventTable;
;
inventTable.selectForUpdate(update);
if (itemId)
{
select firstonly inventTable -->table name
index hint ItemIdx -->index name
where inventTable.ItemId == itemId;
}
return inventTable;
}

Exists :-

As with the find method, there should also exist an exists method.
It basically works the same as the find method, except that it just returns true if a record with the unique index specified by the input parameter(s) is found.

In the next example from the InventTable you can see that it returns true if the
input parameter has a value AND the select statement returns a value.

static boolean exist(ItemId itemId)
{
return itemId && (select RecId from inventTable
index hint ItemIdx
where inventTable.ItemId == itemId
).RecId != 0;
}

Thursday, April 23, 2015

How to Browse a File in Form Using X++ in AX 2012

Follow the below step to add  Browse Functionality in Form

Step1:-  Create a Form
            > Add a StringEdit in Design
            >Assign a EDT Property as FilenameOpen

Step 2:-
           Add the below Methods to the form in order to complete the functionality

  FilenameFilter filenameLookupFilter()
{
    #file
    return [WinAPI::fileType(#xpo), #allfilesName+#xpo, #allFilesType, #allFiles];
}
-----------------------------------------------------------------------------------------------------------
str filenameLookupTitle()
{
    return "Select a trade agreement to import";
}
------------------------------------------------------------------------------------------------------------

str filenameLookupInitialPath()
{
    return "";
}
-------------------------------------------------------------------------------------------------------------

str filenameLookupFileName()
{
    return "";
}
----------------------------------------------------------------------------------------------------------------

All Done !!!!!!!!!
Now you can browse the file in Form

Method 2 :-

Step 1:-  Create a Form
            > Add a StringEdit in Design
            >Assign a EDT Property as FilenameOpen

Step 2:- Override the Lookup method on StringEdit Control.

public void lookup()
{
    FilenameOpen    file;
    Filename        path;
    Filename        name;
    Filename        type;
    #File

    file = WinAPI::getOpenFileName(element.hWnd(),[WinAPI::fileType(#xlsx),#AllFilesName + #xlsx],path,'Select ...',"",name + type);
    if(file)
    {
        StringEdit.text(file);
    }
}


How to select a file using Browse Button in dialog box in AX 2012

/*
Below code will help you to select the file in the dialog box using Browse Button.
*/


static void Esh_FileOpen(Args _args)
{

Dialog dialog;
DialogField dialogField;
Filename filename;
;

dialog = new Dialog('FileOpen');
dialogfield = dialog.addField(extendedTypeStr(Filenameopen), 'File Name');
dialog.run();

if (dialog.run())
{
filename = (dialogfield.value());
}

info(filename);

}

Creating Workflow in AX 2012

Microsoft Dynamics AX provides workflow functionality that you can use to ensure that documents are processed and approved in a consistent and efficient manner.

A workflow represents a business process. A workflow defines how a business document flows through the system by indicating who must process and approve it.


Creating Workflow in AX 2012
  • Configure how the workflow engine is executed on a server.
  • Specify which application module a workflow is applicable to using a workflow category.
  • Link tables to workflows using a query.
  • Create a new workflow type.
  • Apply a workflow to a form.
  • Define what happens when the workflow is approved or denied.
  • Create Event Handlers and apply them to a workflow.
  • Configure a workflow.




In Microsoft Dynamics AX, you define a workflow by creating a workflow type to base the workflow on. In this walkthrough, you will create a workflow type in the AOT that you can add approvals and tasks to.
A workflow type defines information about the following:
  • Which document is being used with the workflow. The workflow document exposes calculated fields and identifies the query that exposes data fields for the workflow.
  • Tasks, automated tasks, and approvals that can be configured by the end user.
  • Workflow categories used for assigning a workflow type to a specific module.
  • Menu items and event handlers.
This walkthrough illustrates the following tasks:
  • Creating a query for a workflow.
  • Creating a workflow category.
  • Creating a workflow type in the AOT.
  • Adding code to the SubmitManager class.

To Create a Query for a Workflow

  1. In the AOT, right-click the Queries node, and then select New Query. A query group displays under the Queries node.
  2. Right-click the new query, click Rename, and then enter MyQuery.
  3. Expand the new query, right-click the Data Sources node, and then click New Data Source. A data source group displays under the Data Sources node.
  4. Right-click the new data source group and then click Properties.
  5. In the Properties sheet, set the Table property to CustTable.
  6. Expand the CusTable_1 data source, and select the Fields node. In the Properties sheet, set the Dynamic property to Yes.
    Note :-

    By setting the Dynamic property to Yes, all data fields in the CustTable table are exposed for workflow conditions. To remove data fields, set the Dynamic property on the Fields node of the data source to No. Expand the Fields node, right-click a field, and then click Delete. If the query is not saved, the Delete command is not available.                                                                                                                                                                                                                                                                    
  7. In the AOT, right-click MyQuery, and then click Save.
After a Microsoft Dynamics AX query is created, you must decide which category the workflow will be part of. We recommend that you choose an existing workflow category. If no category is appropriate, you can create your own.

To Create a Workflow Category

  1. In the AOT, expand the Workflow node.
  2. Right-click the Workflow Categories node, and then select New Workflow Category. A new workflow category group displays under the Workflow Categories node.
  3. Right-click the new workflow category and then click Properties.
  4. In the Properties sheet, set the following properties:
    Property
    Value
    Name
    MyWorkflowCategory
    Module
    Customer
  5. In the AOT, right-click MyWorkflowCategory, and then click Save.
After a workflow category is created, you are ready to create the workflow type.

To Create a Workflow Type in the AOT

  1. In the AOT, expand the Workflow node.
  2. Right-click the Workflow Types node, and then click Add-Ins > Workflow type wizard. The Workflow wizard is displayed. This wizard will help you create a new workflow type.
  3. Click Next.
  4. Set the following values for the wizard.
    Value
    Input
    Name
    Enter MyWorkflowType.
    Category
    Choose MyWorkflowCategory, which is the category that you created.
    Query
    Choose MyQuery, which is the query that you created.
    Document menu item
    Choose CustTable, which points to the main form for displaying customer data.
    Document web menu item
    Choose EPCustTableInfo, which points to the main page for displaying customer data in Enterprise Portal.
  5. Click Both to generate menu items for both the Microsoft Dynamics AX client and Enterprise Portal.
  6. Click Next. A list of all of the resources that will be created for the workflow type is displayed.
  7. Click Finish to create the resources. The wizard will create classes, menu items, web menu items, the workflow type, and a project that contains all of the items.
  8. A dialog box will be displayed that indicates the status. Click OK. The project that contains the workflow type resources is displayed.
After the workflow type is created, you will add code for the workflow events. However, to simplify this walkthrough, you will not add code to any of the event handlers.
To enable end-users to submit a workflow document for approval, you will have to add code that is run when the user clicks Submit in Microsoft Dynamics AX. The main method in the SubmitManager class that was created by the Workflow wizard will run. This code will display a message in the user interface that indicates that the document was submitted to workflow.

To Add Code to the SubmitManager Class

  1. In the AOT, expand the Classes node.
  2. Locate the MyWorkflowTypeSubmitManager class. This was the class created by the Workflow wizard.
  3. Expand the MyWorkflowTypeSubmitManager class, and then double-click the main method. The Editor window opens.
  4. In the Editor window, insert the following code.
    public static void main(Args args)
    {
        // Variable declaration.
        recId _recId = args.record().RecId;
        WorkflowCorrelationId _workflowCorrelationId;
        // Hardcoded type name
        workflowTypeName _workflowTypeName = workFlowTypeStr("MyWorkflowType");
        // Initial note is the information that users enter when they
        // submit the document for workflow.
        WorkflowComment _initialNote = "";
        WorkflowSubmitDialog workflowSubmitDialog;
    
        // Opens the submit to workflow dialog.
        workflowSubmitDialog = WorkflowSubmitDialog::construct(args.caller().getActiveWorkflowConfiguration());
        workflowSubmitDialog.run();
    
        if (workflowSubmitDialog.parmIsClosedOK())
        {
               _recId = args.record().RecId;
            // Get comments from the submit to workflow dialog.
            _initialNote = workflowSubmitDialog.parmWorkflowComment();
    
            try
            {
                ttsbegin;
    
                // Activate the workflow.
                _workflowCorrelationId = Workflow::activateFromWorkflowType(_workflowTypeName, _recId, _initialNote, NoYes::No);
    
                // Send an Infolog message.
                info("Submitted to workflow.");
    
                ttscommit;
            }
    
            catch(exception::Error)
            {
                info("Error on workflow activation.");
            }
        }
    }
    
    
  5. Close the Editor window and then click Yes to save changes.
  6. Any time that you create or modify workflow code, you must regenerate the CIL code. In the AOT, right-click AOT, click Add-Ins, and then select Incremental CIL generation from X++.
After MySubmitToWorkflowClass is created, you can create an action menu item to bind this class to.

To Enable a Form for Workflow

  1. In the AOT, expand the Forms node.
  2. Expand the CustTable form, and then expand the Designs node.
  3. In the Designs node, right-click the Design child node, and then click Properties.
  4. In the Properties sheet, set the following properties.
    Property
    Value
    WorkflowEnabled
    Yes
    WorkflowDataSource
    CustTable
    NoteNote
    This is the root data source specified in the query used for the Document property on the MyWorkfowType type. For more information, see Walkthrough: Creating a Workflow Type.
    WorkflowType
    MyWorkflowType
  5. In the AOT, right-click the CustTable form, and then click Save.
After the form is enabled for workflow, you will add a canSubmitToWorkflow method to the form. This method runs before the Submit button is enabled to verify that the workflow document is in a valid state to submit to workflow. When this method returns true, the Submit button is enabled. An alternative is to add the canSubmitToWorkflowmethod to the main table for the form. This allows both the Microsoft Dynamics AX client and Enterprise Portal to share the same logic to determine whether workflow is enabled.
NoteNote
If there are no records in the data source and the canSubmitToWorkflow method returns true, an exception is thrown. Therefore, you should programatically check for a record when you evaluate the state of the workflow.

To Create a Method to Indicate Whether the Current Document can be Submitted to Workflow

  1. In the AOT, expand the CustTable form, right-click the Methods node and then point to Override method. Click canSubmitToWorkflow.
  2. A method node named canSubmitToWorkflow displays under the Methods node and the Editor window opens.
  3. In the Editor window, enter the following code to enable the Submit button on the form for workflow.
    public boolean canSubmitToWorkflow()
    {
        // ToDo This method always returns true and the Submit
        // button will always be displayed on the form. Enter code
        // here to only return true when the document is NotSubmitted.
        // Also, add code to check if a record exists in the data source.
        return true;
    }
    
  4. Close the Editor window and then click Yes to save changes.
Now that the form is enabled for workflow, you must create a workflow configuration to display the Submit button on the workflow toolbar.

To Create a Configuration

  1. In Microsoft Dynamics AX, click Accounts receivable > Setup > Accounts receivable workflows. The Accounts receivable workflows list is displayed.
  2. In the Accounts receivable workflows list, click New. The Create workflow form is displayed.
  3. On the Create workflow form, select MyWorkflowType, and then click Create workflow. The workflow configuration form is displayed.
  4. In the action pane, click Properties. The Properties form is displayed.
  5. In the Properties form, click Basic Settings. In the Submission instructions text box, enter My workflow submit instructions., and then click Close.
  6. In the MyWorkflowType form, create a simple workflow by dragging a Conditional decision onto the workflow in between the Start and End nodes. Drag a line from the Start node to the Conditional decision 1 node. Then, drag a line from the True output of the Conditional Decision 1 node to the End node. Finally, drag a line from the False output of the Conditional decision 1 node to the End node.
    TipTip
    You may need to scroll down in the workflow designer form to see the End node.
  7. Right-click Conditional decision 1, and select Properties. The Properties form opens.
  8. In the Conditional tab, click Add condition, and then enter Where Customers.Account number contains value 0.
  9. Click Close.
  10. In the workflow designer form, click Save and close. Enter Workflow Walkthrough in the Version notes field and click OK.
  11. The Activate workflow – MyWorkflowType form appears. In the Activate workflow – MyWorkflowType form, select Activate the new version, and then click OK.
  12. Display the Accounts receivable area page.
  13. Click Customers > All customers.
  14. Double-click one of the customers in the list. The Customers form is displayed.
  15. The workflow toolbar is displayed at the top of the CustTable form. Click the View Workflow Instructions icon on the workflow toolbar to display the submission instructions that you created in this walkthrough.
  16. Click MyWorkflowTypeSubmitMenuItem, which is the menu item that you created to submit the customer to workflow. Supply a submission comment and then clickMyWorkflowTypeSubmitMenuItem to see the submitted to workflow Infolog message.

Source :-https://msdn.microsoft.com/EN-US/library/cc641259.aspx

Importing Data from Excel Sheet to Table in AX 2012

Importing Data from Excel Sheet to Table in AX 2012

static void Esh_ImporttoExcelProductType(Args _args)
{
SysExcelApplication application;
SysExcelWorkbooks workbooks;
SysExcelWorkbook workbook;
SysExcelWorksheets worksheets;
SysExcelWorksheet worksheet;
SysExcelCells cells;
COMVariantType type;
Name name;
FileName filename;
Esh_SampleTable esh_sampletable; //Declaring Table Name
int row;
str _productTypeId;
str _productType;
str _description;
;

application = SysExcelApplication::construct();
workbooks = application.workbooks();
//specify the file path that you want to read
filename ='D:\\Test.xlsx'; //ExcelSheet File Name
try
{
workbooks.open(filename);
}
catch (Exception::Error)
{
throw error('File cannot be opened');
}

workbook = workbooks.item(1);
worksheets = workbook.worksheets();
worksheet = worksheets.itemFromNum(1); //Here 1 is the worksheet Number
cells = worksheet.cells();
do
{
row++;
_productTypeId = any2str(cells.item(row, 1).value().toString());
_productType = cells.item(row, 2).value().bStr();
_description = cells.item(row, 3).value().bStr();

esh_sampletable.ID = _productTypeId;
esh_sampletable.Type = _productType;
esh_sampletable.Description = _description;
esh_sampletable.insert();

type = cells.item(row+1, 1).value().variantType();
}
while (type != COMVariantType::VT_EMPTY);
application.quit();
info("Data is Imported");
}



Thursday, April 16, 2015

Sales Order (Confirmation, Picking list, Packing slip, Invoice ) -- Classes and Tables


Creating Sales Order
-------------------------

Classes :- SalesTableType and SaleslineType classes  will get called while creating the orders.
Tables  :- Sales Table, Logistics Postal Address, CustTable, MCRPrimaryAddressCust,SalesLine.

Confirmation
--------------------
Classes :- SalesFormLetter class

Tables  :- SalesParmTable, SalesParmLine Table
CustConfirmJour Table, CustConfirmTrans Table- when a sales order gets confirmed.


SalesFormLetter classes will be used to post the sales order at various document status like picking,packing, invoice etc.

Picking List
---------------
Classes :- SalesFormLetter_PickingList class

 Tables :- SalesTable, SalesParm Tables

Packing List
---------------
Classes :-SalesFormLetter_PackingSlip class

Tables  :-SalesTable, Salesparm Tables

CustPackingSlipJour, CustPackingSlipTrans  when a packing slip is posted.

Invoice
---------
Classes :- SalesFormLetter_Invoice class

CustInvoiceTable, CustInvoiceTrans when invoice is posted.

How to enable the dimension fields based on the Item selected on the form.

[Form] public class KMTShipFromWarehouses extends FormRun {     InventDimCtrl_Frm_EditDimensions        inventDimFormSetup;     /// ...