Tuesday, November 25, 2014

Creating a class object using X++

The following Job shows the code used for creating a "Class" using X++ code. This code may be used in scenarios like AIF service, Workflow generation etc processes where different objects like "Class" are created automatically using the similar code mentioned below.

static void BlogTestJob(Args _args)
{
    ClassBuild  classBuild;
    str         header;
    str         newClassName = "SampleClass";
    ;

    header = 'public class '+ newClassName;
    classBuild = new ClassBuild(newClassName);
    classBuild.addMethod('classdeclaration', header + '\n{\n}\n');
    classBuild.addMethod('main', 'public static void main(Args    _args)' + '\n{\n}\n');
    classBuild.classNode().AOTcompile(1);

    info('Job completed....');
}

Monday, November 24, 2014

Importing Sales order XML using X++

The following job will create Sales order using Document service through X++ code.

static void JobTestWebService_ImportXml(Args _args)
{
    //feed the xml that was modified after exporting through exportxml job
    XmlDocument xml = XmlDocument::newFile(@'C:\SORequest.xml');
    AxdSalesOrder salesOrder;

    try
    {
        salesOrder = new AxdSalesOrder();
        salesOrder.create(xml.xml(),  new AifEndPointActionPolicyInfo(), new AifConstraintList());
    }
    catch
    {
        throw error('Error in document service');
    }
    info(strFmt('Sales order created'));
}

Sample XML File

<?xml version="1.0" encoding="utf-8" ?>
<SalesOrder xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/SalesOrder">
<SalesTable class="entity">
  <CustAccount>1204</CustAccount>
  <DeliveryDate>2011-10-11</DeliveryDate>
  <ReceiptDateRequested>2011-11-11</ReceiptDateRequested>
  <PurchOrderFormNum>ABC-98654</PurchOrderFormNum>
<TableDlvAddr class="entity">
<Address>KEVIN DAVIS 13075 MANCHESTER RD STE 228.A  DES PERES, MO 631311878 </Address>
<City>DES PERES</City>
<CountryRegionId>USA</CountryRegionId>
<County>JEFFERSON</County>
<ISOcode>US</ISOcode>
<LocationName>KEVIN DAVIS</LocationName>
<State>MO</State>
<Street>13075 MANCHESTER RD STE 228.A </Street>
<ValidFrom>2014-11-11T00:00:00Z</ValidFrom>
<ValidTo>2014-11-11T00:00:00Z</ValidTo>
<ZipCode>631311878</ZipCode>
</TableDlvAddr>
  <SalesLine class="entity">
<ItemId>0001</ItemId>
<SalesQty>20</SalesQty>
<SalesPrice>82.25</SalesPrice>
<SalesUnit>Pcs</SalesUnit>
  </SalesLine>
</SalesTable>

</SalesOrder>

Exporting XML Sales order using AIF service

The following job will export the Sales order information into an XML format which can be used by document service in order to test Sales order creation using XML.

static void JobTestWebService_ExportXml(Args _args)
{
    AxdAddress address;
    AxdSalesOrder salesOrder;

    AifEntityKey    key;
    Map             map;

    //dummy variable
    AifPropertyBag bag;

    map = new Map(Types::Integer, Types::Container);
    map.insert(fieldnum(SalesTable, SalesId), ['SO-101327']);
    
    key = new AifEntityKey();
    key.parmTableId(tablenum(SalesTable));
    
    key.parmKeyDataMap(map);

    try
    {
        address = new AxdAddress();
        salesOrder = new AxdSalesOrder();
        info('XML output');
        info(salesOrder.read(key, null, new AifEndPointActionPolicyInfo(), new AifConstraintList(), bag));
    }
    catch
    {
        throw error('Error in document service outbound');
    }
}

Filter records on form using X++

This post will shows the steps required to filter records on form using parameters provided by the caller.

Step 1
Declare a class variable 
In the ClassDeclaration method of form declare a QueryBuildRange

class FormRun extends ObjectRun
{
    QueryBuildRange      abcQueryRange;
    ABC                  abcCode;
}

Step 2
Initialize this range in the init method of datasource after super() call.

public void init()
{
    super();
    abcQueryRange = this.query().dataSourceName('X').addRange(fieldnum(X, ABC));

}

Step 3
Now assign the filter value in the executeQuery method of same datasource before super() call.

public void executeQuery()
{
    if (abcCode)
    {
        abcQueryRange.value(queryValue(abcCode));
    }
    super();

}

The query filtration part is done, you now need to fetch the value of "abcCode" from the caller. For this you need to grab the values from argument passed by the caller in the "init" method form.


public void init()
{
    if (element.args().record())
    {
        if (element.args().record().TableId == tablenum(x))
        {
            abcCode
 = X::findRecId(element.args().record().RecId).abcCode;
        }
    }
    super();

}