Skip to main content

How to implement Runbase form in AX

Today I had a requirement that allow users to run Outlook synchronization process in batch rather sync it manually using out of the box functionality. Let's have a look on existing functionality and then extend it to achieve the requirement of running it in batch.

Existing functionality in AX

Home> Periodic > Synchronize [AOT form name is smmOutlookSyncrhonization]

As you can see someone has to manually sync outlook emails to AX acvitities or viceversa.

Extended functionality in AX

Let's implement this functionality in batch so users can set recurrence the Sync.

Create a new class;
class SyncOutLookEmails_RunbaseForm extends RunBaseBatch
{
    // Packed
    TransDate            testDate; // I am using this variable for own testing purpose
    #define.CurrentVersion(2)
    #define.Version1(2)
    #localmacro.CurrentList
        testDate
    #endmacro

}
public Object dialog()
{
    DialogRunbase   dialog = Dialog::newFormnameRunbase(formstr(smmOutlookSyncrhonization),this);
;
    return dialog;
}
public boolean getFromDialog()
{
    boolean ret;
    ret = super();
    return ret;

}
protected void new()
{
    super();
}
public container pack()
{
    return [#CurrentVersion,#CurrentList];
}
public boolean runsImpersonated()
{
    return true;

}
public boolean showQueryValues()
{
    return true;
}
public boolean unpack(container _packedClass)
{
    boolean     ret;
    Version     version = RunBase::getVersion(_packedClass);
    ;
    switch (version)
    {
        case #CurrentVersion:
            [version, #CurrentList] = _packedClass;
            ret = true;
            break;
        default:
            ret = false;
            break;
    }
    return ret;
}
server static SyncOutLookEmails_RunbaseForm construct()
{
    return new SyncOutLookEmails_RunbaseForm();
}
server static void main(Args args)
{
    SyncOutLookEmails_RunbaseForm   syncOutLookEmails_RunbaseForm = SyncOutLookEmails_RunbaseForm::construct();
    if (syncOutLookEmails_RunbaseForm.prompt())
        syncOutLookEmails_RunbaseForm.run(); 
}
Run this class by pressing F5, Ooopsss!!! it throws an error

A DialogStartGrp group is missing from the form smmOutlookSyncrhonization. In this group dialog controls are added.
This requires to add a group on the form and this has to have under a tab/tab page, let's do this;
How the current form looks in AOT


How it should look like to use it for batch class, created above.


  • Added new Tab
  • Added new Tab page
  • Added dialogStartGrp under tab page
  • Moved exisiting groups under tab page
  • Set caption "General" to tab page.
It requires few more methods at form level to make it working in batch

public class FormRun extends ObjectRun
{
    HcmWorker                   hcmWorker;
    OutlookUserSetup            outlookUserSetup;
    TransDate                   synchronizeFromDate;
    TransDate                   synchronizeToDate;
   
    SyncOutLookEmails_RunbaseForm   syncOutLookEmails_RunbaseForm;
}

public void init()
{
    synchronizeFromDate = systemdateget();
    synchronizeToDate = systemdateget();
   
    syncOutLookEmails_RunbaseForm = element.args().caller().runbase();

    super();

    if (!smmAxaptaOutlookMapping::isOutlookMappingSetupCompleted())
    {
        smmAxaptaOutlookMapping::createDefaultSetup();
    }

    // Find worker connected to the current logged ion
    hcmWorker = HcmWorker::find(HcmWorker::userId2Worker(curuserid()));

    if (hcmWorker)
    {
        outlookUserSetup = OutlookUserSetup::findByWorker(hcmWorker.RecId);
        // Calculate synchronization period based on the employee setup parameters
        activityFromDate.dateValue(systemdateget() - outlookUserSetup.SmmSynchronizeDaysBack);
        activityToDate.dateValue(systemdateget() + outlookUserSetup.SmmSynchronizeDaysForward);
    }
    else
    {
        // No employee is mapped to the current user. Set mapping in Employee option form.
        error("@SYS80637");
        element.close();
    }
}

void closeOk()
{
    DialogRunbase dialog = element.args().caller();
;
    dialog.updateServer();
    if (syncOutLookEmails_RunbaseForm.checkCloseDialog())
        super();
}

//AOSRunMode::Client
RunBase runBase()
{
    return syncOutLookEmails_RunbaseForm;
}
Run class again by pressing F5


Target achieved!!! You can run the form with batch


Happy Dax!ng !!!

Comments

  1. Thanks for your valuable post. Trying to do the same on AX2009 but I dont get how the synchronization can take place on batch server since the main class smmOutlookSync is forced to run on client side only. Also from your post I dont see smmOutlookSync getting called, so how the process is getting executed?

    ReplyDelete
  2. QUICK EASY EMERGENCY URGENT LOANS LOAN OFFER EVERYONE APPLY NOW +918929509036 financialserviceoffer876@gmail.com Dr. James Eric

    ReplyDelete

Post a Comment

I will appreciate your comments !

Popular posts from this blog

The Dual Write implementation - Part 1 - Understand and Setup

What is Dual-write? Tightly couples – complete at one transaction level Near real time Bi-directional Master data and business documents – Customer records you are creating and modifying and at this document we are talking about sales orders or quotes and invoice. Master data could be reference data e.g. customer groups and tax information Why Dual-write and why not Data Integrator? Data Integrator is Manual or Scheduled One directional Now, Let's deep dive and understand what is required for Dual-write setup and from where to start. First thing first, check you have access to https://make.powerapps.com/ Choose right environment of CDS (CE) Make sure you have access to the environment too, click on gear icon and Admin Center  Look for required environment and Open it, you must have access as going forward you are going to configure dual write steps in the environment user the same user you are logged in now. Now, go back to power platform admin center and

D365FO: Entity cannot be deleted while dependent Entities for a processing group exist. Delete dependent Entities for a processing group and try again.

Scenario: There are times when you want to delete an entity from target entity list and when you do so, you face an error message which does not tell you where exactly the entity has been used.  "Entity cannot be deleted while dependent Entities for the processing group exist. Delete dependent Entities for a processing group and try again. " Solution: Browse the environment by appending this part  /?mi=SysTableBrowser&TableName=DMFDefinitionGroupEntity&cmp=USMF   at the end.  For example; if the environment URL is  https://daxture.sandbox.operations.dynamics.com then the complete URL will be https://daxture.sandbox.operations.dynamics.com/?mi=SysTableBrowser&TableName=DMFDefinitionGroupEntity&cmp=USMF Filter for Entity and it will give you the DefinitionGroup where the entity has been added or used in data management import/export projects. Get the DefinitionGroup name and search in the export/import projects under data management and either delete the whole

AX 2012 : Add/Remove Dynalink through X++

DynaLinks can be removed and added between datasources on form using this code; ClearDynaLinks() will remove all existing dynaLinks [these can be seen by right click on the click > Personalise > Query tab > under dataSource node AddDynalink() method has three parameters; 1. Source table field 2. Destination table 3. Destination table field The following code is implemented in the Click event of a button. void  clicked() {     SalesQuotationLine_ds.query().dataSourceNo( 1 ).clearDynalinks();     SalesQuotationLine_ds.query().dataSourceNo( 1 ).addDynalink( fieldNum (SalesQuotationLine, QuotationId),                                                          SAB_DocQuoteGroupRelation,                                                           fieldNum (SAB_DocQuoteGroupRelation,SalesQuotationId));            }