Thursday, June 27, 2013

AX 2012 Post Partial Sales Order using x++ code

In Dynamics AX 2012, we often need to post Sales Order using x++ code. It is very easy to post complete sales order using x++ code by utilizing the SalesFormLetter class. However, what if we need to post the sales order partially and not all the lines.

We have a chooseLinesQuery() method available in SalesFormLetter class that accepts a query object to post only the lines you want to post. See example below.

    SalesTable salesTable;
    SalesFormLetter salesFormLetter;
    Query query;
    QueryRun queryRun;
    QueryBuildDataSource qbds;

    query = new Query(QueryStr(SalesUpdatePackingSlip));
    qbds = query.dataSourceTable(tableNum(SalesLine));

    // Build query range to find those lines which needs to be posted.
    qbds.addRange(fieldNum(SalesLine, mzkBillingDate)).value(queryValue(systemDateGet()));
    qbds.addRange(fieldNum(SalesLine, SalesStatus)).value(queryValue(SalesStatus::Backorder));
    queryRun = new queryRun(query);

    salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice);
    salesFormLetter.chooseLinesQuery(queryRun);
    salesFormLetter.update(salesTable);


Tuesday, June 18, 2013

AX 2012 AIF cannot set field value from .net application

I was working with one of the AIF document services in Dynamics AX 2012. I was trying to create general journal record from .net application but I noticed that few of my field values were not getting saved in AX. AIF will not throw any error, records were getting created but few fields were missing values even I provided the values.

For example:
ledgerJournalTrans.AmountCurCredit  = Convert.ToInt64(500.00);
           
I was trying to set the Credit value like above but I could not. I then found that we can set the specified attribute for such fields to true and then AIF will consider to set the values for these fields. See example below.

ledgerJournalTrans.AmountCurCreditSpecified = true;

When I added this statement, everything started to work as expected.

Sunday, June 16, 2013

Understanding types of AIF services in AX 2012

Dynamics AX 2012 offers different type of services that can be used to perform several operations. It is very important to understand which type of service should be used to perform your desired operation.

There are 3 types of services that are available in Microsoft Dynamics AX 2012.


  1. Document Services
    • Document services are services which expose a business entity. For example, Customer, Vendor, Employee, Sales Order.
    • You can Map the business entity using Query and run through Document Service Wizard to build the web service and perform CRUD operations.
  2. Custom Services
    • To expose a custom x++ logic. 
    • Say, you have a custom module and you want to expose some logic/code to your custom application.
  3. System Services
    • System services are kind of utility services.
    • Up and running when AOS starts.
    • Can be used for interactive clients 
    • Build Ad-hoc query

Wednesday, June 5, 2013

AX 2012 Email templates

While performing several operations in Dynamics AX 2012. We often need to send emails to the users that includes some dynamic information that needs to be included in the email or we can say we need to generate email body on the fly. For example, if I need to send email to several worker, I would like to change the worker name for every email.

Dynamics AX 2012 offers email templates for that purpose, we can use variables in email templates and then swap their values at runtime while sending emails.

First of all, you will need to define an email template. To do this go to Organization Administration à Setup à Email templates.

Once the email templates form is open, create a new email template and give it a name of your choice and fill other fields like Sender email, Sender name, default language etc in both the grids. On the bottom grid, select HTML as Layout.

After the template is created, click on Email message button, this will give you an editor window where you can compose your message. See a sample message below.

Dear %WorkerName%
You have been assigned a project, please find the details below
Event Id: %ProjectId%
Event Name: %ProjectName%


Regards.

Notice the variables defined with % sign, they will be replaced with appropriate values using the following code.

Go to the event from which you want to send the email, for example a button click event and then write following code.

SysEmailId sysEmailId = ProjParameters::find('EmailTemplateName');
Map mappings;
str recepient;
HcmWorker worker;
ProjTable projTable;

worker = HcmWorker::find(_worker);
projTable = projTable::find(_projId);

if (worker && projTable)
{
        recepient = worker.email();

        mappings = new Map(Types::String,Types::String);
        mappings.insert("WorkerName", worker.name()); // this will replace variable with actual value.
        mappings.insert("ProjectId", projTable.ProjId);
        mappings.insert("ProjectName", projTable.Name);

        SysEmailTable::sendMail(sysEmailId,
                        SysEmailTable::find(sysEmailId).DefaultLanguage,
                        recepient,
                        mappings,
                        "",
                        "",
                        true,
                        curUserId(),
                        true);
    }

That's it!!! your email will be sent with appropriate values using the mappings defined above.


Tuesday, June 4, 2013

Execute custom code when a record is inserted using AIF in AX 2012

Dynamics AX 2012 offers a very easy to use wizard to generate AIF services that can be used to perform CRUD operations from any other third party app.

We often need to perform some other operations that needs to have some business logic written to perform some operations.

For the explaination purpose, we will take the example of Sales Order.

One requirement could be to post the Sales Order automatically to AX once it is created in the system. Dynamics AX 2012 provides us the service that can create sales order. However, if you also need to post the Sales Order when it is created using AIF, you will need to write some custom code that can perform this operation for you whenever a Sales Order is created.

The method that will be called after inserting record is the updateNow() method of the Axd<Table> class and for Sales Order, it would be updateNow method of AxdSalesOrder class to perform our operation to post the Sales Order.

We can create our own method in the same class or some other helper class and then call that custom method from the updateNow method to get things done.

See the sample code:
public void updateNow()
{
    // call your custom method here
    AxdSalesOrderHelper::postSalesOrderConfirmation(salesTable);
   
}

Steps for debugging AIF services

In Dynamics AX 2012, debugging AIF code requires certain operations to be performed before you can actually debug the code. Follow these simple steps to debug the AIF service code using Visual Studio


  1. Open Visual Studio
  2. From Application Explorer (Ctrl + D), go to classes, Open the class you want to debug, expand the methods node, right click and select "View code"
  3. Before putting the breakpoint, Go to the Debug menu, select Attach to process, point to Ax32Serv.exe and then click Attach button.
  4. On the status bar, you will see loading symbols...
  5. Once all the symbols are loaded and status bar shows "Ready", put the breakpoint and run your service (either by third party app or batch job) and then you will be able to debug the code.
Also, note that while debugging the code, you will not be able to see the values for the variables by simply hovering the mouse over the variable so you need to insert the variable to the watch list either by using drag/drop or by right click and choosing add to watch.

AIF, execute business logic when all the records in XML are inserted.

While working with Dynamics AX 2012 AIF services. Sometimes, you need to perform some operation once all the records in the XML file are inserted in the table.

For example, let's say you call Sales order service to create 10 Sales order and passed one xml file having 10 sales orders and then you need to perform some operation like posting each sales order ONLY when all the sales order are created. To achieve this, you need to override the createList() method on Axd<Table> class and then you can perform your operations in that method by iterating all the records passed in the xml file.

To see this running, please see the AxdSalesOrder class that implements such functionality.