Continuing the series of articles in SSRS, here I explain how to print the salesInvoice (or any other custom report) in Enterprise Portal.
Despite Packing Slip, this report is not supported in the standard Enterprise portal installation (you don't have the button to print an invoice on the EP invoices list page)
That's because Sales Invoice use a report controller that has not been implemented for the use in EP.
The solution I propose here is a little tricky, but it works pretty well :)
The key is to modify the class EPDocuGet that manages the download of reports or attachments from EP.
In that class you can write some code to print the SalesInvoice PDF to a temporary directory (
how to do that is explained in a post before) and then write out the data in HTTP response of the Web request
So in the method run you can do something like:
void run(Args args = null)
{
IISResponse response = new IISResponse();
;
// Transition to a server function to avoid
// Security problems
if (args)
{
if (args.record().TableId == tableNum(DocuRef))
{
EPDocuGet::runDocument(args.record().data(), response);
}
// Begin change
// Description:
else if (args.record().TableId == tableNum(CustInvoiceJour))
{
EPDocuGet::DWrunReportSalesInvoice(args.record().data(), response);
}
// End
else
{
EPDocuGet::runReport(args.record().data(), response);
}
}
}
So if you got a CustInvoiceJour record you run your custom code. The method DWrunReportSalesInvoice is a copy of the runDocument method, a little bit modified:
#define.BUFFER_SIZE(4096)
#File
client static void DWrunReportSalesInvoice(Common callerRecord, IISResponse response)
{
Query query = new Query();
QueryBuildDataSource qbds;
QueryRun queryRun;
//EPSendDocument document;
BinData binData;
str fileName;
int fileOffset;
DictTable table = new DictTable(callerRecord.TableId);
str tempFileName;
boolean emptyReport;
CustInvoiceJour custInvoiceJour = callerRecord;
;
if (EPDocuGet::hasTableAccess(callerRecord.TableId))
{
qbds = query.addDataSource(callerRecord.TableId);
if (callerRecord && callerRecord.TableId != tableNum(DocuRef))
{
// Requery the record to test record level security
qbds.addRange(table.fieldName2Id('RecId')).value(SysQuery::value(callerRecord.RecId));
query.recordLevelSecurity(true);
queryRun = new QueryRun(query);
if (queryRun.next())
{
//document = new EPSendDocument(callerRecord);
tempFileName = System.IO.Path::GetTempFileName();
EPDocuGet::DWPrintInvoicePdf(callerRecord, tempFileName);
infolog.clear();
//document.parmOriginal(true);
//document.parmFileName(tempFileName);
// Make document will run the report and send it to a PDF file with
// the path specified in tempFileName
//document.makeDocument();
fileName = custInvoiceJour.InvoiceId + ".pdf";
// remove all ';' from the filename. These are treated as delimiters by Ie
fileName = strReplace(fileName, ';', '_');
emptyReport = (WinAPI::fileSize(tempFileName) == 0);
response.clear();
binData = new BinData();
if (emptyReport)
{
response.contentType('application/Octet-Stream');
response.addHeader('Content-Disposition', 'attachment;filename="' + fileName + #txt + '"');
response.writeTxt(strFmt("@SYS58533", fileName));
}
else
{
response.contentType('application/pdf');
response.addHeader('Content-Disposition', 'attachment;filename="' + fileName + #pdf + '"');
// Loop over the stored file and chunk it down to the client
fileOffset = 0;
// Assert permission and get the temp filename
new FileIOPermission(tempFileName, #io_read).assert();
while(true)
{
// BP Deviation Documented
if (!binData.loadFile(tempFileName, fileOffset, #BUFFER_SIZE))
{
break;
}
fileOffset += #BUFFER_SIZE;
response.binaryWrite(binData.getVariant());
}
CodeAccessPermission::revertAssert();
}
binData = null;
WinAPI::deleteFile(tempFileName);
}
}
}
}
And here is the method to print the invoice in PDF:
client static void DWPrintInvoicePdf(Common _record, Filename filename)
{
args args = new args();
CustInvoiceJour custInvoiceJour = _record;
SRSPrintDestinationSettings printSettings;
SalesInvoiceController controller = new SalesInvoiceController();
str pdfPath = filename;
args.record(_record);
//pdfPath = WinAPI::getTempPath() + custInvoiceJour.InvoiceId + ".pdf";
// imposta nome report
controller.parmReportName(ssrsReportStr(SalesInvoice, Report));
// get print settings from contract
printSettings = controller.parmReportContract().parmPrintSettings();
// set print medium
printSettings.printMediumType(SRSPrintMediumType::File);
printSettings.fileFormat(SRSReportFileFormat::PDF);
printSettings.overwriteFile(true);
printSettings.fileName(pdfPath);
// forzo che non vengano cambiati i parametri di stampa che gli passo io
controller.DEVparmLockDestinationProperties(true);
// suppress the parameter dialog
controller.parmShowDialog(false);
controller.parmArgs(args);
// start operation
controller.startOperation();
}
At this point, all you have to do is to create an Output Menu Item with the value "EPDocuGet" in the property "WebMenuItemName" and add this menu item to the EPCustInvoiceListPage form or whatever form you like.