Download Pdf in service level

In MarbleERP>Accounting> Invoices>invoice .


here, Download the invoice (OrginalPDF or CurrentPDF) done by screen level .

how can i archive service level for creating restAPI.

1 Like

Current transition

    <transition name="Invoice.pdf">
        <default-response url="${ec.web.getWebappRootUrl(false, null)}/fop/apps/${appRoot}/Accounting/Invoice/PrintInvoice" url-type="plain">
            <parameter name="invoiceId"/><parameter name="original"/><parameter name="filename" value="Invoice${original == 'true' ? 'Original' : 'Current'}-${invoiceId}.pdf"/></default-response>
    </transition>

This uses the ScreenFacade to render a url through the fop servlet to render a screen into a pdf.

Rest api file in your-component/services/example.xml

<?xml version="1.0" encoding="UTF-8"?>
<resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/rest-api-3.xsd"
        name="test" displayName="Test" version="1.0.0" description="Test">

    <resource name="file.pdf">
        <method type="get"><service name="ExampleServices.get#File"/></method>
    </resource>
</resource>

your-component/services/ExampleServices.xml
We’ll need to render the PrintInvoice screen in the xsl-fo render mode. A good example of how this is done outside of the normal context is sendEmailTemplate.grovvy line 276 through 302. Also see: moqui-framework/framework/service/org/moqui/impl/PrintServices.xml at 1c6984466243869cf973454272a075807afa7311 · moqui/moqui-framework · GitHub.

@Nepolean Sorry I ran out of time working on this. This is my current service hopefully this is good enough to get you started:

<services xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://moqui.org/xsd/service-definition-3.xsd">

    <service verb="get" noun="File">
        <in-parameters>
            <parameter name="invoiceId" required="true"/>
        </in-parameters>
        <actions>
            <script><![CDATA[
                ec.web.sendResourceResponse("${ec.web.getWebappRootUrl(false, null)}/fop/apps/${appRoot}/Accounting/Invoice/PrintInvoice?invoiceId=${invoiceId}")
                ]]></script>
        </actions>
    </service>

    <service verb="print" noun="ScreenDocument">
        <!-- org.moqui.impl.PrintServices.print#ScreenDocument -->
        <in-parameters>
            <parameter name="screenLocation" required="true" default-value="${ec.web.getWebappRootUrl(true, true)}/fop/apps/webroot/Accounting/Invoice/PrintInvoice"/>
            <parameter name="invoiceId"/>
            <parameter name="screenParameters" type="Map" default="[invoiceId:invoiceId]"/>
            <parameter name="screenParametersStr"><description>Groovy expression that evaluates to a Map</description></parameter>
            <parameter name="contentType" default-value="application/pdf"/>
            <parameter name="webappName" default-value="webroot"/>
        </in-parameters>
        <actions>
            <log level="warn" message="screenLocation: [${screenLocation}]"/>
            <script>
                import org.moqui.context.ExecutionContext
                import org.moqui.impl.screen.ScreenDefinition
                import javax.sql.rowset.serial.SerialBlob
                import javax.xml.transform.stream.StreamSource

                ExecutionContext ec = context.ec
                ScreenDefinition screedDef = ec.getScreen().getScreenDefinition(screenLocation)
                if (screedDef == null) {
                    ec.message.addError(ec.resource.expand('Screen not found at [${screenLocation}]',''))
                    return
                }
                Map parmMap = [:]
                if (screenParameters) parmMap.putAll(screenParameters)
                if (screenParametersStr) parmMap.putAll(ec.resource.expression(screenParametersStr, ""))
                context.putAll(parmMap)
                String xslFoText = ec.screen.makeRender().rootScreen(screenLocation).webappName(webappName).renderMode("xsl-fo").render()
                ByteArrayOutputStream baos = new ByteArrayOutputStream()
                ec.resource.xslFoTransform(new StreamSource(new StringReader(xslFoText)), null, baos, contentType)
                serialBlob = new SerialBlob(baos.toByteArray())

                ec.web.sendTextResponse(outWriter.toString())
                ec.web.sendBinaryResponse(serialBlob.binaryStream, contentType, null, null)

//                /* some test code to write a PDF to a file
//                File testFile = new File('test.pdf')
//                testFile.createNewFile()
//                FileOutputStream fos = new FileOutputStream(testFile)
//                org.apache.commons.io.IOUtils.write(baos.toByteArray(), fos)
//                */
            </script>
        </actions>
    </service>

</services>

hi michael,

is this working for you?

<service verb="get" noun="File">
        <in-parameters>
            <parameter name="invoiceId" required="true"/>
        </in-parameters>
        <actions>
            <script><![CDATA[
                ec.web.sendResourceResponse("${ec.web.getWebappRootUrl(false, null)}/fop/apps/${appRoot}/Accounting/Invoice/PrintInvoice?invoiceId=${invoiceId}")
                ]]></script>
        </actions>
    </service>

I get this exception or warn

10:48:24.559  WARN 89448984-122              o.moqui.i.c.WebFacadeImpl Sending not found response, resource not found at: /fop/apps/null/Accounting/Invoice/PrintInvoice

and i gave manually also

ec.web.sendResourceResponse("${ec.web.getWebappRootUrl(false, null)}/fop/apps/marble/Accounting/Invoice/PrintInvoice")

agin i get same thing

10:48:24.559  WARN 89448984-122              o.moqui.i.c.WebFacadeImpl Sending not found response, resource not found at: /fop/apps/marble/Accounting/Invoice/PrintInvoice

I didn’t end up getting it working, but with the examples and a bit more effort it should work.

Hi Micheal,

I have done this with some of the changes

${ec.web.getWebappRootUrl(true,null)}


<service verb="get" noun="File">
        <in-parameters>
            <parameter name="invoiceId" required="true"/>
        </in-parameters>
        <actions>
            <script><![CDATA[   
ec.web.sendResourceResponse("${ec.web.getWebappRootUrl(true,null)}/fop/apps/${appRoot}/Accounting/Invoice/PrintInvoice?invoiceId=${invoiceId}")
                ]]></script>
        </actions>
 </service>

And i have added Permission for this screen

component://SimpleScreens/screen/SimpleScreens/Accounting/Invoice/PrintInvoice.xml

 <artifactGroups artifactGroupId="AllUser_Print_Invoice" description="All App User">
        <artifacts artifactName="component://SimpleScreens/screen/SimpleScreens/Accounting/Invoice/PrintInvoice.xml" artifactTypeEnumId="AT_XML_SCREEN" inheritAuthz="Y"/>
    </artifactGroups>
    <moqui.security.ArtifactAuthz artifactAuthzId="AllUser_PrintInvoiceScreen" userGroupId="ALL_USERS" artifactGroupId="AllUser_Print_Invoice"
                                  authzTypeEnumId="AUTHZT_ALWAYS" authzActionEnumId="AUTHZA_ALL"/>

and i give permission for this service also

mantle.account.InvoiceServices.get#InvoicePrintInfo


 <service verb="get" noun="InvoicePrintInfo" authenticate="anonymous-all">
.
.
.
</service>

can we resolve this ?

12:03:31.724 ERROR p89448984-24               o.moqui.i.w.MoquiServlet Internal error processing request: java.lang.IllegalStateException: getOutputStream() already called
java.lang.IllegalStateException: getOutputStream() already called
	at org.moqui.impl.webapp.ElasticRequestLogFilter$CountingHttpServletResponseWrapper.getWriter(ElasticRequestLogFilter.groovy:238) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at org.moqui.impl.context.WebFacadeImpl.sendJsonResponseInternal(WebFacadeImpl.groovy:724) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at org.moqui.impl.context.WebFacadeImpl.sendJsonResponse(WebFacadeImpl.groovy:675) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at org.moqui.impl.screen.ScreenRenderImpl.sendJsonRedirect(ScreenRenderImpl.groovy:229) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at org.moqui.impl.screen.ScreenRenderImpl.internalRender(ScreenRenderImpl.groovy:593) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at org.moqui.impl.screen.ScreenRenderImpl.render(ScreenRenderImpl.groovy:170) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at org.moqui.impl.webapp.MoquiServlet.service(MoquiServlet.groovy:118) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:750) ~[moqui_temp4602013066928164530WEB-INF_lib_javax.servlet-api-4.0.1.jar.:4.0.1]
	at org.eclipse.jetty.servlet.ServletHolder$NotAsync.service(ServletHolder.java:1410) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1630) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:170) ~[moqui_temp11144346200299248838execlib_websocket-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1600) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.moqui.impl.webapp.ElasticRequestLogFilter.doFilter(ElasticRequestLogFilter.groovy:110) ~[moqui_temp6398064182749215564WEB-INF_lib_moqui-framework-3.0.0.jar.:3.0.0]
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1600) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:506) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578) ~[moqui_temp12330524320238619388execlib_jetty-security-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1571) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1378) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:463) ~[moqui_temp17361578872750249555execlib_jetty-servlet-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1544) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1300) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:717) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.Server.handle(Server.java:562) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.HttpChannel.lambda$handle$0(HttpChannel.java:505) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:762) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:497) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:282) ~[moqui_temp15025907944839319306execlib_jetty-server-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:319) ~[moqui_temp6860988247558886789WEB-INF_lib_jetty-io-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100) ~[moqui_temp6860988247558886789WEB-INF_lib_jetty-io-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53) ~[moqui_temp6860988247558886789WEB-INF_lib_jetty-io-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:412) ~[moqui_temp6022654133703657255WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:381) ~[moqui_temp6022654133703657255WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:268) ~[moqui_temp6022654133703657255WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.lambda$new$0(AdaptiveExecutionStrategy.java:138) ~[moqui_temp6022654133703657255WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:407) ~[moqui_temp6022654133703657255WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:894) ~[moqui_temp6022654133703657255WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1038) ~[moqui_temp6022654133703657255WEB-INF_lib_jetty-util-10.0.9.jar.:10.0.9]
	at java.lang.Thread.run(Thread.java:829) ~[?:?]