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

Версия 7.10.

Вопрос такой - к примеру, есть стандартная колонка даты, которая выводится на страницу примерно так:

{
						"operation": "insert",
						"parentName": "GeneralInformationBlock",
						"propertyName": "items",
						"name": "Date",
						"values": {
							"bindTo": "Date",
							"layout": {"column": 12, "row": 0, "colSpan": 12},
							"dataValueType": Terrasoft.DataValueType.DATE
						}
					},

В соседней теме https://community.terrasoft.ru/questions/mozno-li-zamestit-kontrol#comm…, что стандартный конфиг для контрола даты генерится в схеме ViewGeneratorV2, в методе generateDateEdit, где вызывается контрол DateEdit.

У меня есть свой контрол UsrDateEdit, который имеет некоторые отличия от стандартного DateEdit (нужно для задачи). Как его правильно подключить, чтобы он работал только для конкретных полей (замещение всего ViewGeneratorV2 в этом случае не подходит - оно даёт изменения для всех полей дат). Насколько я понимаю, для этого нужно добавить "UsrDateEdit" в define и что-то в diff. Вопрос - что именно?

Также было бы интересно заодно узнать, как сделать аналогичную замену для случая, когда подключается сразу два блока с датами, связанных в периоде StartDate - DuteDate, как например в мини-карточке при создании Активности ActivityMiniPage. 

Спасибо.

Нравится

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

Добрый день, ответ на ваш вопрос есть в самом первом комментарии темы на которую вы ссылаетесь:

{
   "operation": "merge",
   "name": "Schedule",
   "values": {
      "className": "Terrasoft.UsrReg",
   }
},

Где Terrasoft.UsrReg - и есть альтернативное имя вашего контрола.

Мотков Илья,

Илья, спасибо, действительно проглядел этот момент.

И всё-таки хотел бы уточнить вторую часть вопроса: если я хочу заменить генерацию дат в блоке диапазона внутри MiniPageDatePeriodGenerator, где там следует вызывать изменённый генератор дат?

Внутри этого блока?

this.generateDateTimeEdit({
							bindTo: itemName,
							name: itemName,
							visible: visible,
							controlConfig: timeEditConfig
						})

 

Заместил MiniPageDatePeriodGenerator, в замещении скопипастил код оригинала, + добавил в объект при вызове generateDateTimeEdit параметр isUseMyControl: true.

Далее в генераторе ViewGeneratorV2 в методе generateDateEdit проверяю isUseMyControl и в зависимости от значения использую UsrDateEdit или оригинальный DateEdit.

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

Вопрос - что именно могло отвалиться? Сам файл MiniPageDatePeriodGenerator остался почти без изменений, кроме добавления одного параметра.

UPD: нашёл ошибку, просто надо было изначально создать свой генератор, а не замещать существующий.

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

Добрый день!

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

Нравится

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

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

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

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

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

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

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

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

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

Вернусь к вопросу валидации, который я поднимал ранее...

1. Есть раздел "Подписанты" с полями:

    ФиоКонтакта, РазрешеннаяСумма

    

2. Есть раздел "Договора" с полями

    СуммаДоговора

    ФиоПодписанта = Подписанты.ФиоКонтакта

    

Необходимо произвести валидацию полей на схеме раздела "Договора"

    СуммаДоговора < Подписанты.РазрешеннаяСумма 

где Договор.ФиоПодписанта = Подписанты.ФиоКонтакта

По примерам https://academy.terrasoft.ru/documents/technic-sdk/7-10/postroenie-putey-k-kolonkam-otnositelno-kornevoy-shemy и https://academy.terrasoft.ru/documents/technic-sdk/7-10/poluchenie-rezultata-zaprosa  построил свой запрос 

            

methods: {
	// Метод-валидатор значения 
	SummValidator: function() {
		var message = "";
		// Создаем экземпляр класса Terrasoft.EntitySchemaQuery с корневой схемой [Contact].
		var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
			rootSchemaName: "UsrContract1Page"
		});
		// Добавляем колонку 
		esq.addColumn("UsrLimitAmount2.[UsrSignatories1Page:Id:UsrSignatoriesId].UsrLimitAmount",
			"UsrSignatoriesLimitAmount");
		// Получаем одну запись из выборки по [Id] объекта карточки и отображаем ее
		// в информационном окне.
		esq.getEntityCollection(function(result) {
			if (!result.success) {
				// обработка/логирование ошибки, например
				this.showInformationDialog("Ошибка запроса данных");
				return;
			}
			result.collection.each(function(item) {
				message += item.get("UsrSignatoriesLimitAmount");
			});
			this.showInformationDialog(message);
		}, this);
	},			
	// Переопределение базовой функции, инициализирующей пользовательские валидаторы.
	setValidationConfig: function() {
		// Вызывает инициализацию валидаторов родительской модели представления.
		this.callParent(arguments);				
		this.addColumnValidator("UsrLimitAmount2", this.SummValidator);
		this.addColumnValidator("UsrContractAmount", this.SummValidator);
	}
},

Но при проверке работы проваливаюсь в ошибку this.showInformationDialog("Ошибка запроса данных");

Помогите с решением данного кейса

Нравится

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

 

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

И это еще не все, далее в вашем методе валидаторе не предусматривается логика возвращение объекта, со строго установленными свойствами

{
   fullInvalidMessage: invalidMessage,
   invalidMessage: invalidMessage
};

которые там обязаны быть внимательно ознакомьтесь с примером https://academy.terrasoft.ru/documents/technic-sdk/7-10/dobavlenie-validacii-k-polyu-stranicy

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

 

 

 

Лог консоли:

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

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

Есть на схеме Договора поле типа Справочник имеющее ссылку в раздел Подписанты. Но тут скорей отсутствие навыка разработки в BPM - как подставить сумму в это поле в зависимости от выбранного Подписанта? Как-то "костыльно" получится...

как подставить сумму в это поле 

в это же поле ? в справочное - никак.

в другое поле - с численным типом, по зависимости, см. dependensies свойство в описании атрибутов

Ответ supporta:

Валидацию вы можете применить только к полям или атрибутам текущей схемы, так что для решения задачи вам понадобится виртуальный атрибут, по которому вы будете валидировать. Атрибуты создаются в блоке attributes: {

Примеры реализаций таких атрибутов множество в базовых схемах, поищите. Используются они как обычные колонки, следовательно их можно будет устанавливать this.set и читать this.get, и, использовать их в валидации.

Вам необходимо создать атрибут для вашей «РазрешеннаяСумма»

Далее данный атрибут нужно будет заполнять как при инициализации карточки, метод, onEntityInitialized: function() {

Так и при изменении лукапов от которых зависит получаемая информация. В вашем случае при изменении лукапа "ФиоПодписанта"

И последнее, как получить данные которыми вы хотите заполнить данный атрибут: Как вы правильно поняли, с помощью esq, ссылку на статью которой вы предоставили второй. Вам достаточно сделать запрос к корневой таблице «Подписанты» с условием ФиоКонтакта = this.get(“ФиоПодписанта”)



 

Севостьянов Илья Сергеевич,

Последовал совету supporta и вот что у меня получилось:

1. Создал виртуальную колонку в атрибутах

2. В onEntityInitialized  вызываю функцию setVirtLimitAmount с использованием EntitySchemaQuery для чтения данных из БД

3. dueSummValidator - проверяю значения и setValidationConfig - вызываю инициализацию валидаторов

4. Все это работает, но я бы сказал через одно место... работает синхронно, а мне бы хотелось асинхронно... По сути для этого мне было бы достаточно, каждый раз при изменении Подписанта (UsrSignatories) вызывать функцию setVirtLimitAmount. Возможно ли отследить изменение поля UsrSignatories? Одного Lookup-а недостаточно.

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

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

Есть контрол календарика: https://academy.terrasoft.ru/jscoresdk/#!/api/Terrasoft.controls.DatePi…

Можно ли его как-нибудь заместить в системе, по аналогии с тем, как замещаем схемы и добавляем свой функционал? К примеру, так:

define("UsrDateControl", [], function() {
 
	Ext.define("Terrasoft.controls.UsrDate", {
		extend: "Terrasoft.DatePicker",
		alternateClassName: "Terrasoft.UsrDate",
 
		show: function(){
			this.callParent(arguments);
			console.log("open datepicker");
		},
 
	});
 
});

Попробовал - но не работает.. возможно ли вообще такое замещение?

Изначальная идея - добавить возможность блокировать выбор определённых дат.

Нравится

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

Было бы здорово, если бы на Marketplace появились custom-контролы

Вам поможет вот эта, ранее поднимаемая мною тема.

https://community.terrasoft.ru/questions/rassirit-logiku-susestvuusego-klassa-extjs-v-bpm

 

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

Вам поможет вот эта, ранее поднимаемая мною тема.

Вот в своё время делал похожую штуку с расписанием Schedule. Но там по сути создавался контрол, который наследовался от оригинального контрола расписания, и далее в нужной схеме замещался элемент, использующий контрол, вроде такого:

 

//Контрол
define("UsrRegControl", ["schedule-edit"], function() {
 
	Ext.define("Terrasoft.controls.UsrReg", {
		extend: "Terrasoft.ScheduleEdit",
		alternateClassName: "Terrasoft.UsrReg",
 
		renderSchedulerItems: function(){
			this.callParent(arguments);
			console.log("RENDER");
		},
	});
 
});
 
//Подключение
define("ActivitySectionV2", ["UsrRegControl"],
	function() {
		return {
 
			entitySchemaName: "Activity",
 
			methods: {},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "merge",
					"name": "Schedule",
					"values": {
						"className": "Terrasoft.UsrReg",
					}
				},
 
			]/**SCHEMA_DIFF*/
		};
	}
);

Проблема в том, что datepicker - слишком много где используется, и даже не подключается явно в нужных схемах, по сути привязан к типу колонки "Дата и время". Вопрос - где тогда его заменять?

И ещё вопрос - можно ли где-нибудь посмотреть про override, как правильно его использовать?

Вот, например, сделал свой модуль:

 

define("UsrDatePicker", [], function() {
 
	Ext.define("Terrasoft.controls.UsrDatePicker", {
		override: "Terrasoft.DatePicker",
		alternateClassName: "Terrasoft.UsrDatePicker",
 
/* здесь взял полностью содержимое контрола из https://academy.terrasoft.ru/jscoresdk/source/datepicker.html#Terrasoft-controls-DatePicker + добавил на init и getTplData console.log("test") */
 
	});
 
});

Но такое впечатление, что замещения не произошло - ни одного лога не вывелось при открытии/изменении значения календаря.

Где-то ещё что-то нужно подключить?

Здравствуйте. Если Вам нужно заместить везде станд. контрол даты, то посмотрите на схему "ViewGeneratorV2", он занимается генерацией стандартных конфигов для контролов. В нем есть метод "generateDateEdit", который генерирует view-конфиг для контрола даты, можете заместить эту схему и в этом методе заменить класс "Terrasoft.DateEdit" на свой.

Колебянов Виталий Романович пишет:

Виталий Романочив, здравствуйте.

Спасибо за подсказку, я сделал свою версию модуля DateEdit - UsrDateEdit, скопировал в него текст оригинального DateEdit, и заместил схему ViewGeneratorV2 - это сработало. Но мне нужно заместить не  DateEdit, а DatePicker, который вызывается внутри UsrDateEdit:

 

createDatePicker: function() {
		var datePicker = this.datePicker = Ext.create("Terrasoft.UsrDatePicker", {
			renderTo: Ext.getBody(),
			parentEl: this.wrapEl,
			date: this.value
		});
		datePicker.on("dateSelected", this.onDateSelected, this);
		datePicker.on("currentDateSelected", this.onDateSelected, this);
	},

Вот сейчас если я так укажу, то на Ext.create("Terrasoft.UsrDatePicker" падает ошибка (календарик не показывается): GET https://0418605-sales-enterprise-demo.bpmonline.com/0/Nui/Terrasoft/Usr… 404 (Not Found)

Как мне заместить именно сам календарик DatePicker?

UsrDatePicker - пока по сути тот же DatePicker, только везде где в коде встречается DatePicker дописал Usr.

Все создаваемые файлы в пакете Custom.

Судя по всему, ошибка возникает потому, что замещения не были подгружены в память. Как вариант, вы можете заместить BootstrapModule следующим образом:

 

define("BootstrapModules", function() {
	return {
		"LookupUtilitiesV2": {},
		"ConfigurationEnumsV2": {},
		"ConfigurationConstantsV2": {},
		"DashboardFunnelEnums": {},
		"StructureExplorerUtilitiesV2": {},
		"UsrDatePicker": {},
		"UsrDateEdit": {}
	};
});

 

Смородинов Денис,

Скорее всего проблема в том, что вы не добавили свой "UsrDatePicker" в зависимость UsrDateEdit, т.е. должно быть так:

define("UsrDateEdit", ["UsrDatePicker"], function() {
......
});

 

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

Добрый день!





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

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

Что сделала:

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

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

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

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

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

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

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

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

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

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

Нравится

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

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

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

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

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

1. В детали "Участники активности" не знаю что выбрать в колонке детали и колонке объекта. Пробовала разные варианты - не получается.

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

2. Во всех активностях есть вкладка "Файлы и примечания". Что выбрать в детали "Файлы и ссылки Активности"?

и как добавить пункт "Примечания"?

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

Нравится

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

1) я обычно делаю таким образом:

2) Добавление детали . Примечание ,кажется это группа полей "Примечание"+ текстовое поле,у которого скрыт заголовок. Или же надо посмотреть, как кодом прописать добавление примечания на страницу.

Пример со страницы активности(ActivityPageV2, пакет UIv2).  Для текстового поля "Примечания". Обратите внимание  на controlConfig и images. 

{

                    "operation": "insert",

                    "parentName": "ActivityNotesControlGroup",

                    "propertyName": "items",

                    "name": "Notes",

                    "values": {

                        "contentType": Terrasoft.ContentType.RICH_TEXT,

                        "layout": {"column": 0, "row": 0, "colSpan": 24},

                        "labelConfig": {

                            "visible": false

                        },

                        "controlConfig": {

                            "imageLoaded": {

                                "bindTo": "insertImagesToNotes"

                            },

                            "images": {

                                "bindTo": "NotesImagesCollection"

                            }

                        }

                    }

                }

 

Матвеева Светлана,

Спасибо, попробую!

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

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

Версия 7.10.

При создании активности (новой задачи) есть выбор дат начала и завершения:

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

На практике нужно, чтобы некоторые даты были недоступны для выбора (в зависимости от расписания работы сотрудника, т.е. значения колонки "Ответственный" - 2 через 2, или исключить выходные). Условно, можно считать, что есть массив дат, которые необходимо исключить (будет получаться запросом). Либо наоборот - массив доступных дат, исключаются все остальные.

 

Можно ли такой фильтр как-нибудь добавить на колонку календаря?

Нашёл вот такие фильтры для ExtJS Datepicker: https://stackoverflow.com/questions/29251088/disable-date-in-datepicker… но там речь идёт об установке календаря. А тут надо изменить уже установленный, в зависимости от доступных значений.

Спасибо.

Нравится

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

Здравствуйте, у календаря есть еще возможность вводить значение вручную, так что, на вашем месте в качестве валидации, сделал бы просто this.on("change: нужного поля, в котором бы проверял введенную дату, и в случае несоответствия её графику, откатывал бы ее на предыдущее значение, с соответствующим сообщением.

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

Добрый день!





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

В параметрах нашла только "открывать страницу автоматически".

Возможно ли как-то отображать ее в расписании?

Нравится

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

Ну сделать-то теоретически можно. Вот только вопрос - с точки зрения календаря ему разницы нет процессная активность, страница или обычная. И что у Вас откроется тогда?

Автогенерируемая страница или преднастроенная,смотря что буду использовать в процессе.

Светлана, не выйдет. У календаря своя страница, как вы понимаете. Он не умеет работать с автогенерируемыми, процессными и т.д.

Хорошо) Возможно найти другое решение.

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

Например, назначить ответственного по продаже. Решение можно принять на основании нескольких полей: тип потребности продажи, контрагент. Руководитель заполняет одно поле  "Ответственный". Карточка должна состоять из трех плей в этом случае. 

Для решения таких задач используется обычная активность? а все остальные поля из активности скрывать? 

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

Да нет, это у вас автогенерируемая и есть :( Сделать задачу "Проставить ответственного", прицепить к задаче продажу и прям в ней править. А потом задачу закрывать, можно и автоматом по заполнению поля "Ответственный" в продаже. Но это уж совсем колхоз.  

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

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

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

Нравится

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

Здравствуйте, Павел! 

Если вопрос в выборе из двух разделов, можно попробовать реализовать это путем создания представления в БД, куда слить эти два раздела и таким образом искать, хоть тогда остается актуальным вопрос выбора карточки.

Еще одна альтернатива - при идеальной ситуации, когда у каждого контрагента есть хоть 1 контакт, можно попробовать переписать поиск, чтобы в разделе контакты он выбирал не только по полю ФИО но еще и по полю Контрагент.

Здравствуйте, Илья, спасибо за ответ.

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

Terrasoft.sdk.GridPage.setSearchColumns("Contact", ["Name", "Account"]);

 

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

Добрый день!





Решаю следующую задачу:

 

Необходимо отправлять e-mail уведомление раз в неделю в пятницу руководителю. E-mail должен содержать список лидов, по которым не было ни одной активности в течении 30 .

Решила настроить БП, однако поняла,что не смогу даже определить стартовое событие для данного бп.

Возможно вы сталкивались с аналогичной задачей.

 

Нравится

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

CRON триггер (простого будет достаточно). В принципе и в академии есть и здесь если поиском посмотреть. Логика такая - запускаете процесс один раз руками. Он планирует следующий запуск сам. Потом выбираете нужные лиды, в цикле наполняете текст сообщения [Текст строки] + "<br>", потом это вставляете в тело письма. Лучше всего сделать элементом "скрипт": esq запросом выбрать по параметрам лиды, сложить текст и присвоить значение параметру процесса. Пользовательскими (административными) средствами решить нельзя (пока).

Спасибо за ответы, Дмитрий! Буду пробовать реализовать)

Добрый день!

В ближайшем релизе bpm’online появятся пользовательские инструменты для настройки запуска процессов по расписанию. В дизайнере бизнес процесс появиться новый элемент «Стартовый таймер», с помощью этого элемента можно будет указать любую периодичность запуска бизнес-процесса

https://academy.terrasoft.ru/documents/upcoming-releases#8

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