D365FO Send Report as email attachment

Hi All ,
Usually in any implementation project we get request to send Report as a attachment in email.  Below is code going to help you to send  report as an email attachment.  In the below code I am saving report in report archive(DocuRef table ) reading it from DocuRef table  in to bytes and converting it in to memory stream. The memory stream is further I am going to use to  send an email with Subject and body using SysMailerMessageBuilder class. You can use following methods of this class
setSubject - To set Subject of the email.
setBody -  To Set email body .
setFrom - To set sender of the email.
sendInteractive - To send interactively.
sendNonInteractive - TO send non interactively

        Args                                    args;
        SalesInvoiceContract                    salesInvoiceContract;
        CustInvoiceJour                         custInvoiceJourLocal;
        SRSPrintDestinationSettings             SRSPrintDestinationSettings;
        #SRSFramework
        
        body = "Hello" //HTML BOdy
    
        args = new Args();
        select firstOnly custInvoiceJourLocal where custInvoiceJourLocal.InvoiceId == caaTrustFollowUpInvoices.InvoiceId;
        args.record(custInvoiceJourLocal);
    
        SrsReportRunController  salesInvoiceController = new SrsReportRunController();
        salesInvoiceController.parmArgs(args);
        salesInvoiceController.parmReportName(PrintMgmtDocType::construct(PrintMgmtDocumentType::SalesOrderInvoice).getDefaultReportFormat());
        salesInvoiceController.parmShowDialog(false);
        salesInvoiceController.parmLoadFromSysLastValue(false);
    
        salesInvoiceContract = salesInvoiceController.parmReportContract().parmRdpContract();
        salesInvoiceContract.parmRecordId(custInvoiceJourLocal.RecId);                      // Record id must be passed otherwise the report will be empty

        SrsReportDataContract srsReportDataContract = salesInvoiceController.parmReportContract();
        //srsReportDataContract.parmisMemoryStreamOnly(true);
        salesInvoiceController.parmReportContract(srsReportDataContract);
    
        SRSPrintDestinationSettings = new  SRSPrintDestinationSettings();
        SRSPrintDestinationSettings.overridePrintContractSettings(true);
        SRSPrintDestinationSettings.printMediumType(SRSPrintMediumType::Archive);
        SRSPrintDestinationSettings.parmOverwriteFileIsSet(true);
        SRSPrintDestinationSettings.fileFormat(SRSReportFileFormat::PDF);

        SRSPrintArchiveContract SRSPrintArchiveContract = new SRSPrintArchiveContract(SRSReportFileFormat::PDF);
        SRSPrintDestinationSettings.parmSRSPrintArchiveContract(SRSPrintArchiveContract);
        str archiveName = strFmt('%1-%2', curUserId(), timeNow());
        salesInvoiceController.parmReportContract().parmReportCaption(archiveName);//**This is the 'Description' field in the archive
    
        salesInvoiceController.parmReportContract().parmPrintSettings(SRSPrintDestinationSettings);
    
        salesInvoiceController.run();

        PrintJobHeader printJobHeader;

        select firstonly forupdate printJobHeader where printJobHeader.jobDescription == archiveName;

        DocuRef docuRef;

        select firstonly forupdate docuRef where docuRef.RefRecId == PrintJobHeader.RecId && docuRef.RefTableId == tableNum(PrintJobHeader) && docuRef.TypeId == #SRSArchiveDocument;

        DocuValue docuValue;
        select firstonly forupdate docuValue where docuValue.RecId == docuRef.ValueRecId;
        container reportBytes = docuValue.File;

        System.Byte[] binData;
        System.IO.Stream stream;

        // Turn the Bytes into a stream
        for(int i = 0; i < conLen(reportBytes); i++)
        {
            binData = conPeek(reportBytes,i+1);
            stream = new System.IO.MemoryStream(binData);
        }

        ttsbegin;
        printJobHeader.delete();
        docuRef.delete();
        docuValue.delete();
        ttscommit;

        infolog.clear();//Clear the message about archiving the report
    

        var messageBuilder = new SysMailerMessageBuilder();
        messageBuilder.addTo(sendToEmail)
                    .setSubject(Subject)
                    .setBody(Body)
                    .addCC(HcmWorker::find(ccEmail).email());
        
        if (sendFromEmail)
        {
            messageBuilder.setFrom(sendFromEmail);
        }
        
        if (stream != null)
        {
            messageBuilder.addAttachment(
                stream,
                'Invoice.pdf');
        }

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


Comments

Popular posts from this blog

Running runnable class through URL in Dynamics 365 for Operations

D365FO Use of FileUpload control to Read CSV file