...

Обработчик события в модуле на примере отслеживания изменений контекста элемента приложения

Тема в разделе "Примеры решений и дополнительных модулей", создана пользователем grebina, 28 янв 2022.

  1. grebina

    grebina Техническая поддержка

    Обработчик события — запускает определенное действие в системе после того, как событие произошло. Более подробная информация в официальной справке ELMA365.

    Создадим обработчик события, который будет отслеживать ("перехватывать") изменение значения определённой контекстной переменной элемента приложения и логировать историю этих изменений.

    Рассмотрим пример на основе пользовательского приложения Дисконтная карта (discount_card) в разделе CRM (_clients). В приложении настроен следующий контекст:
    [​IMG]

    В примере мы будем отслеживать изменение значения переменной Размер скидки, % (код: percent_discount, тип Число (целое)) и записывать историю изменений в переменную История изменения скидки (код: discount_history, тип: Строка).

    Реализация обработчика

    1. Создадим пользовательский модуль в разделе Администрирование > Модули.

    2. На вкладке Обработка событий создадим новое событие:

    • Домен события — элементы приложений.
    • Событие — обновление элемента.
    • Тип обработчика — запуск скрипта.

    [​IMG]

    3. На вкладке Настройки в нашем модуля создадим переменную Дисконтная карта с типом Приложение > Дисконтная карта. Это необходимо для дальнейшего поиска определённого элемента в сценарии модуля (так как глобальные константы Global в модулях недоступны).

    [​IMG]

    4. Перейдём на вкладку Сценарии созданного обработчика. На данной вкладке будет создан метод по умолчанию:

    async function action(): Promise<void> {}

    Код обработчика необходимо реализовать в данном методе:

    Код:
    
    async function action(): Promise<void> {
    //проверяем, что обработчик сработал при изменении элемента нужного нам приложения
      
    if (Context.data.__item!.namespace === '_clients' && Context.data.__item!.code === 'discount_card') {
        
    //выполняем поиcк элемента по id, где discount_card - контекстная переменная из настроек модуля
        
    var apcard await Namespace.params.fields.discount_card.app.search().where(=> a.__id.eq(Context.data.__item!.id)).first();
        if (
    apcard) {
          const 
    oldPercent Context.data.oldItem.percent_discount;//получаем значение переменной percent_discount до изменения
          
    const newPercent Context.data.item.percent_discount;//получаем значение переменной percent_discount после изменения
          //сравниваем percent_discount до и после изменения. Если они не совпадают, значит в данном событии было изменено значение percent_discount
          
    if (oldPercent != newPercent) {
            const 
    tip Context.data.item.tip_skidki[0].name//получаем новое значение переменной Тип скидки типа Категория
            
    const createdBy Context.data.__createdByName;//получаем автора изменений
            //формируем строку с записью истории
            
    const history Context.data.__createdAt.format("DD.MM.YYYY HH:mm:ss") + " - " "Пользователь " createdBy +
              
    " изменил размер скидки по карте. Предыдущее значение: " oldPercent.toString() + ", новое значение: " newPercent.toString() + " Новый тип: " tip '\n';
            
    //записываем строку с информацией о изменении percent_discount и tip_skidki в переменную discount_history
            
    apcard!.data.discount_history apcard!.data.discount_history apcard!.data.discount_history history history;
            
    //сохраняем элемент приложения
            
    await apcard!.save();
          }
        }
      }
    }
    В Context.data.__item хранится сам элемент приложения, по которому произошло событие, без привязки к значениям полей до и после изменения. Здесь можно обратиться к параметрам:
    • namespace — код раздела;
    • code — код приложения;
    • id — Id элемента приложения, по которому произошло событие.
    В Context.data.oldItem хранится значение контекста элемента приложения до изменения. Название переменной, значение которой нужно получить, необходимо указывать через точку. Автоподстановка здесь не поддерживается.
    В Context.data.item хранится значение контекста элемента приложения после изменения. Название переменной, значение которой нужно получить, необходимо указывать через точку. Автоподстановка здесь не поддерживается.

    Результат работы данного обработчика на скриншоте:

    [​IMG]


    На форме просмотра элемента приложения в блоке История изменения размера скидки размещена переменная discount_history с отключённой опцией Показывать название на форме.


    Небольшой лайфхак

    Для просмотра структуры Context, который формируется в событии, можно отправить HTTP-запрос на сайт webhook.site/.

    Для этого перейдите на сайт webhook.site/, включите параметр Auto Navigate и скопируйте значение в строке Your unique URL.

    В коде обработчика события реализуйте следующий код:

    Код:
    
    async function action(): Promise<void> {

          
    fetch("https://webhook.site/205c73d1-2036-4e8c-8901-b31ca1a556b1", {

            
    method"POST",

            
    bodyJSON.stringify((<any>Context).json()),

        })

    }


    Где https://webhook.site/205c73d1-2036-4e8c-8901-b31ca1a556b51 – ваше значение unique URL.

    Инициализируйте нужное событие, например, изменение элемента приложения. В результате выполнения данного обработчика, вы получите HTTP-запрос на сайте https://webhook.site, где можно будет просмотреть Context в блоке Raw Content.

    [​IMG]


    После отладки обработчика с помощью сайта webhook.site не забудьте снять обработчик с публикации, чтобы он перестал выполнять настроенные действия!

    Вложения:

    Последнее редактирование: 19 мар 2024
  2. m.krasnoperova

    m.krasnoperova Участник

    Спасибо! Ценно, пригодилось.
  3. nikmix

    nikmix Новичок

    Добрый день! Столкнулся с проблемой обращения на https://webhook.site/ . Вчера отладка обработчика с помощью https://webhook.site работала нормально.Все проходило. Сегодня не отвечает, ждет запроса. Менял и адрес и создавал новый - безрезультатно. И очищал кэш. В чем может быть проблема? Где искать?
  4. grebina

    grebina Техническая поддержка

    Добрый день.
    Вероятно, проблема на стороне https://webhook.site/
    Попробуйте открыть данный сайт в другом браузере/на другом ПК, измените id вебхука. Также сократите код обработчика до минимума (как в примере отладки), и укажите обработку "Всех событий".
  5. okhlopkov_nm

    okhlopkov_nm Участник

    Добрый день! А что будет если в скрипте произойдет ошибка и он не выполнится до конца?
  6. grebina

    grebina Техническая поддержка

    Добрый день.
    На сам элемент приложения это никак не повлияет, то есть код просто не отработает.
    Вы можете обрабатывать ошибки в коде с помощью try catch и отправлять данные об ошибке, например, в ленту элемента или запускать заранее созданный процесс в случае возникновения ошибки.
  7. mrmaxonline

    mrmaxonline Участник

    Появились переменные для отслеживания изменений EventContext.OldItem и EventContext.NewItem