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

D365 Print Management Setup to print reports

In Microsoft Dynamics Ax D365, we have the out of the box feature of print management to print report either OOTB or custom reports of our clients so for that we need to configure the print management settings. We normally faces this warning message when we print the reports without the setting has been done. Firstly , select Form setup ( Accounts Receivable >> Forms >> Form setup  ) Secondly, In the General tab , select Print Management Thirdly, In the Document Tab right click and select New tab Moreover , we need to set the listed below details and need to select our required reports to load using print management Furthermore , we now nee to go to All Free Tax Invoices in AR Lastly you can use the FTI to generate the respective report using the print button. This time the Warning will be Gone!!! 

Upload and Download file to BLOB storage Account in D365 F&O using X++

Hello Devs! This blog will be a source of help for many Devs who are working on Azure Blog Storage account. We normally use azure blob storage account to hold thing that need to be further processed and stored on cloud. Scenario:  We have been asked to * Upload file to azure * Download file from azure "We will be using Share File Management technique" Case #1 : Uploading File to Azure  Note : Here we are using  PurchParameter  table to extract urls and other folder related details you can use your own folder name to access the azure blob folder Further, Credential details have already been extracted i.e vault key,authorization key and has been stored in our custom table and extracted from d365 through azure parameters  storageCredentials  = new Microsoft.WindowsAzure.Storage.Auth.StorageCredentials(SystemParameters::find().CMTStorageAccountName, purchParameters.CMTTankKeyVaultSecret); Or alternatively, CloudStorageAccount storageAccount = ...

Update record set using update_recordset in d365 F&O | AX 2012 using X++

Hello Devs! One the most common condition that we being a developer faces is to update existing records set that is mostly done on report level when we need to add new fields in the Temporary table and we don't wants to make extensions on class level. Here is a small piece of code that will assist you in updating existing record sets.  update_recordset custAgingReportTmp                 setting                 CMTCustInternalCollector = hcmWorker.PersonnelNumber,                 PaymDayId                         = custTable.PaymDayId,                 PaymTermId                       = custTable.PaymTermId,                 CashDisc      ...