Wednesday, 6 May 2015

AX 2012 : Custom Service for importing Sales Agreement data

Custom Service for importing Sales Agreement data : AX2012


Microsoft Dynamics AX 2012 – WCF Custom Services for importing header and line data scenario. 
In this scenario, I will show you how to create sales agreements using custom WCF service. 
We will start with the data models, below are the list of data models used to create sales agreement.
Data model :
1. AgreementHeader
2. SalesAgreementHeader
3. AgreementLine
4. InventDim
5. AgreementLineQuantityCommitment

Classes: 
1. MkSalesAgreementService (Service class)
2. MkAgreementLineContract ( AgreementLines contract class)
3. MkSalesAgreementContract (Agreement Header contract class).

First of all we will start with creating a Contract class for Agreement Header. 
MkSalesAgreementContract : Data contract class
[DataContractAttribute]
public class MkSalesAgreementContract
{
    SalesAgreementId        lSalesAgreementId;
    CustAccount             lCustAccount;

    //list for Agreement Lines
    List                    agreementLines;

}
//Data member for SalesNumberSequence.
[DataMemberAttribute]
public SalesAgreementId SalesNumberSequence(SalesAgreementId _SalesAgreementId = lSalesAgreementId)
{
    lSalesAgreementId = _SalesAgreementId;
    return  lSalesAgreementId;
}
//Data member for CustAccount
[DataMemberAttribute]
public CustAccount CustAccount(CustAccount _CustAccount = lCustAccount)
{
    lCustAccount = _CustAccount;
    return  lCustAccount;
}
//Data member for Agreement Lines data, here we are passing the agreement lines class as parameters
[AifCollectionTypeAttribute('return', Types::Class, classStr(MkAgreementLineContract)), DataMemberAttribute]
public List AgreementLine(List _AgreementLine = agreementLines)
{
    agreementLines = _AgreementLine;
    return agreementLines;
}

now, we will build the data contract class for Agreement Lines.
MkAgreementLineContract :   Data contract class
[DataContractAttribute]
public class MkAgreementLineContract
{
    AgreementHeaderRecId    lAgreement;
    EffectiveDate           lEffectiveDate;
    ExpirationDate          lExpirationDate;
    CommitmentType          lAgreementLineType;
    RefRecId                lCategory;
    ItemId                  lItemId;
    LineNum                 lLineNumber;
    InventQtyJournal        lqty;
}
[DataMemberAttribute]
public AgreementHeaderRecId Agreement(AgreementHeaderRecId _Agreement = lAgreement)
{
    lAgreement = _Agreement;
    return  lAgreement;
}
[DataMemberAttribute]
public CommitmentType AgreementLineType(CommitmentType _AgreementLineType = lAgreementLineType)
{
    lAgreementLineType = _AgreementLineType;
    return  lAgreementLineType;
}
[DataMemberAttribute]
public RefRecId Category(RefRecId _Category = lCategory)
{
    lCategory = _Category;
    return  lCategory;
}
[DataMemberAttribute]
public EffectiveDate EffectiveDate(EffectiveDate _EffectiveDate = lEffectiveDate)
{
    lEffectiveDate = _EffectiveDate;
    return  lEffectiveDate;
}
[DataMemberAttribute]
public ExpirationDate ExpirationDate(ExpirationDate _ExpirationDate = lExpirationDate)
{
    lExpirationDate = _ExpirationDate;
    return  lExpirationDate;
}
[DataMemberAttribute]
public ItemId ItemId(ItemId _ItemId = lItemId)
{
    lItemId = _ItemId;
    return  lItemId;
}
[DataMemberAttribute]
public LineNum LineNum(LineNum _lineNum = lLineNumber)
{
    lLineNumber = _lineNum;
    return lLineNumber;
}
[DataMemberAttribute]
public InventQtyJournal Qty(InventQtyJournal _qty = lqty)
{
    lqty = _qty;
    return lqty;
}

and finally we will build the service class 
MkSalesAgreementContract : Service class
class MkSalesAgreementService
{
}
we will create a service to be assessed from any external system
[SysEntryPointAttribute(true)]
public SalesAgreementId createSalesAgreement(MkSalesAgreementContract _sAgreement)
{
    MkSalesAgreementContract       lAgreementContract;
    MkAgreementLineContract        lAgreementContractLine;  
    SalesAgreementHeader            lSalesAgreementHeader;
    //AgreementLine                   lAgreementLine;
// // as AgreementLine is Abstract table we can not insert data directly, hence we need to insert into child table.
    AgreementLineQuantityCommitment lAgreementLine;
    ListIterator                    literator;
    List                            lAgreementList;
    LineNum                         lineNum;
    SalesAgreementForm              salesAgreementForm;

    try
    {
        ttsbegin;

        lSalesAgreementHeader.clear();
        lSalesAgreementHeader.initValue();
        //salesAgreementForm = SalesAgreementForm::construct();
        lSalesAgreementHeader.SalesNumberSequence   = _sAgreement.SalesNumberSequence() ? _sAgreement.SalesNumberSequence() : MkSalesAgreementService::getAgreementID();
        //lSalesAgreementHeader.DefaultAgreementLineType = salesAgreementForm.parmDefaultCommitmentType();
        lSalesAgreementHeader.CustAccount   = _sAgreement.CustAccount();
       //Mallik Mandatory fields for creating Agreement header, these can be data members methods 
        lSalesAgreementHeader.AgreementClassification = 22565421926;
        lSalesAgreementHeader.Currency  = "CAD";


        if (lSalesAgreementHeader.validateWrite())
        {
            lSalesAgreementHeader.insert();

            literator = new ListIterator(_sAgreement.AgreementLine());

            while (literator.more())
            {
                //lAgreementLine = literator.value();
                lAgreementContractLine = literator.value();
                lineNum++;

                lAgreementLine.clear();
                lAgreementLine.initValue();
                lAgreementLine.initFromAgreementHeader(lSalesAgreementHeader);//initFromInventJournalTable(inventJournalTable);
                lAgreementLine.Agreement = lSalesAgreementHeader.RecId;//lAgreementContractLine.Agreement();
                lAgreementLine.ItemId = lAgreementContractLine.ItemId();
                lAgreementLine.Category = lAgreementContractLine.Category();
                lAgreementLine.AgreementLineType = CommitmentType::ProductQuantity; //lAgreementContractLine.AgreementLineType();
                lAgreementLine.EffectiveDate = lAgreementContractLine.EffectiveDate();
                lAgreementLine.ExpirationDate = lAgreementContractLine.ExpirationDate();
                lAgreementLine.CommitedQuantity = lAgreementContractLine.Qty();
                lAgreementLine.LineNumber = lineNum;

                if (lAgreementLine.validateWrite())
                {
                    lAgreementLine.insert();
                    lAgreementLine.salesAgreementHeader().update();
                }
                else
                {
                    throw error("@SYS18447");
                }

                literator.next();
            }
        }
        else
        {
            throw error("@SYS18447");
        }

        ttscommit;
    }
    catch
    {
        return "";
    }

    return lSalesAgreementHeader.SalesNumberSequence;
}

after building the all x++ logic, it's time to create a service, add the service to ServiceGroup and deploy the service.
Now we are into final step to use the above service/ consume the WCF Custom service in .Net application.
here we go....

Create a console C# project
 add the Service Reference to the project ( WSDL URL of inbound port) 

and the C# code goes as below .......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MkSalesAgreements.ServiceReference1;

namespace MkSalesAgreements
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                DateTime EffectiveDate;
                // Get the value of date1, for example, here it is hard-coded
                EffectiveDate = Convert.ToDateTime("10/01/2015");
                // Calculate new date
                DateTime ExpirationDate = EffectiveDate.AddMonths(3);// AddDays(20);
                // Now, print the newdate or use it in any way you want


                MkSalesAgreementServiceClient client = new MkSalesAgreementServiceClient();

                CallContext context = new CallContext();
                context.Company = "USMF";
                Console.WriteLine("Object Created Success!");
                MkSalesAgreementContract agreements = new MkSalesAgreementContract();

                agreements.SalesNumberSequence = "SAG-000025";
                agreements.CustAccount = "BGRS-00003";
                

                MkAgreementLineContract[] agreementLines = new MkAgreementLineContract[2];

                agreementLines[0] = new MkAgreementLineContract();
                //agreementLines[0].Agreement = "SAG-000016";
                agreementLines[0].ItemId = "A0001";
                agreementLines[0].Qty = 100;
                //agreementLines[0].AgreementLineType = 1;
                agreementLines[0].EffectiveDate = EffectiveDate;
                agreementLines[0].ExpirationDate = ExpirationDate;

                agreementLines[1] = new MkAgreementLineContract();
                agreementLines[1].ItemId = "BA-Services";
                agreementLines[1].Qty = 99;
                //agreementLines[1].AgreementLineType = 1;
                agreementLines[1].EffectiveDate = EffectiveDate;
                agreementLines[1].ExpirationDate = ExpirationDate;

                agreements.AgreementLine = agreementLines; // add Lines to Header 
                Console.WriteLine("Lines added Success!");
                string journalId = client.createSalesAgreement(context, agreements); // call the createSalesAgreement method

                Console.WriteLine("JournalId:" + journalId);

                Console.WriteLine("Success! Mallik.. Happy Learning !!!");
            }
            catch (Exception e)
            {
                Console.WriteLine(e.InnerException.Message);
            }

            Console.ReadLine();
        }
    }
}


Points to Note:
1. as AgreementLine is Abstract table we can not insert data directly, hence we need to insert into child table.
2. The child table data is passed as a class object of child contract class. 

for more information about custom services see here 










No comments:

Import and Export file from BLOB storage Account(Azure) in D365 F&O using X++

  Import and Export file from BLOB storage Account in D365 F&O using X++ Import: /// <summary> /// MKInventQualityOrderLineService...