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

D365FO Use of FileUpload control to Read CSV file

"Object reference not set to an instance of an object Error" When you do show all Fields