0

In NetSuite, some of our Products have MSDS documentation (in the form of PDF files) attached to the record via a Custom Item Field whose "Type" is set to Document. When printing Invoices, we would like to automatically print out any associated MSDS PDF files as well. Is this possible with SuiteScript or any of the other services that extend NetSuite?

(For what it's worth, we know there's an option for printing MSDS documents as part of a Bill of Materials, but printing MSDS docs along with an Invoice doesn't seem to native to NetSuite.)

tedxas
  • 11
  • 4
  • You mean you want to print the Pdf document embedded in the PDF of the record or you want to print PDF as a separate file? – prasun Sep 16 '15 at 05:34
  • Essentially, I need to print an invoice, iterate through each item on the invoice, and print any PDFs that are associated with those items. It doesn't matter if the invoice and associated documents are merged into a single file or printed in succession. The only requirement is that the PDFs relevant to the Invoice Items are printed along with the Invoice in some way. Thanks, in advance, for any help you can offer! – tedxas Sep 16 '15 at 13:18
  • When you print a record in Netsuite you get a pdf or html, do you mean that you want to get pdf mailed or open in browser tabs?? – prasun Sep 16 '15 at 18:02
  • Standard behavior allows a user to generate an Invoice in PDF format for printing later. We would like for the Invoice PDF to have all of the associated MSDS documents merged into it. – tedxas Sep 16 '15 at 18:44

2 Answers2

1

Luckily you can probably do this with Advanced HTML/PDF templates. Your MSDS needs to be in a folder that is accessible to the person doing the printing.

Check out http://bfo.com/products/report/docs/tags/tags/pdfset.html Then your normal invoice would be inside a pdf element something like:

<?xml version="1.0"?>
<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdfset>
<pdf> <!-- normal invoice here -->
<head>
...
</pdf>

<#assign msdsSeen='' /> <!-- if can use javascript hash as a set then great. othewise use string -->
<#list record.item as item>
<#if item.custcol_msds_link?has_content><!-- needs to be sourced from item -->
<#assign msdsKey='_'+item.custcol_msds_link+'_' />
<#if msdsSeen?indexOf(msdsKey) == -1>
<#assign msdsSeen=msdsSeen + msdsKey />
<pdf src="${item.custcol_msds_link}" />
</#if> <!-- msds not linked -->
</#if> <!-- has msds -->
</#list>
bknights
  • 14,408
  • 2
  • 18
  • 31
  • Very, very helpful! I am getting this error when I attempt to save the template: _The template cannot be saved due to the following errors: The value of attribute "src" associated with an element type "pdf" must not contain the '<' character._ I've rendered the ${item.custcol_msds_link} content and verified that it is a working URL so I don't know where it is getting the '<' character. Any ideas? Many thanks again. – tedxas Sep 14 '15 at 21:05
  • You'd have to paste your code for me to comment but check for quote character agreement; proper closing tags etc. If everything balances then one easy thing to do would be instead of the `` to ensure the values are being interpreted correctly by the template. – bknights Sep 14 '15 at 22:34
  • I can see the rendered URL to the PDF using this code: `<#assign msdsSeen='' /> <#list record.item as item> <#if item.custcol_msds?has_content> <#assign msdsKey='_'+item.custcol_msds+'_' /> <#if msdsSeen?index_of(msdsKey) == -1> <#assign msdsSeen=msdsSeen + msdsKey /> ${item.custcol_msds} #if> #if> #list>` – tedxas Sep 15 '15 at 13:35
  • And here's the value of item.custcol_msds: https://system.sandbox.netsuite.com/core/media/media.nl? id=85132&c=951739&h=2fc8ef5a1c00740e41fd&_xt=.pdf – tedxas Sep 15 '15 at 13:40
  • what about this: `` – bknights Sep 15 '15 at 14:09
  • Ah! I see where you're going. Advancted PDF/HTML templates won't let me save the template, however: "The template cannot be saved due to the following errors: Error reading external PDF from {random image file is, literally, displayed here} java.net.MalformedURLException" Looks like NetSuite runs a unit test before saving and, in my case, it defaults to a seemingly-random image file. Wondering if it would complete the preview/save if a conditional could check for the filetype first? – tedxas Sep 15 '15 at 15:28
  • Argh! OK, I tried it by simply hardcoding the URL. Looks like it can't retrieve a remote file (this is the encoded URL. I also tried it unencoded)? The template cannot be saved due to the following errors: Error reading external PDF from https%3A%2F%2Fsystem.sandbox.netsuite.com%2Fcore%2Fmedia%2Fmedia.nl%3Fid%3D85132%26c%3D951739%26h%3D2fc8ef5a1c00740e41fd%26_xt%3D.pdf java.net.MalformedURLException – tedxas Sep 15 '15 at 18:07
  • What if you put the template into source code mode and leave it there. It sounds like you may be getting your errors when you try to use the WYSIWYG view – bknights Sep 15 '15 at 22:20
  • Oh well that doesn't work either. Unfortunately though I've used this several times I've run it through a script. At this point I'd add a new "Print with MSDS" button on the invoice. and just script it. – bknights Sep 15 '15 at 22:32
1

If PDFSET does not works well, you can do the merging using a client application in a server side language like (eg- Java,Node.js).

Write a RESTlet to grab PDFs of record and the attached PDFs. RESTlet will return the PDF in base64 format.

Next, step would be to fetch the PDFs in client application and decode it from base64 and create PDFs. Then using process APIs in client application merge the PDFs using pdftk

PDFtk is a command line tool so you can fairly invoke it using process APIs in your programming language

Below is an example of process APIs in Node.js

var spawn = require('child_process').spawn;
var pdftk = spawn('pdftk', "invoice.pdf attachment.pdf cat output out1.pdf".split(" "));

    pdftk.on('close', function (code) {
        if(code !==0){
            return console.log('Failed PDF with code: ' + code);
        }
        return console.log ('All good');
    });

Below is a Java snippet of Process APIs

Process process = new ProcessBuilder("pdftk","invoice.pdf", "attachment.pdf", "cat", "output", "merged.pdf").start();
                errorStream = process.getErrorStream();
                errorMessage = readInputStream(errorStream);
                if(process.exitValue() == 0) {
                    trace("successful :)");
                }
prasun
  • 7,073
  • 9
  • 41
  • 59