Practical D365 Finance & Operations insights for developers and consultants — X++ code, OData integration, data entities, plus functional setup and how-tos.
Friday, June 4, 2021
Importing data through Data entities using X++
Reading files from Azure Blob container
This post shows X++ code used to list and read all files in Azure Blob container. Please refer to the following code.
/// Start reading files from Blob
/// </summary>
public void startReadingFiles()
{
CloudBlobClient cloudBlobClient;
CloudBlobContainer cloudBlobInputContainer;
CloudStorageAccount cloudStorageAccount;
CloudBlockBlob iterationBlob, cloudBlockReadBlob;
Filename file, fileName;
System.Collections.IEnumerable list;
System.Collections.IEnumerator listEnumerator;
if (!payrollParameters.CUSBlobAccount || !payrollParameters.CUSBlobKey || !payrollParameters.CUSBlobgContainerInput)
{
throw error("Missing Parameters");
}
var storageCredentials = new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(payrollParameters.CUSBlobAccount, payrollParameters.CUSBlobKey);
try
{
cloudStorageAccount = new Microsoft.WindowsAzure.Storage.CloudStorageAccount(storageCredentials, true);
if (cloudStorageAccount)
{
cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
cloudBlobInputContainer = cloudBlobClient.GetContainerReference(payrollParameters.CUSBlobgContainerInput);
list = new System.Collections.Generic.List<str>();
list = cloudBlobInputContainer.ListBlobs(null, false, 0, null, null);
listEnumerator = list.getEnumerator();
while (listEnumerator.moveNext())
{
iterationBlob = listEnumerator.get_Current();
if (iterationBlob.Exists(null, null))
{
file = iterationBlob.StorageUri.PrimaryUri.AbsoluteUri;
fileName = iterationBlob.Name;
cloudBlockReadBlob = cloudBlobInputContainer.GetBlockBlobReference(fileName);
System.IO.Strean readStream = cloudBlockReadBlob.OpenRead(null, null, null);
}
}
info("Read from Blob Successful");
}
}
catch
{
error("Unable to connect to the Blob");
}
}
Wednesday, June 2, 2021
Sample Positive Pay XSLT
This post contains sample XSLT's for both Payroll and Bank positive pay.
Bank Positive Pay XSLT
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl xslthelper"
xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.02"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xslthelper="http://schemas.microsoft.com/BizTalk/2003/xslthelper">
<xsl:output method="text" omit-xml-declaration="yes" version="1.0" encoding="utf-8"/>
<xsl:template match="/">
<Document>
<xsl:for-each select="Document/BANKPOSITIVEPAYEXPORTENTITY">
<!--Cheque Detail begin-->
<xsl:variable name="terminator">"</xsl:variable>
<xsl:choose>
<xsl:when test='CHEQUESTATUS/text()=normalize-space("Void") or CHEQUESTATUS/text()=normalize-space("Rejected") or CHEQUESTATUS/text()=normalize-space("Cancelled")'>
<xsl:value-of select="'C'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'I'"/>
</xsl:otherwise>
</xsl:choose>
<xsl:value-of select="''" />
<xsl:value-of select="substring(concat(ACCOUNTNUM/text(), ' '), 0, 11)"/>
<xsl:value-of select="''" />
<xsl:value-of select="format-number(CHEQUENUM, '0000000000')"/>
<xsl:value-of select="''" />
<xsl:value-of select="translate(format-number(AMOUNTCUR, '00000000.00'), '.', '')"/>
<xsl:value-of select="''" />
<xsl:value-of select="msxsl:format-date(TRANSDATE/text(), 'yyMMdd')"/>
<xsl:value-of select="''" />
<xsl:value-of select="BANKNEGINSTRECIPIENTNAME/text()"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</Document>
</xsl:template>
</xsl:stylesheet>
Payroll Positive Pay XSLT
Upload file in Azure Blob using X++
This post shows how to write a code in X++ to upload file in Azure Blob. Please refer to the following X++ method to understand how it works.
Tuesday, March 9, 2021
Authorization token decode
I came across a very useful website for decoding authorization token while connecting D365 F&O using .net applications, Postman or any other tool.
The site is called https://jwt.io/ where you can put authorization token value to decode it.
This site is really helpful in verifying audience value, incorrect audience value can lead to 401 (Unauthorized) error.
Wednesday, March 20, 2019
Reference Group Control lookup in D365
All we need to do is to register event handler for lookup function and make a lookup little bit differently as shown below.
After handler is registered use the following code.
[FormControlEventHandler(formControlStr(MyWorker, MyWorker_HcmWorkerRecId), FormControlEventType::Lookup)]
public static void MyWorker_HcmWorkerRecId_OnLookup(FormControl sender, FormControlEventArgs e)
{
MyClass::createLookup(sender);
FormControlCancelableSuperEventArgs cancelableArgs = e as FormControlCancelableSuperEventArgs;
cancelableArgs.CancelSuperCall();
}
private static void createLookup(FormReferenceGroupControl _ctrl)
{
SysReferenceTableLookup sysTableLookup = SysReferenceTableLookup::newParameters(tablenum(HcmWorker), _ctrl);
Query query = new Query();
sysTableLookup.addLookupfield(fieldNum(HcmWorker, PersonnelNumber));
query.addDataSource(tablenum(HcmWorker));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}
Changin NewRecordAction through extensions
As you know NewRecordAction property is not enabled when being used in extensions as shown in the picture below.





