Добрый день!

Возник вопрос по элементу процесса Отправить email - можно ли помимо настройки шаблона отправки email (преднастроенный текст для отправки, картинки, кнопки, ссылки и т.д.) прикрепить вложенный файл?

Нравится

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

Процессом формируете активность, потом формируете запись в Файлы активностей, ссылаясь на созданную активность, потом открываете карточку. Файл на детали "Файлы" :)

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

добрый день!

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

это можно отловить через схему детали или через схему карточки объекта, в котором расположена деталь? 

нужно при вложении пользователем файла на определенных страницах(у объекта несколько страниц) менять значение поля.

Нравится

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

Добрый день, отловить событие возможно только из схемы детали. Наиболее оптимальным должно быть замещение метода upload из FileDetailV2. Затем можете отправить сообщение с помощью sandbox в карточку редактирования.

Мотков Илья пишет:

Затем можете отправить сообщение с помощью sandbox в карточку редактирования.

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

Zaitova Liubov,

может this.get("MasterRecordId")?

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

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

добрый день!

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

я сделала событийный подпроцесс на inserting, выглядит он следующим образом

int size = Entity.GetTypedColumnValue("Size");

if (size > 1048576)

    throw new Exception("Размер вложенного файла превышает 1 Мб");

return true;

все работает, но пользователю выходит ошибка "При загрузке возникли ошибки. Ошибка загрузки файла". Ошибка абсолютно ни о чем пользователю не говорит.



 как сделать так, чтобы пользователь видел текст ошибки из кода ?

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

Нравится

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

оказалось следующее: когда закидываешь файл через кнопку добавить(знак скрепки), то все корректно - выходит моя ошибка. если просто закидываешь в область  - то выходит ошибка, которая ни о чем не говорит.

сделала следующее:

заместила filedetail, отловила ошибку в xhr в методе onFileComplete  и сделала свою обработку. 

можно ограничить средствами самого веб-сервера.

в файле конфигурации приложения

Terrasoft.WebApp\Web.config

смотрите ноду 

<requestLimits maxAllowedContentLength="104857600" />

это лимит для загружаемых на сервер данных в байтах

Севостьянов Илья Сергеевич пишет:

можно ограничить средствами самого веб-сервера.

спасибо.

правильно понимаю, что это ограничение на все загружаемые файлы? если ограничения разные для разных разделов( для контрагентов-1мб, для обращений -10мб и тд), то этот метод не подойдет? 

 

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

При изменении бизнес-процесса накопилось большое количество версий. При попытке удаления версии процесса через конфигуратор система предлагает "Удалить все версии схемы и объекты процесса, запущенные ими". Как удалить только определенные версии процесса, а не весь процесс целиком?

Нравится

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

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

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



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

 

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

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

Нравится

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

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

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

Здравствуйте, Коллеги! 

На страничке редактирования детали есть справочное поле Контрагент, мне нужно чтобы при нажатии на кнопку "Добавить" - открывалась страничка создания нового контрагента, у которого будет проставлен в поле "Тип" - Конкурент, и чтобы это поле было нередактируемым.

Логика этой кнопки прописана в модуле - LookupPageViewModelGenerator. Всё вроде бы понятно, заместить этот модуль и передавать сообщение в карточку контрагента. Но проблема в том, что любая попытка замещения этого модуля влечет за собой последствия, показанные во вложенном скрине, проблема наблюдается во всех справочниках. Коллега подсказал, что такого рода модули навряд ли получится нормально заместить, но если это так, то как тогда решить мою задачу? Надеюсь на вашу помощь :)

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

Нравится

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

Вообщем если Вам требуется кастомизировать какой либо lookup (я уже сталкивался с такой задачей не раз) у меня это вышло вот таким вот способом, Вам надо не замещать. (Это вообще сомнительное изначально решение, т.к. логика схемы LookupPageViewModelGenerator в приложении используется повсеместно, и менять ее для всех из-за одного кейса не корректно)

и так...

Необходимо создать совой новый модуль, и объявить в нем свой элемент "окно справочника", модуль сам по себе не должен никакую схему наследовать или замещать (т.е. поле родительский объект должно быть пустым)

 

define("CustomLookupPage", ["LookupPage", "LookupPageViewGenerator", "LookupPageViewModelGenerator",
"ProcessModuleUtilities", "LookupUtilities", "css!LookupPageCSS"],
	function(LookupPage, LookupPageViewGenerator, LookupPageViewModelGenerator, ProcessModuleUtilities) {
		return Ext.define("Terrasoft.configuration.CustomLookupPage", {
			alternateClassName: "Terrasoft.KmGMSLookupPage",
			extend: "Terrasoft.LookupPage",
			gridWrapClasses: ["custom-lookup-control"]
		})
	}
)

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

generateViewModel

и

renderLookupView

pзамещая их функциональность над окном справочника можно производить большинство требуемых кастомизаций.

н/п переименуем кнопки, кое что скроем, подменим обработчик.

//Переопределяем метод в котором мы можем управлять сформированной конфигурацией до рендеринга.
renderLookupView: function(schema, profile) {
	var config = this.getLookupConfig(schema, profile);
	var topPanelConfig = LookupPageViewGenerator.generateFixed(config);
	//----------------------- инъекция логики (начало) ----------------------
	var buttonsConfig;
	//Получаем ссылку на аттрибут-массив конфигурационных объектов-кнопок
	//Используем Underscore.some с возможностью прерывания переборы по возврату от предиката "true"
	_.some(topPanelConfig.items, function(target) {
		//выделяем объект группы кнопок (Wrapper) по id контейнера
		if (target.id === "selectionControlsContainerLookupPage") {
			//в нем ищем подчиненные объекты являющиеся массивом
			_.some(target, function(target) {
					//согласно структуры конфигурационного объекта панели
					//"чистым" массивом является только объект с конфигами кнопок
				if (Array.isArray(target)) {
					//сохраняем ссылку на него в переменной для дальнейшего использования
					buttonsConfig = target;
					//Прерываем перебор
					return true;
				}
			});
			//Прерываем перебор
			return true;
		}
	});
	//Поиск конфигурационного объекта кнопки "Выбрать" в искомом массиве по caption
	_.some(buttonsConfig, function(target) {
		if (target.caption === "Выбрать") {
			//В найденном объекте меняем значение аттрибута caption на "Создать тендеры".
			target.caption = "Создать тендеры";
			return true;
		}
	});
	//Поиск конфигурационного объекта кнопки "Добавить" в искомом массиве по caption
	_.some(buttonsConfig, function(target) {
		if (target.caption === "Добавить") {
			//В найденном объекте меняем значение аттрибута caption на "Создать тендеры".
			target.caption = "Создать запрос";
			//Удаляем тег стандартного действия "Создать запись" (add)
			//исключая навешивания стандартного обработчика в viewmodel генераторе 
			delete target.tag;
			//Устанавливаем совой обработчик
			target.click = {
				bindTo: "AddRequestButton"
			};
			return true;
		}
	});
	//Поиск конфигурационного объекта кнопки "Добавить" в искомом массиве по caption
	_.some(buttonsConfig, function(target) {
		if (target.caption === "Действия") {
			//В найденном объекте меняем значение аттрибута visible на "false"
			//тем самым скрывая кнопку-меню
			target.visible = false;
			return true;
		}
	});
	//----------------------- инъекция логики (конец) ----------------------
	this.renderLookupControls(config, topPanelConfig);
}

view будет выполнять в другом контексте и чтобы расширить его своим методом:

//Переопределяем метод в котором мы можем расширить viewModelConfig собственным методом.
generateViewModel: function() {
	var viewModelConfig = LookupPageViewModelGenerator.generate(this.lookupInfo);
	if (!this.lookupInfo.columnValue &amp;&amp; this.lookupInfo.searchValue) {
		viewModelConfig.values.searchData = this.lookupInfo.searchValue;
		viewModelConfig.values.previousSearchData = this.lookupInfo.searchValue;
	}
	//----------------------- инъекция логики (начало) ----------------------
	//Добавляем свой пользовательский метод
	viewModelConfig.methods.AddRequestButton = function() {
		//Проброшенный через конфиг страницы Id связанного Проекта
		var associatedProjectId = this.values.LookupInfo.associatedProjectId;
		//Вызываем БП
		var args = {
			sysProcessName: "CreateNewRequestFromProject",
			parameters: {
				ProjectId: associatedProjectId
			}
		};
		ProcessModuleUtilities.executeProcess(args);
		this.close();
	};
	//----------------------- инъекция логики (конец) ----------------------
	var viewModel = this.Ext.create("Terrasoft.BaseViewModel", viewModelConfig);
	viewModel.Ext = this.Ext;
	viewModel.sandbox = this.sandbox;
	viewModel.Terrasoft = this.Terrasoft;
	if (this.lookupInfo.updateViewModel) {
		this.lookupInfo.updateViewModel.call(viewModel);
	}
	viewModel.initCaptionLookup();
	viewModel.initHasActions();
	viewModel.initLoadedColumns();
	if (!this.Ext.isEmpty(this.lookupInfo.filterObjectPath)) {
		viewModel.updateFilterByFilterObjectPath(this.lookupInfo.filters, this.lookupInfo.filterObjectPath);
	}
	if (this.lookupInfo.hideActions) {
		viewModel.set("hasActions", false);
	}
	return viewModel;
}

 

Далее чтобы вызвать свое кастомизированное окно справочника используйте метод openLookup

//конфигурационный объект для кастомного окна справочника
var config = {
	entitySchemaName: "Lead",
	columns: ["Id"],
	associatedProjectId: this.get("Id"),
	multiSelect: true,
	filters: filterGroup,
	actionsButtonVisible: true,
    //указываем нашу кастомизированную схему
	lookupPageName: "CustomLookupPage"
};
this.openLookup(
	config,
	function(selected) {
       //callback обрабатывающий результаты выбора
	},
	this
);



 

PS: не пробовал но должно прокатить и через lookpListConfig для какого ни будь справочного поля в теории там lookpListConfig и превращается в config для openLookup :)

Суть ошибки на скриншоте в том, что не подтянулась локализируемая строка CaptionLookupPage. Необходимо добавить в замещающий модуль её вручную.

Спасибо, Коллеги! Как руки доберутся до этой задачи, дам знать получилось ли:)

Мотков Илья,

Добрый день, проверил, в модуле эта лок. строка присутствует. Не хотелось бы из-за этой задачи создавать свое кастомиз. окно справочника, неужели нет другого выхода:(

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

Добрый день!





Подскажите, как решать следующую проблему:



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

Для решения настроила бизнес-правило для поля Создал. Выводит тех сотрудников,у которых поле "Тип"="Сотрудник". К сожалению, в фильтре выводится весь список контактов.

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

Нравится

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

Светлана, вряд ли БП, которое реализовано на странице работает для панели быстрых фильтров.

Варианты решения:

- воспользоваться расширенным фильтром: https://academy.terrasoft.ru/documents/marketing/7-10/rasshirennyy-filtr

- создать свою панель с быстрым фильтром по аналогии как в активностях: https://academy.terrasoft.ru/documents/technic-sdk/7-10/dobavlenie-v-ra… (см. фильтр по ответственному).

Спасибо!

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

Коллеги, здравствуйте!

Возможно ли закрытие всех полей карточки для пользователя (не создателя) для изменения?

Речь идет о невозможности в том числе изменения данных до сохранения.

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

Хотелось бы для такого пользователя в принципе закрыть доступ на поля (сделать их неактивными, например, повесить "замок").

Возможно ли подобное в стандартном функционале?

Заранее спасибо!

 

Нравится

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

Здравствуйте, Эрнст!

В базовой логике приложения данная функциональность отсутствует.

Задача по доработке указаного функционала в последующих релизах, стоит на ответственной команде разработки. 

 

можно использовать вот такой "трюк"

Ext.ComponentMgr.all.each(function(c){
	var cmp = Ext.ComponentMgr.all.map[c];
	if(cmp.className){
		if(cmp.className.indexOf("Edit") !== -1){
			if(cmp.setEnabled){
				cmp.setEnabled(false);
			}
		}
	}
})

выполнение этого кода, сделает все поля карточки недоступными (замок)

можете разместить его например в onEntityInitialized методе схемы

но для какого пользователя выполнять, а для какого нет - это так же задача логики, BPM не предоставляет какой-либо штатной логики для работы с такой информацией в карточках схем, но если плоскость определения кому доступно а кому нет, лежит например в ракурсе, является ли текущий пользователь, пользователем установленным в поле Owner (или другом справочном поле ссылающимся на контакт) то это не составляет труда, если же этот же вопрос рассматривать в ракурсе, является ли текущий пользователь членом какой либо функциональной роли или организационного юнита, то Вам помогут вот эти утилиты  https://community.terrasoft.ru/questions/userutilsmixin-utility-dla-raboty-s-informaciei-o-organizacionnyh-edinicah-roliunity

(только обратите внимание на комментарии в теме)



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

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

Добрый день!

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

Нравится

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

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

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

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

Третий вариант реализации - создать собственный виджет.

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

Вдогонку ко второму варианту с виджетом, пример реализации простейшего виджета:

https://community.terrasoft.ru/articles/kak-sozdat-proizvolnyi-html-vidzet-widget-dla-itogov

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

Добрый день!





Возвращаюсь к своему вопросу по использованию активностей в системе.

Подскажите, как правильно настроить дополнительную страницу активностей для нового типа активности.

Что сделала:

1. В справочник Типы активностей добавила новое значение, "Выбор дальнейшей работы по продаже".

2. В мастере раздела активностей настроила внешний вид новой страницы с типом "выбор дальнейшей работы по продаже".

3. В процессе продаж, добавляю новую активность. Выбрала категорию :"Выбор дальнейшей работы по продаже".

4. После запуска процесса, мне открылась обычная страница активности, не та,что была настроена под новый тип. 

Что заметила:

1. Есть справочник "Категория активностей" и "Категория задачи". Как добавить значение в справочник "Категория задачи". 

2. В параметре "Категория"  выбирала свою категорию. 

 Подскажите, в чем у меня ошибка может быть? И как вы настраиваете страницу активности, если необходимо для каждой задачи ,выводить свой вариант страницы.

Прикладываю скриншоты настроек.

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

Нравится

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

У вас стоит разграничение по колонке "Тип", это справочник "Тип активности", вот именно колонку "Тип" для активности и нужно установить в БП перед открытием в нужную, что бы открылась настроенная страница для этого типа.

Вы скорее всего запутались в подобности справочников "Тип активности" и "Категория активности", это две разные колонки в активности: Type и ActivityCategory. Если вы вдруг не найдете в спровочнике готового справочника для типа или категории, вы можете создать новый, и указать объект "Тип активности" или "Категория активности", и наполнять его как вам нужно.

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