Хаутушки https://gglp.ru/home/howto 2026-10-26T18:35:48+03:00 Фёдоров Александр Joomla! - Open Source Content Management Остановка ранее запущенных экземпляров процесса 2021-08-18T09:14:22+03:00 2021-08-18T09:14:22+03:00 https://gglp.ru/home/howto/21-ostanovka-ranee-zapushchennykh-ekzemplyarov-protsessa Фёдоров Александр <p>Зачастую процессы, запускаемые по таймеру, обрабатывает множество записей и в некоторых случаях их количество настолько велико, что процесс не успевает завершиться до запуска следующего экземпляра. Это чревато нестабильным поведением системы, т.к. фильтры на процессах одинаковые, может запуститься обработка одной и той же записи, могут сбиться счётчики и возникнуть прочие проблемы.</p> <p>Чтобы этого избежать необходимо сделать так, чтобы одновременно в системе работал только один экземпляр интересующего нас процесса.</p> <p><img src="https://gglp.ru/images/021_01.png" alt="" /></p> <h3>Задача</h3> <p>Принудительно завершить ранее запущенные экземпляры процесса при запуске текущего процесса</p> <h3>Решение</h3> <ol> <li>Ожидание требования остановки <ol> <li>Одновременно с запуском процесса запускаем ветку ожидания сигнала прерывания. Называть сигнал лучше по названию процесса. Например, процесс называется <code>ProcessImportOrdersUpdateOpen</code>, тогда сигнал назвать <code>StopProcessImportOrdersUpdateOpen<br /></code><img src="https://gglp.ru/images/021_03.png" alt="" /></li> <li>Ставим таймер задержки прерывания, чтобы процесс не остановил сам себя;</li> </ol> </li> <li>Генерация требования остановки <ol> <li>Добавляем генерацию сигнала по всей системе на остановку прочих экземпляров<br /><img src="https://gglp.ru/images/021_02.png" alt="" /></li> </ol> </li> </ol> <h3>Описание</h3> <p>Процесс идёт по всем безусловным веткам управления одновременно. А дальше останавливается на элементе, который необходимо выполнить. Если это системное действие, оно будет выполнено автоматически, если пользовательское, процесс на нём остановится в ожидании реакции пользователя. На ожидании промежуточного сигнала процесс тоже остановится. Как только в системе будет сгенерирован нужный промежуточный сигнал, продолжит выполняться параллельная ветка процесса и процесс перейдёт к сигналу завершения. В результате процесс будет завершён вне зависимости от статуса выполнения прочих шагов (они будут отменены).</p> <p>Обсудить в <a href="https://t.me/gglpru/17">Telegram</a></p> <p>Зачастую процессы, запускаемые по таймеру, обрабатывает множество записей и в некоторых случаях их количество настолько велико, что процесс не успевает завершиться до запуска следующего экземпляра. Это чревато нестабильным поведением системы, т.к. фильтры на процессах одинаковые, может запуститься обработка одной и той же записи, могут сбиться счётчики и возникнуть прочие проблемы.</p> <p>Чтобы этого избежать необходимо сделать так, чтобы одновременно в системе работал только один экземпляр интересующего нас процесса.</p> <p><img src="https://gglp.ru/images/021_01.png" alt="" /></p> <h3>Задача</h3> <p>Принудительно завершить ранее запущенные экземпляры процесса при запуске текущего процесса</p> <h3>Решение</h3> <ol> <li>Ожидание требования остановки <ol> <li>Одновременно с запуском процесса запускаем ветку ожидания сигнала прерывания. Называть сигнал лучше по названию процесса. Например, процесс называется <code>ProcessImportOrdersUpdateOpen</code>, тогда сигнал назвать <code>StopProcessImportOrdersUpdateOpen<br /></code><img src="https://gglp.ru/images/021_03.png" alt="" /></li> <li>Ставим таймер задержки прерывания, чтобы процесс не остановил сам себя;</li> </ol> </li> <li>Генерация требования остановки <ol> <li>Добавляем генерацию сигнала по всей системе на остановку прочих экземпляров<br /><img src="https://gglp.ru/images/021_02.png" alt="" /></li> </ol> </li> </ol> <h3>Описание</h3> <p>Процесс идёт по всем безусловным веткам управления одновременно. А дальше останавливается на элементе, который необходимо выполнить. Если это системное действие, оно будет выполнено автоматически, если пользовательское, процесс на нём остановится в ожидании реакции пользователя. На ожидании промежуточного сигнала процесс тоже остановится. Как только в системе будет сгенерирован нужный промежуточный сигнал, продолжит выполняться параллельная ветка процесса и процесс перейдёт к сигналу завершения. В результате процесс будет завершён вне зависимости от статуса выполнения прочих шагов (они будут отменены).</p> <p>Обсудить в <a href="https://t.me/gglpru/17">Telegram</a></p> Как сделать кликабельной ссылку в текстовом поле 2021-07-20T18:06:30+03:00 2021-07-20T18:06:30+03:00 https://gglp.ru/home/howto/12-kak-sdelat-klikabelnoj-ssylku-v-tekstovom-pole Фёдоров Александр <p>Если на карточке в текстовом поле вставить ссылку на веб-страницу, она будет отображаться как обычный текст. Чтобы сделать ссылку кликабельной, надо добавить несколько блоков кода в схему карточки (подразумеваем, что текстовое поле уже добавлено в объект и выведено на карточку).</p> <p>Например, надо сделать кликабельной ссылку на собрание в zoom.</p> <p><img src="https://gglp.ru/images/012_01.png" alt="" /></p> <h3>Задача</h3> <p>Кликабельная ссылка в текстовом поле</p> <h3>Решение</h3> <ol> <li>Добавить поле на карточку через мастер раздела. Для примера пусть это будет поле <code>gglpZoomLink</code></li> <li>Добавить следующий код в блок кода <code>values</code> нашего поля:<br /><code>"showValueAsLink": true,</code><br /><code>"href": {</code><br /><code>    "bindTo": "UsrUrlFieldName",</code><br /><code>    "bindConfig": {"converter": "getLinkFormat"}</code><br /><code>},</code><br /><code>"controlConfig": {</code><br /><code>    "className": "Terrasoft.TextEdit",</code><br /><code>    "linkclick": { bindTo: "onLinkClick"}</code><br /><code>}</code></li> <li>Добавить следующий код в блок кода <code>methods</code>:<br /><code>getLinkFormat: function(value) {</code><br /><code>    return {</code><br /><code>        "url": value,</code><br /><code>        "caption": value</code><br /><code>    };</code><br /><code>},</code><br /><code> </code><br /><code>onLinkClick: function(url) {</code><br /><code>    var link = document.createElement("a");</code><br /><code>    link.href = url;</code><br /><code>    link.target = "_blank";</code><br /><code>    document.body.appendChild(link);</code><br /><code>    link.click();</code><br /><code>    document.body.removeChild(link);</code><br /><code>    return false;</code><br /><code>}</code></li> </ol> <h3>Объяснение</h3> <p>Итоговый вид кода страницы получился примерно такой:</p> <p><img src="https://gglp.ru/images/012_02.png" alt="" /></p> <p>Из метода getLinkFormat возвращаются значения двух переменных (можно задавать отдельно ссылку и текст ссылки), но мы используем ссылку для отображения без преобразований.</p> <p>В методе onLinkClick использовано динамическое формирование элемента &lt;a&gt;, чтобы избежать блокировки всплывающих окон браузером.</p> <p>Что интересно, если указывать ссылку без протокола (https://), она будет отображаться как относительная, добавляя в начале адрес приложения.</p> <p>Оригинал решения: <a href="https://customerfx.com/article/how-to-format-a-url-as-a-clickable-link-in-a-text-field-in-creatio/">How to Format a URL as a Clickable Link in a Text Field in Creatio</a></p> <p>Обсудить в <a href="https://t.me/gglpru/16">Telegram</a></p> <p>Если на карточке в текстовом поле вставить ссылку на веб-страницу, она будет отображаться как обычный текст. Чтобы сделать ссылку кликабельной, надо добавить несколько блоков кода в схему карточки (подразумеваем, что текстовое поле уже добавлено в объект и выведено на карточку).</p> <p>Например, надо сделать кликабельной ссылку на собрание в zoom.</p> <p><img src="https://gglp.ru/images/012_01.png" alt="" /></p> <h3>Задача</h3> <p>Кликабельная ссылка в текстовом поле</p> <h3>Решение</h3> <ol> <li>Добавить поле на карточку через мастер раздела. Для примера пусть это будет поле <code>gglpZoomLink</code></li> <li>Добавить следующий код в блок кода <code>values</code> нашего поля:<br /><code>"showValueAsLink": true,</code><br /><code>"href": {</code><br /><code>    "bindTo": "UsrUrlFieldName",</code><br /><code>    "bindConfig": {"converter": "getLinkFormat"}</code><br /><code>},</code><br /><code>"controlConfig": {</code><br /><code>    "className": "Terrasoft.TextEdit",</code><br /><code>    "linkclick": { bindTo: "onLinkClick"}</code><br /><code>}</code></li> <li>Добавить следующий код в блок кода <code>methods</code>:<br /><code>getLinkFormat: function(value) {</code><br /><code>    return {</code><br /><code>        "url": value,</code><br /><code>        "caption": value</code><br /><code>    };</code><br /><code>},</code><br /><code> </code><br /><code>onLinkClick: function(url) {</code><br /><code>    var link = document.createElement("a");</code><br /><code>    link.href = url;</code><br /><code>    link.target = "_blank";</code><br /><code>    document.body.appendChild(link);</code><br /><code>    link.click();</code><br /><code>    document.body.removeChild(link);</code><br /><code>    return false;</code><br /><code>}</code></li> </ol> <h3>Объяснение</h3> <p>Итоговый вид кода страницы получился примерно такой:</p> <p><img src="https://gglp.ru/images/012_02.png" alt="" /></p> <p>Из метода getLinkFormat возвращаются значения двух переменных (можно задавать отдельно ссылку и текст ссылки), но мы используем ссылку для отображения без преобразований.</p> <p>В методе onLinkClick использовано динамическое формирование элемента &lt;a&gt;, чтобы избежать блокировки всплывающих окон браузером.</p> <p>Что интересно, если указывать ссылку без протокола (https://), она будет отображаться как относительная, добавляя в начале адрес приложения.</p> <p>Оригинал решения: <a href="https://customerfx.com/article/how-to-format-a-url-as-a-clickable-link-in-a-text-field-in-creatio/">How to Format a URL as a Clickable Link in a Text Field in Creatio</a></p> <p>Обсудить в <a href="https://t.me/gglpru/16">Telegram</a></p> Отключение процессов на системе заказчика 2021-07-19T20:20:30+03:00 2021-07-19T20:20:30+03:00 https://gglp.ru/home/howto/3-otklyuchenie-protsessov-na-sisteme-zakazchika Фёдоров Александр <p>В проектах бывает необходимость отключить штатный ("коробочный") процесс - заменить его на свой или перенести функциональность в Кейс. Есть варианты быстрый и правильный:</p> <ol> <li>Быстрый - это в дизайнере процессов выключить процесс (снять признак Активный). Однако это надо будет делать на каждом окружении (и клиентских тоже), что само по себе уже неудобно. К тому же со временем необходимость выключения процесса забывается и можно получить нестабильное поведение системы при отработке сигнала.</li> <li>Правильный - это создать замещающий процесс и заменить в нём стартовый сигнал на обычный.</li> </ol> <p>Первый можно использовать для быстрого тестирования или проверки гипотезы на одном из окружений. Если же требуется совсем отключить процесс, то надо использовать второй.</p> <p><img src="https://gglp.ru/images/003_01.png" alt="" /></p> <h3>Задача</h3> <p>Автоматически отключить штатный процесс на всех окружениях.</p> <p>Например, мы хотим отключить процесс дисквалификации Лида.</p> <h3>Решение</h3> <p>Опубликовать новую версию штатного процесса с привязкой его в проектный пакет:</p> <ol> <li>В Библиотеке процессов находим процесс, стартующий по сигналу от объекта системы<br /><img src="https://gglp.ru/images/003_02.png" alt="" /></li> <li>Изменяем в нём стартовый сигнал на обычный (как в первом изображении заметки) и сохраняем новую версию (конечно перед выполнением задачи надо было проверить текущий пакет в системных настройках).<br /><img src="https://gglp.ru/images/003_03.png" alt="" /></li> </ol> <h3>Описание</h3> <p>Изменения между системами переносятся пакетами. В современных версиях Creatio есть отличный механизм версионирования процессов, позволяющий, при необходимости, возвращаться к предыдущим версиям.</p> <p>Обсудить в <a href="https://t.me/gglpru/15">Telegram</a></p> <p>В проектах бывает необходимость отключить штатный ("коробочный") процесс - заменить его на свой или перенести функциональность в Кейс. Есть варианты быстрый и правильный:</p> <ol> <li>Быстрый - это в дизайнере процессов выключить процесс (снять признак Активный). Однако это надо будет делать на каждом окружении (и клиентских тоже), что само по себе уже неудобно. К тому же со временем необходимость выключения процесса забывается и можно получить нестабильное поведение системы при отработке сигнала.</li> <li>Правильный - это создать замещающий процесс и заменить в нём стартовый сигнал на обычный.</li> </ol> <p>Первый можно использовать для быстрого тестирования или проверки гипотезы на одном из окружений. Если же требуется совсем отключить процесс, то надо использовать второй.</p> <p><img src="https://gglp.ru/images/003_01.png" alt="" /></p> <h3>Задача</h3> <p>Автоматически отключить штатный процесс на всех окружениях.</p> <p>Например, мы хотим отключить процесс дисквалификации Лида.</p> <h3>Решение</h3> <p>Опубликовать новую версию штатного процесса с привязкой его в проектный пакет:</p> <ol> <li>В Библиотеке процессов находим процесс, стартующий по сигналу от объекта системы<br /><img src="https://gglp.ru/images/003_02.png" alt="" /></li> <li>Изменяем в нём стартовый сигнал на обычный (как в первом изображении заметки) и сохраняем новую версию (конечно перед выполнением задачи надо было проверить текущий пакет в системных настройках).<br /><img src="https://gglp.ru/images/003_03.png" alt="" /></li> </ol> <h3>Описание</h3> <p>Изменения между системами переносятся пакетами. В современных версиях Creatio есть отличный механизм версионирования процессов, позволяющий, при необходимости, возвращаться к предыдущим версиям.</p> <p>Обсудить в <a href="https://t.me/gglpru/15">Telegram</a></p> Деактивация имеющихся записей в справочниках 2021-07-20T15:50:28+03:00 2021-07-20T15:50:28+03:00 https://gglp.ru/home/howto/8-deaktivatsiya-imeyushchikhsya-zapisej-v-spravochnikakh Фёдоров Александр <p><img src="https://gglp.ru/images/008_01.png" alt="" /></p> <h3>Задача</h3> <p>Сделать недоступными для пользователя (скрыть / удалить) на целевой системе существующие записи в справочнике.</p> <p>Наиболее часто возникает при настройке кейсов по статусной модели.</p> <p>Например, необходимо скрыть, показанные на скриншоте, коробочные значения:</p> <ul> <li>1. Оформление</li> <li>2. Согласование</li> <li>3. Исполнение</li> <li>4. Завершен</li> <li>5. Отменен</li> </ul> <p>Так, чтобы остались и использовались только новые значения:</p> <ul> <li>1. Зарезервирован</li> <li>2. Упакован</li> <li>3. Отгружен</li> <li>4. Доставлен</li> <li>10. Отменен покупателем</li> <li>13. Возвращен покупателем</li> </ul> <h3>Решение</h3> <ol> <li>Включаем в справочнике возможность деактивации записей<br /><img src="https://gglp.ru/images/008_02.png" alt="" /> <ol> <li>Добавляем Замещающий объект</li> <li>Выбираем исходный объект</li> <li>Включаем для него возможность деактивации записей в блоке Поведение - Разрешить деактивацию записей</li> <li>Сохраняем, публикуем</li> </ol> </li> <li>Деактивируем коробочные записи<br /><img src="https://gglp.ru/images/008_03.png" alt="" /> <ol> <li>Выводим колонку Деактивирована в реестр значений справочника</li> <li>Устанавливаем значение поля = Да для лишних записей</li> </ol> </li> <li>Привязываем данные к пакету<br /><img src="https://gglp.ru/images/008_04.png" alt="" /></li> </ol> <h3>Объяснение</h3> <p>Удаление записей через пакет можно перенести только с помощью SQL-скрипта. Однако само по себе удаление коробочных записей не самая хорошая идея, т.к. на них может быть завязана логика приложения (те же статусы могут использоваться в кейсах).</p> <p>Поэтому лучше сами записи оставлять, но не отображать их пользователю.</p> <p>Деактивированные записи не появляются в фильтрах, их нельзя выбрать в выпадающих списках на карточках. Но в реестре записей справочника они отображаются.</p> <p>Если для раздела / справочника включено управление правами по записям, дополнительно можно снимать права на просмотр (в дополнение к изменению / удалению) деактивированных записей. Тогда их не будет видно и в реестре.</p> <p>Обсудить в <a href="https://t.me/gglpru/11">Telegram</a></p> <p><img src="https://gglp.ru/images/008_01.png" alt="" /></p> <h3>Задача</h3> <p>Сделать недоступными для пользователя (скрыть / удалить) на целевой системе существующие записи в справочнике.</p> <p>Наиболее часто возникает при настройке кейсов по статусной модели.</p> <p>Например, необходимо скрыть, показанные на скриншоте, коробочные значения:</p> <ul> <li>1. Оформление</li> <li>2. Согласование</li> <li>3. Исполнение</li> <li>4. Завершен</li> <li>5. Отменен</li> </ul> <p>Так, чтобы остались и использовались только новые значения:</p> <ul> <li>1. Зарезервирован</li> <li>2. Упакован</li> <li>3. Отгружен</li> <li>4. Доставлен</li> <li>10. Отменен покупателем</li> <li>13. Возвращен покупателем</li> </ul> <h3>Решение</h3> <ol> <li>Включаем в справочнике возможность деактивации записей<br /><img src="https://gglp.ru/images/008_02.png" alt="" /> <ol> <li>Добавляем Замещающий объект</li> <li>Выбираем исходный объект</li> <li>Включаем для него возможность деактивации записей в блоке Поведение - Разрешить деактивацию записей</li> <li>Сохраняем, публикуем</li> </ol> </li> <li>Деактивируем коробочные записи<br /><img src="https://gglp.ru/images/008_03.png" alt="" /> <ol> <li>Выводим колонку Деактивирована в реестр значений справочника</li> <li>Устанавливаем значение поля = Да для лишних записей</li> </ol> </li> <li>Привязываем данные к пакету<br /><img src="https://gglp.ru/images/008_04.png" alt="" /></li> </ol> <h3>Объяснение</h3> <p>Удаление записей через пакет можно перенести только с помощью SQL-скрипта. Однако само по себе удаление коробочных записей не самая хорошая идея, т.к. на них может быть завязана логика приложения (те же статусы могут использоваться в кейсах).</p> <p>Поэтому лучше сами записи оставлять, но не отображать их пользователю.</p> <p>Деактивированные записи не появляются в фильтрах, их нельзя выбрать в выпадающих списках на карточках. Но в реестре записей справочника они отображаются.</p> <p>Если для раздела / справочника включено управление правами по записям, дополнительно можно снимать права на просмотр (в дополнение к изменению / удалению) деактивированных записей. Тогда их не будет видно и в реестре.</p> <p>Обсудить в <a href="https://t.me/gglpru/11">Telegram</a></p> Локальное доменное имя 2021-07-20T14:44:31+03:00 2021-07-20T14:44:31+03:00 https://gglp.ru/home/howto/7-local-domain-name Фёдоров Александр <p> <img src="https://gglp.ru/images/loalDomainName01.png" alt="" /></p> <h3>Задача</h3> <p>Сделать так, чтобы локальное приложение работало по доменному имени, а не по IP-адресу + порту.</p> <p>Например, чтобы приложение открывалось не по адресу <a href="http://192.168.1.1:81/,">http://192.168.1.1:81/</a> и не по адресу <a href="http://localhost:81/">http://localhost:81/</a>, а по адресу <a href="http://agile.bequiet.gglp.ru/">http://agile.bequiet.gglp.ru/</a></p> <h3>Решение</h3> <p>Необходимо настроить трансляцию своего доменного имени в локальный IP адрес и настроить привязку сайта на IIS-сервере к своему доменному имени.</p> <ol> <li>Переходим в настройки сайта на IIS-сервере, кликаем на пункт <strong>Привязки</strong> в меню <strong>Изменение веб-сайта</strong>, добавляем доменное имя, по которому мы хотим обращаться к сайту (в нашем примере agile.bequiet.gglp.ru), без протокола http или https, указываем стандартный порт (80 - для http, 443 - для https). Сохраняем.<br /><img src="https://gglp.ru/images/loalDomainName02.png" alt="" /></li> <li>Добавляем трансляцию доменного имени в локальный IP-адрес в файле <a href="https://ru.wikipedia.org/wiki/Hosts">hosts</a>.<br />Файл расположен по пути C:\Windows\System32\drivers\etc\hosts, открывать с правами администратора.<br />В конец файла добавляем строку<br /><code>127.0.0.1  agile.bequiet.gglp.ru</code></li> </ol> <p>Теперь приложение должно открываться по доменному имени. Будет работать только с локального компьютера.</p> <h3>Описание</h3> <p>При разрешении доменного имени в IP-адрес, система сначала смотрит настройки локального файла hosts, а только затем обращается к dns-серверу. Можно сразу указать нужный нам домен и транслировать его в локальный IP-адрес без необходимости обращения к dns-серверу (а перед этим регистрации доменного имени, настройки трансляции, проброски портов на роутере и т.п.).</p> <p>IIS умеет проксировать запросы в рамках определённого доменного имени на нужный сайт. Достаточно настроить привязку имени к сайту.</p> <p>Дополнительный плюс - на одном стандартном порту - 80 или 443, может работать любое количество сайтов / веб-приложений.</p> <p>Чтобы открывать приложение с другого компьютера в локальной сети можно на другом компьютере в файле hosts указать не 127.0.0.1, а локальный IP-адрес компьютера, на котором развёрнуто приложение. В нашем примере это 192.168.1.1</p> <p>Обсудить в <a href="https://t.me/gglpru/10">Telegram</a></p> <p> <img src="https://gglp.ru/images/loalDomainName01.png" alt="" /></p> <h3>Задача</h3> <p>Сделать так, чтобы локальное приложение работало по доменному имени, а не по IP-адресу + порту.</p> <p>Например, чтобы приложение открывалось не по адресу <a href="http://192.168.1.1:81/,">http://192.168.1.1:81/</a> и не по адресу <a href="http://localhost:81/">http://localhost:81/</a>, а по адресу <a href="http://agile.bequiet.gglp.ru/">http://agile.bequiet.gglp.ru/</a></p> <h3>Решение</h3> <p>Необходимо настроить трансляцию своего доменного имени в локальный IP адрес и настроить привязку сайта на IIS-сервере к своему доменному имени.</p> <ol> <li>Переходим в настройки сайта на IIS-сервере, кликаем на пункт <strong>Привязки</strong> в меню <strong>Изменение веб-сайта</strong>, добавляем доменное имя, по которому мы хотим обращаться к сайту (в нашем примере agile.bequiet.gglp.ru), без протокола http или https, указываем стандартный порт (80 - для http, 443 - для https). Сохраняем.<br /><img src="https://gglp.ru/images/loalDomainName02.png" alt="" /></li> <li>Добавляем трансляцию доменного имени в локальный IP-адрес в файле <a href="https://ru.wikipedia.org/wiki/Hosts">hosts</a>.<br />Файл расположен по пути C:\Windows\System32\drivers\etc\hosts, открывать с правами администратора.<br />В конец файла добавляем строку<br /><code>127.0.0.1  agile.bequiet.gglp.ru</code></li> </ol> <p>Теперь приложение должно открываться по доменному имени. Будет работать только с локального компьютера.</p> <h3>Описание</h3> <p>При разрешении доменного имени в IP-адрес, система сначала смотрит настройки локального файла hosts, а только затем обращается к dns-серверу. Можно сразу указать нужный нам домен и транслировать его в локальный IP-адрес без необходимости обращения к dns-серверу (а перед этим регистрации доменного имени, настройки трансляции, проброски портов на роутере и т.п.).</p> <p>IIS умеет проксировать запросы в рамках определённого доменного имени на нужный сайт. Достаточно настроить привязку имени к сайту.</p> <p>Дополнительный плюс - на одном стандартном порту - 80 или 443, может работать любое количество сайтов / веб-приложений.</p> <p>Чтобы открывать приложение с другого компьютера в локальной сети можно на другом компьютере в файле hosts указать не 127.0.0.1, а локальный IP-адрес компьютера, на котором развёрнуто приложение. В нашем примере это 192.168.1.1</p> <p>Обсудить в <a href="https://t.me/gglpru/10">Telegram</a></p> Как в процессе добавить несколько стартовых сигналов 2021-07-16T11:17:41+03:00 2021-07-16T11:17:41+03:00 https://gglp.ru/home/howto/1-kak-v-protsesse-dobavit-neskolko-startovykh-signalov Фёдоров Александр <p>Бывает, что в бизнес-процессах необходимо выполнить одни и те же операции при получении разных сигналов от объекта - создание, изменение, удаление. Чтобы не создавать несколько разных бизнес-процессов, можно создать один процесс с несколькими стартовыми сигналами.</p> <h3><img src="https://gglp.ru/images/MultipleStartSignals.png" alt="Схема бизнес-процесса с несколькими стартовыми сигналами" /></h3> <h3>Задача</h3> <p>Учесть в бизнес-процессе несколько стартовых событийных сигналов.</p> <h3>Решение</h3> <ol> <li>Добавляем нужные стартовые сигналы, заводим их в один шаг Читать данные</li> <li>В шаге Читать данные заполняем фильтры по Id равным Id записей в стартовых сигналах с группировкой в режиме ИЛИ</li> </ol> <h3>Объяснение</h3> <p>По умолчанию Id записей в обоих стартовых сигналах равны null. При срабатывании одного из сигналов в нём заполняется значение Id (например, <code>04f4707e-122b-4dc7-9c70-aaf8f1cbfe14</code>), и при группировке ИЛИ в фильтре выбора нужной записи мы будем получать условие:</p> <p><code>WHERE Id = '04f4707e-122b-4dc7-9c70-aaf8f1cbfe14' OR Id is null</code></p> <p>Т.к. поле Id во всех записях системное и обязательное для заполнения, оно не может быть равно null, соответственно в результате всегда будет выдаваться только одна запись с указанным Id.</p> <p>Обсудить в <a href="https://t.me/gglpru/8">Telegram</a></p> <p>Бывает, что в бизнес-процессах необходимо выполнить одни и те же операции при получении разных сигналов от объекта - создание, изменение, удаление. Чтобы не создавать несколько разных бизнес-процессов, можно создать один процесс с несколькими стартовыми сигналами.</p> <h3><img src="https://gglp.ru/images/MultipleStartSignals.png" alt="Схема бизнес-процесса с несколькими стартовыми сигналами" /></h3> <h3>Задача</h3> <p>Учесть в бизнес-процессе несколько стартовых событийных сигналов.</p> <h3>Решение</h3> <ol> <li>Добавляем нужные стартовые сигналы, заводим их в один шаг Читать данные</li> <li>В шаге Читать данные заполняем фильтры по Id равным Id записей в стартовых сигналах с группировкой в режиме ИЛИ</li> </ol> <h3>Объяснение</h3> <p>По умолчанию Id записей в обоих стартовых сигналах равны null. При срабатывании одного из сигналов в нём заполняется значение Id (например, <code>04f4707e-122b-4dc7-9c70-aaf8f1cbfe14</code>), и при группировке ИЛИ в фильтре выбора нужной записи мы будем получать условие:</p> <p><code>WHERE Id = '04f4707e-122b-4dc7-9c70-aaf8f1cbfe14' OR Id is null</code></p> <p>Т.к. поле Id во всех записях системное и обязательное для заполнения, оно не может быть равно null, соответственно в результате всегда будет выдаваться только одна запись с указанным Id.</p> <p>Обсудить в <a href="https://t.me/gglpru/8">Telegram</a></p>