Используя входные данные обоих предыдущих ответов, вот полное рабочее решение и снимок экрана с результатом:
Шаг 1) Клиентский скрипт для установки обработчика кликов для пользовательской кнопки, он захватывает идентификатор моей текущей записи и передает его моему пакету, который выполняется в новом окне
define(['N/url', 'N/currentRecord'], function (url, currentRecord) {
/**
*
* @NApiVersion 2.x
* @NScriptType ClientScript
* @appliedtorecord deposit
*/
var exports = {};
/**
* <code>pageInit</code> event handler
*
* @gov XXX
*
* @param context
* {Object}
* @param context.mode
* {String} The access mode of the current record. will be one of
* <ul>
* <li>copy</li>
* <li>create</li>
* <li>edit</li>
* </ul>
*
* @return {void}
*
* @static
* @function pageInit
*/
function pageInit(context) {
// TODO
}
function onButtonClick() {
var suiteletUrl = url.resolveScript({
scriptId: 'customscript_depositslip_pdf', //the script id of my suitelet
deploymentId: 'customdeploy_depositslip_pdf', //the deployment id of my suitelet
returnExternalUrl: false,
params: {
custom_id: currentRecord.get().id,
},
});
window.open(suiteletUrl);
}
exports.onButtonClick = onButtonClick;
exports.pageInit = pageInit;
return exports;
});
Шаг 2) Сценарий пользовательских событий для создания пользовательской кнопки, видимой как в режиме редактирования, так и в режиме просмотра моей записи депозита, и вызывает обработчик кликов из моего клиентского скрипта.
define([], function () {
/**
*
* @NApiVersion 2.x
* @NScriptType UserEventScript
* @appliedtorecord deposit
*/
var exports = {};
/**
* <code>beforeLoad</code> event handler
*
* @gov 0
*
* @param context
* {Object}
* @param context.newRecord
* {record} the new record being loaded
* @param context.type
* {UserEventType} the action that triggered this event
* @param context.form
* {form} The current UI form
*
* @return {void}
*
* @static
* @function beforeLoad
*/
function beforeLoad(context) {
context.form.addButton({
id: "custpage_printdepositslip",
label: "Print Deposit Slip",
functionName: "onButtonClick"
});
context.form.clientScriptModulePath = "SuiteScripts/ss2-add-button/customDepositSlipButton.js"
}
exports.beforeLoad = beforeLoad;
return exports;
});
Шаг 3) Suitelet Script для создания пользовательской формы из XML относительно идентификатора записи текущего депозита (где вы нажали кнопку), которая извлекает информацию из подсписка депозита и возвращает ее в организованной таблице в формате PDF с раздел верхнего и нижнего колонтитула, который сохраняется на каждой странице, если таблице требуется несколько страниц.
define(['N/render', 'N/record', 'N/xml', 'N/format'],
function(render, record, xml, format) {
/**
*@NApiVersion 2.x
* @NScriptType Suitelet
* @appliedtorecord deposit
*/
/**
* <code>onRequest</code> event handler
* @gov 0
*
* @param request
* {Object}
* @param response
* {String}
*
* @return {void}
*
* @static
* @function onRequest
* @function generateXml
*/
function onRequest(context) {
var id = context.request.parameters.custom_id;
if (!id) {
context.response.write('The parameter "custom_id" is required');
return;
}
var xmlString = generateXml(id);
context.response.renderPdf({ xmlString : xmlString });
}
function generateXml(id) {
var depositRecord = record.load({ type: record.Type.DEPOSIT, id: id });
var totes = depositRecord.getValue('total');
var totally = format.format({value:totes, type:format.Type.CURRENCY});
var fulldate = depositRecord.getValue('trandate');
var mmdddate = format.format({value:fulldate, type:format.Type.DATE});
var xml='<?xml version="1.0" encoding="utf-8"?>\n<!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">\n<pdf>\n<head>\n<macrolist>\n<macro id="nlheader">\n';
xml += '<table width="100%" align="center" style="font-size:11px;">\n';
xml += '<tr>\n';
xml += '<td><b>Deposit Number:</b> ' + depositRecord.getValue('tranid') + '</td>\n';
xml += '</tr>\n';
xml += '<tr>\n';
xml += '<td><b>Date:</b> ' + mmdddate + '</td>\n';
xml += '</tr>\n';
xml += '<tr>\n';
xml += '<td><b>Account:</b> ' + depositRecord.getText('account') + '</td>\n';
xml += '</tr>\n';
xml += '<tr>\n';
xml += '<td><b>Total:</b> ' + totally + '</td>\n';
xml += '</tr>\n';
xml += '<tr>\n';
xml += '<td><b>Posting Period:</b> ' + depositRecord.getText('postingperiod') + '</td>\n';
xml += '</tr>\n';
xml += '<tr>\n';
xml += '<td><b>Memo:</b> ' + depositRecord.getText('memo') + '</td>\n';
xml += '</tr>\n';
xml += '</table>\n';
xml += '</macro>\n<macro id="nlfooter">\n<table style="width: 100%;">\n<tr>\n<td align="right" style="padding: 0; font-size:8pt;">\n<p align="right" text-align="right" ><br /><pagenumber/> of <totalpages/></p>\n</td>\n</tr>\n</table>\n</macro>\n</macrolist>\n</head>\n<body header="nlheader" header-height="13%" footer="nlfooter" footer-height="10pt" padding="0.375in 0.5in 0.5in 0.5in" style="font:10px arial, sans-serif; text-align:left;">\n';
xml += '<table width="100%" align="center" cellpadding="4" cellspacing="0" style="text-align:left; border-left:1px solid #ccc; border-right:1px solid #ccc;">\n';
xml += '<thead>\n';
xml += '<tr style="border:1px solid #ccc; background-color:#efefef;">\n';
xml += '<th style="border-right:1px solid #ccc;"><b>Date</b></th>\n';
xml += '<th style="border-right:1px solid #ccc;"><b>ID</b></th>\n';
xml += '<th style="border-right:1px solid #ccc;"><b>Customer</b></th>\n';
xml += '<th style="border-right:1px solid #ccc;"><b>Payment Method</b></th>\n';
xml += '<th style="border-right:1px solid #ccc;"><b>Type</b></th>\n';
xml += '<th style="border-right:1px solid #ccc;"><b>Ref No.</b></th>\n';
xml += '<th><b>Amount</b></th>\n';
xml += '</tr>\n';
xml += '</thead>\n';
xml += '<tbody>\n';
for (var i = 0; i < parseInt(depositRecord.getLineCount({sublistId: 'payment'})); i++)
{
var amt = depositRecord.getSublistValue({sublistId: 'payment', fieldId: 'paymentamount', line: i});
var payamt = format.format({value:amt, type:format.Type.CURRENCY});
var longdate = depositRecord.getSublistValue({sublistId: 'payment', fieldId: 'docdate', line: i});
var shortdate = format.format({value:longdate, type:format.Type.DATE});
if (depositRecord.getSublistText({sublistId: 'payment', fieldId: 'deposit', line: i}) == 'T')
{
xml += '<tr style="border-bottom:1px solid #ccc;">\n';
xml += '<td style="border-right:1px solid #ccc;">' + shortdate + '</td>\n';
xml += '<td style="border-right:1px solid #ccc;">' + depositRecord.getSublistValue({sublistId: 'payment', fieldId: 'docnumber', line: i}) + '</td>\n';
var name= depositRecord.getSublistText({sublistId: 'payment', fieldId: 'entity', line: i})
var andName = name.match('&')
if(andName){
var newName = name.replace("&", "&");
xml += '<td style="border-right:1px solid #ccc;">' + newName + '</td>\n';
}
else
xml += '<td style="border-right:1px solid #ccc;">' + name + '</td>\n';
xml += '<td style="border-right:1px solid #ccc;">' + depositRecord.getSublistText({sublistId: 'payment', fieldId: 'paymentmethod', line: i}) + '</td>\n';
xml += '<td style="border-right:1px solid #ccc;">' + depositRecord.getSublistValue({sublistId: 'payment', fieldId: 'type', line: i}) + '</td>\n';
xml += '<td style="border-right:1px solid #ccc;">' + depositRecord.getSublistValue({sublistId: 'payment', fieldId: 'refnum', line: i}) + '</td>\n';
xml += '<td align="right" style="text-align:right !important;"><p style="text-align:right !important;">' + payamt + '</p></td>\n';
xml += '</tr>\n';
}
}
xml += '</tbody>\n';
xml += '</table>\n';
xml += '</body>\n</pdf>';
return xml;
}
return {
generateXml:generateXml,
onRequest: onRequest
}
});
Основным препятствием, с которым я столкнулся, было то, что у многих наших клиентов в имени клиента были амперсанды, а xml интерпретировал это как оператор, для этого требовалась условная обработка амперсанда в поле подсписка «сущность». Кроме того, xml хотел вернуть гораздо более длинную форму поля даты, которая включала метки времени, я использую переменные и модуль N / format, чтобы изменить дату в формате мм / дд / гггг в результирующей форме.
Все это приведет к тому, что на экране вашего депозита появится пользовательская кнопка с надписью «Распечатать бланк депозита» или все, что вы выберете, чтобы пометить ее в сценарии пользовательских событий. И когда вы нажимаете на это, он должен дать вам форму PDF в новом окне, которое выглядит следующим образом (обратите внимание, что потенциально конфиденциальная информация была пикселирована для целей этой демонстрации):
И это все! Я надеюсь, что это поможет кому-то еще в будущем.