Thursday, December 15, 2011

AX 2012: Reference To the VS Projects not updated in AOT



Common error when using a class that runs on server and references a Visual studio DLL file.
I am trying to consume web service from external systems in AX. To do this, I have added the references in VS 2010 solution and that in turn is added to the AOT. I have set the deploy on client and server to yes.





When you add the solution to the AOT, the AX server will store the relevant DLL and its configuration file to the folder under the application as below. The highlighted part is the instance name.
C:\Program Files\Microsoft Dynamics AX\60\Server\Lexjet_DEV_AX\bin\VSAssemblies
When you use the reference to the web services in a class, which is very much simplified in AX 2012 as it gets stored under the VS references, you may want to execute the class always from server. In my case it is a batch job so it becomes mandatory for me.


But when my code tries to create a service client, it points out the configuration path to the client rather than the destination pointed above.


Second Problem with this path reference is that when you try updating a service in VS 2010 and update the project to AOT, only the server folder gets the latest artifacts of the project. Below is a screen that shows that the last modified date of the client folder is older than the one in server.

 
The deploy to client did not work and even though you run the class from server it takes the client’s path reference in the createServiceClient method.
Workaround:
Every time you add or update the service reference, you need to copy the configuration and DLL from server to the client folder.
This is a big overhead when you are developing integration scenarios and you tend to update the service reference again and again.
You also do not want to refer to the client’s directory in case of a batch job. This is a big pain when you are migrate your code to other environments.

Wednesday, September 14, 2011

Importing Vendor Into Ax 2012

Having all the relations of GAB structure changed, it became mandatory to write a script to import vendor data into Ax 2012. I will create a DirParty record and then associate it to vendor fields. The addresses can be attached to the vendor's PartyRecId. The use of views to record all the address fields help to initialize the linked tables.



static void importVendor(Args _args)
{
    CommaIO                     csvFile;
    container                   readCon;
    counter                     icount,inserted;
    Dialog                      dialog;
    DialogField                 dfFileName;
    DirPartyRecId               partyRecId,contactPartyRecid;
    Name                        name,contactName;
    VendTable                   vendtable;
    FileName                    fileName;
    str                         contactperson;
    DirPartyPostalAddressView   addressView;
    DirPartyContactInfoView     contactView;
    ContactPerson               contactpersonTable;
    LogisticsElectronicAddressMethodType enumType;


    DirParty                    dirParty;
    LogisticsPostalAddress      address;
    LogisticsElectronicAddress  logisticsElectronicAddress;
    BinData binData;
    str stringImage;
    inserted =0;
    #File


    dialog = new Dialog("Pick the file");
    dfFileName = dialog.addField(extendedTypeStr(FileNameOpen));
    dialog.filenameLookupFilter(["All files", #AllFiles]);


        if (dialog.run())
        {
             filename =  dfFileName.value();
        }




    csvFile = new CommaIO(filename, 'r');
    
   
    if (csvFile)
    {
        readCon = csvFile.read();
        ttsbegin;
        while (csvFile.status() == IO_Status::OK)
        {
            readCon = csvFile.read();
            icount++;
            if (readCon)
            {
                name = conPeek(readCon,2);
                partyRecId = DirPartyTable::createNew( DirPartyType::Organization, name).RecId;


                vendtable.clear();
                vendtable.initValue();
                vendtable.Party = partyRecId;
                vendtable.AccountNum = conPeek(readCon,1);
                vendtable.VendGroup  = conPeek(readCon,5);
                vendtable.Currency   = conPeek(readCon,6);
                //vendtable.Blocked    =
                vendtable.DlvMode    = conPeek(readCon,8);
                vendtable.PaymMode   = conPeek(readCon,9);
                ContactPerson = conPeek(readCon,12);
                if(contactperson != '')
                {
                    contactname = conPeek(readCon,12);
                    ContactPerson::findOrCreateNameParty(partyRecId,contactname);
                }
        
                vendtable.insert();


                address.CountryRegionId = strLRTrim(conPeek(readCon,14));
                //addressView.State = strLRTrim(conPeek(readCon,16));
                address.ZipCode = strLRTrim(conPeek(readCon,15));
                address.Street  = strLRTrim(conPeek(readCon,19));
               // address.county = strLRTrim(conPeek(readCon,17));
               address.City    = strLRTrim(conPeek(readCon,18));
                addressView.LocationName = name;
                addressView.IsPrimary = NoYes::Yes;
                addressView.Party = partyRecId;
                addressview.initFromPostalAddress(address);


                DirParty = DirParty::constructFromPartyRecId(addressView.Party );
                DirParty.createOrUpdatePostalAddress(addressView);


                contactView.LocationName = "Delivery email";
                contactView.Locator      = strLRTrim(conPeek(readCon,10));
                contactView.Type         = LogisticsElectronicAddressMethodType::Email;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);


                contactView.LocationName = "Delivery Cellular Phone";
                contactView.Locator      = strLRTrim(conPeek(readCon,11));
                contactView.Type         = LogisticsElectronicAddressMethodType::Phone;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);


                contactView.LocationName = "Delivery Phone";
                contactView.Locator      = strLRTrim(conPeek(readCon,3));
                contactView.Type         = LogisticsElectronicAddressMethodType::Phone;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);


                contactView.LocationName = "Delivery Fax";
                contactView.Locator      = strLRTrim(conPeek(readCon,4));
                contactView.Type         = LogisticsElectronicAddressMethodType::Fax;
                contactView.Party        = partyRecId;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);
                inserted++;
            }
        }
        ttsCommit;
    }
    info(strfmt("%1 records inserted out of %2",inserted,icount));
}