Example of Using Custom Data Sources for Advanced Printing

When setting up an advanced template, you can use multiple data sources. This example shows how to use a JSON object and an XML file together with NetSuite data from a saved search to create a packing slip for a customer.

The JSON object provides customer names and language preferences.

          {"customers":[
    {"firstName":"John", "lastName":"Doe", "language":"English"},
    {"firstName":"Anna", "lastName":"Smith", "language":"Spanish"},
    {"firstName":"Peter", "lastName":"Jones", "language": "English"}
]} 

        

The XML file provides a holiday greeting in the customer’s preferred language.

          <?xml version="1.0" encoding="UTF-8"?>
<message>
    <engbody>Happy holidays! We are closed from Dec 22 - Jan 3. Take advantage of our great prices before Christmas!</engbody>
    <spbody>¡Feliz Navidad! Estamos cerrados del 22 de diciembre al 3 de enero. Aproveche nuestros excelentes precios antes de Navidad!</spbody>
</message> 

        

The advanced PDF/HTML template is edited in markup source view to incorporate the XML file and JSON object.

          <?xml version="1.0"?>
<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdf>
<head>
<macrolist>
    <macro id="nlheader">

    <!-- XML Part -->
    <#if XML?has_content>
        <p style="color: blue">
        <#if .locale?starts_with("es_")>
            ${XML.message.spbody}
        <#else>
            ${XML.message.engbody}
        </#if>
        </p>
    </#if>
    <!-- End XML Part -->

    <table class="header">
        <tr>
            <td rowspan="3">
                <span class="addressheader">${‌companyInformation.companyName}</span><br />
                <span class="addressheader">${‌companyInformation.addressText}</span></td>
            <td align="right"><span class="title">${record@title}</span></td>
        </tr>
        <tr>
            <td align="right"><span class="number">#${‌record.tranid}</span></td>
        </tr>
        <tr>
            <td align="right">${‌record.trandate}</td>
        </tr>
    </table>
    </macro>
</macrolist>

<style type="text/css">
    table {
        font-family: sans-serif;
        font-size: 9pt;
        table-layout: fixed;
    }
    th {
        font-weight: bold;
        font-size: 8pt;
        vertical-align: middle;
        padding: 5px 6px 3px;
        background-color: #e3e3e3;
    }
    td {
        padding: 4px 6px;
    }
         td.addressheader {
            font-size: 8pt;
            padding-top: 6px;
            padding-bottom: 2px;
         }
         span.number {
            font-size: 16pt;
         }</style>
</head>

<body header="nlheader" header-height="20%" padding="0.5in 0.5in 0.5in 0.5in" size="Letter">
    <table style="width: 100%; margin-top: 10px;">
        <tr>
            <td colspan="3" style="font-size: 8pt; font-weight: bold;">${record.billaddress@label}</td>
            <td colspan="3" style="font-size: 8pt; font-weight: bold;">${record.shipaddress@label}</td>
            <td colspan="5" style="font-size: 12pt; background-color: #e3e3e3; font-weight: bold;">${record.total@label?upper_case}</td>
        </tr>
           <tr>
            <td colspan="3" style="padding: 0;">${‌record.billaddress}</td>
            <td colspan="3" style="padding: 0;">${‌record.shipaddress}</td>
            <td align="right" colspan="5">${‌record.total}</td>
        </tr>
    </table>

    <table style="width: 100%; margin-top: 10px;">
        <tr>
            <th>${record.paymentmethod@label}</th>
            <th>${record.otherrefnum@label}</th>
            <th>${record.shipmethod@label}</th>
            <th>${record.shipdate@label}</th>
        </tr>
        <tr>
            <td style="padding-top: 2px;">${‌record.paymentmethod}</td>
            <td style="padding-top: 2px;">${‌record.otherrefnum}</td>
            <td style="padding-top: 2px;">${‌record.shipmethod}</td>
            <td style="padding-top: 2px;">${‌record.shipdate}</td>
        </tr>
    </table>

    <#if record.item?has_content>
        <table style="width: 100%; margin-top: 10px;">

        <!-- Start Items -->
        <#list record.item as item>
        <#if item_index==0>
            <thead>
                <tr>
                    <th align="center" colspan="3">${item.quantity@label}</th>
                    <th colspan="12">${item.item@label}</th>
                    <th align="right" colspan="4">${item.rate@label}</th>
                    <th align="right" colspan="4">${item.amount@label}</th>
                </tr>
            </thead>
        </#if>
        <tr>
            <td align="center" colspan="3" line-height="150%">${‌item.quantity}</td>
            <td colspan="12">
                <span style="font-weight: bold; line-height: 150%;">${‌item.item}</span>
                <br />
                ${‌item.description}
            </td>
            <td align="right" colspan="4">${‌item.rate}</td>
            <td align="right" colspan="4">${‌item.amount}</td>
        </tr>
    </#list>
    <!-- End Items -->

    </table>

    <hr style="width: 100%; color: #d3d3d3; background-color: #d3d3d3; height: 1px;" />
    </#if>

    <table style="page-break-inside: avoid; width: 100%; margin-top: 10px;">
        <tr>
            <td colspan="4">&nbsp;</td>
            <td align="right" style="font-weight: bold;">${record.subtotal@label}</td>
            <td align="right">${‌record.subtotal}</td>
        </tr>
        <tr>
            <td colspan="4">&nbsp;</td>
            <td align="right" style="font-weight: bold;">
                ${record.taxtotal@label}
                ${‌record.taxrate}%)
            </td>
            <td align="right">${‌record.taxtotal}</td>
        </tr>
        <tr style="background-color: #e3e3e3; line-height: 200%;">
            <td background-color="#ffffff" colspan="4">&nbsp;</td>
            <td align="right" style="font-weight: bold;">${record.total@label}</td>
            <td align="right">${‌record.total}</td>
        </tr>
    </table>

<!-- JSON Part -->
    <#if JSON?has_content>
        <p style="color: red">
            JSON data:
        </p>
        <table style="width: 100%; margin-top: 10px;">
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Language</th>
                </tr>
            </thead>
            <#list JSON.customers as item>
                <tr>
                    <td>${‌item.firstName}</td>
                    <td>${‌item.lastName}</td>
                    <td>${‌item.language}</td>
                </tr>
            </#list>
        </table>
    </#if>
<!-- End JSON Part -->

<!-- Saved Search Part -->
    <#if SEARCH?has_content>
        <p style="color: green">
            Saved Search results:
        </p>
        <table style="width: 100%; margin-top: 10px;">
            <thead>
                <tr>
                    <th>trandate</th>
                    <th>amount</th>
                    <th>entity</th>
                </tr>
            </thead>
            <#list SEARCH as item>
                <tr>
                    <td>${‌item.trandate}</td>
                    <td>${‌item.amount}</td>
                    <td>${‌item.entity}</td>
                </tr>
            </#list>
        </table>
    </#if>
<!-- End Saved Search Part -->

</body>
</pdf> 

        

The SuiteScript file incorporates the JSON object and XML file with NetSuite data and the advanced template.

          /** *
@NApiVersion 2.x 
*/
require(['N/render', 'N/file', 'N/record', 'N/search'],
    function(render, file, record, search) {
        // load JSON file from file cabinet
        var jsonFile = file.load({
            id: #json_content_file_cabinet_id#
        });
        // load XML file from file cabinet
        var xmlFile = file.load({
            id: #xml_content_file_cabinet_id#
        });
        // load printing template file from cabinet
        var templateFile = file.load({
            id: #template_content_file_cabinet_id#
        });

        var renderer = render.create();

        renderer.templateContent = templateFile.getContents();

        // add JSON custom data source
        renderer.addCustomDataSource({
            alias: "JSON",
            format: render.DataSource.JSON,
            data: jsonFile.getContents()
        });

        // add XML custom data source
        renderer.addCustomDataSource({
            alias: "XML",
            format: render.DataSource.XML_STRING,
            data: xmlFile.getContents()
        });

        // add search data source
        var rs = search.create({
            type: search.Type.TRANSACTION,
            columns: ['trandate', 'amount', 'entity'],
            filters: []
        }).run();
        var results = rs.getRange(0, 1000);
        renderer.addSearchResults({
            templateName: 'SEARCH', 
            searchResult: results
        });

        // add record data source
        var objRecord = record.create({
            type: record.Type.SALES_ORDER
        });
        renderer.addRecord({
            templateName: 'record',
            record: objRecord
        });

        // render PDF file and save
        var invoicePdf = renderer.renderAsPdf();
            invoicePdf.folder = #file_cabinet_folder_id#;
            var id = invoicePdf.save();
        }); 

        

The output of this example resembles the following.

Sample Sales Order PDF output.

Related Topics

General Notices