Thursday, 29 August 2013

Passing Data Data to Form with a Temporary Data Source X++ AX 2012

Scenario - Let us suppose we wanted to pass some data to a form, but the requirement mandates that this data source be a temporary table.

I developed this for a vertical I was built for AX 2012. Take a look at the data flow diagram below.




Once we have that data into the temp table we can process it, for example if we are dealing with financial entries we can post the entries as  JV.

Lets begin with a temporary table.

Step 1 - Create a new table and specify the table type property to "Temp DB". Remember this should be a replica of the table you want to query.


Step 2 Create a query of the original table.

From the AOT go to "Queries" and create a new query. Add the original table as the data source.

Step 3 Create the Form

 Create a simple grid form and add the temp table as the data source.



Next Override the following methods.

 //Override the form's init method  
 public void init()  
 {  
   super();  
   ITLPDCDetailsTmp_ds.autoQuery(false);  
 }  
 //Override the datasources's init method  
 public void init()  
 {  
   super();  
   PDCDetailsTmp.linkPhysicalTableInstance(element.args().record());  
 }  

Step 4 Create the Class

Now in the class we are going to need a dialog to open up so we can query the original data source.

Basically we want the dialog to look like this.



The yellow box are normal dialog fields that i haves added to the dialog box, but let us focus on ht green box. The green box is highlighting the query that we created.

Class Declarations 

In order to use a query on a dialog box we the class has to extend "RunBase". If you want to add a batch to the dialog the class has to extend "RunBaseBatch" Along with extending "RunBase" there are a few other required methods, for adding a query to a dialog.

  1. Dialog
  2. GetFromDialog
  3. New
  4. Pack 
  5. Unpack
  6. QueryRun
  7. showQueryValues
  8. runImpersonated
  9. Description

 Public class ITLPDCSelectionPost extends RunBase  
 {  
   DialogField         dlgFieldFromDate;  
   DialogField         dlgFieldToDate;  
   DialogRunbase      dialog;  
   QueryRun          qr;  
   Query             q;  
   PDCDetails         PDCDetail ;  
   PDCDetailsTmp  PDCDetailTmp;;  
   ITLARNTable         ITLARNTable;  
   TransDate          FromDate;  
   TransDate          ToDate;  
   Form              form;  
   Args               args;  
    #DEFINE.CurrentVersion(1)  
 }  

Dialog Method

 /// <summary>  
 ///  Returns a class that contains the methods that are described by the <c>RunBaseDialogable</c>  
 ///  interface.  
 /// </summary>  
 /// <returns>  
 ///  A class that contains the methods that are described by the <c>RunBaseDialogable</c> interface.  
 /// </returns>  
 /// <remarks>  
 ///  A dialog can be either built by using the <c>Dialog</c> class or by using a class that is created  
 ///  in the Application Object Tree (AOT).  
 /// </remarks>  
 public Object dialog()  
 {  
   dialog     = super();  
   dlgFieldFromDate  = dialog.addField(extendedTypeStr(TransDate), "From Date");  
   dlgFieldToDate   = dialog.addField(extendedTypeStr(ToDate),"To Date");  
   return dialog;  
 }  

GetFromDialog Method

 public boolean getFromDialog()  
 {  
   fromDate = dlgFieldFromDate.value();  
   ToDate  = dlgFieldToDate.value();  
   return super();  
 }  

  New Method

 public void new()  
 {  
   super();  
   qr = new QueryRun(querystr(PDCDetailsQuery));  
 }  

Pack  Method

 public container pack()  
 {  
    return [#CurrentVersion,qr.pack()];  
 }  

Unpack Method

 public boolean unpack(container packedClass)  
 {  
   Integer   version   = conpeek(packedClass,1);  
   container  packedQuery;  
   switch (version)  
   {  
     case #CurrentVersion :  
       [version,packedQuery] = packedClass;  
       if (packedQuery)  
         qr = new QueryRun(packedQuery);  
       break;  
     default :  
       return false;  
   }  
   return true;  
 }  

QueryRun Method

 /// <summary>  
 ///  Retrieves the instance of the <c>QueryRun</c> class, which is used by the <c>queryPrompt</c> method.  
 /// </summary>  
 /// <returns>  
 ///  The instance of the <c>QueryRun</c> class, which is used by the <c>queryPrompt</c> method.  
 /// </returns>  
 /// <remarks>  
 ///  This method is used if a query prompt is the dialog and if a select menu item is added to a dialog.  
 ///  Do not create the instance of the <c>QueryRun</c> class when this method is called. Do it in the  
 ///  <c>unpack</c> method and the <c>initParmDefault</c> method, or in the <c>init</c> method.  
 /// </remarks>  
 public QueryRun queryRun()  
 {  
   return qr;  
 }  

showQueryValues Method

 /// <summary>  
 ///  Determines whether to add a select button to the dialog.  
 /// </summary>  
 /// <returns>  
 ///  Always returns true.  
 /// </returns>  
 /// <remarks>  
 ///  If you click this button, it will show the query form. Therefore, the <c>queryRun</c> method has to  
 ///  return a valid <c>queryRun</c> .If you change the return value to false the button will no longer  
 ///  be added.  
 /// </remarks>  
 boolean showQueryValues()  
 {  
   return true;  
 }  

runImpersonated Method

 /// <summary>  
 ///  Determines whether the batch task is run on the server or on a client.  
 /// </summary>  
 /// <returns>  
 ///  Always returns true.  
 /// </returns>  
 /// <remarks>  
 ///  Your classes that extend the this class must override the <c>runsImpersonated</c> method and return  
 ///  false, if you want those tasks to run on a client.  
 /// </remarks>  
 public boolean runsImpersonated()  
 {  
   return true;  
 }  

Description Method

 client server static ClassDescription description()  
 {  
   return "Select PDC Booking";  
 }  


Now create a new method that will be used to populate the records form your "original table" and insert them into your "temp table".

Populate Records - Queries and Inserts the records in to the temp table

 
PDCDetailsTmp PopulateRecords()  
 {  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, PDCdate)).value(strFmt('%1..%2', FromDate, ToDate));  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, PDCStatus)).value(enum2str(ITL_PDCStatus::Open));  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, PDCStatus)).value(enum2str(PDCStatus::Bounced));  
   qr.query().dataSourceTable(tableNum(PDCDetails)).addRange(fieldNum(PDCDetails, isGenerated)).value(enum2str(NOYes::Yes));  
   ttsbegin;  
   while (qr.next())  
   {  
     PDCDetail = qr.get(tableNum(PDCDetails));  
     if(_PDCDetail.PDCAmount)  
     {  
       _PDCDetailTmp.CustAccount = _PDCDetail.CustAccount;  
       _PDCDetailTmp.PDCAmount = _PDCDetail.PDCAmount;  
       _PDCDetailTmp.PDCDate = _PDCDetail.PDCDate;  
       _PDCDetailTmp.PDCStatus = _PDCDetail.PDCStatus;  
       _PDCDetailTmp.PDCNumber = _PDCDetail.PDCNumber;  
       _PDCDetailTmp.RecRefId = _PDCDetail.Recid;  
       _PDCDetailTmp.DueDate = _PDCDetail.DueDate;  
       _PDCDetailTmp.InstallmentNumber = _PDCDetail.InstallmentNumber;  
       _PDCDetailTmp.BankAccountNum = _PDCDetail.BankAccountNum;  
       _PDCDetailTmp.CustBankAccountId = _PDCDetail.CustBankAccountId;  
       _PDCDetailTmp.ITLSARDAte = _PDCDetail.SARDate;  
       _PDCDetailTmp.ITLSARID = _PDCDetail.SARID;  
       _PDCDetailTmp.toPost = NoYes::Yes;  
       _PDCDetailTmp.insert();  
     }  
   }
   return _PDCDetailTmp;
 }  


Now we have our run method which will open our form. So in the run method our task will be to pass the TempTable we inserted data into to the forms datasource.

Run Method

 /// <summary>  
 ///  Contains the code that does the actual job of the class.  
 /// </summary>  
 public void run()  
 {  
   //Call the Populate Records Method  
   this.PopulateRecords();  
   args = new Args();  
   args.object(form);  
   //Set the Args Record to the Temp Table we Inserted Data into)  
   args.record(_PdcDetailTmp);  
   //Open the form and pass args  
   new MenuFunction(menuitemDisplayStr(PDCPostingSelection), MenuItemType::Display).run(args);  
 }  

Main Method

 static void main(Args _args)  
 {  
   PDCSelectionPOSt  PDCSelectionPOSt;  
   ;  
   if (PDCSelectionPOSt.prompt())  
     PDCSelectionPOSt.run();  
 }  

 



No comments:

Post a Comment