Monday, 1 October 2018

Custom service to import product master using WCF service AX 2012.

In this article, we will see how to import a product into Dynamics AX 2012 using WCF custom service. Use this approach only you need to extream customization otherwise, we can use the standard DIXF Product master for details you can check below link.

 "How to import items master data using Data Migration Framework"


Coming to Custom service to import product master. 

1. We need to create a service class which extends SysOperationServiceBase
class MK_ItemMasterService extends SysOperationServiceBase
{
}

2. Add Entry point method which takes contract class as parameter. 

[SysEntryPointAttribute(true)]
public ItemId createProduct(MK_ItemImportContract _itemImport)
{
      InventTable            inventTable,ret;
    try
    {
        ttsBegin;
        inventTable = InventTable::find(_itemImport.parmProductNumber(),true);
        if (inventTable.RecId)
        {
            //update product
            this.update(_itemImport,inventTable);
        }
        else
        {
            //create new product
            ret = this.create(_itemImport);
        }// end of else
        ttsCommit;
    }
    catch
    {
        return "";
    }

    return ret.itemid;

}

3. Now we can create a Data contract class as below.

[DataContractAttribute]
public class MK_ItemImportContract
{
    Str DisplayProductNumber; // = "Bulb60W1",
    //ProductType = AxdEnum_EcoResProductType.Item,
    str SearchName;// = "Bulb60W1"
    str Name;
    str ProductNumber;
    str StorageDimGroup;
    str ProductDimGroup;
    str TrackingDimGroup;
}

4. Add Data member attribute method for all the variables declared in the class like below.

[DataMemberAttribute]
public str parmStorageDimGroup(Str _StorageDimGroup = StorageDimGroup)
{
    StorageDimGroup = _StorageDimGroup;
    return  StorageDimGroup;
}

5. Now it is the time to create a service 

Goto AOT\Services\ and right click and add new 
Name : MK_ItemMasterService
Class: Service class name (MK_ItemMasterService)
Description: "Product Import Service".
External Name: 

6. Add the Operations to Service.
By Expanding the service and right click on Operations and add
Select the method "CreateProduct" and click ok.

7. Create Service Group 
\Service Groups\MK_ItemMasterServices
Name: MK_ItemMasterServices
AutoDeploy: Yes
Description:

add the above-created service (step 6) to this service group.

8. Deploy the service Group.
Right click on Service Group and deploy.
This will create an Inbound service. 
Copy the WSDL URL.

Now it's time to test the above service. For that, we will create a C# console application.

9. Create a C# console application 
Right click on the references and add a service reference 
Past the URL copied from step 8.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MKProductImportService.ServiceReference1;

namespace MKProductImportService
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                MK_ItemMasterServiceClient client = new MK_ItemMasterServiceClient();
                CallContext context = new CallContext();
                context.Company = "CW01";
                Console.WriteLine("Object Created Success!");

                MK_ItemImportContract procuct = new MK_ItemImportContract();
                procuct.parmDisplayProductNumber = "T00003";
                procuct.parmName = "Test3 Procut WCF";
                procuct.parmProductNumber = "T00003";
                procuct.parmStorageDimGroup = "WL";
                procuct.parmTrackingDimGroup = "BS";
                procuct.parmSearchName = "Test3 WCF";

                Console.WriteLine("Lines added Success!");
                string itemid = client.createProduct(context, procuct); // call the create product method

                Console.WriteLine("Item Created:" + itemid);

                Console.WriteLine("Success! !!!");

            }
            catch (Exception e)
            {
                Console.WriteLine(e.InnerException.Message);
            }
            //Console.ReadLine();
        }
    }
}

10. Build and run 

........................


Monday, 10 September 2018

Get temp data from class to form Data source AX 2012 + X++

Get temp data from class to form Data source AX 2012 + X++

In the below example we will see how we can use the temporary table as form datasource.
we can use a temporary table as datasource whether it is of type tempDb or InMemory.

1. Create a temporary table and just need to drag into the form datasource.
2. Create a class to fill the temporary table.

public class MK_ItemDiscountGroup
{
    MK_tmpInventTable          tmpInventTable;
   
    PriceDiscGroup              priceDiscGroup;

}
3. add a method to fill temp data and return tempTable

public MK_tmpInventTable fillTmpData()
{
    InventTable         inventTable;
    InventTableModule   inventTableModule;
    //MK_tmpInventTable  tmpInventTable;
    //RecordInsertList insertList = null;
    //insertList = new RecordInsertList(tablenum(MK_tmpInventTable));
    ttsbegin;
    while select inventTable
        join inventTableModule
        where inventTable.ItemId == inventTableModule.ItemId
        && inventTableModule.ModuleType == ModuleInventPurchSales::Sales
        && inventTableModule.LineDisc == priceDiscGroup.GroupId
    {
       
            tmpInventTable.ItemId = inventTable.ItemId;
            tmpInventTable.NameAlias = inventTable.NameAlias;
            tmpInventTable.Name = inventTable::name(inventTable.ItemId);
            tmpInventTable.LineDisc = inventTableModule.LineDisc;
            tmpInventTable.insert();
       
        //insertList.add(tmpInventTable);

    }

    //insertList.insertDatabase();
    ttscommit;
    return tmpInventTable;


}

4. call this method in init method of form after super.

public void init()
{

     super();
     itemDiscountGroup = MK_ItemDiscountGroup::construct(priceDiscGroup);
    itemDiscountGroup.fillTmpData();
    //if table is of type tempDb, call following method.
    MK_tmpInventTable.linkPhysicalTableInstance(itemDiscountGroup.fillTmpData());
    //Note:// if table is of type InMemory,call following method.

    MK_tmpInventTable.setTmpData(element.insertRecords());
}

// important thing comes here
// if the table is of type InMemory, call following method.

TmpTable.setTmpData(element.insertRecords());

// if the table is of type tempDb, call following method.

TmpTable.linkPhysicalTableInstance(element.insertRecords());

Wednesday, 11 July 2018

How to Use LIKE Operator in select Query X++

It is very common to use Like Operator in SQL 

SELECT column1, column2, ...
FROM table_name
WHERE columnN LIKE pattern;

Now we will see how we can use the Like operator in X++

It is very similar to SQL as shown in the below example. In this example, I'm updating  TrvPartyEmployeeRelationship with HcmWorker table.


static void MK_TrvPartyEmpUpd(Args _args)
{
    DataArea    dataArea;
    TrvPartyEmployeeRelationship    empRelation;
    HcmWorker                       worker;
    HcmPersonnelNumberId            empName;
    while select dataArea
        where dataArea.isVirtual == NoYes::No
    {
        changeCompany(dataArea.id)
        {
            empRelation = null;
            while select forUpdate empRelation
            {
                worker = null;
                empName = "";
                empName = strFmt("%1%2%3","*",empRelation.DEL_EmplId,"*");
                select firstOnly worker 
                where worker.PersonnelNumber like empName;
                if (worker.RecId)
                {
                    ttsBegin;
                    empRelation.selectForUpdate(true);
                    empRelation.Worker = worker.RecId;
                    empRelation.doDelete();
                    ttsCommit;
                    
                }
            }
            
        }
    }
}

Tuesday, 17 April 2018

Generate file name with time and random number X++

static str getFileName(str _fileName)
{
    str             lFileName;
    UtcDateTime     dateTime = DateTimeUtil::getSystemDateTime();
    int             randomNumber;
    str             hours = '';
    str             minutes = '';
    str             seconds = '';
    str             yyyy = '';
    str             mm = '';
    str             dd = '';

    randomNumber = 0;
    randomNumber = xGlobal::randomPositiveInt32();

    hours   = int2str(DateTimeUtil::hour(dateTime));
    minutes = int2str(DateTimeUtil::minute(dateTime));
    seconds = int2str(DateTimeUtil::second(dateTime));
    yyyy    = int2str(DateTimeUtil::year(dateTime));
    mm      = int2str(DateTimeUtil::month(dateTime));
    dd      = int2str(DateTimeUtil::day(dateTime));
   
    hours   = (strLen(hours) == 1) ? '0' + hours : hours ;
    minutes = (strLen(minutes) == 1) ? '0' + minutes : minutes ;
    seconds = (strLen(seconds) == 1) ? '0' + seconds : seconds ;
    mm      = (strLen(mm) == 1) ? '0' + mm : mm ;
    dd      = (strLen(dd) == 1) ? '0' + dd : dd ;
   
    lFileName = strFmt('%1_%2%3%4_%5%6%7_%8.xml',lFileName,yyyy,mm,dd,hours,minutes,seconds,randomNumber);
    return lFileName;

}

Monday, 16 April 2018

SSRS Web Service fix


1.1        Start SSRS Service

1.       From Server, check http://pbi04/Reports from IE
2.       If we received “This page can’t be displayed”
3.       Then Open Reporting Services Configuration Management
4.       Connect to Server – PBI04 and check Report Server is “Start”
5.       Once all Green apply then select PBI04\MSSQLSERVER to all options available to edit
6.       Go to Web Service URL option and click Report Server Web Service URLs to test
7.       If page is not open then following need to check
-                      Open Command Prompt with “Run as Administrator”
-                      Run netstat –an
-                      Check list and see which Local Address has Port 80, if too many lists then
0.0.0.0 ß all IPv4 addresses on the local machine
192.168.xx.xx ß allocated IP address, for example 192.168.29.143
127.0.0.1 ß Localhost
o        Run command: netsh http show iplisten
o        This command will only show with Port 80
-                      More likely specific IP does not have Port 80 (listen) – 192.168.42.178 & 0.0.0.0
-                      Run following to add
o        netsh http add iplisten ipaddress=192.168.42.178:80
o        netsh http add iplisten ipaddress=0.0.0.0:80

Sunday, 15 April 2018

MDM Development Setup and Configuration and Troubleshooting


MDM Development Setup and Configuration and Troubleshooting
1.       All the user account which part of MDM integration is should have been grant with following permissions,
a.       MDS Service Account in computer management
b.      Should be an LogOn user to MDS Database
c.       MDS Database user should have the membership mdm_exec and axmdm_exec permission should be checked
d.      MDS Database user should have the Owned schema are mdm,stg,mdq,dqs
e.      Users should be added to MDS site user with Super user permissions.
2.       All the MDM Database should be associated with an IIS site under Default website, so you verify the same by looking into the web config of the respective MDS IIS site where the MDS Database is configuring to connect between IIS site and MDS Database.
3.       We need to make sure that MDS IIS site is up and running and the user have enough privilege to access the same by browsing the site from IIS. Basically you can verify the permission once you open the MDS site you can see all the feature like System Administration, Integration Management and User Group Permission etc.
4.       Log on to AX machine and open the Dynamics AX Management shell and execute the following command,
a.       Syntax: Set-AXMasterDataManagementMDSSetup –MDSServerName -MDSDatabase

Eg: Set-AXMasterDataManagementMDSSetup –MDSServerName dBI04 -MDSDatabase MDS
5.       Open the Dynamics AX client and make sure that the License configuration has been enabled for the MDM in the following path,
a.       System Administration->License Configuration->Data Import and Export -> MDM
6.       In Dynamics AX client, go to Data Import and Export Menu under Master Data Management select Configure MDM with following parameters,
a.       Server : MDM Database server name Eg: DBI04
b.      Repository : MDM Database Eg: MDS
c.       Service URL : Basically you can find this under MDM IIS site-> Services-> Service.svc and click on browse. Copy the same URL and paste it here.
d.      Click on Test configuration -> If user has all permission the connection should be succeeded.
7.       In Dynamics AX client, go to Publish Entities and Click on Create schema by selecting the required entity, this will basically create the schema in MDS site with new Model and Entity and you can verify the same by looking in to the MDS site. Basically, publishing the entities required Schema permission as I have mentioned above in point 1. Once the Entity schema is created in MDS site, the InMDS checkbox will be checked in the Publish entity form.
8.       In Dynamics AX client, go to Manage Synchronous and  create new Sync group. Go to entities Only published entities will be displayed in lookup, choose the required entity and save. Go to Settings and configure the Push and Pull operation. Finally click on New Schedule and Run the Sync either by batch or normally based on the Push and Pull configuration it sync the data to MDS. Once the sync is completed we’ll get info about the record count that is synced From and To MDS site.
Configuring Customer Interface
Assumption: AOS1 and AOS2 – Customer synchronous through MDM via MDS service. Let’s say AOS1 is the Source and AOS2 is the Destination.
 





By Default, Microsoft Dynamics AX 2012 R3 system contains out of BOX MDM entities they are,
1.       Customer
2.       Vendor
3.       Product
4.       Party
5.       Employee
This section describes about How to configure the standard out of box Customer Interface Sync between two different AOS system using MDS service.
1.       Open AOS1 environment and Dynamics AX client.
2.       Click on Publish Entities under MDM section under DIXF.
3.       Select Customer entity and click on Create Schema. Basically, it requires the following schema owner for the mds_schema_user user,
a.       mdm
b.      stg
c.       mdq
d.      dqs
4.      
Once the entity is published, we’ll get info saying that the “Entity is published successfully” and you can verify the same by looking into the entity in MDS site with same entity name and Model.










5.       Click on Manage Synchronization menu and Click on New to create new Sync group.
6.       After creating Sync group, click on Entity on the respective Sync group, all the Published entities will be displayed in the lookup. Select the Customer entity in the lookup and save the same.
7.       After the selecting the entity, click on settings and select the Synchronization Type, it should Push and Pull.
8.       Open AOS2 environment and Dynamics AX client.
9.       AOS2 environment should also be configured with same MDS server where the AOS1 system is connected.
10.   Once you click on Publish entities menu, you can see that the Customer entity is already Synced with checkbox InMDS is true, it says that already Customer entity is published.
11.   Click on Manage Synchronization menu and Click on New to create new Sync group.
12.   After creating Sync group, click on Entity on the respective Sync group, all the Published entities will be displayed in the lookup. Select the Customer entity in the lookup and save the same.
13.   After the selecting the entity, click on settings and select the Synchronization Type, it should be Pull.
14.   Click on New Schedule on the Sync Group and setup the Batch JOB
15.   Go to AOS1 machine and click on New Schedule on the Sync Group and setup the Batch JOB.

Important Links for the references:

How to Get Trade Agreement Line Discount Percentage by Item and Date in D365FO Using X++

  In Microsoft Dynamics 365 Finance and Operations (D365FO), trade agreements are used to manage prices and discounts for customers, vendor...