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.