AX 2012: Existing DIXF service for new AOS instance

Product:

Dynamics AX 2012

Purpose:

The purpose of this document is to explain what we can do to reuse a DIXF service of an existing AOS instance for a new AOS instance

Steps:

Copy paste the following files from the bin folder of an existing AOS instance to the bin folder of the new AOS instance:

  • DMFClientConfig.xml
  • DMFConfig.xml
  • Microsoft.Dynamics.AX.Framework.Tools.DMF.ServiceProxy.dll.config
Advertisements

D365FO: Data entity filter on enum field

To filter data entity using an enum field, we need to use a specific query expression syntax. For example, to filter Purchase order header data entity, PurchaseOrderHeadersV2, to get only ‘Confirmed’ purchase orders, we can add filter to DocumentApprovalStatus entity field which sources its value from VersioningDocumentState enum like below:

https://usnconeboxax1aos.cloud.onebox.dynamics.com/data/PurchaseOrderHeadersV2?$filter=DocumentApprovalStatus eq Microsoft.Dynamics.DataEntities.VersioningDocumentState’Confirmed’

Untitled

As you can see below the query filter successfully filters Purchase order header entity to get only ‘Confirmed’ purchase orders:

Untitled

AX 2012: Create SSRS Line Chart Report

MakItemSalesHistory

 

Purpose:

The purpose of this document is to demonstrate how we can leverage the power of business intelligence through a simple SSRS line chart report.

Prerequisites:

  1. Visual Studio 2013
  2. Visual Studio 2013 tools.
  3. Reporting extension.
  4. Report Builder.
  5. Should be well-versed in Report Programming Model.

Business requirement:

Leverage business intelligence by analyzing sales trends for top item groups over the period of time.

Project overview:

MakItemSalesHistoryProject

Development:

We will be following the Report Programming Model to develop a precision design report.

1. Create an InMemory table, MakItemSalesHistoryTmp. This table will be used as a data set for the report in Visual Studio.

MakItemSalesHistory

2. Create an AOT query, MakItemSalesHistory. This query will be used in the Data Provider class to fetch records for the report.

MakItemSalesHistory

3. Create a data provider class, MakItemSalesHistoryDP. Bind the AOT query with it.

[
    SRSReportQueryAttribute(queryStr(MakItemSalesHistory))
]
class MakItemSalesHistoryDP extends SRSReportDataProviderBase
{
    MakItemSalesHistoryTmp  makItemSalesHistoryTmp;
}
[
    SRSReportDataSetAttribute(tableStr(MakItemSalesHistoryTmp))
]
public MakItemSalesHistoryTmp getItemSalesHistoryTmp()
{
    select makItemSalesHistoryTmp;
    return makItemSalesHistoryTmp;
}
private void insertTmpTable(SalesLine _salesLine)
{
    Qty                 qty;
    Date                shipDate;
    InventItemGroupItem groupItem;

    qty = _salesLine.QtyOrdered;
    shipDate = _salesLine.ShippingDateConfirmed;
    groupItem = InventItemGroupItem::findByItemIdLegalEntity(
        _salesLine.ItemId,
        _salesLine.DataAreaId);

    ttsBegin;
    makItemSalesHistoryTmp.clear();
    makItemSalesHistoryTmp.ItemId = _salesLine.ItemId;
    makItemSalesHistoryTmp.ItemGroupId = groupItem.ItemGroupId;
    makItemSalesHistoryTmp.Price = _salesLine.salesPrice;
    makItemSalesHistoryTmp.Amount = _salesLine.SalesPrice * Qty;
    makItemSalesHistoryTmp.Qty = qty;
    makItemSalesHistoryTmp.Year = year(shipDate);
    makItemSalesHistoryTmp.MonthOfYearId = mthOfYr(shipDate);
    makItemSalesHistoryTmp.Days = dayOfMth(shipDate);
    makItemSalesHistoryTmp.insert();
    ttsCommit;
}
[SysEntryPointAttribute(false)]
public void processReport()
{
    Query                   query;
    QueryRun                queryRun;
    QueryBuildDataSource    qbds;
    QueryBuildRange         qbr;
    SalesLine               salesLine;
    InventItemGroup         ItemitemGroup;

    query = this.parmQuery();
    qbds = query.dataSourceTable(tableNum(InventItemGroupItem));
    qbds.name("InventItemGroupItem");

    qbr = qbds.addRange(fieldNum(InventItemGroupItem, ItemGroupId));
    qbr.value(strFmt('((%1.%2 == "Speakers") || (%1.%2 == "Television"))',
        qbds.name(),
        fieldStr(InventItemGroupItem, ItemGroupId)));

    queryRun = new queryRun(query);

    while (queryRun.next())
    {
        salesLine = queryRun.get(tableNum(salesLine));
        this.insertTmpTable(salesLine);
    }
}

4. Create a controller class, MakItemSalesHistoryController. You can observe, how the report dialog has been suppressed in the controller.

class MakItemSalesHistoryController extends SrsReportRunController
{
}
static void main(Args _args)
{
    MakItemSalesHistoryController controller;

    controller = new MakItemSalesHistoryController();
    controller.parmReportName(ssrsReportStr(MakItemSalesHistory, LineChart));
    controller.parmArgs(_args);
    controller.parmShowDialog(false);
    controller.startOperation();
}

5. In Visual Studio 2013

  • Create a new Project
  • Add new Report to the solution.
  • Add new Dataset, MakItemSalesHistoryTmp, of type Report Data Provider.
  • Choose MakItemSalesHistoryDP class in the Query.
  • Add new precision design, LineChart, to the report Designs node.

MakItemSalesHistory

6. Edit LineChart using Designer.
7. Insert a new Chart report item from the Toolbox.

MakItemSalesHistory

8. Double click on the chart area to open the field editor, add the following fields as specified.

Field Drop area
Year, MonthOfYearId Category
ItemGroupId Series
Qty Data

9. Next, you can improve the aesthetics of the chart, as it pleases, by updating different chart properties available out of the box in Visual Studio.
10. Save, build and deploy the report.
11. Create an output menu item and bind it with the SSRS report.

MakItemSalesHistory

12. Add menu item to Sales and marketing > Reports > Sales orders > Item sales history.
13. You should be able to see the report in the Report viewer.

MakItemSalesHistory

AX 2012: Automated build deployment process

Purpose:

The purpose of this document is to describe how we can deploy automated builds to different Dynamics AX pre-production environments so that newly developed features could be rolled-out for UAT. The document also illustrates how version controlling by TFS and data migration activities fit into the big picture.

Business requirement:

Ability to release, deploy automated builds to different Dynamics AX pre-production environments to roll-out newly developed features, bug fixes for testing.

Assumptions:

  • Dynamics AX Management Utilities have been installed and configured.
  • Build scripts have been installed and configured.

AX pre-production servers topology:

ax-pre-production-environments

Process:

  1. ISV model server (Optional)
    1. Only applicable when an ISV model needs to be updated in the next build.
    2. TFS Force sync.
    3. Perform full compile, full CIL, DB synchronization.
    4. Export ISV model.
  2. Build server
    1. Must have 2 AOS instances, build and deploy. Both must not be connected to TFS.
    2. Copy ISV model to file system.
    3. Uninstall existing ISV model from build instance.
    4. Uninstall existing ISV model from deploy instance.
    5. Install new ISV model to build instance.
    6. Install new ISV model to deploy instance.
    7. Restart AOS service of build instance.
    8. Restart AOS service of deploy instance.
    9. Perform full compile, full CIL, DB synchronization on build instance.
    10. Perform full compile, full CIL, DB synchronization on deploy instance.
    11. Run build command, buildax.ps1, on build instance.
      1. Output is CUS model file created on the file system.
    12. Run deploy command, deployax.ps1 on deploy instance.
      1. Output is modelstore file created on the file system.
  3. ConsTest server
    1. Copy modelstore file to file system.
    2. Import modelstore file via powershell.
    3. Restart AOS service.
    4. Perform full compile, full CIL, DB synchronization.
  4. Document newly developed features and bug fixes in release notes.
  5. Email the notification and release notes to business stake holders.

AX 2012: Create AIF document service

Purpose:

The purpose of this document is to illustrate how we can develop AIF document service, what are the important methods available that can be overridden to do the customization and finally how we can consume/unit test the document service through an external .NET application.

Business requirement:

Ability to integrate Dynamics AX with external systems.

Assumptions:

Application Integration Framework (AIF) has been configured to process inbound and outbound messages.

Development:

  • Create an AOT query. Prefix it with Axd to follow the naming convention for document service.
  • Run AIF document service wizard to generate/regenerate:
    • Document class (Axd class).
      • Represents whole business document.
      • Used to perform cross-table validations.
      • Serializes/deserializes the document to/from XML.
    • Document object class
      • Object interface to whole business document.
    • Data object classes
      • Object interface to underlying tables involved in the document.
    • AxBC classes, if chosen
      • Wrapper classes for underlying tables involved in the document.
      • Used to perform table-level validations.
        • For example, AxSalesLine.validateWrite method.
        • It then calls validateWrite method of SalesLine table.
      • Used by Axd class to create, read, update, delete data in tables.
    • Service class
      • Contains the service operations in the form of methods.
    • Service node
      • Exposes service operations to inbound/outbound ports
  • Change namespace property of service node (optional).
  • Generate incremental CIL.
  • Register the service
  • Create security privilege for each service operation (optional).
  • Create an enhanced inbound port
  • Choose an adapter
    • File system adapter
    • HTTP
    • ISABEL SEPA credit transfer
    • MSMQ
    • NetTcp
    • Windows Azure Service Bus
  • Choose service operations
  • Activate

Important methods:

  • Axd class
    • prepareForSave/prepareForSaveExtended method
      • Validation code goes here.
      • For example checkSalesTable method in AxdSalesOrder class.
    • updateNow method
      • Business logic to be executed post insert/update of document.
      • For example, post receipt in II7.
    • expandSurrogateForeignKeys method
      • To automatically resolve surrogate foreign keys to natural keys.
    • getSurrogateForeignKeyValue method
      • To manually resolve surrogate foreign keys to natural keys.
  • AxBC class
    • initMandatoryFieldsExemptionList method
      • To make a field optional which is mandatory at the table level.
    • initMandatoryFieldsMap method
      • To make a field mandatory which is optional at the table level.
    • set<Field> method
      • To set default value of a field in service.
      • This method calls parm method to set the default value.
      • For example, setLineNum method of AxSalesLine class.
      • It calls parmLineNum method of AxSalesLine class.

Consuming service:

  • Create console application in Visual Studio
  • Add service reference
  • Sometimes, setting some fields doesn’t work in C#. We use “<Field>Specified” parameters for them.
  • For example:
    • Course.Name = “Name”;
    • Course.NameSpecified = true;
    • Course.Description = “Desc”;
    • Course.DescriptionSpecified = true;

AX 2012: Create AIF custom service

Purpose:

The purpose of this document is to illustrate how we can develop AIF custom service.

Business requirement:

Ability to integrate Dynamics AX with external systems.

Assumptions:

Application Integration Framework has been configured to process inbound and outbound messages.

Development:

  1. Create a data contract class.
    1. Use [DataContractAttribute(‘Name’)] attribute to indicate class represents data contract.
    2. Use [DataMemberAttribute(‘Name’)] attribute to indicate method represents data member.
    3. Use [AifCollectionTypeAttribute] attribute to define parameter and return types.
  2. Create a service class.
    1. Set RunOn property of class to Server.
    2. Create a method attributed with [SysEntryPointAttribute(true)] to designate it as a service operation.
    3. The boolean parameter of attribute defines whether AOSAuthorization property of tables will be checked or not in this method.
  3. Create a service contract by creating service node.
  4. Add service operation.
  5. Create a service group for the basic inbound port.
  6. Deploy the service group.
  7. The inbound port created must be activated now.