При добавлении или редактировании концертной программы для случая, если она ежедневная, выполнять проверку: если в результате изменений общее число активных ежедневных программ в системе будет превышать значение 3 (UsrSysSetingMaxNumberActiveDailyPrograms) то выводить сообщение об ошибке

Способ реализации:

обработчики в коде JavaScript страницы редактирования с применением клиентского ESQ и механизма валидации.

Нравится

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

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

Не совсем понимаю, что вы подразумеваете под "концертной" программой? Это объект в системе наподоби контактов или контрагентов?

Илья, реализовать вашу логику можно несколькими вариантами. 

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

2) Использовать событийный слой. Тут логика похожая, только можно считывать значение системной настройки UsrSysSetingMaxNumberActiveDailyPrograms и уже по нему выполнять необходимую логику. Также в этой событийной логике вы можете прописать логику добавления значения к этой системной настройке.

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

Добрый день!

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

При открытии карточки, чтобы не исчезал фильтр в поле, после закрытия карточки.

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

Нравится

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

Мы подобным образом делали поиск лидов в LeadSectionV2 по многим полям

 

		attributes: {
			"UseSearchFilter": {
				dataValueType: Terrasoft.DataValueType.BOOLEAN,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN,
				value: false
			},
			"SearchFilter": {
				dataValueType: Terrasoft.DataValueType.TEXT,
				type: Terrasoft.ViewModelColumnType.VIRTUAL_COLUMN
			}
		},
			initQueryFilters: function(esq) {
				this.callParent(arguments);
				var useSearchFilter = this.get("UseSearchFilter");
				var searchFilter = this.get("SearchFilter");
				if (!useSearchFilter || !searchFilter) {
					esq.filters.removeByKey("FilterContactCommunication");
				}
				else {
					var filterGroup = new Terrasoft.createFilterGroup();
					filterGroup.logicalOperation = Terrasoft.LogicalOperatorType.OR;
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].Contact", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].Account", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].BusinesPhone", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].MobilePhone", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].Email", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].Website", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].QualifiedAccount.Name", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[Lead:Id:Id].QualifiedContact.Name", searchFilter));
						filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[ContactCommunication:Contact:QualifiedContact].SearchNumber", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[ContactCommunication:Contact:QualifiedContact].Number", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[AccountCommunication:Account:QualifiedAccount].SearchNumber", searchFilter));
					filterGroup.addItem(Terrasoft.createColumnFilterWithParameter(
						Terrasoft.ComparisonType.CONTAIN, "[AccountCommunication:Account:QualifiedAccount].Number", searchFilter));
					esq.filters.add("FilterCommunication", filterGroup);
				}
			},
			searchFilter: function() {
				this.reloadGridData();
			},
			enableSearchFilter: function() {
				this.set("UseSearchFilter", true);
			},
			disableSearchFilter: function() {
				this.set("UseSearchFilter", false);
				this.reloadGridData();
			}
		},
		diff: /**SCHEMA_DIFF*/[
			{
				"operation": "insert",
				"name": "FilterSearchContainer",
				"parentName": "FiltersContainer",
				"propertyName": "items",
				"index": 0,
				"values": {
					"id": "FilterSearchContainer",
					"selectors": { wrapEl: "#FilterSearchContainer" },
					"itemType": Terrasoft.ViewItemType.CONTAINER,
					"wrapClass": ["quick-filter-module-container-wrapClass", "custom-filter-container"],
					"items": []
				}
			},
			{
				"operation": "insert",
				"parentName": "FilterSearchContainer",
				"propertyName": "items",
				"name": "EnableSearchFilter",
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"style": Terrasoft.controls.ButtonEnums.style.TRANSPARENT,
					"click": {"bindTo": "enableSearchFilter"},
					"caption": "Search"
				}
			},
			{
				"operation": "insert",
				"parentName": "FilterSearchContainer",
				"propertyName": "items",
				"name": "SearchFilter",
				"values": {
					"bindTo": "SearchFilter",
					"visible": {"bindTo": "UseSearchFilter"},
					"labelConfig": {
						"visible": false
					},
					"controlConfig": {
						"className": "Terrasoft.TextEdit"
					},
					"textSize": "Small"
				}
			},
			{
				"operation": "insert",
				"parentName": "FilterSearchContainer",
				"propertyName": "items",
				"name": "UseSearchFilter",
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"style": Terrasoft.controls.ButtonEnums.style.BLUE,
					"click": {"bindTo": "searchFilter"},
					"visible": {"bindTo": "UseSearchFilter"},
					"markerValue": "applyButton",
					"imageConfig": {"bindTo": "Resources.Images.ApplyButtonImageNew"}
				}
			},
			{
				"operation": "insert",
				"parentName": "FilterSearchContainer",
				"propertyName": "items",
				"name": "DisableSearchFilter",
				"values": {
					"itemType": Terrasoft.ViewItemType.BUTTON,
					"click": {"bindTo": "disableSearchFilter"},
					"visible": {"bindTo": "UseSearchFilter"},
					"markerValue": "cancelButton",
					"imageConfig": {"bindTo": "Resources.Images.CancelButtonImageNew"}
				}
			}
   }

 

Владимир Соколов,

Спасибо, попробуем

Владимир Соколов,

При открытии карточки фильтр очищается :(( а нам нужно, чтобы  хранился, пока не отменим

 

Тогда надо сохранять значение фильтра в профиле. Что-то похожее здесь обсуждалось - 

https://community.terrasoft.ru/questions/polzovatelskiy-fiksirovannyy-f…

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

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

Нравится

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

Попробуйте посмотреть в таблице

select * from SysAdminUnit

where Name = 'rolename'

 

Либо, если в процессе нужно, то читать данные из "Объект администрирования"

Попробуйте посмотреть в таблице

select * from SysAdminUnit

where Name = 'rolename'

 

Либо, если в процессе нужно, то читать данные из "Объект администрирования"

Спасибо, помогло

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

Добрый день!

 

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

Как я понимаю можно использовать метод фиксированных фильтров initFixedFiltersConfig для фильтрации, но каким методом можно будет настроить права доступа для них?

 

Код фильтрации:

initFixedFiltersConfig: function() {
            	console.log("initFixedFiltersConfig");
                // Создание конфигурационного объекта.
                var fixedFilterConfig = {
                    // В качестве схемы объекта для фиксированных фильтров указывается схема объекта раздела.
                    entitySchema: this.entitySchema,
                    // Массив фильтров.
                    filters: [
                        // Фильтр ответственного.
                        {
                            // Название фильтра.
                            name: "Owner",
                            // Заголовок фильтра.
                            caption: this.get("Resources.Strings.OwnerFilterCaption"),
                            // Фильтрация данных из колонки [Owner].
                            columnName: "Owner",
                            // В качестве значения по умолчанию указывается контакт текущего пользователя.
                            // Значение берется из системной настройки.
                            defValue: this.Terrasoft.SysValue.CURRENT_USER_CONTACT,
                            // Тип данных — справочник.
                            dataValueType: this.Terrasoft.DataValueType.LOOKUP,
                            // Фильтр.
                            //filter: BaseFiltersGenerateModule.OwnerFilter
                        }
                    ]
                };
                // Колонке [FixedFilterConfig] присваивается ссылка на созданный конфигурационный объект.
                this.set("FixedFilterConfig", fixedFilterConfig);
            }
		}

 

Нравится

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

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

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

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

Есть страница, которую создали в бп(преднастроенная страница). Как в в коде открыть ее не через БП?

Запуск страницы происходит из модуля групп. 

Нравится

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

ищите на community по кодовому слому openCardInChain

Владимир Соколов,

openCardInChain - нет в модуле групп, меня скорее интересует каким модулем можно прорисовать мою карточку в renderTo: "centerPanel"

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

Если вам не поможет openCardInChain, то можно попробовать использовать this.sandbox.loadModule().

Загрузка модулей через this.sandbox.loadModule() предусматривает использование метода initSchemaName (его реализацию можно найти в baseSchemaModule).

В этом методе можно увидеть, как берётся название страницы, что рендерится в модуле. Однако, можно напрямую задать страницу для рендера, пример этого есть в схеме CtiPanelModule где переопределён метод initSchemaName.

Можно написать свой модуль по примеру CtiPanelModule, где также переопределить метод initSchemaName куда передать нужную вам схему.

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

Добрый день!

 

Склонировали бд и в конфиге поменяли на новую, после запуска при аутентификации выходит следующая ошибка:

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

Подскажите, куда смотреть, что делать? Пробовали выполнять полную компиляцию

Нравится

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

Добрый день.

Выше Павел описал решение проблемы.

Немного дополню:

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

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

1. {Site-name}/0/dev

2. Перейти в конфигурацию другого сайта с такой же версией и скопировать адрессную строку и зайти на сайт с ошибкой изменив название сайта.



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

Конфигуратор открывается? /0/dev открывается? Если открывается, то обычно помогает "генерация" схем.

Добрый день.

Выше Павел описал решение проблемы.

Немного дополню:

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

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

1. {Site-name}/0/dev

2. Перейти в конфигурацию другого сайта с такой же версией и скопировать адрессную строку и зайти на сайт с ошибкой изменив название сайта.



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

Спасибо!

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

Добрый день.

Коллеги, прошу помочь.

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

 

Реализация через запрос esq:

prepareResponseCollectionItem: function(item) {
    this.callParent(arguments);
	let accountId = item.get("Id");
	var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
		rootSchemaName: "AccountAddress"
	});
	esq.addColumn("Account");
	esq.addColumn("AddressType");
	var esqFirstFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "Account", accountId);
	var esqSecondFilter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "AddressType", "0092db56-5b25-4804-a900-ab3b00912832");
	esq.filters.logicalOperation = Terrasoft.LogicalOperatorType.AND;
	esq.filters.add("esqFirstFilter", esqFirstFilter);
	esq.filters.add("esqSecondFilter", esqSecondFilter);
	esq.getEntityCollection(function(result) {
		if (result.success) {
			result.collection.each(function(item) {
				item.customStyle = {
				"background": "#ffaf3e"
				};
			});
		}
	}, this);
},

Реализация через вызов сервиса (который возвращает true/false):

prepareResponseCollectionItem: function(item) {
	this.callParent(arguments);
	let accountId = item.get("Id");
	var serviceData = {
		AccountId: accountId
	};
	ServiceHelper.callService("MyService", "MyMethod", function(response) {
		if (response.MyServiceResult === true) {
			item.customStyle = {
				"background": "#ffaf3e"
			};
		}
	}, serviceData, this);
},

 

Оба варианта не успевают выполниться при отрисовке страницы.

Прошу подсказать как можно поменять цвет записи реестре путем обращения в БД, а не относительно колонки обьекта.

 

Спасибо.

Нравится

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

Соловьев Сергей Николаевич,

Добрый день! Есть решение.

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

			addGridDataColumns: function(esq) {
						this.callParent(arguments);
						this.AccountAdressColumn(esq);
					},
 
					AccountAdressColumn: function(esq) {
						var aggregationColumn = this.Ext.create("Terrasoft.SubQueryColumn", {
							aggregationType: Terrasoft.AggregationType.COUNT,
							columnPath: "[AccountAddress:Account].Id",
							subFilters: this.getFilterGroup()
						});
						if (!esq.columns.contains("HasAddress")) {
							esq.addColumn(aggregationColumn, "HasAddress");
						}
					},
					getFilterGroup: function(){
						var filterGroup = Ext.create("Terrasoft.FilterGroup");
										filterGroup.add("AddressType",
									Terrasoft.createColumnFilterWithParameter(
										Terrasoft.ComparisonType.EQUAL,
										"AddressType",
										"770bf68c-4b6e-df11-b988-001d60e938c6"));
						return filterGroup;
					},
					prepareResponseCollectionItem: function(item) {
						this.callParent(arguments);
						if(item.get("HasAddress")>0) {
							console.log(item.get("Name"));
						}
					},

 

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

 

Вашу задачу можно реализовать таким образом.

 

1. В таблицу контрагентов добавьте булевское поле 'IsLegalAddressExists', для которого нужно реализовать логику установки значения true, если для контрагента есть хотя бы один юридический адрес, и false, если нет ни одного юридического.

 

2. А в реестре подсветку реализуйте в зависимости от значения нового поля 'IsLegalAddressExists'.

Сергей, добрый день!

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

Добрый день.

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

 

А я хочу реализовать логику, которая будет красить реестр на основании любого условия.

Соловьев Сергей Николаевич,

Не совсем понимаю чем вам не подходят указанные варианты. В приведённом мною примере записи логика успеет выполниться перед отрисовкой страницы. Само же условие можно сделать любым, главное чтобы выполнилось условие true для блока if, где ставиться стиль, хороший пример условия if описала Алла в своём сообщении. Также замечу, что стили не хранятся в БД, поэтому невозможно написать такой к ней запрос, который изменит цвет для записи.

Дима Вовченко,

 

Вы предлагаете реализовать логику на основании колонки обьекта (в примере по ссылке, колонка Status). А я как раз не хочу использовать колонку (потому как такой нет).

 

Для того что выполнить мою бизнес-задачу  с использованием колонки, то нужно добавить (в моем понимании) "костыльную" логику:

1. Добавить колонку в обьект

2. Реализовать логику заполнения и снятия признака с колонки.

Соловьев Сергей Николаевич,

Добрый день! Есть решение.

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

			addGridDataColumns: function(esq) {
						this.callParent(arguments);
						this.AccountAdressColumn(esq);
					},
 
					AccountAdressColumn: function(esq) {
						var aggregationColumn = this.Ext.create("Terrasoft.SubQueryColumn", {
							aggregationType: Terrasoft.AggregationType.COUNT,
							columnPath: "[AccountAddress:Account].Id",
							subFilters: this.getFilterGroup()
						});
						if (!esq.columns.contains("HasAddress")) {
							esq.addColumn(aggregationColumn, "HasAddress");
						}
					},
					getFilterGroup: function(){
						var filterGroup = Ext.create("Terrasoft.FilterGroup");
										filterGroup.add("AddressType",
									Terrasoft.createColumnFilterWithParameter(
										Terrasoft.ComparisonType.EQUAL,
										"AddressType",
										"770bf68c-4b6e-df11-b988-001d60e938c6"));
						return filterGroup;
					},
					prepareResponseCollectionItem: function(item) {
						this.callParent(arguments);
						if(item.get("HasAddress")>0) {
							console.log(item.get("Name"));
						}
					},

 

Трефилов Павел Сергеевич пишет:

Добрый день! Есть решение.

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


 
			addGridDataColumns: function(esq) {
						this.callParent(arguments);
						this.AccountAdressColumn(esq);
					},
 
					AccountAdressColumn: function(esq) {
						var aggregationColumn = this.Ext.create("Terrasoft.SubQueryColumn", {
							aggregationType: Terrasoft.AggregationType.COUNT,
							columnPath: "[AccountAddress:Account].Id",
							subFilters: this.getFilterGroup()
						});
						if (!esq.columns.contains("HasAddress")) {
							esq.addColumn(aggregationColumn, "HasAddress");
						}
					},
					getFilterGroup: function(){
						var filterGroup = Ext.create("Terrasoft.FilterGroup");
										filterGroup.add("AddressType",
									Terrasoft.createColumnFilterWithParameter(
										Terrasoft.ComparisonType.EQUAL,
										"AddressType",
										"770bf68c-4b6e-df11-b988-001d60e938c6"));
						return filterGroup;
					},
					prepareResponseCollectionItem: function(item) {
						this.callParent(arguments);
						if(item.get("HasAddress")>0) {
							console.log(item.get("Name"));
						}
					},

Дякую!

Це те що треба! 

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

Доброго дня!



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

Например, приходит уведомление на почту что зарегистрировано N объектов с каким-то признаком (например, задач на определенного пользователя). И есть кнопка "Перейти к списку задач". Есть необходимость при нажатии на кнопку в письме перейти к перечню записей, в которых поле X равно определенному значению.

Возможно ли как-то формировать url на отфильтрованный перечень?

Нравится

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

Здравствуйте, Вадим!



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

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

Друзья, подскажите, может кто сталкивался Creatio Studio 7/18/5.

При сохранении БП возникает ошибка 

Error occurred when saving: Method not found: 'Microsoft.CodeAnalysis.SyntaxTree Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(System.String, Microsoft.CodeAnalysis.CSharp.CSharpParseOptions, System.String, System.Text.Encoding, System.Collections.Immutable.ImmutableDictionary`2, System.Threading.CancellationToken)'.

 

Переустановил Net Core,

NET Framework

Microsoft Visual C++ 2010 Redistributable Package (x64)

Обязательные компоненты все есть.

 

При чем на той же машине развернута 7.17 Bank sales, и с ней все в порядке.

Нравится

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

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

Так же рекомендую проверить зависимости у пакета, в котором находится БП, с которым вы работаете.

В БП есть элемент "Задание-сценарий"? Возможно к ошибке приводит скрипт, который добавлен в этот элемент. Вы можете выгрузить БП (В дизайнере Бизнес процессов -> действия -> экспорт метаданных), для того чтобы мы могли проанализировать данный БП на наличие ошибок.

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

Добрый день!

при попытке компиляции в конфигурации Creatio выбивает ошибку

File name                                         Description                        Code                  Line

Microsoft.CSharp.Core.targets    Unexpected exception:   MSB3883           59

Ошибка ведет в Visual Studio, которое в работе не используется  Изображение удалено.

установлено Visual Studio 2019 

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

В чем может быть проблема?  

Нравится

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

Добрый день!

Рекомендую также попробовать переустановить компоненты .NetCore и .NetFramework:

 

Скачать 64-разрядный .NET Core SDK 3.1.301

Скачать 64-разрядный .NET Framework SDK v 4.7.2

 

Для Linux-сборок инструкция доступна по ссылке.

После переустановки нужно обязательно выполнить перезапуск машины.

 

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

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