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