David Sandor

Build succeeded.

Microsoft Dynamics Ax 2009 Repairs Module in Silverlight 4

clock May 17, 2011 13:46 by author dsandor

Business Problem

Microsoft Dynamics Ax 2009 has a gap in functionality with regard to order management for repair orders.  MDSi has several equipment repair and configuration labs on site.  Customer equipment can be staged and configured or physically repaired and reconditioned.  While Microsoft Dynamics Ax 2009 does provide some of the functionality required to perform in-house repairs, it falls short in supporting the expanded workflow of a repair lab.  Repair orders needed to be tracked, labor costs tracked, and part/item inventory locations need to be updated in Ax to reflect where the parts are located based on workflow transactions.  For example, if a repair technician brings a part to his/her workstation and marks the repair line as in process, Ax needs to be updated to reflect the inventory has been transferred to the repair technicians ‘bin location’.

Solution

The solution was to fill the gap with a Silverlight 4.0 line of business application that will provide a simple user interface that allows warehouse workers and technicians to simply change the status of a repair line.  The application will perform the necessary inventory movement journal transactions to move the part from staging bins to in process and finally to complete warehouse bins.  If a part is successfully repaired a sales order is generated to allow for the invoicing of the repair.  If the repair cannot be completed, a disposal order is created.

AllRepairs

All repair orders show in the main view.  Users can filter or group using the data grid.  From this view the user can also view the repair lines of a repair order and edit the details of a repair order.

RepairOrderDetails

Creating or editing a repair order is accomplished through the screen above.

RepairOrderDetailEdit

Editing the details of a repair line displays a modal view.

PostPickingList

Warehouse personnel can pick the repair lines that are awaiting staging.  The above view shows all the repair lines that were picked by user dsandor.  From here, the user can print repair labels for the items and post the items.  When the user posts the items it indicates to the repair technicians that there are parts in the ‘inbound’ repair staging bin location.  Technicians will retrieve the items from the staging location and indicate the part is now ‘in repair’ which transfers the part in Ax to the tech’s bin location.

This project was developed in Silverlight 4.0 and C#.  It leverages WCF Services and SQL Server 2008 R2 T-SQL Stored Procedures to query data from Microsoft Dynamics Ax 2009.  Create, Update, and Delete operations are performed by interfacing with the .NET Business Connector for Dynamics Ax.  The application uses the MVVM design pattern and was developed in little over one week.



Dynamics Ax 2009 Logon/Logoff overhead, Business Connector, AIF.

clock April 17, 2011 17:54 by author dsandor

So last week I attended Convergence 2011 in Atlanta to prepare for Dynamics AX 2012.  I attended a few interactive discussions and met some folks that made some rather wild claims that I knew for a fact were wrong.  I advised them that they were probably missing something or there was a problem with their installation / database / or code.

The claim was that there is a 2 or more second authentication delay when logging on to Dynamics Ax from the AIF (and others claimed from the Business Connector as well).  Someone stated that it took them 5 hours to import 30,000 sales orders via the BC.  I import a heck of a lot more data then that on a routine basis and I am confident I could import 30k sales order in less than 2 mins.

The proof that they are wrong.

To prove this I wrote an application that logs on to AX and then off of AX and times the process with the Stopwatch class.  The system running AX is a Dynamics AX 2009 SP1 installation on a Dell i7 920 with 12G of RAM.  AOS, App files, and DB (SQL 2008R2 with 4GB of ram allocated to SQL) all run on the same machine.  So this is a basic low end developer workstation running everything.  Your production servers should run circles around the performance of my test machine.

Here are the results:

I ran the loop to logon and logoff 100 times.  You will see the first call takes 220ms and each subsequent call is at about 14ms.  This is a far cry from the 2,000+ ms claims from the interactive discussion at Convergence.

Start time: 0
sessionId: 5
Stop time: 220
Elapsed time: 220

Start time: 220
sessionId: 6
Stop time: 237
Elapsed time: 17

Start time: 237
sessionId: 7
Stop time: 256
Elapsed time: 19

Start time: 256
sessionId: 8
Stop time: 270
Elapsed time: 14

Start time: 270
sessionId: 9
Stop time: 284
Elapsed time: 14

Start time: 1629
sessionId: 103
Stop time: 1643
Elapsed time: 14

Start time: 1644
sessionId: 104
Stop time: 1658
Elapsed time: 14

What I suspect is that the code these folks are using is very poorly written.  Potentially executing a Refresh() call for each session that is constructed.  If you are running into a performance problem with your AIF or Business Connector code feel free to contact me to help you track it down.  My consulting rates are reasonable :)

The code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Dynamics.BusinessConnectorNet;
using log4net;
 
namespace AxConsoleForTests
{
    class Program
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));
 
        static void Main(string[] args)
        {
            
 
            using (Axapta ax = new Axapta())
            {
                string aosConnString = string.Format("{0}@{1}:{2}",
                    "ceu",
                    "devsql-s-06",
                    "2713");
 
                log.InfoFormat("MyMethodName - Connecting to AX Server: {0}", aosConnString);
                System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
                sw.Start();
                long startTime = 0, stopTime = 0;
 
                for (int i = 0; i < 100; i++)
                {
                    try
                    {
                        startTime = sw.ElapsedMilliseconds;
                        Console.WriteLine("Start time: {0}", startTime);
 
                        ax.LogonAs("axTestUser", "",
                            new System.Net.NetworkCredentials
                              ("axTestUser", "password", "devsql.local")
                            ,
                            "ceu", "", aosConnString, "");
 
                        Console.WriteLine("sessionId: {0}", ax.Session());
 
                    }
                    catch (Exception ex)
                    {
                        log.ErrorFormat("MyMethodName - Failure: {0}\r\n{1}", ex.Message, ex);
                        throw ex;
                    }
                    finally
                    {
                        ax.Logoff();
                        stopTime = sw.ElapsedMilliseconds;
 
                        Console.WriteLine("Stop time: {0}", stopTime);
                        Console.WriteLine("Elapsed time: {0}\r\n", stopTime - startTime);
                    }
                }
 
                sw.Stop();
            }
            
            Console.WriteLine("Done");
            Console.ReadLine();
        }
    }
}

In order to thwart any comments that I cheated by placing my loop inside a using statement, I looped outside of it as well and the results are the same. 



About the author

David Sandor is a Software Architect working in Chicago, IL.  My development focuses around the Microsoft Stack including Azure, AppFabric, Silverlight, WPF, .NET Framework, and various mobile devices including iOS (iPhone/iTouch), Android, Windows Mobile and Windows Phone 7.

Month List

Sign in