class RetailSharedParameters_Eventhandlers
{
/// <summary>
/// Event handler for the "UploadFile" button click event.
/// </summary>
/// <param name="sender">The form control that triggered the event.</param>
/// <param name="e">Event arguments.</param>
[FormControlEventHandler(formControlStr(RetailSharedParameters, UploadFile), FormControlEventType::Clicked)]
public static void UploadFile_OnClicked(FormControl sender, FormControlEventArgs e)
{
// Get the button that triggered the event
FormButtonControl callerButton = sender as FormButtonControl;
// Get the form run instance
FormRun form = callerButton.formRun();
// Get the data source for the RetailSharedParameters table
FormDataSource RetailSharedParameters_ds = form.dataSource(formDataSourceStr(RetailSharedParameters, RetailSharedParameters)) as FormDataSource;
// Get the current record from the data source
RetailSharedParameters RetailSharedParameters = RetailSharedParameters_ds.cursor();
// Prompt the user to upload a file
FileUploadTemporaryStorageResult result = File::GetFileFromUser() as FileUploadTemporaryStorageResult;
// Check if the file upload was successful
if (result && result.getUploadStatus())
{
// Store the file name and download URL in the table
RetailSharedParameters.FileName = result.getFileName();
RetailSharedParameters.SoundFile = result.getDownloadUrl();
// Save the changes to the database
RetailSharedParameters.write();
}
}
/// <summary>
/// Event handler for the "DownloadFile" button click event.
/// </summary>
/// <param name="sender">The form control that triggered the event.</param>
/// <param name="e">Event arguments.</param>
[FormControlEventHandler(formControlStr(RetailSharedParameters, DownloadFile), FormControlEventType::Clicked)]
public static void DownloadFile_OnClicked(FormControl sender, FormControlEventArgs e)
{
// Variable to store the file URL
str fileUrl = '';
// Get the button that triggered the event
FormButtonControl callerButton = sender as FormButtonControl;
// Get the form run instance
FormRun form = callerButton.formRun();
// Get the data source for the RetailSharedParameters table
FormDataSource RetailSharedParameters_ds = form.dataSource(formDataSourceStr(RetailSharedParameters, RetailSharedParameters)) as FormDataSource;
// Get the current record from the data source
RetailSharedParameters RetailSharedParameters = RetailSharedParameters_ds.cursor();
// Retrieve the stored file URL
fileUrl = RetailSharedParameters.SoundFile;
// Open the file URL in a browser
if (fileUrl)
{
new Browser().navigate(fileUrl);
}
else
{
// Notify the user if no file URL is found
warning("No file URL found.");
}
}
}
Sherif Fayed
Wednesday, January 29, 2025
X++ Upload and Download file - D365 FO
Saturday, December 21, 2024
D365 Sending Email with Docentric Template for SalesInvoice.Report report as attachment using X++
public final class SendEmailHelper
{
public static str CCEmail, Esender;
public static LogisticsElectronicAddressLocator GetPrimaryEmail(AccountNum ACCNum)
{
if (!ACCNum)
{
throw error("Account number cannot be null or empty.");
}
DirPartyTable dirPartyTable = DirPartyTable::findRec(CustTable::find(ACCNum).Party);
if (!dirPartyTable)
{
throw error("No party found for the provided account number.");
}
LogisticsElectronicAddress logisticsElectronicAddress;
DirPartyLocation dirLocation;
select logisticsElectronicAddress
join dirLocation
where dirLocation.Location == logisticsElectronicAddress.Location &&
logisticsElectronicAddress.IsPrimary &&
dirLocation.Party == dirPartyTable.RecId &&
logisticsElectronicAddress.Type == LogisticsElectronicAddressMethodType::Email;
if (!logisticsElectronicAddress)
{
warning("No primary email address found.");
}
return logisticsElectronicAddress.Locator;
}
public static container getEmailTemplate(SysEmailId _emailId, LanguageId _languageId)
{
// Info(_emailId);
SysEmailMessageSYSTEMTable messageTable = SysEmailMessageSYSTEMTable::find(_emailId, _languageId);
SysEmailSYSTEMTable emailTable = SysEmailSYSTEMTable::find(_emailId);
if (!messageTable && emailTable)
{
// Try to find the email message using the default language from the email parameters
messageTable = SysEmailMessageSYSTEMTable::find(_emailId, emailTable.DefaultLanguage);
}
if (messageTable)
{
//CCEmail = emailTable.EmailId;
return [messageTable.Subject, messageTable.Mail, emailTable.SenderAddr, emailTable.EmailId];
}
else
{
warning("We didn't find a template"); // Let the user know we didn't find a template
return ['', '', emailTable.SenderAddr, emailTable.SenderName, emailTable.EmailId];
}
}
public static str Email_Body(CustInvoiceJour _custinvoicejour)
{
str InvoiceId = _custinvoicejour.InvoiceId;
str salesid = _custinvoicejour.SalesId;
str invoiceDate = date2str(DateTimeUtil::date(_custinvoicejour.InvoiceDate), 123,DateDay::Digits2,DateSeparator::Slash,DateMonth::Digits2,DateSeparator::Slash,DateYear::Digits4);
str customerName = CustTable::find(_custinvoicejour.InvoiceAccount).name();
str orderDate = date2str(DateTimeUtil::date(SalesTable::find(_custinvoicejour.SalesId).CreatedDateTime), 123,DateDay::Digits2,DateSeparator::Slash,DateMonth::Digits2,DateSeparator::Slash,DateYear::Digits4);
//str trackingNumber
RetailConfigurationParameters _RetailConfigurationParameters = RetailConfigurationParameters::findByName("INVOICED_TEMPLATE_ID");
str sub,tmp,Sender,frm;
str EmailId = _RetailConfigurationParameters.Value;
[sub,tmp,Sender,frm] = SendEmailHelper::getEmailTemplate(EmailId,'en-us');
Esender = sender;
tmp = strReplace(tmp,'%salesid%','%1');
tmp = strReplace(tmp,'%invoiceId%','%2');
tmp = strReplace(tmp,'%invoiceDate%','%3');
tmp = strReplace(tmp,'%customername%','%4');
tmp = strReplace(tmp,'%orderDate%','%5');
str ret = strFmt(tmp,salesid,InvoiceId,invoiceDate,customerName ,orderDate);
return ret;
}
public static void Sendmail(CustInvoiceJour _custinvoicejour)
{
System.Exception ex;
try
{
if (!_custinvoicejour)
{
throw error("CustInvoiceJour parameter is null.");
}
str invoiceId = _custinvoicejour.InvoiceId;
str body = SendEmailHelper::Email_Body(_custinvoicejour);
str emailTo = SendEmailHelper::GetPrimaryEmail(_custinvoicejour.InvoiceAccount);
if (!emailTo)
{
throw error("No email address found for the customer.");
}
SysMailerMessageBuilder builder = new SysMailerMessageBuilder();
builder.setBody(body);
builder.setFrom(Esender);
builder.addTo(emailTo);
builder.setSubject("Your order has been invoiced - " + invoiceId);
System.IO.Stream stream = SendEmailHelper::generateReportStream(_custinvoicejour.RecId);
if (stream)
{
builder.addAttachment(stream, "Your order has been invoiced - " + invoiceId + ".pdf");
}
else
{
warning("Stream for the report attachment could not be generated.");
}
SysMailerFactory::getNonInteractiveMailer().sendNonInteractive(builder.getMessage());
}
catch (Exception::CLRError)
{
ex = CLRInterop::getLastException();
throw error(ex.Message);
}
}
public static System.IO.MemoryStream generateReportStream(RecId invJournalRecId)
{
SalesInvoiceContract contract = new SalesInvoiceContract();
DocReportTemplate _DocReportTemplate ;
//Get Default Template to use from Docentric
select firstonly _DocReportTemplate
where _DocReportTemplate.Report == DOCREPORTTABLE::findReportId("SalesInvoice.Report").RecId
&& _DocReportTemplate.IsDefaultTemplate == NoYes::Yes;
//Get Invoice Record
CustInvoiceJour CustInvoiceJour = CustInvoiceJour::findRecId(invJournalRecId);
Filename fileName = _DocReportTemplate.TemplateId;
// Initialize the SalesInvoiceController
SrsReportRunController controller = new SrsReportRunController();
Args args = new Args();
// Attach the CustInvoiceJour record to the arguments
args.record(CustInvoiceJour);
controller.parmArgs(args);
// Set the report name
controller.parmReportName(ssrsReportStr(SalesInvoice, Report));
contract.parmRecordId(CustInvoiceJour.RecId);
controller.parmShowDialog(false);
controller.parmReportContract().parmRdpContract(contract);
// Use Docentric to generate the report
DocSrsReportGenerator docReportGenerator = new DocSrsReportGenerator(controller);
// Configure Docentric output settings directly in the generator
docReportGenerator.setPrintDestinationSettings_DocentricReport(DocOutputFileFormat::PDF, fileName);
// Generate the report as a container
container reportContainer = docReportGenerator.generateReport();
// Convert container to MemoryStream
System.IO.MemoryStream reportStream;
if (reportContainer)
{
reportStream = DocGlobalHelper::convertContainerToMemoryStream(reportContainer);
}
return reportStream;
}
}
Wednesday, July 24, 2024
D365 Sending Email with Customer Account Statement SSRS report as attachment using X++
public Email getCustEmail(CustAccount _custAccount){ CustTable custTable; DirPartyLocation dirPartyLocation; LogisticsLocation logisticsLocation; LogisticsElectronicAddress logisticsElectronicAddress; custTable = CustTable::find(_custAccount); select firstonly Location, Party from dirPartyLocation where dirPartyLocation.Party == custTable.Party join RecId from logisticsLocation where logisticsLocation.RecId == dirPartyLocation.Location join Locator from logisticsElectronicAddress where logisticsElectronicAddress.Location == logisticsLocation.RecId && logisticsElectronicAddress.Type == LogisticsElectronicAddressMethodType::Email && logisticsElectronicAddress.IsPrimary == NoYes::Yes; return logisticsElectronicAddress.Locator;}Tuesday, July 23, 2024
clicking link on info message X++ to Open form
Message::AddAction() method can be used to embed an action within a message sent to the message bar. This method supports adding a single action that is associated with a display or action menu item, which is then visualized as a link button, redirecting users directly to the form with the correct record selected. Here's how it can be used.
public static void pushNotification(str NotificationMsg, str actionText,LedgerJournalTable journalTable)
{
MenuItemMessageAction actionData = new MenuItemMessageAction();
actionData.MenuItemName(menuItemDisplayStr(LedgerJournalTable));
actionData.TableName(tableStr(LedgerJournalTable));
actionData.RecId(journalTable.RecId);
str jsonData = FormJsonSerializer::serializeClass(actionData);
int64 messageId = Message::AddAction(MessageSeverity::Informational,NotificationMsg ,actionText, MessageActionType::DisplayMenuItem, jsonData);
}
Muhammad Aamir Hanif Reference
Thursday, November 30, 2023
D365 FO - Send Email with attachments by X++
Go to System administration >> Setup >> Email >> System email templates
Create New template
Monday, November 27, 2023
D365 FO Data entity Export using X++
Data entity Export using X++ in D365 FO
Export data entity through X++ in D365 FO.
public final class ExportEntity
{
public static void main(Args _args)
{
#dmf
Query query;
DMFEntityName entityName = "Batch groups";
SharedServiceUnitFileID fileId;
// Update query
// query = new Query(DMFUtil::getDefaultQueryForEntity(entityName));
query = new query(dmfutil::getDefaultQueryForEntityV3(entityname));
querybuilddatasource qbds = query.datasourcetable(tablenum(BatchGroupEntity));
sysquery::findorcreaterange(qbds, fieldnum(BatchGroupEntity, ServerId)).value("Batch:DEMO");
// Export file
DMFDefinitionGroupName definitionGroupName = 'BatchGroupEntityExport';
try
{
DMFEntityExporter exporter = new DMFEntityExporter();
//There are optional parameters also added
fileId = exporter.exportToFile(
entityName, //Entity label
definitionGroupName, //Definition group
'', //ExecutionId group
'CSV', // or 'XML-Element',//Source format to export in
#FieldGroupName_AllFields,//Specify the field group fields to include in export.
query.pack(), //Query criteria to export records
curExt(),//
null, //List of XSLT files
true, //showErrorMessages
false); //showSuccessMessages
if (fileId != '')
{
//Get Azure blob url from guid
str downloadUrl = DMFDataPopulation::getAzureBlobReadUrl(str2Guid(fileId));
System.Uri uri = new System.Uri(downloadUrl);
str fileExt;
if (uri != null)
{
fileExt = System.IO.Path::GetExtension(uri.LocalPath);
}
Filename filename = strFmt('CustomerPaymentData%1',fileExt);
System.IO.Stream stream = File::UseFileFromURL(downloadUrl);
//Send the file to user
File::SendFileToUser(stream, filename);
// Below code will delete the export group.
//DMFDefinitionGroup::find(definitionGroupName, true).delete();
}
else
{
throw error("The file was not generated succefully. See execution log");
}
}
catch
{
throw error("DMF execution failed");
}
}
}D365 FO Encryption And Decryption Using A Symmetric Key(AES) using X++
Encryption And Decryption Using A Symmetric Key(AES) using x++
Encryption And Decryption Using A Symmetric Key(AES) using x++.
I received a requirement to generate an XML file with encrypted data using a symmetric key. The recipients on the other side will decrypt the text using the same symmetric key. To test this, I used a dummy value such as 'RRR'.
To achieve this, I wrote the code in C# and added the resulting DLL to my project references.
C# Code:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace EncryptionDecryptionUsingSymmetricKey
{
public class AesOperation
{
public static string EncryptString(string key, string plainText)
{
byte[] iv = new byte[16];
byte[] array;
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(plainText);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);// It will convert bytes to string
}
public static string DecryptString(string key, string cipherText)
{
byte[] iv = new byte[16];
byte[] buffer = Convert.FromBase64String(cipherText); // It will convert string to bytes
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream(buffer))
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader((Stream)cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
}
}X++ Code:
b14ca5898a4e4133bbce2ea2315a1916
Using EncryptionDecryptionUsingSymmetricKey;
internal final class TestRunnableClass1
{
public static void main(Args _args)
{
str key = "b65ff7654brt8799fghj4ed7892b6798";
str text = 'RRR';
str encryptedString = AesOperation::EncryptString(key, text);
info(encryptedString);
str decryptedString = AesOperation::DecryptString(key, encryptedString);
info(decryptedString);
}
}References Ref1 Ref2

