Событийная модель Oracle Siebel CRM (Часть 1)

Данная статья предназначена для тех, кто знаком с системой Oracle Siebel CRM и кто хорошо понимает её трехуровневую архитектуру.

При проектировании системы важно хорошо понимать, как она будет реагировать на различные действия пользователя: создание или удаление записи бизнес-компоненты, нажатие на кнопку на апплете, редактирование поля, сохранение данных и т.д. Чтобы создать именно ту архитектуру, которая с одной стороны реализует требования заказчика, а с другой не будет увеличивать издержки на дальнейшую поддержку и масштабирование, нужно знать, как Oracle Siebel CRM обрабатывает каждое событие, которое инициирует пользователь либо процедура.

В общем виде обработка событий в рамках каждого объекта проходит несколько этапов:
  1. Pre-Branch
  2. Стандартный обработчик
  3. Post-Branch




Event Model

Фактически Pre-Branch и Post-Branch – это заглушки, внутри которых у разработчиков есть возможность написать свои обработчики, то есть заложить свой алгоритм обработки события. Выбор ветки, в которой пишется этот алгоритм, зависит от того, что делает стандартный обработчик. В данной статье подробно разбираются два самых часто используемых события на уровне бизнес-компонент: SetFieldValue (обновление значения поля) и WriteRecord (сохранение изменений в базу данных).

SetFieldValue – скрипт


Рассмотрим бизнес-компоненту Contact и её поле [Work Phone #]. Это обычное базовое поле, которое пользователь может редактировать. На текущий момент для этого поля выставлено свойство Immediate Post Change равно ‘Y’:

Immediate Post Change

Что именно делает это свойство, мы увидим позже.

Далее рассмотрим такой скрипт на уровне бизнес-компоненты Contact:

function BusComp_PreSetFieldValue (FieldName, FieldValue)
{
	if (FieldName == "Work Phone #")
	{
		TheApplication().RaiseErrorText("Телефон: " + this.GetFieldValue("Work Phone #"));
	}
	return (ContinueOperation);
}

По сути, написан обработчик на ветке Pre-Branch для события SetFieldValue, который будет вызван до стандартного обработчика. Что же произойдет в тот момент, когда пользователь захочет обновить поле [Work Phone #]? В данном случае система должна отобразить ошибку и фактически до вызова стандартного обработчика дело не дойдет.

Было до ввода нового значения:



Ввод нового значения:



После перехода на другое поле:



Получилось следующее:

На начальном этапе на всех трех уровнях значение было одинаково (с поправкой на форматирование, которое определяется типом поля DTYPE_PHONE).

После чего пользователь ввел новое значение в текстовое поле «Work #» на уровне апплета. В этот момент на уровне бизнес-компоненты и на уровне таблицы значение не поменялось.

После того как пользователь перевел фокус с текстового поля «Work #», апплет инициировал событие SetFieldValue на уровне бизнес-компонента. В этот момент система увидела, что есть скрипт в рамках функции BusComp_PreSetFieldValue, и начала его выполнение. В рамках этого скрипта было считано текущее значение поля [Work Phone #], и через функцию TheApplication().RaiseErrorText() это значение было выведено на экран. Данная функция заканчивает обработку события, соответственно, до стандартного обработчика и до ветки Post-Branch система не дошла. В результате в тексте ошибки отображается старое значение телефона, и на уровне апплета новое значение так же не сохранилось.


Теперь рассмотрим такую же ситуацию, только перенесем данный скрипт на Post-Branch события SetFieldValue:

function BusComp_SetFieldValue (FieldName)
{
	if (FieldName == "Work Phone #")
	{
		TheApplication().RaiseErrorText("Телефон: " + this.GetFieldValue("Work Phone #"));
	}
}

Повторяем все те же самые действия и видим немного другой результат:



Во-первых, в тексте ошибки отображается новое значение. Во-вторых, несмотря на ошибку, которую видит пользователь, введенное значение осталось на месте.

Если система дошла до выполнения Post Branch, то можно утверждать, что стандартный обработчик закончил свое выполнение без ошибок. Значит, из приведенного примера можно сделать вывод, что стандартный обработчик SetFieldValue обновляет значение поля на уровне бизнес-компоненты. Тут важно заметить, что на уровне таблицы в этот момент ничего не поменялось. Убедиться в этом можно, выполнив простой запрос в базу данных.


Из приведенного примера можно сделать вывод: если обращаться к полю бизнес-компоненты на Pre-Branch события SetFieldValue, то система вернет текущее значение поля, которое там было до ввода нового значения. С другой стороны, если обращаться к полю бизнес-компоненты на Post-Branch события SetFieldValue, то система вернет введенное пользователем значение.

SetFieldValue – Run-Time Event


Все приведенные принципы работают и в том случае, если обработчики для Post-Branch и для Pre-Branch будут запускаться через механизм Run-Time Events, а не через скрипты.

Для демонстрации этого рассмотрим вот такое простое правило валидации (Administration – Data Validation):



Поскольку 1 никогда не равен 0, каждый раз при обращении системы к этому правилу пользователь получает сообщение об ошибке, а система прекращает дальнейшую обработку события, которое в этот момент было запущено. Data Validation Manager – это отдельная большая тема, достойная отдельной статьи. Здесь я не буду подробно останавливаться на особенностях его настройки.

Чтобы запустить это правило, нужно создать Action Set (Administration – Runtime Events) с одним действием. Параметры для этого действия приведены таблице:
Action Type BusService
Business Service Name Data Validation Manager
Business Service Method Validate
Business Service Context «Rule Set Name», «SBL Contact Dummy Validation»

В результате обработчик готов и его нужно прицепить к соответствующему событию. Для этого потребуется создать Event:



В данном случае обработчик будет запущен на ветке Pre-Branch события SetFieldValue бизнес-компоненты Contact, если будет обновляться поле [Email Address]. Тут важно обратить внимание на Conditional Expression. В его рамках система должна считать значение из поля [Email Address] и убедиться, что длина этого значения меньше 3 символов. Только в случае выполнения условия обработчик будет запущен.

Теперь можно проверить, как система будет реагировать на внесение изменений почтового адреса физического лица.

Изначально Email заполнен значением siebel@oracle.com:



Ввод нового значения, длина которого меньше 3-х символов:



После перехода на другое поле:



Никакой ошибки система не отобразила. Значение осталось прежним. Значит, условие Len([Email Address]) < 3 не прошло. То есть система в этот момент считала старое значение в поле [Email Address], которое было равно siebel@oracle.com, увидела, что длина этого значения больше 3-х, и не стала запускать обработчик. Никакой ошибки не произошло, и поле бизнес-компоненты успешно обновилось.

Если теперь ввести старое значение в это поле:



и перейти на другое поле:



то, во-первых, пользователь увидит ошибку, во-вторых, значение в поле не изменится. Фактически мы получили сразу две ошибки: первая – системная, вторая – ошибка от Data Validation. Если кто-нибудь знает, как избавиться от первой в данном случае, напишите в комментариях. Если понимать принцип работы стандартного обработчика для события SetFieldValue, то полученный результат окажется вполне логичным.

Теперь можно внести маленькое изменение в рассмотренный Event:



В данном случае обработчик привязан к Post-Branch события SetFieldValue. Всё остальное остается, как было, но поведение системы будет существенно другим.

После этих изменений система не станет «ругаться» на внесение значения siebel@oracle.com в текстовое поле «Email»:



Но если попытаться внести значение меньше 3-х символов, то произойдет следующее:



Пользователь увидит сообщение об ошибке, но при этом значение останется в поле бизнес-компоненты. Сообщение об ошибке отобразилось, поскольку в Conditional Expression проверялась длина вновь введенного значения. Но, так как ошибка произошла в момент Post-Branch, то есть после работы стандартного обработчика, введенное значение осталось на месте.

WriteRecord


Если стандартный обработчик события SetFieldValue фактически спускает значения с уровня апплета на уровень бизнес-компоненты, то стандартный обработчик WriteRecord спускает данные с уровня бизнес-компоненты на уровень таблицы. То есть происходит обновление данных в соответствующих таблицах, которые потом смогут увидеть другие пользователи системы.



Разница между SetFieldValue и WriteRecord заключается ещё в том, что в первом случае обновление полей происходит по отдельности, а во втором случае в базу данных спускаются изменения сразу по всем полям.

Если разработчик напишет свой обработчик и привяжет его к Pre-Branch события WriteRecord, то все действия система выполнит до записи данных в базу, в другом случае запись в базу данных уже будет произведена. Соответственно, если на ветке Pre-Branch произойдет ошибка, то данные в базе не изменятся, и наоборот, если ошибка произойдет на ветке Post-Branch, то это не повлияет на стандартный обработчик и данные в базе обновятся.

Зная этот факт можно более грамотно реализовывать бизнес-логику. Например, на Pre-Branch нужно вешать различные процедуры валидации данных, чтобы гарантировать, что в базу не попадет «кривая» информация. На Post-Branch можно прикрепить процедуры уведомления. Например, настроить отправку Email-сообщения при переходе заявки на ту или иную стадию.

Immediate Post Change


Свойство поля Immediate Post Change, в случае если оно равно «Y», говорит системе о том, что событие SetFieldValue для соответствующего поля нужно запустить в тот момент, когда пользователь внес изменения и пытается перевести курсор в другое место. Если оно не выставлено, а у большинства полей это так, то событие SetFieldValue происходит в рамках обработки события WriteRecord. То есть система смотрит, какие данные с уровня апплета не были перенесены на уровень бизнес-компонента, и для каждого поля запускает SetFieldValue, а уже потом запускается WriteRecord.

Выводы


С учетом того, как Oracle Siebel CRM обрабатывает события, я рекомендую запускать валидацию данных на ветке Pre-Branch события WriteRecord. В этом случае при попытке пользователя сохранить созданную им запись система говорит, в каких полях данные не соответствуют определенной бизнес-логике. Пользователь вносит соответствующие корректировки и вновь пробует всё сохранить.

Проверка значений каждого поля потребует написания скрипта, так как Run-Time Event не имеет доступа к новому значению, когда находится на ветке Pre-Branch события SetFieldValue.

Все описанные принципы действуют не только когда пользователь вносит изменения через интерфейс, но и когда работает EAI-интеграция или просто скрипт запускает метод SetFieldValue напрямую. Например: bcContact.SetFieldValue(“Email Address”, “rrr@kk.ru”).
  • –1
  • 9.9k
  • 3
Инфосистемы Джет
410.87
Системный интегратор
Share post

Comments 3

    +1
    Спрячьте, основной контент под хабракат
      0
      И, желательно, поскорее, а то нахватаете минусов.
        0
        Спасибо, сделали.

    Only users with full accounts can post comments. Log in, please.