Добрый день.

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

В loginmodule.js в onLoginButtonClick добавляю вызов аналогичный ..AuthService.svc/Login.

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

Анонимный сервис делал по аналогии https://academy.terrasoft.ru/documents/technic-sdk/7-13/kak-sozdat-anon…

Нравится

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

Скорее всего у вас не выполнен или выполнен с ошибками 4 пункт  руководства по созданию анонимного веб-сервиса а именно: Настройте доступ к WCF-сервиса для всех пользователей.

Возможно после окончания настройки сервиса вы не выполнили рестарт пула IIS

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

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

Григорий Чех,

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

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

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

Почему для моего случая не работает?

Либо что-то неверно в коде, либо не так зарегистрирован в конфигах.

Может как-то влиять, что вызов моего сервиса происходит в callback сервиса авторизации? также в примере из академии пример не компилировался и я добавил наследование от BaseService. 

Сам сервис доступен без авторизации postman отправлять.

Также, если необходимо, могу привести пример клиент. кода loginmodule.js

Привожу пример моего сервиса:

[OperationContract]

        [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped,

        ResponseFormat = WebMessageFormat.Json)]

        public string GetMyService(string Name)

        {

            var returnObject = new

            {

                ResultCode = 0,

                ResponseText = ""

            };

            return JsonConvert.SerializeObject(returnObject);

        }

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

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

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

Если авторизация уже прошла, то можно обычный сервис.

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

у пользователя может не быть лицензии, авторизация не пройдет полноценно, хотя AuthService возвращает OK, поэтому я рассчитывал настроить анонимный сервис

Все входы, в том числе и неуспешные, можно логировать:

 

scr_chapter_system_operations_log_system_setting.png

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

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

это усложняет задачу, через вызов сервиса никак нельзя?

Можно: 

Зверев Александр пишет:

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

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

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

Заметил интересную вещь о стандартным сервисом авторизации:

Запускаю его с клиента (у пользователя нет лицензии) в loginmodule.js и в колбэке еще раз его. Он отрабатывает и 401 ошибки нет. Как мне свой кастомный сервис также настроить?

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

А сервису авторизации не нужно знать, вошёл ранее или нет, он заменяет куки новыми.

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

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

Сервис авторизации сделан на уровне ядра, в конфигурации его нет.

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

Подскажите, как из бизнес-процесса сделать запись в центр уведомлений (нужно записать текст ошибки для админа при работе интеграции сделанной с  помощью бизнес-процесса)?

Нравится

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

Prime Source,

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

Обсуждалось тут описано тут

Григорий Чех,

 

Можно найти эту запись в базе в таблице Reminding и посмотреть значение поля NotificationTypeId и других интересующих полей.

Григорий Чех,

 Можно ли отправить уведомление не конкретному человеку а группе, к примеру пользователям с правами System Administrator ?

Нет, поле «Кому» ссылается только на контакт.

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

 это я тоже заметил. Но есть же наверно возможность уведомления в центр уведомлений отправлять группе? Или все же это только поименно и других нет способов?

Почему Вы считаете, что такая возможность есть? Список полей объекта виден в дизайнере, там поля «Группа пользователей» нет.

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

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

Prime Source,

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

Как вариант, писать в ленту. Создать канал, подписать на него нужную группу пользователей.

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

во, отличная идея про канал. Теперь только нужно подумать как из процесса в канал отправить сообщение))

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

Добрый день!

Подскажите, пожалуйста, возможно ли передавать дополнительные параметры в макрос, вызываемый в email-шаблоне через [#@Invoke.MyMacros#] ?

Например, нужно реализовать конвертацию значения поля типа boolean из true/false в "да"/"нет". Или преобразовать дату в специальный формат.

Метод GetMacrosValue(object arguments) интерфейса IMacrosInvokable принимает объект с аргументами, но по умолчанию в нем - только идентификатор текущей записи.

Нравится

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

Стандартно в системе есть макрос EstimateLinksGenerator для голосования за оценку, он находится в одноимённой схеме. Но там тоже получают Id и далее работают с ним. Если дата или логическое значение находятся в полях этой записи, то к ним можно получить доступ по её Id.

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

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

Может, есть какой-то альтернативный вариант решения проблемы?

Нужно смотреть в MacrosHelper, который это всё обрабатывает, как там устроено и есть ли возможность для расширения.

Добрый день, подскажите, может кто нашел решение данной задачи?

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

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

Есть деталь. Нужно сделать в ней 2 вкладки, в них должно быть разные фильтры. Есть у кого какие идеи? Как вариант сделать в детале бул поле и на негго вешать установку-снятие фильтра. Но возможно можно сделать вкладки, как в тройке

Нравится

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

Радчук Виталий Владимирович,

А зачем вам вкладки? Почему бы не сделать обновление грида детали по нужным фильтрам? А для детали просто добавить 2 кнопки, нажатие 1 кнопки приведет к установке Фильтров А и обновлению грида, а по 2 следовательно Фильтры Б и обновление грида.

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

Те вы хотите одну и туже деталь использовать в 2х вкладках с разными условиями фильтрации (отбора данных) ?

 

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

Григорий Чех,

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

Радчук Виталий Владимирович,

А зачем вам вкладки? Почему бы не сделать обновление грида детали по нужным фильтрам? А для детали просто добавить 2 кнопки, нажатие 1 кнопки приведет к установке Фильтров А и обновлению грида, а по 2 следовательно Фильтры Б и обновление грида.

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

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

Есть БП который вызывается через кнопку в клиентском модуле, он заполняет деталь. Как через сообщения сделать обновление детали после окончания работы БП что бы было видно наполнение детали? На форуме был такой вопрос но там было сделано через ивент в БП старого типа, в новых это не работает.

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

Нравится

7 комментариев
Лучший ответ
PostMessage отправляет конкретному юзеру. Поэтому надо быть уверенным, что бп запущен от нужного пользователя и он на нужной странице(где есть код для обработки обратного сигнала). 
Если не подходит, можно воспользоваться PostMessageToAll(string sender, string message). Рассылает сообщение по всей конфигурации всем пользователям.

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

В конце БП в элементе Задание-сценарий вставляете следующую строку:

 

MsgChannelUtilities.PostMessage(UserConnection, "MyMessage", "UpdateDetail");

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

 

init: function () {
				this.callParent(arguments);
				this.subscriptionFunction();
			},
subscriptionFunction: function() {
				Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
				this.bpListenerMessage, this);
			},
bpListenerMessage: function(scope, message) {
				if (!message || message.Header.Sender !== "MyMessage") {
					return;
				}
				var message2 = message.Body;
				if (!this.Ext.isEmpty(message2) && message2 === "UpdateDetail") {
					this.updateDetail();
				}
			}

Примерно так.

Нигрескул Алексей,

 

Не обновляет, уже и не знаю в чем дело может быть

В БП

var userConnection = Get<UserConnection>("UserConnection");
Terrasoft.Configuration.MsgChannelUtilities.PostMessage(userConnection, "ReloadDetailConcert", "UpdateDetail");
return true;

На клиенте

init: function () {
	this.callParent(arguments);
	this.subscriptionFunction();
},
subscriptionFunction: function() {
	Terrasoft.ServerChannel.on(Terrasoft.EventName.ON_MESSAGE,
	this.bpListenerMessage, this);
},
bpListenerMessage: function(scope, message) {
	if (!message || message.Header.Sender !== "ReloadDetailConcert") {
		return;
	}
	var message2 = message.Body;
	if (!this.Ext.isEmpty(message2) && message2 === "UpdateDetail") {
		this.updateDetail();
	}
},

 

PostMessage отправляет конкретному юзеру. Поэтому надо быть уверенным, что бп запущен от нужного пользователя и он на нужной странице(где есть код для обработки обратного сигнала). 
Если не подходит, можно воспользоваться PostMessageToAll(string sender, string message). Рассылает сообщение по всей конфигурации всем пользователям.

Варфоломеев Данила,

Изменил на 

Terrasoft.Configuration.MsgChannelUtilities.PostMessageToAll("ReloadDetailConcert", "UpdateDetail");
return true;

не помогло

Нужно ли еще прописать?

messages: {
	"ReloadDetailConcert": {
		mode: Terrasoft.MessageMode.BROADCAST,
		"direction": Terrasoft.MessageDirectionType.SUBSCRIBE
	}
},

 

Prime Source,

Да нет. Должно и так работать. Даже subscriptionFunction не вызывается?

Варфоломеев Данила,

По дебагу срабатывает, и сообщение правильно ловит, и выполняет this.updateDetail(); ,но почему нет данных в детали не пойму. Может что в процессе не так? Вот его скрин, там идет цикл который делает 8 проходов, и когда в таблице 8 записей становится он выполняет скрипт сообщения и завершает

 

Prime Source,

//Relationships - название детали из details.
//пример:
this.updateDetail({detail: "Relationships"});

Проверьте код(указывается ли имя детали). Плюс должны быть настроены колонки

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

Cделан запрос в базу данных из клиентского модуля для получения системной настройки: 

this.Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(value) {
	countSettings = value;
}, this);

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

message - сообщение для поля валидации;

periodicity  - выпадающий список (словарь) в котором есть значение "Ежедневно";

countSettings  - ранее полученное значение системной настройки;

concertProgramsCount - количество записей в таблице;

var periodicity = "";
if (this.get("PsPeriodicity")) {
	periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
	rootSchemaName: "PsConcertPrograms"
});
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
var esq1Filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
	"PsPeriodicity.Name", "Ежедневно");
esq.filters.add("esq1Filter", esq1Filter);
esq.getEntityCollection(function(result) {
	var message = "";
	if (result.success) {
		var concertProgramsCount = result.collection.collection.length;
		if (periodicity === "Ежедневно" && concertProgramsCount <= countSettings ) {
			message = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
		}
	}
	return message;
}, this);

Вывод валидации для поля и при сохранении страницы:

concertHallsValidator: function(message) {
	var invalidMessage = message;
	return {
		fullInvalidMessage: invalidMessage,
		invalidMessage: invalidMessage
	};
}

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

Спасибо всем кто окажет помощь в решении проблемы.

Нравится

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

Prime Source,

нет. стоп. я думал вы прогоняете esq в onEntityInitialized, а потом используете this.$PeriodValidationMessage для проверки. тогда такие варианты:

1) на изменение поля PsPeriodicity запускаете concertHallsValidator. Изменяете this.addColumnValidator("CreatedOn", this.MessageValidator);

2) Используете asyncValidate (вроде так называется метод)

И уберите return. Ну не используется он в асинхронных функциях)

немного не понимаю смысла return из async функции, поэтому вариант такой:

в attributes добавляете 

"PeriodValidationMessage": {
	dataValueType: 1,
	value: ""
}

esq:

var periodicity = "";
if (this.get("PsPeriodicity")) {
	periodicity = this.get("PsPeriodicity").displayValue;
}
var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "PsPeriodicity.Name", "Ежедневно"));
esq.getEntityCollection(function(result) {
	if (result.success) {
		var concertProgramsCount = result.collection.collection.length;
		//считывание сист. настройки
		Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
			//сравнение
			if (periodicity === "Ежедневно" &amp;&amp; concertProgramsCount &lt;= countSettings ) {
				this.$PeriodValidationMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
			}
 
		}, this);
	}
}, this);

валидация

concertHallsValidator: function(message) {
	var invalidMessage = this.$PeriodValidationMessage;
	return {
		fullInvalidMessage: invalidMessage,
		invalidMessage: invalidMessage
	};
}

 

Добрый день,

Каждый борется с асинхронностью своими средствами :)

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

Тёскин Дмитрий Валерьевич,

 

Пробовал, тогда return возвращает поздно ответ

concertHallsValidator:  function(){
	var periodicity = "";
	if (this.get("PsPeriodicity")) {
		periodicity = this.get("PsPeriodicity").displayValue;
	}
	this.Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
			rootSchemaName: "PsConcertPrograms"
		});
		esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
		var esq1Filter = esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL,
			"PsPeriodicity.Name", "Ежедневно");
		esq.filters.add("esq1Filter", esq1Filter);
		esq.getEntityCollection(function(result) {
			var invalidMessage = "";
			if (result.success) {
				var concertProgramsCount = result.collection.collection.length;
				if (periodicity === "Ежедневно" &amp;&amp; concertProgramsCount &gt; countSettings ) {
					invalidMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
				}
			}
			return invalidMessage;
		}, this);
	}, this);
},
setValidationConfig: function() {
	this.callParent(arguments);
	this.addColumnValidator("PsPeriodicity", this.concertHallsValidator);
}

 

Варфоломеев Данила,

Асинхронность не дает

methods: {
	concertHallsValidator:  function(callback){
		var periodicity = "";
		if (this.get("PsPeriodicity")) {
			periodicity = this.get("PsPeriodicity").displayValue;
		}
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
		esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
		esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, "PsPeriodicity.Name", "Ежедневно"));
		esq.getEntityCollection(function(result) {
			if (result.success) {
				var concertProgramsCount = result.collection.collection.length;
				//считывание сист. настройки
				Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
					//сравнение
					if (periodicity === "Ежедневно" &amp;&amp; concertProgramsCount &lt;= countSettings ) {
						this.$PeriodValidationMessage = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
					}
					return callback.call(this);
				}, this);
			}
		}, this);
	},
	MessageValidator: function() {
		var invalidMessage = this.$PeriodValidationMessage;
		return {
			fullInvalidMessage: invalidMessage,
			invalidMessage: invalidMessage
		};
	},
	setValidationConfig: function() {
		// Вызывает инициализацию валидаторов родительской модели представления.
		this.callParent(arguments);
		this.addColumnValidator("CreatedOn", this.concertHallsValidator(this.MessageValidator));
	}
},
			}

 

Prime Source,

нет. стоп. я думал вы прогоняете esq в onEntityInitialized, а потом используете this.$PeriodValidationMessage для проверки. тогда такие варианты:

1) на изменение поля PsPeriodicity запускаете concertHallsValidator. Изменяете this.addColumnValidator("CreatedOn", this.MessageValidator);

2) Используете asyncValidate (вроде так называется метод)

И уберите return. Ну не используется он в асинхронных функциях)

Варфоломеев Данила,

 

Спасибо большее, помогло отлично asyncValidate. Раньше не знал что этот метод. Вод такой код заработал отлично:

asyncValidate: function(callback, scope) {
	this.callParent([function(response) {
		if (!this.validateResponse(response)) {
			return;
		}
		Terrasoft.chain(
			function(next) {
				this.validateConcertHalls(function(response) {
					if (this.validateResponse(response)) {
						next();
					}
				}, this);
			},
			function(next) {
				callback.call(scope, response);
				next();
			}, this);
	}, this]);
},
validateConcertHalls: function(callback, scope) {
	Terrasoft.SysSettings.querySysSettingsItem("PsMaximumProgramsCount", function(countSettings) {
		var periodicity = "";
		var result = {success: true};
		if (this.get("PsPeriodicity")) {
			periodicity = this.get("PsPeriodicity").displayValue;
		}
		var esq = Ext.create("Terrasoft.EntitySchemaQuery", { rootSchemaName: "PsConcertPrograms" });
		esq.addColumn("PsPeriodicity.Name", "PsPeriodicityName");
		esq.filters.addItem(esq.createColumnFilterWithParameter(Terrasoft.ComparisonType.EQUAL, 
			"PsPeriodicity.Name", "Ежедневно"));
		esq.getEntityCollection(function(response) {
			if (response.success &amp;&amp; periodicity === "Ежедневно" &amp;&amp; (!this.isAddMode() &amp;&amp; 
				response.collection.getCount() &gt; countSettings) || (this.isAddMode() &amp;&amp; 
				response.collection.getCount() &gt;= countSettings)) {
					result.message = this.get("Resources.Strings.PsFewFreeConcertHalls").replace("NNN", countSettings);
					result.success = false;
			}
			callback.call(scope || this, result);
		}, this);
	}, this);
}

 

Prime Source,

Если ваша функция должна возвращать какие-то значение, то из коллбэка это сделать не получится. В этом случае у вас уже должны быть где-то готовые значения для того, что бы функция валидации могла синхронно выполниться и вернуть значения. Например значение системной настройки можно получить при инициализации страницы и сохранить в атрибуте страницы, т.к. системная настройка скорее всего не будет часто меняться. Значение из esq запроса можно так же получить раньше и сохранить в атрибут, а потом уже при валидации оперировать существующими значениями. Ну или сделать так, как посоветовал Варфоломеев Данила.

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

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

Два вопроса (не связанных друг с другом):

1. Есть ли возможность вызвать какую-либо функцию после авторизации? Для примера - показывать окно с сообщением сразу после авторизации пользователя. Попробовал добавлять такие вызовы в схемы, загружающиеся только один раз (MainHeaderSchema, CommunicationPanel и т.д.), но вот проблема - если пользователь нажмёт F5, то снова сработает загрузка, а значит - вызов окна.

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

2. Есть ли в фильтрах - https://academy.terrasoft.ru/documents/technic-sdk/7-8/rabota-s-filtram… (именно в варианте для клиентской части) фильтрация "последних нескольких записей"? Т.е. к примеру, фильтрация по колонке с датой:

var dateColumn = esq.addColumn("UsrDate");
dateColumn.orderDirection = Terrasoft.OrderDirection.DESC;
dateColumn.orderPosition = 0;

выведет все записи в порядке убывания значений колонки UsrDate. А как мне вытащить только, допустим, первые пять?

Нравится

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

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

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
      rootSchemaName: "UsrTable",
      rowCount: 5
}
var createdOnColumn = esq.addColumn("CreatedOn");
createdOnColumn .orderDirection = Terrasoft.OrderDirection.DESC;
createdOnColumn .orderPosition = 0;

 

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

2. Вам нужно указать при обращении к EntitySchemaQuery кол-во выводимых записей в запросе:

  var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
      rootSchemaName: "UsrTable",
      rowCount: 5
   }

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

var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
      rootSchemaName: "UsrTable",
      rowCount: 5
}
var createdOnColumn = esq.addColumn("CreatedOn");
createdOnColumn .orderDirection = Terrasoft.OrderDirection.DESC;
createdOnColumn .orderPosition = 0;

 

Григорий Чех пишет:

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

Из второго вопроса Дениса понятно, он понимает, что записи должны быть отсортированы (он даже приводит пример). А я ответила на конкретный вопрос пользователя 'как мне вытащить только, допустим, первые пять?'. 

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

Где можно изменить стандартную страницу для заявок портала по умолчанию?

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

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

Нравится

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

Стандартно страницы «Базовая страница заявок портала самообслуживания» в системе нет. Видимо, у Вас она была переименована или полностью самодельная.

Страница, которая будет отображаться при входе пользователя на портал задаётся в системной настройке SSPMainPage. По умолчанию это раздел «Главная страница».

А другие разделы на портале задаются как обычные разделы рабочего места «Портал» в мастере разделов.

Информация о портале с точки зрения разработки есть тут.

Добавить комментарий

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

Спасибо за ответ.

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

По кнопке открывается страница PortalCasePage.

А как настраивать главную страницу портала и её блоки, описано тут. В дизайнере системы есть специальное действие.

Блок со списком обращений задан в схеме UserCasesListModule. 

Видимо, в нём потребуется переделать функцию getAddCardUrl, чтобы открывало вместо PortalCasePage нужную Вам карточку.

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

Объект - ContractVisa,

Метод- GetNotificationInfo

Ошибка: При формировании визы по договору получаем значение contract.AccountName и contract.ContactName.

Но если для объекта Account и/или Contact изменить поле для отображения то при получении значения contract.AccountName (contract.ContactName) получаем ошибку Undefined.

Нравится

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

В объекте Contract нет отдельного поля AccountName. Это автоматически созданное поле для первичного поля отображения контрагента:

{
  "UId": "b1b39ef5-5550-41b4-9ad9-77f60c847d89",
  "Name": "Account",
  "CreatedInSchemaUId": "897be3e4-0333-467d-88e2-b7a945c0d810",
  "ModifiedInSchemaUId": "897be3e4-0333-467d-88e2-b7a945c0d810",
  "CreatedInPackageId": "1401a881-7126-4c81-86f8-4e9e355b0669",
  "DataValueTypeUId": "b295071f-7ea9-4e62-8d1a-919bf3732ff2",
  "ReferenceSchemaUId": "25d7c1ab-1de0-4501-b402-02e0e5a72d6e",
  "RequirementType": 1,
  "IsIndexed": true,
  "ColumnValueName": "AccountId",
  "DisplayColumnValueName": "AccountName"
},

Соответственно, при изменении первичного поля в настройках объекта Account поле в Contract тоже изменит название. С ContactName всё аналогично.

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

 

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

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

Вопрос - как можно увидеть остальные 63 пользователей что бы видеть из лицензии в менеджере лицензий? И можно ли экспортировать этот список с полями "Пользователь - тип лицензии"?

Нравится

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

Prime Source,

А раздел Пользователи системы из дизайнера системы доступен? По сути одно и то же. В менеджере лицензий нет возможности исправить набор колонок и отобразить больше 100 записей. Ответ от техподдержки звучал так: "На уровне приложения можно просмотреть только 100 записей. Это действительно так. У нас есть задачи по доработке функционала, однако в ближайшее время они реализованы не будут."

Есть нет раздела Пользователи системы, то выгружать из БД. 

Подобный вопрос был. Я решал через настройку колонок в Студия.Пользователи системы. Вывел колонки Активен, тип подключения, Тип, Лицензия.Количество. 

либо запрос к БД - покажет пользователей без лицензий.

SELECT us.NAME

    ,lic.SysLicPackageId

    ,licp.NAME

    ,lic.Active

    ,lic.SysUserId

FROM SysAdminUnit us

LEFT JOIN SysLicUser lic ON lic.SysUserId = us.id

LEFT JOIN SysLicPackage licp ON lic.SysLicPackageId = licp.id

WHERE us.SysAdminUnitTypeValue = 4 and lic.SysLicPackageId is null.

Алексей Следь,

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

Экспорт выходит можно только через БД сделать?

Prime Source,

А раздел Пользователи системы из дизайнера системы доступен? По сути одно и то же. В менеджере лицензий нет возможности исправить набор колонок и отобразить больше 100 записей. Ответ от техподдержки звучал так: "На уровне приложения можно просмотреть только 100 записей. Это действительно так. У нас есть задачи по доработке функционала, однако в ближайшее время они реализованы не будут."

Есть нет раздела Пользователи системы, то выгружать из БД. 

Алексей Следь,

 

Пользователи есть, спасибо, попробую там

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