Вопрос

Коллеги, приветствую!

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

Благодарю заранее.

У меня такой же вопрос

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

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

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

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

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

Добрый день. Подскажите, есть 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 записей. Это действительно так. У нас есть задачи по доработке функционала, однако в ближайшее время они реализованы не будут."

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

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

 

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

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

Коллеги, добрый день.

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

"Превышено максимально допустимое количество подключений"

Лицензии у пользователей есть.

Как устранить данную ошибку? 

 

update: Нашли не законченные сессии, которые висят еще с 17 года. Как правильно их закончить? Достаточно будет ли сделать update записей прописав им дату завершения сеанса сегодняшним числом? Могут ли данные сессии использовать лицензии и быть причиной возникновения ситуации описанной выше?

У меня такой же вопрос

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

Добрый день, Евгений.

Вероятно, сессии зависли после некорректного завершения. Если у Вас конкурентные лицензии - это действительно может являться причиной ошибки. Попробуйте в нерабочее время выполнить скрипт через SQL Management Studio, который закроет все пользовательские сессии (после применения, все сессии принудительно закроются, т.е. пользователя выбросит из системы на страницу логина):
UPDATE SysAdminUnit SET LoggedIn = 0 WHERE LoggedIn = 1
UPDATE SysUserSession SET SessionEndDate = '2018-02-12 10:16:49.078' WHERE SessionEndDate IS NULL

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

Антон Малий,

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

Антон Малий,

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

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

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

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

В API текущего приложения, не входит каких либо инструментов для упрощенной работы с элементами организационной структуры:
"Функциональные роли", "Организационные юниты", "Пользователи" (само по себе)
Уже обсуждалось вот в этой теме
Там же я выложил первые наработки, миксин-модуля с некоторыми методами решающими классические "юзкейсы".
С тех пор его пришлось существенно доработать и расширить функционал, по этому выложу его в этой отдельной теме для тех кому может понадобиться.
Во вложении (ZIP-архив) вы найдете исчерпывающую документацию в виде HTML-страницы.
Модуль реализован в виде "миксина", т.е. без каких либо трудностей подключайте в любой схеме и пользуйтесь на здоровье :) так же в конце темы есть исходный код, а так-же Уже готовая к импорту схема в виде MD-файла.
Краткое описание:
getRelAU ([id], callback, [contactModeFlag], [scope]);
Получить информацию об административных юнитах связанных с пользователем, по его идентификатору Id или Id связанного с ним контакта, или для текущего пользователя если опустить первый аргумент.
(элементы "Организационной структуры", "Функциональные роли", "Организации", "Роли руководителей" (если он в них входит)) в виде структурированного объекта с дополнительной информацией (н/п о родительских OU/FU) будут переданы в callback вызов.
checkUserInAU (AUname, [AUtype], [UserId], callback, [scope])
Проверить принадлежит ли текущий пользователь (или произвольный по его Id) к конкретному административному юниту по его имени (элементу "Организационной структуры", "Функциональные роли", "Организации").
В целях оптимизации предусмотрен поиск только по конкретным типам Орг.юнитов. Результат передается в виде булева примитива в callback-функцию
getUsersFromRole (RoleId, [getManagerFlag], callback, [scope])
Получить всех пользователей непосредственно входящих в целевые орг.юнит или функциональную роль, в том числе руководителей (пользователей из специалищированного связанного орг.юнита).
Коллекция пользователей будет передана в callback-функцию

Исходный код:

define("UserUtilsMixin", ["UserUtilsMixinResources"],
        function(resources) {
                Ext.define("Terrasoft.configuration.mixins.UserUtilsMixin", {
                        "alternateClassName": "Terrasoft.UserUtilsMixin",
                        "getRelAU": function(UserId, callback, UseContactIdFlag, scope) {
                                var serviceScope;
                                if (callback === undefined) {
                                        callback = UserId;
                                        UserId = Terrasoft.core.enums.SysValue.CURRENT_USER.value;
                                }
                                if (typeof callback === "object") {
                                        scope = callback;
                                        callback = UserId;
                                        UserId = Terrasoft.core.enums.SysValue.CURRENT_USER.value;
                                }
                                if (typeof UseContactIdFlag === "object") {
                                        scope = UseContactIdFlag;
                                        UseContactIdFlag = false;
                                }
                                if (typeof scope !== "object") {
                                        scope = this;
                                } else if (scope.scope) {
                                        serviceScope = scope;
                                        scope = scope.scope;
                                }
                                function mainLogick(UserId, callback) {
                                        var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                                                rootSchemaName: "SysUserInRole"
                                        });
                                        var filter = this.scope.Terrasoft.createColumnFilterWithParameter(
                                                this.scope.Terrasoft.ComparisonType.EQUAL,
                                                "SysUser",
                                                UserId
                                        );
                                        esq.filters.addItem(filter);
                                        esq.addColumn("SysRole");
                                        esq.addColumn("[SysAdminUnit:Id:SysRole].Name", "AuName");
                                        esq.addColumn("[SysAdminUnit:Id:SysRole].ParentRole", "Parent");
                                        esq.addColumn("[SysAdminUnit:Id:SysRole].[SysAdminUnitType:Value:SysAdminUnitTypeValue].Name", "AuType");
                                        esq.getEntityCollection(
                                                function(response) {
                                                        if (response && response.success) {
                                                                var resultObject = {
                                                                        FuncRoles: [],
                                                                        OrgUnits: [],
                                                                        Organizations: [],
                                                                        Managers: [],
                                                                        Teams: []
                                                                };
                                                                response.collection.each(function(item) {
                                                                        var wrapObj = {
                                                                                name: item.values.AuName,
                                                                                id: item.values.SysRole.value,
                                                                                parentAU: item.values.Parent
                                                                        };
                                                                        var type = item.values.AuType;
                                                                        if (type === "Division") {
                                                                                resultObject.OrgUnits.push(wrapObj);
                                                                        } else if (type === "Функциональная роль") {
                                                                                resultObject.FuncRoles.push(wrapObj);
                                                                        } else if (type === "Organization") {
                                                                                resultObject.Organizations.push(wrapObj);
                                                                        } else if (type ===  "Manager") {
                                                                                resultObject.Managers.push(wrapObj);
                                                                        } else if (type ===  "Team") {
                                                                                resultObject.Teams.push(wrapObj);
                                                                        }
                                                                });
                                                                if (serviceScope) {
                                                                        this.callback.call(serviceScope, resultObject);
                                                                } else {
                                                                        this.callback.call(scope, resultObject);
                                                                }
                                                        }
                                                },
                                                {callback: callback, scope: this.scope}
                                        );
                                }
                                var wrapOfMainLogick = mainLogick.bind({scope: scope, callback: callback});
                                if (UseContactIdFlag) {
                                        var esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                                                rootSchemaName: "SysAdminUnit"
                                        });
                                        var filter = this.Terrasoft.createColumnFilterWithParameter(
                                                this.Terrasoft.ComparisonType.EQUAL,
                                                "Contact.Id",
                                                UserId
                                        );
                                        esq.filters.addItem(filter);
                                        esq.getEntityCollection(
                                                function(response) {
                                                        if (response.collection.getCount() !== 1) {
                                                                this.scope.log("(getRelAU) Target Contact is not associated with User", Terrasoft.LogMessageType.ERROR);
                                                        } else {
                                                                this.mainLogick(response.collection.getByIndex(0).values.Id, this.callback);
                                                        }
                                                },
                                                {
                                                        scope: scope,
                                                        mainLogick: wrapOfMainLogick,
                                                        callback: callback
                                                }
                                        );
                                } else {
                                        wrapOfMainLogick(UserId, callback);
                                }
                        },
                        "checkUserInAU": function(AUname, AUtype, UserId, callback, scope) {
                                if (typeof AUtype === "function" && UserId === undefined) {
                                        callback = AUtype;
                                        AUtype = "ALL";
                                        if (typeof UserId === "object") {
                                                scope = UserId;
                                        }
                                        UserId = Terrasoft.core.enums.SysValue.CURRENT_USER.value;
                                }
                                if (typeof UserId === "function") {
                                        if (typeof callback === "object") {
                                                scope = callback;
                                        }
                                        callback = UserId;
                                        UserId = Terrasoft.core.enums.SysValue.CURRENT_USER.value;
                                }
                                if (typeof UserId !== "object") {
                                        scope = this;
                                }
                                this.getRelAU(UserId, function(result) {
                                        var CompareResult = false;
                                        switch (this.AUtype) {
                                                case "OU":
                                                        for (var OU in result.OrgUnits) {
                                                                if (this.AUname === result.OrgUnits[OU].name) {
                                                                        CompareResult = true;
                                                                }
                                                        }
                                                        break;
                                                case "FR":
                                                        for (var FU in result.FuncRoles) {
                                                                if (this.AUname === result.FuncRoles[FU].name) {
                                                                        CompareResult = true;
                                                                }
                                                        }
                                                        break;
                                                case "ORG":
                                                        for (var orgIndex in result.Organizations) {
                                                                if (this.AUname === result.Organizations[orgIndex].name) {
                                                                        CompareResult = true;
                                                                }
                                                        }
                                                        break;
                                                default:
                                                        for (var each in result) {
                                                                for (var subarray in result[each]) {
                                                                        if (this.AUname === result[each][subarray].name) {
                                                                                CompareResult = true;
                                                                        }
                                                                }
                                                        }
                                                        break;
                                        }
                                        this.callback.call(this.scope, CompareResult);
                                }, {
                                        scope: scope,
                                        AUtype: AUtype,
                                        AUname: AUname,
                                        callback: callback
                                });
                        },
                        "getUsersFromRole": function(RoleId, getManager, callback, scope) {
                                var getManagerFlag = false, filter = Terrasoft.createFilterGroup(), esq;
                                if (typeof getManager === "function") {
                                        callback = getManager;
                                        if (typeof callback === "object") {
                                                scope = callback;
                                        }
                                } else {
                                        getManagerFlag = getManager;
                                }
                                if (typeof scope !== "object") {
                                        scope = this;
                                }
                                if (getManagerFlag) {
                                        filter.logicalOperation = Terrasoft.LogicalOperatorType.AND;
                                        esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                                                rootSchemaName: "SysAdminUnit"
                                        });
                                        filter.addItem(
                                                this.Terrasoft.createColumnFilterWithParameter(
                                                        this.Terrasoft.ComparisonType.EQUAL,
                                                        "ParentRole",
                                                        RoleId
                                                )
                                        );
                                        filter.addItem(
                                                this.Terrasoft.createColumnFilterWithParameter(
                                                        this.Terrasoft.ComparisonType.EQUAL,
                                                        "SysAdminUnitTypeValue",
                                                        2
                                                )
                                        );
                                        esq.addColumn("Name");
                                } else {
                                        esq = Ext.create("Terrasoft.EntitySchemaQuery", {
                                                rootSchemaName: "SysUserInRole"
                                        });
                                        filter.addItem(
                                                this.Terrasoft.createColumnFilterWithParameter(
                                                        this.Terrasoft.ComparisonType.EQUAL,
                                                        "SysRole",
                                                        RoleId
                                                )
                                        );
                                        esq.addColumn("[SysAdminUnit:Id:SysUser].Name", "UserName");
                                        esq.addColumn("[SysAdminUnit:Id:SysUser].Id", "UserId");
                                        esq.addColumn("[SysAdminUnit:Id:SysUser].Contact", "Contact");
                                }
                                esq.filters.addItem(filter);
                                esq.getEntityCollection(
                                        function(response) {
                                                var cleanArray = [];
                                                if (this.getManagerFlag) {
                                                        this.scope.getUsersFromRole(
                                                                response.collection.getByIndex(0).values.Id,
                                                                this.callback,
                                                                this.scope
                                                        );
                                                } else {
                                                        response.collection.each(function(elem) {
                                                                elem.values.Id = elem.values.UserId;
                                                                delete elem.values.UserId;
                                                                cleanArray.push(elem.values);
                                                        });
                                                        this.callback.call(this.scope, cleanArray);
                                                }
                                        }, {
                                                scope: scope,
                                                callback: callback,
                                                getManagerFlag: getManagerFlag
                                        }
                                );
                        }
                });
        });

У меня такой же вопрос

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

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

Полезная информация, спасибо.

код миксина обновлен (исправлены некоторые проблемы, добавлены некоторые решения), MD-файл из приложений убрал он не актуален.
берите код из листинга в теме.

примеры для вызова getRelAU

//Получаем результирующий объект для текущего пользователя
this.getRelAU(
         function(result) {
                console.log(result);
         }
);
//Тот же вызов, но с явным определением контекста для callback-функции
this.getRelAU(
         function(result) {
                console.log(result);
         }
, context);
//Получаем результирующий объект для пользователя с id "9D3B1042-9E88-499F-B13F-3E7F7F3FAD7D"
this.getRelAU(
    "9D3B1042-9E88-499F-B13F-3E7F7F3FAD7D",
   function(result) {
        console.log(result);
    }
);
//Тот же вызов, но с явным определением контекста для callback-функции
this.getRelAU(
    "9D3B1042-9E88-499F-B13F-3E7F7F3FAD7D",
    function(result) {
        console.log(result);
    }
, context);
//Получаем результирующий объект для пользователя связанного с контактом id которого "E7D525FB-88EE-4947-94CC-D013E85D2F79"
this.getRelAU(
    "E7D525FB-88EE-4947-94CC-D013E85D2F79",
    function(result) {
        console.log(result);
    },
    true
 );
//Тот же вызов, но с явным определением контекста для callback-функции
this.getRelAU(
    "E7D525FB-88EE-4947-94CC-D013E85D2F79",
    function(result) {
        console.log(result);
    },
    true,
    context
);

в схему корректно не выгружается кириллица, а поскольку в SysAdminUnitType одна только "Функциональная роль" названа кириллицей.
То после импорта схемы посмотрите в исходник, там где "кракозебры" замените на "Функциональная роль"
Будет время, обновлю MD-корректный

                      

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

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

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

define("UserUtilsMixin", ["UserUtilsMixinResources"]

 

создала у себя миксин, но без этого UserUtilsMixinResources, а также изменив названия миксина в 3 местах. когда его подключаю в своем клиентском модуле, выходит ошибка.

Есть какие-то особенности при этого подключении миксина?

UserUtilsMixinResources, это имя модуля + Resources стандартная мнемоника для объявления ресурсов в зависимостях для схем.

в 3-х местах это в каких ?

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

Добрый день!

Прошу подсказать, каким наиболее изящным образом можно формировать обобщённую статистику по активности пользователей при работе в CRM? Интересует аналог журнала аудита, который показывал бы в каких разделах и какие действия выполняли пользователи, с возможностью фильтра и экспорта в Excel.

Заранее благодарен!

У меня такой же вопрос

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

Сергей, здравствуйте!

На текущий момент, с помощью базовых средств Вы можете в итогах создать график по объекту "Сеанс пользователя", где можно будет отобразить начало и завершение сеанса определенного пользователя и выгрузить указанный список в Excel (см. скриншоты).
Также, в реестре разделов Вы можете вывести колонку "Дата изменения", которая будет отображать последнюю дату изменения записи. Реестр разделов, также можно экспоритировать.

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

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

В базовой конфигурации описанный механизм не реализован.

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

Добрый день!
7.6
В разделе Пользователи есть деталь Правила доступа, на которой отображаются Сессии пользователя
!text

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

У меня такой же вопрос

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

Здравствуйте, Дарья!

Данная деталь "смотрит" на объект Сеанс пользователя (SysUserSession). Колонка связи с разделом Пользователь.Id == Сеанс пользователя.Пользователь

Используя эти данные и правила фильтрации найденных записей, Вы можете вывести информацию о последнем сеансе пользователя в реестр.

"Демьяник Алексей Олегович" написал:правила фильтрации найденных записей

Вот только в списке связей при построении расширенного фильтра для "Объекта администрирования" "Сеанса пользователя" нет :wink:

Да, в том-то и дело, что не нахожу "Сеанса пользователя" для "Объекта администрирования" в расширенном фильтре при поиски связей

Дарья,

дело в том, что "Сеанс пользователя" является системным объектом (как и все объекты, которые начинаются с "Sys%")

Системные объекты не отображаются при фильтрации и настройке колонок.

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

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

"Безродный Андрей" написал:Но можно попробовать создать представление на основе этой таблицы и по нему выполнять фильтрацию.

Адрей т.е если есть задачи где требуется пользователю предоставить возможным выполнять фильтрацию по системным таблицам, то лучше заранее делать "Представления". Я правильно вас понял? спасибо!!!

Добрый день!
Представление для таблицы "Сеанс пользователя" можно в этом случае создать как замещающий объект от "Сеанс пользователя" с установленной галкой "представление в БД" ?
или лучше вообще не выбирать для представления родительский объект в данном случае?

"Татаровская Дарья" написал:
Представление для таблицы "Сеанс пользователя" можно в этом случае создать как замещающий объект от "Сеанс пользователя" с установленной галкой "представление в БД" ?
или лучше вообще не выбирать для представления родительский объект в данном случае?

Да именно так и нужно Дарья сделать, а еще нужно написать SQL скрипт для создания представления, иначе представление в "Реальной БД" не появится. Примеры SQL сценариев можно подсмотреть в админке. Переходим "Конфигурация" -- > "SQL сценарии", В строке поиска указываем "vw%" и смотрим. примеры. и делаем свой Вьювер (представление)

про представления я знаю) и про sql скрипт тоже..
Меня интересует в этом конкретном случае - его лучше создать как все-таки замещающий объект или лучше ничего не указывать в родительском объекте?

Дарья день добрый!!!

В родительском объекте при Первом создании Представления указываем родительскую таблицу. К примеру создаю Представление для таблицы Контрагенты, следовательно в родительской таблице указываю Контрагенты и выставляю галочку, что это будет Представление. А уже после создаю SQL сценарий.

ну то есть представление в данном случае - это новый объект, не замещающий объект

спасибо

Создала представление. Теперь в расширенном фильтре появилось данное представления для связи - все получилось

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

Добрый день!
Скажите, пожалуйста, можно ли настраивать авторизацию с LDAP "точечно" - то есть, например, не всех пользователей из группы в LDAP, а только некоторых.
Если такой возможности нет, то какое обходное решение вы можете посоветовать?

У меня такой же вопрос

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

Здравствуйте, Дарья!

Мы уточнили у Вас, что речь идет не об авторизации, а именно о синхронизации пользователей с помощью LDAP.
Решение следующее:
1. Сначала Вам необходимо на сервере Active Directory (где находится информация о пользователях) создать новую группу.
2. В созданную группу внести только тех пользователей, которых Вы хотите синхронизировать с bpm'online.
3. В настройках синхронизации с LDAP указать название новой группы. Сохранить настройки.

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

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

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

Организационная роль является элементом организационной структуры компании, ее подразделением, например, “Отдел продаж московского филиала” или “HR-отдел киевского филиала”.

Функциональная роль отражает должность, которую сотрудник занимает в компании, например,
роль “Менеджеры по продажам”.

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

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

Чтобы предоставить доступ к разделу системы для определенной функциональной роли:

1.   Добавьте и настройте функциональную роль.

2.   Предоставьте доступ к объекту для добавленной функциональной роли.

Как добавить и настроить функциональную роль

Предположим, вам необходимо предоставить доступ к разделу [Продажи] для менеджеров
по продажам, работающим в московском и киевском филиалах компании. Для этого:

1.   Из дизайнера системы перейдите в раздел управления ролями и пользователями,
нажав на ссылку [Функциональные роли].

2.   На странице раздела нажмите на кнопку [Добавить]. На появившейся странице функциональной
роли определите ее параметры:

a.   Введите название роли, например, “Менеджеры по продажам”.

b.   На детали [Организационные роли] добавьте организационные роли, которые должны
входить в данную функциональную роль, например, “Отдел продаж московского филиала”
и “Отдел продаж киевского филиала”.

На заметку

Если доступ к разделу дополнительно требуется предоставить отдельным пользователям,
не входящим в добавленные организационные роли, добавьте необходимых пользователей
на детали [Пользователи].

Если необходимо определить список диапазонов IP-адресов, с которых пользователям
и их руководителям будет разрешен вход в систему, используйте деталь [Диапазон разрешенных
IP-адресов] вкладки [Правила доступа].

c.   Закройте страницу записи.

3.   Актуализируйте настроенные роли. Для этого в меню действий раздела выберите
команду [Актуализировать роли].

Актуализация ролей

Актуализация ролей

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

Как предоставить доступ к разделу

Чтобы предоставить доступ к разделу:

1.   Перейдите в раздел [Доступ к объектам], используя ссылку [Права доступа на объекты]
дизайнера системы.

2.   В списке раздела выберите необходимый объект, например, “Продажа”. Объект должен
администрироваться по операциям. Если администрирование по операциям отключено, установите
признак в колонке [Администрируется по операциям] для выбранного объекта. Обратите
внимание, что установка признака может занять некоторое время.

3.   Перейдите на деталь [Доступ к объекту].

4.   Нажмите на кнопку [Добавить] панели инструментов детали и в открывшемся окне
добавьте роль, для которой будет предоставлен доступ к разделу, например, роль “Менеджеры
по продажам”.

В результате на деталь будет добавлена роль “Менеджеры по продажам”, пользователи
которой смогут читать, добавлять, изменять и удалять данные раздела [Продажи]. Если
необходимо запретить какую-либо из этих операций, например, удаление записей, установите
запрет на удаление в соответствующей колонке.

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

Например,  сотрудник одновременно входит в роль “Менеджеры по продажам” и “Менеджеры
поддержки продаж”. Для роли “Менеджеры поддержки продаж” определено право только
на чтение раздела [Продажи], а для роли “Менеджеры по продажам” — право на все операции.
Чтобы сотрудник получил максимальные права доступа, переместите роль “Менеджеры по
продажам” так, чтобы она оказалась выше роли “Менеджеры поддержки продаж”. В результате
пользователь получит доступ к разделу [Продажи] в соответствии с правами, определенными
для роли “Менеджеры по продаже”, а не “Менеджеры поддержки продаж”.

Для перемещения ролей в списке используйте кнопки [Вверх] и [Вниз] панели инструментов
детали.

Поделиться

0 комментариев
Войдите или зарегистрируйтесь, чтобы комментировать
Вопрос

Кто-то знает этот запрос (для чего он, зачем и можно ли оптимизировать):

exec sp_executesql N'SELECT
        [vw_Account].[ID] AS [ID],
        [vw_Account].[Name] AS [Name]
FROM
        [dbo].[vw_Account] AS [vw_Account]
WHERE(EXISTS
        (SELECT
                [vw_Contact].[ID] AS [ID]
        FROM
                [dbo].[vw_Contact] AS [vw_Contact]
        WHERE([vw_Contact].[AccountID] = [vw_Account].[ID] AND
                EXISTS
                (SELECT
                        [tbl_AdminUnit].[ID] AS [ID]
                FROM
                        [dbo].[tbl_AdminUnit] AS [tbl_AdminUnit]
                WHERE([tbl_AdminUnit].[UserContactID] = [vw_Contact].[ID] AND
                        [tbl_AdminUnit].[UserIsEnabled] = @P1)))))
ORDER BY
        2 ASC'
,N'@P1 int',1

У меня такой же вопрос

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

Угадайка?

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

Можно exists убрать и условие ядреное, через inner join как мне кажется... только надо ли?

"Александр Кудряшов" написал:Можно exists убрать

Спасибо, Александр!
К сожалеюнию, пока нельзя убрать, так как не знаю откуда оно формируется. Но когда узнаю, то постараюсь сделать поле "IsUserAccount", в которое запихивать 1 при создании нового юзера с новым юзерКонтрагентом. тада выборка будет проще

SELECT
        [vw_Account].[ID] AS [ID],
        [vw_Account].[Name] AS [Name]
FROM
        [dbo].[vw_Account] AS [vw_Account]
WHERE IsUserAccount IS NOT NULL

Мне кажется отработает раз в 100 быстрее

SELECT
        [vw_Account].[ID] AS [ID],
        [vw_Account].[Name] AS [Name]
FROM
        [dbo].[[tbl_AdminUnit] AS [[tbl_AdminUnit]
inner join [vw_Contact] on [tbl_AdminUnit].[UserContactID] = [vw_Contact].[ID]
inner join [vw_Account] on [vw_Contact].[AccountID] = [vw_Account].[ID]
 
WHERE [tbl_AdminUnit].[UserIsEnabled] = @P1
 
ORDER BY
        2 ASC',N'@P1 int',1

формируется именно из системы, где-то сервис запроса есть, можно его переписать...

а что реально долго работает и тормозит систему???

ps почитал изыскания пытливых умов - вроде как exists в такой ситуации даже быстрее inner'а отработает

затер сообщение. был неправ :lol:

"AlexLS" написал:в которое запихивать 1 при создании нового юзера с новым юзерКонтрагентом

не правильно - надо это поле перезаписывать при изменении признака Активен любого пользователя, привязанного к этому контрагенту и выставлять в 0, если активных пользователей не осталось

"Андросов Дмитрий" написал:не правильно - надо это поле перезаписывать при изменении признака Активен любого пользователя, привязанного к этому контрагенту и выставлять в 0, если активных пользователей не осталось

Дмитрий, спасибо за ответ! Остается малое - выяснить откуда этот зловещий код выполняется!

"Александр Кудряшов" написал:а что реально долго работает и тормозит систему???

к сожалению из "самых страшных" в нашей терре он на 5 месте (остальные прорабатываю), а по частоте выполнения лидирует! То есть суммарный дюрейшен у юзеров зашкаливает!!!

а вообще это похоже на запрос для какого-то справочника типа "Контрагенты ответсвенных"
поищите UserIsEnabled с помощью GREP (у меня есть только в wnd_LicenseManagerScript, но там не то)
вот для сравнения запрос для справочника Ответсвенный (поиск по имени)

exec sp_executesql N'SELECT TOP 2
	[tbl_Contact].[ID] AS [ID],
	[tbl_Contact].[Name] AS [Name]
FROM
	[dbo].[vw_Contact] AS [tbl_Contact]
INNER JOIN
	[dbo].[tbl_AdminUnit] AS [tbl_AdminUnit] ON [tbl_AdminUnit].[UserContactID] = [tbl_Contact].[ID]
WHERE([tbl_AdminUnit].[UserIsEnabled] = @P1 AND
	[tbl_Contact].[Name] LIKE @P2 + ''%'')
ORDER BY
	1 ASC',N'@P1 int,@P2 nvarchar(4000)',1,N'слепо'

"Андросов Дмитрий" написал:но там не то

Я вот тоже не нашел :)
Похожие запросы есть в Users, LicenseManager, но вот точно такого же не было

"Андросов Дмитрий" написал:поищите UserIsEnabled с помощью GREP

к сожалению эта штука ищет только в scr_
а вот в sq_ увы...

"Александр Кудряшов" написал:Похожие запросы есть в Users, LicenseManager, но вот точно такого же не было

хехех. еще бы уметь его находить...

этот запрос выполняется перед function wnd_MainOnPrepare(Window). Как я понимаю, его и ядро юзает...

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

exec sp_executesql N'SELECT
	[tbl_SystemSetting].[ID] AS [ID],
	[tbl_SystemSetting].[Code] AS [Code],
	[tbl_SystemSetting].[ValueTypeID] AS [ValueTypeID],
	[tbl_SystemSetting].[StringValue] AS [StringValue],
	[tbl_SystemSetting].[FloatValue] AS [FloatValue],
	[tbl_SystemSetting].[IntegerValue] AS [IntegerValue],
	[tbl_SystemSetting].[BooleanValue] AS [BooleanValue],
	[tbl_SystemSetting].[DateTimeValue] AS [DateTimeValue],
	[tbl_SystemSetting].[DictionaryRecordID] AS [DictionaryRecordID],
	[tbl_SystemSetting].[EnumItemID] AS [EnumItemID],
	[tbl_SystemSetting].[IsCaching] AS [IsCaching]
FROM
	[dbo].[tbl_SystemSetting] AS [tbl_SystemSetting]
WHERE([tbl_SystemSetting].[Code] = @P1)',N'@P1 nvarchar(4000)',N'UpdateActiveSessionPeriod'

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

"Александр Кудряшов" написал:

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


Александр, а есть код выполняющийся перед wnd_MainOnPrepare?

"AlexLS" написал:а есть код выполняющийся перед wnd_MainOnPrepare?

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

"Александр Кудряшов" написал:Там раньше окно авторизации и проверка лицензии как раз идет

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

"Александр Кудряшов" написал:тут То Самое Ядро может что-то вызывать

Александр, вот мне кажется что ядро вызывает банальный sq_ который и поправили под собственные нужды не задумываясь, что оно где-то глобально юзается!!!

Кстати, оно же (запрос) вызывается и Outlook'ом...

"Андросов Дмитрий" написал:по всем вопросам, связанным с лицензиями все заканчивается заявлением, что механизм лицензирования закрыт и сакрален

Дмитрий, мне кажется что лицензии врядли вьюхой проверять будут, скорее всего обращались бы напрямую к tbl_Account и, так же кажется, что разработчики Террасофта, все-таки не настолько ... (тут каждый сам себе додумает), чтобы такой идиотский код. Хотя, возможно, и у них есть отдельные личности, к примеру разработчики лицензирования :smile:
В принципе, в недалекой перспективе, предполагаем переход на TSv7 и эта тайна может так и остаться не разрешенной, хотя кто знает, может на смену мне прийдут новые :biggrin: с этим же вопросом!

Кстати, очередной банальный (уж простите) вопрос: если выгрузить все сервисы в файлы и потом какой-нить утилиткой "поиск текста в xml" пройтись, тогда шансы на поиск увеличатся?

"AlexLS" написал:чтобы такой идиотский код

Ход абсолютно верен.
У простых пользователей НЕТ доступа к tbl_Account, а есть доступ только к vw_Account.
И проверка лицензии не то, ради чего стоит ломать имеющийся движок обращения к данным.

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

Да, может и так... поискал в sq_ по слову "UserIsEnabled" нашлось в sq_AdminUnit, sq_Contact, sq_ContactInTask, sq_User

Судя по Grep-поиску в скриптах и нахождению етого слова в wnd_LicenseManagerScript ... закрываю тему, благо ясно что этот код зашит

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

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

У меня такой же вопрос

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

Олеся, Вам необходимо раздать права доступа на существующие продукты (те, которые не отображаются у пользователей). Права на существующие записи распределяются через деталь [Доступ].
Т.е. Вам необходимо:
1. Под пользователем с правами администратора авторизоваться в Terrasoft.
2. Перейти в раздел [Продукты]. Через деталь [Доступ] изменить уровень прав для пользователей на требуемые продукты.

Если таких записей много, обратите внимание на скрипты: 1 и 2

Спасибо!

Войдите или зарегистрируйтесь, чтобы комментировать