Saturday, July 20, 2013

ERD (Entity relationship diagrams) for dynamics ax tables


     Yesterday I read the news from Microsoft dynamics ax community forum that Microsoft has published ER diagrams for some dynamics ax tables. so I just want to share with you guys. It includes 30 database ERDs for tables in dynamics ax. Its very helpful for developer like us to finding the relations between tables when we are trying to customize. here I given the link go and enjoy

ERDs-  http://go.microsoft.com/fwlink/p/?linkid=296623

Microsoft dynamics ax interview questions part 3 - Senior technical consultant

         
           Before I am joining Wipro InfoTech I had attend lot of interviews and I got offer from some finest companies. I feel proud to join in Wipro. so here I am going to post my third series of dynamics questions but its senior level. get on
 
  • Name the two dynamics framework newly added on Ax 2012
  • Explain ledger framework in AX 2012
  • In AX 2012 journal postings are running on IL code. So how do you debug the posting
  • What are all the steps in Dynamics ax 2012 upgradation. in which level you worked extensively explain it.
  • Name the two newly added best practices in Dynamics ax 2012 on all the AOT objects
  • Explain the table inheritance in AX 2012 with examples
  • Consider the situation that huge number of invoices happening on the particular company. so Client wants you to modify something on the invoice place. so what are all the steps would you take to prevent fall of performance in the system
  • Have you worked on SSRS.
  • When user wants to open the SSRS report I want some user input for the report. What are all the steps to get user input. (here I explained about the controller classes and dialogs to get user inputs)
  • Ok I need a lookup in that SSRS dialog field. how do you achieve it. what are all the classes you use.
  • Explain the types of way to get Data sources in SSRS report
  • Explain the data methods in SSRS report. what is the purpose when did you use it
  • Explain post handler and pre handler in AX 2012
  • how do you get the exchange rate for transaction currency (here I explained about exchangeratehelper class)
  • Explain trade agreements and their use
  • Explain model and model store
  • say some scripts you used at the time of data migration
  • How do you migrate the changes from Development to UAT
  • What is inbound and outbound
  • Explain the steps for creating services in dynamics ax
  • Explain the real time steps for development (Interviewer asking about the series of real-time development lifecycle in dynamics ax. This actually a tricky question here you have to explain the document preparation and step by step development process from Requirment to TDD)

 
 
 

Monday, July 15, 2013

Customer/Vendor Address import in dynamics AX 2012 through X++

15-07-13
Customer and Address import in Dynamics AX 2012 using X++
Problem: I was assigned to a task that import customer and their addresses from Excel sheet. I can import customer through code by using AXCustTable service class but what about addresses. In AX 2012 addresses changed a lot they created new framework for addresses.
Solved: I had gone through lot of websites for customer address import. Every code was almost identical. I am happy with all the codes but one thing the code doesn’t solve it. They all work until you have to fill all the address masters before create new address for customer. In my case I have to create new address not selecting the address for my customer. So I had gone through address framework and created the code for creating addresses as well as customers. So I had liked to share with you.  (But here I covered only the address part electronic address included)
 
Main method creating for address:
    DirPartyRecId                                                partyRecId;
    DirPartyPostalAddressView                          addressView;
    AxLogisticsAddressCountryRegion              axCountryRegion;
    AxLogisticsAddressCounty                           axCounty;
    AxLogisticsAddressState                               axState;
    AxLogisticsAddressZipCode                         axZipcode;
    AxLogisticsAddresssCity                               axCity;
    DirParty                                                          DirParty;
    DirPartyContactInfoView                              contactView;
    LogisticsLocationRecId                                 locationRecid;
    ;
    try
    {
            addressView.CountryRegionId = _CountryRegionId;
            addressView.State   = _state;
            addressView.City    = _city  ;
            addressView.ZipCode = _zipCode;
            addressView.Street  = _street;
            addressView.Party   = _custTable.Party;
            //addressView.Location    =   locationRecid;
                //Separate method find it in below code
            this.processAddress(addressView,_custTable);
            DirParty = DirParty::constructFromPartyRecId(addressView.Party);
                //Creating new address using dir party class
            if( addressView.Street || addressView.ZipCode || addressView.City || addressView.State ||                       addressView.CountryRegionId)
            {
                DirParty.createOrUpdatePostalAddress(addressView,_roleId);
            }
                //Electronic address creaiton
            if(_AccountManagerEmail!='')
            {
                contactView.LocationName = "Delivery email";
                contactView.Locator      = _AccountManagerEmail;
                contactView.Type         = LogisticsElectronicAddressMethodType::Email;
                contactView.Party        = _custTable.Party;
                contactView.IsPrimary    = NoYes::Yes;
                DirParty = DirParty::constructFromPartyRecId(contactView.Party);
                dirParty.createOrUpdateContactInfo(contactView);
            }
            if(_phone!='')
            {
                contactView.LocationName = "Phone";
                contactView.Locator      = _phone;
                contactView.Type         = LogisticsElectronicAddressMethodType::Phone;
                contactView.Party        = _custTable.Party;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);
            }
            if(_teleFax!='')
            {
                contactView.LocationName = "Tele Fax";
                contactView.Locator      = _teleFax;
                contactView.Type         = LogisticsElectronicAddressMethodType::Telex;
                contactView.Party        = _custTable.Party;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);
            }
            if(_url!='')
            {
                contactView.LocationName = "URL";
                contactView.Locator      = _url;
                contactView.Type         = LogisticsElectronicAddressMethodType::URL;
                contactView.Party        = _custTable.Party;
                contactView.IsPrimary    = NoYes::Yes;
                dirParty.createOrUpdateContactInfo(contactView);
            }
    }
    catch (Exception::Error)
    {
        info ("Customers not created");
    }
 
  Process address method:
    AxLogisticsAddressCountryRegion axCountryRegion;
    AxLogisticsAddressCounty        axCounty;
    AxLogisticsAddressState         axState;
    AxLogisticsAddressZipCode       axZipcode;
    AxLogisticsAddresssCity         axCity;
    LogisticsAddresssCity            addressCity; 
    ; 
    if(addressView.CountryRegionId  &&  !LogisticsAddressCountryRegion::exist       (addressView.CountryRegionId))
    {
        axCountryRegion =   new AxLogisticsAddressCountryRegion();
        axCountryRegion.parmCountryRegionId(addressView.CountryRegionId);
        axCountryRegion.parmCurrencyCode(_custTable.Currency);
        axCountryRegion.parmAddrFormat("0014");
        axCountryRegion.save();
    }
    if (addressView.State && !LogisticsAddressState::exist(addressView.CountryRegionId, addressView.State))
    {
        axState =   new AxLogisticsAddressState();
        axState.parmCountryRegionId(addressview.CountryRegionId);
        axState.parmStateId(addressView.State);
        axState.parmName(addressView.State);
        axstate.save();
    }
    if (addressView.County && !LogisticsAddressCounty::exist(addressView.CountryRegionId, addressView.State, addressView.County))
    {
        axCounty    =   new AxLogisticsAddressCounty();
        axCounty.parmCountryRegionId(addressview.CountryRegionId);
        axCounty.parmStateId(addressview.State);
        axCounty.parmCountyId(addressView.County);
        axCounty.parmName(addressview.County);
        axCounty.save();
    }
    if(AddressView.City &&  !Logisticsaddressscity::exist(Logisticsaddressscity::find(addressView.city).RecId))
    {
        /*axcity  =   new AxLogisticsAddresssCity();
        axCity.parmCountryRegionId(addressview.CountryRegionId);
        axCity.parmCountyId(addressview.County);
        axCity.parmName(addressView.City);
        axCity.parmStateId(addressview.State);
        axCity.save();*/
        addressCity.CountryRegionId =   addressView.CountryRegionId;
        addressCity.Name    =   addressView.City;
        addressCity.StateId =   addressView.State;
        addressCity.doInsert();
    }
    if (addressView.ZipCode &&  !LogisticsAddressZipCode::exist(addressView.ZipCode))
    {
        axZipcode   =   new AxLogisticsAddressZipCode();
        axZipcode.parmCity(addressview.City);
        axZipcode.parmCityRecId(Logisticsaddressscity::find(addressView.city).RecId);
        axZipcode.parmCountryRegionId(addressview.CountryRegionId);
        axZipcode.parmCounty(addressView.County);
        axZipcode.parmState(addressView.State);
        axZipcode.parmStreetName(addressView.Street);
        axZipcode.parmZipCode(addressView.ZipCode);
        axZipcode.save();
    }

Tuesday, June 18, 2013

Dynamics AX Interview Question Part 2 - scenario based

One of my friend attend a interview for an Europe client.. so i just want to share the questions he faced.

Client: Code optimization, There is one class in Ax. If the client wants to reduce the execution time of that operation. Its a custom class. so what are all your steps to optimize the class and reduce the time of execution

My Friend:
  • Use trace and code pro filer to find out the process that take much time and optimize it
  • Use indexes, joins and Queries in code.
Client: If there any clean ups available in AX to delete tables

My Friend : Yes, Sales and Purch parm table cleanups are available under AP/AR -> periodic
-> clean up. Then we can clear database log with the help of batch job. In  production its not advisable to enable the database log.

Client : Difference between For loop and While loop

My Friend: In for loop we can control the loop execution with the help of incremental operator.

Wednesday, January 2, 2013

Dynamics AX 2012: Import Inventory Journal Lines through code


01-02-2012

Import Inventory Journal Lines Through code in Dynamics AX 2012

Problem: My task was to import the journal lines in dynamics AX 2012 through code.

Solved:     There are two ways to import the code office add-ins and X++ code. Here I am going to explain importing journal lines through code. Because there are lot of blogs explaining the office –add in method. This code was given by my colleague Mahendran.

In below you can find the code used to import the journal lines. Here I missed out something; I hope you people can manage those things. Like,
·         X++ code to read data from excel
·         Proper class declarations and variable declarations
I am just going to give the heart of the solution. If you can’t make it up to this please feel free to mail me at hapkarm@outlook.com

    //Getting the essential values from Excel
    itemId                               = cells.item(row, 1).value().bStr();
    inventSiteId                       = cells.item(row, 2).value().bStr();
    inventLocationId               = cells.item(row, 3).value().bStr();
    inventBatchId                    = cells.item(row, 4).value().bStr();
    qty                                    = cells.item(row, 5).value().double();
    costPrice                           = cells.item(row, 6).value().double();
    mainAcc                            = cells.item(row, 7).value().bStr();
    department                        = cells.item(row, 8).value().bStr();
   
    locInventDim.inventBatchId                   = inventBatchId;
    locInventDim.InventSiteId                       = inventSiteId;
    locInventDim.InventLocationId             = inventLocationId;
    journalTrans.clear();
    journalTrans.initFromInventJournalTable(journalTable);
    journalTrans.TransDate                             = systemDateGet();
    journalTrans.ItemId                                    = itemId;

    //Finding out the invent dim id from given value
    journalTrans.InventDimId                        = InventDim::findOrCreate(locInventDim).inventDimId;
    journalTrans.PriceUnit                               = 1;
    journalTrans.Qty                                          = qty;
    journalTrans.CostPrice                              = costPrice;
    journalTrans.CostAmount                        = journalTrans.Qty * journalTrans.CostPrice;
    //Except these below two lines above things are same as like in dynamics AX 2009
    //If you want to insert the dimension value with account
    //In below code I have no dimension with main account so I just put 0, Instead I have two        
    //dimension
    //write a code like “[“MainAccount”, mainAcc, 2, Dinemsion1, dimVal1, Dimension2, dimVal2)
    offsetEntryPattern                                      = ["MainAccount",mainAcc,0];
    journalTrans.LedgerDimension              = AxdDimensionUtil::getLedgerAccountId(offsetEntryPattern);
    //Default dimension Value either you can insert the dimension value here.
    defaultDim                                                     = [1,"Department",department];
    journalTrans.DefaultDimension             =        AxdDimensionUtil::getDimensionAttributeValueSetId(defaultDim);
    journalTrans.insert();

If you need any assistance from above code feel free to put a mail on hapkarm@outlook.com

Thursday, December 20, 2012

Go to main table reference for display fields


12-18-2012
Go to main table reference for Display fields
Problem:   My task was to enable the go to main table reference for display fields (using display methods instead of table fields)
Solved:      In normal table fields EmplId used formref properties to enable the go to main table reference for display fields. There are no such properties. Rather than dynamics provides one method called jumpref. You can override this method in forms to enable this go to main table functionality. Here I given some sample code.
 
                         args = new Args();
                         args.caller(element);
                         args.record(Datasource);
 menuFunction = new MenuFunction(menuitemdisplaystr        (menuitemname),MenuItemType::Display);
             menuFunction.run(args);

Tuesday, May 29, 2012

Batch Job System Date Problem


05-29-2012

Batch job system date problem

Problem: I created the exchange rate update automation (previous blog) for client. But when I check this exchange rate I changed the system date to verify whether the add-on working on month end or not. After i changed the system to original date since the batch job is not working unless the system date changed to the future date.

Solved:    I tried various forums; I didn’t find any solution related to this. At last I found the solution in community dynamics blog . In this article the author explained the whole batch job process in depth. Here I found out the vital point for batch processing. Please read the article before get into details that I am going to explain here.

BatchGlobal -This table responsible for Batch processing and Cleanup the dead tasks. What i am saying here is, it is responsible for changing the job from waiting to executing status vice versa and Executed tasks changed to end status.
                        This table contains the date and time of job when to execute and when to end. You cannot open the table directly, AOS won’t allow it. So you can open it using a job. See the below screen
Batch Infolog

                        When you change the system date, batchGlobal dates changed to future date (last executed job date and time). So the current date jobs cannot be executed the Batch engine wait for the future date to come.
                        Changing the date to current date in batchGlobal table will solve this problem. But you can’t change it in AOS you must go to sqlserver to change the date to current date (time should be 5 hours behind the current time you will understand this if you read the blog), and then wait sometime it won’t affect quickly it take some time.