Tuesday, 17 November 2015

Testing Read service in X++

static void TestingService(Args _args)
{
    PurchPurchReqService     customerService;            // Customer Service class
    CustCustomer            customer;                   // Customer Document object
    PurchPurchReq            customerRead;               // Customer Document object
    CustCustomer_CustTable  custTable;                  // CustTable data object
    CustCustomer_CustTable  custTableRead;              // CustTable data object
    AifEntityKeyList        entityKeyList;              // Entity key list
    AifEntityKeyList        entityKeyListFind;          // Entity key list
    AifQueryCriteria        queryCriteria;
    AifCriteriaElement      criteriaElement;
    AccountNum              accountNum;




    // Create the service instance
    customerService =  PurchPurchReqService::construct();


    queryCriteria = new AifQueryCriteria();
    criteriaElement = AifCriteriaElement::newCriteriaElement('VendPurchOrderJour', 'PurchId', AifCriteriaOperator::Equal, 'US1PO0000440');
    queryCriteria.addCriteriaElement(criteriaElement);
    entityKeyListFind = customerService.findKeys(queryCriteria);


    // Read Customer using returned entity key
    customerRead = customerService.read(entityKeyListFind);
    info(customerRead.serialize());
    //custTableRead = customerRead.parmCustTable().get_Item(0);
    //info(strfmt("Read customer: Account Number: %1, Name: %2.", custTableRead.parmAccountNum(), custTableRead.parmName()));





}

Debugging Services in AX 2012

Regardless of the adapter type you choose, services in AX 2012 run as IL code - even if you are using the file adapter.  To debug IL code
you must use Visual Studio.
The steps for debugging a service are:
  1. On the AOS, install the AX Application Explorer from the Microsoft Dynamics AX CD by choosing the
    component Developer Tools, and then click Visual Studio Tools.  If the AX debugger is not installed,
    you will also need to install it.
  2. Open Visual Studio, create a new project, and in the AX Application Explorer find the methods in the
    service classes that are of interest.
  3. In Visual Studio add breakpoints where needed.
  4. Click Debug, and then click Attach to Process.
  5. Mark the checkboxes for Show processes from all users and Show processes in all sessions.
  6. Select AX32Serv.exe and click Attach.The Ax32Serv.exe won't be able available if you are not debugging on the AOS, so
    you need to be on the AOS.
  7. In a separate instance of VS (so have two different projects/solutions open) run the code that calls
    the service.One instance to run the code that
    calls the service and another instance of VS to do the debugging.  By
    having two instances open, you can leave the debugging instance attached to the
    AOS while you run the service code over and over again.

Friday, 13 November 2015

AIF Document services operations

static void AifSample_CustomerService(Args _args)
{

CustCustomerService     customerService;            // Customer Service class
    CustCustomer            customer;                   // Customer Document object
    CustCustomer            customerRead;               // Customer Document object
    CustCustomer_CustTable  custTable;                  // CustTable data object
    CustCustomer_CustTable  custTableRead;              // CustTable data object
    AifEntityKeyList        entityKeyList;              // Entity key list
    AifEntityKeyList        entityKeyListFind;          // Entity key list
    AifQueryCriteria        queryCriteria;
    AifCriteriaElement      criteriaElement;
    AccountNum              accountNum;
    Name                    name;
    ;

    // Create the service instance
    customerService =  CustCustomerService::construct();

    // Create the Customer document object
    customer = new CustCustomer();
    customer.createCustTable();                            // Create the CustTable list
    custTable = customer.parmCustTable().addNew();         // Add CustTable instance to CustTable list

    // Initialize the CustTable instance
   // custTable.parmName("Cust01");
    custTable.parmAccountNum("22220002");
    custTable.parmCustGroup("10");
    custTable.parmCurrency("USD");
    custTable.parmPartyType(DirPartyType::Organization);

    // Create Customer
    entityKeyList = customerService.create(customer);
    accountNum = entityKeyList.getEntityKey(1).parmKeyDataMap().lookup(fieldnum(CustTable, accountnum));
    info(strfmt("Created customer:  Account Number: %1.", accountNum));

    //Creating another Customer
    entityKeyList = customerService.create(customer);
    accountNum = entityKeyList.getEntityKey(2).parmKeyDataMap().lookup(FieldNum(Custtable,accountNum));
    info(strfmt("Created another Customer :  Account Number : %1. ",accountNum));


    // Read Customer using returned entity key
    customerRead = customerService.read(entityKeyList);
    custTableRead = customerRead.parmCustTable().get_Item(0);
    info(strfmt("Read customer: Account Number: %1, Name: %2.", custTableRead.parmAccountNum(), custTableRead.parmName()));

    // Update Customer
    custTableRead.parmName(custTableRead.parmName() + ": Updated Name");
    customerService.update(entityKeyList, customerRead);
    info (strfmt("Updated Customer: Account Number: %1.", custTableRead.parmAccountNum()));

    // Call Read to check update
    customer = customerService.read(entityKeyList);
    custTable = customerRead.parmCustTable().get_Item(0);
    info(strfmt("Read updated customer: Account Number: %1, Name: %2.", custTable.parmAccountNum(), custTable.parmName()));

    // Call FindKeys to find entity keys of matching customer entity keys
    queryCriteria = new AifQueryCriteria();
    criteriaElement = AifCriteriaElement::newCriteriaElement('CustTable', 'CustGroup', AifCriteriaOperator::Equal, '10');
    queryCriteria.addCriteriaElement(criteriaElement);
    entityKeyListFind = customerService.findKeys(queryCriteria);
    info(strfmt("Find customer keys: Result count: %1", entityKeyListFind.getEntityKeyCount()));

    // Call Find to find matching customers
    queryCriteria = new AifQueryCriteria();
    criteriaElement = AifCriteriaElement::newCriteriaElement('CustTable', 'CustGroup', AifCriteriaOperator::Equal, '10');
    queryCriteria.addCriteriaElement(criteriaElement);
    customerRead = customerService.find(queryCriteria);
    info(strfmt("Find customer: Result count: %1", customerRead.existsCustTable()?customerRead.parmCustTable().get_Count():0));

    info("TO DO: To test delete, uncomment delete code in the job.");
    // TODO: UNCOMMENT TO DELETE CUSTOMER
    /*
    // calling deleting customer
    customerService.delete(entityKeyList);
    info(strfmt("Deleted customer:  Account Number: %1.", accountNum));
    */
    pause;

}

Monday, 13 October 2014

Create/Delete Customer using AIF Service Class in Dynamics AX

The Application Integration Framework allows us to create/update/delete or read data. Now in AX2009 we have a facility of creating/deleting records using AIF Service classes. There is "NO ADDITIONAL AIF SETUP"(Like Enabling Endpoints etc.) required to execute the code via service class. The services can be used to read/write data in AX.
X++ service class job is illustrated below. 

tatic void Services_CustTable_Create(Args _args)
{
    // Customer Service class
    CustCustomerService     custService;
    CustCustomer                customer;

    // Data object of Service class
    CustCustomer_CustTable  custTable;
    AifEntityKeyList               entityKeyList;
    AccountNum                    accountNum;
    ;

    //Service instance
    custService =  CustCustomerService::construct();

    customer = new CustCustomer();
    customer.createCustTable();
    custTable = customer.parmCustTable().addNew();

    custTable.parmName("Cust_Service");
    custTable.parmCustGroup("20");
    custTable.parmCurrency("EUR");
    custTable.parmPartyType(DirPartyType::Organization);

    // Create Customer
    entityKeyList = custService.create(customer);

    if(entityKeyList)
        accountNum = entityKeyList.getEntityKey(1).parmKeyDataMap().lookup(fieldnum(CustTable, AccountNum));
        infolog.messageWin().addLine(accountNum);
}

static void Services_CustTable_Delete(Args _args)
{
    AifEntityKeyList          entityKeyList;
    AifEntityKey               aifEntityKey;
   
    // Data object of Service class
    CustCustomerService     custService;
    CustTable                     custTable;
    ;

    aifEntityKey  = new AifEntityKey();
    entityKeyList = new AifEntityKeyList();
    custService   = CustCustomerService::construct();

    select firstonly custTable
        where custTable.Name == "Cust_Service";

    aifEntityKey.parmKeyDataMap(SysDictTable::getKeyData(custTable));
    entityKeyList.addEntityKey(aifEntityKey);

    try
    {
        // Delete Customer
        custService.delete(entityKeyList);
        info ("CustTable record was successfully deleted.");
    }
    catch(Exception::Error)
    {
        exceptionTextFallThrough();
    }
}

SO Creation:

static void Services_SO_Create(Args _args)
{
    // Sales Order Service class
    SalesSalesOrderService     salesService;
    SalesSalesOrder                salesOrder;

    // Data object of Service class
    SalesSalesOrder_SalesTable  salesTable;
    SalesSalesOrder_SalesLine    salesLine;
    AifEntityKeyList                   entityKeyList;

    SalesId                                salesId;
    ;

    //Service instance
    salesService =  SalesSalesOrderService::construct();

    salesOrder = new SalesSalesOrder();
    salesOrder.createSalesTable();
    salesTable = salesOrder.parmSalesTable().addNew();
    salesLine   = salesTable.createSalesLine().addNew();

    // Mandatory data filled for SalesTable
    salesTable.parmCustAccount("4000");
    salesTable.parmDeliveryDate(today());
    salesTable.parmPurchOrderFormNum(‘Test’);

    // Mandatory data filled
    salesLine.parmItemId(‘B-R14′);
    salesLine.parmSalesQty(1);
    salesLine.parmSalesUnit(‘Pcs’);

    // Create Sales Order
    entityKeyList = salesService.create(salesOrder);
    if(entityKeyList)
        salesId = entityKeyList.getEntityKey(1).parmKeyDataMap().lookup(fieldnum(SalesTable, SalesId));
        infolog.messageWin().addLine(salesId);
}

Wednesday, 8 October 2014

Working with models in AX 2012

How to: Export and Import a Model AX 2012

 Run:  enter: Cmd >> go to specified path C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin

Type the following command:
// creating the Model in the Layer
AxUtil.exe  create /model:"Name" /Layer:CUS

// exporting the model to file
AxUtil.exe export /model:"NAME" /file:"Name".axmodel

// importing the model from file
AxUtil.exe import /file:Name.axmodel 
>>  /config:instanceName ( import to correct AOS)
>> /createparents (in case of conflicting with system model)

// delete the model
AxUtil.exe delete /model:"Name"
or  AxUtil.exe delete /model:<model working id>

//delete the layer
AxUtil.exe delete /layer:ISV

// if you have multiple instances running
//delete the layer from the database and AXserver.
AxUtil.exe delete /layer:ISV /db:<database> /s:<server>

// full compile from AX2012 CU7 AxBuild:
axbuild xppcompileall /s=01

or
Axbuild xppcompileall /aos=01 /log="E:\log" /altbin="C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin" /compiler="C:\Program Files\Microsoft Dynamics AX\60\Server\AX2012R2\bin\ax32serv.exe"
















AxBuild.exe can accomplish a full compile of all X++ code, into AX p-code, many times faster than the traditional compile that you start from the MorphX client menu.


How to deploy Dynamics AX2012 reports:
  1. Through AOT
    AOT > SSRS Reports > Reports > right click on report > Deploy Element
     
  2. Through Visual Studio
    Open the report project > Right click on the project or solution node > Deploy
     
  3. Through PowerShell
    Publish-AXReport -ReportName *

Step by step: import layer without losing data

Step 1. Create a model and move all the objects that you want to move out of the layer.
Tool > Model Management > Create model

Step 2. Create a project of this model and export the project as an xpo.
Tool > Model Management > Create project from model

Step 3. Backup the database and delete the old model created in step 1

Step 4. Synchronize the database from the AOT. This will delete the data but we will retrieve it later.

Step 5. Import the xpo from step 2

Step 6. Synchronize the database.

Step 7. Export this new model.

Step 8. Restore the database that was backed up from step 3

Step 9. Import the new model (step 7), Synchronize and compile
This restores the I’d values of the objects and tables / fields. So no data will be lost

Step 10. Delete old model, compile / synchronize.

How to: Open Visual Studio with a Specific Configuration or Layer [AX 2012]

To Open Visual Studio with a Specific Configuration from a Shortcut

1.       On the client computer that is running Visual Studio, open the Start menu, right-click Visual Studio 2010, and select Properties.
2.       Update the Target field and add the /AxConfig switch with either the name of the client configuration or the name of the client configuration file as shown in the following examples:

"C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe" /AxConfig z:\Config\ContosoDev.axc

If you run the Visual Studio executable with a parameter of /?, then it will show you all the available switches you can use.

Label
We now have a new node in AOT – Label Files

All labels in the system are grouped under this node.
Now suppose we have a label from another installation which we want to bring in to our system. Right click on the Label Files node and select Create from File. Browse and selct your .ald file. Once you select the file and hit OK, a new node is added under the Label Files node corresponding to the label file imported. You will get an info message saying “Imported label file:C:\Users\Administrator\Desktop\MyLabelen-us.ald”

In AX 2009, after placing a label file, we needed to restart the AOS so that the label index was build. This isn’t required in Dynamics AX 2012. Just try using the label somewhere, and you will see that it is immediately referenced.
If you search in your application folder, you wont find the label file there. The application folder is located here C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\bin\Application\Appl\Standard
In Dynamics AX 2012, the label file is imported in your current model.
Now let us restart the AOS and see what happens. After restarting the AOS, go back to your application folder and try to find the label file again. This time the label file will be found.
Point to remember, on every AOS restart, all label files will be copied to the application folder from the model store. So your label files are contained in your models but they are stored in your application folder as well.
Now let us try to delete the label file. Right click on your label file. Do you see a delete/remove option?
The answer is no. So how do we delete the label file then? The solution which I figured out was,
To create a temporary model
Move our label file to the temporary model
Stop the AOS
Delete the temporary model
Start the AOS
Let us get about with these tasks
Go to Tools -> Model management -> Create model
Enter name as TemporaryModel. Press OK. You will recieve an info message saying “The model TemporaryModel was created successfully in layer var.”
Right click on your label file and select “Move to model”
Select the TemporaryModel checkbox and press OK.
Stop the AOS.
Open a command prompt. We will be using the command line utility AXUTIL to delete the model.
Issue the following command in the command promptAXUTIL delete /model:TemporaryModel
You will be prompted if you want to delete the model or not. Press Y
Start the AOS
Delete the label file from your application folder as well.

When you open AX now, you will get a dialog saying that “Your model store has been modified.” This is normal because each time you perform an operation on a model, you will get this dialog. Depending on your operation, you should select one of the option. Since we just deleted a model which just had a label file, select Skip.
Open AOT and notice that the label file is deleted now.

Monday, 21 July 2014

“Connection with the Application Object Server could not be established”

Scenario:
Installing Dynamics AX 2009/2012 in two different domains or two different networks. AOS server in one domain (192.168.1.xxx network) and users and AX Client PC/ terminal servers in other domain (10.5.1.xxx network).
  1. When a AX client from a laptop attempts to connect to AOS you receive the following message or error “Connection with the Application Object Server could not be established”.
Solution:
It is network problem and you can solve it.
Open host file (c:\windows\system32\drivers\etc\hosts) on the AX Client PC or Terminal Server. Add IP address of AOS server and AOS server name
192.168.1.25     AOSServer
in host file then Run the command nbtstat-R and start Dynamics AX Client.

Tuesday, 8 July 2014

Import Contoso Data Using Test Data Transfer Tool(Beta)

Pre-requisites:
1-      Download the test data transfer tool from the below mentioned link.
https://informationsource.dynamics.com//RFPServicesOnline/Rfpservicesonline.aspx?ToolDocName=Microsoft+Dynamics+AX+2012+Test+Data+Transfer+Tool+(Beta)+-+Updated+7th+Jan+2014%7cQJ4JEM76642V-8-1465

2-      Download demo data for AX2012 R3 from partner source site.

Steps: 


  • Extract the demo data files from DynamicsAX2012R3DemoData.exe to a specific location.
zb1
  • The output folder will contain the files of following extension types:
  1. .OUT—– data file that contains metadata for AX transactional database
  2. .OutModel —- data file that contain metadata for AX model database
  3. .XML —- data file that contains AX table data.
  •  Run the Test Data Transfer Tool.Exe file to install the utility.

zb2 

  • After successful installation, the folder will look like as shown below:
zb3
  • Open AX client and import the .XPO named (MetaDataXMLGenerator.Xpo)


zb4 

  • On successful import a job will be created as shown below:
zb5
  • Run the job <MetadataXMLGenerator(usr)>, a  meta data file will be generated and the path will be displayed in the infolog as shown in the snapshot below:
zb6 

  • Copy the metadata file from the above path and paste it in [lists] folder (where Test Data Transfer Tool has been extracted). If the file already exists, then overwrite the file.
  • Stop MS Dynamics AX service.
  • Open command prompt using administrator and navigate to the path where the Test Data Transfer Tool is extracted).
  • Run the following command:
Dp.exe Import “C:\R3DemoData\DynamicsAXR3DemoData” DynamicsAXR3
C:\R3DemoData\DynamicsAXR3DemoData—— update the path accordingly
DynamicsAXR3—— provide the actual database name.

If you are multiple instances of a database server then use below,
Dp.exe Import “C:\R3DemoData\DynamicsAXR3DemoData” DynamicsAXR3 “DatabaseServerName\InstanceName

zb7
If we enter ‘Y’, then following screen will open up describing the count for importing the table data and Error (if they come up)

zb8 

  • The process may prolong depending upon machine configuration.
  • On successful import, Open AX client and data will show up.
zb9