Monday, July 30, 2012

Creating and Posting Inventory ProfitLoss journals in DAX using .NET Business Connector


using System;
using Microsoft.Dynamics.BusinessConnectorNet;

namespace ProfitLossPostingAppl
{
    class AxProfitLossPostingEngine
    {
        static void Main(string[] args)
        {
            Axapta ax = new Axapta();
            // company name, language, object server, configuration
            // this uses Windows Authentication
            ax.Logon("cmul", null, "localhost", null);
            
            try
            {
                // Start a transaction
                ax.TTSBegin();

                // AxaptaRecord is a class that allows to work with Tables in AX
                AxaptaRecord header = ax.CreateAxaptaRecord("InventJournalTable");
                AxaptaRecord journalName = ax.CreateAxaptaRecord("InventJournalName");
                AxaptaRecord line = ax.CreateAxaptaRecord("InventJournalTrans");
                AxaptaRecord inventTable = ax.CreateAxaptaRecord("InventTable");
                AxaptaRecord warehouse = ax.CreateAxaptaRecord("InventDim");

                // You can call static table methods using the following syntax
                journalName = ax.CallStaticRecordMethod("InventJournalName", "find", "IPL") as AxaptaRecord;

                // There is a set of predefined methods on the AxaptaRecord class, like the clear(), initValue, DML operations, etc.
                header.Clear();
                header.InitValue();
                // You can call table object methods as well, not only static
                header.Call("initFromInventJournalName", journalName);
                header.Insert();

                line.Clear();
                line.InitValue();
                line.Call("initFromInventJournalTable", header);
                // You cannot use table fields directly as in X++. Instead you have set/get methods
                line.set_Field("itemId", "B-R14");

                // Instead of using static table methods (like find) you can execute a direct SQL statement and receive the result in the AxaptaRecord object
                inventTable.ExecuteStmt("select * from %1 where %1.ItemId == 'B-R14'");
                // If you receive more that one record you can iterate through them using Next (as in AX)
                line.Call("initFromInventTable", inventTable);

                line.set_Field("Qty", 160.0);

                warehouse.Clear();
                warehouse.set_Field("InventLocationId", "MW");

                warehouse = ax.CallStaticRecordMethod("InventDim", "findOrCreate", warehouse) as AxaptaRecord;
                
                line.set_Field("InventDimId", warehouse.get_Field("inventDimId"));
                line.Insert();

                // Notice AxaptaRecord is passed by reference here
                ax.CallStaticRecordMethod("InventJournalTable", "initTotal", header);
                header.Update();

                ax.TTSCommit();
                
                // You can call static class methods the same way you call table static methods, but using a different method on Axapta class
                // So in case you wrote the posting in X++, you would be able to call it, passing the JournalId as the argument
                // int numOfLinesPosted = (int)ax.CallStaticClassMethod("DEV_ProfitLossEngine", "postProfitLossJournal", header.get_Field("JournalId"));
                
                // Or, you can use the AxaptaObject class to accomplish the same from C# 
                // You can initialize a new class using the Axapta class method
                // AxaptaObject journalCheckPost = ax.CreateAxaptaObject("InventJournalCheckPost");
                
                // Or using a static method, if that suites your needs better
                // Notice here that an object of type AxaptaRecord is passed into a method that expects InventJournalTable as the argument
                AxaptaObject journalCheckPost = ax.CallStaticClassMethod("InventJournalCheckPost", "newPostJournal", header) as AxaptaObject;
                // You can object methods the same way you would on a table
                journalCheckPost.Call("parmShowInfoResult", false);
                journalCheckPost.Call("parmThrowCheckFailed", true);
                journalCheckPost.Call("parmTransferErrors", false);
    
                journalCheckPost.Call("run");
                int numOfLinesPosted = (int)journalCheckPost.Call("numOfPostedLines");

                Console.WriteLine(String.Format("{0} line(s) have been successfully posted", numOfLinesPosted));
                Console.WriteLine("JournalId is " + header.get_Field("JournalId"));
                Console.WriteLine("Press any key to continue ...");

                ax.Logoff();
            }
            catch (Exception ex)
            {
                ax.TTSAbort();
                ax.Logoff();

                Console.WriteLine(ex.Message);
            }

            Console.ReadKey();
        }
    }
}

Thursday, July 26, 2012

Table and field Finding


static void testing(Args _args)
{
    TreeNode            node;
    TreeNode            childNode;
    TreeNodeIterator    nodeIt;
    FilePath            path;
    str             Property;
    identifiername  Type,Mandatory;
    ;


    path        = @'\Data dictionary\Tables\PFSComponentTypes\Fields';
    node        = TreeNode::findNode(path);
    nodeIt      = node.AOTiterator();
    childNode   = nodeIt.next();


    while(childNode)
    {
        //info(childNode.treeNodeName());
        ///info(childNode.AOTname());
        Property    = childNode.AOTgetProperties();
        Type        = findproperty(Property, 'Type');
        Mandatory   = findproperty(Property, 'Mandatory');
        info(strFmt("-%1-%2-%3",childNode.AOTname(),Type,Mandatory));
        childNode = nodeIt.next();
    }
}

Friday, July 13, 2012

AX 2012 : Delete All Transactions

We need to modify the SysDatabaseTransDelete.handletable method with the below code :

void handleTable(SysDictTable sysDictTable)

{

    TableGroup      tableGroup;

    if (tableSet.in(sysDictTable.id()))

        return;

    tableSet.add(sysDictTable.id());

    if (sysDictTable && !sysDictTable.isTmp() && !sysDictTable.isMap())

    {

        tableGroup = sysDictTable.tableGroup();

        // Handle company specific tables to be deleted

        if (sysDictTable.dataPrCompany())

        {

            switch(tableGroup)

            {

                case TableGroup::Transaction:

                case TableGroup::WorksheetHeader:

                case TableGroup::WorksheetLine:

                //FIX - Support new AX2012 transaction table types

                case TableGroup::TransactionHeader:

                case TableGroup::TransactionLine:

                    this.handleTransTable(sysDictTable);

                    break;

                default:

                    this.handleNonTransTable(sysDictTable);

                    break;

            }

        }

        else

        {

            // Handle global tables to be deleted

            switch(tableGroup)

            {

                case TableGroup::Transaction:

                case TableGroup::WorksheetHeader:

                case TableGroup::WorksheetLine:

                //FIX - Support new AX2012 transaction table types

                case TableGroup::TransactionHeader:

                case TableGroup::TransactionLine:

                    this.handleGlobalTransTable(sysDictTable);

                    break;

                default:

                    break;

            }

        }

    }

}

How to identify the user that was used to change an object from AOT in AX2012

Get the object name for which we need to track these (user and date&time) information's. Login to SQL Server Management Studio an...