Публикация

Принудительное добавление прав для любого ответственного

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

Предлагаю такой рецепт: в функции btnOKOnClick проверяем, равен ли ответственный в карточке текущему ответственному и менялся ли ответственный вообще. Затем, если успешно отработала функция scr_BaseDBEdit.btnOKOnClick(Control) (проверяем по состоянию датасета, он в этом случае переходит в dstInactive (см. константы состояний в scr_SysEmums), создаём и выполняем SQL-строку, добавляющую запись прав (возможны два варианта: для представления, если текущий пользователь - не администратор, и для таблицы, если он администратор). И обновляем деталь "Доступ".

Предлагаемый пример годится для раздела "Продукты" (используется таблица прав tbl_OfferingRight). Аналогично можно сделать для любого другого раздела: стоит только поменять имя таблицы. Сделано для MSSQL, легко переделывается и для Oracle.

function btnOKOnClick(Control) {
        var Dataset = dlData.Dataset;
        var DatasetState = Dataset.State;
        var ID = Dataset.Values('ID');
        var OwnerID = Dataset.Values('OwnerID');

        //Требуется ли раздавать права
        var NeedInsertRight = Dataset.Values('OwnerID') != Connector.CurrentUser.ContactID &&
                Dataset.Datafields.ItemsByName('OwnerID').ValueIsChanged;
        scr_BaseDBEdit.btnOKOnClick(Control); //Базовый ОК
       
        //Создаём доступ для записи, если есть такая необходимость
        //И если запись по ОК сохранена
        if (NeedInsertRight && Dataset.State == dstInactive){
                var Prefix = (Connector.CurrentUser.IsAdmin)?'tbl':'vw';
                var SQL = 'declare @OwnerID nvarchar(250) \n\n'+
                'set @OwnerID = (select top 1 [ID] from [tbl_AdminUnit] \n'+
                'where [UserContactID] = \'' + OwnerID + '\') \n\n' +
                'if (@OwnerID Is Not Null)\n Begin \n' +
                'insert into [' + Prefix + '_OfferingRight] '+
                '([ID], [RecordID], [AdminUnitID], [CanRead], [CanWrite], [CanDelete], [CanChangeAccess])'+
                ' values '+'(newid(), \'' + ID + '\', @OwnerID,1,1,1,0)\n'+
                'END';//Если поставить 1,1,1,1 - будет полный набор прав. Нужно варьировать в зависимости от пожеланий КВ.
                //Log.Write(1, SQL);
                Connector.DBEngine.ExecuteCustomSQL(SQL, System.EmptyValue);
                //Обновляем грид
                var RightGridDataset = wnd_OfferingEdit.Attributes('NotifyObject').ParentContainer.ParentWindow.
ComponentsByName('wndAccessDetail').Window.NonVisualComponents.ItemsByName('dlData').Dataset;
                if (Assigned(RightGridDataset)){
                        RightGridDataset.Close();
                        RightGridDataset.Open();
                }
        }
}

Нравится

Поделиться

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

Анатолий, добрый день.

Есть пару замечаний:
1. Не рекомендую размещать подобную логику в обработчике вообще и в обработчике btnOKOnClick в частности. Логику следует реализовать в отдельном методе, а вызывать этот метод стоит из обработчика событий набора данных - идеально для этого подойдет обработчик "AfterPost".
2. Не совсем ясно, зачем в данном конкретном случае понадобилась работа с ExecuteCustomSQL. Ведь можно было бы обойтись стандартными средствами, создав один единственный сервис вставки, в котором потребовалось бы динамически проставлять только одно свойство - таблицу прав. Примеры работы по такой схеме можно посмотреть в scr_Access.

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

Спасибо за замечания! Справедливо, такие вещи нужно делать AfterPost. Это позволит, прежде всего, отслеживать изменения ответственных не только из карточки редактирования, но и при любом использовании набора данных. Разве что обновление детали прав будет выглядеть сложнее.

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

>> Не совсем ясно, зачем в данном конкретном случае понадобилась работа с ExecuteCustomSQL. Ведь можно было бы обойтись стандартными средствами, создав один единственный сервис вставки, в котором потребовалось бы динамически проставлять только одно свойство - таблицу прав. Примеры работы по такой схеме можно посмотреть в scr_Access.

В ряде случаев использование ExecuteCustomSQL предпочтительнее использования сервисов. В частности, если функционал выполняется очень часто, то, на мой взгляд, лучше использовать ExecuteCustomSQL.

>>В ряде случаев использование ExecuteCustomSQL предпочтительнее использования сервисов. В частности, если функционал выполняется очень часто, то, на мой взгляд, лучше использовать ExecuteCustomSQL.

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

Прекрасно! Видны и плюсы и минусы. Если кому-то потребуется решить такую задачу, можно будет взвесить все "за" и "против" и выбрать самый лучший метод.

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