web
You’re offline. This is a read only version of the page.
close
Skip to main content

Announcements

No record found.

News and Announcements icon
Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Unanswered

Generating Proforma Invoice in X++

(1) ShareShare
ReportReport
Posted on by 4
I have a requirement to generate proforma invoices for every open sales order into a single PDF file. If anyone has an easier way to accomplish this I'm happy to hear it, but I couldn't figure out how to do that with print management so I'm onto x++.  
 
When I call srsReportRunService.preRunReport() I get an error message "A currency to convert from is required to retrieve exchange rate information." When I debug I see that it errors on a line with a _CustInvoiceTrans record that's empty/null, so no currency info, it runs earlier successfully, so it feels like this is part of the proforma logic I'm missing. The invoice temp tables are populating fine, my sales lines all have currencies set, I can't figure out how to get past this error message. 
 
What I've got is something like this:
 
 #FILE
 Microsoft.Dynamics.AX.Framework.Reporting.Shared.ReportingService.ParameterValue[]  parameterValueArray;
 Map                             reportParametersMap;
 SRSProxy                        srsProxy;
 SRSReportExecutionInfo          executionInfo       = new SRSReportExecutionInfo();
 System.Byte[]                   reportBytes         = new System.Byte[0]();
 SRSReportRunService             srsReportRunService = new SrsReportRunService();
 SalesFormLetter_Invoice salesFormLetter_Invoice = SalesFormLetter::construct(DocumentStatus::Invoice); // controller
 SalesFormLetterInvoiceContract contract = salesFormLetter_Invoice.getInvoiceContract();
 SalesInvoiceContract rdpContract = new SalesInvoiceContract();
 rdpContract.parmRecordId(_salesTable.RecId);
 
 salesFormLetter_Invoice.initParmSalesTable(_salesTable);
 salesFormLetter_Invoice.update(_salesTable, systemDateGet(), SalesUpdate::All);
 salesFormLetter_Invoice.defaultGiroType(NoYes::No);
     
 SrsReportRunController  srsReportRunController = new SrsReportRunController();
 srsReportRunController.parmReportName(ssrsReportStr(SalesInvoiceLevel5, ProForma));
 srsReportRunController.parmExecutionMode(SysOperationExecutionMode::Synchronous);
 srsReportRunController.parmShowDialog(false);
 srsReportRunController.parmReportContract().parmRdpContract(rdpContract);

 SRSPrintDestinationSettings printerSettings = srsReportRunController.parmReportContract().parmPrintSettings();
 printerSettings.printMediumType(SRSPrintMediumType::File);
 printerSettings.fileFormat(SRSReportFileFormat::PDF);
 printerSettings.parmFileName(_salesTable.SalesId + #pdf);
 printerSettings.overwriteFile(true);

 srsReportRunController.parmReportContract().parmReportServerConfig(SRSConfiguration::getDefaultServerConfiguration());
 srsReportRunController.parmReportContract().parmReportExecutionInfo(executionInfo);
 srsReportRunService.getReportDataContract(srsReportRunController.parmreportcontract().parmReportName());
 srsReportRunService.preRunReport(srsReportRunController.parmreportcontract()); // this errors out due to currency issue
 reportParametersMap = srsReportRunService.createParamMapFromContract(srsReportRunController.parmReportContract());
 parameterValueArray = SrsReportRunUtil::getParameterValueArray(reportParametersMap);
 srsProxy = SRSProxy::constructWithConfiguration(srsReportRunController.parmReportContract().parmReportServerConfig());

 reportBytes = srsproxy.renderReportToByteArray(srsReportRunController.parmreportcontract().parmreportpath(),
                                 parameterValueArray,
                                 printerSettings.fileFormat(),
                                 printerSettings.deviceinfo());
 if (reportBytes)
 {
     System.IO.MemoryStream outputStream = new System.IO.MemoryStream(reportBytes);
     reportsInStreams.Add(outputStream);
 }
Categories:
I have the same question (0)
  • Martin Dráb Profile Picture
    238,957 Most Valuable Professional on at
    An obvious problem is that you're using RecId of SalesTable in SalesInvoiceContract, which is wrong. An invoice is an CustInvoiceJour record, not a SalesTable record.
     
    Moved from Integration, Dataverse, and general topics forum to Finance | Project Operations, Human Resources, AX, GP, SL forum.
  • CU26030657-0 Profile Picture
    4 on at
    For Proforma invoices the source is a sales table record, they haven't been invoiced yet.
  • Martin Dráb Profile Picture
    238,957 Most Valuable Professional on at
    No, that's not correct. The report needs an invoice  to print it, even if it's a proforma invoice. The sales order doesn't know what's on the invoice, e.g. when you invoice just a part of the order.
     
    Check out how the record ID is populated in SalesInvoiceController:
    salesInvoiceContract.parmRecordId(custInvoiceJour.RecId);
    and used in SalesInvoiceDP:
    this.parmCustInvoiceJour(CustInvoiceJour::findRecId(contract.parmRecordId()));
    Also, you can see how the RDP class determines whether it's a proforma invoice - it calls isProforma() method of CustInvoiceJour.
     
    The proforma posting does create an invoice journal, it just deletes it afterwards (see CustPrintOutInvoice.cleanUpProforma()).

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Introducing the 2026 Season 1 community Super Users

Congratulations to our 2026 Super Stars!

Congratulations to our 2025 Community Spotlights

Thanks to all of our 2025 Community Spotlight stars!

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Giorgio Bonacorsi Profile Picture

Giorgio Bonacorsi 573

#1
Giorgio Bonacorsi Profile Picture

Giorgio Bonacorsi 573

#3
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 396 Super User 2026 Season 1

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans