Loading...

D365 FO Sending Email with SSRS reports as attachment using X++

D365 FO Sending Email with SSRS reports as attachment using X++

 Public class EmailCustAccountStmnt

{

public void run(CustTable _custTable)

{

SysOperationQueryDataContractInfo sysOperationQueryDataContractInfo;

SrsReportRunController reportRunController;

CustTransListContract custTransListContract;

SRSReportExecutionInfo reportExecutionInfo;

SRSPrintDestinationSettings printDestinationSettings;

SRSReportRunService srsReportRunService;

SRSProxy srsProxy;

QueryBuildRange qbrCustAccount;

QueryBuildDataSource queryBuildDataSource;

Object dataContractInfoObject;

Map reportParametersMap;

Map mapCustAccount;

MapEnumerator mapEnumerator;

Array arrayFiles;

System.Byte[] reportBytes;

Filename fileName;

Args args;

System.IO.MemoryStream memoryStream;

System.IO.MemoryStream fileStream;

CustParameters custParameters;

Email toEmail;

 

    Map                                 templateTokens;

    str                                 emailSenderName;

    str                                 emailSenderAddr;

    str                                 emailSubject;

    str                                 emailBody;

 

    Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[]  parameterValueArray;

 

    #define.Subject("Subject")

    #define.CustAccount("CustAccount")

    #define.EmailDate("Date");

 

    custParameters          = CustParameters::find();

 

    reportRunController     = new SrsReportRunController();

    custTransListContract   = new CustTransListContract();

    reportExecutionInfo     = new SRSReportExecutionInfo();

    srsReportRunService     = new SrsReportRunService();

    reportBytes             = new System.Byte[0]();

    args                    = new Args();

    templateTokens          = new Map(Types::String, Types::String);

    var messageBuilder      = new SysMailerMessageBuilder();

 

    custTransListContract.parmNewPage(NoYes::Yes);

 

    fileName    = strFmt("CustomerAccountStatement_%1.pdf", _custTable.AccountNum);

 

    reportRunController.parmArgs(args);

    reportRunController.parmReportName(ssrsReportStr(CustTransList, Report));

    reportRunController.parmShowDialog(false);

    reportRunController.parmLoadFromSysLastValue(false);

    reportRunController.parmReportContract().parmRdpContract(custTransListContract);

 

    // Modify query

    mapCustAccount = reportRunController.getDataContractInfoObjects();

    mapEnumerator = mapCustAccount.getEnumerator();

 

    while (mapEnumerator.moveNext())

    {

        dataContractInfoObject = mapEnumerator.currentValue();

 

        if (dataContractInfoObject is SysOperationQueryDataContractInfo)

        {

            sysOperationQueryDataContractInfo = dataContractInfoObject;

 

            queryBuildDataSource    = SysQuery::findOrCreateDataSource(sysOperationQueryDataContractInfo.parmQuery()

                                                                    , tableNum(CustTable));

            qbrCustAccount          = SysQuery::findOrCreateRange(queryBuildDataSource, fieldNum(CustTable, AccountNum));

            qbrCustAccount.value(_custTable.AccountNum);

        }

    }

 

    printDestinationSettings = reportRunController.parmReportContract().parmPrintSettings();

    printDestinationSettings.printMediumType(SRSPrintMediumType::File);

    printDestinationSettings.fileName(fileName);

    printDestinationSettings.fileFormat(SRSReportFileFormat::PDF);

 

    reportRunController.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());

    reportRunController.parmReportContract().parmReportExecutionInfo(reportExecutionInfo);

 

    srsReportRunService.getReportDataContract(reportRunController.parmreportcontract().parmReportName());

    srsReportRunService.preRunReport(reportRunController.parmreportcontract());

 

    reportParametersMap = srsReportRunService.createParamMapFromContract(reportRunController.parmReportContract());

    parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);

 

    srsProxy        = SRSProxy::constructWithConfiguration(reportRunController.parmReportContract().parmReportServerConfig());

    reportBytes     = srsproxy.renderReportToByteArray(reportRunController.parmreportcontract().parmreportpath()

                                                    , parameterValueArray

                                                    , printDestinationSettings.fileFormat()

                                                    , printDestinationSettings.deviceinfo());

 

    memoryStream    = new System.IO.MemoryStream(reportBytes);

    memoryStream.Position = 0;

 

    fileStream      = memoryStream;

    toEmail         = this.getCustEmail(_custTable.AccountNum);

 

    if (custParameters.EmailId && toEmail)

    {

 

        templateTokens.insert(#CustAccount, _custTable.name());

        templateTokens.insert(#EmailDate, date2StrXpp(systemDateGet()));

 

        [emailSubject, emailBody, emailSenderAddr, emailSenderName] =

            EmailCustAccountStmnt::getEmailTemplate(custParameters.EmailId, _custTable.languageId());

 

 

        messageBuilder.addTo(this.getCustEmail(_custTable.AccountNum))

                        .setSubject(strFmt("Customer account statement for %1", _custTable.AccountNum))

                        .setBody(SysEmailMessage::stringExpand(emailBody, SysEmailTable::htmlEncodeParameters(templateTokens)))

                        .addCC("");

 

        messageBuilder.setFrom(emailSenderAddr, emailSenderName);

        messageBuilder.addAttachment(fileStream, fileName);

 

        SysMailerFactory::sendNonInteractive(messageBuilder.getMessage());

 

        info(strFmt("Email sent successfully to the customer account %1", _custTable.AccountNum));

    }

    else

    {

        info(strFmt("There is no email id mappiing for this customer %1 or check the Email template setup.", _custTable.AccountNum));

    }

}

 

protected static container getEmailTemplate(SysEmailId _emailId, LanguageId _languageId)

{

    var messageTable = SysEmailMessageTable::find(_emailId, _languageId);

    var emailTable = SysEmailTable::find(_emailId);

 

    if (!messageTable && emailTable)

    {

        // Try to find the email message using the default language from the email parameters

        messageTable = SysEmailMessageTable::find(_emailId, emailTable.DefaultLanguage);

    }

 

    if (messageTable)

    {

        return [messageTable.Subject, messageTable.Mail, emailTable.SenderAddr, emailTable.SenderName];

    }

    else

    {

        warning("@SYS135886"); // Let the user know we didn't find a template

        return ['', '', emailTable.SenderAddr, emailTable.SenderName];

    }

}

 

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;

}

Published on:

Learn more
Sherif Fayed
Sherif Fayed

Share post:

Related posts

New Approved Customer List mapping for Items in Dynamics 365 Finance and operations

Take control of your sales process with the latest feature in Microsoft Dynamics 365 Finance – the Approved Customer List! This powerful new f...

2 days ago

Part-9: Connect and Query Dynamics 365 Finance and operations data with Copilot studio

In this video, we kick off an exciting new series focused on extending Copilot Studio capabilities by connecting it to real enterprise data! �...

2 days ago

How to Create Deep Links to D365 F&O Records with Dataverse Virtual Tables

It is a common requirement for SaaS platform that exposes form over data to be able to share a secure link (a.k.a. Deep Link) to access a give...

2 months ago

Simplifying License Management for Dynamics 365 Finance and Operations: Improved User License Validation

Starting April 30th, Dynamics 365 administrators will gain access to new license usage reporting tools, centralizing user license management. ...

3 months ago

D365FO Integration: Import Sales Orders from an External Web Application

Learn how to implement robust and efficient process to import complex documents into Dynamics 365 Finance and Operations from external Web ser...

4 months ago

Practical Hints for Technical Management of D365FO Go-Live

In this post, I share practical insights from my experience managing the technical side of Go-Live for D365FO projects, focusing on key activi...

8 months ago

D365FO Integration: Event-Based Exports to External Web Services

How to implement robust, efficient integrations between Dynamics 365 Finance and Operations and external Web Services. This post covers design...

9 months ago
Stay up to date with latest Microsoft Dynamics 365 and Power Platform news!
* Yes, I agree to the privacy policy