Skip to main content

Send email with report attachment using x++

 Hello Devs!

Sending auto email functionality is one of the most common functionality that client asks for. Similarly, I have documented this blog to help people to achieve this functionality. 



Pre Requisites for this approach:
1)  SMTP setting must be configured based on server. 





Core Logic :

public void sendEmailwithAttachment(SalesTable _salesTable)

    {

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

        SysOperationQueryDataContractInfo       sysOperationQueryDataContractInfo;

        SrsReportRunController                  reportRunController;

        SRSReportExecutionInfo                  reportExecutionInfo;

        SRSPrintDestinationSettings             printDestinationSettings;

        SRSReportRunService                     srsReportRunService;

        SRSProxy                                srsProxy;

        Object                                  dataContractInfoObject;

        Map                                     reportParametersMap;

        System.Byte[]                           reportBytes;

        Filename                                fileName;

        Args                                    args;

        System.IO.MemoryStream                  memoryStream;

        System.IO.MemoryStream                  fileStream;

        Email                                   toEmail  ;

        CfzEcomDigiReceiptContract              contract;

        Map                                     templateTokens;

        str                                     emailSubject, emailBody;

        CustTable                               custtable;

        SalesTable                              SalesTable;

        logisticsPostalAddress                  logisticsPostalAddress;


        custtable               = custtable::find(_salesTable.CustAccount);

        reportRunController     = new SrsReportRunController();

        contract                = new CfzEcomDigiReceiptContract();

        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();

        


        contract.parmSalesId(_salesTable.SalesId);


        fileName    = strFmt("@CFZLabels:fileName", custTable.AccountNum);


        reportRunController.parmArgs(args);

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

        reportRunController.parmShowDialog(false);

        reportRunController.parmLoadFromSysLastValue(false);

        reportRunController.parmReportContract().parmRdpContract(contract);

                

        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         = custtable.email();


        if ( toEmail)

        {

            SysEmailTable   SysEmailTable;

            select firstonly SenderAddr, EmailId from SysEmailTable;

            emailSubject = strFmt("@CFZLabels:ECOReceipt", _salesTable.CustomerRef);

            templateTokens.insert("@SYS74341", emailSubject);

            templateTokens.insert("@SYS4009003", filename);

            logisticsPostalAddress =             LogisticsPostalAddress::findRecId(_salesTable.DELIVERYPOSTALADDRESS);

            emailBody = strFmt("@CFZLabels:EcoBody", _salesTable.CustomerRef, logisticsPostalAddress.address);

            emailBody = SysEmailMessage::stringExpand(emailBody, SysEmailTable::htmlEncodeParameters(templateTokens));

            emailBody = strReplace(emailBody, '\n', '<br>');

            messageBuilder.addTo(toEmail)

                                    .setSubject(emailSubject)

                                    .setBody(emailBody)

                                    .addCC("");


            messageBuilder.setFrom(SysEmailTable.SenderAddr , SysEmailTable.SenderName) ;

            messageBuilder.addAttachment(fileStream, fileName);


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


            info(strFmt("@XYZLabels:EmailSentMessage", custtable.AccountNum));

            select forupdate salestable

                where  salestable.salesid ==  _salesTable.SalesId;

            ttsbegin;

            salestable.XYZIsEmailSent = NoYes::Yes;

            salestable.update();

            ttscommit;

        }

        else

        {

            info(strFmt("@XYZLabels:NoEmail", custtable.AccountNum));

        }

    }





Comments

Popular posts from this blog

Adding D365 F&O Extension in Visual Studio 2022 | Dynamics

  Hello Devs! This is a very common scenario when it comes to enabling D365 extension within VS 2022, so for that below are list of steps needs to be done to enable extension for development. Please note for Older VS versions please refer to my blog below : https://www.linkedin.com/feed/update/urn:li:ugcPost:7033677029451440128/ Prerequisites: Visual Studio 2022 should be installed before performing below steps. Step # 1: Login to LCS (Microsoft Dynamics lifecycle services). In the main page after login there is a option of Shared asset library (without entering into project folder). Step # 2: In the list of sub menus , Select Software deployment package and search for latest Service update. For my case I am downloading 10.0.41 Step # 3 : Once you have downloaded it. Unzip the folder and search for FinanceAndOperations_10.0.2015.54_Application\DevToolsService\Scripts Before installation you will not be able to see Dynamics 365 option within VS 2022. Now please clos...

Import DB backup from .BacPac file in D365 F&O using CMD

Hello Devs! This is one of the most quickest way to import DB from .Bacpac file. Bacpac files are those which are generated from Tier 2 or higher environments as a DB backup.   Alternate Approach ----> Using wizard Prerequisites: 1) Access to LCS folder Asset library --> Database Backup Incase you don't see the folder ask your project owner to give you the access. Step 1:  Download the file and save it in local non-user directory.  Step 2: - Services to be stopped World Wide Web Publishing Service Management Reporter 2012 Process Service Microsoft Dynamics 365 Unified Operations: Batch Management Service Microsoft Dynamics 365 Unified Operations: Data Import Export Framework Service - Download SqlPackage.Exe.  Download link :  https://learn.microsoft.com/en-us/sql/tools/sqlpackage/sqlpackage-download?view=sql-server-ver15 Extract it and Open CMD as admin.  Step 3 :  Navigate to directory where you have extracted the SqlPackage.Exe folder us...

Error : 9002 The Transaction Log for database 'DB' is full due to 'LOG_BACKUP' Sql Server Error in Event View for AX dynamics D365

This is one of the most common error faced by developers often working with database. This error is very much common for SQL servers as when the LOG size runs out in other words reaches 100% then we encounter this error. Being an AX developer, when the log usage reaches to 100% AX stops working and throw reconnecting request error. For this there is a rapid solution and i have written query for it. Step #1: --this could be use to check you Database log file name and its location use AxDB--in my case AxDB is my Database Name select * from sys.database_files Step #2: --This could be used to see you log space usage for your particular log DBCC SQLPERF (LOGSPACE) Step #3: --In my case Database log file name is D365DB_log --use this query to shrink your log file size USE AxDB; GO -- Truncate the log by changing the database recovery model to SIMPLE. ALTER DATABASE AxDB SET RECOVERY SIMPLE; GO -- Shrink the truncated log file to 1 MB. DBCC SHRINKFILE (D365DB_log, 1); G...