Friday, January 24, 2020

How to dynamically save PDF generated by SSRS Report for Multiple Free Text Invoices using x++ in D365 FO

Hi all ,


Most of the times we struggle when we get the requirement for extracting PDF from SSRS Report not manually but automatically as the user does not want to export the PDF one by one.

In order to save time and effort we can do this programatically as well using the below code :-


using Microsoft.Dynamics.AX.Framework.DocumentContract;

class FreeTextInvoiceEventHandler
{

    [FormControlEventHandler(formControlStr(CustFreeInvoice, BulkInvoiceSave), FormControlEventType::Clicked)]
    public static void BulkInvoiceSave_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        int                                                    loop;
        str                                                    url;
        FormDataSource                             fds;
        MultiSelectionHelper                      selectionHelper = MultiSelectionHelper::construct();
        Set                                                    selectedRecords = new Set(Types::Record);
        CustPrintOutInvoice                        custPrintOutInvoice;
        NoYes                                              usePrintManagement;
        RecordSortedList                            recordSortedList;
        CustInvoiceTable                            currentCustInvoiceTable;
        SalesInvoiceJournalPrint                salesInvoiceJournalPrint;
        CustInvoiceJour                             custInvoiceJour;
        CustInvoiceTable                           currCustInvoiceTable;
        SRSPrintDestinationSettings         srsPrintDestinationSettings;
        RecordSortedList                           custInvoiceJourList;
        RecordSortedList                           rsl, rs2;
        SrsReportRunController                controller = new SrsReportRunController();
        FreeTextInvoiceContract               rdpContract = new FreeTextInvoiceContract();
        SysCorpNetPrinters                       netPrinters;
        Filename                                       _filename;

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

        SRSProxy    srsProxy;

        SRSReportRunService    srsReportRunService = new SrsReportRunService();

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

        SRSReportExecutionInfo       executionInfo = new SRSReportExecutionInfo();

        fds = sender.formRun().dataSource('CustInvoiceTable');

        rsl = FreeTextInvoiceEventHandler::getSelectedRecords(fds);
        rs2 = FreeTextInvoiceEventHandler::getSelectedRecords(fds);

        Args args = new Args();

        select firstonly netPrinters where
        netPrinters.Active == NoYesCombo::Yes &&
            netPrinters.EnableSalesInvoiceDocumentPrint==NoYes::Yes;

        custInvoiceJourList = new RecordSortedList(tableNum(CustInvoiceJour));

        custInvoiceJourList.sortOrder(fieldNum(CustInvoiceJour, RecId));

        if (!WinAPI::pathExists("C:\\Temp\\Invoices\\"))
        {
            WinAPI::createDirectoryPath("C:\\Temp\\Invoices\\");
        }

        for (loop = rsl.len(); loop > 0; loop--)
        {
            rsl.next(currentCustInvoiceTable);

            custInvoiceJour = currentCustInvoiceTable.custInvoiceJour();

            if (custInvoiceJour.RecId)
            {
                selectedRecords.add(custInvoiceJour);

                _filename = strFmt("C:\\Temp\\Invoices\\%2 - %1.pdf"
                        ,custInvoiceJour.InvoiceId,CustTable::find(custInvoiceJour.InvoiceAccount).name());
               
                controller.parmReportName(ssrsReportStr(FreeTextInvoiceNew, Report));

                controller.parmExecutionMode(SysOperationExecutionMode::Synchronous);

                controller.parmShowDialog(false);

                rdpContract.parmRefRecid(currentCustInvoiceTable.RecId);

                rdpContract.parmInvoiceId(currentCustInvoiceTable.InvoiceId);

                controller.parmReportContract().parmRdpContract(rdpContract);

                srsPrintDestinationSettings = controller.parmReportContract().parmPrintSettings();
                srsPrintDestinationSettings.printMediumType(SRSPrintMediumType::File);
                srsPrintDestinationSettings.fileFormat(SRSReportFileFormat::PDF);
                srsPrintDestinationSettings.fileName(_filename);
                srsPrintDestinationSettings.printerName(netPrinters.PrinterName);
                srsPrintDestinationSettings.numberOfCopies(1);
                srsPrintDestinationSettings.collate(false);
                srsPrintDestinationSettings.printAllPages(true);
                srsPrintDestinationSettings.overwriteFile(true);
                srsPrintDestinationSettings.landscape(false);
                srsPrintDestinationSettings.fromPage(0);
                srsPrintDestinationSettings.toPage(0);
                srsPrintDestinationSettings.parmSendToPrinterAsPdf(true);
                srsPrintDestinationSettings.pack();
               
               
                controller.parmReportContract().parmReportServerConfig
                                             (SRSConfiguration::getDefaultServerConfiguration());

                controller.parmReportContract().parmReportExecutionInfo(executionInfo);
               
                 srsReportRunService.getReportDataContract
                                                 (controller.parmreportcontract().parmReportName());

                srsReportRunService.preRunReport(controller.parmreportcontract());

                reportParametersMap =                                                                                                                                     srsReportRunService.createParamMapFromContract(controller.parmReportContract());
               
               parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);

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

                // Actual rendering to byte array
                reportBytes =  srsproxy.renderReportToByteArray
                                                     (controller.parmreportcontract().parmreportpath(),
                                                      parameterValueArray,                                                                                                                              srsPrintDestinationSettings.fileFormat(SRSReportFileFormat::PDF),
                                                    srsPrintDestinationSettings.deviceinfo());

                if (reportBytes)
                {
                    System.IO.Stream            stream         = new System.IO.MemoryStream(reportBytes);

                    var fileStream = new System.IO.FileStream(_filename, System.IO.FileMode::Create,                                                                                                 System.IO.FileAccess::ReadWrite);
                    stream.CopyTo(fileStream);
                 
                    url = File::SendFileToTempStore(fileStream, _filename, classstr                                                                                                                   (FileUploadTemporaryStorageStrategy));
                    new Browser().navigate(url, true);

                }
               
            }
        }

    }

    public static  RecordSortedList getSelectedRecords(FormDataSource fds1)
    {
        RecordSortedList recordSortedList;
        CustInvoiceTable currentCustInvoiceTable;

        recordSortedList = new RecordSortedList(tableNum(CustInvoiceTable));
        recordSortedList.sortOrder(fieldNum(CustInvoiceTable,RecId));

        currentCustInvoiceTable = Global::getFirstSelection(fds1);

        while (currentCustInvoiceTable)
        {
            recordSortedList.ins(currentCustInvoiceTable);
            currentCustInvoiceTable = fds1.getNext() as CustInvoiceTable;
        }

        return recordSortedList;
    }
}

2 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Here
    is my positive experience with Mod APK, which offers users a more flexible and enjoyable way to explore mobile applications. Mod APK versions can provide extra features, improved options, and a fresh experience compared to regular apps. I appreciate the convenience and creativity that these modified apps bring. For users who want to discover new possibilities and enhance their mobile entertainment, Mod APK is an interesting choice worth exploring.

    ReplyDelete

Importing Excel Dates in D365 F&O through X++ without the Apostrophe Trick

  We often get a requirement to create excel upload custom functionality in x++ . In this post we will see how to handle Excel OLE Automatio...