Friday, May 31, 2019

Creating a Document Inbound Service in Microsoft Dynamics AX 2012

Microsoft Dynamics AX exposes data for exchange with external systems through business logic exposed as services. 

The data and business logic together is called a document.

The document service classes are part of the XML Document Framework. 
This framework consists of the classes that implement the business logic for individual documents in Microsoft Dynamics AX. You can also use this framework to create your own custom documents that can be sent using AIF. 
As a group, these classes encapsulate the business logic for individual documents.
The XML Document Framework contains these types of classes:
  • Document service classes (with data contracts)
  • Axd <Document> classes (also known as Axd classes)
  • Ax <Table> classes
A document service class is the top-level class that provides an external interface that represents the business logic. Document service classes include the service classes and their related data contract classes.

Document Service Classes

The service class is the top-level class that is exposed as a service through the Application Object Tree (AOT). You can view service classes in the Classes node in the AOT. The service classes are exposed as services, which you can view in Services node in the AOT. Each service class is derived from the AifDocumentService class. The service methods delegate their operations to the AifDocumentService class. For example, the SalesSalesOrderService.read method calls the AifDocumentService.readList method as shown in the following code.
public SalesSalesOrder read(AifEntityKeyList _entityKeyList) { SalesSalesOrder salesSalesOrder = new SalesSalesOrder(); this.readList(_entityKeyList, salesSalesOrder); return salesSalesOrder; }

The service class implements the methods that are needed to perform operations on the data. These methods are exposed as service operations by the service.

Data Object Classes

Data objects provide a data contract for the XML data that is exchanged through AIF. The data object classes reflect the data hierarchy of the query that is the basis of an AIF document. These classes are used only to work with data; they contain no business logic. The data object classes are found in the Classes node in the AOT.
The following table shows how the relationship between the data sources, XML elements, and data object classes is modeled in for a subset of the data sources included in the Customer service.
Object
XML element
Data object class
AxdCustomer query
<Customer>
CustCustomer
CustTable data source
<CustTable>
CustCustomer_CustTable
DirParty data source
<DirParty>
CustCustomer_DirParty

Document Data Object Class

The document data object class is the top-level data object and represents the whole XML document. The following list contains features of the document data object classes:
  • Implement the AifDocument class.
  • Encapsulate data being exchanged with AIF.
  • Passed as parameters to the update and create methods.
  • Used as the return value of the service class find and read methods.
For example, CustCustomer is the document data object and depends on the CustCustomer_CustTable data object. The CustCustomer_CustTable data object in turn depends on the CustCustomer_DirParty data object.
Although the document data object class implements the AifDocument class, it is still considered a data object. This is because the AifDocument class implements the AfStronglyTypedDataContainer class, just as the data object classes do.

Data Object Classes

The data object classes provide an object model for the service data. Data object classes implement the AifStronglyTypedDataContainer class which in turn implements the AifXmlSerializable interface.
There is a data object class for each data source in the query. For example, the customer data objects are the CustCustomer_CustTable class and the CustCustomer_DirParty class. The CustCustomer_CustTable class depends on the CustCustomer_DirParty class which models the relationship of this data in the database.


AIF Class Naming Conventions


Artifact type
Name description
Name generation rules
Example
Document name
Name of the document
User-defined name describing the document
SalesOrder
Service class
Name of the AIF service class
<Prefix> + <Document Name> + "Service"
SalesSalesOrderService
Document class
Name of the X++ class for the root data object
<Prefix> + <Document Name>
SalesSalesOrder
Data objects
Name of the X++ class for the child data objects of the document class
<Root data object name> + "_" + <Query data source Name>
SalesSalesOrder_SalesTable, SalesSalesOrder_DocuRefHeader, SalesSalesOrder_DocuRefLine, SalesSalesOrder_InventDim, SalesSalesOrder_MarkupTransHeader, SalesSalesOrder_MarkupTransLine, SalesSalesOrder_SalesLine
AOT service node
Name of the AOT node for the service
<Prefix> + <Document Name> + "Service"
SalesSalesOrderService
Service external name
Name of the service published to Windows Communication Foundation (WCF)
<Document Name> + "Service"
SalesOrderService
Table class names
Name of the Ax <Table> classes
"Ax" + query data source table name
AxSalesTable, AxInventDim, AxDocuRef, AxMarkupTrans, AxSalesLine
Query
Name of the query
"Axd" + user-defined document name
AxdSalesOrder
Document class name
Name of the Axd <Document> class
Same name as the query
AxdSalesOrder




The source of data for each document is a query (the Axd document query). The query controls the content and structure of the data in the document.

Document services are XML documents that initiate transfer of data into or out of Dynamics AX. Any entity in AX can be represented as Documents, such as Customers or Sales Orders.

Document services are used when we have to execute complex CRUD (Create, Read, Update, Delete) operations on an entity.


  1. Document service uses an AOT query to generate related artifacts. For this tutorial, InventTable query will be used

  • Open Microsoft Dynamics AX Development workspace. Go to Tools à Application Integration Framework àCreate document service


  • This will open the AIF Document Service Wizard. Click Next to proceed

  • In this step, specify the Document parameters. Select the Query for which service has to be created. The Document name will default to Query name. Modify it as required and give a suitable Document label as shown below. Click Next

  • Now specify the Code generation parameters. The wizard will use this to create the respective classes. Check the required Service operations you want to be automatically created by the wizard. Click Next
    Note: To allow Update/Delete/Create Service operations, the Update property must be set to Yes

  • In the Generate code window, review the artifacts that will be generated. Click Generate to proceed

  • The wizard will now generate all the artifacts. In the end, a Completed screen will display the list of artifacts it created. Click Finish to exit the wizard

  • The next step is to create a service group and deploy the service to an Inbound Port

  • Go to Service Groups, right click on it, and select New Service Group

  • Name it InventServiceDemoGroup

  • Set AutoDeploy to Yes (so the service will start automatically when AOS is started) and set the Description to Item Id service

  • Right click the newly created service group and select New Service Node Reference

  • In the newly created service node, set the Service property to InventTableDemoService. The Name property will automatically default to the Service name

  • Now right click the service group and select Deploy Service Group

  • A success message will appear if the service group is successfully deployed

  • To verify, go to System administration à Setup à Services and Application Integration Framework à Inbound ports

  • The Service group name InventServiceDemoGroup will appear here as Port name with a green tick mark. This shows that the service group is deployed and active. If a red cross mark is present, select Activate from the action pane to activate the port

  • The WSDL URI is the URL of the service which can be used by external systems to access the service

Thursday, May 30, 2019

Services And AIF in ax 2012

The AIF provides capability to integrate Microsoft Dynamics AX 2012 with other systems inside and outside an organization by enabling the exchange of data through XML.


This formatted XML is referred to as a document, and each document contains data and business logic. Documents are based on a document class and defined by using Microsoft Dynamics AX.


Further, AX 2012 ships together with standard document services that support common business processes. As in AX 2009, in AX 2012 we can also customize existing services or create our services.

How documents are exchanged?

The AIF provides an extensible framework for the exchange of XML documents with external systems. The framework supports both synchronous and asynchronous transports.

In synchronous mode, requests are tightly coupled to responses, which means that the submitter of the request must wait for a response from AIF before proceeding.  In this case, AIF does process the request immediately and then sends a response.

In asynchronous mode, however, requests are placed into a queue, called the gateway queue. Queued messages are processed at a later time and AIF sends a response when processing is completed. In this case, responses are delayed, but note that large volumes of messages can be processed more efficiently, and message processing can be controlled by changing various configuration settings. Further, the AIF can be used to send and retrieve data into/from AX.

Inbound / Outbound Exchanges

Inbound exchange, an external system may send a sales order so that the sales order can be saved to the Microsoft Dynamics AX database.
 
Outbound exchange, an external system may send a request for a purchase order and receive the purchase order.

The inbound and outbound exchanges can be categorized in the following ways:

  • Send data – AX sends documents to an external system.

  • Send data in response to requests – AX receives requests for documents from another authorized system, and retrieves the requested information, such as a document or a list of documents, from the AX database. Then AX returns the information to the requesting system.

  • Receive and create data – AX receives documents from another authorized system and creates new records in the Microsoft Dynamics AX database.


AIF Architecture

AX 2012 exposes its functionality through services that are based on Windows Communication Foundation (WCF) and hosted on Application Object Server (AOS).

External applications and client applications on the local area network consume AX services by accessing them directly from AOS. These clients and applications include AX components such as the AX client, Office Add-, and Enterprise Portal.

The following diagram illustrates the services and AIF architecture.







Application Integration Framework Process

  • Internet-based external applications and clients access the AX services through Internet Information Services (IIS).

  • IIS routes the incoming requests for AX services to AOS. All services requests, regardless of their origin, are handled by the WCF runtime that is hosted on AOS.
  • The AIF request pre-processor, if it is configured, can intercept the inbound request messages for custom preprocessing, such as message transforms or value substitutions.

  • The AX service invokes the necessary business logic to process the inbound request message.

  • Similarly, the AIF response post-processor, if it is configured, can intercept the outbound response messages for custom post-processing, such as message transforms or value substitutions.

  • The AIF response post-processor then returns the response to the client.

NOTE:  Microsoft Dynamics AX 2012 no longer includes a BizTalk adapter. For more information about how to use Microsoft BizTalk Server together with Microsoft Dynamics AX 2012, see Exchanging documents between BizTalk Server and AIF.

Services in AX 2012

Application Object Server (AOS) is the Windows Communication Foundation (WCF) service host for Microsoft Dynamics AX 2012 services that are exposed to users and applications on an intranet.
  • To consume services over the Internet, you must host services on Internet Information Services (IIS).

  • Services that are hosted on IIS use the WCF message routing service. IIS routes all service requests to AOS.

  • All service requests are processed on AOS, regardless of whether they originate on the Internet or an intranet. AOS then returns a response to the service consumer via IIS.

  • Exchanges that are configured to use Web services are processed synchronously and therefore are not queued.

  • AX deploys the service that is based on Web Services Description Language (WSDL) to a subfolder of the virtual directory that is associated with the Web site that you provide.

NOTE: In general when dealing with the AIF, keep in mind that the AIF user names and passwords are encrypted in the Application.Host configuration file located in C:\Windows\System32\Inetsrv\Config. Therefore, DO NOT copy files from other environments into this location when the AIF and/or Workflow are running in the same machine.


AX 2012 supports the following three kinds of services:

  • Document services are query-based services that can be used to exchange data with external systems by sending and receiving XML documents. These documents represent business entities, such as customers, vendors, or sales orders.

  • Custom services can be used by developers to expose any X++ logic, such as X++ classes and their members, through a service interface.

  • System services are provided by Microsoft Dynamics AX. System services include the Query service, the Metadata service, and the User Session service.
Further, system services are not customizable, and they are not mapped to any query or X++ code. For more information about system services, see AIF System Services.


Integration ports in AX 2012

In Microsoft Dynamics AX 2012, integration ports provide simplified administration of services and Application Integration Framework (AIF). Integration ports replace the AIF endpoints and related concepts that were used in previous releases of Microsoft Dynamics AX.

  • Each integration port can expose one or more services, and each integration port has a unique Uniform Resource Identifier (URI) that identifies the address of the port.

  • Each integration port also has a direction. An integration port can be either an inbound integration port or an outbound integration port.

  • An inbound integration port is a destination for messages that originate from outside Microsoft Dynamics AX.

  • An outbound integration port is a destination for messages that originate from your Microsoft Dynamics AX system. Inbound integration ports can be one of two types: basic or enhanced. Outbound integration ports are always enhanced ports.

Basic integration ports

Basic integration ports are exposed at a specific Windows Communication Foundation (WCF) endpoint on the Application Object Server (AOS) host. Only a developer can create a new basic integration port.
 


Enhanced integration ports

If you want advanced integration capabilities that you can use to customize the behavior of an integration port, you must create an enhanced integration port.

Enhanced integration ports provide the following capabilities that basic integration ports do not provide:

  • A variety of protocols are supported through WCF adapters. These protocols include HTTP, NetTCP, and Message Queuing, which is also known as MSMQ.
  • Enhanced integration ports also support a file system adapter that lets you use file paths as addresses.
  • You can perform pre-processing and post-processing of service requests and service responses.
  • You can create customizations for data contracts by specifying service operations and policies for document data.
  • You can specify advanced security and troubleshooting settings.

Adapters

In AX 2012 services and AIF, integration ports use adapters. These adapters enable AX to communicate by using various transport protocols.

AX 2012 provides the following four adapters that represent predefined bindings:

HTTP adapter – This adapter provides for synchronous message exchanges by using an HTTP or HTTPs transport.

NetTCP adapter – This adapter provides for synchronous exchanges by using WS-* standards support over the Transmission Control Protocol (TCP) transport.

This adapter corresponds to the WCF-NetTcp binding in Windows Communication Foundation (WCF).

MSMQ adapter – This adapter provides support for queuing by using Message Queuing as a transport. Message Queuing is also known as MSMQ.

Message Queuing is a type of asynchronous communication. This adapter corresponds to the WCF-NetMsmq binding in WCF.

File system adapter – This adapter provides support for the asynchronous exchange of documents through file system directories.


Messages and transforms in AIF

In AX 2012 services and AIF, a message corresponds to a Windows Communication Foundation (WCF) message. A message is a self-contained unit of data that can consist of several parts. These parts include a body and headers. When AIF receives and processes an inbound message, it generates an outbound message in response.

Although AIF supports the transfer of data in any arbitrary format, most information exchanges with AIF services use XML documents.

In order to create an XML document that adheres to a standard for a particular exchange of information, AIF requires XML documents to follow an XML style definition (XSD). XSD files (which have a .xsd file name extension) are meta-documents that describe the format, or schema, of XML documents that declare the namespace of the XSD.

Each schema includes rules about the hierarchical arrangement of XML elements, which elements must be present in the document, and other such requirements.


Schemas

1-Document service schemas: Each document service has a unique schema that describes the fields that can be added, read, updated, and so forth, by using the particular document service.

2-Message schema: Asynchronous exchanges require XML messages to be contained by the AIF message envelope. The namespace for the message schema is:
http://schemas.microsoft.com/dynamics/2011/01/documents/Message

3-Message-set schema: AIF uses the message-set, or batch, schema to contain batched AIF messages in asynchronous exchanges. The namespace for the message-set schema is:

http://schemas.microsoft.com/dynamics/2009/06/documents/Batch

4-Entity key schemas: AIF uses entity key schemas to contain name-value pairs, such as those used to query for a particular item during a read operation or when sending a response to a create operation. The namespaces for entity keys and entity key lists are:

http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKey
http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKeyList

5-Shared types schema: AIF aggregates common property types in the shared-types schema. The namespace for the shared-types schema is:

http://schemas.microsoft.com/dynamics/2008/01/sharedtypes

6-Fault schema: AIF uses the fault schema to contain response messages about error conditions. The namespace for the fault schema is:

http://schemas.microsoft.com/dynamics/2008/01/documents/Fault


Schema locations

You can save XSDs for particular document services, including their imported schemas (such as the shared-types schema) and any port-specific customizations, when you configure data policies for an integration port.

You can retrieve XSDs for common schemas from the following directory where you installed Microsoft Dynamics AX:
Program files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\Application\Share\Include


Processing messages

When you use an enhanced integration port for services and AIF, you can perform custom processing of data, such as XML documents, as each message passes through the integration port. Enhanced integration ports use the following two concepts to process messages during inbound or outbound exchanges:

  • Extensible Stylesheet Language Transformations (XSLT)
  • .NET-based transforms to messages.

In addition, transforms are run for inbound exchanges before they are run for outbound exchanges. Transforms process the whole message. Headers are included in the processing.

NOTE: Transforms apply only to asynchronous exchanges.

.Net-based transforms can convert messages to or from any proprietary format. AX services and AIF can process XML documents only if the documents comply with the service XSD.

If an incoming document is based on XML but uses a different schema, you can use Extensible Stylesheet Language (XSL) to transform the document to the AIF schema.

If an incoming document is not based on XML, such as a comma-delimited file, you can use a .NET Framework assembly to convert the file to the AIF schema.
Pipelines use components to enable the processing of requests for service operations. These components include custom components that are written in X++ code.

For example, if an inbound message contains customer records, your AIF pipeline can contain an XSLT component that updates an element in the XML, based on the value of the customer status element.

Further, your AIF pipeline can contain one or more of any available transformation component. Alternatively, your AIF pipeline can contain no transformation components.

Processing that occurs in pipelines, including XML transformation, applies to both synchronous and asynchronous exchanges.

For inbound exchanges, pipelines are run after transforms. For outbound exchanges, pipelines are run before transforms.

The following diagram shows how data moves through an enhanced inbound integration port.





https://axwonders.blogspot.com/2012/01/microsoft-dynamics-ax-2012-services-and.html

Friday, May 24, 2019

X++ code to return Workflow approver name

Method to return value of last approver :


public Name workflowApprover(RecId _recId)
        {
            WorkflowTrackingStatusTable workflowTrackingStatus;
            WorkflowTrackingTable workflowTrackingTable;
            WorkflowTrackingCommentTable workflowTrackingCommentTable;
            UserInfo userInfo;
       
            select firstFast RecId, User from workflowTrackingTable
                order by RecId desc
            join workflowTrackingCommentTable
                where workflowTrackingCommentTable.WorkflowTrackingTable == workflowTrackingTable.RecId
            join UserInfo
                where UserInfo.id == WorkflowTrackingTable.User
            exists join workflowTrackingStatus
                where workflowTrackingTable.WorkflowTrackingStatusTable == workflowTrackingStatus.RecId
            && workflowTrackingStatus.ContextRecId      == _recId
            && workflowTrackingStatus.ContextTableId    == tableNum(CICGBCreditCommittal)// your custom table on which workflow is enabled.
            && workflowTrackingTable.TrackingType == WorkflowTrackingType::Approval;
       
            if (workflowTrackingTable.RecId > 0)
            {
                return userInfo.name;
            }
            else
            {
                return '';
            }
       
        }

=======================================================================

Display method for the same :


display Name displayWorkflowApproverName()
{
    WorkflowTrackingStatusTable     workflowTrackingStatus;
    WorkflowTrackingTable           workflowTrackingTable;
    WorkflowTrackingCommentTable    workflowTrackingCommentTable;
    UserInfo                        userInfo;
    Name                            _name;


    select firstFast RecId, User from workflowTrackingTable
        order by RecId desc
            join workflowTrackingCommentTable
        where workflowTrackingCommentTable.WorkflowTrackingTable == workflowTrackingTable.RecId
            join UserInfo
        where UserInfo.id == WorkflowTrackingTable.User
            exists join workflowTrackingStatus
        where workflowTrackingTable.WorkflowTrackingStatusTable == workflowTrackingStatus.RecId
    && workflowTrackingStatus.ContextRecId      == this.RecId
    && workflowTrackingStatus.ContextTableId    == tableNum(CICGBCreditCommittal)
    && workflowTrackingTable.TrackingType       == WorkflowTrackingType::Approval;

    if (workflowTrackingTable.RecId > 0)
    {
        _name=userInfo.name;
    }

    else
    {
        _name='';
    }
    return _name;
}

SSRS Report with multi select lookup parameter

  Contract Class with Param Methods :-       

       [
            DataContractAttribute,
            SysOperationContractProcessingAttribute(classStr(CIC_CreditReportUIBuilder)),
            SysOperationGroupAttribute('Date', "@SYS7402", '1',FormArrangeMethod::Vertical)
        ]
       
        public class CIC_CreditReportContract implements SysOperationValidatable, SysOperationInitializable
        {
            TransDate           fromDate;
            TransDate           toDate;
                 
            List                     agentBroker, policy, profitCenter, userId, businessTypeId, requestor;
       
        }

======================================================================

public void initialize()
        {
            this.parmFromDate(systemdateget());
            this.parmToDate(nextyr(systemdateget() - 1));
        }

=======================================================================

       [
            DataMemberAttribute('FromDate'),
            SysOperationLabelAttribute(literalstr("@SYS4083")),
            SysOperationHelpTextAttribute(literalstr("From date")),
            SysOperationGroupMemberAttribute('Date'),
            SysOperationDisplayOrderAttribute('1')
        ]
        public TransDate parmFromDate(TransDate _fromDate = fromDate)
        {
            fromDate = _fromDate;
            return fromDate;
        }

========================================================================
   
       [
            DataMemberAttribute('ToDate'),
            SysOperationLabelAttribute(literalstr("@SYS8828")),
            SysOperationHelpTextAttribute(literalstr("To date")),
            SysOperationGroupMemberAttribute('Date'),
            SysOperationDisplayOrderAttribute('2')
        ]
        public TransDate parmToDate(TransDate _toDate = toDate)
        {
            toDate = _toDate;
            return toDate;
        }

======================================================================

       [
            DataMemberAttribute('Approver'),
            AifCollectionTypeAttribute("Approver", Types::String),
            SysOperationLabelAttribute(literalstr('Approver')),
            SysOperationHelpTextAttribute(literalstr('Workflow Approver')),
            SysOperationGroupMemberAttribute('Date'),
            SysOperationDisplayOrderAttribute('4')
        ]
        public List parmUserId(List _userId = userId)
        {
            userId = _userId;
       
            return userId;
        }

=======================================================================
        [
            DataMemberAttribute('ProfitCenter'),
            AifCollectionTypeAttribute("ProfitCenter", Types::String),
            SysOperationLabelAttribute(literalstr('ProfitCenter')),
            SysOperationHelpTextAttribute(literalstr('ProfitCenter')),
            SysOperationGroupMemberAttribute('Date'),
            SysOperationDisplayOrderAttribute('5')
        ]
        public List parmProfitCenter(List _profitCenter = profitCenter)
        {
            profitCenter = _profitCenter;
       
            return profitCenter;
        }

========================================================================
         public boolean validate()
        {
            boolean ret = true;
            if (!fromDate)
            {
                 fromDate = systemdateget();
            }
       
            if (!toDate)
            {
                toDate = systemdateget();
            }
            if (toDate < fromDate)
            {
                ret = checkFailed("@SYS16982");
            }
            return ret;
        }
=======================================================================

UI Builder Class


public class CIC_CreditReportUIBuilder extends SrsReportDataContractUIBuilder
        {
            CIC_CreditReportContract    creditReportContract;
        }

=======================================================================

public void getFromDialog()
        {
            creditReportContract contract = this.dataContractObject();
            super();
        }

======================================================================

public void initializeFields()
        {
            creditReportContract contract = this.dataContractObject();
        
        }
=======================================================================

private void lookupApprover(FormStringControl _formStringControl)
        {
            SysLookupMultiSelectGrid            msCtrlApprover;
        
            msCtrlApprover = SysLookupMultiSelectGrid::construct(_formStringControl, _formStringControl);
            msCtrlApprover.parmQuery(this.approverQuery());
            msCtrlApprover.run();
        
        }

=======================================================================

private Query approverQuery()
        {
            Query       query;
            query = new query();
        
            query.addDataSource(tableNum(UserInfo));
            query.dataSourceTable(tableNum(UserInfo)).addSelectionField(fieldNum(UserInfo,Id));
            query.dataSourceTable(tableNum(UserInfo)).addSelectionField(fieldNum(UserInfo,Name));
        
            return query;
        }

========================================================================

private void lookupProfitCenter(FormStringControl _formStringControl)
        {
            SysLookupMultiSelectGrid            msCtrlProfitCenter;
        
            msCtrlProfitCenter = SysLookupMultiSelectGrid::construct(_formStringControl, _formStringControl);
            msCtrlProfitCenter.parmQuery(this.profitCenterQuery());
            msCtrlProfitCenter.run();
        
        }

========================================================================

private Query profitCenterQuery()
        {
            Query                   query;
            QueryBuildDataSource    qbds, qbds1;
            DimensionAttribute      dimAttr;
            define.DimensionName("ProfitCenter")
        
            query = new query();
            dimAttr         = DimensionAttribute::findByName("Profitcenter");
            qbds    =   query.addDataSource(tableNum(DimensionFinancialTag));
            qbds.addSelectionField(fieldNum(DimensionFinancialTag,Value));
            qbds.addSelectionField(fieldNum(DimensionFinancialTag,Description));
            qbds1   =   qbds.addDataSource(tableNum(DimensionAttributeDirCategory));
            qbds1.addLink(fieldNum(DimensionFinancialTag,FinancialTagCategory),fieldnum(DimensionAttributeDirCategory,RecId));
            qbds1.addRange(fieldNum(DimensionAttributeDirCategory, DimensionAttribute)).value(queryvalue(dimAttr.recid));
            qbds1.addSelectionField(fieldNum(DimensionAttributeDirCategory,DimensionAttribute));
        
            return query;
        
        }

=======================================================================

public void build()
        {
            Dialog dialogObject =  this.dialog();
        
            creditReportContract =  this.dataContractObject();
        
            dialogObject.addGroup('Date');
            this.addDialogField(methodstr(CIC_CreditReportContract,parmFromDate),creditReportContract);
            this.addDialogField(methodstr(CIC_CreditReportContract,parmToDate),creditReportContract);
        
            dialogObject.addGroup('Customer');
            this.addDialogField(methodstr(CIC_CreditReportContract,parmUserId),creditReportContract);
            
 this.addDialogField(methodstr(CIC_CreditReportContract,parmProfitCenter),creditReportContract);
        }

=======================================================================

public void postBuild()
        {
            DialogField                 dialogFromDate;
            DialogField                 dialogToDate;
            DialogField                 dialogApprover;
            DialogField                 dialogProfitCenter;
          
        
            super();
        
            dialogApprover          = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(CIC_CreditReportContract,parmUserId));
            dialogProfitCenter      = this.bindInfo().getDialogField(this.dataContractObject(), methodStr(CIC_CreditReportContract,parmProfitCenter));
            
           
        
            dialogApprover.registerOverrideMethod(methodStr(FormStringControl, lookup),
                                                  methodStr(CIC_CreditReportUIBuilder, lookupApprover), this);
            dialogProfitCenter.registerOverrideMethod(methodStr(FormStringControl, lookup),
                                                  methodStr(CIC_CreditReportUIBuilder, lookupProfitCenter), this);
            
        }

=======================================================================

public void postRun()
        {
            creditReportContract contract = this.dataContractObject();
        }

=======================================================================

RDP Class

        [
            SRSReportQueryAttribute(querystr(CICGBCreditReport)),
            SRSReportParameterAttribute(classstr(CIC_CreditReportContract))
        ]
        class CIC_CreditReportDP  extends SRSReportDataProviderBase
        {
            CICGBCreditCommittal            cicGBCreditCommittal;
            CICCreditReportTmp              cicCreditReportTmp;
            DirPerson                                dirPerson;
            CustTrans                               custTrans;
            VendTable                              vendTable;
            FromDate                               fromDate;
            ToDate                                   toDate;
            List                                       intermediary,
                                                         profitCenter,
                                                        userId;
                                            
            ListIterator                           literator;
            define.FromDate('FromDate')
            define.ToDate('ToDate')
        
        }

======================================================================

        [
            SRSReportDataSetAttribute('CICCreditReportTmp')
        ]
        public CICCreditReportTmp getcicCreditReportTmp()
        {
            select cicCreditReportTmp;
            return cicCreditReportTmp;
        }

=======================================================================

private void insertIntoTempTable()
        {
            cicCreditReportTmp.PolicyNumber             = cicGBCreditCommittal.Policy;
            cicCreditReportTmp.Endorsement              = cicGBCreditCommittal.Endorsement;
            cicCreditReportTmp.ClientName               = cicGBCreditCommittal.CustomerName;
            cicCreditReportTmp.CreditAmount             = cicGBCreditCommittal.PremiumAmount;
            cicCreditReportTmp.CreditDays               = cicGBCreditCommittal.CreditDays;
            cicCreditReportTmp.UnderwritersNarration    = cicGBCreditCommittal.OperationRemarks;
            cicCreditReportTmp.FinanceRemarks           = cicGBCreditCommittal.FinanceRemarks;
            cicCreditReportTmp.CreditStatus             = cicGBCreditCommittal.CreditApprovalStatus;
            cicCreditReportTmp.RecNo                    = cicGBCreditCommittal.VoucherNo;
            cicCreditReportTmp.AmountPaid               = cicGBCreditCommittal.VoucherAmount;
            cicCreditReportTmp.Approver                 = cicGBCreditCommittal.Approver;
            cicCreditReportTmp.Requestor                = cicGBCreditCommittal.Requestor;
            cicCreditReportTmp.RequestDate              = cicGBCreditCommittal.RequestDate;
            cicCreditReportTmp.OverDueDays              = date2num(cicGBCreditCommittal.DueDate) - date2num(systemDateGet());
            cicCreditReportTmp.OutsCreditAmount         = custTrans.remainAmountMST();
            cicCreditReportTmp.IntermediaryCode         = custTrans.CICAgentBroker;
            cicCreditReportTmp.Channel                  = custTrans.CICChannelDesc;
            cicCreditReportTmp.RecDate                  = custTrans.TransDate;
            cicCreditReportTmp.IntermediaryName         = vendTable.name();
            cicCreditReportTmp.Profitcenter             = custTrans.CICProfitcenter;
        
        
            if (businessTypeId)
            {
                cicCreditReportTmp.BusinessType    = cicBusinessType.Name;
            }
            else
            {
                select firstOnly Name from cicBusinessType
                    where cicBusinessType.BusinessTypeId == CustTrans.CICBusinessType;
        
                if (cicBusinessType)
                {
                    cicCreditReportTmp.BusinessType = cicBusinessType.Name;
                }
            }
        
            cicCreditReportTmp.insert();
        }

======================================================================

[AifDocumentCreateAttribute, SysEntryPointAttribute(true)]
        public void processReport()
        {
            Query                   query;
            QueryRun                qr;
            QueryBuildRange         qbdRange, custTransQbr,businessTypeQbr,userInfoQbr,cicGBCreditCommittalQbr,profitCenterQbr;
            QueryBuildDataSource    custTransQbds, businessTypeQbds,userInfoQbds,cicGBCreditCommittalQbds, profitCenterQbds;
        
        
            CIC_CreditReportContract contract = this.parmDataContract() as CIC_CreditReportContract;
        
            fromDate            = contract.parmFromDate();
            toDate              = contract.parmToDate();
            userId              = contract.parmUserId();
            profitCenter        = contract.parmProfitCenter();
        
            //Checking for null date
            if (!fromDate)
            {
                fromDate = systemdateget();
            }
             //Checking for null date
            if (!toDate)
            {
                toDate = systemdateget();
            }
        
            query = this.parmQuery();
        
            if(fromDate && toDate)
            {
                query.dataSourceTable(tableNum(CustTrans)).addRange(fieldNum(CustTrans,TransDate)).value(SysQuery::range(fromDate, todate));
        
            }
        
                   
            if(!userId.empty())
            {
                literator = new ListIterator(userId);
                cicGBCreditCommittalQbds = query.dataSourceTable(tableNum(CICGBCreditCommittal));
                userInfoQbds             = cicGBCreditCommittalQbds.addDataSource(tableNum(UserInfo));
                userInfoQbds.addLink(fieldNum(CICGBCreditCommittal,Approver),fieldNum(UserInfo,name));
        
                while (literator.more())
                {
                    userInfoQbr              =  userInfoQbds.addRange(fieldNum(UserInfo,name));
                    userInfoQbr.value(literator.value());
                    literator.next();
                }
            }
        
                   
            if(!profitCenter.empty())
            {
                literator = new ListIterator(profitCenter);
                custTransQbds = query.dataSourceTable(tableNum(custTrans));
                profitCenterQbds =  custTransQbds.addDataSource(tableNum(DefaultDimensionView));
                profitCenterQbds.addLink(fieldNum(custTrans,DefaultDimension),fieldNum(DefaultDimensionView,DefaultDimension));
                while (literator.more())
                {
                    profitCenterQbr =  profitCenterQbds.addRange(fieldNum(DefaultDimensionView, DisplayValue));
                    profitCenterQbr.value(literator.value());
                    literator.next();
                }
            }
        
                    
            qr = new QueryRun(query);
        
            while (qr.next())
            {
                custTrans            = qr.get(tableNum(custTrans));
                cicGBCreditCommittal = qr.get(tableNum(cicGBCreditCommittal));
        
               if(custTrans.Voucher)
               {
                    select firstOnly AccountNum from vendTable
                        where VendTable.AccountNum == custTrans.CICAgentBroker;
                  //vendTable = vendTable::find(custTrans.CICAgentBroker);
                  this.insertIntoTempTable();
               }
             }
        
        }

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

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