Скажем, есть асинхронный метод в разделе Methods, ну или в пакете сервис с ними лежит. И надо это как-то вызвать внутри бизнес-процесса в блоке ScriptTask, но ведь, если я правильно понимаю, код внутри этого скрипт таска идёт в ScriptTask1Execute(), а тот в свою очередь синхронный и повлиять на это никак нельзя. Всё правильно или я что-то не так понимаю?

Нравится

2 комментария

Добрый день!

Рекомендую вам в БП вместо ScriptTask вызвать элементом подпроцесс, который будет фоновым и он выполнится в параллельном потоке.

В систетеме стоит использовать фоновые процессы и с процесса вызвать подпроцесс фоновый. Статьи про фоновые процессы, в которых есть примеры кода для реализации вашей задачи:

https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/back-end-development/data-operations-back-end/execute-operations-in-the-background/overview

https://academy.creatio.com/docs/8.x/dev/development-on-creatio-platform/back-end-development/data-operations-back-end/execute-operations-in-the-background/examples/register-a-background-operation

Anhelina,



Добрый день! Прочитал статьи, но что-то не совсем понял, как там с асинхронным кодом работать. Метод Run(), что находится внутри IBackgroundTask, ведь синхронный. Единственный способ, что я вижу, чтобы в нём был асинхронный код - это вызывать его синхронно, условно

 

public void Run(UsrActivityData data) {
        var task = DoSmthAsync();
        task.Wait();
        return task.Result;
}

Я для решения своей задачи изначально планировал просто сделать отдельный класс с синхронными методами(которые будут вызываться из СкриптТаска), где точно так же, как на моём примере выше, будут вызываться нужные мне асинхронные. Но это в любом случае вызов аснхронного из синхронного, что плохо и что я пытаюсь понять, можно ли избежать. Здесь есть какое-то преимущество при использовании IBackgroundTask или я не так понял, как им пользоваться?

Показать все комментарии

Есть пакет, в котором есть класс, что наследуется от интерфейса IAppEventListener, в нём своя логика для OnAppStart, OnAppEnd, OnSessionStart, OnSessionEnd. В рамках другого пакета мне понадобилось добавить свою логику в OnAppStart, соотетственно в нём я хочу сделать свой класс с наследованием от этого интерфейса. Но меня интересует, является ли такой подход рекоммендуемым? Не будет ли проблем от того, что в двух разных пакетах запускаются свои разные OnAppStart?

Нравится

2 комментария
Лучший ответ

Добрый день,

Такой подход не должен вызвать проблем, вы можете его обнаружить даже в базовых схемах, например ProcessMaintenanceEventListener и GlobalSearchEventListener. Они находятся в разных пакетах и в них используется OnAppStart

Добрый день,

Такой подход не должен вызвать проблем, вы можете его обнаружить даже в базовых схемах, например ProcessMaintenanceEventListener и GlobalSearchEventListener. Они находятся в разных пакетах и в них используется OnAppStart

Дима Вовченко,



Понял, спасибо.

Показать все комментарии

Добрый день. Вопрос по поводу синхронизации с Google Календарем.

Настроена синхронизация и частично работает. 

Задачи созданные в Creatio при синхронизации появляются в GКалендаре. Если изменить в Задаче время, изменится и в GКалендаре.

Но Задачи созданные в GКалендаре при синхронизации не появляются в Creatio.

Так же, при удалении задачи в Creatio задача GКалендаре не удаляется.

Подскажите куда смотреть, в чем может быть проблема?

Нравится

2 комментария

Добрый день.

В данном вопросе необходимо проанализировать логи приложения в момент синхронизации задач созданных в GКалендаре.

 

Дополнительно, на время анализа, можно включить логгер Calendar на уровне отладки и проверить логи за время этой синхронизации. 

Для этого можно добавить строку в файл nlog.cloud:

< logger name=" Calendar " minlevel="Debug" writeTo="AdoNetBufferedAppender" />

 

Для более детального точечного анализа рекомендуем обратится в <support@creatio.com>.

Показать все комментарии

Добрий день. 

Підкажіть, будь ласка, як у валідаторі поріняти значення поля до я кого прив'язаний валідатор з іншим полем. 

Приклад. На сторінці (Freedom UI) є дві дати:

Дата завершення проекту

Дата завершення завдання, 

Потрібно налаштувати валідацію поля "Дата завершення завдання", щоб вона не перевищувала дату завершення проетку. 







"usr.UniversalDateValidator": {

        validator: function (config) {

        return function (control) {

            let minValue = new Date(config.minValue);

            let controlDate = new Date(control.value);

            let isDateValid = controlDate >= minValue;

            var result;

            if (isDateValid) {

                result = null;

            } else {

                result = {

                    "usr.UniversalDateValidator": { 

                        message: config.message || "Введена дата не відповідає умовам"

                    }

                };

            }

            return result;

        };

    },

    params: [

        {

            name: "minValue"

        },

        {

            name: "message"

        }

    ],

    async: false

}

Нравится

3 комментария

Добрий день,

 

При умові, що дві дати отримано коректно, далі треба використати стандартний підхід до порівняння двох дат в JS (наприклад, як описано ось тут https://www.freecodecamp.org/news/javascript-date-comparison-how-to-com…), а на основі порівняння проставляти isDateValid значення.

Oscar Dylan,

Дякую, не зовісім коректно сформулював питання.  Мене цікавть якраз як коректно отримати другу дату у коді валідатора. Допоможіть, будь ласка. 

Oscar Dylan,

Я пробую отак:

var timeStartValue = control.parent.get("DateTimeAttribute_84s5bhk").value;

але отримую помилку Cannot read properties of undefined (reading 'get') Cannot read properties of undefined (reading 'get)

Показать все комментарии

Допоможіть, будь ласка, розібратись з валідаторам.

Прив'язав валідатор до поля типу ДатаЧас у сторінці створення запису. Сторінка відкривається, алідатор працює,  але через частинку коду у блоці viewModelConfigDiff не відкривається дизайнер цієї сторінки (Якщо цю частину закоментувати - відкривається). Використаний код додаю. 



У блоці стоінки viewModelConfigDiff прив'язав валідатор до поля



"DateTimeAttribute_qc2mfzm": {

                        "modelConfig": {

                            "path": "UsrAppNewTasksDS.UsrDateDeadline"

                        },

                        

                        

                        "validators": {

                                   "MyDateValidator": {

                                        "type": "usr.UniversalDateValidator",

                                            "params": {

                                                        "minValue": new Date(new Date().getTime() + (3 * 60 * 60 * 1000)), 

                                                        "message": "Термін виконання завдання не може бути меншим ніж 3 години."

                                                    }

                                                        }

                                            }            

            

                        

                    },





В блоці validators: 



"usr.UniversalDateValidator": {

        validator: function (config) {

        return function (control) {

            let minValue = new Date(config.minValue);

            let controlDate = new Date(control.value);

            let isDateValid = controlDate >= minValue;

            var result;

            if (isDateValid) {

                result = null;

            } else {

                result = {

                    "usr.UniversalDateValidator": { 

                        message: config.message || "Введена дата не відповідає умовам"

                    }

                };

            }

            return result;

        };

    },

    params: [

        {

            name: "minValue"

        },

        {

            name: "message"

        }

    ],

    async: false

}

            

               

Нравится

2 комментария
Лучший ответ

Проблема в "minValue": new Date(new Date().getTime() + (3 * 60 * 60 * 1000)), в параметрах валідатора в атрибуті. Якщо його прописати текстом (наприклад "2023-12-10"), то дизайнер відкривається. Перенесіть, будь ласка, цю перевірку в середину логіки валідатора (там де if (isDateValid) {), а не передавайте в config.

Добрий день,

 

Яка помилка виникає при спробі відкрити дизайнер (в консолі)? Ви робили відладку помилки?

Проблема в "minValue": new Date(new Date().getTime() + (3 * 60 * 60 * 1000)), в параметрах валідатора в атрибуті. Якщо його прописати текстом (наприклад "2023-12-10"), то дизайнер відкривається. Перенесіть, будь ласка, цю перевірку в середину логіки валідатора (там де if (isDateValid) {), а не передавайте в config.

Показать все комментарии

Пытался вспомнить, как из скрипта получить доступ к данным, прочитанным в Read Data, наткнулся на этот вопрос - https://community.creatio.com/questions/how-get-read-data-fields-script…



Здесь именно тот подход, что я и хотел вспомнить, но при этом автор ответа в своём ответе утверждает, что на проде таким лучше не пользоваться. Мой вопрос в том, действительно ли это плохой подход? Какие именно в нём проблемы? Если отказаться от него, то остаётся только класть нужные значение в переменные бизнес-процесса, а потом в скрипте доставать их через this.get ?

Нравится

2 комментария

Здравствуйте, Александр!

Лучше использовать параметры процесса, так как это делает БП более универсальным. Если мы передаём сразу определенные значения в процесс, а через некоторое время произведем изменения значения в приложении, то БП будет падать с ошибкой. К примеру: удалим переданный в процесс id контакта, то БП запустится, не найдет указанный ранее контакт и не отработает корректно в итоге.

В случае передачи параметра – мы указываем точное место поиска необходимого элемента, а не его имя. Можно прямо в параметре процесса сказать, что нужно взять колонку из ReadData элемента, при обращении к этому параметру. Таким образом мы можем использовать БП повторно для нескольких задач.

Get/Set методы действительно являются самыми проверенными и точными для передачи данных в Script task БП.

П.С. В этих статьях с академии вы можете подробно прочитать про Read data и Script task.

Anhelina пишет:

Можно прямо в параметре процесса сказать, что нужно взять колонку из ReadData элемента, при обращении к этому параметру

Не совсем понял эту часть. Есть параметр процесса, где-то в процессе есть ReadData, и в этом параметре вы указываете, как значение, колонку из ReadData, правильно? Если так, то разве не будет проблемы в том, что параметры процесса инициализируются в начале работы процесса, когда ReadData ещё не выполнился, что приведёт к тому, что в параметре пустота будет записана?

Показать все комментарии

пробували налаштували відправлення пуш-сповіщень на телефон про отримання нового звернення на відповідального, але вони не приходять хоча в журналі БП відображає, що БП відпрацював без помилок



Изображение удалено.

Використовували інструкцію з сайту: 

https://academy.terrasoft.ua/docs/user/biznes_processy/primery_nastrojk…



Можливо хтось зіштовхувався з даною проблемою?

 

Нравится

2 комментария

Добрий день,

 

Просимо вас звернутися напряму у нашу тех підтримку, написавши на пошту support@creatio.com, оскільки нам необіхдно детально проаналізувати вашу проблему з доступом до вашого веб сайту для того, щоб зрозуміти у чому полягає проблема такої поведінки. 

 

Дякуємо.

В мене схожа складність з портальними користувачами.  Якщо дію, що запускає процес виконує портальний користувач - сповіщення не приходить, хоча процес відпрацьовує (В журналі процесів успішно завершений). В моїй ситуації допомогло надати права на читання об'кта SysAdminUnit портальним користувачам. 

Показать все комментарии

Есть поле на edit странице объекта, добавлено туда через визард страницы, этому полю я хочу добавить обязательность + свои кастомные валидации. Сделать поле обязательным, конечно, можно было бы в визарде через бизнес-правила, но я не хочу мешать это с кастомными валидациями, поэтому и то, и то сделал в коде страницы через asyncValidate. Валидации работают, но у поля в таком случае нет этой красной звёздочки, символизирующей обязательность заполнения этого поля. Можно ли её как-то добавить без использования бизнес-правил?

Нравится

2 комментария
Лучший ответ

Чтобы оно появилось, вы должны IsRequired прописать в атрибутах и в diff

                attributes: {

                    "UrsField": {

                        "isRequired": true

                },

                diff: /**SCHEMA_DIFF*/ [

                    {

                        "operation": "insert",

                        "name": "UrsField",

                        "values": {

                            "layout": {

                                "colSpan": 13,

                                "rowSpan": 1,

                                "column": 11,

                                "row": 4,

                                "layoutName": "GoalContainer"

                            },

                            "isRequired": true,

                        },

                        "parentName": "GoalContainer",

                        "propertyName": "items"

                    }

                ] /**SCHEMA_DIFF*/ ,

Чтобы оно появилось, вы должны IsRequired прописать в атрибутах и в diff

                attributes: {

                    "UrsField": {

                        "isRequired": true

                },

                diff: /**SCHEMA_DIFF*/ [

                    {

                        "operation": "insert",

                        "name": "UrsField",

                        "values": {

                            "layout": {

                                "colSpan": 13,

                                "rowSpan": 1,

                                "column": 11,

                                "row": 4,

                                "layoutName": "GoalContainer"

                            },

                            "isRequired": true,

                        },

                        "parentName": "GoalContainer",

                        "propertyName": "items"

                    }

                ] /**SCHEMA_DIFF*/ ,

Ислам Ибрагимжанов,

спасибо, всё работает.

Показать все комментарии

Добрый день. Развернули в Docker сервис глобального поиска согласно инструкции https://academy.creatio.com/docs/8.x/setup-and-administration/on-site-deployment/containerized-components/global-search#title-254-33 

 

Подключили сайт 8010.salesup-it.com - работает.

При попытке настоить аналогичным способом сайт driveforce.salesup-it.com ошибка:

Изображение удалено.

сайт зарегестрирован в elasticsearch 

Изображение удалено.

но проверка статуса выдает ошибку

Изображение удалено.

 

В процессе настройки сайт driveforce.salesup-it.com регистрировался (команды curl -v -X POST -d '{"databaseType": "[DATABASE_TYPE]", "databaseConnectionString": "[DATABASE_CONNECTION_STRING]"}' -H "Content-Type: application/json"  http://10.10.20.26:81/sites/driveforce.salesup-it.com и curl -v -X POST -d '{"templateName": "default.json"}' -H "Content-Type: application/json" http://10.10.20.26:81/sites/driveforce.salesup-it.com/search) в elasticsearch, удалялся (команда curl -v -X DELETE http://10.10.20.26:81/sites/driveforce.salesup-it.com) и снова добавлялся. Судя по ошибке я понял, что остался след от предыдущей регистрации и надо удалить item с таким же ключем, подскажите где и как это сделать?

Нравится

3 комментария

Добрый день!

 

Судя по описанной проблеме, возможно, Вы пропустили использование параметра "DELETE​/sites​/{siteName}​/search". Ниже я опишу пошаговую последовательность передобавления сайта и шаблона через Swagger.  

 

Порядок настройки

  1. Зайти по адресу: [адрес_сервера_ГП]:81/api/index.html

  2. Выбрать параметр "DELETE​/sites​/{siteName}​/search"

 

- Нажать "Try iy out".

- Необходимо ввести название сайта, которое указывали при добавлении, и удалить поиск.

3. Выбрать параметр "DELETE​/sites​/{siteName}"

 

 

- Нажать "Try iy out".

- Необходимо ввести название сайта, которое указывали при добавлении, и удалить сайт.

 

***

4. Создаем новый сайт. Для этого используем параметр "POST​/sites​/{siteName}"

- Нажимаем "Try iy out".

- Необходимо ввести название нового сайта (Это может быть любой текст).

- Необходимо в теле запроса указать тип СУБД и строку подключения к БД сайта.

 

5. Указываем для сайта шаблон. Для этого используем параметр "POST​/sites​/{siteName}".

- Нажать "Try iy out".

- Необходимо ввести название сайта, который создали на прошлом шаге.

- В теле запроса нужно удалить все параметры, кроме templateName (Пример добавления дефолтного шаблона, все шаблоны описаны в статье).

 

6. В системной настройке "GlobalSearchUrl" необходимо указать значение, которое вернет предыдущий запрос.

7. Перезапуск приложения и чистка редиса.

8. Чтобы запустить вручную переиндексацию, можно выполнить запрос в консоль браузера:

require(["ServiceHelper"], (ServiceHelper) => {    ServiceHelper.callService("IndexingConfigService", "SendIndexationConfigs");});

Zhmurko Sergii,

Добрый день, спасибо за ответ.

Увы, рекомендация не помогла. После удаления сайта "DELETE​/sites​/{siteName}​/search", "DELETE​/sites​/{siteName}​" и добавления заново ошибка прежняя.

Возможно надо удалять что-то в базе сайта? Попробовал переименовать сайт (изменил только bind, connection string остался прежним) и зарегистрировал под другим именем (было: driveforce, стало: drive-force) но все та же ошибка: 

Решено: Оказалоcь, что в базе сайта задублировались значения "GlobalSearchUrl", "GlobalSearchConfigServiceUrl" и "GlobalSearchIndexingApiUrl".

Запрос для PostgreSQL:

 

--посмотреть записи с кодом GlobalSearchUrl

SELECT *

FROM "SysSettingsValue"

WHERE "SysSettingsId" = (SELECT "Id" FROM "SysSettings" WHERE "Code" = 'GlobalSearchUrl' LIMIT 1);

 

--удалить строку используя id

DELETE FROM "SysSettingsValue"

WHERE "Id" = 'уникальный_Id_дублирующейся_строки';

 

повторить для "GlobalSearchConfigServiceUrl" и "GlobalSearchIndexingApiUrl" по аналогии с "GlobalSearchUrl".

Показать все комментарии

добрый день,

в приложении реализован функционал как указано здесь - https://community.terrasoft.ua/questions/kak-poluchit-kontakty-iz-dinam… . но это подход для старых фильтров которые были из 7.18.

в новом же интерфейсе добавили тоже фильтры, но они работают по другому принципу - записи храняться не в *Folder таблице.

можете подсказать как реализовать фильтрацию записей из сишарп кода используя пользовательские фильтры, созданные в новом Freedom UI интерфейсе?

спасибо!

Нравится

1 комментарий

Добрый день!

 

Папки, созданные в интерфейсе Freedom UI, хранятся в единой таблице «FolderTree».

Вы можете получить Id папки путем запроса к ней по имени папки (колонка «Name»)  и названию схемы объекта (колонка «EntitySchemaName»).

 

С уважением,

Наталия

Показать все комментарии