Search This Blog

Tuesday, September 13, 2011

List All forms From AOT

Sample code lists all the forms from AOT

static void krishh_listAllForms(Args _args)
{
     #AOT
    TreeNode tNode;
    XInfo  xinfo=new XInfo();
    Counter    cntr;
    ;
    tNode=xinfo.findNode(#FormsPath);
    tNode=tnode.AOTFirstChild();
    while(tNode)
    {
         info(tNode.treeNodeName());
         tNode=tnode.AOTnextSibling();
         cntr++;
    }
}

AX2012 Certifications

Monday, September 12, 2011

Computed Column to a View in AX 2012

This post describes how you can add a computed column to a view in Microsoft Dynamics AX.
A computed column is the output of a computation that inputs a regular column.

For example, suppose your table has a column that is named AnnualRent. Your view could return a computed column that is named MonthlyRent and which calculates AnnualRent/12.

You can add the computed column to the select list of columns only. If the computed column is itself a select statement with a where clause, you can include the name of a real column in that where clause.

Create a View
In this section you create a view named TestCompColView.
  1. Click AOT > Data Dictionary > Views > New View.
  2. Right-click the new View1 node, and then click Properties.
  3. In the Properties window, change the Name property to TestCompColView.
  4. Expand the Views > TestCompColView > Metadata > Data Sources node.
  5. Open a second AOT window and drop the node AOT > Data Dictionary > Tables > CustTable onto the TestCompColView > Metadata > Data Sources node in the first AOT window.
  6. Expand the TestCompColView > Metadata > Data Sources > CustTable_1 > Fields node.
  7. In the other AOT window, expand the TestCompColView > Fields node.
  8. From under the TestCompColView > Metadata > Data Sources > CustTable_1 > Fields node, drop the AccountNum field onto the TestCompColView > Fields node of the other AOT. Also drop the SubsegmentId field in the same way.
  9. Click TestCompColView > Save.
Add a Static Method to the View
The technique to add a computed column begins with you adding a static method to the view. The method must return a string. The system automatically concatenates the returned string with other strings that the system generates to form an entire T-SQL create view statement.
 
The method that you add to the view typically has at least one call to the DictView.computedColumnString method. The parameters into the computedColumnString method include the name of a data source on the view, and one field name from that data source. The computedColumnString method returns the name of the field after qualifying the name with the alias of the associated table. For example, if the computedColumnString method is given the field name of AccountNum, it returns a string such as A.AccountNum or B.AccountNum.

Steps to add a method to a view

  1. Under AOT > Data Dictionary > Views, expand the node for your TestCompColView view that you created in the previous section.
  2. Under your view, click Methods > New Method. The method editor window is displayed.
  3. Change the method definition to the following:
    private static server str compColSubsegAcctMethod()
Code in the Body of the Method

private static server str compColSubsegAcctMethod()
{
    #define.ViewName(TestCompColView)
    #define.DataSourceName("CustTable_1")
    #define.FieldSubsegmentId("SubsegmentId")
    #define.FieldAccountNum("AccountNum")
    str sReturn,
        sAccountNum,
        sSubsegmentId;
    DictView dictView2;

    // Construct a DictView object for the present view.
    dictView2 = new DictView(tableNum(#ViewName));

    // Get a string that has the target field name
    // propertly qualified with an alias (such
    // as "A." or "B.").
    sAccountNum = dictView2.computedColumnString
        (#DataSourceName,
        #FieldAccountNum,
        FieldNameGenerationMode::FieldList,
        true);

    sSubsegmentId = dictView2.computedColumnString
        (#DataSourceName,
        #FieldSubsegmentId,
        FieldNameGenerationMode::FieldList,
        true);

    sReturn = "substring("
        + sSubsegmentId
        + ",1,1) + ' - ' + "
        + sAccountNum;

    // Helpful confirming or diagnostic information.
    info(sAccountNum);
    info(sSubsegmentId);
    info(sReturn);

    return sReturn;
}
Add a Computed Column to the View 
In this section you add a computed column to the view.
  1. Right-click the Fields node under your view, and then click String Computed Column.
  2. For the new field or column, change the Name property to compCol_Subseg_Acct.
  3. Change the StringSize property to 32.
Link the Computed Column to the Method
In this section you relate the computed column to the static method that you added in a previous section.
  1. For the computed column, you set the ViewMethod property to the name of the compColSubsegAcctMethod method that you wrote in a previous step.
See the Data in the Computed Column
 
The data that is generated for the computed column can be seen by using the AOT. Click AOT > Data Dictionary > Views > TestCompColView > Open.

Sample Data from the View

The following table displays sample data that includes the computed column.
SubsegmentId AccountNum CompCol_Subseg_Acct
Medium 4000 M - 4000
Gross 4001 G - 4001

Installation of Object ID's in AX2012

Installation-specific IDs What can you do? Microsoft Dynamics AX 2009 Microsoft Dynamics AX 2012 Why is this important?
Object IDs such as table IDs, field IDs, and class IDs are now installation specific. With this change, you no longer need to worry about conflicting object IDs in different installations. Objects IDs were assigned when a model element was created. When a new model element is saved, imported, or installed, a unique ID is assigned to the model element at that installation site.
For example, when a new class is added by a developer and saved to the model store, the class will be assigned a class ID. But when the same class is imported to another installation at a customer site, the class ID may be different to the ID assigned in the first installation site.
The new object IDs assigned for Microsoft Dynamics AX 2012 installations are greater than the previous object ID range and will not conflict with any of the earlier versions of Microsoft Dynamics AX.
In an upgrade scenario, object IDs are preserved because they are automatically assigned to the new LegacyId property on the application objects.
With installation-specific IDs, conflicts are avoided because an ID is not assigned until installation time.
Because the assignment of the object IDs is handled at the installation site, the Team Server is no longer required to manage IDs. Team Server is no longer installed, and version control setup is no longer dependent on Team Server

AX2012 Unit of Work

A record gets RecId value at the moment it is inserted into the database. What if we are doing bulk insert of a journal with many lines and the journal header contains some totals calculated based on its lines. It is impossible to insert lines before header since the value of the journal's surrogate key is unknown. But that would be so convenient because otherwise the header should be inserted first, then the lines and then the header should be updated with the calculated totals.

The answer is – use Unit of Work. It allows to perform create, update and delete operations without worrying about the order of those and without a need to specify surrogate key values. It will all be done automatically in the kernel

Let us do some sample-
Create the following Tables


















After Creating the tables create a job for doing the insertion for the above tables using UnitOfWork.




















 















Some more details about the unit of work feature:
All database operations happen only when unitofwork.saveChanges() method is invoked.
  1. UnitOfWork class has insertOnSaveChanges(), updateOnSaveChanges() and deleteOnSaveChanges() methods for CUD operations.
  2. Surrogate keys can be propagated automatically to related records if buffers are linked via navigation methods (AJournalLine.header() method in the example). Navigation methods can be created automatically from relations. I’ll write a separate post about them.
AX client has the great support of the unit of work as well.
This means that form datasources can be grouped into a unit of work.

Friday, September 9, 2011

AX2012 BOF (Business operation framework)

Business Operation Framework (BOF) [AX 2012]
The Business Operation Framework service is one of the system services exposed by Microsoft Dynamics AX and that adheres to the Windows Communication Foundation (WCF) protocols and standards.
This service enables you to  develop the Service and attach that service to BOF

·         Allows menu-driven execution or batch execution of services.
·         Calls services in synchronous or asynchronous mode.
·         Automatically creates a customizable UI based on the data contract.
·         Encapsulates code to operate on the appropriate tier (prompting on the client tier, and business logic on the server tier).

SysOperationServiceController
ServiceClassName
SysOperationExecutionMode
Enums

Overview
To create a Business Operation Framework service, the following steps must be performed.
·         Create a data contract class
·         Identify the parameters passed to the service
·         Register the class as a Business Operation Framework service
·         Optionally customize the automatically generated UI for the class
Create a data contract class
Create one or more classes to define the parameters for the operation.
The X++ attribute [DataContractAttribute] identifies the class as a data contract class.

[DataContractAttribute]
class SimpleDataContract
{
    int property1;
    str property2;
}
Identify parameters
The X++ attribute [DataMemberAttribute] identifies the property accessor methods, which are the parameters to the service call.

[DataMemberAttribute]
public int property1(int _property1 = property1)
{
    property1 = _property1;
    return property1;
}

[DataMemberAttribute]
public str property2(str _property2 = property2)
{
    property2 = _property2;
    return property2;
}
The data contract class can have properties that return data contract classes for more complex scenarios.
Register service
After the data contract classes are defined, creating the service operation is simple.

class SimpleService
{
}

public str operation1(SimpleDataContract _dataContract)
{
    str returnValue;

    returnValue = strfmt('Input was %1, %2',
        _dataContract.property1(),
        _dataContract.property2());

    return returnValue;
}
To register this class as a service, the following steps must be performed.
1.       The class must be marked to run on the server.
2.       The class must be registered in Application::registerServices.

void registerServices()
{

    xApplication::addXppService(new DictClass(classnum(SimpleService)));
}

Generate and customize the UI for the class
When the Business Operation Framework service executes, the framework will automatically generate a UI for the operation by reflecting on the data contract class and building a dialog. No further work is required if the generated UI is adequate.
However, if you wish to modify the automatically generated UI, you can make those modifications two ways: Attribute-based customization and code-based customization.
Attribute-based UI customization
In most scenarios attribute based customization is sufficient.
To add a UI group for the parameters, add a SysOperationGroupAttribute to the DataContractAttribute:

[DataContractAttribute,
    SysOperationGroupAttribute('group1', "@SYS1001", '1')]
class SimpleDataContract
{
    int property1;
    str property2;
}
To order property2 before property1 within group1, and use labels on both properties:
[DataMemberAttribute,
    SysOperationGroupMemberAttribute('group1'),SysOperationLabelAttribute('SYS1002'),SysOperationHelpTextAttribute('SYS1003'),SysOperationDisplayOrderAttribute('2')]
public int property1(int _property1 = property1)
{
    property1 = _property1;
    return property1;
}

[DataMemberAttribute,
    SysOperationGroupMemberAttribute('group1'),SysOperationLabelAttribute('SYS3000'),SysOperationHelpTextAttribute('SYS301868'),SysOperationDisplayOrderAttribute('1')]
public str property2(str _property2 = property2)
{
    property2 = _property2;
    return property2;
}
Code-based UI customization
Note: I could not find information in the spec on code-based UI customization.
 
A Business Operation Framework service can be called in four ways:
As a menu item or as a batch process. And it can be called synchronously or asynchronously.
To call a Business Operation Framework service from a menu item
1.       Create an Action Menu Item
2.       Set the ObjectType to Class
3.       Set the Object to SysOperationServiceController
4.       Set the Parameters to <ServiceClassName>.<MethodName>
To call a Business Operation Framework service as a batch operation
To execute a batch operation:
static void Job2(Args _args)
{
    SimpleDataContract parameters = new SimpleDataContract();
    SimpleService service = new SimpleService();
    str returnValue;
   
    parameters.property1(99);
    parameters.property2('Hello World');
   
    returnValue = service.operation1(parameters);
    info(returnValue);
}
To call a Business Operation Framework service synchronously
To run the service synchronously, edit the menu item:
1.       Set the EnumTypeParameter to SysOperationExecutionMode
2.       Set the EnumParameter to Synchronous
After the service operation is complete, the result will be displayed in the InfoLog.
To call a Business Operation Framework service asynchronously
To run the service asynchronously, edit the menu item:
1.       Set the EnumTypeParameter to SysOperationExecutionMode
2.       Set the EnumParameter to Asynchronous
After the service operation is complete, the result will be displayed in the InfoLog.

AX2012 Table Inheritance And Type Hierarchies

One of the huge, underlying changes from a architecture, and really database design point of view for Microsoft Dynamics AX 2012 is the use of Type or Table Hierarchies.

This is actually extending upon the type hierarchy system that already existed within Dynamics AX, however to a whole new level!

Looking at the AOT as a new add-in for Microsoft Dynamics AX 2012. Select Table right click -Addins->typehierarchies browser- which will show the heierarchies of that table.

With this concept, OO Design is being forced onto Relational data. I know, I know, that statement seems like it would be an oxymoron. I mean how can relation data truly be and live with OO attributes, design concepts, and adhere to such rules that govern things like: inheritance & polymorphism?

The answer to that is super normalization! That is what is taking place with Microsoft Dynamics AX 2012 and type hierarchies for Table objects.

Because Microsoft Dynamics AX 2012 manages it's relation database, through a meta layer, then through the combining of these two concepts, such things as inheritance and polymorphism can be applied.

So with this, we now have new attributes of tables, called: concrete or abstract, as well as if a table inherts from another table or not.

In doing this 'extending from' at a table level, the table that extends from an abstract table, inherits the fields and methods of the super or base table being inherited from.

This new approach along, plus just adhereing to BP, means that you should *never* access to the database of an Microsoft Dynamics AX 2012 instance directly. So many reasons why, and with Microsoft Dynamics AX 2012, so many more reasons will exists.

And this is true today actually, should not have direct access to the DB of an AX instance, however it's still done today in certain cases.

AX2012 And Eventing Concepts

One of the great new development improvements for Microsoft Dynamics AX 2012,

For most people, that have ever done any Object oriented development or programming, eventing is a concept that most familiar.

It's is a concept that is used to fire before, just before or just after a given method call takes place. These can also be design within the middle of a method as well, if a given peice of business logic within the middle of a method, make sense to tie an event too.

If you bring this to a more functional level, you can think of eventing as something that happens for a given object. So if you have PackingSlip and Invoice. These are functional concepts represented by technical objects. Classes, business logic, etc.

So when something happens, you can say a Sales Order was invoiced, or packing slip updated.

To help explain, take a look at the following diagram.:


As you can see, we have a basic workflow of functional concepts taking place. We see that the two main functional concepts are PackingSlip and Invoice.

With these two concepts we see two common "events" or a Pre-PackingSlip Update, and a Post-PackingSlip Update. The same is said for Invoice, in that we have a Pre-Invoiced and a Post-Invoiced. What we also see is a custom, Mid-Invoiced event as well.

From this, we see two events that are used to call into CSharp or Xpp business logic, when these events are fired.

One is Post-PackinSlip and the other from the Custom Mid-Invoice event. This, I hope gives a good construct and idea behind the purpose and use of eventing.

You have the ability to "raise" and event, depending on certain actions within business logic. These events, when raised, have listeners, that can then fire into either Xpp code, or CSharp (.Net) developed code.

Moving forward, events are meant to support the following development concepts.:
  • Observation
  • Information dissemintation
  • Decoupling

After getting into what eventing can offer a customer doing custom development, or an ISV offering vertical expertise, we can see how this can help with the pains of upgrading.

So with eventing and Microsoft Dynamics AX 2012, a new possible way to develop custom code for a customer, or as an ISV is offered that has all kinds of great benefits. Everyone that does any development in Microsoft Dynamics AX, that does not undestand eventing, needs to make a priority to understanding eventing.



The above are some great resources to help understand eventings, event, delegates, and technical uses of events from a .Net point of view.

This is very important, as Microsoft Dynamics AX 2012 eventing, is based on .Net Eventing Concepts. What you will see, when looking at eventing in Microsoft Dynamics AX 2012 is.:
  • Producer - business logic or entity that raises an event
  • Consumer - a event listener, or logic called when a specific event is fired
  • Event - the given event called or raised when a process takes place
  • Event Payload - data or information caried within a fired event, for the consumers use
  • Delegate - is defined as informatin that was passed from a producer to a listener or consumer when an event is raised
I hope that you enjoyed this deeper dive into eventing with Microsoft Dynamics AX 2012, and eventing concept. It's a great move, that allows all kinds of possibilities, that all of us .Net developers, who also develop in Xpp have been looking for!