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

Нравится

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

Добрый день.

 

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

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

 

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

Ivan Kuchma,

Такой вопрос, можно ли добавить уже созданную деталь просто на форму мини-карточки при помощи разработки? И обязательно ли создавать под это контейнер с полями tabs?

Глеб Макаров,

рекомендую обратить внимание на похожую тему  для миникарточки с детали, а также на статью о реализации сообщений между деталями через sandbox.
Детальнее работе с sandbox можете ознакомится в статье: https://academy.terrasoft.ua/docs/7-18/developer/front-end_development/…

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

Добрый день!
 

Был ли у кого-то опыт отображения конструктора процесса в карточке объекта?

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

 

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

Нравится

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

Вадим, добрый день!

Чисто технически возможно реализовать что-то подобное на схему кампании, однако, для этого необходимо большое  количество трудозатрат. Наподоби вкладки "Обработка" в обращениях, "Схема кампании" является уникальным функционалом для раздела. Для его повторение необходимы навыки разработки, системой не предусмотрено повторение такого пользовательскими средствами. Если же вы всёже желаете это реализовать, то необходимо будет проанализировать содержимое пакетов Campaigns, CampaignDesigner, CampaignElements и тд.

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

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

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

Был ли у кого-то опыт размещения данного раздела на карточке? 

 

Нравится

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

Добрый день.

 

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

Пользовательских средств для реализации фильтра по умолчанию нет в коробке. Только разработкой.

 

Необходимо переопределить initQueryFilters
initQueryFilters: function(esq) {
                    this.callParent(arguments);
                    esq.filters.add("ConnectionType",
                            Terrasoft.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "ConnectionType",1));
                    }

 

Подобные вопросы рассматривались на портале, ссылки ниже:

https://community.creatio.com/questions/how-filter-section-list-records…

https://community.terrasoft.ru/questions/kak-predustanovit-uslovie-v-fi…

https://community.terrasoft.ru/questions/vidimost-sotrudnikov-v-kontakt…

https://community.creatio.com/questions/default-filter-section

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

Вы можете подсмотреть реализацию тут:
DocListInConditionPageV2
Там увидите подключение контейнера FilterProperties, в который подгружается FilterEditModule

Литвинко Павел,

Видимо, в текущей версии нет этого файла :( не могли бы поделиться его листингом?

Вадим Курунов пишет:

define("DocListInConditionPageV2", ["FilterEditModule"],
	function() {
		return {
			entitySchemaName: "DocListInCondition",
			attributes: {
				/**
				 * Filtration object schema name.
				 */
				"FilterEntitySchemaName": {
					"dataValueType": this.Terrasoft.DataValueType.TEXT,
					"type": this.Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
					"dependencies": [{
						"columns": ["DocumentListStage"],
						"methodName": "updateFilterModule"
					}]
				}
			},
			mixins: {},
			diff: /**SCHEMA_DIFF*/[
				{
					"operation": "insert",
					"name": "Document",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"dataValueType": Terrasoft.DataValueType.LOOKUP,
						"value": {"bindTo": "Document"},
						"layout": {
							"column": 0,
							"row": 0,
							"colSpan": 10
						}
					}
				},
				{
					"operation": "insert",
					"name": "DocListGroup",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"dataValueType": this.Terrasoft.DataValueType.ENUM,
						"value": {"bindTo": "DocListGroup"},
						"layout": {
							"column": 0,
							"row": 1,
							"colSpan": 10
						}
					}
				},
				{
					"operation": "insert",
					"name": "DocumentListStage",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"dataValueType": Terrasoft.DataValueType.ENUM,
						"value": {"bindTo": "DocumentListStage"},
						"layout": {
							"column": 0,
							"row": 2,
							"colSpan": 10
						}
					}
				},
				{
					"operation": "insert",
					"name": "ParticipantRole",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"dataValueType": Terrasoft.DataValueType.ENUM,
						"value": {"bindTo": "ParticipantRole"},
						"layout": {
							"column": 0,
							"row": 3,
							"colSpan": 10
						}
					}
				},
				{
					"operation": "insert",
					"name": "DocumentType",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"dataValueType": Terrasoft.DataValueType.ENUM,
						"value": {"bindTo": "DocumentType"},
						"layout": {
							"column": 0,
							"row": 4,
							"colSpan": 10
						}
					}
				},
				{
					"operation": "insert",
					"name": "SysModuleReport",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"dataValueType": Terrasoft.DataValueType.LOOKUP,
						"value": {"bindTo": "SysModuleReport"},
						"layout": {
							"column": 0,
							"row": 5,
							"colSpan": 10
						}
					}
				},
				{
					"operation": "insert",
					"name": "IsRequired",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"layout": {
							"column": 0,
							"row": 6,
							"colSpan": 10
						}
					}
				},
				{
					"operation": "insert",
					"name": "FilterProperties",
					"parentName": "Header",
					"propertyName": "items",
					"values": {
						"id": "FilterProperties",
						"itemType": Terrasoft.ViewItemType.CONTAINER,
						"items": [],
						"layout": {
							"column": 15,
							"row": 0,
							"colSpan": 9,
							"rowSpan": 12
						}
					}
				},
				{
					"operation": "remove",
					"name": "actions"
				}
			]/**SCHEMA_DIFF*/,
			messages: {
				/**
				 * Subscription on filter change.
				 */
				"OnFiltersChanged": {
					mode: Terrasoft.MessageMode.BROADCAST,
					direction: Terrasoft.MessageDirectionType.SUBSCRIBE
				},
 
				/**
				 * Subscription on receiving of filter module configuration object.
				 */
				"GetFilterModuleConfig": {
					mode: Terrasoft.MessageMode.PTP,
					direction: Terrasoft.MessageDirectionType.SUBSCRIBE
				},
 
				/**
				 * Publishing message about setting filter module.
				 */
				"SetFilterModuleConfig": {
					mode: Terrasoft.MessageMode.BROADCAST,
					direction: Terrasoft.MessageDirectionType.PUBLISH
				}
			},
			methods: {
 
				/**
				 * Returns Id of filtration module.
				 * @protected
				 * @return {String} Filtration module Id.
				 */
				getFilterEditModuleId: function() {
					return this.sandbox.id + "_ExtendedFilterEditModule";
				},
 
				/**
				 * Loads filter module.
				 * @protected
				 */
				loadFilterModule: function() {
					var moduleId = this.getFilterEditModuleId();
					this.sandbox.subscribe("OnFiltersChanged", this.onFiltersChanged, this, [moduleId]);
					this.sandbox.subscribe("GetFilterModuleConfig", this.onGetFilterModuleConfig, this, [moduleId]);
					this.sandbox.loadModule("FilterEditModule", {
						renderTo: "FilterProperties",
						id: moduleId
					});
					this.set("FilterModuleLoaded", true);
				},
 
				/**
				 * Sets FilterConfig by filter that was received from filtration module.
				 * @param {Object} args Object with serialized filter.
				 * @protected
				 */
				onFiltersChanged: function(args) {
					this.hideBodyMask();
					this.setFilterConfig(args.serializedFilter);
				},
 
				/**
				 * Sets field FilterConfigand flag HasFilters in objects.
				 * @param {String} serializedFilter Serialized filter.
				 * @private
				 */
				setFilterConfig: function(serializedFilter) {
					this.set("FilterConfig", serializedFilter);
					var filters = this.Terrasoft.deserialize(serializedFilter);
					this.set("HasFilters", this.Ext.isEmpty(filters) ? false : filters.getCount() > 0);
				},
 
				/**
				 * Returns config for filtration module.
				 * @protected
				 * @return {Object} Cofiguration object.
				 */
				onGetFilterModuleConfig: function() {
					return {
						rootSchemaName: this.get("FilterEntitySchemaName"),
						filters: this.get("FilterConfig")
					};
				},
 
				/**
				 * Unloads filter module.
				 * @protected
				 */
				unloadFilterModule: function() {
					var moduleId = this.getFilterEditModuleId();
					this.sandbox.unloadModule(moduleId);
					this.set("FilterModuleLoaded", false);
				},
 
				/**
				 * Creates Terrasoft.EntitySchemaQuery instance for receiving SysEntitySchemaName of FilterEntity that
				 * is specified in DocumentListStage record.
				 * @protected
				 * @return {Terrasoft.EntitySchemaQuery} Terrasoft.EntitySchemaQuery instance with initialized
				 * rootSchemaName and columns
				 */
				getEsqForInitFilterEntityByDocListStage: function() {
					var esq = this.Ext.create("Terrasoft.EntitySchemaQuery", {
						rootSchemaName: "DocumentListStage"
					});
					esq.addColumn("FilterEntity.SysEntitySchemaName", "FilterEntitySchemaName");
					return esq;
				},
 
				/**
				 * Initializes FilterEntitySchemaName property depending on the DocumentListStage property and calls
				 * callback function.
				 * @protected
				 * @param {Function} callback The callback function.
				 * @param {Object} scope The scope of callback function.
				 */
				initFilterEntity: function(callback, scope) {
					var docListStage = this.get("DocumentListStage");
					if (docListStage && docListStage.value) {
						this.initFilterEntityByDocListStage(docListStage.value, callback, scope);
					} else {
						this.set("FilterEntitySchemaName", null);
						this.Ext.callback(callback, scope);
					}
				},
 
				/**
				 * Receives SysEntitySchemaName of FilterEntity that is specified in DocumentListStage record,
				 * sets is to FilterEntitySchemaName property and calls callback funcion.
				 * @protected
				 * @param {Guid} docListStageId Id of document list stage record.
				 * @param {Function} callback The callback function.
				 * @param {Object} scope The scope of callback function.
				 */
				initFilterEntityByDocListStage: function(docListStageId, callback, scope) {
					var esq = this.getEsqForInitFilterEntityByDocListStage();
					esq.getEntity(docListStageId, function(result) {
						var entity = result.success ? result.entity : null;
						this.initFilterEntityByDocListStageCallback(entity);
						this.Ext.callback(callback, scope);
					}, this);
				},
 
				/**
				 * Processes result of query in initFilterEntityByDocListStage method.
				 * @protected
				 * @param {Object} entity Object with entity that returned by query.
				 */
				initFilterEntityByDocListStageCallback: function(entity) {
					var entitySchemaName = !this.Ext.isEmpty(entity)
						? entity.get("FilterEntitySchemaName")
						: null;
					this.set("FilterEntitySchemaName", entitySchemaName);
				},
 
				/**
				 * Updates filter module. Clears filter if filter object is changed.
				 * @protected
				 * @param {Function} callback The callback function.
				 * @param {Object} scope The scope of callback function.
				 */
				updateFilterModule: function(callback, scope) {
					this.showBodyMask();
					this.initFilterEntity(function() {
						var filterEntitySchemaName = this.get("FilterEntitySchemaName");
						if (this.Ext.isEmpty(filterEntitySchemaName)) {
							if (this.get("FilterModuleLoaded")) {
								this.setFilterConfig(null);
								this.unloadFilterModule();
							}
							this.hideBodyMask();
						} else if (!this.get("FilterModuleLoaded")) {
							this.loadFilterModule();
						} else {
							var config = this.get("IsEntityInitialized") ? null : this.get("FilterConfig");
							this.setFilterModuleConfig(filterEntitySchemaName, config);
						}
						this.Ext.callback(callback, scope);
					}, this);
				},
 
				/**
				 * Publishes message SetFilterModuleConfig for filtration module.
				 * @param {String} entitySchemaName Name of object that conditions will be setting for.
				 * @param {String} filterConfig Serialized filter.
				 * @protected
				 */
				setFilterModuleConfig: function(entitySchemaName, filterConfig) {
					var moduleId = this.getFilterEditModuleId();
					this.sandbox.publish("SetFilterModuleConfig", {
						rootSchemaName: entitySchemaName,
						filters: filterConfig
					}, [moduleId]);
				},
 
				/**
				 * @inheritdoc Terrasoft.BasePageV2#onEntityInitialized
				 * @overridden
				 */
				onEntityInitialized: function() {
					this.callParent(arguments);
					this.updateFilterModule();
				},
 
				/**
				 * @inheritdoc Terrasoft.BasePageV2#onDiscardChangesClick
				 * @overridden
				 */
				onDiscardChangesClick: function() {
					if (this.isNew) {
						this.sandbox.publish("BackHistoryState");
						return;
					}
					this.set("IsEntityInitialized", false);
					this.loadEntity(this.get("Id"), function() {
						this.updateButtonsVisibility(false, {
							force: true
						});
						this.initMultiLookup();
						this.updateFilterModule(function() {
							this.set("IsEntityInitialized", true);
							this.discardDetailChange();
						}, this);
					}, this);
					if (this.get("ForceUpdate")) {
						this.set("ForceUpdate", false);
					}
				}
			}
		};
	});

 

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

Добрый день!

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

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

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

 

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

this.save({silent:true});

 

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

Добрый вечер, Коллеги.

У кого-нибудь возникала на странице еще "одна страница с полями" (см. скрин внизу)

В мастере разделов нижней страницы нет.

Нравится

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

На странице описано поле(в diff),  у которого неправильно указан родительский контейнер

Похоже на деталь "Связи". Вы делали новую страницу на основе Активности?

На странице описано поле(в diff),  у которого неправильно указан родительский контейнер

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

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

Возник вопрос:
Как при помощи БП или есть ли какие-то другие возможности реализации, после перевода объекта лид на стадию дисквалифицирован (дис)квалификации ЛИДа, сделать карточку объекта ЛИДА нередактируемой.

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

Нравится

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

В такой постановке вопроса, используйте элемент для изменения прав доступа. Т.е. заберите право на изменение у необходимых сотрудников

Роман, здравствуйте!

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

Логвин Андрей Витальевич,

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

Коллеги, спасибо! Но тогда таким образом я заберу права у пользователей и в дальнейшем у них не будет возможности работать с обьектом ЛИДов. 

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

Роман, по этому поводу есть статья на SDK - https://academy.terrasoft.ru/documents/technic-sdk/7-11/kak-polnostyu-z…

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

Добрый день, подскажите, пожалуйста, можно ли сделать активную ссылку в списке менеджеров(как при выборе во всплывающем окне, но должен оставаться именно списком), чтобы при нажатие на неё происходил переход в карточку менеджера?
И можно ли сделать так, чтобы у менеджера отображалось к каким сделкам привязан этот сотрудник (за какие активности ответственен)?

Нравится

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

Мария, при использования элемента "Список" - можно открывать карточку контакта. А на страницу самой карточки добавить деталь, которая и свяжет его со сделками.

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

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

В выпадающем списке в базовой версии нет ссылок. Для решения измените тип поля на "Выбор из справочника".

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

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

Нравится

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

Здравствуйте, Мария!

В базовой версии продукта в карточке контакта присутствует данный функционал.

.

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

Добрый день. Как можно стандартными средствами реализовать вывод html блока на странице редактирования карточки.
В HTML блок будет подгружаться исходные данные HTML письма присланное на почту.

Нравится

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

Доброго дня!
Подскажите пожалуйста, стоит задача сделать кнопку для импорта из excel файла в деталь раздела
Я вроде нашел пример, но пока что ничего не получается. Не могу понять в чем проблема, поскольку проходит все без ошибок, но позиции не импортируются.

function importQuote()
{

        var FileName = GetNewValue();
        if (!(System.OpenDialog(FileName, '*', EmptyStr, EmptyStr, EmptyStr))) {
                return;
        }
       
        var ExelApp = new ActiveXObject("Excel.Application");
        var WorkBook = ExelApp.Workbooks.Open(FileName.Value);
        var Sheet = WorkBook.ActiveSheet;
       
        var startRow = 2;
        var currentRow = startRow;
        var rate = Sheet.Cells(2, 12).Value;
       
        var OfferingInContractDS =  GetSingleItemByCode('ds_OfferingInOrderX',  'OfferingInOrderX');
        EnableDatasetFilters(OfferingInContractDS,  false);
        OfferingInContractDS.Open();

        var offeringsNotFound = 0;
        try {
                while(Sheet.Cells(currentRow, 12).Value != null)
                {
                        OfferingInContractDS.Append();
                        var num = Sheet.Cells(currentRow, 12).Value;
                        OfferingInContractDS('Name') = num;
                        var partNumber = Sheet.Cells(currentRow, 12).Value;
                        OfferingInContractDS('Description') = partNumber;
                       
                        OfferingInContractDS.Post();                                                   
                        currentRow++;
                }
        } finally {
                OfferingInContractDS.Close();    
        }
        dlData.Dataset.Close();
        dlData.Dataset.Open();
        WorkBook.Close();
       
        ShowWarningDialog('Загружено: ' + (currentRow - startRow));
}

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

Нравится

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

Может, у Вас просто Excel «не хочет» работать по ActiveX?
Если пройти пошагово в отладчике, то на какой строке виснет?

Я немного подправил скрипт и теперь вылетает ошибка:
"Ошибка выполнения метода 'btnImportOnClick'. Ошибка сохранения записи. Оригинальное сообщение об ошибке: The statement has been terminated.
Cannot insert the value NULL into column 'SpecificationID', table 'TSXRM3.dbo.tbl_OfferingInOrderX'; column does not allow nulls. INSERT fails «Call Stack»"
Хотя я вроде в эту колонку ничего не импортирую

import_test.xlsx

function importQuote()
{
 
	var FileName = GetNewValue();
	if (!(System.OpenDialog(FileName, '*', EmptyStr, EmptyStr, EmptyStr))) {
		return;
	}
 
	var ExelApp = new ActiveXObject("Excel.Application");
	var WorkBook = ExelApp.Workbooks.Open(FileName.Value);
	var Sheet = WorkBook.ActiveSheet;
 
	var startRow = 12;
	var currentRow = startRow;
	var rate = Sheet.Cells(12, 2).Value;
 
	var OfferingInContractDS =  GetSingleItemByCode('ds_OfferingInOrderX',  'OfferingInOrderX');
	EnableDatasetFilters(OfferingInContractDS,  false);
	OfferingInContractDS.Open();
 
	var offeringsNotFound = 0;
	try {
		while(Sheet.Cells(currentRow, 2).Value != null)
		{
			OfferingInContractDS.Append();
			var num = Sheet.Cells(currentRow, 2).Value;
			OfferingInContractDS('Name') = num;
			var partNumber = Sheet.Cells(currentRow, 3).Value;
			OfferingInContractDS('Description') = partNumber; 
 
			OfferingInContractDS.Post();							
			currentRow++;
		}
	} finally {
		OfferingInContractDS.Close();    
	}
	dlData.Dataset.Close();
	dlData.Dataset.Open();
	WorkBook.Close();
 
	ShowWarningDialog('Загружено: ' + (currentRow - startRow));
}

"Родненок Дмитрий Павлович" написал:Хотя я вроде в эту колонку ничего не импортирую

В том и дело. Вы не заполняете значением обязательное поле.

Понял, спасибо!
Теперь все импортирует!
Есть еще маленький вопрос:
У меня имеется поле с номером, который является автоинкрементом и храниться в системных настройках.
Каким образом я могу проставлять на все импортируемые файлы этот номер +1 и записывать последнее значение в системные настройки?Чтобы каждая позиция имела уникальный номер
И может быть сможете подсказать, как реализовать вложенность при импорте, поскольку деталь древовидная

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