netsuite
Событие пользователя: до и после отправки событий
Поиск…
Синтаксис
- beforeSubmit (type) // Before Submit, 1.0
- beforeSubmit (scriptContext) // Before Submit, 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
Эти два события инициируются любой операцией записи базы данных в записи. Каждый раз, когда пользователь, сценарий, импорт CSV или запрос веб-службы пытаются записать запись в базу данных, активируются события отправки.
Записывать действия, которые запускают как события отправки:
- Создайте
- редактировать
- удалять
- XEdit (встроенное редактирование)
- Утвердить
- отклонять
- отменить
- пак
- Корабль
Записывать действия, которые запускаются beforeSubmit
only:
- Mark Complete
- Переназначить (случаи поддержки)
- Изменить прогноз
Записывать действия, которые запускаются только после afterSubmit
:
- Dropship
- Особое распоряжение
- Элементы заказа
- Оплачивать счета
Типичные случаи использования для beforeSubmit
- Проверять запись до того, как она будет привязана к базе данных
- Проверка разрешений и ограничений
- Изменения в последнюю минуту перед фиксацией базы данных
- Вытягивать обновления из внешних систем
Типичные случаи использования для afterSubmit
- Уведомление об изменении записи по электронной почте
- Переадресация браузера
- Создание / обновление зависимых записей
- Ввод изменений в внешние системы
Пользовательские события не связаны
Код, записанный в Пользовательских событиях, не будет запускать какие-либо пользовательские события в других записях. Например, изменение связанной записи клиента из записи beforeSubmit
в beforeSubmit
клиента не приведет к возникновению событий отправки записи клиента.
NetSuite делает это, чтобы пользовательские события не запускали друг друга в бесконечном цикле. Если вам нужно пользовательские события , чтобы стрелять в прикованной последовательности, другие типы сценариев (например , RESTlets, Suitelets, Запланированные скрипты) должны быть введены между событиями.
Обработчики событий возвращают void
Обратный тип обработчиков событий Submit void
. Любые данные, возвращаемые нашим обработчиком событий, не влияют на систему. Нам не нужно возвращать что-либо из нашей функции обработчика, поскольку мы ничего не можем сделать с ее возвращаемым значением.
!! ВНИМАНИЕ !!
Будьте очень осторожны при сравнении значений между старыми и новыми записями. Пустые поля из старой записи возвращаются как null
, а пустые поля из новой записи возвращаются как пустая строка. Это означает, что вы не можете просто сравнить старые с новыми, иначе вы получите ложные срабатывания. Любая логика, которую вы пишете, должна обрабатывать случай, когда один является 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
исключение. Часто разработчики пытаются return false
из своей функции, ожидая, что этого будет достаточно, но этого недостаточно. Объекты ошибок создаются в версии 2.0 с использованием модуля N/error
, а в 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
, а пустые поля из новой записи возвращаются как пустая строка. Это означает, что вы не можете просто сравнить старые с новыми, иначе вы получите ложные срабатывания. Любая логика, которую вы пишете, должна обрабатывать случай, когда один является null
а один - пустой строкой.