Печать PDF в NetSuite с выбором нескольких записей транзакций - PullRequest
0 голосов
/ 20 ноября 2018

Можно ли напечатать несколько транзакций в одном документе PDF?Я вижу только два варианта, которые, по-видимому, имеют существенные недостатки:

1) Загружать отдельные записи в каждый из своих собственных объектов nlobjTemplateRenderer, а затем сшивать их все вместе в тегах перед рендерингом в PDF.Имеет ограничение менее 50 транзакций в зависимости от других действий, выполняемых при использовании в Suitelet.

2) Выполните поиск по внутренним идентификаторам выбранных записей и передайте результаты поиска в объект nlobjTemplateRenderer.Этот метод, основанный на существующей документации, не дает оснований полагать, что он будет правильно отображать записи с данными строк в виде столбцов результатов полностью внутри одного документа.

Мне кажется, что мой лучший вариант - № 1, норазбить желаемую транзакцию на группы по 5-10 записей и повторно вызвать Suitelet с небольшими группами в надежде достичь 45-секундного ограничения времени ожидания nlapiRequestURL, прежде чем объединить все результаты и вернуть окончательный PDF-документ.Я в значительной степени вижу базовую форму этого как следующее:

// 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(""));
}

Если это действительно лучший способ, то пусть так и будет, но я надеюсь, что есть более элегантное решение, которое я 'Я просто не вижу.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2018

Есть несколько частей, которые вы можете соединить вместе, чтобы сделать это.

  1. В пост-обработчике вашего Suitelet используйте библиотеку N / task, чтобы запланировать задачу / уменьшить задачу. Метод task.submit возвращает идентификатор задачи, который вы можете использовать для отслеживания хода выполнения вашей работы. Как только ваш пользовательский интерфейс имеет идентификатор задачи, он может периодически проверять, завершена ли задача. После завершения вы можете показать сгенерированный .pdf. Вы также можете сообщить пользователю, что создание PDF-файла может занять несколько минут, и предложите отправить его по электронной почте, когда закончите. Вот фрагмент, который планирует запланированный сценарий с параметрами:

  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 script\n'+e.message
    }));
  1. Используйте скрипт Map / Reduce, где ваш метод карты генерирует и возвращает URL-адрес pdf-файла каждой транзакции. У вас будет только один ключ, чтобы результаты всех этапов карты объединились в одно сокращение.
  2. На шаге сокращения вы можете создавать и открывать PDF-файлы по мере необходимости и помещать их ссылки в ваш отображенный массив PDF-файлов.
  3. Используйте набор PDF, чтобы связать все ваши отдельные PDF-файлы в один 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')
	});
}
0 голосов
/ 20 ноября 2018

Почему бы не использовать скрипт Map Reduce для создания PDF?Это должен быть суклет?

...