NetSuite客户端脚本:如何实现物料组子组件的账单状态自动设置?
NetSuite客户端脚本:物料组子组件未同步设置账单状态的解决方案
问题背景
需求:NetSuite报价单中,当表头「Financial Treatment」为
cat5/cat7,且表单是指定的合同报价或PCR报价时,所有行的「Billable Status」必须设为「non billable」。
现状:现有validateLine脚本对普通行有效,但添加物料组后,只有主项目行生效,子组件行仍保留原有账单状态。
问题根源
原脚本只在validateLine事件中修改当前选中的子列表行,而物料组的子组件行是系统自动插入的,不会触发validateLine事件,因此这些子行完全没被处理。
解决方案
把字段设置逻辑抽成通用函数,同时监听sublistChanged事件(子列表内容变化时触发),确保物料组插入的子行也被覆盖。另外增加表头字段变化的监听,保证条件变更时所有行同步更新。
修改后代码
/** * @NApiVersion 2.x * @NScriptType ClientScript */ define(['N/currentRecord'], function(currentRecord) { // 统一处理所有item行的账单状态设置 function setAllNonBillable(currentRec) { var sublistId = 'item'; var lineCount = currentRec.getLineCount({ sublistId: sublistId }); // 遍历所有行强制设置为non billable for (var i = 0; i < lineCount; i++) { currentRec.setSublistValue({ sublistId: sublistId, fieldId: 'custcol_billable_status', line: i, value: 'nonbillable' // 替换成你NetSuite里的实际内部ID或有效值 }); } } // 判断是否满足设置条件 function meetsConditions(currentRec) { var financialTreatment = currentRec.getValue({ fieldId: 'custbody_financial_treatment' }); var customForm = currentRec.getValue({ fieldId: 'customform' }); // 替换成你的实际表单ID var contractQuoteFormId = '123'; var pcrQuoteFormId = '456'; return (customForm === contractQuoteFormId || customForm === pcrQuoteFormId) && (financialTreatment === 'cat5' || financialTreatment === 'cat7'); } function validateLine(context) { var currentRec = currentRecord.get(); var sublistName = context.sublistId; if (sublistName !== 'item') return true; if (meetsConditions(currentRec)) { // 先设当前行,延迟100ms再遍历所有行(确保物料组子行已生成) currentRec.setCurrentSublistValue({ sublistId: 'item', fieldId: 'custcol_billable_status', value: 'nonbillable' }); setTimeout(() => setAllNonBillable(currentRec), 100); } return true; } function sublistChanged(context) { var currentRec = currentRecord.get(); var sublistName = context.sublistId; if (sublistName !== 'item') return; if (meetsConditions(currentRec)) { setAllNonBillable(currentRec); } } // 可选:表头条件变化时自动同步所有行 function fieldChanged(context) { var currentRec = currentRecord.get(); var fieldId = context.fieldId; if (fieldId === 'custbody_financial_treatment' || fieldId === 'customform') { meetsConditions(currentRec) ? setAllNonBillable(currentRec) : null; } } return { validateLine: validateLine, sublistChanged: sublistChanged, fieldChanged: fieldChanged // 不需要可以删掉 }; });
关键说明
setAllNonBillable函数:遍历所有item行强制设置状态,不管是普通行还是物料组子行都能覆盖;- 延迟执行:
validateLine里加100ms延迟是因为物料组子行是主行添加后系统异步插入的,直接遍历可能抓不到; sublistChanged监听:子列表内容变化(比如物料组插入子行)时自动触发,补漏处理漏网的子行;fieldChanged监听:表头的条件字段(Financial Treatment/表单)变化时,自动同步所有行状态,避免手动修改表头后行状态不一致。
注意事项
- 把代码里的表单ID、字段值替换成你NetSuite环境里的实际内部ID(别用显示值,容易出问题);
- 延迟时间可以根据你的系统响应速度调整,50-200ms都可以;
- 如果担心遍历所有行影响性能,可以优化成只识别物料组的子行,但大部分场景下遍历几十行完全没问题。
内容的提问来源于stack exchange,提问作者Maira S
相关产品推荐
相关产品推荐

