Коллеги, добрый день! Есть объект UsrOrder, в нем есть строковое поле JetOrderNumber. В конфигурации открываю этот объект, перехожу на вкладку События и включаю галочку "Перед сохранением записи" (UsrOrderSaving). Далее нажимаю на кнопку "Открыть процесс". Там создаю Событийный подпроцесс, начальным событием которого является Сообщение UsrOrderSaving, а после него создаю заданию-сценарий, в котором прописываю:

Entity.SetColumnValue("UsrOrderNumber", "новая запись");

throw new Exception("i123");

return true;

Далее сохраняю, публикую, компилирую. 

В итоге после сохранения поле UsrOrderNumber пустое, в консоли ничего нет, в Network ничего нет. Поможете мне понять почему ничего не происходит? Изображение удалено.

Нравится

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

Добрый день.

 

На первый взгляд все должно работать.

Но если у вас пакет-сборка, то нет, так как в пакетах-сборках не работают событийные-процессы.



Та и вообще процессы использовать последнее время практика устарела. Лучше писать логику на объектах с помощью EntityEventListener. Такая логика будет работать и в пакетах-сборках.

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

Здравствуйте

Хотелось бы узнать, как можно в событийном подпроцессе прервать сохранение. Например, на событии Inserting. Точно такой же вопрос обсуждался в теме https://community.terrasoft.ru/questions/proverka-polei-v-sobytiinom-po…, но там так и не было дано ответа. Вариант с завершающим элементом действительно не работает, проверка на клиенте не подходит, как и выкидывание Exception. Может кто-то знает, как правильно отменить дальнейшее выполнение события, в данном случае сохранения. 

Нравится

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

Ольга, здравствуйте!

Как раз правильно это делать одним из откинутым Вами способов.

Встроенные процессы для данной цели не предназначены (кроме как отправить exception).

Понятно, спасибо за ответ

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

Коллеги, добрый день!

Такой кейс: есть бизнес-процесс с несколькими задачами, которые создаю с помощью элемента бизнес-процесса «Выполнить задачу». Для примера, создаем такой процесс: при создании новой записи в разделе «Счета» запускается бизнес-процесс, состоящий из трех последовательных задач: «Уточнить юридический адрес Контрагента», «Отправить счет на оплату по почте» и «Ожидать оплату». Для заполнения параметров создаваемой активности «Читаю данные» из записи созданного Счёта, в том числе, в поле «Ответственный» создаваемых Активностей ставлю значение поля «Ответственный» из записи Счёта.

В реальной жизни, пока пользователь выполнял задачу, ответственный сотрудник по Счёту мог поменяться (уволился, перевёлся и т.д.). Логично, что при формировании следующей задачи следует в поле «Ответственный» поставить новое значение из Счёта. Однако для этого необходимо заново прочитать запись «Счёт» с помощью элемента «Читать данные». Таким образом, поскольку мы не знаем, когда будут изменены данные в Счёте, приходится перед каждым элементом задачи ставить элемент «Читать данные» и ориентироваться на него при создании новой Активности.

Хотела бы обсудить, какие еще варианты решения этого кейса есть. Напрашивается вытащить однотипные действия (в нашем случае – «Читать данные» Счёта) в отдельный событийный подпроцесс, но что бы я не делала, я не смогла запустить его более одного раза либо без ошибок.

Нравится

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

Проще всего именно так и делать - три раза читать данные. Просто и надежно.

Добрый день! 

Оптимальнее всего это будет сделать посредством бизнес-кейсов:

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

Также это избавит от необходимости создавать множество чтений данных.

Удачи!

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

Добрый день, коллеги!

Понадобилось реализовать следующий кейс - При добавлении участника встречи необходимо проверять, не задействован ли он в это время на другой встрече. Поскольку добавление участника - вставка записи в объект ActivityParticipant, решено было добавить в этот объект событийный подпроцесс, запускающийся по сигналу ActvityParticipantSaving. В событийном подпроцессе после сигнала идет скрипт, который будет делать запросы в базу и проверять пересечения с другими активностями нужного типа, после чего будет возвращать Id активности, в которой задействован этот участник, если нашелся конфликт, или просто null, если конфликтов не найдено. После этого встает несколько подзадач:
1) Как запретить при нахождении конфликта дальнейшее сохранение записи в базу;
2) Как вывести пользователю окно с ссылкой на активность, которая вызывает конфликт;
3) Как продолжить сохранение в нормальном режиме, если конфликт не найден.

Нашел переменную IsProcessModeSave, думал попробовать присваивать ей значение false.
Все темы, которые я нашел были устаревшими или не раскрывали сути вопроса.

Система sales enterprise 7.9.2

Нравится

6 комментариев

Добрый день, Олег!

Подобный кейс обсуждался еще здесь:
http://www.community.terrasoft.ru/forum/topic/9994#comment-43946
Не смотрите, что скрин из пятерки, логика ровно та же - если активностей в указанное время не найдено - сгенерировать событие, если нет - передать id встречи на клиент, и там уже сформировать ссылку на проблемную активность. Пример создания ссылки можно подсмотреть в createLink из GridUtilitiesV2, либо же просто захардкодить. После чего показать данную ссылку.

Добрый день, Илья!

Можно пожалуйста поподробнее, какое именно событие надо сгенерировать, чтобы продолжить сохранение в штатном режиме? Если я правильно понял из приложенной статьи, нужно просто сгенерировать опять то же событие, что и вызывает мой скрипт, это так? Если это событие в моем скрипте не будет сгенерировано, т.е. подпроцесс пойдет по второй ветке, запись не будет сохранена? Как из C# кода подпроцесса передать id встречи на клиента, через публикацию сообщения, а в схеме его ловить? Если да, то где можно посмотреть пример генерации сообщения для клиента из серверного кода?

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

Олег, по Вашим вопросам:

1) Да, то же событие
2) Да, не будет сохранена, так как фактически Вы заместите логику обработки сообщения
3) Да, есть отличный класс MsgChannelUtilities, у которого есть такие методы:

public static void PostMessage(UserConnection userConnection, string senderName, string messageText)
 
public static void PostMessageToAll(string senderName, string messageText)

Итого, в C# отправляем сообщение:

MsgChannelUtilities.PostMessage(UserConnection, "LimitBudget", accountId.ToString());

В JS на клиенте подписываемся на него и обрабатываем:

init: function(callback, scope) {
    this.Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE, this.onMessage, this);
},
 
onMessage: function(scope, message) {
if (message.Header.Sender === "LimitBudget") {
// do something
     }
},
 
destroy: function() {
    this.Terrasoft.ServerChannel.un(Terrasoft.EventName.ON_MESSAGE, this.onMessage, this);
    this.callParent   (arguments)
}

Добрый день!

Вернулся опять к этой задаче, отдебажил запросы в базу, теперь получаю следующую ошибку:

Процесс "ActivityEventProcess" остановлен. Превышено максимальное количество повторений элемента "Activity Saving". Если я правильно понимаю, то генерация такого же сообщения, по которому запускается подпроцесс, зацикливает его. Я точно правильно понял, какое сообщение нужно генерировать?

Здравствуйте, вашу задачу проще и корректней сделать на уровне JS, там же и выводить сообщение пользователю, а запросы в БД делать асинхронно. Данный алгоритм с асинхронной валидацией обсуждался в этой теме:
http://www.community.terrasoft.ru/forum/topic/25300#comment-67748

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

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