Хаутушкиhttps://gglp.ru/home/howto2026-10-26T18:35:48+03:00Фёдоров АлександрJoomla! - Open Source Content ManagementОстановка ранее запущенных экземпляров процесса2021-08-18T09:14:22+03:002021-08-18T09:14:22+03:00https://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:002021-07-20T18:06:30+03:00https://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 использовано динамическое формирование элемента <a>, чтобы избежать блокировки всплывающих окон браузером.</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 использовано динамическое формирование элемента <a>, чтобы избежать блокировки всплывающих окон браузером.</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:002021-07-19T20:20:30+03:00https://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:002021-07-20T15:50:28+03:00https://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:002021-07-20T14:44:31+03:00https://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:002021-07-16T11:17:41+03:00https://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>