Добрый день

Появилась необходимость дать части пользователям права на ведение части справочников. 

Первая мысль - дать права на операцию CanManageLookups и создать кастомный раздел в котором регистрировать справочники доступные для ведения польхователей.

Но! Если я дам права на CanManageLookups, то получается, пользователь сможет вести практически все справочники через пункт Добавить в выпадающем списке. Или что хуже додумается перейти через главную страницу к разделу справочники.

Есть еще идеи?

Нравится

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

Алексей, только недавно похожее обсуждали. Такая идея разграничения прав на разные справочники заведена, есть обходные решения разной степени удобства.

 

Можно, например, сделать из справочника раздел с карточкой и пользователи будут наполнять в нём.

 

Но нужно ещё учесть, что на уровне объекта «Базовый справочник», от которого унаследованы остальные, есть проверка на это право:

Скрипт запускает функцию:

public virtual void CheckCanManageLookups() {
	UserConnection.DBSecurityEngine.CheckCanExecuteOperation("CanManageLookups");
}

Чтобы она не срабатывала, нужно в объекте нужного справочника переопределить её пустой. Насколько я понимаю, для ряда справочников это уже сделано в стандартной поставке.

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

Добрый вечер!

Вопрос по работе с элементом "Задание-сценарий".



Имеем бизнес-процесс, который срабатывает по сигналу добавления текстовой записи. Как только добавляется запись, процесс считывает текст записи и формулой добавляет этот текст в некий параметр "UsrInput". Далее сценарий регулярным выражением находит текст в кавычках и отправляет этот текст в другой параметр "UsrOutput". После чего процесс дальше идет по цепочке из стандартных элементов БП.

Проблема в том, что во время обработки процесса почему-то  в журнале процессов появляется ошибка:

System.NotSupportedException: Match

Метод System.Text.RegularExpressions я в процесс добавил.

Помогите понять, пожалуйста, с чем может быть это связано?

 

Пример текста:

Диалогу присвоена категория "Тест"

Код сценария:

string message = Get<string>("UsrInput");
string pattern = "\"(.*?)\"";
Match result = Regex.Match(message, pattern);
Set("UsrOutput", result);
return true;

 

Прикрепленные файлы

Нравится

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

Через тот же https://repl.it/repls/RegalHarshDeclarations все срабатывает без ошибок, а внутри процесса никак.

Разобрался. Надо было в string превратить result

..
string result1 = result.Value;
Set("UsrOutput", result1);
return true;

 

Спасибо за упоминание сайта https://repl.it, не знал, что такой есть, пригодился.

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

Добрый вечер!

Вопрос по бизнес-правилам.

Подскажите, как можно в правиле задать условие для действия фильтра значений в поле?

 

Имеется единый справочник тематик, из которого сотрудники выбирают необходимую по окончании общения в чатах и звонках.

Для чатов и звонков созданы отдельные разделы. В каждом разделе есть карточки чатов и звонков. В каждой карточке создана деталь с тематиками, что ссылается на справочник в виде выпадающего списка тематик.

Цель: сделать так, чтобы для чатов выпадал один список, а для звонков другой, используя один и тот же вышеуказанный справочник.

Прикрепленные файлы

Нравится

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

Николай Ходаковский,

вы для чата указываете значение по умолчанию Чат. для звонка - звонок. Еще раз - на страницы для объектов чат и звонок вы добавляете справочное поле Тип(тот же самый справочник, что вы создали в справочнике Тематики) и для каждого раздела там устанавливаете свое значение по умолчанию. Значение по умолчанию вам нужно будет установить через конфигуратор в свойствах соответствующих объектов (чат и звонок). Понятно объяснил или где-то надо углубится?

Я может быть неправильно вас понял, но по моему ваша задача аналогична фильтру городов по странам. Т.е. в справочнике Тематики создаете поле Тип(Звонок, Чат) и в ваших страницах раздела помещаете этот справочник Тип(можно на страницу редактирования не выводить а просто добавить в объект с соответствующими значениями по умолчанию). Ну и дальше делаете для каждого раздела свое бизнес правило где фильтр справочника строится по значению Тип у раздела.

Сидоров Александр Валерьевич, спасибо за ответ. Значение по умолчанию — это интересная мысль.

Мы используем деталь с тематиками, благодаря чему сотрудник может выбрать несколько тематик в карточке чата. После чего в отдельной таблице собираются все выбранные тематики с указанием id чата/звонка.

Получается следующее, если я добавляю к своему справочнику Тип, то его надо будет всегда выбирать, чтобы подтянуть правильный список со справочника. Как можно сделать, чтобы система сама устанавливала нужный Тип при открытии карточки чата, например? Где задается это умолчание?

Николай Ходаковский,

вы для чата указываете значение по умолчанию Чат. для звонка - звонок. Еще раз - на страницы для объектов чат и звонок вы добавляете справочное поле Тип(тот же самый справочник, что вы создали в справочнике Тематики) и для каждого раздела там устанавливаете свое значение по умолчанию. Значение по умолчанию вам нужно будет установить через конфигуратор в свойствах соответствующих объектов (чат и звонок). Понятно объяснил или где-то надо углубится?

Сидоров Александр Валерьевич, уловил вашу мысль.

Все получилось, спасибо большое!

 

Решил вместо типа всё-таки использовать чекбоксы.

По вашему совету в объектах чатов и звонков создал чекбоксы, где выставил установил по умолчанию "true". Такие же логические чекбоксы сделал для справочника тематик (отдельно для чатов и звонков), где также по для нужных записей выставил 'true'.

Далее к детали тематик привязал правило по этим чекбоксам :)

 

Рад, что смог помочь! Велком)

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

Добрый день.

 

В бизнес-процессе добавлен подпроцесс. Он запускается один раз всегда и при определенных условиях должен запускаться повторно. Первый раз выполнение проходит без ошибок. Но второй раз подпроцесс не запускается. При этом в журнале состояние подпроцесса "Выполняется", но выполнения нет, список элементов процесса пустой, диаграмма выполнения без отметок о выполнении элементов. А основной процесс стоит в состоянии "Ошибка", но на самом элементе подпроцесса ошибки нет. Описания ошибки нет.

Нравится

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

Константин, слишком мало информации. Неизвестно, какая версия (похожее было в 7.8-7.10), зависит ли от конкретного процесса и подпроцесса, или так себя ведёт с любыми. Попробуйте воспроизвести то же самое с другим процессом и подпроцессом, а также на триал-сайте последней версии, который можно завести тут. Возможно, больше получится узнать при помощи трассировки процесса (если окажется, что нужное значение параметра не передалось) или текст ошибки найдётся в логах.

Зверев Александр,

Кажется смог выделить проблему. 

В подпроцессе есть параметр "Заголовок", тип данных "Строка (250 символов)".

На входе этот параметр заполняется "текстом"+[значение другого параметра].

 

Если в этом параметре оставить только текст (без параметра), то выполнение идет без ошибок.

Подскажите где посмотреть лог процесса? 

Я имел в виду лог всех ошибок системы, возможно, что-то интересное в момент падения процесса или второго запуска подпроцесса видно в нём. Если у Вас система on site, то он падает в текстовые файлы Error.log в папке за нужную дату на том сервере, где IIS. А если в облаке, то получить можно только через поддержку.

 

Судя по скриншоту, отменённый подпроцесс выполнялся больше 2 дней, потом его Вы отменили вручную? Для подпроцесса в свойствах тоже включили трассировку?

Зверев Александр,

Кажется смог выделить проблему. 

В подпроцессе есть параметр "Заголовок", тип данных "Строка (250 символов)".

На входе этот параметр заполняется "текстом"+[значение другого параметра].

Если в этом параметре оставить только текст (без параметра), то выполнение идет без ошибок.

При добавлении любого параметра в "Заголовок" возникает ошибка.

 

В логе показывает ошибке на совсем другом элементе, хотя в диаграмме он выполняется без ошибок

 

 

 

Константин, спасибо за информацию, можно попробовать воспроизвести.

Вы в стёртом сообщении написали свою версию системы. А на более новой, той, что в демо-версиях, не пробовали скопировать схему процесса, там тоже так себя ведёт?

Если кому пригодится, получилось сделать по другому. Ранее задавал "заголовок" входящим параметром подпроцесса ("текст"+значение параметра 1), теперь "заголовок" формирую внутри подпроцесса.

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

Добрый день.

Подскажите, пожалуйста можно ли пользовательскими настройками сделать обязательность полей для разных функц.ролей. Т.е. для функц.роли Руководитель сделать одни поля обязательные к заполнению, для роли Сотрудник сделать другие поля обязательные?

Заполнить поля они должны вместе на одной стадии, параллельно.

Нравится

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

Можно сделать булевое поле в атрибуте со значением по умолчанию, забиндить его для поля на странице в параметр видимости, а при старте запускать проверку роли пользователя текущего (сделать можно через написанный Ильей миксин, спасибо ему за это https://community.terrasoft.ru/questions/userutilsmixin-utility-dla-rab…)  с возвратом присвоения значения атрибуту.

Если нужно могу написать как это реализовать в коде, просто сейчас на выструю руку пишу

Лучше не прямо проверять роли, а завести системную операцию, выдать права на неё нужным ролям и в коде страницы проверять наличие у текущего пользователя. Они для этого и придуманы.

См. примеры тут, у Вас аналогично, только не enabled, а isRequired.

Спасибо за помощь, попробуем разобраться.

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

Добрый день!

 

У меня в CTI панели есть два поля:

Линия соединения и Тематика. В Тематике есть справочная колонка Линия соединения. Мне необходимо фильтровать справочник 2 по значению в поле 1.

Я попробовал сделать это тремя способами:

1. lookupListConfig. Не работает, в фильтр даже дебаггер не проваливается.Изображение удалено.

2. Бизнес правила. Тоже не работают.

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

3. И дальше я попытался написать метод, который будет вызываться по изменению колонки 1, чтобы там уже программно добавлять/удалять необходимые значения из справочника в поле 2.

В итоге и в этот метод не могу провалиться дебаггером.

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



Скрины по каждому варианту во вложении.

Кто сталкивался? Что происходит? В других карточках все методы работают, именно в CTI панели - нет.

 

Нравится

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

У Вас какая версия? У меня так же не работает код фильтрации в разделе активностей на поле "Ответственный" - версия Sales 7.15.2 для СУБД Oracle

Александр, не думаю, что это как-то связано с Вашим случаем. Вы же добавляли в обычную карточку, а у CTI-панели, видимо, есть особенности.

 

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

scr_section_service_requests_buttons_on_call.png

Александр Тыра,

В обычных страницах у меня работает. Версия такая же только Service.

Зверев Александр,

Да, на крайний случай так и сделаю

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

Всем добрый день!

Друзья, подскажите, пожалуйста, кто-нибудь работал с деталью на странице портала самообслуживания?

Для бандла service сейчас пытаюсь реализовать деталь с редактируемым реестром, чтобы можно было указывать в заявке несколько значений из справочника. Всем известно, что, когда пытаешься добавить в деталь новое значение, то вызывается метод, который сохраняет родительскую запись, так как запись детали обязательно должна быть связана с родительской записью. Можно как-то добавить в деталь запись, не вызывая метод, который сохраняет родителя, но при этом, чтобы после сохранения родителя, в детали все корректно связалось? Как-то же это реализовано для файлов например.

Нравится

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

Это ещё реализовано и в Средствах связи

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

В средствах связи, схеме ContactCommunicationDetailV2 добавленные и удалённые складываются в две коллекции Collection и DeletedItems и при сохранении из них извлекаются и идут на сервер одним составным запросом:

deleteItem: function(item) {
	var deletedItems = this.get("DeletedItems");
	var collection = this.get("Collection");
	collection.removeByKey(item.get("Id"));
	deletedItems.addItem(item);
},
 
addItem: function(tag) {
	if (this.get("IsDetailCollapsed")) {
		return;
	}
	var communicationTypes = this.get("CommunicationTypes");
	var communicationType = communicationTypes.get(tag);
	var newItem = this.Ext.create("Terrasoft.BaseCommunicationViewModel", {
		entitySchema: this.entitySchema,
		columns: this.columns
	});
	newItem.set("CommunicationTypes", communicationTypes);
	newItem.sandbox = this.sandbox;
	newItem.setDefaultValues(function() {
		newItem.set("CommunicationType", {
			value: communicationType.get("Id"),
			displayValue: communicationType.get("Name")
		});
		newItem.set("Contact", {
			value: this.get("MasterRecordId")
		});
		var itemKey = newItem.get("Id");
		var collection = this.get("Collection");
		collection.add(itemKey, newItem);
		this.changeCardPageButtonsVisibility(true);
	}, this);
	return newItem;
},
 
...
 
getDeleteItemsQueries: function() {
	var deletedItems = this.get("DeletedItems");
	var deleteQueries = [];
	deletedItems.each(function(item) {
		var primaryColumnValue = item.get(item.primaryColumnName);
		var deleteQuery = item.getDeleteQuery();
		deleteQuery.enablePrimaryColumnFilter(primaryColumnValue);
		deleteQueries.push(deleteQuery);
	}, this);
	return deleteQueries;
},
 
getSaveItemsQueries: function() {
	var collection = this.get("Collection");
	var saveQueries = [];
	collection.each(function(item) {
		if (item.isChanged() &amp;&amp; item.validate()) {
			saveQueries.push(item.getSaveQuery());
		}
	}, this);
	return saveQueries;
},
 
...
 
save: function() {
	var restrictionsQuery = this.getSaveRestrictionsQuery();
	var queries = restrictionsQuery ? [restrictionsQuery] : [];
	var saveQueries = this.getSaveItemsQueries();
	queries = queries.concat(saveQueries);
	var deleteQueries = this.getDeleteItemsQueries();
	queries = queries.concat(deleteQueries);
	if (Ext.isEmpty(queries)) {
		this.publishSaveResponse({
			success: true
		});
		return true;
	}
	var batchQuery = Ext.create("Terrasoft.BatchQuery");
	Terrasoft.each(queries, function(query) {
		batchQuery.add(query);
	}, this);
	batchQuery.execute(this.onSaved, this);
	return true;
},
 
onSaved: function(response) {
	var message = response.ResponseStatus &amp;&amp; response.ResponseStatus.Message;
	if (response.success &amp;&amp; !message) {
		var deletedItems = this.get("DeletedItems");
		var collection = this.get("Collection");
		collection.each(function(item) {
			item.isNew = false;
			item.changedValues = null;
		}, this);
		deletedItems.clear();
		this.publishSaveResponse(response);
	} else {
		this.publishSaveResponse({
			success: false,
			message: this.getValidationMessage(message)
		});
	}
},

 

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

Всем доброго времени суток!

Есть задача: по нажатию кнопки в модальном окне открывается окно с выбором

полей текущего раздела. Выбирается любое поле и добавляется в модальное окно. И так далее. То есть получается добавленные поля существуют только пока  открыто модальное окно. Это нужно для создания отчета Excel, где указанные значения в полях будут фильтрами.

В разделе полей много. Плюс в будущем поля могут добавляться. Поэтому забивать их жестко в diff смысла не вижу.

Вопрос: есть ли возможность как-то динамически наполнять массив diff полями? 

Нравится

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

А если создать фиксированное количество виртуальных полей и программно их скрывать, показывать, а также менять заголовки?

 

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

 

Наконец, если формируете фильтр по значениям полей, можно воспользоваться готовым механизмом динамических групп, где такой тоже настраивается. То есть стандартными средствами создать группу, а затем выбрать её в окне настроек отчёта, а затем программно разбирать её фильтр.

 

А вообще, описанное Вами очень похоже на автогенерируемую страницу в БП. Может, с её помощью получится?

Зверев Александр,

Спасибо за ответ. Фиксированное количество виртуальных полей не вариант, так как в будущем клиент самостоятельно может добавлять поля, которые тоже должны выбираться. Мне подсказали создать на странице модального окна ContainerList. Вот такой элемент diff:

{
    "operation": "insert",
    "name": "CommunicationsContainer",
    "parentName": "ContainerListContainer",
    "propertyName": "items",
    "values": {
        "generator": "ConfigurationItemGenerator.generateContainerList",
        "idProperty": "Id",
        "collection": "CaseFieldCollection",
        "observableRowNumber": 10,
        "onGetItemConfig": "getCaseItemConfig"
    }
}

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

"onGetItemConfig" - метод, где формируется структура каждого поля.

Только вот до конца не ясно как с этим всем работать.

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

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

Как можно набрать номер телефона пользователя, если у него есть добавочный номер? 


Запущена интеграция bpm'online со штатным коннектором Oktell.

Нравится

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

Автоматически возможности не предусмотрено, набирайте вручную. Сперва сам номер, потом добавочный.

 

Звонилка Android позволяет указать номер вида 0443633133, 5271. Далее после ответа на первую часть номера телефон выполняет донабор самостоятельно. Аналогично работает звонилка на IOS.  И даже в кнопочных Nokia были p и w.

Поддерживается 2 опции:

  • p (,) - пауза на 2 секунды, можно использовать несколько подряд, если не хватает
  • w (:) - пауза до подтверждения пользователем. Приложение спросит подтверждение донабрать символы после дозвона

 

Возможно, в некоторых программах-клиентах такое есть, но не везде.

В web-интерфейсе Oktell при вводе номера 0443633133,5221 звонок выполняется на 04436331335221. В то же время при использовании X-Lite и подключении к серверу Oktell удавалось корректно позвонить на номер вида 0443633133,5221. Похоже что данная возможность отрабатывает на уровне SIP клиента.

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

Добрый день!

Руководствуясь статьей "Формулы" на Академии, пытаюсь создать в БП условный поток с проверкой заполненности поля, но при сохранении выдает ошибку:

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

________________________________________________________________________________________

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

Нравится

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

Вы пытаетесь сравнить Дату с Guid. Поэтому формула и выдает вам ошибку. Вам нужно сравнивать с DateTime.MinValue

Вы пытаетесь сравнить Дату с Guid. Поэтому формула и выдает вам ошибку. Вам нужно сравнивать с DateTime.MinValue

Сидоров Александр Валерьевич,

 благодарю, разобрался.

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