AX7/AX 2012 Retail Omni-channel Hub-and-Spoke Architecture

The simplest definition of “hub and spoke” is that it is a model for integrating the ERP system used at a company’s headquarters with the systems used by its subsidiaries and branch offices. This blogpost discusses approaches on how to benefit from the fast innovation cycle that Dynamics AX have, without starting a new big-bang ERP implementation project.

Implementing any ERP system is a huge investment. It is not uncommon that thousands of hours is required before you can start to see the benefits. The cost of performing a large scale upgrade simply cannot be justified. It is therefore common to see companies implementing Dynamics AX, and then waits a few years before they take the effort to upgrade to newer releases. In my experience I see that it is most common to jump over a major release.

The innovation cycle that we see with Dynamics AX, new ground breaking technology is being released every year. Much of this new innovation is directly related to new possibilities in having true Omni-channels. The Dynamics AX Retail solution became mature in release AX 2012 R3. But there is a lot of companies still using AX 2009, any they have a well working systems for financials, procurement, supply chain and order management. They don’t want to upgrade, but they are still missing the ability to benefit from becoming a true Omni-channel retailer. The challenge is that the competition will be stronger and more mature.

I have met several customers that are implementing AX 2012/AX7 only for the Omni-channel, while keeping their AX 2009/legacy system taking care of the traditional ERP-processes. This approach focuses on limiting the implementation scope to only cover the Omni-Channel Retail vision. The idea is to only use AX 2012 on the retail channels. This means that retail stores, WEB, retail hierarchies, call-center is features that the AX 2012 (green) is covering. Then an integration between the legacy system (AX 2009) and AX 2012 is done using DIXF, that seamlessly connects the systems.

What I like about the Dynamics AX retail, is that what we currently have in AX 2012 is a very stable and is built for supporting a much faster implementation cycle. This means we can faster take advantage of new technologies. The AX for retail support the N-1 approach. This means that we can upgrade the AX 2012 parts to AX7, without making changes to the POS or the e-commerce systems. We can also in a timely fashion roll-out updated version to new channels, without being concerned of disrupting the existing channels.

I can share a personal experience with this approach. A customer came to us that had Dynamics NAV as their legacy system, and wanted to roll-out Dynamics AX POS to several countries. From the time we did the kick-off, and until the first store was up and running it took only 8 hardworking weeks. We used the Hub-and-Spoke approach, and it shows that it is a quick and achievable way to get return-on-investment fast.

So my advice is; Start your Omni-Channel journey today. Don’t wait until you have upgraded your legacy systems, because you can do that later.

Happy DAX’ing friends, and thanks for reading my blogposts!

AX suggestion: XML Columns and XML indexes

In AX we have the following datatypes we can use in table fields.

But in MS SQL server there is a XML data type. With the XML data type we can store XML documents in the SQL Server database. And we can create columns and variables of the xml type and store XML instances in them. we can also create XML-indexes that speeds up searching on the XML contents. As seen here, I have manually added a XML column, and a XML primary index.

The Xml datatype allows us to perform several operations on the xml data from within t-sql. Although this is not very fast, it’s often better than round-tripping and doing the xml parsing in an application like Dynamics AX. Take a look at the following blog-post for a sample SQL- Querying XML attributes from XML Columns.

Why would this be interesting for the Dynamics AX ?

Let’s say we want to have the possibility to dynamically add new fields and information to an item/customer/BOM, but we don’t want to make customizations. One possibility would then be to have a XML field or a related table that contains a XML datatype column. In this column new fields and values could be stored inside the XML. By having some generic code that is extracting the XML values into fields or computed columns, would mean that we could provide a generic way of letting the user interact with dynamic fields, and that the user could add the fields as wanted on the fly without customizations. And still have the search, sort and filter capabilities.

I would like to use it for storing metadata like searchable retail product attributes. Since the XML format is a bit generic additional actions and events could also be stored inside the XML document. This could be functional triggers and workflows to be executed. It could even be specified down to the lowest record level.

So what is the difference from having XML’s in an ordinary text field ? One difference is the ability to use XML indexes, and to have search, filter and sort capabilities on the values stored inside the XML, without parsing the entire XML. More information on this is available here. Then the user could work with dynamic fields as it was real fields.

The first step in exploring this possibility is to have XML columns and XML indexes available in AX.

So my question to Microsoft is “Can we get the XML datatype and the ability to create XML indexes in AX 7.X ?

At least I think it is an interesting idea for the future.

DAX2012R3CU9 – DIXF – Automate import/export without customizations

The Microsoft Dynamics AX 2012 Data Import/Export Framework(DIXF) is an AX module import and export data in Microsoft Dynamics AX. We often use it in data migration projects to load legacy data from old systems. I was wondering if I could use DIXF as an automated integration, without any customizations. I wanted to see if I could have a folder where new customers are dropped in a folder, and then the DIXF automatically picked up the file, and imported it.

My first step is to have a small and minimalistic Excel sheet, that users can paste in the new customer records. This is how my Excel sheet looks like:

Most of these customers exists from before, but the last record is a new customer that don’t exists in my database.

The recommended process of setting up an import/export process is described here.

The first step is to create a source data format:

I then determine what entity to use, and create a target entity

When I do this, the mapping is done automatically for me, and I don’t have to understand all the database related complexity.

My next step is to create the processing group

 

I then click on the Entities in the processing group, and I select my created entity and that I want to use my created Excel source data format. I also select a sample file to see if the mapping is OK.

I then just check the mapping from Excel to the staging format, and make the necessary corrections.

My next step is to go back to the processing group, and to make the necessary batch job for automatic processing.

As you see here, I set the “type” to Directory, that DIXF will scan for new files. I also specify directories for processing, completed and error. I have therefore created the following directory structure for each integration:

The other important thing is the “Execute target step”. This this used for also executing the step that transfers data from the staging table to the target tables.

I then want this to be work in batch, so I enable the batch processing.

And then I need to wait for an entire minute……… I then saw that the file was moved from the 1_new folder, and ended up in the ¤_Completed folder.

I also see in the execution history, that the files was imported into the staging tables, and then imported into the target tables.

In my customer overview, I now see that I have a new customer, but is also made sure that other related data as addresses, and phone etc was created.

This concludes how you can use DIXF to automatically import data. What I can now do to import data, is just to create my Excel file, and then dump it into the right folder (.\1_New), and then the batch system take care of the test.

If you wonder all entities that are “out-of-the-box” supported from Microsoft, then take a look here. If still something is missing, you can always ask a developer to assist in creating the DIXF entities you need.

Happy DIXF’ing J

 

DAX 2012 R3 – Retail Channel POS reports

Both ePOS, mPOS and the upcoming AX7 CloudPOS have a built-in feature for showing small reports and KPI’s directly on the POS. These reports are not running against the Dynamics AX database, but against the retail channel database connected to that specific terminal.

The great thing about these reports, is that it does not require any heavy development to define these reports. They are just XML report definitions, that queries the database for specific columns or stored procedures. This means that we easily can create new reports based on the direct reporting requirements. In the report, shown below a report called “Sales by staff” is shown. Here the staff name, number of transactions, sales amount and average sales amount is shown.

The report can also be shown as graphics.

The report definitions are located in the RetailàSetupàChannel report configuration.

We see here the report definition, and it can look a bit cryptic. But let’s format the XML to better understand the definition. We here see that the retail report basically have 3 sections. The dataset, parameters and the reportcharts.

As we can see here, the dataset is referring to a stored procedure, with 3 parameters; Channel, start-date and end-date. If we open the SQL stored procedure we can see the exact implementation of it.

We see here that the actual source tables are an inner join between retailTransactionTable and retailStaffTable. We can also see that the amount is “retailTransactionTable.paymentAmount”. This amount is the amount of what the customer is actually paying inclusive taxes.

But a US-based customer of me asked if it is possible to make some minor changes, and just show the reporting exclusive taxes. To do this, it means that we must do some changes. We cannot use the existing standard stored procedure. We could surely create new stored procedures, but rolling this out to hundreds of terminals would take a lot of time. But we have the option to use an actual query in the report XML definition instead.

The first step is to try to create a SQL that retrieves the sales amount minus taxes. As far as I have interpreted the table retailTransactionTable, it seems that the field I can use is the -1*[NETAMOUNT]. Here is the query tested directly in SQL Manager, and I have “yellowed” out the differences compared to the script used in the stored procedure CRT. GETSALESBYSTAFFREPORT

It seems to be working, and the next step is to create a new XML report definition. I therefore took the report “101 Sales by staff”, and created a “101_US Sales by staff”, with the following XML report. Here I have colored the differenced to the original report in yellow. As you can see here, I use a query, instead of a stored procedure.

I also localize the labels in the report

To have the new report available to the users, I need to run the CDX Async job to send data to channels.

  1. In AX, go to Retail > Periodic > Data distribution > Distribution schedule


  1. Select job 1110, click Run now


  1. Wait couple of minutes for the job to finish

I then have the new retail report available.

Then I get my POS report, where the amounts is without taxes J

Happy DAX’ing !

DAX 2012 R3 CU9 Retail database version mismatch and GAC issues

When upgrading the Contoso AX 2012 R3 CU8 to AX 2012 R3 CU9 and then trying to open the ePOS, you might get the following error. “Database version mismatch. You must either apply a Retail POS hotfix or upgrade the Retail POS database

In the event viewer you might see the following:

A TechNet article gave me some indications that the issue was related to the CreateDatabase.dll in the Retail Channel Utility.

My trick to make this work again was to open the installation folder for CU9, and apply the retaildatabaseutility.msp

This upgraded the CreateDatabase.dll to include upgrade to version 6.3.105

When I then re-run the Retail Channel Configuration Utility on the channel database and on the offline database

After successfully upgraded the channel database, when trying to startup the POS, I get the following error; Could not load type ‘Microsoft.Dynamics.Retail.Notification.Contracts.SignatureCaptureConfirmation’ from assembly ‘Microsoft.Dynamics.Retail.Notification.Contracts, Version=6.3.0.0, Culture=neutral..

And the POS screen shows no login, just the following “corrupted” screen.

I raisted a service request to Microsoft, and I got my answer today. It is related to All .NET applications will check first if the required assembly is available in the Global Assembly Cache (GAC) before searchin in the AppBase folder.

If we look at the C:\Windows\Microsoft.Net\assembly\GAC_MSIL we see the following

The date is older than the CU9. Microsoft explained me that this issue occures, because we have a “one-box” installation, and As we didn’t redeploy the Online Store after upgrading to CU9, the old assemblies were still in the GAC, causing the error. This would not come up in a real situation where all components are installed in separated server, but with this being an all in one environment we had this side effect.

The solution is therefore to uninstall the assembly from the GAC.

1. Check that GACUTIL is located at C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools in the VM-image

2. Run the command “gacutil /u Microsoft.dynamics.retail.notifocation.contracts”

You may need to do this for all Microsoft.dynamics.retail.* in the GAC_MIL folder

Then you can start the ePOS as expected J

Thank you Microsoft J

Dynamics AX 2012: Warming up for presales demo

To really impress potential buyers of Dynamics AX, it is important that we are capable to show that AX 2012 responds fast. We normally use the Contoso hyper-v demo environment, and our laptops have limited resources. Starting a demo on a cold system, we often see that forms takes some time to operate in optimal performance. If you already have opened a form, it is much faster the second time you open it.

So how can we give the users a view of a fast system without manually opening all the forms prior to the demo?

We can warm them up J. I use the following job-script to open and close all the forms I’m planning to use. I just traverse through the AOT, and open the form, and then I close them again.

static void WarmupRF(Args _args)
{
    //This code is for "warming" up all RF* forms and code I have in the VAR-layer
    UtilElements e;
    TreeNode treeNode;
    FormRun formRun;
    Args args = new Args();

    while select e
        where e.utilLevel  == UtilEntryLevel::var    //<-- spesify layer here
        &&    e.recordType == UtilElementType::Form  //<-- and only forms
        &&    e.name like "RF*"                      //<-- I only want the forms that starts with the prefix RF*
        {
            try
            {
                treeNode = xUtilElements::getNodeInTree(xUtilElements::parentElement(e));
                args.name(treeNode.AOTname());
                formRun = ClassFactory.formRunClass(args);
                formRun.init();
                //formRun.run();   //<-- No need to run the form, but sometimes it can load the data
                formRun.close();
            }
            catch
            {
                Infolog.clear();
                continue;
            }
        }
}

The code must be modified to suit what you want to “warm-up”, but you get the idea.

This will make you demo go much more smooth, and you truly show the potential and performance of a warm Dynamics AX system.

Happy DAX’ing

DAX 2012 Remove reservations and markings from a sales order

Some friends of me have asked how to remove reservations and markings on a sales order. Going through line by line can be time consuming and they wanted to know how this could be solved by a single “click”.

 

static void Tutorial_UnreserveSalesTable(Args _args)
{
    InventTrans             inventTrans;
    InventTransOrigin       inventTransOrigin;
    SalesLine               salesLine;
    InventMovement          inventMovement;
    InventUpd_Reservation   inventUpd_Reservation ;
    SalesId                 SalesId = "001260";//<--- Send/get sales id here

    // Remove reservations and markings on a reserved salesorder
    while select inventTrans
        where inventTrans.StatusReceipt                == StatusReceipt::None
           && (inventTrans.StatusIssue                 == StatusIssue::ReservPhysical 
           ||  inventTrans.StatusIssue                 == StatusIssue::ReservOrdered)
        exists join inventTransOrigin 
            where   inventTransOrigin.RecId            == inventTrans.InventTransOrigin
        exists join salesLine 
            where   salesLine.InventTransId            == inventTransOrigin.InventTransId                    
                &&  SalesLine.SalesId                  == SalesId    
    {
            if (inventTrans.MarkingRefInventTransOrigin)
            {
                InventTransOrigin::deleteMarking(inventTrans.MarkingRefInventTransOrigin, inventTrans.InventTransOrigin, -inventTrans.Qty, true);
                InventTransOrigin::deleteMarking(inventTrans.InventTransOrigin, inventTrans.MarkingRefInventTransOrigin, inventTrans.Qty, true);
            }

            if (inventTrans.StatusIssue == StatusIssue::ReservPhysical || inventTrans.StatusIssue == StatusIssue::ReservOrdered)
            {                
                Inventmovement = inventTrans.inventmovement(true); 
                inventUpd_Reservation = InventUpd_Reservation::newInventDim(inventmovement,inventTrans.inventDim(), -1 * inventTrans.Qty, false); 
                inventUpd_Reservation.updatenow(); 
            }
    }
}

The next step would be to create a class, so that it can be performed in CIL, and some code that refreshes the sales order for the end-user.

AX2012 – How to get Retail Store specific CUE’s

In Dynamics AX, the role center may contain a lot, but some times it is wanted to show more specific and isolated information. In this blog-post I would like to show you how to create a cue that only shows number of sales and amount related to a specific retail store. This blogpost is meant to show the pattern we can use, and is not only restricted to retail. We can use this technic almost everywhere in Dynamics AX.

Here we see a CUE where I show the number of sales and the amount for a specific store. But the nice thing here, it that the values changes depending on what store the user is assigned to.

Do be able to do this we need a dynamic query, that changes the store, depending on the current user, and we need to have a place, where a user is assigned to a store. This is already available in Dynamics AX, and is a setting on the User profiles

So here, I’m assigning a user to a role, and to a store. The next thing I need to have is a way to sum up all the retail sales transactions, and for this I use the form Retail sales transactions.

I then create an advanced filter by using the CTRL-F3, and save as a CUE.

You see here that in the criteria for store number, I write (EGCurrentRetailStoreID()). This is a very nice trick in Dynamics AX. The ability to create dynamic queries. I have blogged about it before here.

The code needed to use dynamic query criteria is located in SysQueryRangeUtil is the following:

This code will return the store ID for the current user. The last step is to select the CUE in the shared role center.

Then you have a CUE, that shows the sales in your local retail store.

 

Happy DAX’ing

New DAX 2012 R3 CU8 Global Retail codeplex solution available

Hi friends.

I’m happy to announce the first release of a new free codeplex solution; Global Retail.

The solution covers:

  1. Global Product price templates – The ability to assign a price template to a product, that will quickly enable retail prices available in different countries and currencies.
  2. Global Product pricing – The ability to set recommended retail prices directly on products. Global prices are posted in price journals to price agreements in all legal entities.
  3. Global Product barcodes – Assign and maintain product barcodes, and it will automatically synchronize to all legal entities.
  4. Simplified Product translations and simplified local pricing screen. Multi dimensional retail hierarchies for filtering, search and availability. Full price log and the use of case management for price change processes.
  5. Simplified file import and export of products, retail hierarchies, barcodes, prices, translations, availability, counting journals. (Excel, csv, xml)

Take a look here > https://ax2012globalretail.codeplex.com/ (more documentation will come later)

PS! This is the real-deal !

Giving away your silver for a golden future


(Picture is borrowed from Robin Dickinson)

In the AX-Ecosystem we see that blogging, sharing and networking is strong and open. Colleagues and knowledge friends find each other across company borders and culture. Quite a lot business is actually created through this community. And those that is not here will struggle to get into position. Some people ask me: “Why are you doing this ?” This quick answer is: “Because I like to, and because it is fun”. But there are more to it than that. Here is the “secret two line” business model of sharing.

  • Give away some ideas, components/code, wisdom and experience – for free – and hope that the dynamics ecosystem (the crowd) will use it.
  • Then do our best to make sure that some of them want to buy more of our ideas, our know-how and our hard-earned wisdom and experience.

Some companies talk about the value of protecting their IP-rights, and they have IP-rights on everything. Down to the little small code samples. But an IP-based business model have some fundamental issues:

  • Revenue is often based on licenses and yearly support fee’s.
  • Requires substantial costs on sales, presales, support and R&D efforts to meet standards and expectations.
  • Keeping it on the “pricelist” have a cost.
  • Customers expect components to be compliant with new Microsoft versions and releases.
  • Bug and Issues are expected to be fixed free of charge.
  • Risks quickly becomes expensive

The assumption is that the revenue must be higher than the costs of maintain and keeping the components on the price list.

However, what we see is that Investments stops. No innovation. Very difficult to find for the customers. Knowledge is lost, and IP based components are often not profitable in long term.

 

So, what kind of things are we talking about ?

  • Small ideas, that would never be a product.
  • Potential reusable components.
  • Customer financed customizations.
  • Basically things we cannot build an ordinary business model on.

One alternative is to use Codeplex as a business model.

  • The Dynamics ecosystem is small. Very easy to get high visibility.
  • Sharing is a very positive message. Can strengthen the your brand.
  • Can increase service revenue. New customers seek knowledge from the sources.
  • Triggers customers “Pull” behavior instead of “Push”.
  • Reach new potential employees that take a pride on sharing their knowledge and ideas.

A few days ago, I wanted to test this approach, so I blogged about a very small code piece I gave away, and wanted to measure the effectiveness, and here is the effect after 2 days.


How much would it cost in traditional marketing and brand building to achieve this reach ? Surely more then the small hour I used to publish it. I can also assure you that by giving away some of your work though sites like codeplex do build brand value and do generate a profitable and golden future.

 

(*From the Coca Cola dude)

Dynamics AX 2012 R3: Global recommended retail price

Maintaining retail prices in a multi company and franchise scenario can be a challenge in Dynamics AX 2012 R3. Let say we have a retailer with stores in many countries. We often also see owner structures that makes us model the retail chain with many companies.

I’m currently in an implementation to an international retailer present in 22 countries, and it keeps growing every day. To model this we need to create one Dynamics AX company per country and per partner.

The ability to maintain and control prices in such a scenario is a challenge, because prices is a property of a released item. (PriceDiscTable)

So we decided to create very small customization so that we could keep track of prices and item barcodes on the product instead of the released product level.

By doing this, the product managers have one screen where they can create and maintain product prices. The prices can be specified per currency, country and company/partner. But this is not just a simple table, but a two-way frontend for populating the standard AX price tables.

We therefore have a shared table:


The code for publishing prices into standard AX, using the price journal posting looks like this:


void publishProductRetailPrices()
{
    #Admin
    #Zebra
    DataArea                            dataArea;
    PriceDiscTable                      priceDiscTable;
    PriceDiscAdmTable                   priceDiscAdmTable;
    PriceDiscAdmTrans                   priceDiscAdmTrans;
    PriceDiscAdmCheckPost               priceDiscAdmCheckPost;
    InventDimId                         inventDimId;
    Ledger                              ledger;
    CompanyInfo                         legalEntity;
    LogisticsAddressCountryRegionId     countryRegionId;
    #define.ImportPriceDiscJournalName("Prices")
    PriceDiscAdmName                    priceDiscAdmName;

    ttsbegin;
    while select Id from  dataArea where dataArea.Id != #DATCompany
    {
        changecompany(dataArea.Id)
        {
            legalEntity             = CompanyInfo::find();
            ledger                  = Ledger::findByLegalEntity(legalEntity.RecId);
            countryRegionId         = CompanyInfo::find().postalAddress().CountryRegionId;
            this.createOrUpdatePriceGroup();

            if (this.RefCompanyId       == dataArea.Id ||
                this.CountryRegionId    == countryRegionId ||
               (this.RefCompanyId == "" && this.CountryRegionId == "" && this.CurrencyCode == ledger.AccountingCurrency))
           {
                if (InventTable::exist(this.ProductNumber))
                {
                    priceDiscAdmName = this.findOrCreatePriceDiscAdmName(#ImportPriceDiscJournalName,"@SYS342509");

                    priceDiscAdmTable.clear();
                    priceDiscAdmTable.JournalName       = priceDiscAdmName.JournalName;
                    priceDiscAdmTable.Name              = priceDiscAdmName.Name;
                    priceDiscAdmTable.insert();

                    priceDiscAdmTrans.clear();
                    priceDiscAdmTrans.initValue();
                    inventDimId = InventDim::findOrCreateBlank().InventDimId;

                    while select firstonly priceDiscTable
                        where   priceDiscTable.Relation         == PriceType::PriceSales
                            &&  priceDiscTable.ItemCode         == TableGroupAll::Table
                            &&  priceDiscTable.ItemRelation     == this.ProductNumber
                            &&  priceDiscTable.AccountCode      == TableGroupAll::GroupId
                            &&  priceDiscTable.AccountRelation  == #RRP
                            &&  priceDiscTable.Currency         == this.CurrencyCode
                            &&  priceDiscTable.InventDimId      == inventDimId
                            &&  priceDiscTable.PriceUnit        == this.PriceUnit
                    {
                        priceDiscAdmTrans.initFromPriceDiscTable(priceDiscTable);
                    }
                    priceDiscAdmTrans.Relation         = PriceType::PriceSales;
                    priceDiscAdmTrans.ItemCode         = TableGroupAll::Table;
                    priceDiscAdmTrans.ItemRelation     = this.ProductNumber;
                    priceDiscAdmTrans.AccountCode      = TableGroupAll::GroupId;
                    priceDiscAdmTrans.AccountRelation  = #RRP;
                    priceDiscAdmTrans.Currency         = this.CurrencyCode;
                    priceDiscAdmTrans.InventDimId      = inventDimId;
                    priceDiscAdmTrans.PriceUnit        = this.PriceUnit;
                    priceDiscAdmTrans.JournalNum       = priceDiscAdmTable.JournalNum;
                    priceDiscAdmTrans.QuantityAmountFrom  = 0;
                    priceDiscAdmTrans.Amount           = this.Amount;
                    priceDiscAdmTrans.UnitId           = InventTable::find(this.ProductNumber).salesUnitId();
                    priceDiscAdmTrans.SearchAgain      = NoYes::Yes;
                    priceDiscAdmTrans.insert();
                    if(priceDiscAdmTable.RecId)
                    {
                        priceDiscAdmCheckPost = new PriceDiscAdmCheckPost(false);
                        priceDiscAdmCheckPost.initJournalNum(priceDiscAdmTable.JournalNum);
                        priceDiscAdmCheckPost.run();
                        infolog.clear();
                    }
                }
            }
        }
    }
    ttscommit;
}

Project Quotes

The fall is high season for Dynamics AX projects, and we can often feel the pressure to make sure we can go-live. We have tons of different tools and suggestions to help us reach our goal. Like SureStep, RapidValue, LiveCycleServices, InfoSource and all kinds of methods to be in control, agile and lean in our projects. There is one project tool that is underestimated for successful implementations; Having fun !

Here are some project statements that can help us through the milestones; Enjoy!

Nothing is impossible for the person who doesn’t have to do it.

Never put off until tomorrow what you can put off until the day after.

Warning: dates in the calendar are closer than you think.

The first 90% of a project takes 90% of the time the last 10% takes the other 90%.

To estimate a project, work out how long it would take one person to do it then multiply that by the number of people on the project.

There are no good project managers – only lucky ones.

Planning without action is futile, action without planning is fatal.

If you don’t attack the risks, the risks will attack you.

If project content is allowed to change freely the rate of change will exceed the rate of progress.

If it wasn’t for the ‘last minute’, nothing would get done.

If an IT project works the first time, it is wrong.

Schedule – cost – quality: you can have any two.

A verbal contract isn’t worth the paper it’s written on.

A project gets a year late one day at a time.

A project as not over until the fat cheque is cashed.

A problem shared is a buck passed.

A minute saved at the start is just as effective as one saved at the end.

 

And remember; Creativity is intelligence having fun (Albert Einstein)

 

Dynamics AX 2012 R3 > Retail Essentials

I have been looking into a concept called Dynamics AX “Retail Essentials”. Retail essentials is a retail-centric configuration option for Microsoft Dynamics AX. Retail essentials provides a simplified, streamlined user experience that is optimized for organizations that use only the retail management functions of Microsoft Dynamics AX. Retail essentials is ideal for companies that have less complex requirements, and that have to manage only brick-and-mortar stores. In this configuration, access to typical Microsoft Dynamics AX functions is limited. Additionally, omni-channel retail capabilities such as e-commerce are not available.

To enable the Retail essentials, there is a configuration key that must be disabled.


So the change is for all companies, and applies to the entire installation.

What then happens is that the menu structure and screens changes dramatically. Only the «Retail essentials» menus are available. No other menus!


Also forms like Sales order and Purchase order changes quite a bit. Here is an example of what happends with purchase orders:



In total the following forms is “retail essentials” enabled:

CustTable, EcoResProductCreate, EcoResProductDetails, HcmJob, HcmPosition, HCMWorker, LogisticsPostalAddress, PirceDiscAdm, PurchCreateorder, PurchTable, RetailParameters,Vendtable. And also the list pages related to this.

Personally I like the idea of having a reduced the complexity in the store. But I don’t like that this is an “on/off” feature for the entire Dynamics AX 2012 R3 application.

If you would like to differentiate this on/off feature based on user/company/access rights etc, there is a central class that controls this behavior : RETAILSMB.


There are surely many other pitfalls, but it may be worth a try. It can surely make our retail store implementations easier for the store end users.

Happy DAX’ing

Generic prices in Dynamics AX 2013 R3

In Dynamics AX 2012 R3 you can specify a sales price on a released item. You cannot specify a price on a set of products using the trade agreements.

I wanted to change this, so that AX 2012 R3 do have the possibility to have a price that is used by many released products. Here is what I did:

First I created a new field on the item master sales (InventTableModule):

Then I made it possible to create sales price groups, and to specify prices per currency for this price group:

Then when creating sales order it selects the generic price.

With this little change I can now control prices on thousands of released products, and rather to put individual prices on each item, I just classify each item to a price group. Let’s say I have 10.000 released products and prices in 6 currencies this would minimum have resulted in 60.000 records in the price agreement table. If I in addition have 10 companies where I also want to use the prices, this results in 600.000 records on prices.

If I have standardized my pricing levels to consumer oriented prices, and using the sales price group, I would only need to maintain 60 * number of price groups. Just a fraction J

To make this happen, the following objects needs to be modified:

If you come across a similar requirement or you need this, feel free to contact me on the blog J

Happy DAX’ing

AX 2012 R3 : Do not enable WMS-II and the new Warehouse and Transportation management in the same installation

In DAX 2012 R3 we have received a new module for Warehouse and Transportation, that Microsoft acquired from Blue Horseshoe. In time it is expected that this will replace the WMS-II module that have been existing in Dynamics AX since version 2.0.

But there are some limitations that you need to be aware of. You should not enable both WMS-II and the new Warehouse and Transportation management configuration key. If you do so, then the following “red” issue will appear:

I asked Microsoft if they could come with an official statement regarding this issue, and here it is:

Microsoft Dynamics AX 2012 R3 includes new Warehouse and Transportation Management modules that are enabled by a single configuration key, along with the previously released Warehouse Management II module. Users should enable the configuration key for ONLY ONE of these modules, but not both, in a single-instance, single-partition deployment. Although technically feasible, enabling the configuration keys for both of these modules in a single-instance, single-partition deployment is not supported by Microsoft. This combination may result in a serious loss of data or the creation of incorrect data, which could block or interrupt business processes, impair future upgrades, or cause other adverse effects to your system or business operations. Microsoft is not liable for damages that result from your use or enablement of both of these modules in a single-instance, single-partition deployment. If you use or enable, or attempt to use or enable, both of these modules in a single-instance, single-partition deployment, Microsoft’s maximum, aggregate liability for this unsupported configuration is limited to direct damages in an amount not to exceed US$1.00. By downloading, installing, using or attempting to download, install, or use Microsoft Dynamics AX 2012 R3, you have agreed to these terms, which are a supplement to the Software License Terms for Microsoft Dynamics AX 2012 R3. See License code and configuration key reference for more information about enabling the configuration keys for the new Warehouse and Transportation Management modules or the Warehouse Management II module. The Warehouse and Transportation management configuration key is enabled by the Trade and Logistics license code, and the Warehouse management II configuration key is enabled by the Warehouse management II license code”

What this means technically is that the two following configuration keys should not be enabled together:

Since the “Warehouse management II” is locked, it means that you need to remove the licensekey for Warehouse management II.

I have also been asked by customers, what is the WMS II, and what would we loose if we want to use the WAX/TRAX ? And here is a list of features that is depending on WMS-II.

  1. WMS-forklifts
  2. Picking locations on warehouse items
  3. Location blocking causes

  4. Shipping templates
  5. Outbound rules
  6. Shipment reservation sequences and reservation combinations
  7. Store zones

  8. Store area’s
  9. Pallets and pallet types
  10. Pallet transport handling
  11. In addition everything related to consolidated shipping will also be removed, and just order picking will remain.

If you want to be support compliant, you need to take a clear choice of WMS-II or WAX/TRAX before starting any implementation or upgrade.

 

Running Dynamics AX R3 on Azure

To install and use Dynamics AX R3 on Azure is easy to setup is ready within 15 minutes.

All you have to do is to log into https://lcs.dynamics.com/

Then create a project, and click on the “Cloud hosted environments(Beta)”

Then click on the “plus” to deploy the image, and give it a name.

Let it run for 15 minutes, and the image is now available in the Microsoft Azure portal.

Then Click on the “Connect” button, and you will receive a RDP-file you can use to log into the image.

PS!

Here is some small tips for improving performance:

  1. Change the power plan to High Performance
  2. Set performance options in the VM to “Best performance”
  3. Run index rebuild/re-organize on both data and model database, as described here.
  4. I also “pimped-up” my VM images with 8 CPU and 56 Gb Ram, to get the best possible performance.(But it cost!)

 

Congratulation you are now “certified” for deploying Azure demo images for Dynamics AX 2012 R3:

 

 

AX 2012 R2 – Cross docking for smaller warehouses

Based on some customer requirements, a simplified generic “Cross-docking” solution have been created. When items is received, it was wanted that Dynamics AX should try to suggest a crossdock – putaway location on those arrival lines that could be sent within a spesified horizon. Also to mark the receipt and issue inventory transactions.

To accomplish this a new query based cross-docking setup screen have been created.

Here as many cross-docking rules as needed can be set up.

The main fields are:

Warehouse – where the rule is effective
Priority – search sequence of the rules
Crossdocking location name – Name of the rule/description of the location
Crossdocking horizon – number of days to look forward
Enable crossdocking – On/off parameter to enable/disable this crossdocking rule.

Then there are two query criteria that is used:
Receipt criteria : Is used to select what receipts that could be cross-docked, and is based on purchase and arrival lines. Create additional critiera like vendors, projects, items and item groups.
Issue criteria : Is used find crossdocking candidates, and is based on sales lines.

The grid is a view only, and shows show the query selection. This is for simplyfing the readability of the query.

To change the query, click on the “select values”, to get up a standard AX query Screen.

Some criteria lines are gray, meaning that they have been locked, and cannot be changed to the user. Some of the criteria is also dynamic values, like the confirmed shipdate that also handles orders there only requested shippingdates have been filled.

The receive process can be drawn like this:

This will result in a arrival journal that looks like this:

The Cross-docking feature will also work the same in the DCS/PDA solution.

 

Solution study in a medium complex crossdocking scenario.

Here I will show the crossdocking solution in action, when having multiple salesorders and where also some goods are crossdocked, and some are put to the warehouse.

First, the Crossdocking rules. I decided to test the scenario with 2 rules. One for each customer.

The first rule «priority1», covers ONLY item 100, and customer no-001, and outbound dock Out_01

The secound rule, covers all items, but ONLY customer DMO-100, and outbound dock Out_02

Then I create a small purchase order with the items 100 and 101, with 10 each.

I then create 2 sales orders both with the items.

I then want to use the DCS to create the receive:

As seen in the last DCS screen, we see that 5 lines is remaining. This because the 2 purchase lines, have been split to one line per destination. If we look at the Arrival journal in AX, we can see this split. The Yellow lines is the “cross-docking” lines.

If we look down at the inventory transactions, and check out the inventory marking we see the transaction effect of the cross-docking.

As seen here, the purchase is correctly marked against two sales orders. We also see that the inventory transactions for the sales order is reserved ordered:

If we continue with the DCS receive process, the user will be informed that the receive line is a cross-docking, with the correct quantity and also suggest the cross-docking location specified in the cross-docking setup

When all lines have been received, then the user clicks Post, and can then also post the product receipt list:

If we also check out the sales orders, we see that the reservation has been changed to “reserved physical” towards the location that was selected as the put-away location.

 

Post to Codeplex ?

AX 2012 R2 – Zoneless pick customization

A customer of me wants to perform consolidated picking, but do want to control on the shipping template if the picking routes should be split per picking area.

image

So the solution was to create a boolean parameter for this on the shipping template:

image 

Then this can be controlled in the consolidated picking creation process:

image

That’s it.  Shipping template based Zoneless pick achieved in a consolidated picking scenario.

Happy DAX’ing

AX 2012 R2 – Where is the picking lines created ?

In R2 there are several steps and places that picking routes/Picking lines are created, depending if you have an order-based picking or consolidated picking.

The fundamental element for a picking route is output orders, that acts as the basis.

And Output orders are created through the class\WMSOrderCreate:

clip_image001

As soon as the WMSOrder is created, it can try to attach itself to a shipment (consolidated scenario)(Also WMSOrderCreate)

clip_image002

If you follow the trace in the wmsOrder.autoAddShipment() you will get to the code where the WMSOrderTrans is created.

WMSOrderTrans is created here

clip_image003

And here :

clip_image004

The final step is the creation of the WMSPickingRoute, that happens in the shipment reservation.  And inside this method you will also find the creation process for the picking route.

clip_image005

So the sequence and steps for creating a picking route is the following :

1. WMSOrder is created

2. WMSShipment is created

3. WMSOrderTrans is created

4. WMSPickingroute is created

Also remember that the structure of shipmentId, PickingrouteID’s is very loose entities, and is not strongly anchored to inventTrans. So it is possible to move wmsorderTrans transactions between pickingroute and shipments quite easily by using X++.

 

Happy DAX’ing

Output orders and lines

The following post, is a bit advanced, and I guess that 90% of all implementations never encounters any issues related to this. But if you struggle with open inventory orders that “locks” your sales orders, then this post can bring some lights to it. It is valid for both AX 2009 and AX 2012.

In Dynamics AX you can split up the picking of a sales order (or any other issue-based orders) by using output orders (WMSOrder) and picking lines (WmsOrderTrans). The picking line lines can be “split” into several lines, if the quantity needs to be picked from several locations. As seen in the example below, you see one output order with 2 picking lines.

The quantity of the output order that is included in a shipment can be seen as this:

If I open the shipment related, I can see the same lines:

When you manually delete one(or all) of theese from the shipment lines

Then we see in the output order that if changes:

But the inventory transaction (inventTrans) does not change.

I often see people struggle in such scenario’s, because they feel “locked” by this marking on the inventory transaction. Often warehouse workers wants to make the “deleted” lines free and available to be places on a new picking route.

There is a way out of this, but it requires a small code change.

This will reduce the quantity on the output order, and making the inventory transaction “available” again to be reserved, and even to create a new picking route on the deleted lines.

Happy DAX’ing.

 

All X++ source code for Dynamics AX R3 available

Rumors says that in the upcoming AX 2012 R3, the entire library of X++ code will be available for Partners and Customers. The Dynamics community embraces this approach and says that this makes it possible for new solutions and ideas to be built 100% integrated with the Dynamics AX platform. Microsoft have even make it possible for others to share, using the codeplex.

A business analyst describes what’s happing as:

“All too frequently, SMBs and enterprises deploy expensive closed ERP systems, not realizing that significant cost savings and flexibility can be realized through the use of openness of Dynamics AX. And coupled with a near-instant deployment using Azure will allow many more companies to realize the benefits of ERP-systems with an open and available source code.”, says Kurt Hatlevik, a Dynamics AX nerd.


Competitors has described this approach as a “cheap” way to build a DAX-community and ecosystem. They argue that their own approach for proprietary closed systems is the only way forward to maintain a high revenue stream and customer dependence.

This is not a April’s-fool, but a Aprils-fact J

Update: Dynamics AX has always had an open X++ source code.  This post was a April’s-joke.

 

 

 

Dynamics AX: Why simplicity always wins

The Dynamics ecosystem love to complicate things. And now with the AX 2012 R3 it can really get complex, with the biggest codebase ever. The more functionality we demand to get into Dynamics AX, the better it will become, and the more we can sell, right?

Wrong.

Simplicity wins. Every time. (iPod, anyone?)

As a Dynamics AX “expert”, I get to hang out with other Dynamics AX “experts” (and we act all clubby and hip and cool like it’s some secret club – but it really is). In those circles I get to see and hear a gajillion awesome features that allows us so solve ANY problem. (Basically because the solutions is sets of LEGO-bricks we are selling, and you can build anything with LEGO)

Oftentimes, many of the solutions is over-complicated complex. For the ones that isn’t, the difference between a winning or losing solution invariably comes down to simplicity and elegance.

The Fix

Look folks – if we want to win in the ERP-marketplace, we must focus more on simplicity (twitter’s 140 characters anyone?). A few things to think about:

– What EXACTLY is the problem we are trying to solve? Do a lot of people have it and want it to go away?

– What’s the CURRENT way our customers treating the problem? THAT’S our competition – it’s their next-best alternative relative to your proposed solution. THAT’S what your solution has to beat (both from a capability and cost standpoint including accounting for switching costs).

– What’s the ABSOLUTE MINIMUM solution you need to put on the market to solve the problem? BUILD THAT and validate you have a solution that works.

Stop making solutions so hard, complex, and confusing. We are wasting investment dollars that instead could be used for marketing and scaling our much simpler (and cheaper to build) alternative solutions.

Create solutions that only require a few weeks of implementation time, and that is so easy to use that it can be trained in minutes.

“Simplicity is the ultimate sophistication.”
Leonardo da Vinci

WMS and voice pick with Google Glasses (Sci-Fi)

With the WMS and voice pick for Google Glasses you can revolutionize your supply chain and warehouse processes. Google glasses will

  • You will have both hands free
  • Directly connected to your ERP system
  • Support real time transactions like receiving, picking, counting and shipping
  • Guide the warehouse worker in all the processes both by voice and by visual graphics
  • Voice pick, scan barcodes using the built-in camera or use Bluetooth connected barcode scanner
  • Connect directly with vendors and customers when working with issues or questions

The only problem is that such a solution does not exist. The google glasses are still in the experimental phase, and it will still be a while before it is available as a commercial consumer product. But Google Glasses has been opened for commercial actors to create such applications and possibilities.

Who have the willingness and the resources to create such a solution ?

Dynamics AX 2012: At your service!

Dynamics AX Service management can be used for service agreements and service subscriptions, handle service orders and customer inquiries, and to manage and analyze the delivery of services to customers. You can use service agreements to define the resources that are used in a typical service visit. You can also use service agreements to view how those resources are invoiced to the customer. A service agreement can also include a service level agreement that specifies standard response times, and offers tools to record the actual time.

What I wanted was to see how much we could simplify the registration of needed repair materials and service hours.

The Dynamics AX service orders is tightly integrated to the project module, and sometimes our customers react that they feel the registration of materials in a warehouse scenario is a bit confusing. The reason for this, is that there are two ways of registering used items on a service order.

  1. You can key in the material in the service order (As you can see in the picture above), and then post it. Then the items will be SOLD from the specified location using a project item journal. There are now way to implement proper warehouse processes in this scenario.
  2. You can create item requirements, that essential is a sales order line, and so support warehouse processes. The drawback, it that the lines posted in the item requirement isn’t visible on the service order screen.

So I decided to create a very easy to use Data Collection Studio application, that allows a more simpler en easy to use approach, and that it closed to the expected process flow.

In this service order I need some items that is not on the list, so I scan item 100, and I need 2 pcs

On the service order, the new line is added, but is marked as “posted” :

But this is “just-for-show” to create a better visibility for the service operator.

The real transaction is located on the item requirements:

The next stage is packingslip update or invoicing.

By this added functionality it means that we have a very simplified way for allowing service personnel into the warehouse, and still maintaining 100% inventory accuracy.

I end this blogpost with a picture from WMD warehouse:

AX 2012: Future item reservation requirements

Those of us that have completed large scale Dynamics AX warehouse implementations knows the importance of having a control of item reservation. Dynamics AX 2012 supports several algorithms for reserving the right goods to a sales order(or any other issue transaction).

We can mainly classify the reservations into the following reservation types :

  1. Reserved ordered
  2. Reserved physical    

We can also them into categories:

  1. Normal” reservation
  2. FEFO and batch expiry date reservation
  3. Shipment reservation

But if you start looking deeper into the algorithms in AX 2012 R2 that actually performs the reservation, it is more or less located in the class InventUpd_Reservation.

The reservation in AX 2012 is pretty much user based, meaning that either a user/batch runs a process, and the reservation is done. There are a few exceptions where Dynamics AX 2012 will physically reserve goods when they arrive. But this relates to transactions that is already reserved ordered, or does have an inventory marking.

The way Dynamics AX 2012 is reserving, works in most cases OK, but there are a bit more functionality we would love to have. And here is my “wish list”:

  1. Reservation hierarchy. This means that when you create the sales order/transaction you may reserve on site/warehouse level. The customers order is physically reserved, but the system has not yet decided from where it actually should be picked from. When the picking route is created, then the reservation is sharpened down to more a detailed reservation specifying like location. At the TECH2014 it was shown that this will be there in future releases for a one-level reservation hierarchy. What I would love to see, is more levels, like 2 or even 3 levels. Meaning that you may start with site level. Then maybe after master planning or some other process, the reservation is sharpened down to warehouse. When the picking route is created then it could further be sharpened down to location or batch. In short, we want more reservation levels, because this gives us control and flexibility.

     

  2. Reservation period. The concept of reservation period means that you can control WHEN the reservation should happen. If you create a sales order with delivery date 6 months ahead, you don’t want to “lock the stock”, and waiting for the delivery date. If the items, let’s say only have 14 days lead time, why not have an engine that performs the reservation at the right time. And even more importantly, if a customer moves his requested delivery date, then the reservation engine should be able to “lift” the reservation back to “reserved ordered” or even back to “ordered”.

     

     

  3. Order Reservation sequence. We often know the concept of “first ordered – first served”. Some customers signals their demand and orders early to secure that they get the goods on their requested date. Then you have “bad” customers that needs the goods today, and just orders right when he needs it! The way Dynamics AX works, is that it does not give any customers any priority other than the delivery date. Meaning that you very easily could end up in a situation where the “good” customer could end up in a situation where the “bad” customer actually managed to physically reserve the limited goods. We need mechanism that would allow the “good customer” to be prioritized when limited goods should be reserved. A “ATP-sequence ID” should solve this issue, and making sure that customers that orders early and gives good visibility of their demand is more secure in getting their items on time.

     

  4. Reservation Location sequence

    In a warehouse we can have inbound, buffer, picking and outbound locations. But we can also have fast and slow locations. Items can also exists in multiple locations to prevent hotspot areas, or certain area is for different sales channels (like one for retail stores, one for eCommerce etc) It would be lovely to have a better control from what location should be prioritized depending on some criteria. Also when building up the picking route I could decide from witch location would be best to take the goods out from. I know from TECH2014 that the concept of location directives will be introduced in future releases, and we are looking forward to learn more about this.

Looking forward to see what the future brings. I have a feeling that 50% of my wishes will come true in AX 2012 R3.

AX 2012 Consignor solution available on CodePlex

The tool can be downloaded at http://ax2012consignor.codeplex.com/

There are some additional information that needs to be addressed. So here is my “What does the FAQ’s say” ?

Question

Answer

What is the Consignor solution?

The Consignor integration tool made available for Dynamics AX is a multipurpose tool for creating, exporting and importing CSV-files, XML-files or Excel spreadsheets.

Is it a generic solution?

The tool should be regarded as a generic tool, but as the name suggest, it does have a ready to use integration to Consignor. CONSIGNOR is a system designed for easy and efficient printing of labels, to address and send goods which are to be handled and delivered by a range of carriers, for example Posten Norge, Bring, Schenker, Tollpost, DSV, DHL, Nor Lines, Ramberg, and many more who use EDI data. CONSIGNOR may also be used to print labels for carriers who are not set up to handle EDI data. For an updated list of EDI supported carriers, please see Consignors website http://www.edi-soft.com/.

Who can use the tool?

The tool has been specifically created to enable end-users and business consultants to perform data export and import, without knowing how do develop in Dynamics AX and X++. Creating an export/import definition can be done in a few minutes.

Can this replace my other integration solutions?

No. This tool has a specific purpose to easily extract data from Dynamics AX. It is not built to replace or compete with any other integration solution.

How much does it cost?

Nothing it’s free at CodePlex. But if you can add more functionality to it, it is expected that you share with the community.

Is it fast?

No. It’s is not very fast. When exporting to Excel it is capable of a 15-20 lines per second. Exporting to XML or CSV is a bit faster.

Can it import data?

Yes it can import data from. But this is a alfa release, meaning that more testing is required. The logics for evaluating the import must in many cases be developed in separate classes to perform as needed.

How can I get help?

On CodePlex there are some documentation. But you can also add questions and report issues.

Is it difficult to install?

No. For now, the solution is exported as a XPO with a Zero footprint in AX. Later we will add it as a model. The current build is done with AX 2012 R2 CU7. Please remember to check the “issue list” before you install.

Can I have a demo?

Yes. Nice people can have a demo. Just ask meJ

 

Happy DAX’ing J

Import/Export: Reinventing the wheel

I was suppose to create a small tool for simplifying integrations to freight forwarders, but I ended up with an easy to use and zero footprint import/export solution. I wanted to create a solution that was easy to use for end-customers and business consultants, enabling them to very easily create CSV, XML and Excel files.

The Consignor integration tool made available for Dynamics AX is a multipurpose tool for creating, exporting and importing CSV-files, XML-files or Excel spreadsheets. The tool has been specifically created to enable end-users and business consultants to perform data export and import, without knowing how do develop in Dynamics AX and X++. The feedback I have received colleagues is very good, and it works as a basis for the upcoming consignor integration.

  1. How to use the consignor integration

    For an end user it is very easy to use the tool. There are two approaches to start the export.

  2. Export file using short-cut

    In Dynamics AX it is possible to short-cuts. For the Consignor, this short-cut is CTRL-Z. Then the following menu will be visible, if there exists a defined consignor format.


    Here the user can select a predefined format. If a Excel format is selected, then Excel will be opened and filled in. Also if XML or CSV is selected, a file containing the defined format will be opened.


    Export file using Menu

    It is also possible to create menu buttons to start the export, and this require a small “drag-and-drop” of a menu item to the form you want to have the consignor integration activated on.


    How to setup an integration

    The consignor integration setup is located under system administrationàperiodic, and consists of two menu items.

    Consignor menu

    In the consignor message types, the definition of the integration is setup.

    The consignor messages is all logged messages, when this are enabled for an integration.

    Consignor message types

    The consignor message types, it the form that is used to defines integrations. The form contains several settings, and in this chapter all fields are described.


    Message file details

    Field Description
    Message type Unique identifier of the integration. This is the name that the user will select, when selecting an integration type.
    Name Name of the integration type
    Note A small note can be added. Use this to log changes made to the integration.
    Approved Select if the integration is approved. Only approved integrations can be selected by the user. Also, when approved, the integration cannot be changed
    Include column names When exporting to a CSV file, the first line can contain the fieldnames. For Excel and XML this parameter have no effect.
    Log message To log all messages, enable this parameter.
    Open file After a file has been exported, the consignor integration can open the file. CSV files will normally be opened in Excel, and XML will be opened in internet explorer. But it’s the windows file association that decides when program to use when opening the file.
    Import/Export Define if the definition is an export, or an import. In the initial release, import is only supported using CSV files. But this will be changed in future releases.
    File type Select the file type of the export/import. The following format are available: Comma Separated File(CSV), XML and Excel.
    File path File path where the export files will be exported, and where files will be imported from.
    Archive file path When importing a file, from the “file path”, the file can be moved to the “Archive file path”. The reason for this, is because when importing files, the import batch-job can read a folder, and fetch all files that is dropped into this folder.

    Message datasource setup

    Field Description
    Source Class It is possible to select a predefined class, where all the fields have been setup. This simplifies creating integrations. The source class also provides support for more complex integrations that require coding to perform. When a source class is selected, the Main table is also automatically given. The field is not mandatory. For a detailed, list of available source classes se the appendix 1 for source classes.
    Main Table identifier All integration need to have a main table identifier. This is used to help the selection of what integrations that can be used, based on the data when the integration is started. If the user is on the customer form, then only integrations that have the customer table defined in the Main Table Identifier can be selected.
    Query setup The consignor integration supports quite complex data structures, where information is fetched from different tables, and display methods. The query will use available relations to present what can be associated with the main table. Right click on the data source to select what tables you want to add. Both n:1 and 1:n relations is supported, but in a 1:n relation, only the first record in the applied relation will be used in the integration
    Button:Criteria The criteria button is used to simplify the consignor message type selection. If the user have several integrations for different customers, then it is possible to define a selection query, so that the correct integration is presented to the user.
    Button:Reset Resets the query, leaving only the main table left.

    Message field setup

    Buttons Description
    Add a new field to the consignor integration definition
    Remove the selected fields from the integration
    This button will create all the fields for the integration, based on the source class.
    This button will create all the fields, based on the query that is associated with the integration.
    Renumber will renumber the fields, so that no fields have the same number. The field field will get the value 1, and so on.
    Multi select fields, and activate/deactivate the fields.
    Field Description
    Field ID This is the name of the field. When manually creating a integration, it will be the column name, or the XML tag identifier. If a source class is selected, normally the fieldname is automatically provided.
    Type The field type can be a database field, Class method, display method or a free text. Selecting Field means that the value is fetched from the associated table and field.
    Class method, means that the value is fetched/calculated in the associated source class. Display method, means that the value is fetched from a table display method.

    Free Text means that the values is defined in the default value field.

    Table Tables means the table where the value is selected from. Since the data source can be a query, there can be several tables to select data from.
    Field This is the field from the selected table. If the type is a display method, then the name of the display method can be selected here. For Class methods, it is not necessary to select a field. But when importing data, the data will always be placed in the field defined.
    Default value When exporting or importing data, and the source is missing a value, then the default text will be used.
    Description Just a textual description of the field. By default the text here is fetched from the help field in the extended data type.
    Active Only active fields will be imported/exported. Fields that is not active will be filtered away on approved messages.
    Field number The field number defines the sequence that the fields will be defined in a file. In a CSV file, field number 1 will be first, followed by 2. The field number can be defined manually, or automatically by using the “renumber” button. The field number can also be moved up/down by using the “up/Down” buttons.
    Unique index field This field indicates will this field should be regarded as a unique index field. When importing data, sometimes we want records to be updated instead of being inserted. To find the associated record to update, the Consignor integration will use all “unique index fields” to find the record to be updated.
    Mandatory Fields can be defined as mandatory. This means, that when importing, this field needs to be filled in.

    Export format setup

    The export format is used to defined if the “export dialog” should be presented to the user.

    Field Description
    Worker Name of the worker
    Show dialog Indicates if the “export dialog” should be presented to the user.

    Other menu items

    In the top of the form, there are some more buttons.

    Button Description
    Create a new integration
    Delete an integration
    Shows logged messages
    Manually export data, using a query window
    Import messages by selecting a file, or by selecting a path to fetch all the files from. The import can also be set in batch, and can periodically be executed to import the files.
    To improve performance, the consignor integration does a lot of caching of export/import definition. When changing on an existing integration, the cache should be reset, by clicking on this button.

    Consignor messages

    All consignor import/exports can be logged, so that the exported/imported values is documented. There is a small performance penalty on logging messages.

    Field Description
    Message A unique message ID
    Message type Type of the message
    Processing date Date the message was imported/exported
    Worker Name of the worker that performed the import/export
    Import/Export Import/export type
    Filename Name of the file that has been exported/imported.

    Field values

    In the field values, all the field values are presented.

    Field Description
    Field ID Name of the field. This is used on column name, or in a XML tag.
    Field number The field number that is used
    Field value Value of the field
    Description Description of the field
    Multi line Field value In the bottom there is also a field that shows a multiline version of the value. Fields like addresses is often multiline, and will be correctly represented here.

    I hope to release the tool to CodePlex in the beginning of 2014.

    Happy DAXing J

Turn your Dynamics AX WMS from ‘Where’s My Stuff’ to an actual ‘Warehouse Management System’

Problem 1

“Your receiving area is so packed that you haven’t seen the floor since 1994.”

Ask for Advanced shipping notice (ASN)

With the technology available in Dynamics AX companies have EDI capabilities using the AIF. Sharing container level detail via ASN’s has become common practice. ASN’s can reduce the effort to receive by as much as 70%. It can eliminate the need for detail receiving from trusted vendors. It will simplify labeling, counting and sorting.

Since it is known upfront what is expected, it can also reduce the need for receipt breakdown, with the use of pre-sorted containers and pre-calculated system directed put away path.

Perform receiving sortation

Receiving sortation can improve productivity when receiving breakdown and detail receiving are required. Receipts of partial pallet quantities contain a mix of products that will be stored in different areas can be improved. Products are received in small quantities that don’t justify a trip into the warehouse on their own can be collected and wait until the require quantity if reached.

Receiving sortation involves separating products based on put away area. Master licenses can be constructed for given areas. Put away can be postponed until there are enough items destined for the same area to warrant the travel. System directs operators in the most efficient travel path.

Problem 2

“It takes so long to get product put-away you composed a new song called The Fill Rate Blues

Staying on top of put away tasks

When push comes to pull, put-away is one of the work tasks that takes a back seat to picking, replenishments and loading.

Pulling resources from put-away can have several negative effects like lower fill rates, congestion in the aisles and obstructions to picking that leads to lower productivity.

Managing the put away process

The process becomes manageable by defining the put-away as a process, where you plan, execute and monitor the put-away process.

Plan:

  • Review expected receipts
  • Review current backlog
  • Calculate resource requirements based on standard rates per zone

Execute

  • Assign resources based on plan
  • Consider factors such as:
    • Zone congestion
    • Hot receipt priorities

Monitor

  • How many tasks are outstanding
  • What part of the facility are they destined for
  • How many people are currently doing put away tasks

Then repeat the process!

Problem 3

“Your wave templates have become so numerous and complicated your actively recruiting a rocket scientist from MIT to run the allocation process”

Document and analyze

Document how many waves you run each day for a one week period. Capture reasons why so many waves are needed, and document perceived benefits and negative results.

Analyze your current process and look for ways to:

  • Pre-define and save wave templates
  • Develop a daily schedule that governs
    • Which wave templates to run
    • When to run them
  • Automate the allocation process when it make sense
  • Apply some general rules of thumb

General rules of thumb

One word; KISS (keep it simple stupid). Reduce the number of wave templates used and work to a schedule like “I need to run wave templates at 9:00AM everyday”

Allocate as close to picking as possible. The Dynamics AX WMS has a better picture of inventory at picking time: Pending put away tasks, moves, etc.

Allocate a few large waves vs. many small ones, because when Dynamics AX WMS has a larger group of orders allows optimal work assignment size and allows for better order grouping to optimize pick path.

Problem 4…

“The warehouse is so full you set up an overflow storage area in the lunch room where employees sit at full pallets rather than tables”

Re-warehousing and consolidation

Re-Warehousing is the process of moving goods from one warehouse to another or to a different location within a warehouse. Re-warehousing can be performed in several ways, like based on storage strategies and on picking strategies. Also use Dynamics AX WMS transactions to identify and execute on consolidation opportunities. Then create a set of re-warehousing/transfer moves and schedule them accordingly.

Problem 5…

“Product demand and velocity change so often that you begin using an ouija board to slot product”

Warehouse optimization

Objective is to improve picking productivity by reducing travel time and improving ergonomics for high demand product. WMS supports opportunity based optimization (slotting) through strategy changes and re-slot products through normal picking and storage processes.

As velocity changes so does optimal pick and storage locations. By changing master strategy products can be cleaned out of non-optimal locations as a normal part of picking. Also products can be stored to new optimal location as a normal part of put away.

Storage/put-away examples

High velocity product. Always try to store to prime locations first.

Sequence

Zone/sub zone

Pallet

Carton

Each

1

10 (reserve)

Y

N

N

2

20 (forward)

N

Y

Y

3

30 (forward)

N

Y

Y

4

40 (forward)

N

Y

Y

Low velocity product. Always try to store to non-prime locations first.

Sequence

Zone/sub zone

Pallet

Carton

Each

1

10 (reserve)

Y

N

N

2

40 (forward)

N

Y

Y

3

30 (forward)

N

Y

Y

4

20 (forward)

N

Y

Y

Picking examples

High velocity product. Always try to pick from none-prime locations first and clean stock out of none-prime locations first until there is only stock left in new prime locations.

Sequence

Zone/sub zone

Pallet

Carton

Each

1

10 (reserve)

Y

N

N

2

40 (forward)

N

Y

Y

3

30 (forward)

N

Y

Y

4

20 (forward)

N

Y

Y

Low velocity product. Always try to pick from prime locations first and clean stock out of prime locations first until there is only stock left in new non-prime locations

Sequence

Zone/sub zone

Pallet

Carton

Each

1

10 (reserve)

Y

N

N

2

20 (forward)

N

Y

Y

3

30 (forward)

N

Y

Y

4

40 (forward)

N

Y

Y

Product profiling steps

The saying “A place for everything, and everything in its place” almost sums up the idea behind warehouse slotting and profiling. A more accurate version might be, “An ideal place for everything, and everything in the most efficient place.” Analyze for optimal product placement based on

  • Velocity
  • Demand
  • Bin trips
  • Compare to actual product location.
  • Identify and prioritize opportunities to relocate product.
  • Schedule and execute moves.

Slotting

Balancing picking efficiency and replenishment frequency is an important factor in achieving least-cost labor associated with both activities, while also maintaining adequate inventory in pick slots to attain high customer service levels. Steps to achieve this is to:

Analyze

  • Racking requirements (linear length of racking)
  • Recommended fixture type to SKU (bins vs. pallet flow lanes)
  • Overall productivity rates, replenishment requirements, etc.

Slot

  • Ideal SKU to Location assignment throughout warehouse
  • Precise Location sizing (opening size, capacity) to meet on hand inventory requirements
  • Exact SKU slotting characteristics (# faces, orientation) to maximize utilization of racking space

Maintain

  • Analysis of SKU moves required to improve overall profile
  • Generation of moves to maximize utilization of labor in completing moves

Problem 6…

“Your picking productivity is so low you’re considering benchmarking it as a reverse logistics operation”

Picking productivity

Picking is the most labor intensive time critical operation in the warehouse. Optimizing other operations at the expense of picking costs more in the long run. Manage the flow of picking work to avoid congestion, bottle necks and shipping delays

Improving picking productivity

Ergonomics – take the time to make product pick ready. Develop special storage fixtures when warranted. Orient product to make it easy to pick. Remove excess packaging. Locate heavy or odd shaped product in easy to access locations.

Properly slot product based on Ergonomics and demand/velocity, and develop an ongoing slotting program to analyze and relocate products. Even minimal effort can reap significant benefits.

Validate that you are using the appropriate type of picking. The theme is eliminate non-value added steps. Evaluate pick and pack vs. pick and consolidate. Eliminate packing processes where appropriate. Minimize travel time – keep the pickers in the aisles. Look for ways to pick multiple orders at a time by using batch and bulk picking. And measure, measure, measure!

  • Establish a benchmark
  • Implement adjustments and compare to benchmark
  • Incremental improvements add up over time

Communicate productivity expectations to employees

  • Engineered time standards
  • Standardized work assignments

Give employees feedback on performance and evaluate one on one vs. public. WMS provides all the necessary productivity data. Develop daily work plan and communicate it to the team. Communicate progress throughout the day and remember that co-workers are the best motivators.

Problem 7…

“You handle products so many times in the warehouse you may have to start selling them as used”

Eliminating waste

Map your processes. Flow charts or process flows are proven tools and analyze each step for the value it provides. Eliminate non-value added steps and look for ways to streamline and simplify. “We always did it this way”… doesn’t cut it anymore. Great new ideas get bogged down by exceptions. If you spend more than 10% of the time dealing with an exception then it probably is not an exception.

Focus on incremental approach because silver bullets are rare and small improvements add up over time

Problem 8…

“You are considering purchasing turbo charged fork lifts to help your material handlers get Replenishments done in a timely fashion”

Replenishment do’s and don’ts

Stock one day’s inventory in forward pick locations where possible. If space is short – focus on the highest velocity items. Manage the priorities of replenishment tasks through the WMS, can classify emergency vs. regular. Avoid fit problems and let the WMS release replenishments when they will fit.

Employ the correct replenishment model by zone

  • Real time – when flow is fairly even
  • Allocation based – when spikes in demand are common
  • Scheduled – when there is enough stock in forward to support daily picking demands

Avoid excessive replenishments and set thresholds properly. Don’t streamline replenishments at the expense of picking. The true measure of success is keeping enough stock to support picking with a minimum of effort.

Monitor replenishment activities through the WMS

  • Look for backlogs from zone to zone
  • Identify the number of employees currently assigned
  • Adjust as needed

Problem 9…

“The auditors are so carried away with inventory accuracy they want you to cycle count the contents of vending machines in the lunch room”

Warehouse Manager vs. Auditor

Warehouse Managers and Inventory Auditors have different objectives. Managers want accuracy with minimal effort and auditors want minimal risk of errors. Dynamics AX WMS is very good at maintaining inventory accuracy… Take advantage of that fact! Negotiate with your auditors to reduce the requirements and propose a pilot with verifiable results.

Minimize your effort

Reduce your dependence on cycle counting to correct errors. Look for ways to ensure accuracy on the front end.

  • Simplified processes
  • Procedures that promote accuracy
  • Thorough training
  • Validation, validation, validation
    • Bar Codes
    • Check Digits

Look for incentives to motivate employee accuracy.

Minimize the risk

Standardize your accuracy reporting and track accuracy on a weekly basis. Research and correct root causes like training, problem employees or complicated processes.

Leverage the data available in your Dynamics AX. Establish benchmarks both you and the auditor can live with. Build a solid track record to support future changes.

And the number 10…

Turn your Dynamics AX WMS from ‘Where’s My Stuff’ to an actual ‘Warehouse Management System’

Happy DAX’ing, and with R3 we will be closer.

SYNC for AX 2012 R2 CU7

A few weeks ago, I released the Kitting solution on Codeplex, and WOW!   Now 307 downloads on kitting for AX 2012 R2 CU6.   We also have a lot of people that wants to participate to further develop the kitting.  MSDynamicsWorld.com also created a story on this here. This commitment to the community truly inspires me.

I have therefore uploaded an AX 2012 R2 CU7 release of the kitting, that can be downloaded.

I also have released another small tool for master data synchronization. It’s called SYNC for AX 2012 R2 CU7, and is available on Codeplex here. Check it out.

image

Happy DAX’ing !!

My Dynamics AX preselling tips.

I have done countless pre-sales Dynamics AX presentations, both on-line and in-person in front of a potential customer. I wanted to share some of my thoughts, techniques and topics that works for me. I’m not saying they will work in all settings, but I normally get good feedback.

My first step is to think through the presentation beforehand. I first want to find the story that I want to bring to the audience. I have a passion for power point, but I don’t use a lot of text on them. I try to have pictures, screenshots and bullet points.

image

It is important for me to tell the story, not just read it. So when I do my presentation I’m trying to bring them into my story. I’m trying to explain the WHY and not the HOW. WHY do we have a role center? WHY does the sales order screen look like it does?

And I also do some real demo’s in Dynamics AX, and my favorite list of short 1-2 minutes demo’s are:

Role based navigation and organization hierarchy

clip_image004

Tip : Use the CFO role center. Fantastic graphics and a fun overview.

Create new customer/Create a sales order

clip_image006

Tip : Cleanup the screen upfront, so that only the needed fields show. Use the “hide” function extensively. Sales orders is a very common core function, and we must show how easy it actually is.

Export to Excel

clip_image008

Tip: Show it…. And smile BACK to the audience. They will love this.

Add some of your own flavor.

Most of us have our own small add-ons implemented at our customers. I have the DCS/PDA and label printout.

clip_image010

Advanced – Show supply schedule

clip_image012

Tip: Put some data in. Makes it more fun to look at.

Advanced – Show the BOM designer

clip_image014

Tip: Drag and drop, or just double click to add items to your BOM.

Advanced – Show the action messages graph

clip_image016

Tip : Explain the “apply”, and show it. Tell that it can really save inventory carry cost.

clip_image018

Tip: Run master planning first, to show how action messages affects each order

Advanced – Show the new retail eCommerce sites

clip_image020

clip_image022

Tip: The clean design gives good inspiration. But build down the expectation. A lot of work is needed to bring such a site online for a customer.

Advanced – Show sales/purchase category

clip_image024

Tips: Tree structures are easy to understand.

Advanced – Show resource capacity and reservations

clip_image026

Tips: Add data !

Advanced – Show gantt plan

clip_image028

Funny

Show the two games we have: Tetris and horse race

clip_image030

Have fun and happy DAX’ing.

The warehouse dream

I was mesmerized by this simple but cool Microsoft Surface demo at Convergence conference in Copenhagen 2009.  Lachlan Cash was kind enough to share the video here as a great example of how touch can transform visualization and manipulation of complex line-of-business information. 

From 2m 15s

http://channel9.msdn.com/Blogs/benriga/Using-Touch-in-Line-of-Business-Apps

The demo during Kirill Tatarinov’s keynote session shows top-down heat-map visualization of the bins in a warehouse.  The color-coding gives an immediate view into the status of the warehouse with blue showing cold (i.e. bins with low pick rates) and red showing hot (i.e. bins with high pick rates).  Multi-touch is fully supported on Surface allowing multiple warehouse staff to collaborate while manipulating the data to optimize the warehouse for fast picking.

Very nice vision.

Retail and Supply Chain Trends

One of the most famous principles in retailing is, of course, “retail is detail” — this is where the challenge lies: how do you become more detailed and what detail should you focus on? All retailers know that having products available to customers is one of the most fundamental requirement. Manufacturing, distribution and selling a product can challenge the best organizations. As a retailer’s business drivers change, business processes, SCM technology investment and the overall approach to supply chain management must change and keep pace. An inefficient and poorly functioning supply chain can negatively impact every aspect of a retail organization, jeopardizing the long-term performance and success of a business.

To remain successful companies need organization-wide buy-in to supply chain excellence and some will need to re-evaluate their current processes and performance with these key trends in mind:

• Demand Planning
• Globalization
• Price pressures
• Shorter and complex product life cycles
• Online Collaboration

Companies that reevaluate their business and how the current supply chain structure supports the business-from a strategy, process, technology and organizational perspective-must focus on keeping their supply chain aligned with the overall business strategy.

To succeed, companies must embrace Supply Chain Excellence as a core competency at all levels throughout the company and recognize that supply chain management is executed in many areas, not just the functional supply chain organization.

Dynamics AX works closely with leading retailers and helps them address their business challenges. From our experience working with key companies in food and beverage, consumer products, high tech and industrial manufacturing, there are five key trends causing significant impact and change to retailers performance.

Demand planning

The demand-driven approach helps retailers to create a more customer-focused mindset, without sacrificing operational efficiency. I have often seen that Demand Planning success is often tied to organizational structure. Companies with the right tools and dedicated resources focused around demand planning and forecasting yield stronger results and drive more value to their business. I expect that demand planning will a very important feature to look into when the AX 2012 R3 is released.

Globalization and Supply Chain Management

The business landscape is rapidly becoming more global. Largely due to improvements in communications, globalization is dramatically impacting the way business is managed and transacted, even on the most local levels. No area of a business is affected more by the trend to a global business environment than the supply chain. Manufacturing, distribution, sourcing of materials, invoicing and returns have all been significantly impacted by the increased integration of a global customer and supplier base, and many companies find that existing processes and technology are not flexible enough for this new business environment.

Global competition and price pressures

The internet has changed our shopping habits and will continue to do so. E-commerce websites have opened up the world of “non-geographic” retail — a retail world without the need to visit the physical store. The emergence of “etail” from retail has been the biggest change over the past 20 years. Historically, price, product features and brand recognition were enough to differentiate many products in the marketplace. With the continued commoditization of many products, companies need better ways to distinguish themselves. Product innovation and brand equity is no longer allowing retailers to command a higher price in the market. In order to continue to compete with that commoditized product they made significant cost improvements with supply chain re-design and technology. Retailers are looking to their supply chains in two ways to help offset this trend. First, they are looking at ways to reduce cost and are creating a more efficient value chain to remain cost competitive. Second, retailers are looking at ways they can provide value-added services to meet the demands of more sophisticated customers.

Shortened and more complex product life cycles

As the economy becomes more global, labeling and compliance to packaging requirements and regulations have become critical to success. Without adherence to local packaging and labeling regulations a product may violate local requirements, preventing it from being distributed and sold in that market. Product lifecycle management technology and processes can help ensure that products being produced and targeted for specific markets are well-managed and are compliant. Product lifecycle management processes have helped retailers with their efforts to try to continually drive demand through packaging and labeling innovation and design. Implementation of an optimal PLM process and technology can allow retailers to effectively produce and distribute products that are only targeted for regional promotions or consumer preferences.

Integration and collaboration with customers and suppliers

As supply chains continue to develop and mature, a move toward more intense collaboration between customers and suppliers has occurred. The level of collaboration goes beyond linking information systems to fully integrating business processes and organization structures across companies that comprise the full value chain. The ultimate goal of collaboration is to increase visibility throughout the value chain in an effort to make better management decisions and to ultimately decrease value chain costs. With the right tools, processes and organizational structure in place, collaboration provides key people throughout the value chain with the information needed to make business-critical decisions with the best available information. As retailers are increasingly using their supply chain to compete and gain market share, spending and activity in this area are notably on the upswing. Technology and process upgrades at forward-thinking companies clearly show that supply chain excellence is more widely accepted as an element of overall business strategy and that increasing value to customers is not just management’s, but everyone’s business.

Technology supporting these trends

As supply chain networks have become more complex, the need for greater and improved solutions has become critical. The Dynamics ecosystem have done significant investments in developing solutions and verticals to address the needs of retail and distribution companies in areas, such as:

• Transportation and Inventory Optimization
• Logistics and replenishment Optimization
• Product Lifecycle Management and labeling
• Handheld solutions
• Sales and Operations Planning
• Procurement
• Manufacturing Optimization
• Business Intelligence
• eCommerce
• Collaboration platforms

These technologies have helped enable the retail and supply chain “information worker” innovate, drive cost reductions, improve service and meet customer expectations better than ever. In order to have sustainable improvement in retail and supply chain performance, the Dynamics ecosystem must find the right balance of investments in organization, processes and technology. Lack of investment and focus in these areas will reduce the ability to achieve fundamental, sustainable improvements.

Microsoft Acquires WAX/TRAX

Yesterday, one of the most public secrets was officially announced.

Microsoft (MSFT) Acquires Blue Horseshos’ WAX, TRAX Solutions

It will be interesting to see how this will evolve, and we welcome more focus on WMS and logistics.  When more information becomes public, I will keep you up to date on what to expect and how this solution will fit different segments requirements. The release date is expected at the end of this year, and will at the first version be a optional feature pack located in a separate layer.

Show if data is synchronized

The post is related to the masterdata synchronization.

I wanted to give end-users an explanation why they cannot change some of the fields in a synchronized records.  I  decided to create a generic way of alerting the end-user, like you see in the screenshot below, and also to lock any fields that is synchronized.

image

So if a record is originating from another master-company, then the following yellow text will be visible. Doing this on a single form is surely easy, but I wanted to create a generic solution that has Zero footprint, and NOT making any changes to any standard form. 

Can it be done ?  Yes 🙂

So what I did, was to create a event handler on the info.formNotify():

image

Then the code looks like this (the code contains some ColSync* references, but you see the idea:

public static void colSyncEnableFields(XppPrePostArgs _args)
{
    FormRun                 formRun;
    FormDesign              formDesign;
    FormNotify              event;
    FormNotifyEventArgs     eventArgs;
    ColSyncCache            colSyncCache;
    Common                  common;
    ColSyncLine             colSyncLine;
    ColSyncTable            colSyncTable;
    ColSyncDefinition       colSyncDefinition;
    ColSyncDestinations     colSyncDestinations;
    FormGroupControl        actionBarGroup;
    FormActionPaneControl   actionPane;
    FormGroupControl        firstGroup;
    int                     defaultBackgroundColor;
    FormStaticTextControl   actionBarMessageText;
    int                     i;

    #define.SyncActionBarGroup('SyncActionBarGroup')
    #define.SyncActionBarMessageText('SyncBarMessageText')

    event     = _args.getArg('event');
    eventArgs = _args.getArg('eventArgs');

    switch (event)
    {
        case FormNotify::RecordChange:
            if ((eventArgs != null) &&
                (eventArgs.formDataSource()))
            {
                formRun   = _args.getArg('formRun');
                colSyncCache = ColSyncCache::construct();
                common = eventArgs.formDataSource().getFirst(true) ? eventArgs.formDataSource().getFirst(true) : eventArgs.formDataSource().cursor();
                if (common.RecId &&
                    colSyncCache.isSyncEnabledDestination(common))
                {
                    formDesign = formrun.design();
                    for (i=1; i<=formDesign.controlCount(); i++)
                    {
                        if ((formDesign.controlNum(i).handle() == classNum(FormActionPaneControl)))
                        {
                            actionPane = formDesign.controlNum(i);
                            break;
                        }
                    }
                    formRun.lock();

                    if (actionPane != null)
                    {
                        for (i=1; i<=formDesign.controlCount(); i++)
                        {
                            if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl) &&
                                 formDesign.controlNum(i).name() == #SyncActionBarGroup ))
                            {
                                actionBarGroup = formDesign.controlNum(i);
                                break;
                            }
                        }

                        if (!actionBarGroup)
                            actionBarGroup = formDesign.addControl(FormControlType::Group, #SyncActionBarGroup, actionPane);
                    }
                    // add directly to top of form design
                    else
                    {
                        for (i=1; i<=formDesign.controlCount(); i++)
                        {
                            if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl) &&
                                 formDesign.controlNum(i).name() == #SyncActionBarGroup ))
                            {
                                actionBarGroup = formDesign.controlNum(i);
                                break;
                            }
                        }

                        if (!actionBarGroup)
                        {
                            // find the first group control on form (if one exists)
                            for (i=1; i<=formDesign.controlCount(); i++)
                            {
                                if ((formDesign.controlNum(i).handle() == classNum(FormGroupControl)))
                                {
                                    firstGroup = formDesign.controlNum(i);
                                    break;
                                }
                            }
                            if(firstGroup)
                            {
                                actionBarGroup = firstGroup.addControl(FormControlType::Group, #SyncActionBarGroup);
                                actionBarGroup.top(FormTop::Auto);
                            }
                            else
                            {
                                actionBarGroup = formDesign.addControl(FormControlType::Group,#SyncActionBarGroup);
                                actionBarGroup.top(1, FormTop::Auto);
                            }
                        }
                    }

                    defaultBackgroundColor = formDesign.backgroundColor();
                    actionBarGroup.frameType(FormFrameType::None);
                    actionBarGroup.height(27);
                    actionBarGroup.hideIfEmpty(false);
                    actionBarGroup.topMargin(1);
                    actionBarGroup.bottomMargin(1);
                    actionBarGroup.widthMode(FormWidth::ColumnWidth);
                    actionBarGroup.colorScheme(FormColorScheme::RGB);
                    actionBarGroup.verticalSpacingValue(0);
                    if (System.Windows.SystemParameters::get_HighContrast())
                    {
                        actionBarGroup.colorScheme(FormColorScheme::WindowsPalette);
                        actionBarGroup.backgroundColor(WindowsPalette::TooltipBackground);
                    }
                    else
                    {
                        actionBarGroup.colorScheme(FormColorScheme::RGB);
                        actionBarGroup.backgroundColor(WinAPI::RGB2int(255,255,153));
                    }
                    // don't reserve space for details forms
                    if (formDesign.style() == FormStyle::DetailsFormMaster || formDesign.style() == FormStyle::DetailsFormTransaction)
                    {
                        actionBarGroup.visible(false);
                    }

                    for (i=1; i<=actionBarGroup.controlCount(); i++)
                    {
                        if ((actionBarGroup.controlNum(i).handle() == classNum(FormStaticTextControl)))
                        {
                            actionBarMessageText = actionBarGroup.controlNum(i);
                            if (actionBarMessageText && actionBarMessageText.name() == #SyncActionBarMessageText)
                                break;
                        }
                    }

                    if (!actionBarMessageText)
                    {
                        actionBarMessageText = actionBarGroup.addControl(FormControlType::StaticText, #SyncActionBarMessageText, actionBarGroup);
                    }
                    actionBarMessageText.backStyle(FormBackStyle::Opaque);
                    actionBarMessageText.colorScheme(FormColorScheme::RGB);
                    actionBarMessageText.backgroundColor(WinAPI::RGB2int(255,255,153));
                    actionBarMessageText.widthMode(FormWidth::ColumnWidth);
                    actionBarMessageText.text(strFmt("@SYN112"));
                    actionBarMessageText.visible(true);
                    formRun.unLock();

                    while select  SyncFieldId from  colSyncLine group by SyncFieldId
                            where   colSyncLine.SyncTableId == eventArgs.formDataSource().table()
                                &&  colSyncLine.SyncType == ColSyncType::SynchronizeField
                        exists join colSyncTable
                            where   colSyncTable.SyncId == colSyncLine.SyncId
                                &&  colSyncTable.SyncTableId == colSyncLine.SyncTableId
                                &&  colSyncTable.SyncActive == NoYes::Yes
                        exists join colSyncDefinition
                            where   colSyncDefinition.SyncId == colSyncLine.SyncId
                                &&  colSyncDefinition.SyncActive == NoYes::Yes
                        exists join colSyncDestinations
                            where   colSyncDestinations.SyncId == colSyncLine.SyncId
                                &&  colSyncDestinations.ToDataAreaId == common.dataAreaId
                                &&  colSyncDestinations.LockSyncFields == true
                    {
                        eventArgs.formDataSource().object(colSyncLine.SyncFieldId).allowEdit(false);
                    }
                    eventArgs.formDataSource().allowCreate(false);
                    eventArgs.formDataSource().allowDelete(false);
                }
                else if (common.RecId &&
                         colSyncCache.isGlobalTableEnabled(common))
                {
                    eventArgs.formDataSource().allowCreate(false);
                    eventArgs.formDataSource().allowEdit(false);
                    eventArgs.formDataSource().allowDelete(false);
                }
            }
        break;
    }
}

Enable database logging on groups and parameters

First I would say that I do NOT recommend to enable any database logging, unless it is business important for you, and you need to have a track of parameter changes.

But in some cases customers demand to have database logging.  I agreed and explained that it will have performance consequences, but we could do it on parameters and groups.

But I’m a type of guy that likes to create scripts to enable things.  So I wanted to share with you a small script that enables database logging on all groups and parameters.

(This script is for AX2009)

static void KHA_AddDatabaseLogging(Args _args)
{
    #AOT Name name;

    TreeNode treeNode;
    SysDictTable sysDictTable;
    DatabaseLog  DatabaseLog;
    ;
    treeNode = TreeNode::findNode(#TablesPath);
    treeNode = treeNode.AOTfirstChild();
    while (treeNode)
    {
        name = treeNode.AOTname();
        sysDictTable = SysDictTable::newTableId(treeNode.applObjectId());

        if ((sysDictTable.tableGroup() == tableGroup::Parameter ||
             sysDictTable.tableGroup() == tableGroup::Group) &&
             !sysDictTable.isMap() &&
             !sysDictTable.isTmp() &&
             !sysDictTable.isView() &&
             sysDictTable.enabled())
        {
            select firstonly DatabaseLog where DatabaseLog.logTable == sysDictTable.id();
            
            if (!DatabaseLog)
            {
                DatabaseLog.domainId = "Admin";
                DatabaseLog.logType  = DatabaseLogType::Update;
                DatabaseLog.logTable = sysDictTable.id();
                DatabaseLog.logField = 0;
                DatabaseLog.insert();
            }
            info(strfmt("Databaselogging enabled on %1",sysDictTable.name()));
        }
        treeNode = treeNode.AOTnextSibling();
    }
}

Master data synchronization using ColumbusSync

I wanted to share a nice tool I’m working on for Dynamics AX 2012.  It is called ColumbusSync, and solves some requirements we often see at larger enterprises.  The ability to quick and easy distribute master data from a master company to a set of “client” companies.  In this way a large set of companies can act as a single enterprise, even though it actually are a set of unique companies.   

image

What makes this tool great, it that is generic and uses all known relations defined in Dynamics AX 2012.  This means that if you want to synchronize your customers, then all other tables that have a dependency will also be suggested to be included in the synchronization. RecID related relations are also handled. Transactions(like sales orders, inventory transactions etc) are not supported to be included in this tool, and it will not work across partitions.

On each field you can define if the field should de synchronized, is a local field, is a fixed field or a script is associated to the field.  So parts of a record can be locally controlled and parts are synchronized.

You can also define a query criteria, so that set up that only a sub-set of the records should be synchronized to a set of destination companies.

The amount of data that could be included in the synchronization could surely be massive, so there is a set of optimizations that makes use of the Dynamics AX multithreading batch framework.  Just like the master planning in Dynamics AX,  splitting the synchronization into sub-jobs, that is executed the the correct sequence.  (Meaning that groups are typically synchronized before main table records)

The RecVersion field is also used find exactly those records that should be synchronized.  To also support “close-to-real-time” synchronization the current changed/added record can be collected just like the standard AX 2012 database log.

The tool is not ready for shipping yet, but I know that many companies has requested this.  It will also solve a requirement I have seen in the community a lot.  The ability to quickly create a new client company.  The idea is that you may just run the data synchronization to a destination company. 

Visit the blog later, and I’ll share some more details of the tool.

Take care, and happy DAXing.

Changing the query for an existing CUE

In AX 2009 we could change the query behind a personalized CUE.  This seams to have been removed from AX 2012.

image

But we that can develop, still have a chance, using X++.

Run the following job script, and you will get the query up, so that you can change the query.

image

This will bring up the normal query form, where you can make your changes, and then press OK to save the new query in you Cue.

image

 

Take care and happy Daxing.

Can Dynamics AX 2012 talk ?

I was playing around on some with some of the classes, and I found a  small thing that I wanted to share with the community.  How to enable the speech synthesizer in Dynamics AX 2012.  (This is the core essence of the “virtual burger” demo)

Here is the code that makes Dynamics AX speak:

image

You also need to add the System.Speech to the references in AX:

image

Making Dynamics AX 2012 talk in a demo is great, but the functional value is normally low.

Happy Daxing Smilefjes

How to be rich on your Dynamics AX add-ons

First I need to say I’m sorry for the trick headlines. This quick answer is that it is very unlikely to get rich on money by developing Dynamics AX add-ons, and especially if you try to this alone. However, what you will be is much richer in experience and I guarantee you will have fun. Also a warning; if you are not internally motivated to share and learn more, than do not go down this path.

I wanted to share with you some own experience in how to create, promote and sell your great ideas.

Step 1 is the idea, and step 2 is to have a either a rich uncle, nice employer or a customer that believes in your idea. It is more difficult if you are missing on step 1 or 2, and you could risk going home hungry.

image

Step 3 is product quality and development, and this is very well discussed and described in other blogs and from Microsoft, and I will not go down there now. One important tip here is to be clear about what versions of Dynamics AX you do support.

Step 4 is documentation. When I develop Dynamics AX Add-ons/modules, I spend a lot of time documenting with the end-user in mind. The documents I create for each add-on are; brochure, installation manual, user manual, step-by-step guide, training presentation, and a sales presentation. Do it in English!

image

Step 5 is about promoting your solution, and this may be the most important part. Marketing can be very expensive. A blog (like this) is much cheaper. You may need to share more than you want to attract readers (also called potential customers). You need to write about what you are doing, how you are doing it, and why it is important. Share from your documentation. Show your genuine interest in your particular subject, and what it’s capable to do. If you can share ideas and code snippets, do so. Don’t be afraid of that some may steal your code or idea. The true value is your expertise, and the ability to have a continued focus. You will probably not be rich on the product anyway, and BING/GOOGLE will figure out that what you write have value for readers. Many of the customers that have purchased my solutions have found the solution here on this blog, and then contacted me. Also try to promote your product internally among colleges and friends.

image

Step 6 is about making your product commercial. Then you need a pricelist. One tip, is to price it so low, that other partners/developers cannot make the same features as customizations at the same price. High price = no customers. Low price = some customers. You probably also need to create a partner model, so that partners that brings customers to you can make money on it. Also, if you want to continue to improve and further develop your product, try to sell your product with yearly enhancement fees.

Step 7 is to show and demo the product. In most cases this will be Microsoft Partners, that first “scans” the marketplace according to what a potential or existing customer needs. You will therefore need tools to do this, like Lync, GotoMeeting or any other meeting tools. If your product is great, try to demo it as often as possible, to as many as possible. They need to see that it’s actually working and are living up to the expectations explained in your blog.

 image

Step 8 let your customers/partners try the product. “Try before you buy” is popular, because all have experiences to purchase things/software that does not live up to the expectations. But since your idea and product is great, be prepare to let them try it. You should also probably create a NDA (Non-Disclosure Agreement), that the customer needs to sign before you hand over all you have for trial. Let you customers try the software in the way they want, and therefore you should make the installation (XPO or AX-models) available. In many cases, customers prefer to have a Hyper-V or VMWARE image downloaded, since it will contain both solution and data ready to try.

Step 9 is to make sure the product, documentation and support capabilities are available. Use the a WEB-page where the customers must log in. I prefer a SharePoint site, where I make all installation, documentation AND support available. As long as the customer is on an enhancement plan, they have access to what they need. I also let partners and customers on NDA have read only access to this SharePoint site. Also remember to remove users from the SharePoint site, where you see/understand that they will not purchase. Tell them that they can continue to read more on the blogSmilefjes

Step 10 is to sell your product. You should then have a SLA (Software License Agreement), that make sure that you and the customer is protected. Also create a document called “How to purchase”, where you describe how customers and partners should go forward. After the product is delivered, then you invoice it.

Step 11 is to be proud, and remember that you don’t do this to get rich. You do it, because on this journey you are learning a lot, and you are creating solutions that customers benefit’s from. You will also increase your own value and public recognition on the path.

  image

Also remember that there are always winners in the lottery.  One time it could be youSmilefjes

Receipt status arrived: The forgotten jewel

There are two ways to learn how Dynamics AX is working. Users can do courses, read manuals, self-training, “try and fail”, blogs etc. Professionals can also read code. Each time Microsoft is releasing a new version I try to read the code for better understanding new features and possibilities.

I then often find traces of functionality that exists, but that Microsoft never took the “last mile” and created the front-end functionality. This code is often made by the best developers in the industry. And it is open and free to use for partners and customers.

One of these hidden jewels are the status arrived.

To explain what this is, we need to understand how the real physical logistics flow is translated and viewed in Dynamics AX.

image

Dynamics AX tries to mirror this processes with transactions, and reflect each status as both transactions and as inventory statuses. Take a look at the following Dynamics AX On-hand screen.

image

What I suggest, is that they should start using the Arrived status more. Because it can give some very important information. When an order processor (like Susan) take a look at the current on-hand, because she have a customer on the phone, she can see that the items has arrived, and it is probably just a few hours before the items are available in stock, and ready to be picked.

It also tells the warehouse manager how much goods has arrived to the warehouse, and how he should prioritize his workforce to do quality control and put-away.

It answers one of the most basic logistics questions: Has the items arrived yet?

You may now ask the question: Why have we not heard about this, and why isn’t we using this more?

There is a catch. In order to use the Arrived status, you need to use pallets, and pallet transports. Microsoft is describing the process in this blog. But it is actually quite few that uses pallets in their warehouses. Most SMB companies have warehouses, but just places the goods in cartons into the warehouse.

In the following section I would like to tell you how to go around this, so that you actually can use the arrived status without using pallets. It is just a small modification needed, and it will make sure that the “forgotten jewel” again can shine.

We do this, by making some small changes to how the arrival journal is working. When the user adds a record in the arrival journal we want the inventory transactions to reflect this.

image

This will be reflected in the on-hand screen as been before.

Here is how I made this possible.

Warning ! The following section is for developers only J, and are created for Dynamics AX 2012 R2.

1.First I need a function for summing up arrived transactions.

image

2.Create some static methods that controls the arrived status based on WMSJournalTrans.

image

image

image

3.Create event handlers on insert, update and delete methods on the table WMSJournalTrans.

image

image

4.A small correction to std. AX is also needed, so that arrived transactions can be seen from the arrival overview.

image

This concludes the adjustment to make status arrived work for companies that don’t do pallets.

Take care, and happy daxing.

How to use dynamic date ranges in RoleCenter Cue’s

In Dynamics AX 2012 (and 2009) we have the possibility to add Cue’s to the role center.

image

However, sometimes we would like to have Cue’s that reflect a dynamic time dimension. This is like: Orders today, Orders yesterday etc.

What we then can do is to use query values as today(), day(-1), LessThanDate(), RateRage() etc.

Like in the following example fetching sales order lines created today. Here I use the greaterThanDate(-1). Pay attention to the extra parentheses to make it work.

image

In AX 2012 you will find many such «dynamic» data query values, and you can find them in the class SysQueryRangeUtil.

image

Then here is the developers trick: Create your own methods to get the query range you need.

I have created my self some nice methods for getting a query rage for ThisWeek() and PrevWeek()

image

image

Or here is a way if you have a CreateDateTime field, like, and want all orders created today:

image

So now it is easy to create Role center cues with data like:

– Number of Sales order with value so far today/yesterday/this week/this month etc

Try it, and happy Daxing

PDA tools for retail stores

I have several customers with retail stores.  So I wanted to create some PDA applications that can be used in the stores, that focuses on supply chain.  It actually turned out to be a small module in the PDA solution.

image

The retail menu is optimized for scenario’s where a central distribution center is doing automatic replenishment using transfer orders of the stores, and the stores are within the same company as the central distribution center.

In scenarios where the stores is buying directly from vendors, or intercompany transactions is used, then the purchase and arrival menus can be used.

Create transfer order

The create transfer order is all about creating transfer orders from a central distribution warehouse or from other stores/warehouses. The screen is very easy-to-use, and focuses on the core process.

image

To warehouse: This is the destination warehouse (or store), and is normally auto filled based on the current user.

From warehouse: This is the Source warehouse (or store), and is normally auto filled based what is the main central warehouse.

Barcode: Accepts item barcodes or EAN128 codes.
The magnifier button will open the items details for this item/barcode.

Quantity: Accepts Quantity or quantity from item barcodes or GS1-128/EAN128 codes. The field on the left show how many units are already ordered, and (hopefully) on it way. Before ordering, check this field to prevent double ordering.

The buttons in the bottom will be either add or create, depending on of there already exists an open and untouched transfer order.

Create/Pick transfer order

The create/pick transfer order is an optimization of the create transfer order. But this process will also physically pick the items while you are creating the transfer. This form is particularly useful if you want to create a transfer order based on physical items you have in the store or at the central warehouse. One of this processes is the end-of-season distribution. Returning items to central warehouse, or sending items to other stores.

image

To warehouse: This is the destination warehouse (or store), and is normally auto filled based on the current user.

From warehouse: This is the Source warehouse (or store), and is normally auto filled based what is the main central warehouse.

Barcode: Accepts item barcodes or EAN128 codes. The magnifier button will open the items details for this item/barcode.

Location: Scan the location where the lines is being picked from.

Quantity: Accepts Quantity or quantity from item barcodes or GS1-128/EAN128 codes.

The buttons in the bottom will be either add or create, depending on of there already exists an open and untouched transfer order.

1.3. Add transfer lines

If you already have a transfer order, and just wants to add lines to a specific transfer order, then use this function.

image

This form behaves just like the two previous, but here the user can specifically select the transfer order. The lookup button will only show already open transfer orders that fill the criteria of “To”-, and “From”- warehouse.

1.4. Inquire item barcode

For retailers it is important to quickly get information that is different then what a warehouse worker needs.

image

The sales price presented here is the price including VAT. So this is the price that the customer will get in the POS.

The minimum, is the minimum on-hand, and is used for replenishment. Adjusting this can automatically create transfer orders through the master planning. The magnifier button will show a lot of information on the scanned item. This is KPI that normally is used to set the minimum level of an item at the store. Here is an explanation of the KPI’s/statistics.

Last sales date : The last date there was a sale on this item/barcode from this store/warehouse.

Sales this/last week/month : Calculates some sales statistics on the item barcode from this store/warehouse.

Sales value on-hand : Current physical on-hand * sales price inclusive VAT.

Turnover this/last year : Calculates the turnover ratio for this item in this store/warehouse. The logics for creating this is the same as in standard AX.

Lead time : Getting the lead-time of the item. The logics is the same as standard AX is using in master planning.

Multiple : Show the multiple quantity parameter as defined on the item.

Recommended minimum : This parameter give a minimum advice. The logics is the same as how standard AX is calculating safety journals, but it is rounded up to the nearest multiple quantity.

As shown in the figure, the Print-button will print retail shelf labels, and these can be setup as wanted in the Columbus BarTender integration.

Count

Counting program for stores is very much the same as counting in a warehouse.

image

Inquire location

This program is the same as found in the warehouse menu.

image

AX2012–GS1-128–delivery labels

My BarTender integration and PDA solution now supports full GS1-128 labels and application identifiers.

image

Pick, ship and send directly from a PDA. 

Now also available with a overview screen of shipped SSCC :

image

And use the Microsoft Bing to visualize the Transport route by a single click:

image

You can even try it out your self, by clicking here.

Take care, and happy Daxing