[英]NetSuite - Using SuiteScript to Create Button to Print Packing List on Transfer Order
我正在嘗試按照 SuiteAnswers 41269(用於將裝箱單添加到項目履行)添加一個按鈕以將裝箱單打印到轉移單。 這本質上是一個測試,旨在嘗試並能夠在更多非 NetSuite 本地事務(VRMA 等)上打印更多表單。
請注意,上面的 SuiteAnswers 似乎已經過時,因為它引用了 SS1.0 和 SS2.0,但 SS2.0 的一些代碼似乎也使用了 SS1.0 代碼。 由於 SA 有點偏離,我瀏覽了很多 NetSuite 幫助文件,這些文件涉及渲染和 url 模塊的不同部分,以幫助構建這些腳本。
我的問題是,單擊“打印 1”按鈕時,我不斷收到錯誤消息:
Uncaught ReferenceError: print1 is not defined
at trnfrord.nl?id=658266&whence=&cmid=1652279684591_1868:1132:30
at Object.execCb (NsRequire.js:2047:26)
at Ma.check (NsRequire.js:1193:28)
at Ma.enable (NsRequire.js:1475:10)
at Ma.init (NsRequire.js:1106:11)
at NsRequire.js:1771:18
我正在使用 UserEvent 腳本、客戶端腳本和 Suitelet 腳本。 我目前正在使用轉移訂單的靜態實體 ID,而我正在測試這個,一旦我得到這個工作,我會添加一個動態實體 ID。
更新:接受下面的建議后,我意識到我將 deploymentID 設置為部署的實際內部 ID,而不是與 scriptID 字段匹配的 ID。 我還意識到我的 beforeLoad 函數使用的是 scriptContext 而不是函數內部的上下文。
解決這些問題后,我開始收到“不允許您直接導航到此頁面”錯誤。 我的腳本部署設置為測試,所以我將它們更改為已發布,但仍然出現此錯誤。
我將 returnExternalUrl 從 true 更改為 false 並收到“無效的 PDF 布局”錯誤。
我在網上查看並意識到我的部分錯誤是使用實際 PDF 的 formID,而不是創建新的自定義交易表單並分配 PDF 以從該表單打印。
完成后,我現在收到此錯誤:
{"type":"error.SuiteScriptError","name":"UNEXPECTED_ERROR","message":null,"stack":["renderPackingSlip(N/render)","onRequest(/SuiteScripts/buttonTest2/print_suitelet_script.js:18)"],"cause":{"type":"internal error","code":"UNEXPECTED_ERROR","details":null,"userEvent":null,"stackTrace":["renderPackingSlip(N/render)","onRequest(/SuiteScripts/buttonTest2/print_suitelet_script.js:18)"],"notifyOff":false},"id":"7fb1b24b-b66f-44bf-b6f3-282444013ca5-2d323032322e30352e3133","notifyOff":false,"userFacing":false}
這是現在更新的腳本,它們會引發上述錯誤:
更新的 UE 腳本:
/**
* @NApiVersion 2.x
* @NScriptType UserEventScript
* @NModuleScope SameAccount
*/
define([
'N/url',
'N/ui/serverWidget',
],
function (url) {
function beforeLoad(scriptContext) {
try {
if (scriptContext.type == 'view') {
const href = url.resolveScript({
scriptId: 699,
deploymentId: 3,
returnExternalUrl: true
});
scriptContext.form.addButton({
id: 'custpage_print1',
label: 'Print 1',
functionName: "(window.location='" + href + "')"
});
}
} catch (error) {
log.debug('ERROR', error);
}
}
return {
beforeLoad: beforeLoad
};
});
更新的 SS 腳本:
/**
* @NApiVersion 2.x
* @NScriptType Suitelet
*/
define(['N/render'],
function(render) {
function onRequest(context) {
var total = 0;
if (context.request.method == 'GET'){
var ifid = context.request.parameters.custparam_ifid;
var fileObj = render.packingSlip({
entityId: 658266,
printMode: render.PrintMode.PDF,
formId: 129
});
fileObj.save()
}
}
return {
onRequest: onRequest
};
});
PDF:
<?xml version="1.0"?><!DOCTYPE pdf PUBLIC "-//big.faceless.org//report" "report-1.1.dtd">
<pdf>
<head>
<link name="NotoSans" type="font" subtype="truetype" src="${nsfont.NotoSans_Regular}" src-bold="${nsfont.NotoSans_Bold}" src-italic="${nsfont.NotoSans_Italic}" src-bolditalic="${nsfont.NotoSans_BoldItalic}" bytes="2" />
<#if .locale == "zh_CN">
<link name="NotoSansCJKsc" type="font" subtype="opentype" src="${nsfont.NotoSansCJKsc_Regular}" src-bold="${nsfont.NotoSansCJKsc_Bold}" bytes="2" />
<#elseif .locale == "zh_TW">
<link name="NotoSansCJKtc" type="font" subtype="opentype" src="${nsfont.NotoSansCJKtc_Regular}" src-bold="${nsfont.NotoSansCJKtc_Bold}" bytes="2" />
<#elseif .locale == "ja_JP">
<link name="NotoSansCJKjp" type="font" subtype="opentype" src="${nsfont.NotoSansCJKjp_Regular}" src-bold="${nsfont.NotoSansCJKjp_Bold}" bytes="2" />
<#elseif .locale == "ko_KR">
<link name="NotoSansCJKkr" type="font" subtype="opentype" src="${nsfont.NotoSansCJKkr_Regular}" src-bold="${nsfont.NotoSansCJKkr_Bold}" bytes="2" />
<#elseif .locale == "th_TH">
<link name="NotoSansThai" type="font" subtype="opentype" src="${nsfont.NotoSansThai_Regular}" src-bold="${nsfont.NotoSansThai_Bold}" bytes="2" />
</#if>
<macrolist>
<macro id="nlheader">
<table style="width: 100%; font-size: 10pt;"><tr>
<td rowspan="3" style="padding: 0px; width: 222px;"><#if companyInformation.logoUrl?length != 0><img src="${companyInformation.logoUrl}" style="margin: 5px; width: 120px; height: 60px; float: left;" /> </#if></td>
<td rowspan="3" style="padding: 0px; width: 248px;">${companyInformation.addressText}</td>
<td align="right" style="padding: 0px; width: 323px;"><span style="font-size: 28pt;">${record@title}</span></td>
</tr>
<tr>
<td align="right" style="width: 337px;"><span class="number">#${record.tranid}</span></td>
</tr>
<tr>
<td align="right" style="width: 337px;">${record.trandate}</td>
</tr></table>
</macro>
<macro id="nlfooter">
<table class="footer"><tr><#if preferences.PRINT_BARCODES>
<td><barcode codetype="code128" showtext="true" value="${record.tranid}"/></td>
</#if>
<td align="right"><pagenumber/> of <totalpages/></td>
</tr></table>
</macro>
</macrolist>
<style type="text/css">* {
<#if .locale == "zh_CN">
font-family: NotoSans, NotoSansCJKsc, sans-serif;
<#elseif .locale == "zh_TW">
font-family: NotoSans, NotoSansCJKtc, sans-serif;
<#elseif .locale == "ja_JP">
font-family: NotoSans, NotoSansCJKjp, sans-serif;
<#elseif .locale == "ko_KR">
font-family: NotoSans, NotoSansCJKkr, sans-serif;
<#elseif .locale == "th_TH">
font-family: NotoSans, NotoSansThai, sans-serif;
<#else>
font-family: NotoSans, sans-serif;
</#if>
}
table {
font-size: 9pt;
table-layout: fixed;
}
th {
font-weight: bold;
font-size: 8pt;
vertical-align: middle;
padding: 5px 6px 3px;
background-color: #e3e3e3;
color: #333333;
}
td {
padding: 4px 6px;
}
td p { align:left }
b {
font-weight: bold;
color: #333333;
}
table.header td {
padding: 0;
font-size: 10pt;
}
table.footer td {
padding: 0;
font-size: 8pt;
}
table.itemtable th {
padding-bottom: 10px;
padding-top: 10px;
}
table.body td {
padding-top: 2px;
}
td.addressheader {
font-size: 8pt;
font-weight: bold;
padding-top: 6px;
padding-bottom: 2px;
}
td.address {
padding-top: 0;
}
span.title {
font-size: 28pt;
}
span.number {
font-size: 16pt;
}
span.itemname {
font-weight: bold;
line-height: 150%;
}
div.returnform {
width: 100%;
/* To ensure minimal height of return form */
height: 200pt;
page-break-inside: avoid;
page-break-after: avoid;
}
hr {
border-top: 1px dashed #d3d3d3;
width: 100%;
color: #ffffff;
background-color: #ffffff;
height: 1px;
}
</style>
</head>
<body header="nlheader" header-height="10%" footer="nlfooter" footer-height="20pt" padding="0.5in 0.5in 0.5in 0.5in" size="Letter">
<table style="width: 100%; margin-top: 10px;"><tr>
</tr>
<tr>
</tr></table>
<table class="body" style="width: 100%; margin-top: 10px;"><tr>
<th style="width: 160px;">${record.shipmethod@label}</th>
<th>${record.shipphone@label}</th>
</tr>
<tr>
<td style="width: 160px;">${record.shipmethod}</td>
<td>${record.shipphone}</td>
</tr></table>
<#if record.item?has_content>
<table class="itemtable" style="margin-top:10px;width:100%;">
<thead>
<tr>
<th colspan="12" style="width: 264px;">Item</th>
<th colspan="4" style="width: 165px;">UPC / ISBN</th>
<th colspan="3" style="width: 90px;">Options</th>
<th colspan="3" style="width: 90px;">Retail</th>
<th align="right" colspan="2" style="width: 89px;">Remaining</th>
<th align="right" colspan="2" style="width: 64px;">Shipped</th>
</tr>
</thead>
<#list record.item as tranline><tr>
<td colspan="12" style="width: 264px;"><span style="font-size:11px;"><span class="itemname">${tranline.item}</span></span><br /><span style="font-size:10px;">${tranline.description}</span></td>
<td colspan="4" style="width: 165px;"><span style="font-size:10px;">${tranline.custcol_nsts_csic_upc}</span></td>
<td colspan="3" style="width: 90px;"><span style="font-size:10px;">${tranline.options} <#if (tranline.custcol_nsts_csre_rnt_guid?has_content)> Rental <#else> </#if> </span></td>
<td colspan="3" style="width: 90px;"><span style="font-size:10px;">${tranline.custcol_retail}</span></td>
<td align="right" colspan="2" style="width: 89px;"><span style="font-size:10px;">${tranline.quantityremaining}</span></td>
<td align="right" colspan="2" style="width: 64px;"><span style="font-size:10px;">${tranline.quantity}</span></td>
</tr>
</#list></table>
<table align="right" border="1" cellpadding="1" cellspacing="1" style="width:35%;">
<tr>
<td style="width: 114px;">Quantity Total</td>
<td style="width: 97px;">${record.quantity.total}</td>
</tr>
<tr>
<td style="width: 114px;">Subtotal</td>
<td style="width: 97px;">${record.custbody_pack_slip_subtotal}</td>
</tr>
<tr>
<td style="width: 114px;">Shipping & Handling</td>
<td style="width: 97px;">${record.custbody_pack_slip_shiptotal}</td>
</tr>
<tr>
<td style="width: 114px;">Tax</td>
<td style="width: 97px;">${record.custbody_pack_slip_taxtotal}</td>
</tr>
<tr>
<td style="width: 114px;">Total</td>
<td style="width: 97px;">${record.custbody_pack_slip_trxtotal}</td>
</tr></table>
</#if>
</body>
</pdf>
您沒有調用該函數或提供 eval 參數(有點)。 functionName 參數應該只是從客戶端腳本中導出的函數名稱,不帶括號。 例如:
functionName: 'print1'
另請注意,客戶端腳本不必是 ClientScript 並且(IMO)如果您使用,您的代碼更具可移植性
formObj.clientScriptModulePath = './custom_print_CS.js'; // or whatever you name it and save it besid your User Event script code.
您的客戶端腳本可能如下所示:
/**
* @NApiVersion 2.x
*/
define([
'N/url',
],
function(url) {
function print1() {
var output = url.resolveScript({
scriptId: 698,
deploymentId: 1695,
returnExternalUrl: true
});
window.open(output);
}
return {
print1: print1
};
})
我知道 Suite Answer 建議這樣做,但有一個替代解決方案可以讓您跳過 Client Script ,通過直接將重定向放在按鈕上,直接從按鈕重定向到 Suitelet。 事件腳本 beforeLoad 函數的內部看起來像這樣
const href = url.resolveScript({
scriptId:698,
deploymentId: 1695,
returnExternalUrl: true
});
context.form.addButton({
id:'custpage_print1',
label: 'Print 1',
functionName: "(window.location='"+href +"')"
});
不要忘記加載 N/url 模塊
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.