Wednesday, May 22, 2013

.NET Wonders in Microsoft Dynamics AX Retail Development: Creating a custom fields for Receipts in AX Retail...

.NET Wonders in Microsoft Dynamics AX Retail Development: Creating a custom fields for Receipts in AX Retail...: http://community.dynamics.com/ax/b/axsupport/archive/2013/02/16/ax-for-retail-2012-r2-working-with-custom-fields-for-receipts.aspx#.UXkVZ7V...

.NET Wonders in Microsoft Dynamics AX Retail Development: Customizing the New Customer form in Retail POS.

.NET Wonders in Microsoft Dynamics AX Retail Development: Customizing the New Customer form in Retail POS.:         Well, Modifying the UI of POS form is bit difficult, it is easy if you follow the steps which i have published. First, Selec...

.NET Wonders in Microsoft Dynamics AX Retail Development: Adding a Button to AX Retail POS Application

.NET Wonders in Microsoft Dynamics AX Retail Development: Adding a Button to AX Retail POS Application: Dynamics AX for Retail  is a retail software that integrates point of sale (POS), retail store management, and ERP all in one solution. I a...

.NET Wonders in Microsoft Dynamics AX Retail Development: Adding a Button to AX Retail POS Application

.NET Wonders in Microsoft Dynamics AX Retail Development: Adding a Button to AX Retail POS Application: Dynamics AX for Retail  is a retail software that integrates point of sale (POS), retail store management, and ERP all in one solution. I a...

Tuesday, May 14, 2013

Adding a Button to AX Retail POS Application

Dynamics AX for Retail is a retail software that integrates point of sale (POS), retail store management, and ERP all in one solution. I am assuming you all understand how it works (atleast from functional point of view). It's implementation includes four separate applications.

1) Dynamics AX for Retail Headquarters is managed and implemented in AX. It is designed to run at the head office. It has three modules in AX.
  • Retail Headquarters module is used to configure and manage stores, terminals, staff, retail items, promotions, gift cards, retail sales transactions and other records.
  • Retail Scheduler module is used to synchronize data between head office (AX) and stores / terminals.
  • Retail Store Inventory is used to send store inventory documents to stores to use for receiving inventory for a purchase order, picking or receiving inventory for a transfer order, or counting stock for a count order.
2) Dynamics AX for Retail POS is a .Net touch screen application having its own local database to work offline during network interruptions. This can be fully customized for any type of business and store procedures. This is what we are going to cover in this article.

3) Dynamics AX for Retail Store Connect is a windows service that sends data between the head office, stores and individual POS terminals.

4) Dynamics AX for Retail Transaction Service is again a windows service that is also a part of communication mechanism of Dynamics AX for Retail. For example; this service is used to authenticate the cashier logon credentials etc.

Customize Retail POS: After going through this article you should be able to modify or extend existing POS functionality.

In order to customize the POS, you need to download the Microsoft Dynamics AX for Retail POS Plug-ins. These plug-ins are available on Microsoft Dynamics PartnerSource or CustomerSource website.

Plug-ins folder structure.

When you download plug-ins you will get C# source code for services and triggers as well as the required documentation. Download also comes with a some .Net tutorials and a developer's guide to customization.

Services: Services are actually .Net assemblies. POS implements many of the features as services using interfaces and can be modified using Visual Studio 2008. POS loads these services at run time by calling the interfaces. So whenever you modify or extend the standard service keep the assembly name same as original so that POS can recognize it and call it at run time.

Each service provides a specific feature in POS. There is a special service called Blank service. This service can be used to implement custom operations and can be invoked using the Blank operation.

NOTE: You can modify or develop new business logic or new touch screen forms when talking about customizing the POS. Logic is written in C# and should not be a big thing for a C# developer. In order to create touch screens Microsoft uses third party controls from DevExpress. You need buys a license of a specific version (9.2.109.0) of DXperience WinForms for Retail April Refresh R2.

Triggers: Triggers are called before and after the operations. There are two types of triggers, Pre-triggers and Post-triggers. Pre-triggers provide a way of validation before a certain operation is executed. Post-triggers are used to respond to an operation after it has finished. You can modify the triggers same way as services. 




Steps to follow are:
1. Create a OperationID:- Click a Operation in AX->Retail Headquarters-> Setup-> Operations , Clcik new in Left Top Most and give a Unique id and Operation Name. Note the Operation Id

2. Add a Button


AX->Retail Headquarters-> Setup-> Button Grid.

Click on Button Grid.

Select the Button Grid ID you want to add, then click on designer. 



Right click to select button  Properties.



Give the Operation id in Operation Number and Give a Blank Operation Param.

3. Run the Jobs

Ax-> Retail-> Periodic -> Retail Schedular-> Distribution Schedule.

Run all the jobs of A-1090 and N-1090.

4. Modify the code in .NET

Then go to BlankOperations Project in .NET Source. Open BlankOperations.cs and locate BlankOperation Method and write the following code:-


 switch (operationInfo.OperationId)
            {
                case "1220":                        //Operation ID
                    //Your Own Code
                    MessageBox.Show("Your Own code");
                    break;
            }



Thursday, May 2, 2013

Customizing the New Customer form in Retail POS.


        Well, Modifying the UI of POS form is bit difficult, it is easy if you follow the steps which i have published.

First, Select the main table layout from the form. click on right top most arrow icon 



Next, Click on Edit Rows and Columns and increase the row size to 800-1000 so that you can add new rows. and note that you have to set to autosize after adding the controls to the rows. Add required new rows, set the row to Absolute as 30 size. and drag required controls into the form and set Cell property of that control to the required row. and after your modification done set the contols and  tablelayoutpanel from Absolute size to Auto Size.

    I have dragged some controls into customer form and that looks like ,



After that create some new fields in AX Database and POS database.

Notice that, According to my research we cannot update the Microsoft.Dynamics.Retail.Pos.Contracts.dll to get the newly created fields to call in our code. To insert the record with new fields we need to get the Customerid and write the update method in AX and call that in .NET. Here am Updating the three checkboxes in Primary and two checkboxes in OptIn

To get the customer ID we need write a int in SaveCustomer() method

int custid = Customer.CustomerId


and in AX, create a method in RetailTransactionServiceEx as CustomerUpdate and write the code as following


public static container CustomerUpdate(AccountNum party,Boolean storeEvent, Boolean newsLetter, Boolean phone, Boolean email, Boolean url)
{
    CustTable custTable;
    container result = [false, ''];
    DirPartyLocation    locationPhone, locationEmail, locationURL;
    LogisticsElectronicAddress  logisticsElectronicAddress;
    boolean         updated = false;

    if (party)
    {
        ttsBegin;
       select forupdate custTable where custTable.AccountNum == party;
        if (custTable)
        {
            custTable.DVFOptInInStoreEvent = storeEvent;
            custTable.DVFOptInNewsletter   = newsLetter;
            custTable.update();

            select forupdate locationPhone where locationPhone.Party ==  custtable.Party                                  join logisticsElectronicAddress
                where logisticsElectronicAddress.Location == locationPhone.Location
                   && logisticsElectronicAddress.Type ==              LogisticsElectronicAddressMethodType::Phone;
            if(locationPhone)
            {
                 locationPhone.IsPrimary = phone;              locationPhone.validTimeStateUpdateMode(ValidTimeStateUpdate::CreateNewTimePeriod);
                locationPhone.update();
            }
            select forupdate locationEmail
                where locationEmail.Party ==  custtable.Party
            join logisticsElectronicAddress
                where logisticsElectronicAddress.Location == locationEmail.Location
                   && logisticsElectronicAddress.Type ==            LogisticsElectronicAddressMethodType::Email;
            if(locationEmail)
            {
                locationEmail.IsPrimary = email;
                locationEmail.validTimeStateUpdateMode(ValidTimeStateUpdate::CreateNewTimePeriod);
                locationEmail.update();
            }

            select forupdate locationURL
                where locationURL.Party ==  custtable.Party
            join logisticsElectronicAddress
                where logisticsElectronicAddress.Location == locationURL.Location
                   && logisticsElectronicAddress.Type == LogisticsElectronicAddressMethodType::URL;
            if(locationURL)
            {
                locationURL.IsPrimary = url;
                locationURL.validTimeStateUpdateMode(ValidTimeStateUpdate::CreateNewTimePeriod);
                locationURL.update();
            }
        ttsCommit;
            result = [true, 'Success!', custTable.name()];
        }
        else
        {
            updated = true;
            result = [false, 'Customer not found'];
        }
    }
    else
    {
        updated = true;
        result = [false, 'accountNumber is null.'];
    }
    if(updated)
    {
        ttsBegin;
        custTable.delete();
        ttsCommit;
    }

    return result;
}


and to call this method in AX. 

Pos.Customer.Customer.InternalApplication.TransactionServices.InvokeExtension("cgsCustomerUpdate", AccNo, storeEvent, newsLetter, primaryPhnNum, primaryEmail, primarySite);


the created Method is: 



public void CgsUpdateCustomer(string AccNo, bool storeEvent, bool newsLetter,bool primaryPhnNum, bool primaryEmail, bool primarySite)
        {
            try
            {
                var response = Pos.Customer.Customer.InternalApplication.TransactionServices.InvokeExtension("cgsCustomerUpdate", AccNo, storeEvent, newsLetter, primaryPhnNum, primaryEmail, primarySite);
            }

            catch (Exception ex)
            {
                LSRetailPosis.ApplicationExceptionHandler.HandleException(this.ToString(), ex);
                Pos.Customer.Customer.InternalApplication.Services.Dialog.ShowMessage(Convert.ToInt32("Unable to create the customer"), MessageBoxButtons.OK);
            }
        }


 and call this method in SaveCustomer() method

CgsUpdateCustomer(Customer.CustomerId, storeevent, newsletter, PhnChk, Emailchk, Sitechk);


To get the storevent,newsletter,PhnChk etc....

bool storevent = false;
if(chkStoreEvent.checked == true)
{
bool storevent = true;
}


etc....


Then generate a dll of Customer Class Library and paste the dll in C:\Program Files\Microsoft Dynamics AX\60\Retail POS\Services and run the POS Application.