Examples Of Formevent Handlers in AX 7

  Here Im using CustGroup Form To Perform Some Operations By using FormEventHandlers.

1.Using On Intilizing EventHandler To disable a Control In CustGroup form.

     Here the Code snippet....


2.Using On clicked EventHandler For a Button 

   [FormControlEventHandler(formControlStr(CustGroup, Clicked), FormControlEventType::Clicked)]

public static void Clicked_OnClicked(FormControl sender, FormControlEventArgs e)

{

// FormRun formRun = sender.formRun() as FormRun;

CustGroup custGroup;

custGroup = sender.formRun().dataSource().cursor(); // to get current activated Record

info(strFmt('%1 - %2 ',custGroup.CustGroup,custGroup.Name));

}

3. Using onInitilized event handler to disable a button 

[formeventhandler(formstr(custgroup), formeventtype::initialized)]

public static void custgroup_oninitialized(xformrun sender, formeventargs e)

{

custgroup custgroup;

formdatasource ds = sender.datasource(formdatasourcestr(custgroup, custgroup)); //current datasource

sender.design().controlname(formcontrolstr(custgroup,clicked)).enabled(false);

custgroup = ds.cursor(); 

info(custgroup.custgroup);

}

3.   Using onActivated event handler 

[formdatasourceeventhandler(formdatasourcestr(Custgroup, Custgroup), formdatasourceeventtype::activated)]

public static void custgroup_onactivated(formdatasource sender, formdatasourceeventargs e)

{

Custgroup custgroup;

// formdatasource ds = sender.datasource(formdatasourcestr(custgroup, custgroup));

FormRun formRun = sender.formRun() as FormRun;

custgroup = sender.cursor();

formRun.design().controlName(formControlStr(Custgroup,Clicked)).enabled(custgroup.CustGroup <='30');

//if(custgroup.CustGroup <='30')

//{

// formRun.design().controlName(formControlStr(Custgroup,Clicked)).enabled(false);

//}

//else

//{

// formRun.design().controlName(formControlStr(Custgroup,Clicked)).enabled(true);

//}


// info(strfmt('%1 - %2 ',custgroup.custgroup,custgroup.name));

}







 

WorkFlow In ax2012

   A custom Workflow In AX 2012

 Workflows define how a business document flows through the system and indicates who must process and approve it. The workflow functionality in Microsoft Dynamics AX 2012 helps ensure that documents are processed and approved in a consistent and efficient manner. Read on to understand the workflow system in Microsoft Dynamics AX and see how you can configure, extend, and use it.

 Basically The life cycle of workflow will depends on three steps. 

DESIGN -> CONFIGURATION -> RUN   
  • Developer design the workflow based on customer requirements.
  • The company administrator configures the workflow.
  • Users run the workflow.
At first we will start with devlomenmt.

   Workflow concept:
       The Basic Fundamentals that we are used in workflows are following.
  1. workflow elements
  2. workflow types
  3. workflow action
  4. workflow participants
  • Workflow elements
    • Task
      • Manual task : It’s handle by user.
      • Automated task : It’s handle by system.
    • Flow elements
      • Conditional decision : Provide two branches like True and False functionality, It will be handle by system.
      • Manual decision: Provide two branches, It will be handle by user.
      • Parallel : Two or more branches are run in a same time.
      • Sub workflow: It will be run based on another workflow.
    • Approvals:Its provide an option for Approve and reject.
  • Workflow types: If user wants to create a workflow then user need workflow type , it will available in each and every module example “Module name “+workflows
  • Workflow action:Actions are describe in terms of submit , Reject, Complete and provide branches in manual decision.
  • Workflow participants: participants are the user and these user may be systems administrator , workflow owner, originator and task assignee.
 
Coming to devlopment
  The Major Things That we have to remeber are  following:

Workflow category

When you create a workflow type in Microsoft Dynamics AX, it must be assigned to a workflow category. The workflow category indicates if a particular workflow type is available in a specific module. If an appropriate workflow category does not already exist, you must create one.

Workflow query

You can create a query to retrieve data by using the query classes.

Workflow type

To add workflow support for a document in Microsoft Dynamics AX, you must create a workflow type. The workflow type can then be used to create workflow configurations. Workflow types should be created to define:

  • Workflow documents
  • Workflow categories
  • Tasks and approvals for the workflow
  • Event handlers such as workflow started, completed, configuration data change, and cancelled
  • A SubmitToWorkflowMenuItem
  • A Cancel menuitem        

Workflow Approvals;

     Class Manages The tasks performed by workflow.

like submit, cancel, resubmit,deny actions. it ccreats a event handler class and resubmit manger class along with resepcted tasks menuitems 

Workflow elements

Any workflow consists of certain elements that define the task or the approval process. Mentioned below are some workflow elements:

  • Base enum: To define the workflow state
  • New field in table: To maintain the workflow status as per the table record
  • canSubmitToWorkflow() method to table: To check if a record should be submitted to the workflow or not
  • Workflow properties on form: To set created workflow elements on workflow property of the related form
  • Display menu items: To create new workflows on the list page
  • Form: To perform workflow activities on the form
 
step 1;
 

Create Base Enum

  • Expand Base Enums node in AOT >> Data Dictionary
  • Create New Base Enum for workflow states
  • Set properties of the newly created enum
  • Add elements for workflow state to enum (i.e. not submitted, submitted, approved, rejected)

STEP 2:
   Add newly created base enum tho the table.

New field in table

  • Select table (on which the workflow will work) from AOT >> Data Dictionary >> Tables
  • Add new enum type field and set enum type property to enum created in previous step
  • Compile and synchronize the table


 canSubmitToWorkflow() method to table

  • Expand method node on table (on which the workflow will work)
  • Add/modify the canSubmitToWorklfow() method to check whether record should be added to the workflow or not. This method contains code which defines eligibility of record to submit it to workflow
  • Sample code
public boolean canSubmitToWorkflow(str _workflowType = '')
{
    boolean ret;

    ret = super(_workflowType);
    if (this.WorkflowStatus==SalesCreditLimitApprovalStatus::NotSubmitted)
    {
        ret=boolean::true;
    }
    else
    {
        ret=boolean::false;
    }

    return ret;
}
STEP 3:
  •   Add newly Created field To The sales table form in design level.
  STEP 4 :
    Create A query Which holds the data for Perfrorm  our workflow.

Create query

  • Expand the Queries node in AOT
  • Click on New Query
  • Set properties like Title and Description on the newly created query
  • Expand the newly created query
  • Add main data source
  • Set dynamic property of field node of added data source to Yes


 STEP 5 :
  

 Create workflow category to specify our module

  • Expand Workflow Categories node in AOT >> Workflow.
  • Create New Workflow Category
  • Set namelabel, and module properties for newly created workflow category

 STEP 6 :

Create workflow type 

  • Expand Workflow Type node in AOT >> Workflow
  • Create New Workflow Type using workflow type wizard
  • Follow the wizard and set workflow type name,category (created in step5 ), query (created in  STEP 4 ) and document menu item (display menu item of form on which the workflow will be attached)
  • On clicking next, the wizard will show a list of objects that are going to be created. A new development project with new elements will be created

 
 STEP 7 :
    Add a submit method in your submit manger calss. I will provide a sample code here.
     public static void submit(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.");
        }
    }
}
     In the Submit class create main method and Creat a object for class and call the submit method
 EX. Obj.submit(_args) ;

 STEP 8 :

 Workflow properties on the form

  • Select Form from AOT >> Forms on workflow will be attached
  • Set properties related to workflow as below on form design

WorkflowEnabled = Yes

WorkflowDatasource = Table on which you added canSubmitToWorkflow() method

WrokflowType = Workflow type created in step 4

STEP 9:
Create a new workflow approval element using wizard. For this go to AOT -> Workflow -> Approvals -> Add-ins ->  Approval wizard
Add following information on it and it will create list of artifacts
- Name of workflow approval
- Workflow document
- Document menu item
    -  Document field group


















STEP 10:

 Add methods in eventhandler class to perform actions on workflow.
 

add element level event handler

  • Select Event Handler Class from AOT >> Classes to perform the action on sales order
  • When work flow status is updated, update the sales order enum element as well
  • Sample code

public void started(WorkflowElementEventArgs _workflowElementEventArgs)

{

ttsBegin;

select forupdate SalesTable

where SalesTable.RecId == _workflowElementEventArgs.parmWorkflowContext().parmRecId();

if(SalesTable.RecId)

{

SalesTable.INDSalesCreditLimitApprovalStatus = INDSalesCreditLimitApprovalStatus::PendingApproval;

SalesTable.update();

}

ttsCommit;

}

  • You need to perform this action on completed, change requested, canceled, created, denied and returned method in the event handler class
   

 Drag workflow approval to workflow type

  • Go to workflow node from the AOT. Select workflow element from the workflow elements node and then after drag this element into the workflow types - >Supported elements node like the following image


STEP 11 :

 Workflow author

  • Create new display menu items. Go to AOT >> Menu Items >> Display.
  • Change the following properties in the display menu item.
    1. Set the label to "Sales order credit limit work flow"
    2. Set the object to WorkflowTableListPage
    3. Set the EnumTypeParameter to ModuleAxapta
    4. Set the EnumParameter to Basic

  • Now drag display menu items in the home context area page
  • Set the IsDisplayedInContentArea to Yes
  • Perform the incremental CIL
STEP 11 :

Create and enable workflow for sales order

  • Select Display Menu Items which have previously been created and open it
  • Select New button to select workflow from the list
  • Select the Work Flow Type from the list and click on Create Workflow


STEP 12: 
 

Design workflow

  • Drag and drop the approvals from the Workflow Elements window to the Workflow window
  • Drag the bottom node of the Start box to the top node of the Approval box
  • Drag the bottom node of the Approval box to the top node of the End box



  • Now double click on the Approval box
  • Select Step from the workflow elements. Select Assignment
  • On the Assignment type tab, select User. On the User tab, select the user and drag user into the selected user list
  • Click on Basic Settings and then enter subject and instructions for the approval
  • Click on Save and Close
  • Enter workflow notes and click Ok
  • Then click on Activate the New Version and click Ok



The Configuration of work flow based on coditions will published in next blog ...Thank You...










Get Current datasources,controls,records using Event Handlers...

 

Get formRun, Form control, datasource and selected record from form datasource using Eventhandlers on Form in D365

Get formRun, Form control, datasource and selected record from form datasource :

[FormDataSourceEventHandler(formDataSourceStr(MyForm, MyRandomTableDS), FormDataSourceEventType::Written)] public static void MyRandomTableDS_OnWritten(FormDataSource sender, FormDataSourceEventArgs e)
{

FormRun formRun = sender.formRun() as FormRun;

// you can even call custom methods
formRun.myCustomMethod();

// Get the selected datasource record
TableName tableBuffer = sender.cursor();

// Get datasource variable
FormDataSource DSVariable = sender.formRun().dataSource(“TableName”);
}

Get form datasource from xFormRun
[FormEventHandler(formStr(SomeForm), FormEventType::Initialized)] 
public static void SomeForm_OnInitialized(xFormRun sender, FormEventArgs e)
{
FormDataSource MyRandomTable_ds = sender.dataSource(formDataSourceStr(SomeForm, MyRandomTableDS));

}

Access form control from xFormRun
[FormEventHandler(formStr(SomeForm), FormEventType::Initialized)] 
public static void SomeForm_OnInitialized(xFormRun sender, FormEventArgs e)
{
// set the control to invisible as an example
sender.design().controlName(formControlStr(SomeForm, MyControl)).visible(false);
}

Get FormRun from form control
[FormControlEventHandler(formControlStr(MyForm, MyButton), FormControlEventType::Clicked)] public static void MyButton_OnClicked(FormControl sender, FormControlEventArgs e)
{
FormRun formRun = sender.formRun() as FormRun;
formRun.myCustomMethod();
}

Get current record in form control event
[FormControlEventHandler(formControlStr(SomeForm, SomeButton), FormControlEventType::Clicked)] public static void SomeButton_OnClicked(FormControl sender, FormControlEventArgs e)
{
// as an example the datasource number is used for access; I perceive the formDataSourceStr as more robust
SomeTable callerRec = sender.formRun().dataSource(1).cursor();
}



EDIT METHOD IN FORM DATA SOURCE LEVEL IN AX2012

 edit FirstName editform(boolean _set,DaxCustTable _DaxCustTable,FirstName _name)

{

    FirstName name= _name;

    //DaxCustTable _DaxCustTable;

   DaxCustTable1 _DaxCustTable1;

    if (_set)

    {

        if (name)

        {

         ttsBegin;

            select forupdate _DaxCustTable1 where _DaxCustTable1.ID==_DaxCustTable.ID;

            _DaxCustTable1.FirstName=name;

            _DaxCustTable1.update();

         ttsCommit;

        }


    }

    else

    {


    select FirstName from  _DaxCustTable1 where _DaxCustTable1.ID==_DaxCustTable.ID;


    }

    return _DaxCustTable1.FirstName;

}

Set default currency values in create apyment proposals in ax2012



 if daxtest is checked to yes automatically currency field will set to default in create payment propsals 

for that

 \Classes\CustVendCreatePaymJournal 

 //Ns by thiru

     select ledgerJournalName where ledgerJournalName.JournalName=='custpay';

    if (ledgerJournalName.DaxTest==NoYes::yes)

    {

        dialogPaymCurrency.value(Ledger::accountingCurrency(CompanyInfo::current()));

        dialogPaymCurrency.enabled(false);

    }