Friday, September 9, 2016

This table method can be used to reset fields values to their default. We don't want to use clear() because for TempDB clear can remove the link between table on TempDB and Ax buffer.
public void resetFields()
{
    SysDictTable dictTable  = SysDictTable::newTableId(this.TableId);
    Set fields              = dictTable.fields();
    SetEnumerator setEnum   = fields.getEnumerator();
    SysDictField dictField;

    while(setEnum.moveNext())
    {
        dictField = setEnum.current();
        if(!dictField.isSystem())
            this.(dictField.id()) = nullValueFromType(dictField.baseType());
    }
}

Wednesday, August 10, 2016

Calling an external RESTful Web Service from X++

With the following Job you can consume an External RESTful Web Service:
static void ConsumingRestService(Args _args)
{
    str destinationUrl = 'http://<server>/<service>', requestXml, responseXml;
    System.Net.HttpWebRequest       request;
    System.Net.HttpWebResponse      response;
    CLRObject                       clrObj;
    System.Byte[]                   bytes;
    System.Text.Encoding            utf8;
    System.IO.Stream                requestStream, responseStream;
    System.IO.StreamReader          streamReader;
    System.Exception                ex;

    requestXml = ""
        +"<XML>"
        +"</XML>";

    try
    {
        clrObj = System.Net.WebRequest::Create(destinationUrl);
        request = clrObj;

        utf8 = System.Text.Encoding::get_UTF8();
        bytes = utf8.GetBytes(requestXml);

        request.set_ContentType("text/xml; encoding='utf-8'");
        request.set_ContentLength(bytes.get_Length());
        request.set_Method("POST");

        requestStream = request.GetRequestStream();
        requestStream.Write(bytes, 0, bytes.get_Length());

        response = request.GetResponse();

        responseStream = response.GetResponseStream();
        streamReader = new System.IO.StreamReader(responseStream);
        responseXml = streamReader.ReadToEnd();

        info(responseXml);
    }
    catch (Exception::CLRError)
    {
        //bp deviation documented
        ex = CLRInterop::getLastException().GetBaseException();
        error(ex.get_Message());
    }


    requestStream.Close();
    streamReader.Close();
    responseStream.Close();
    response.Close();

}

Thursday, May 5, 2016

Print table fields

static void PrintTableFieldName(Args _args)
{
    SysDictTable    dictTable = SysDictTable::newTableId(tableNum(CustParameters));
    SysDictField    dictField;
    Set             fields = dictTable.fields(true, true, true);
    SetEnumerator   setEnum = fields.getEnumerator();

    while (setEnum.moveNext())
    {
        dictField = setEnum.current();
        info(dictField.label());
    }
}

Tuesday, May 3, 2016

Example of how to handle formdatasource multiselection through args:

public static void main(Args _args)
{
    Common                  record = _args.record();
    FormDataSource          fds;
    MultiSelectionHelper    multiSelectionHelper;

    if(!record || !record.dataSource())
        throw error(Error::wrongUseOfFunction(funcName()));

    fds = record.dataSource();

    multiSelectionHelper = MultiSelectionHelper::construct();
    multiSelectionHelper.parmDatasource(fds);

    record = multiSelectionHelper.getFirst();
    while (record)
    {
        // function here
        record = multiSelectionHelper.getNext();
    }
}

Send via AIF multiple records to outbound file

If you have a requirement to send more than one record per XML as an outbound, then have a look on the following job:
static void AifSendCustomerFromQuery(Args _args)
{
    AxdSendContext                  axdSendContext      = AxdSendContext::construct();
    AifAction                       aifAction;
    AifConstraint                   aifConstraint       = new AifConstraint();
    AifConstraintList               aifConstraintList   = new AifConstraintList();
    AifOutboundProcessingService    aifOutboundProcessingService = new AifOutboundProcessingService();
    AifGatewaySendService           aifGatewaySendService = new AifGatewaySendService();
    AifActionId                     actionId;
    AifEndpointList                 endpointList;
    Query                           query;
    QueryBuildDataSource            queryBuildDataSource;
    ;

    query = new Query(queryStr(AxdCustomer));
    AxdSend::removeChildDs(query);
    queryBuildDataSource = query.dataSourceTable(tablenum(CustTable));
    queryBuildDataSource.addRange(fieldnum(CustTable, RecId));
    queryBuildDataSource.rangeField(fieldnum(CustTable, RecId)).value(strfmt('5637144577..5637144587'));

    aifAction = AifAction::find(AifSendService::getDefaultSendAction(
                                                        classnum(CustCustomerService), 
                                                        AifSendActionType::SendByQuery));

    axdSendContext.parmXMLDocPurpose(XMLDocPurpose::Original);
    axdSendContext.parmSecurity(false);

    aifConstraint.parmType(AifConstraintType::NoConstraint);
    aifConstraintList.addConstraint(aifConstraint) ;

    endPointList = AifSendService::getEligibleEndpoints(aifAction.ActionId,aifConstraintList);

    AifSendService::submitFromQuery(aifAction.ActionId, endpointList, query, AifSendMode::Sync);

    AifGatewaySendService.run();
    AifOutboundProcessingService.run();
}

Thursday, April 21, 2016

Insert a dynamic message bar on forms

Display a message bar on the form like the following:

...and here the code:
public static client boolean showMessageBar(FormRun formRun, str _message)
{
    #define.AddressActionBar('_gab_MessageActionBar')
    #define.MessagePane('Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessagePane')
    #define.Assembly('Microsoft.Dynamics.Framework.UI.WinForms.Controls, Culture=neutral, 
                                             PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL')
    #define.MessageBar('Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessageBar')

    FormManagedHostControl  messageBarHost;
    Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessagePane messagePane;
    Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessageBar messageBar;
    Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessageBarType messageBarType;
    boolean show = true;

    formRun.lock();

    messageBarHost = formRun.design().controlName(#AddressActionBar);
    if (!messageBarHost && show)
    {
        messageBarHost = formRun.design().addControl(FormControlType::ManagedHost, 
                                                                   #AddressActionBar, null);
        // This is a bit non-obvious. addControl() will add the control at the bottom of the form.
        // MoveControl() without the second parameter will move it to be the first control.

        // This will position the message bar under any of the Action Panes
        FormRun.design().moveControl(messageBarHost.id());

        messageBarHost.assemblyName(#Assembly);
        messageBarHost.typeName(#MessagePane);
        messageBarHost.widthMode(FormWidth::ColumnWidth);
        messageBarHost.sizing(Sizing::SizeToContent);
        messagePane = messageBarHost.control();

        messageBarType =
               Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessageBarType::InformationOnly;

        messageBar = new Microsoft.Dynamics.Framework.UI.WinForms.Controls.MessageBar();
        messageBar.set_Text(_message);
        messageBar.set_MessageBarType(messageBarType);

        messagePane.Add(messageBar);
    }

    if (messageBarHost)
    {
        messageBarHost.visible(show);
    }

    formRun.unLock();

    return show;
}

Tuesday, April 19, 2016

Run AIF import and export manually

Here is a job to run import and export manually, so you don’t have to wait for the batch jobs:
static void AIFImportExport(Args _args)
{
    // Inbound (import)
    new AifGatewayReceiveService().run();
    new AifInboundProcessingService().run();

    // Outbound (export)
    new AifOutboundProcessingService().run();
    new AifGatewaySendService().run();

    info("AIF import/export done");
}