Hi,
AX D365 FTP Interface with Third Party System
Part 1: Define FTP InterfaceParameters
Part 2: Write FTP Code
Write FTP Code (Outbound XML file as output)
1. Generate XML – Here is sales invoice xml sample (outbound)
2. Upload XML File to FTP
3. Place a button in Sales Invoice CustInvoiceJournal and Call class on click event of the button
4. Output XML in FTP server
5. References
class SalesInvoiceEDIOutbound
{
//1. #Generate XML for outbound
public void GenerateXMLFile(CustInvoiceJour _custInvoiceJour)
{
String255 TempPath="";
//Get Temp Path for Cloud Services RDP i.e. C:\\Windows\\Temp as default
TempPath =
System.IO.Path::GetTempPath();
str fileNamePath=TempPath +_custInvoiceJour.SalesId + " - "+
_custInvoiceJour.InvoiceId + ".xml";
FileIoPermission permission;
XMLDocument xmlDoc =
XMLDocument::newBlank();
XMLNode rootNode;
XMLNode NodeHeader, NodeName,
NodeAddr,NodeMsg,NodeAction,NodeSenderId,NodeBody,NodeSalesInvoice,NodeCustInvoiceJour,NodeMessageParts;
XMLElement xmlElement,xmlElementBody;
XMLText xmlText;
CustInvoiceJour custInvoiceJour;
CustInvoiceTrans custInvoiceTrans;
str fileName= _custInvoiceJour.SalesId
+ " - " + _custInvoiceJour.InvoiceId
;
permission= new
FileIoPermission(fileNamePath,'w');
permission.assert();
xmlDoc = XMLDocument::newBlank();
// Create first line containing version
info
rootNode = xmlDoc.documentElement();
// Create a node for the name
Str messageId =_custInvoiceJour.SalesId
+ " - " + _custInvoiceJour.InvoiceId;
xmlElement =
xmlDoc.createElement('MessageId');
NodeMsg =
NodeHeader.appendChild(xmlElement);
xmlText =xmlDoc.createTextNode (messageId);
NodeMsg.appendChild(xmlText);
// Create a node for the Body record
xmlElement =
xmlDoc.createElement('Body');
NodeBody =
rootNode.appendChild(xmlElement);
// Create a node for the SalesInvoice
xmlElement =
xmlDoc.createElement('SalesInvoice');
NodeSalesInvoice =
NodeBody.appendChild(xmlElement);
// Create a node for the
CustInvoiceJour
xmlElement =
xmlDoc.createElement('CustInvoiceJour');
NodeCustInvoiceJour =
NodeSalesInvoice.appendChild(xmlElement);
XmlNode
Nodesalesid,NodeCurrencyCode,NodeCustGrp,NodeCustInvoiceTrans,NodeCustomerLineNum,NodeInvoiceDate,NodeInvoiceId,NodeItemId;
XmlNode
NodeDeliveryName,NodeInvoiceAccount,NodeInvoiceAmount,NodeOrderAccount,NodeInvoiceDateJour,NodePurchaseOrder;
XmlNode
NodeInvoiceIdJour,NodeLineAmountInclTax,NodeQty,NodeSalesUnit;
while select custInvoiceJour where custInvoiceJour.SalesId
==_custInvoiceJour.salesid && custInvoiceJour.InvoiceId ==
_custInvoiceJour.invoiceId
{
// Create a node for the
CurrencyCode
xmlElement =
xmlDoc.createElement('CurrencyCode');
NodeCurrencyCode =
NodeCustInvoiceJour.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(custInvoiceJour.CurrencyCode );
NodeCurrencyCode.appendChild(xmlText);
// Create a node for the
InvoiceAccount
xmlElement =
xmlDoc.createElement('InvoiceAccount');
NodeInvoiceAccount =
NodeCustInvoiceJour.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(custInvoiceJour.InvoiceAccount);
NodeInvoiceAccount.appendChild(xmlText);
// Create a node for the
InvoiceAmount
xmlElement =
xmlDoc.createElement('InvoiceAmount');
NodeInvoiceAmount =
NodeCustInvoiceJour.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(num2Str(custInvoiceJour.InvoiceAmount,0,2,1,2));
// xmlText
=xmlDoc.createTextNode(num2Text(custInvoiceJour.InvoiceAmount));
NodeInvoiceAmount.appendChild(xmlText);
// Create a node for the InvoiceDate
xmlElement =
xmlDoc.createElement('InvoiceDate');
NodeInvoiceDateJour =
NodeCustInvoiceJour.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(date2StrUsr(custInvoiceJour.InvoiceDate ));
NodeInvoiceDateJour.appendChild(xmlText);
// Create a node for the InvoiceId
xmlElement =
xmlDoc.createElement('InvoiceId');
NodeInvoiceIdJour =
NodeCustInvoiceJour.appendChild(xmlElement);
xmlText =xmlDoc.createTextNode(custInvoiceJour.InvoiceId );
NodeInvoiceIdJour.appendChild(xmlText);
while select custInvoiceTrans where
custInvoiceTrans.SalesId == custInvoiceJour.salesid &&
custInvoiceTrans.InvoiceId == custInvoiceJour.invoiceId
{
// Create a node for the
CustInvoiceTrans
xmlElement =
xmlDoc.createElement('CustInvoiceTrans');
NodeCustInvoiceTrans =
NodeCustInvoiceJour.appendChild(xmlElement);
NodeCustInvoiceTrans.attributes().setNamedItem(entityAttribute);
// Create a node for the CustomerLineNum
xmlElement =
xmlDoc.createElement('CustomerLineNum');
NodeCustomerLineNum =
NodeCustInvoiceTrans.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(int2Str(custInvoiceTrans.CustomerLineNum));
NodeCustomerLineNum.appendChild(xmlText);
// Create a node for the ItemId
xmlElement =
xmlDoc.createElement('ItemId');
NodeItemId =
NodeCustInvoiceTrans.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(custInvoiceTrans.ItemId );
NodeItemId.appendChild(xmlText);
// Create a node for the Qty
xmlElement = xmlDoc.createElement('Qty');
NodeQty =
NodeCustInvoiceTrans.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(num2Str(custInvoiceTrans.Qty ,0,2,1,2 ));
NodeQty.appendChild(xmlText);
// Create a node for the
SalesUnit
xmlElement =
xmlDoc.createElement('SalesUnit');
NodeSalesUnit =
NodeCustInvoiceTrans.appendChild(xmlElement);
xmlText
=xmlDoc.createTextNode(custInvoiceTrans.SalesUnit );
NodeSalesUnit.appendChild(xmlText);
}
}
// Save the file in Windows Temp
Location
xmldoc.save(fileNamePath );
//Call Upload method to write a
file on FTP
this.uploadFileFTP(fileNamePath,messageId);
}
// 2. Upload XML File to FTP####################
public client server str uploadFileFTP(str _fileNamePath,EDIMessageId _messageId)
{
System.Object ftpo;
System.Object ftpResponse;
System.Net.FtpWebRequest request;
System.IO.StreamReader reader;
System.IO.Stream requestStream;
System.Byte[] bytes;
System.IO.Stream readStream;
System.Text.Encoding utf8;
System.Net.FtpWebResponse response;
System.Object credential;
System.Exception netExcepn;
str
retVal;
try
{
//This calls FTP Parameters and validates
InterfaceParametersCheck interfaceParametersCheck= new InterfaceParametersCheck() ;
if(!interfaceParametersCheck.FTPParameters())
{
return "FTP details is missing";
}
//Interface
Parameter
InterfaceParameters parameters;
//Fetching
Interface Parameters
parameters =
interfaceParametersCheck.FTPDetails();
str ftpFileName;
ftpFileName = parameters.FTPAddress;
if (subStr(ftpFileName, strLen(ftpFileName) - 1, 1) != '/')
{
ftpFileName += '/';
}
if (parameters.FTPFolder8)
{
//ProductCatalog Outbound
ftpFileName +=
parameters.FTPFolder8 ;
ftpFileName += '/';
}
String50 FTPUserName=parameters.FTPUserName;
String30 FTPPassword=parameters.FTPPassword;
Commaio file;
container line;
ftpFileName+=_messageId+ ".xml";
// Read
file
_fileNamePath =
strReplace(_fileNamePath,"\\","/");
reader = new
System.IO.StreamReader(_fileNamePath);
utf8 =
System.Text.Encoding::get_UTF8();
bytes = utf8.GetBytes(
reader.ReadToEnd() );
reader.Close();
//Create
File in FTP
ftpo =
System.Net.WebRequest::Create(ftpFileName);
request = ftpo;
credential = new
System.Net.NetworkCredential(FTPUserName, FTPPassword);
request.set_Credentials(credential);
request.set_ContentLength(bytes.get_Length());
////FTP
file UploadFile represents STOR
///FTP
file UploadFileWithUniqueName represents STOU
request.set_Method('STOR');
requestStream =
request.GetRequestStream();
requestStream.Write(bytes,0,bytes.get_Length());
requestStream.Close();
ftpResponse =
request.GetResponse();
response = ftpResponse;
}
catch (Exception::CLRError)
{
netExcepn = CLRInterop::getLastException();
error(netExcepn.ToString());
}
catch
{
// Error
desconocido / Unknown error
error("@SYS83461");
}
if (response)
{
retVal =
int2Str(response.StatusCode);
}
return retVal;
}
}
3. Place a button in Sales Invoice CustInvoiceJournal and
Call above class on click event of the button
class CustInvoiceJourEventHandlers
{
[FormControlEventHandler(formControlStr(CustInvoiceJournal, SendToFTP),
FormControlEventType::Clicked)]
public static void SendToFTP_OnClicked(FormControl sender, FormControlEventArgs e)
{
FormButtonControl callerButton = sender as
FormButtonControl; //Retrieves the
button that we're reacting to
FormRun form = callerButton.formRun();
//Gets the running SalesEditLines form
FormDataSource custInvoiceJour_ds =
form.dataSource(formDataSourceStr(CustInvoiceJournal, CustInvoiceJour)) as
FormDataSource;
CustInvoiceJour _custInvoiceJour =
custInvoiceJour_ds.cursor();
if(_custInvoiceJour)
{
SalesInvoiceEDIOutbound salesInvoiceEDIOutbound=new
SalesInvoiceEDIOutbound();
str retVal;
retVal =salesInvoiceEDIOutbound. GenerateXMLFile(_custInvoiceJour);
if(retVal==int2Str(226)) //Transfer
OK Status == 226
{
CustInvoiceJour custInvoiceJourUpdate;
ttsbegin ;
select firstonly forupdate custInvoiceJourUpdate order by custInvoiceJourUpdate.RecId
desc where custInvoiceJourUpdate.SalesId==
_custInvoiceJour.SalesId && custInvoiceJourUpdate.InvoiceId
==_custInvoiceJour.InvoiceId ;
custInvoiceJourUpdate.Transmitted
=NoYes::Yes;
custInvoiceJourUpdate.doUpdate();
ttscommit;
info("File sent
successfully to FTP. Transfer Code is " + retVal );
}
else
{
info("File sent unsuccessful.
Transfer Code is " + retVal );
}
}
}
4. Output XML in FTP server
5. References
FTP Read
D365 Integration
Absolutely to the point and extremely helpful post.. :)
ReplyDeleteKudos to Shyam!!!
contcrudOceso Stuart Coo https://wakelet.com/wake/y6q7ZVWCDGlnMjATiA-IJ
ReplyDeletesaihydfeme