Tuesday, May 24, 2016

Microsoft Dynamics 365 for Operations - Tips and Questions

Deep dive into AX 7 - How development happens and where all source code stores;
With AX 7, the development has moved back to file system, any technical change we make in the application is saved into an XML file.


What does development environment include?
The development environment is the one box deployment of AX 7 with its own local SQL database installed.


What is the format of the source code files?

Source code (Technical changes) are the set of XML files (model elements) onto your disk.

Does AOS require to be running during development?
Visual Studio user interface communicates with source files (XML files) with metadata API. When you build from Visual Studio, you are compiling into assemblies and other binaries that runtime. Through this whole process of development and build, you are working against files and as we all know Visual Studio works very weel with files so technically there is no need for AOS to be running during design and compilation.

Is there any AOS service running anywhere for AX 7?

No, there is no AOS service running into you box for AX 7, unlikely we have had in AX 2012. AOS service is actually a Web Service in IIS and there is a separate service for Batch processing in IIS called Microsoft Dynamics AX Batch Management Service.

What is a Deployment Package?

This is a compiled binary version of the model(s) and Package(s) that can be deployed to Cloud (UAT or Production). Once development or stage or development is complete and you are requires to moved these changes to UAT or to Production, this is where you create deployment package to move your changes.

How X++ code is executed in AX 7?

Executing X++ code, displaying a from, or running a report is integrated with Visual Studio debug (F5, Ctrl-F5) experience. This execution is through the AOS Web Application that is running into the local IIS.

What is model element in AX 7?

Model element (A Class, a table or a form) is simply an XML file sitting onto your disk and they are organized in folders per model.

How Model, Package and a Project related in AX 7?

Several models constitute a Package. A project always belongs to one model, it cannot belong to more than one model.

Where does the Package sit in disk?

Package are folders located in the model store folder of the Dynamics AX 7 Application. Packages can be seen from following path;


Where does the model sit in disk?
Model folders are contained in their Package folder. Each model folder contains type-specific folders, for example; all table in a model belong to the folder AxTable. Models can been seen from following path;




What is a model descriptor?
A Package folder contains a descriptor folder that lists all model that belong the package. A model descriptor file contains metadata about a model's properties. 


Why is there a need for Visual Studio for whole development?
Visual Studio is simply a user interface on top of this architecture it allows you to be more productive and to only do things with the metadata that you are supposed to do instead of basically editing them in XML or in the text editor.

Stay tuned! There is more to cover in future parts of this post...

Happy Dax!ng...

Sunday, May 22, 2016

Microsoft Dynamics 365 for Operations - How Packages and Models live in Visual Studio

In continuation of my previous post on few major technical changes in the world of AX 7, this post is all about to understand the core components of AX 7 development before we jump into AX development IDE in visual studio. Yes, we will write X++ code into Visual Studio by using four components.

There are 4 main components to understand in Visual Studio include Elements, Models, Projects and Packages. To explore more let's have a look at a screenshot of the Application Explorer. Within it, there is an AOT node.


Model(s) and Packages(s) in Visual Studio environment

I am gonna dig dipper into what Model and Package mean?


Model:

  1. Model is a group of elements that represents the particular solution (Tables, Forms, and Classes e.t.c) 
  2. The definition of the Model is similar to what it was in AX 2012 (AX 2012 Models) 
  3. Model is a design time concept. For example A Fleet Management Model, A Project Account Model
  4. A Model may contains multiple Visual Studio projects. However, a project many only belong to one model
  5. All of the sub-nodes below the AOT node are different models, this is call Model View

Package:

  1. A Package is a more of a compilation unit and distribution unit to move binaries and any other runtime artefacts that your model need between environments during the development ALM process. For example; moving them from the development box to the Cloud to run.
  2. A Package typically is one or more Packages typically packages into one we called deployment package and this is the unit that you use to move code to Cloud.
  3. A Package is a deployment unit that may contain one ore more models. In addition to elements, it includes more metadata, which is a description data that defines the properties and behaviour of the model.
  4. A Package can be exported into a file which can then be deployed into a staging or production environment. 

Model in AX 2012 and in AX 7

Model concept in AX 7 is quite similar to what it was in AX 2012. These are the source code so ISV distributing their solutions to partners or to customers are typically giving the models, they don't provide Packages. They provide models that can be installed onto your box, customize them and the move them into your Cloud environment.

Package in AX 2012 and in AX 7
In the AX 2012 world, Package is closer to what we used to call the model store to what we used to call the model files. Because you know they are pre-compiled things that you can deploy to a production or to UAT environment. 

Visual Studio Project and Elements

I am gonna dig dipper into what Project and Element mean?


Visual Studio Projects

  1. Recommended way of development is to create Visual Studio project for all changes and the project always belongs to model, you can think of them is a subset of your model. Why do we have a different concept for model and project? The only reason we have two concepts of a model and a project is, typically AX 7 models are very large and its not a good practice to compile entire model for a simple code change activities during your development.
  2. Project always belongs to a particular model and is basically a subset of elements that belongs a model.
  3. One or more model can constitute a package, typically every package has one model. The reason sometimes we have one or more models in particular package when you customize during overlaying of source code.

Elements

Elements are AOT objects, for example; Base Enums, Extended Data Types, Tables, Classes, Forms, and Menu items and a lot more.

Stay tuned! I will be posting more on how we can use these four components in real development.


Happy Dax!ng

How to: Generate number sequence for new developed module in AX 2012

In this post I am going to create a number sequence for newly developed module in AX 2012. 

1. Add a new element in NumberSeqModule baseenum with your new module name

2. Create a new Class NumberSequenceModuleModuleName extends NumberSequenceModule

3. Override loadModule method by adding the parameters of the sequence

    NumberSeqDatatype datatype = NumberSeqDatatype::construct();

    //Message ID: MessageID is a new EDT of string type
    datatype.parmDatatypeId(extendedtypenum(MessageID));
    datatype.parmReferenceHelp(literalstr("MessageId"));
    datatype.parmWizardIsManual(NoYes::No);
    datatype.parmWizardIsChangeDownAllowed(NoYes::No);
    datatype.parmWizardIsChangeUpAllowed(NoYes::No);
    datatype.parmSortField(2);

    datatype.addParameterType(NumberSeqParameterType::DataArea, true, false);
    this.create(datatype);

4. Override numberSeqModule method

   public NumberSeqModule numberSeqModule()  
   {  
     return NumberSeqModule::NewModule;  
   }  

5. Create new job to load number sequence

   static void MessageIDNumSeqLoad(Args _args)
   {
      NumberSeqApplicationModule::loadAll();
   }  

6. Go to Organisation Administration | Common Forms | Number sequences | Number Sequences | Generate and follow the wizard to end to generate number sequence for new module.

AX 2012 - sysOperation Framework - Use controller class to open dialog from AX form

In my previous post on sysOperation framework Example I described how the sysOperation framework can be used for the batch functionality in contrast to RunBaseBatch framework. In this post I will explain how you can use sysOperation Framework classes to open a dialog from a AX form using contract and controller classes and then run logic in Service class.

In this example I added a new menu item "Example" on projProjectsListPage form which will call controller class. This example is create project transactions using service calls at the end.








First we need to create a contract class which holds parameters (dialog fields value or user input). To keep it simple I only added two parameters ProjId (Project Id) and ProjContractId (Project Contract Id). That's the model part of MVC pattern and view part is automatically created by using these data member attributes.
[DataContractAttribute]
class FF_ExampleContract
{
    ProjId              projId;
    ProjInvoiceProjId   projContractId;
}
[DataMemberAttribute,
SysOperationLabelAttribute(literalStr("Selected Project Id")),
SysOperationHelpTextAttribute(literalStr("Selected Project Id from projects")),
SysOperationDisplayOrderAttribute('1')
]
public ProjId parmProjId(ProjId _projId = projId)
{
    projId = _projId;
    return projId;
}
[DataMemberAttribute,
SysOperationLabelAttribute(literalStr("Selected Project contract Id")),
SysOperationHelpTextAttribute(literalStr("Selected Project Contract Id from projects")),
SysOperationDisplayOrderAttribute('2')
]
public ProjInvoiceProjId parmProjContractId(ProjInvoiceProjId _projContractId = projContractId)
{
    projContractId = _projContractId;
    return projContractId;
}

Let's move to controller part of sysOperation framework and create a new controller class.

For this example I don't need to have batch tab on dialog, so I set return value to FALSE in canGoBatch() method.
class FF_ExampleController extends SysOperationServiceController
{
    Common callerRecord;
}
public static void main(Args _args)
{
    FF_ExampleController controller;
    controller = FF_ExampleController::newFromArgs(_args);
    controller.parmShowDialog(true);
    controller.initFromCaller();
    controller.startOperation();
    controller.refreshCallerRecord();
}
public static FF_ExampleController newFromArgs(Args _args)
{
    FF_ExampleController        controller;
    IdentifierName              className;
    IdentifierName              methodName;
    SysOperationExecutionMode   executionMode;
    [className, methodName, executionMode] = SysOperationServiceController::parseServiceInfo(_args);
    if (_args.record())
    {
        executionMode = SysOperationExecutionMode::Synchronous;
    }
    controller = new FF_ExampleController(className, methodName, executionMode);
    controller.parmArgs(_args);
    controller.parmCallerRecord(_args.record());
    return controller;
}
public LabelType parmDialogCaption(LabelType _dialogCaption = "")
{
    LabelType caption;
    // This appears as the window name
    caption = "Create project transaction";
    return caption;
}
protected void new(
    IdentifierName _className = classStr(FF_ExampleService),
    IdentifierName _methodName = methodStr(FF_ExampleService, example),
    SysOperationExecutionMode _executionMode = SysOperationExecutionMode::ReliableAsynchronous
    )
{
    super(_className, _methodName, _executionMode);
}
private void initFromCaller()
{
    #define.dataContractKey('_contract')
    FF_ExampleContract contract;
    ProjTable       projTable;
    contract = this.getDataContractObject(#dataContractKey) as FF_ExampleContract;
    switch (this.parmCallerRecord().TableId)
    {
        case tableNum(ProjTable) :
            projTable = this.parmCallerRecord() as ProjTable;
            contract.parmProjId(projTable.ProjId);
            contract.parmProjContractId(projTable.ProjInvoiceProjId);
            break;
    }
}
public boolean canGoBatch()
{
    return false;
}
public Common parmCallerRecord(
    Common _callerRecord = callerRecord
    )
{
    callerRecord = _callerRecord;
    return callerRecord;
}
/// <summary>
///    Refreshes the calling form data source.
/// </summary>
protected void refreshCallerRecord()
{
    FormDataSource callerDataSource;
    if (this.parmCallerRecord() && this.parmCallerRecord().dataSource())
    {
        callerDataSource = this.parmCallerRecord().dataSource();
        callerDataSource.research(true);
    }
}

In the new method of controller class it is eventually calling service class method. We could create a method in controller class itself and refer that method into the new method of controller class to process business logic. This seems to be a lot for controller class, first to handle all parameters and then process business logic, recommended way is to separate the business logic in service class and another advantage of having service class is, these operations can also be used in web services (AIF) operations. That's the separate topic and we will talk about it later...

Let's create new service class and add entry point method to process business logic.
class FF_ExampleService
{
    FF_ExampleContract contract;
}
[SysEntryPointAttribute]
public void createProjectTransaction(FF_ExampleContract _contract)
{
    ProjId                  projId;
    ProjInvoiceProjId       projContractId;
    contract            = _contract;
    projId          = contract.parmProjId();
    projContractId  = contract.parmProjContractId();
    /*
   
    .... create project transactions
   
    */
}

Have we achieved what we aimed at start?

We are almost there, just need to add a new action menu item and assign controller & service class to it.




















That's it!!! run the menu item and see how it works...




Click on Example menu item from Project list page, it opened a dialog with correct title 'Create project transactions' and with correct Project Id passed from calling form (ProProjectsListPage). 

Happy Dax!ng...

Saturday, May 7, 2016

AX 2012 - Find company currency through X++

CompanyInfo::standardCurrency() or
Ledger::accountingCurrency(CompanyInfo::current());

AX 2012 - how to use 'NOT LIKE' in AX statements

Please note that I am using ! after 'where' keyword to reverses the effect of 'like' 

static void Not_Like(Args _args)
{
    #define.createdBy('faisal')
    InventTable     inventTable;
   
    while select inventTable
        where !(inventTable.ItemId like 'I*')
    {
        // do your logic  
    }

}