netsuite
ユーザーイベント:送信イベントの前後
サーチ…
構文
- beforeSubmit(type)//送信する前に、1.0
- beforeSubmit(scriptContext)//送信する前に、2.0
- afterSubmit(type)//送信後、1.0
- afterSubmit(scriptContext)//送信後、2.0
パラメーター
パラメータ | 詳細 |
---|---|
SuiteScript 2.0 | - |
scriptContext | {Object} |
scriptContext.newRecord | {N/record.Record} データベースから読み取られているレコードへの参照。レコードのフィールド値を変更するために使用することができます |
scriptContext.oldRecord | {N/record.Record} レコードの前の状態への読み取り専用参照。新しい値との比較に使用できます |
scriptContext.type | {UserEventType} 実行されている書き込みアクションのタイプの列挙体 |
SuiteScript 1.0 | - |
type | {String} 実行される書き込みアクションのタイプ |
備考
beforeSubmit
とafterSubmit
これらの2つのイベントは、レコードに対するデータベース書き込み操作によってトリガーされます。ユーザー、スクリプト、CSVインポート、またはWebサービス要求がデータベースにレコードを書き込もうとするたびに、送信イベントが発生します。
両方の送信イベントをトリガするアクションを記録する:
- 作成する
- 編集
- 削除
- XEdit(インライン編集)
- 承認する
- 拒否
- キャンセル
- パック
- 船
トリガー録音アクションbeforeSubmit
のみ:
- マーク完了
- 再割り当て(サポートケース)
- 予測の編集
afterSubmit
のみトリガーするアクションを記録する:
- ドロップシップ
- 特別注文
- 注文アイテム
- 手形を支払う
典型的なユースケースbeforeSubmit
- データベースにコミットされる前にレコードを検証する
- 許可と制限のチェック
- データベースをコミットする前の最後の変更
- 外部システムから更新を引き出す
afterSubmit
典型的な使用例
- レコード変更の電子メール通知
- ブラウザリダイレクト
- 従属レコードの登録/更新
- 外部システムへの変更をプッシュする
ユーザーイベントは連鎖しません
ユーザーイベントで書かれたコードは、 他のレコードのユーザーイベントをトリガーしません。たとえば、Sales OrderレコードのbeforeSubmit
から関連するCustomerレコードを変更しても、CustomerレコードのSubmitイベントはトリガーされません 。
NetSuiteはこれを実行して、無限ループ内でお互いにトリガするユーザイベントを回避します。連鎖シーケンスで起動するためにユーザーイベントが必要な場合は、他のスクリプトタイプ(RESTlets、Suitelets、Scheduled Scriptsなど)をイベントの間に挿入する必要があります。
イベントハンドラがvoid
返す
Submitイベントハンドラの戻り値の型はvoid
です。イベントハンドラから返されたデータはシステムに影響しません。戻り値では実際には何もできないので、ハンドラ関数から何も返す必要はありません。
!!注意 !!
古いレコードと新しいレコードの値を比較するときは、非常に注意してください。 古いレコードの空のフィールドはnull
として返され、 新しいレコードの空のフィールドは空のStringとして返されます。つまり、単に古いものと新しいものを比較することはできません。そうしないと、誤検出が発生します。あなたが書くロジックは、いずれかがnull
で、空文字列が適切である場合を処理する必要があります。
最小:メッセージを記録する
// 1.0, Revealing Module pattern
var myNamespace = myNamespace || {};
myNamespace.example = (function () {
/**
* User Event 1.0 example detailing usage of the Submit events
*
* @appliedtorecord employee
*/
var exports = {};
function beforeSubmit(type) {
nlapiLogExecution("DEBUG", "Before Submit", "action=" + type);
}
function afterSubmit(type) {
nlapiLogExecution("DEBUG", "After Submit", "action=" + type);
}
exports.beforeSubmit = beforeSubmit;
exports.afterSubmit = afterSubmit;
return exports;
})();
// 2.0
define(["N/log"], function (log) {
/**
* User Event 2.0 example showing usage of the Submit events
*
* @NApiVersion 2.x
* @NModuleScope SameAccount
* @NScriptType UserEventScript
* @appliedtorecord employee
*/
var exports = {};
function beforeSubmit(scriptContext) {
log.debug({
"title": "Before Submit",
"details": "action=" + scriptContext.type
});
}
function afterSubmit(scriptContext) {
log.debug({
"title": "After Submit",
"details": "action=" + scriptContext.type
});
}
exports.beforeSubmit = beforeSubmit;
exports.afterSubmit = afterSubmit;
return exports;
});
送信前:データベースにコミットされる前にレコードを検証する
この例では、 プロジェクトリソースとしてマークされている従業員にも適切な人件費が定義されていることを確認します。
// 1.0, Revealing Module pattern
var myNamespace = myNamespace || {};
myNamespace.example = (function () {
/**
* User Event 1.0 example detailing usage of the Submit events
*
* @appliedtorecord employee
*/
var exports = {};
function beforeSubmit(type) {
if (!isEmployeeValid(nlapiGetNewRecord())) {
throw nlapiCreateError("STOIC_ERR_INVALID_DATA", "Employee data is not valid", true);
}
}
function isEmployeeValid(employee) {
return (!isProjectResource(employee) || hasValidLaborCost(employee));
}
function isProjectResource(employee) {
return (employee.getFieldValue("isjobresource") === "T");
}
function hasValidLaborCost(employee) {
var laborCost = parseFloat(employee.getFieldValue("laborcost"));
return (Boolean(laborCost) && (laborCost > 0));
}
exports.beforeSubmit = beforeSubmit;
return exports;
})();
// 2.0
define(["N/error"], function (err) {
var exports = {};
/**
* User Event 2.0 example detailing usage of the Submit events
*
* @NApiVersion 2.x
* @NModuleScope SameAccount
* @NScriptType UserEventScript
* @appliedtorecord employee
*/
function beforeSubmit(scriptContext) {
if (!isEmployeeValid(scriptContext)) {
throw err.create({
"name": "STOIC_ERR_INVALID_DATA",
"message": "Employee data is not valid",
"notifyOff": true
});
}
}
function isEmployeeValid(scriptContext) {
return (!isProjectResource(scriptContext.newRecord) || hasValidLaborCost(scriptContext.newRecord));
}
function isProjectResource(employee) {
return (employee.getValue({"fieldId" : "isjobresource"}));
}
function hasValidLaborCost(employee) {
var laborCost = employee.getValue({"fieldId" : "laborcost"});
return (Boolean(laborCost) && (laborCost > 0));
}
exports.beforeSubmit = beforeSubmit;
return exports;
});
以前の値が何であっても気にしないので、 新しいレコードへの参照を検証に渡すことに注意してください。私たちはデータベースに書き込まれようとしている値にのみ関心を持っています。 2.0では、 scriptContext.newRecord
リファレンスを使用して行い、1.0ではグローバル関数nlapiGetNewRecord
を呼び出します。
送信されたデータが有効でない場合は、エラーを作成してスローします。 beforeSubmit
イベントでは、変更がデータベースに書き込まれないようにするには、関数が例外をthrow
する必要throw
あります。多くの場合、開発者は十分に機能すると期待して機能からreturn false
をreturn false
うとしますが、十分ではありません。エラーオブジェクトは、 N/error
モジュールを使用して2.0で作成され、1.0ではグローバルnlapiCreateError
関数を使用して作成されます。作成したエラーオブジェクトをthrow
キーワードで使用して例外を発生させます。
送信後:フィールドが変更されたかどうかを確認する
レコードがデータベースに格納された後、レコード上で何が変更されたかを調べる必要があります。この検査は、古いレコードインスタンスと新しいレコードインスタンスの値を比較して行います。
// 1.0, Revealing Module pattern
var myNamespace = myNamespace || {};
myNamespace.example = (function () {
/**
* User Event 1.0 example detailing usage of the Submit events
*
* @appliedtorecord employee
*/
var exports = {};
function afterSubmit(type) {
notifySupervisor();
}
function notifySupervisor() {
// Old and New record instances are retrieved from global functions
var employee = nlapiGetNewRecord();
var prevEmployee = nlapiGetOldRecord();
// If Employee Status didn't change, there's nothing to do
if (!didStatusChange(employee, prevEmployee)) {
return;
}
// Otherwise, continue with business logic...
}
function didStatusChange(employee, prevEmployee) {
var status = employee.getFieldValue("employeestatus");
var prevStatus = prevEmployee.getFieldValue("employeestatus");
/* !! Caution !!
* Empty fields from the Old record come back as `null`
* Empty fields from the New record come back as an empty String
* This means you cannot simply compare the old and new
*/
return ((prevStatus || status) && (status !== prevStatus));
}
exports.afterSubmit = afterSubmit;
return exports;
})();
// 2.0
define(["N/runtime"], function (runtime) {
/**
* User Event 2.0 example detailing usage of the Submit events
*
* @NApiVersion 2.x
* @NModuleScope SameAccount
* @NScriptType UserEventScript
* @appliedtorecord employee
*/
var exports = {};
function afterSubmit(scriptContext) {
notifySupervisor(scriptContext);
}
function notifySupervisor(scriptContext) {
// Old and New records are simply properties on scriptContext
var employee = scriptContext.newRecord;
var prevEmployee = scriptContext.oldRecord;
// If Employee Status didn't change, there's nothing to do
if (!didStatusChange(employee, prevEmployee)) {
return;
}
// Otherwise, continue with business logic...
}
function didStatusChange(employee, prevEmployee) {
var status = employee.getValue({"fieldId" : "employeestatus"});
var prevStatus = prevEmployee.getValue({"fieldId" : "employeestatus"});
/* !! Caution !!
* Empty fields from the Old record come back as `null`
* Empty fields from the New record come back as an empty String
* This means you cannot simply compare the old and new
*/
return ((prevStatus || status) && (status !== prevStatus));
}
exports.afterSubmit = afterSubmit;
return exports;
});
古いレコードと新しいレコードの値を比較するときは、非常に注意してください。 古いレコードの空のフィールドはnull
として返され、 新しいレコードの空のフィールドは空のStringとして返されます。つまり、単に古いものと新しいものを比較することはできません。そうしないと、誤検出が発生します。あなたが書くロジックは、いずれかがnull
で、空文字列が適切である場合を処理する必要があります。