December 29, 2012

Import Opening Stock Balance into Dynamics AX

Import Opening Stock Balance into Dynamics AX

When we import opening stock balance into inventory journal using the standard import/export functionality, the most common problem is dealing with Inventory Dimension id (InventDimId). We might know the warehouse and batch, but we do not know what is the InventDimId that represents the combination of these two inventory dimension.
One way to do this is to lookup the InventDimId value manually before performing the import. This is only possible if very few inventory dimensions are used.


An alternative is using the Custom import functionality to import stock balance CSV file into Tag counting journal.
There is a conversion functionality in the Custom import, where you can write a little X++ code to find the InventDimId using the inventory dimensions.
Here is an example of finding the InventDimId using Site and Warehouse dimension.




You must select Run conversion checkbox to activate the conversion. You may also use the compile icon (on the right hand) to validate the X++ code.
The purpose to use Tag counting journal instead of Movement/Counting journal is we let the system to create the Lot ID when we post the Tag counting journal into Counting journal.


- Harry

December 07, 2012

Change company from the current company in X++ code

Change company from the current company in X++ code

If in any point you need to change change company during the code, This example will helps you to change the company from current company in x++ code.

static void main()
{
  CustTable custTable;
  ;
  //Assume that you are running in company 'DAT'.
  changeCompany('DAT1') //Default company is now 'DAT1'.
  {
    custTable = null;
    while select custTable
    {
       //custTable is now selected in company 'DAT1'.
    }
  }
 //Default company is again set back to 'DAT'.
 changeCompany('DAT2') //Default company is now 'DAT2'.
 {
   //Clear custTable to let the select work
   //on the new default company.
   custTable = null;
   while select custTable
    {
      //custTable is now selected in company 'DAT2'.
    }
 }
//Default company is again 'DAT'.

}

-Harry.

December 05, 2012

Dynamics Ax Layers

 Dynamics Ax Layers

Dynamics AX 2009 consists of sixteen application object layers that contain all the
elements you see in the AOT.
These layers can be looked at as an onion with multiple layers. In the middle is the
core application in the SYS layer and the outermost layer is the user layer USR.
Therefore, when any application element is being executed the system will look at
the outermost code layer first to see if there is any code for that element; if not, it peels a layer off the onion, and tries the next layer. When it hits a layer where the element exists, it will use the code from this layer, and will not continue to peel off layers to find code for that element in the innermost layers.
Layers with their description



SYS The standard application is implemented at the lowest level,
the SYS layer.The application objects in the standard
application can never be deleted.

GLS Country/region specific changes will be developed in GLS
Layer.For e.g as you all know that Tax structure differs
from country to country.So such localization functionality
can be developed in GLS layer.

HFX HFX is an application object patch layer reserved by
Microsoft for future patching or other updates.

SL1, SL2,or SL3 A layer where the distributor can implement
vertical partner solutions.

BUS When a business partner creates their own generic solution,
their modifications are saved in the BUS layer and the top-
level application objects are used.

VAR Value Added Resellers (VAR) can make modifications or new
developments to the VAR layer as specified by the customers
or as a strategy of creating an industry-specific solution.
Such modifications are saved in the VAR layer.

CUS The supervisor or administrator of an end user installation
might want to make modifications that are generic to the
company. Such modifications are saved in the CUS (CUStomer)
layer.

USR End users might want to make their own modifications, such
as in their reports.These modifications are saved in the USR
layer.
-Harry

December 04, 2012

Workflow configuration error in Dynamics Ax: 401 Unauthorized

 Workflow configuration error in Dynamics Ax: 401 Unauthorized
Some times we faced unusual error after installing Dynamics AX Workflow: “401 Unauthorized” after running Workflow infrastructure configuration wizard
 (Dynamics AX –> Administration –> Setup)
at the first time installation of Dynamics Ax then you should go through the following steps….
It is mainly happening when database, AOS, Application and workflow servers are individual (especially workflow & AOS and Database server)
  1. Check AOS Service is running under an active domain user (domain\username)
  2. Workflow website and workflow application pool are having the same .NET Business Connector user name Identity (and of course, this should be an active domain user)
  3. You added the workflow website (http://servername:portnumber/DynamicsAXWorkflow50 for example) to the trusted sites in Internet Options of AOS server
  4. Run the following on the Workflow server:
  • After checking above points and then perform the following steps
  1. Start a command prompt.
  2. Locate and then change to the directory that contains the Adsutil.vbs file. (By default, this directory is C:\Inetpub\Adminscripts.)
  3. Type the following command, and then press ENTER: cscript adsutil.vbs set w3svc/NTAuthenticationProviders “NTLM”
  4. To verify that the NtAuthenticationProviders metabase property is set to NTLM, type the following command, and then press ENTER: cscript adsutil.vbs get w3svc/NTAuthenticationProviders
The output:
NTAuthenticationProviders       : (STRING) "NTLM"

After completing above procedure successfully then please take a restart of Ax and IIS service and then workflow infrastructure configuration wizard will work fine.

-Harry




December 01, 2012

Open web pages from X++ code

Sending mail from AX using .NET Framework

Sometimes happen that SysMailer class (using CDO) is not the right solution for sending mails with attachments. There is a little sample of X++ Job that is using System.Net.Mail namespace to achieve same.


static void JobNETSendMail(Args _args)
{
    System.Net.Mail.MailMessage             mailMessage;
    System.Net.Mail.Attachment              attachment;
    System.Net.Mail.AttachmentCollection    attachementCollection;
    System.Net.Mail.SmtpClient              smtpClient;
    System.Net.Mail.MailAddress             mailAddressFrom;
    System.Net.Mail.MailAddress             mailAddressTo;
    str                                     strBody;
    str                                     strSMTPServer;
    str                                     strFileName;
    FileIOPermission                        perm;
    ;

    // preparing parameters
    mailAddressFrom = new System.Net.Mail.MailAddres"test@localmail.com", "");
    mailAddressTo = new  System.Net.Mail.MailAddress("admin@localmail.com","");
    strBody = "There is a email body";
    strSMTPServer = "MailServerName";
    
    // preparing mail with body, subject, from, to.
    mailMessage = new System.Net.Mail.MailMessage(mailAddressFrom, mailAddressTo);
    mailmessage.set_Subject("There is a email subject");
    mailmessage.set_Body(strBody);
    attachementCollection = mailMessage.get_Attachments();

    strFileName = "C:\\path\\filename";
    // assert permision
    perm = new FileIOPermission(strFileName,'w');
    perm.assert();

    // attaching file to that email.
    attachment = new System.Net.Mail.Attachment(strFileName);
    attachementCollection.Add(attachment);
    smtpClient = new System.Net.Mail.SmtpClient(strSMTPServer);
    smtpClient.Send(mailmessage);
    
    // release permision
    CodeAccessPermission::revertAssert();
}

-Harry

November 24, 2012

The MorphX Tools - Project Designer

How to Create a Project in AXapta

For a fully customizable overview of the elements, you can use projects. In a project, elements can be grouped and structured according to the developer’s preference. The Project Designer is a powerful alternative to the AOT because you can collect all the elements needed for a feature in one project.
Creating a New Project
You open the Project Designer by clicking the Project button on the toolbar. Figure 1 shows the Project Designer and its Private and Shared projects.

Figure 1. Project Designer, showing available private and shared projects


Except for its structure, the Project Designer behaves exactly like the AOT. Every element in a project is also present in the AOT.
When you create a new project, you must decide whether it should be private or shared among all developers. You can’t set access requirements on shared projects. You can make a shared project private (and a private project shared) by dragging it from the shared category into the private category.

Note
Central features of Dynamics AX 2009 are captured in shared projects to provide an overview of all the elements in a feature. No private projects are included with the application.
You can specify a startup project in the Options dialog box. If specified, the chosen project automatically opens when Dynamics AX is started.

Automatically Generated Projects
Projects can be automatically generated in several ways—from using group masks to customizing special project types—to make working with them easier. We discuss the various ways to automatically generate projects in the sections that follow.

Group Masks
Groups are folders in a project. When you create a group, you can have its contents be automatically generated by setting the ProjectGroupType property (All is an option) and a regular expression as theGroupMask property. The contents of the group are created automatically and kept up to date as elements are created, deleted, and renamed. Using group masks ensures that your project is always current, even when elements are created directly in the AOT.
Figure 2 shows the ProjectGroupType property set to Tables and the GroupMask property set to <xRef on a project group. All table names starting with xRef (the prefix for the Cross-reference tool) will be included in the project group.

Figure 2. Property sheet specifying settings for ProjectGroupType and GroupMask

Figure 3 shows the resulting project when the settings from Figure 2 are used.

Figure 3. Project created by using group masks


Filters
You can also generate a project based on a filter. Because all elements in the AOT persist in a database format, you can use a query to filter elements and have the results presented in a project. You create a project filter by clicking the Filter button on the project’s toolbar. Depending on the complexity of the query, a project can be generated instantly or might take several minutes.
Filters allow you to create projects containing the following kinds of elements:
  • Elements created or modified within the last month
  • Elements created or modified by a named user
  • Elements from a particular layer

Development Tools
Several development tools, such as the Wizard wizard, produce projects containing elements the wizard creates. The result of running the Wizard wizard is a new project that includes a form, a class, and a menu item—all the elements comprising the newly created wizard.
You can also use several other wizards, such as the Report Wizard and the Class Wizard, to create projects. You can access these wizards from the Microsoft Dynamics AX drop-down menu by clicking Tools\Development Tools\Wizards.

Layer Comparison
You can compare all the elements in one layer with the elements in another layer, called the reference layer. If an element exists in both layers, and the definitions of the element are different or the element doesn’t exist in the reference layer, the element will be added to the resulting project. You can compare layers by clicking Tools\Development Tools\Code Upgrade from the Microsoft Dynamics AX drop-down menu.

Upgrade Projects
When you upgrade from one version of Dynamics AX to another or install a new service pack, you need to deal with any new elements that are introduced and existing elements that have been modified. These changes might conflict with customizations you’ve implemented in a higher layer.
The Create Upgrade Project feature makes a three-way comparison to establish whether an element has any upgrade conflicts. It compares the original version with both the customized version and the updated version. If a conflict is detected, the element is added to the project.
The resulting project provides a list of elements to update based on upgrade conflicts between versions. You can use the Compare tool, to see the conflicts in each element. Together, these features provide a cost-effective toolbox to use when upgrading.
You can create upgrade projects by clicking Tools\Development Tools\Code Upgrade\Detect Code Upgrade conflicts from the Microsoft Dynamics AX drop-down menu.

Project Types
When you create a new project, you can specify a project type.  Two specialized project types are also provided in Dynamics AX:
  • Test project Project used to group a set of classes for unit testing
  • Help Book project Project used for the table of contents in the online Help system
You can create a custom specialized project by creating a new class that extends the ProjectNode class. Specialized projects allow you to control the structure, icons, and actions available to the project.

-Harry

How to go to the object from Infolog

How to go to the object from Infolog

When we print a transaction id through infolog Usually, it is more useful if the user can go directly to the object from an Infolog line.

For example, we need to see all the BOM without any active version. By the way, this is a good example, too, for what we cannot do by means of Advanced Filter but quickly by coding a short job.


static void SIBOMwithNoActiveVersion(Args _args)
{
    BOMTable    bomTable;
    BOMVersion  bomVersion;
    int         nmbr, i;
    boolean     printOnly = false;
    ;

    SetPrefix('BOMs without any active version');
    Nmbr = 0;

    while select bomTable
    notexists join bomVersion
    where bomVersion.Active == NoYes::Yes
    && bomVersion.BOMId == bomTable.BOMId
    {
        nmbr++;
        info(strfmt("%1 %2, %3, %4, %5, %6, %7",
                                          nmbr,
                                          bomTable.BOMId,
                                          bomTable.Name,
                                          bomVersion.ItemId,
                                          bomVersion.Name,
                                          bomVersion.Active
                                          ),"",
        SysInfoAction_TableField::newBufferField(bomTable, fieldnum(bomTable, BOMId)));

    }

}

Now the user can opt for Show from the context menu or just double-click on the interesting line to open the related form.







-Harry

November 16, 2012

Opening the table from x++ code

Opening the table from x++ code

This code helps you to open the any Table from X++ code. Here is an example for SalesTable, just copy and paste this into a job you will get the table.

static void TableBrowser(Args _args)
{
SysTableBrowser sysTableBrowser = new SysTableBrowser();
;
//Browse the SalesTable table
sysTableBrowser.run(tablenum(SalesTable ));
}

How to run Client Batches on AX 2009

How to run Client Batches on AX 2009

In AX 2009 the batch engine has been changed to run as a service.
The batch services do only process server batches they don't process client batches aynmore.

There might still be some situations where you would like to run client batches.
The following description explains how to do this.

  • Create a new batch group 'Client' which is used for client batches later.
    (Administration -> Setup -> Batch groups)
  • Add this batch group to an AOS acting as batch server.
    (Administration -> Setup -> Server configuration)
    This is needed to change the status from 'Waiting' to 'Ready' on the batch tasks and to 'Execute' on the batch jobs.
    The batch server will not process any client batches.
  • Start the legacy batch client
    (Basic -> Periodic -> Batch -> Processing)
  • Select the new created batch group 'Client' and press 'OK'
The client batch server will now process all client batches of the 'Client' batch group.
-Harry

November 10, 2012

Designate a batch server


Designate a batch server

A batch server is an Application Object Server (AOS) instance that processes batch jobs. Batch jobs are used to run tasks, such as printing reports or posting journals, at a specified time and probably on a different computer.
The first AOS to be set up is automatically designated as a batch server. Use multiple batch servers to increase throughput and reduce the amount of time it takes to run batches.

When you set up a batch server, you can specify the times that it is available for batch processing. We recommend excluding a server from batch processing when it is busy with regular transaction processing. For example, you may have servers in different time zones. You can set server schedules so that each AOS is available for user traffic during the day and for batch traffic overnight.

For more information about batches, 
see the Applications and Business Processes Help, 
available from the Microsoft Dynamics AX Help menu. 

1. Click Administration > Setup > Server configuration.

2. Press CTRL+N to add a new batch server.

3. On the Overview tab, enter a server ID in the following format: InstanceName@ServerName.

4. Select Is Batch Server to enable batch processing on the server. 

5. On the Batch server schedule tab, enter the maximum number of batch tasks that can be run on the AOS instance at one time. The server will continue to pick up tasks from the queue until it reaches its maximum.

6. To specify when the server is available for batch processing, enter a starting time in the Start time field and an ending time in the End time field. Press CTRL+N to enter an additional time period.
Note: If the server is running a task when its batch processing availability ends, the task will continue running to completion. However, the server will not pick up any more tasks from the queue.

7. On the Batch server groups tab, use the arrow buttons to specify the batch groups that can run on the selected server. Batch groups are used to direct batch tasks to specific servers.

- Harry

How to update vendor addresses in Dynamics AX

How to update vendor addresses in Dynamics AX 2009

Here is trick of X++ by which we can update the address for a vendor in Dynamics ax 2009,  below job is the possible answer and may helps.


static void UpdateVendAddressType(Args _args)
{
VendTable          vendTab; // Replace VendTable with CustTable when run this for customers.
DirPartyTable     dirPartyTab;
Address              addTab;
;
ttsbegin;
while select vendTab join dirPartyTab join forupdate addTab
                                                          where vendTab.PartyId        == dirPartyTab.PartyId
                                                             && addTab.AddrTableId == dirPartyTab.TableId
                                                            && addTab.AddrRecId     == dirPartyTab.RecId
{
      if(addTab.Name == ‘Birincil Adres’)
     {
        addTab.type = AddressType::Payment;
         addTab.update();
     }
}
ttscommit;
}

- Harry

November 08, 2012

Create Alert using X++ codes

Create Alert using X++ codes


Sometimes Infolog message is not sufficient enough for prompting information to users. It is possible to create alert message using code as an alternative. It is fairly simple to create alert message manually by just inserting a new record in EventTable where all the alert messages are stored. Below is a code snippet for creating alert using code in AX 2009.
Try following code......





static void CreateAlertUsingCode(Args _args)
{
EventInbox          inbox;
;
inbox.initValue();
inbox.ShowPopup     = NoYes::Yes;
inbox.Subject       = "This is the Alert subject";
inbox.Message       = "This is the Alert message";
inbox.AlertedFor    = "This alert is just information no links are available";
inbox.SendEmail     = false;
inbox.UserId        = curuserid();
inbox.TypeId        = classnum(EventType);
inbox.AlertTableId  = tablenum(Address);
inbox.AlertFieldId  = fieldnum(Address, Name);
inbox.TypeTrigger   = EventTypeTrigger::FieldChanged;
inbox.CompanyId     = curext();
inbox.InboxId       = EventInbox::nextEventId();;
inbox.AlertCreatedDateTime = DateTimeUtil::getSystemDateTime();
inbox.insert();
}
 
- Harry

November 07, 2012

SysQueryRangeUtil class -Use method name as query criteria(Reports)

SysQueryRangeUtil class - use method name as query criteria

This is a cool new feature in AX 2009 - you can now use a method name instead of literal value in query criteria!

For example, if you run a report every month, previously you need to change the date criteria in each month you running the report 
(ie.“01/06/2010..30/06/2010”,  “01/07/2010..31/07/2010”, etc).
Now you only need to enter (monthRange(0, 0)) which will automatic return the correct first day and last day of the month.

For Example: - 




You can also refer to the SysQueryRangeUtil class – there are a lot of useful methods such as dateRange(), currentEmployeeId(), etc. It’s also possible to create new method on this class for special purpose. But do this with caution.


- Harry

Finding all data sources in a form through Job

Finding all data sources in a form through code

Hi ,
Here is small trick to find the datasource in form. Open job node , and a new job and copy paste following code over there,.....

static void AllDataSourcesInForm(Args _args)
{
    Args args = new Args();
    FormRun fr;
    FormBuildDataSource formBuildDataSource;
    counter i;
    ;
    args.name("CustTable");   // its your FORM name
    fr = ClassFactory.formRunClass(args);
    for(i=1 ; i<=fr.form().dataSourceCount();i++)
    {
        formBuildDataSource = fr.form().dataSource(i);
        info(new DictTable(formBuildDataSource.table()).name());
    }
}



When you run this job you get all data source which is used in CustTable Form




















- Harry

November 06, 2012

Differences among reread(), refresh(),research()

Differences among reread(), refresh(),research()

When working with Forms, commonly after opened the form we need to do some operations with existing data. In few cases we need to interact with data base again and again in order to do. For that we will use these methods. But some times its create confuse what exactly use of these methods, when should we call these methods and why, here is brief info these methods...

refresh() : this method will refresh the data in the data source cache. But it will not interact with the data base to fetch the new/updated record values. What ever values have fetched in the previous query will store in data source cache, this method will just refresh the data source cache only.

reread(): this method will interact with the data base and runs the query against the data base in order to fetch the new/updated record values. But this will not show the updated values in the form until calling the refresh method. that means it will update the data source form cache only but not existing form control values.
So it is better to call the methods as shown here, like reread and after refresh methods in order to fetch the new / updated values from the data base.

formDataSource.reread()
formDataSource.refresh()


research():Calling research() will rerun the existing form query against the database, therefore updating the list with new/removed records as well as updating all existing rows.

- Harry





November 01, 2012

How to get the current database name in axapta

How to get the current database name in axapta

Here is a small trick to know the name of current data base in axapta.
Axapta supports a class called SysSqlSystemInfo by using this class we can get the current database name...
To do this just create a new job and write following code or you can copy paste from here also.


static void sqlSysName(Args _args)
{
    ;
    info(SysSQLSystemInfo::construct().getloginDatabase());
}

- Harry

October 20, 2012

Document Handling in Microsoft Dynamics AX

Document Handling in Microsoft Dynamics AX 2009 and 2012





Document Handling is very useful to attach files related to AX data to forms. It’s possible to add data at any form. It is also useful to attache any reference document to any record in Form.
To use Document Handling you have to activate it by follow these steps...

To activate this feature follow the next steps:


1. Go to BasicSetupDocument management:


image
image
2. Setup Parameters:

image

Active directory is the default path where allocate the files to attach.
Check Use Active document tables has to be activated.


image

Number sequence to numerate the attachments.
3. Define Document types:

image

For each type it’s necessary define the location folder:

image

4. Select in which forms it’s possible to attach documents in Active document tables:

image


5. Now, we can attach documents in the above forms. For example in Employees form:

image
image


For this example, we are going to attach a Photo:
image

Select the photo and click open:

image


With the check Show file activated we can see the photo/document:

image

Also, we can open the document with the right button Open.

-Harry

October 16, 2012

Types of delete action

Types of delete action

In Table node there is a sub node called "Delete Action". In axapta there is mainly three type of delete action. Each of them have their own specific use. Here is the simplest defination for each of them.
Cascade
A cascading deletion action will delete all records in the related table, where the foreign key is equivalent to the primary key of the current table. That is, deleting the parent record will also delete the child record(s) in the related table.
This cascading will take place whether the deletion is performed in code or directly by a user through the user interface.
Restricted
A restricting delete action will raise an error message if the user tries to delete a record, where records exist in the related table where the foreign key is equivalent to the primary key of the current table.
This error will only appear if the deletion is performed through the user interface. A deletion from X++ code will be allowed to proceed and will not be cascaded to the related table. In this case the programmer should call .validateDelete() themselves prior to the call to .delete()
Cascade+Restricted
This delete action normally works as a Restricted delete action. However if the deletion is performed through X++ code, no error will be raised and the deletion will be cascaded to the related table.


for more details on delete action follow these links


- Harry



October 10, 2012

October 09, 2012

Build numbers of Axapta

Build numbers of Microsoft Dynamics Ax

Hi all,



Here theAxapta Versions, with a description of the version represented.
in following tables all build version numbers are split into three parts. 
First one is  the client version number , followed by the application version. Formatted 
like: Build #client version/application version/localization vertsion e.g. #1951.7500/514-320/OP023-196 - for 3.0 KR2 client and 3.0 SP4 application.

Dynamics AX 2012
Build number Version
6.0.852.78 2012 Beta
6.0.947.0 2012 RTM
6.0.947.61 2012 Cumulative Update 1 (CU1)
6.0.947.280 2012 Cumulative Update 2 (CU2)
6.0.947.862 2012 Feature Pack
6.0.1108.670 2012 Feature Pack with CU3





Dynamics AX 2009
Build number Version RPC interface version
5.0.593.0 2009 RTM 50444.0 (C50C.0000)
5.0.593.439 2009 Hotfix Rollup 1 (RU1) N/A
5.0.593.662 2009 Hotfix Rollup 2 (RU2) N/A
5.0.593.827 2009 Hotfix Rollup 3 (RU3) N/A
5.0.593.1084 2009 Hotfix Rollup 4 (RU4) N/A
5.0.593.1287 2009 Hotfix Rollup 5 (RU5) N/A
5.0.593.1429 2009 Hotfix Rollup 6 (RU6) N/A
5.0.1000.52 2009 SP1 50444.0 (C50C.0000)
5.0.1500.358 2009 SP1 Hotfix Rollup 1 (RU1) 50444.0 (C50C.0000)
5.0.1500.809 2009 SP1 Hotfix Rollup 2 (RU2) 50444.0 (C50C.0000)
5.0.1500.1313 2009 SP1 Hotfix Rollup 3 (RU3) 50444.0 (C50C.0000)
5.0.1500.2116 2009 SP1 Hotfix Rollup 4 (RU4) 50444.0 (C50C.0000)
5.0.1500.2985 2009 SP1 Hotfix Rollup 5 (RU5) 50444.0 (C50C.0000)
5.0.1500.3761 2009 SP1 Hotfix Rollup 6 (RU6) 50444.0 (C50C.0000)
5.0.1500.4570 2009 SP1 Hotfix Rollup 7 (RU7) 50444.0 (C50C.0000)
5.0.1500.6491 2009 SP1 Hotfix Rollup 8 (RU8) 50444.0 (C50C.0000)





Dynamics AX 4.0
Build number Version RPC interface version
4.0.1659.26 4.0 RTM 41638.0 (A2A6.0000)
4.0.1659.35 4.0 RTM (localized) N/A
4.0.2163.0 4.0 SP1 42060.0 (A44C.0000)
4.0.2500.XXX 4.0 SP1 DIS layer hotfixes 42060.0 (A44C.0000)
4.0.2501.116 4.0 SP2 42060.0 (A44C.0000)
4.0.2503.XXX 4.0 SP2 DIS layer hotfixes 42060.0 (A44C.0000)





Axapta 3.0
Build number Client version AOCP version
1951.8 3.0 N/A
1951.17 3.0 SP1 60029 (0xEA7D)
1951.18 3.0 SP1 N/A
1951.2410 3.0 SP2 60031 (0xEA7F)
1951.2411 3.0 SP2 Hotfixed 60031 (0xEA7F)
1951.3730 3.0 SP3 60031 (0xEA7F)
1951.3733 3.0 SP3 Hotfixed 60031 (0xEA7F)
1951.4060 3.0 SP4 60031 (0xEA7F)
1951.5160 3.0 SP5 61031 (0xEE67)
1951.6710 3.0 Kernel Rollup 1 61031 (0xEE67)
1951.7500 3.0 Kernel Rollup 2 63031 (0xF637)
1951.7609 3.0 Kernel Rollup 3 63031 (0xF637)
Build number Application version
514-90 3.0 SP2
514-193 3.0 SP3
514-320 3.0 SP4
514-513 3.0 SP5
514-859 3.0 SP6


-Harry

September 27, 2012

How to Restore deleted sales order or purchase order

How to Restore deleted sales order or purchase order in AX 2009






Hi Frnds,

Some times fortunately or unfortunately user delete a record from Purchase Order OR Sales Order Forms,
and it can be drag you in a big problems, Here I am sharing a trick to restore these deleted Order records.
When ever a record is deleted from a Form, it sits in the void tables. These orders can be viewed from

AR -> Inquiries -> History -> Voided sales order or AP -> Inquiries -> History -> Voided Sales order.

AP -> Inquiries -> History -> Voided sales order or AP -> Inquiries -> History -> Voided Purchase order.

Now from this form you can only view the deleted orders but there is not option of restoring them.
Below are some sample code, you can use this to restore the voided orders.

Sales order restoration:
static void restoreDeletedSO(Args _args)
{
    SalesTableDelete    salesTableDelete;
    SalesLineDelete     salesLineDelete;
    SalesTable          salesTable;
    SalesLine           salesLine;
    ;

    SalesTableDelete = SalesTableDelete::find('00450_036', true);
    ttsbegin;
    switch (salesTableDelete.Cancelled)
    {
        case Voided::Voided :
            salesTable  = conpeek(salesTableDelete.SalesTable, 1);
            salesTable.insert();

            while select forupdate salesLineDelete where salesLineDelete.SalesId == salesTableDelete.SalesId
            {
                salesLine = conpeek(salesLineDelete.SalesLine, 1);
                salesLine.insert();
            }
            salesTableDelete.delete();
            break;

        case Voided::linesVoided :
            while select forupdate salesLineDelete where salesLineDelete.SalesId == salesTableDelete.SalesId
            {
                salesLine = conpeek(salesLineDelete.SalesLine, 1);
                salesLine.insert();
                salesLineDelete.delete();
            }
            salesTableDelete.delete();
            break;
   }

   ttscommit;
}


Purchase order restoration:





static void restoreDeletedPO(Args _args)
{
    PurchTableDelete    purchTableDelete;
    PurchLineDelete     purchLineDelete;
    PurchTable          purchTable;
    PurchLine           purchLine;
    ;

    purchTableDelete = PurchTableDelete::find('00242_049', true);
    ttsbegin;
    switch (purchTableDelete.Cancelled)
    {
        case Voided::Voided :
            purchTable  = conpeek(purchTableDelete.PurchTable, 1);
            purchTable.insert();

            while select forupdate purchLineDelete where purchLineDelete.PurchId == purchTableDelete.PurchId
            {
                purchLine = conpeek(purchLineDelete.PurchLine, 1);
                purchLine.insert();
            }
            purchTableDelete.delete();
            break;

        case Voided::linesVoided :
            while select forupdate purchLineDelete where purchLineDelete.PurchId == purchTableDelete.PurchId
            {
                purchLine = conpeek(purchLineDelete.PurchLine, 1);
                purchLine.insert();
                purchLineDelete.delete();
            }
            purchTableDelete.delete();
            break;
   }

   ttscommit;
}



If you have any query for the same feel free to ask.  
-Harry

September 22, 2012

AX 2012 – Data Migration Framework


AX 2012 – Data Migration Framework: Step-by-step setup

Recently i found a great blog on Data Migration Framework,
follow this link

AX 2012 – Data Migration Framework: Step-by-step setup

Its really help full for the step by step process of Data migration in AX 2009 to Ax 2012.

- Hary

September 10, 2012

How to send E-Mail In Microsoft Dynamics AX

How to send E-mail In  AX

There are more than one way to send emails through Microsoft Dynamics AX system, using X++ code.
The most recommended way is to use the standard mail mechanism built in the system.
That way copies of any email you send will be save in the Email sending status form (based on tableSysOutgoingEmailTable) and you will be able to monitor and see status of sent emails:

http://theaxapta.blogspot.in/

(Administration -> Periodic -> E-mail processing -> Email sending status; Form: SysOutgoingEmailTable)





This mechanism based on a system table that contain the emails, and a batch job that scan that table and send the emails, one by one (with retries and status controlling).
This technique is very simple to use and therefore it has some disadvantages; you cannot add attachments or use advanced email properties (cc, bcc, priority flag, etc).
To use this mechanism, first you have to make sure you a SMTP server configured and running.
Go to
  Administration -> Setup -> E-mail parameters 
and fill the required settings:



(Form: SysEmailParameters)

Next step is to make sure the E-mail distributor batch is up and running.
Go to
  Basic -> Inquiries -> Batch Job and check if the batch job exists with status Executing orWaiting.



(Form: BatchJob)
If it doesn’t, you can activate it from Administration -> Periodic -> E-mail processing -> Batch.
Now we are ready to implement our X++ code:
void SendMail()
{
    SysMailer mail;
    SysOutgoingEmailTable outgoingEmailTable;
    SysEmailItemId nextEmailItemId;
    Map map;
    str SenderName, SenderEmail, To, Subject, Body;
;

SenderName = "X++.info";
SenderEmail = "Sender@xplusplus.info";
To = "recipient@xplusplus.info";
Subject = "Subject line for the email";
Body = "<B>Body of the email</B>";

nextEmailItemId = EventInbox::nextEventId();
outgoingEmailTable.EmailItemId = nextEmailItemId;
outgoingEmailTable.IsSystemEmail = NoYes::No;
outgoingEmailTable.Sender = SenderEmail;
outgoingEmailTable.SenderName = SenderName;
outgoingEmailTable.Recipient = To;
outgoingEmailTable.Subject = SysEmailMessage::stringExpand(Subject, map);
outgoingEmailTable.Priority = eMailPriority::Normal ;
outgoingEmailTable.WithRetries = false;
outgoingEmailTable.RetryNum = 0;
outgoingEmailTable.UserId = curUserId();
outgoingEmailTable.Status = SysEmailStatus::Unsent;
outgoingEmailTable.Message = Body;
outgoingEmailTable.LatestStatusChangeDateTime = DateTimeUtil::getSystemDateTime();
outgoingEmailTable.insert();
}

The result of the example above will shown in the Email sending status form as mentioned above.



(Administration -> Periodic -> E-mail processing -> Email sending status; Form: SysOutgoingEmailTable)

- I Hope it will  usefull for all of you...
-Harry