Printing PDF in NetSuite with selection of Multiple Transaction Records












0















Is there a way to have a selection of many transactions printed into a single PDF document? I only see two options which seem to have significant drawbacks:



1) Load individual records into each of their own nlobjTemplateRenderer objects, and then stitch them all together within tags before rendering to PDF. Has a limit of less than 50 transactions depending on other actions taken when used within a Suitelet.



2) Do a search based upon internals IDs of selected records and pass the search results into a nlobjTemplateRenderer object. This method, based upon existing documentation, does not lead me to believe that it will properly display records with line data as result columns completely within a single document.



It almost seems like my best option is #1, but to split the desired transaction up into groups of 5-10 records and repeatedly calling a Suitelet with the small groups in the hopes of meeting the 45-second timeout limit of nlapiRequestURL before stitching together all of the results and returning the final PDF document. I pretty much see a basic form of that as the following:



// initial called function that will return completed PDF document file
function buildPdfFromRecords() {
var pdfBuilder = ;
var selectedIDs = ;
var chunks = chunkify(selectedIDs, 10);
for (var c = 0; c < chunks.length; c++) {
var param = { id_list : JSON.stringify(chunks[s]) };
var result = nlapiRequestURL(url, param).getBody();
pdfBuilder.push(result);
}
var finalXML = "<pdfset>" + pdfBuilder.join("") + "</pdfset>";
var pdfDoc = nlapiXMLToPDF(finalXML);
}

// function in suitelet called by url to handle individual groups of record internal IDs
// to mitigate scripting governance limits
function handleRecordIdListRequest(request, reponse) {
var idList = JSON.parse(request.getParameter("id_list"));
var templateXML = nlapiLoadRecord("template.txt").getValue();
var pdfBuilder = ;
for (var i = 0; i < idList.length; i++) {
var transRecord = nlapiLoadRecord("recordtype", idList[i]);
var renderer = nlapiCreateTemplateRenderer();
renderer.setTemplate(templateXML);
renderer.addRecord("record", transRecord);
pdfBuilder.push(renderer.renderToString());
}
response.write(pdfBuilder.join(""));
}


If this is really the best way, then so be it, but I'm hoping there's a more elegant solution out there that I'm just not seeing.










share|improve this question





























    0















    Is there a way to have a selection of many transactions printed into a single PDF document? I only see two options which seem to have significant drawbacks:



    1) Load individual records into each of their own nlobjTemplateRenderer objects, and then stitch them all together within tags before rendering to PDF. Has a limit of less than 50 transactions depending on other actions taken when used within a Suitelet.



    2) Do a search based upon internals IDs of selected records and pass the search results into a nlobjTemplateRenderer object. This method, based upon existing documentation, does not lead me to believe that it will properly display records with line data as result columns completely within a single document.



    It almost seems like my best option is #1, but to split the desired transaction up into groups of 5-10 records and repeatedly calling a Suitelet with the small groups in the hopes of meeting the 45-second timeout limit of nlapiRequestURL before stitching together all of the results and returning the final PDF document. I pretty much see a basic form of that as the following:



    // initial called function that will return completed PDF document file
    function buildPdfFromRecords() {
    var pdfBuilder = ;
    var selectedIDs = ;
    var chunks = chunkify(selectedIDs, 10);
    for (var c = 0; c < chunks.length; c++) {
    var param = { id_list : JSON.stringify(chunks[s]) };
    var result = nlapiRequestURL(url, param).getBody();
    pdfBuilder.push(result);
    }
    var finalXML = "<pdfset>" + pdfBuilder.join("") + "</pdfset>";
    var pdfDoc = nlapiXMLToPDF(finalXML);
    }

    // function in suitelet called by url to handle individual groups of record internal IDs
    // to mitigate scripting governance limits
    function handleRecordIdListRequest(request, reponse) {
    var idList = JSON.parse(request.getParameter("id_list"));
    var templateXML = nlapiLoadRecord("template.txt").getValue();
    var pdfBuilder = ;
    for (var i = 0; i < idList.length; i++) {
    var transRecord = nlapiLoadRecord("recordtype", idList[i]);
    var renderer = nlapiCreateTemplateRenderer();
    renderer.setTemplate(templateXML);
    renderer.addRecord("record", transRecord);
    pdfBuilder.push(renderer.renderToString());
    }
    response.write(pdfBuilder.join(""));
    }


    If this is really the best way, then so be it, but I'm hoping there's a more elegant solution out there that I'm just not seeing.










    share|improve this question



























      0












      0








      0








      Is there a way to have a selection of many transactions printed into a single PDF document? I only see two options which seem to have significant drawbacks:



      1) Load individual records into each of their own nlobjTemplateRenderer objects, and then stitch them all together within tags before rendering to PDF. Has a limit of less than 50 transactions depending on other actions taken when used within a Suitelet.



      2) Do a search based upon internals IDs of selected records and pass the search results into a nlobjTemplateRenderer object. This method, based upon existing documentation, does not lead me to believe that it will properly display records with line data as result columns completely within a single document.



      It almost seems like my best option is #1, but to split the desired transaction up into groups of 5-10 records and repeatedly calling a Suitelet with the small groups in the hopes of meeting the 45-second timeout limit of nlapiRequestURL before stitching together all of the results and returning the final PDF document. I pretty much see a basic form of that as the following:



      // initial called function that will return completed PDF document file
      function buildPdfFromRecords() {
      var pdfBuilder = ;
      var selectedIDs = ;
      var chunks = chunkify(selectedIDs, 10);
      for (var c = 0; c < chunks.length; c++) {
      var param = { id_list : JSON.stringify(chunks[s]) };
      var result = nlapiRequestURL(url, param).getBody();
      pdfBuilder.push(result);
      }
      var finalXML = "<pdfset>" + pdfBuilder.join("") + "</pdfset>";
      var pdfDoc = nlapiXMLToPDF(finalXML);
      }

      // function in suitelet called by url to handle individual groups of record internal IDs
      // to mitigate scripting governance limits
      function handleRecordIdListRequest(request, reponse) {
      var idList = JSON.parse(request.getParameter("id_list"));
      var templateXML = nlapiLoadRecord("template.txt").getValue();
      var pdfBuilder = ;
      for (var i = 0; i < idList.length; i++) {
      var transRecord = nlapiLoadRecord("recordtype", idList[i]);
      var renderer = nlapiCreateTemplateRenderer();
      renderer.setTemplate(templateXML);
      renderer.addRecord("record", transRecord);
      pdfBuilder.push(renderer.renderToString());
      }
      response.write(pdfBuilder.join(""));
      }


      If this is really the best way, then so be it, but I'm hoping there's a more elegant solution out there that I'm just not seeing.










      share|improve this question
















      Is there a way to have a selection of many transactions printed into a single PDF document? I only see two options which seem to have significant drawbacks:



      1) Load individual records into each of their own nlobjTemplateRenderer objects, and then stitch them all together within tags before rendering to PDF. Has a limit of less than 50 transactions depending on other actions taken when used within a Suitelet.



      2) Do a search based upon internals IDs of selected records and pass the search results into a nlobjTemplateRenderer object. This method, based upon existing documentation, does not lead me to believe that it will properly display records with line data as result columns completely within a single document.



      It almost seems like my best option is #1, but to split the desired transaction up into groups of 5-10 records and repeatedly calling a Suitelet with the small groups in the hopes of meeting the 45-second timeout limit of nlapiRequestURL before stitching together all of the results and returning the final PDF document. I pretty much see a basic form of that as the following:



      // initial called function that will return completed PDF document file
      function buildPdfFromRecords() {
      var pdfBuilder = ;
      var selectedIDs = ;
      var chunks = chunkify(selectedIDs, 10);
      for (var c = 0; c < chunks.length; c++) {
      var param = { id_list : JSON.stringify(chunks[s]) };
      var result = nlapiRequestURL(url, param).getBody();
      pdfBuilder.push(result);
      }
      var finalXML = "<pdfset>" + pdfBuilder.join("") + "</pdfset>";
      var pdfDoc = nlapiXMLToPDF(finalXML);
      }

      // function in suitelet called by url to handle individual groups of record internal IDs
      // to mitigate scripting governance limits
      function handleRecordIdListRequest(request, reponse) {
      var idList = JSON.parse(request.getParameter("id_list"));
      var templateXML = nlapiLoadRecord("template.txt").getValue();
      var pdfBuilder = ;
      for (var i = 0; i < idList.length; i++) {
      var transRecord = nlapiLoadRecord("recordtype", idList[i]);
      var renderer = nlapiCreateTemplateRenderer();
      renderer.setTemplate(templateXML);
      renderer.addRecord("record", transRecord);
      pdfBuilder.push(renderer.renderToString());
      }
      response.write(pdfBuilder.join(""));
      }


      If this is really the best way, then so be it, but I'm hoping there's a more elegant solution out there that I'm just not seeing.







      javascript netsuite suitescript bfo






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 '18 at 17:38







      Michael McCauley

















      asked Nov 19 '18 at 21:23









      Michael McCauleyMichael McCauley

      2281318




      2281318
























          2 Answers
          2






          active

          oldest

          votes


















          0














          There are a number of pieces you can stitch together to get this done.




          1. In the post handler of your Suitelet use the N/task library to schedule a map/reduce task. The task.submit method returns a taskId that you can use to monitor the progress of your job. Once your UI has a taskId it can periodically check to see if the task has completed. When complete you can show the generated .pdf. You could also let the user know that the pdf might take a few minutes to generate and offer to email it to them when done. Here's a snippet that schedules a scheduled script with parameters:





            const mrTask = task.create({
          taskType:task.TaskType.SCHEDULED_SCRIPT,
          scriptId:'customscript_knsi_batch_products',
          deploymentId: deploymentId,
          params: {
          custscript_knsi_batch_operator:user.id,
          custscript_knsi_batch_sourcing: sourcingId
          }
          });

          try{
          const taskId = mrTask.submit();
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:true,
          message:'queued as task: '+ taskId
          }));
          }catch(e){
          log.error({
          title:'triggering '+ sourcingId +' for '+ user.email,
          details:(e.message || e.toString()) + (e.getStackTrace ? (' n n' + e.getStackTrace().join(' n')) : '')
          });
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:false,
          message:'An error occured scheduling this scriptn'+e.message
          }));






          1. Use a Map/Reduce script where your map method generates and returns each transaction's pdf file url. You'll only have a single key so that the results of all map stages coalesce into a single reduce.

          2. In the reduce step you can generate open and close pdf files as necessary and put their references into your mapped array of pdfs.

          3. Use the pdfset to bind all your individual pdfs into a single pdf:





          function renderSet(opts){
          var tpl = ['<?xml version="1.0"?>','<pdfset>'];

          opts.files.forEach(function(id, idx){
          const partFile = file.load({id:id});
          var pdf_fileURL = xml.escape({xmlText:partFile.url});
          tpl.push("<pdf src='" + pdf_fileURL + "'/>");
          });

          tpl.push("</pdfset>");

          log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('n')})});

          return render.xmlToPdf({
          xmlString: tpl.join('n')
          });
          }








          share|improve this answer
























          • I like this idea, and I've been testing it out. But now I'm getting weird errors from the XMLToPDF parser where it says "Error Parsing XML" and gives back the url of the first PDF added, but the URL always starts with "system.netsuite.com", regardless if I append "system.netsuite.com" to the beginning of the file URL or not. And I've verified that the ampersands are indeed escaped.

            – Michael McCauley
            Nov 20 '18 at 22:46











          • Oh, nevermind that last comment. I forgot to set the component PDF docs to "Is Online". Making that change solved the little issue there.

            – Michael McCauley
            Nov 20 '18 at 22:59



















          0














          Why not use a Map Reduce script to generate the PDF? Does it need to be a Suitelet?






          share|improve this answer
























          • I'm starting with a Suitelet in order to generate an interface for users. Also, I'm unfamiliar with the map/reduce script type, I haven't had enough time to check it out. Are you able to pass it parameters and get a response back that allows you present a PDF to a user in the browser tab? Because that's why I'm using Suitelets.

            – Michael McCauley
            Nov 20 '18 at 15:45











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382843%2fprinting-pdf-in-netsuite-with-selection-of-multiple-transaction-records%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          There are a number of pieces you can stitch together to get this done.




          1. In the post handler of your Suitelet use the N/task library to schedule a map/reduce task. The task.submit method returns a taskId that you can use to monitor the progress of your job. Once your UI has a taskId it can periodically check to see if the task has completed. When complete you can show the generated .pdf. You could also let the user know that the pdf might take a few minutes to generate and offer to email it to them when done. Here's a snippet that schedules a scheduled script with parameters:





            const mrTask = task.create({
          taskType:task.TaskType.SCHEDULED_SCRIPT,
          scriptId:'customscript_knsi_batch_products',
          deploymentId: deploymentId,
          params: {
          custscript_knsi_batch_operator:user.id,
          custscript_knsi_batch_sourcing: sourcingId
          }
          });

          try{
          const taskId = mrTask.submit();
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:true,
          message:'queued as task: '+ taskId
          }));
          }catch(e){
          log.error({
          title:'triggering '+ sourcingId +' for '+ user.email,
          details:(e.message || e.toString()) + (e.getStackTrace ? (' n n' + e.getStackTrace().join(' n')) : '')
          });
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:false,
          message:'An error occured scheduling this scriptn'+e.message
          }));






          1. Use a Map/Reduce script where your map method generates and returns each transaction's pdf file url. You'll only have a single key so that the results of all map stages coalesce into a single reduce.

          2. In the reduce step you can generate open and close pdf files as necessary and put their references into your mapped array of pdfs.

          3. Use the pdfset to bind all your individual pdfs into a single pdf:





          function renderSet(opts){
          var tpl = ['<?xml version="1.0"?>','<pdfset>'];

          opts.files.forEach(function(id, idx){
          const partFile = file.load({id:id});
          var pdf_fileURL = xml.escape({xmlText:partFile.url});
          tpl.push("<pdf src='" + pdf_fileURL + "'/>");
          });

          tpl.push("</pdfset>");

          log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('n')})});

          return render.xmlToPdf({
          xmlString: tpl.join('n')
          });
          }








          share|improve this answer
























          • I like this idea, and I've been testing it out. But now I'm getting weird errors from the XMLToPDF parser where it says "Error Parsing XML" and gives back the url of the first PDF added, but the URL always starts with "system.netsuite.com", regardless if I append "system.netsuite.com" to the beginning of the file URL or not. And I've verified that the ampersands are indeed escaped.

            – Michael McCauley
            Nov 20 '18 at 22:46











          • Oh, nevermind that last comment. I forgot to set the component PDF docs to "Is Online". Making that change solved the little issue there.

            – Michael McCauley
            Nov 20 '18 at 22:59
















          0














          There are a number of pieces you can stitch together to get this done.




          1. In the post handler of your Suitelet use the N/task library to schedule a map/reduce task. The task.submit method returns a taskId that you can use to monitor the progress of your job. Once your UI has a taskId it can periodically check to see if the task has completed. When complete you can show the generated .pdf. You could also let the user know that the pdf might take a few minutes to generate and offer to email it to them when done. Here's a snippet that schedules a scheduled script with parameters:





            const mrTask = task.create({
          taskType:task.TaskType.SCHEDULED_SCRIPT,
          scriptId:'customscript_knsi_batch_products',
          deploymentId: deploymentId,
          params: {
          custscript_knsi_batch_operator:user.id,
          custscript_knsi_batch_sourcing: sourcingId
          }
          });

          try{
          const taskId = mrTask.submit();
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:true,
          message:'queued as task: '+ taskId
          }));
          }catch(e){
          log.error({
          title:'triggering '+ sourcingId +' for '+ user.email,
          details:(e.message || e.toString()) + (e.getStackTrace ? (' n n' + e.getStackTrace().join(' n')) : '')
          });
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:false,
          message:'An error occured scheduling this scriptn'+e.message
          }));






          1. Use a Map/Reduce script where your map method generates and returns each transaction's pdf file url. You'll only have a single key so that the results of all map stages coalesce into a single reduce.

          2. In the reduce step you can generate open and close pdf files as necessary and put their references into your mapped array of pdfs.

          3. Use the pdfset to bind all your individual pdfs into a single pdf:





          function renderSet(opts){
          var tpl = ['<?xml version="1.0"?>','<pdfset>'];

          opts.files.forEach(function(id, idx){
          const partFile = file.load({id:id});
          var pdf_fileURL = xml.escape({xmlText:partFile.url});
          tpl.push("<pdf src='" + pdf_fileURL + "'/>");
          });

          tpl.push("</pdfset>");

          log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('n')})});

          return render.xmlToPdf({
          xmlString: tpl.join('n')
          });
          }








          share|improve this answer
























          • I like this idea, and I've been testing it out. But now I'm getting weird errors from the XMLToPDF parser where it says "Error Parsing XML" and gives back the url of the first PDF added, but the URL always starts with "system.netsuite.com", regardless if I append "system.netsuite.com" to the beginning of the file URL or not. And I've verified that the ampersands are indeed escaped.

            – Michael McCauley
            Nov 20 '18 at 22:46











          • Oh, nevermind that last comment. I forgot to set the component PDF docs to "Is Online". Making that change solved the little issue there.

            – Michael McCauley
            Nov 20 '18 at 22:59














          0












          0








          0







          There are a number of pieces you can stitch together to get this done.




          1. In the post handler of your Suitelet use the N/task library to schedule a map/reduce task. The task.submit method returns a taskId that you can use to monitor the progress of your job. Once your UI has a taskId it can periodically check to see if the task has completed. When complete you can show the generated .pdf. You could also let the user know that the pdf might take a few minutes to generate and offer to email it to them when done. Here's a snippet that schedules a scheduled script with parameters:





            const mrTask = task.create({
          taskType:task.TaskType.SCHEDULED_SCRIPT,
          scriptId:'customscript_knsi_batch_products',
          deploymentId: deploymentId,
          params: {
          custscript_knsi_batch_operator:user.id,
          custscript_knsi_batch_sourcing: sourcingId
          }
          });

          try{
          const taskId = mrTask.submit();
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:true,
          message:'queued as task: '+ taskId
          }));
          }catch(e){
          log.error({
          title:'triggering '+ sourcingId +' for '+ user.email,
          details:(e.message || e.toString()) + (e.getStackTrace ? (' n n' + e.getStackTrace().join(' n')) : '')
          });
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:false,
          message:'An error occured scheduling this scriptn'+e.message
          }));






          1. Use a Map/Reduce script where your map method generates and returns each transaction's pdf file url. You'll only have a single key so that the results of all map stages coalesce into a single reduce.

          2. In the reduce step you can generate open and close pdf files as necessary and put their references into your mapped array of pdfs.

          3. Use the pdfset to bind all your individual pdfs into a single pdf:





          function renderSet(opts){
          var tpl = ['<?xml version="1.0"?>','<pdfset>'];

          opts.files.forEach(function(id, idx){
          const partFile = file.load({id:id});
          var pdf_fileURL = xml.escape({xmlText:partFile.url});
          tpl.push("<pdf src='" + pdf_fileURL + "'/>");
          });

          tpl.push("</pdfset>");

          log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('n')})});

          return render.xmlToPdf({
          xmlString: tpl.join('n')
          });
          }








          share|improve this answer













          There are a number of pieces you can stitch together to get this done.




          1. In the post handler of your Suitelet use the N/task library to schedule a map/reduce task. The task.submit method returns a taskId that you can use to monitor the progress of your job. Once your UI has a taskId it can periodically check to see if the task has completed. When complete you can show the generated .pdf. You could also let the user know that the pdf might take a few minutes to generate and offer to email it to them when done. Here's a snippet that schedules a scheduled script with parameters:





            const mrTask = task.create({
          taskType:task.TaskType.SCHEDULED_SCRIPT,
          scriptId:'customscript_knsi_batch_products',
          deploymentId: deploymentId,
          params: {
          custscript_knsi_batch_operator:user.id,
          custscript_knsi_batch_sourcing: sourcingId
          }
          });

          try{
          const taskId = mrTask.submit();
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:true,
          message:'queued as task: '+ taskId
          }));
          }catch(e){
          log.error({
          title:'triggering '+ sourcingId +' for '+ user.email,
          details:(e.message || e.toString()) + (e.getStackTrace ? (' n n' + e.getStackTrace().join(' n')) : '')
          });
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:false,
          message:'An error occured scheduling this scriptn'+e.message
          }));






          1. Use a Map/Reduce script where your map method generates and returns each transaction's pdf file url. You'll only have a single key so that the results of all map stages coalesce into a single reduce.

          2. In the reduce step you can generate open and close pdf files as necessary and put their references into your mapped array of pdfs.

          3. Use the pdfset to bind all your individual pdfs into a single pdf:





          function renderSet(opts){
          var tpl = ['<?xml version="1.0"?>','<pdfset>'];

          opts.files.forEach(function(id, idx){
          const partFile = file.load({id:id});
          var pdf_fileURL = xml.escape({xmlText:partFile.url});
          tpl.push("<pdf src='" + pdf_fileURL + "'/>");
          });

          tpl.push("</pdfset>");

          log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('n')})});

          return render.xmlToPdf({
          xmlString: tpl.join('n')
          });
          }








            const mrTask = task.create({
          taskType:task.TaskType.SCHEDULED_SCRIPT,
          scriptId:'customscript_knsi_batch_products',
          deploymentId: deploymentId,
          params: {
          custscript_knsi_batch_operator:user.id,
          custscript_knsi_batch_sourcing: sourcingId
          }
          });

          try{
          const taskId = mrTask.submit();
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:true,
          message:'queued as task: '+ taskId
          }));
          }catch(e){
          log.error({
          title:'triggering '+ sourcingId +' for '+ user.email,
          details:(e.message || e.toString()) + (e.getStackTrace ? (' n n' + e.getStackTrace().join(' n')) : '')
          });
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:false,
          message:'An error occured scheduling this scriptn'+e.message
          }));





            const mrTask = task.create({
          taskType:task.TaskType.SCHEDULED_SCRIPT,
          scriptId:'customscript_knsi_batch_products',
          deploymentId: deploymentId,
          params: {
          custscript_knsi_batch_operator:user.id,
          custscript_knsi_batch_sourcing: sourcingId
          }
          });

          try{
          const taskId = mrTask.submit();
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:true,
          message:'queued as task: '+ taskId
          }));
          }catch(e){
          log.error({
          title:'triggering '+ sourcingId +' for '+ user.email,
          details:(e.message || e.toString()) + (e.getStackTrace ? (' n n' + e.getStackTrace().join(' n')) : '')
          });
          context.response.setHeader({name:'content-type', value:'application/json'});
          context.response.write(JSON.stringify({
          success:false,
          message:'An error occured scheduling this scriptn'+e.message
          }));





          function renderSet(opts){
          var tpl = ['<?xml version="1.0"?>','<pdfset>'];

          opts.files.forEach(function(id, idx){
          const partFile = file.load({id:id});
          var pdf_fileURL = xml.escape({xmlText:partFile.url});
          tpl.push("<pdf src='" + pdf_fileURL + "'/>");
          });

          tpl.push("</pdfset>");

          log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('n')})});

          return render.xmlToPdf({
          xmlString: tpl.join('n')
          });
          }





          function renderSet(opts){
          var tpl = ['<?xml version="1.0"?>','<pdfset>'];

          opts.files.forEach(function(id, idx){
          const partFile = file.load({id:id});
          var pdf_fileURL = xml.escape({xmlText:partFile.url});
          tpl.push("<pdf src='" + pdf_fileURL + "'/>");
          });

          tpl.push("</pdfset>");

          log.debug({title:'bound template', details:xml.escape({xmlText:tpl.join('n')})});

          return render.xmlToPdf({
          xmlString: tpl.join('n')
          });
          }






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 20 '18 at 17:34









          bknightsbknights

          8,0412821




          8,0412821













          • I like this idea, and I've been testing it out. But now I'm getting weird errors from the XMLToPDF parser where it says "Error Parsing XML" and gives back the url of the first PDF added, but the URL always starts with "system.netsuite.com", regardless if I append "system.netsuite.com" to the beginning of the file URL or not. And I've verified that the ampersands are indeed escaped.

            – Michael McCauley
            Nov 20 '18 at 22:46











          • Oh, nevermind that last comment. I forgot to set the component PDF docs to "Is Online". Making that change solved the little issue there.

            – Michael McCauley
            Nov 20 '18 at 22:59



















          • I like this idea, and I've been testing it out. But now I'm getting weird errors from the XMLToPDF parser where it says "Error Parsing XML" and gives back the url of the first PDF added, but the URL always starts with "system.netsuite.com", regardless if I append "system.netsuite.com" to the beginning of the file URL or not. And I've verified that the ampersands are indeed escaped.

            – Michael McCauley
            Nov 20 '18 at 22:46











          • Oh, nevermind that last comment. I forgot to set the component PDF docs to "Is Online". Making that change solved the little issue there.

            – Michael McCauley
            Nov 20 '18 at 22:59

















          I like this idea, and I've been testing it out. But now I'm getting weird errors from the XMLToPDF parser where it says "Error Parsing XML" and gives back the url of the first PDF added, but the URL always starts with "system.netsuite.com", regardless if I append "system.netsuite.com" to the beginning of the file URL or not. And I've verified that the ampersands are indeed escaped.

          – Michael McCauley
          Nov 20 '18 at 22:46





          I like this idea, and I've been testing it out. But now I'm getting weird errors from the XMLToPDF parser where it says "Error Parsing XML" and gives back the url of the first PDF added, but the URL always starts with "system.netsuite.com", regardless if I append "system.netsuite.com" to the beginning of the file URL or not. And I've verified that the ampersands are indeed escaped.

          – Michael McCauley
          Nov 20 '18 at 22:46













          Oh, nevermind that last comment. I forgot to set the component PDF docs to "Is Online". Making that change solved the little issue there.

          – Michael McCauley
          Nov 20 '18 at 22:59





          Oh, nevermind that last comment. I forgot to set the component PDF docs to "Is Online". Making that change solved the little issue there.

          – Michael McCauley
          Nov 20 '18 at 22:59













          0














          Why not use a Map Reduce script to generate the PDF? Does it need to be a Suitelet?






          share|improve this answer
























          • I'm starting with a Suitelet in order to generate an interface for users. Also, I'm unfamiliar with the map/reduce script type, I haven't had enough time to check it out. Are you able to pass it parameters and get a response back that allows you present a PDF to a user in the browser tab? Because that's why I'm using Suitelets.

            – Michael McCauley
            Nov 20 '18 at 15:45
















          0














          Why not use a Map Reduce script to generate the PDF? Does it need to be a Suitelet?






          share|improve this answer
























          • I'm starting with a Suitelet in order to generate an interface for users. Also, I'm unfamiliar with the map/reduce script type, I haven't had enough time to check it out. Are you able to pass it parameters and get a response back that allows you present a PDF to a user in the browser tab? Because that's why I'm using Suitelets.

            – Michael McCauley
            Nov 20 '18 at 15:45














          0












          0








          0







          Why not use a Map Reduce script to generate the PDF? Does it need to be a Suitelet?






          share|improve this answer













          Why not use a Map Reduce script to generate the PDF? Does it need to be a Suitelet?







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 20 '18 at 2:52









          Rusty ShacklesRusty Shackles

          2,11159




          2,11159













          • I'm starting with a Suitelet in order to generate an interface for users. Also, I'm unfamiliar with the map/reduce script type, I haven't had enough time to check it out. Are you able to pass it parameters and get a response back that allows you present a PDF to a user in the browser tab? Because that's why I'm using Suitelets.

            – Michael McCauley
            Nov 20 '18 at 15:45



















          • I'm starting with a Suitelet in order to generate an interface for users. Also, I'm unfamiliar with the map/reduce script type, I haven't had enough time to check it out. Are you able to pass it parameters and get a response back that allows you present a PDF to a user in the browser tab? Because that's why I'm using Suitelets.

            – Michael McCauley
            Nov 20 '18 at 15:45

















          I'm starting with a Suitelet in order to generate an interface for users. Also, I'm unfamiliar with the map/reduce script type, I haven't had enough time to check it out. Are you able to pass it parameters and get a response back that allows you present a PDF to a user in the browser tab? Because that's why I'm using Suitelets.

          – Michael McCauley
          Nov 20 '18 at 15:45





          I'm starting with a Suitelet in order to generate an interface for users. Also, I'm unfamiliar with the map/reduce script type, I haven't had enough time to check it out. Are you able to pass it parameters and get a response back that allows you present a PDF to a user in the browser tab? Because that's why I'm using Suitelets.

          – Michael McCauley
          Nov 20 '18 at 15:45


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382843%2fprinting-pdf-in-netsuite-with-selection-of-multiple-transaction-records%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          mysqli_query(): Empty query in /home/lucindabrummitt/public_html/blog/wp-includes/wp-db.php on line 1924

          How to change which sound is reproduced for terminal bell?

          Can I use Tabulator js library in my java Spring + Thymeleaf project?