11.04.2018, 11:15 | #1 |
Участник
|
Как ограничить доступ к редактированию полей на форме определенной группе пользователей
Добрый день.
Подскажите, пожалуйста, как ограничить доступ к редактированию полей на форме определенной группе пользователей. Предистория - есть группа пользователей "Бухгалтерия" и группа пользователей "Закупка". Закупщики создают договоры, поставщиков и регистрируют заказ на покупку, счет на оплату. У бухгалтеров на все это тоже есть полный доступ, в каких-то случаях они сами все это делают, + имеется куча других прав. Теперь бухгалтеры хотят, чтобы Закупщики создавали Договоры, Поставщиков, но после сохранения не могли редактировать данные. Доступ на редактирование должен быть только у бухгалтеров и у админов. Делала так, но теперь у Закупщиков при создании договора данные поля не доступны совсем. Как еще это можно сделать, чтобы выполнялись требования бухгалтерии? Делала на форме RContractTable метод init() public void init() { Args args = this.args(); super(); if (args.parmEnumType() == enumnum(RcontractPartnerTypeAll)) { contractType.selection(args.parmEnum()); } contractType.visible(! this.args().dataset() && contractType.selection() == RcontractPartnerTypeAll::All); this.updateDesign(); // --> if(UserInfoHelp::userInUserGroup(curUserId(), 'Закупка' )&&!UserInfoHelp::userInUserGroup(curUserId(), 'Admin' )&&!UserInfoHelp::userInUserGroup(curUserId(), 'Бухгалтерия' )) { allowEdit = UserInfoHelp::userInUserGroup(curUserId(), 'Закупка'); RContractTable_SubContract.allowEdit(!allowedit); RContractTable_ContractDate.allowEdit(!allowedit); RContractTable_RContractNumber.allowEdit(!allowedit); RContractTable_BusinessNum.allowEdit(!allowedit); RContractTable_PrivateNum.allowEdit(!allowedit); RContractTable_ContractAmount.allowEdit(!allowedit); RContractTable_RContractStatus.allowEdit(!allowedit); RContractTable_PostingProfile.allowEdit(!allowedit); RContractTable_Sign_DeferredCharges.allowEdit(!allowedit); RContractTable_MainContractAccount.allowEdit(!allowedit); LongContract.allowEdit(!allowedit); } // <-- } P.S. Перенесла тему из раздела Функционал. Советовали перекрыть метод active. Мне бы примеры. Спасибо. |
|
11.04.2018, 11:18 | #2 |
Участник
|
Я бы начал с постановки задачи. Прям вот сразу как только сохранил - сразу ничего больше нельзя редактировать? Это не очень правильно и совсем не удобно. Если уж нужны разграничения, то нужно делать статусы и, например, документам и справочникам в статусе "в работе" действительно ограничивать доступ по группам.
__________________
Ivanhoe as is.. |
|
11.04.2018, 12:49 | #3 |
Участник
|
Цитата:
Сообщение от Ivanhoe
Я бы начал с постановки задачи. Прям вот сразу как только сохранил - сразу ничего больше нельзя редактировать? Это не очень правильно и совсем не удобно. Если уж нужны разграничения, то нужно делать статусы и, например, документам и справочникам в статусе "в работе" действительно ограничивать доступ по группам.
|
|
11.04.2018, 12:52 | #4 |
Участник
|
В Аксапте нет явной кнопки "Сохранить" - непроизвольно для пользователя может произойти сохранение при переходе по гриду, вкладкам и т.п. (в связи со структурой таблиц и не только). И вы предлагаете сразу же не давать ничего поправить? Моментально помойкой станет справочник.
__________________
Ivanhoe as is.. |
|
11.04.2018, 16:07 | #5 |
Участник
|
Я бы посоветовал все-таки настроить безопасность для групп, чем вот так извращаться. Если у вас меняются функции персонала сейчас, то ничто не гарантирует стабильности в этом направлении завтра. Так что теперь, при смене регламента на предприятии каждый раз код переписывать?
__________________
// no comments |
|
11.04.2018, 16:11 | #6 |
Участник
|
Судя по коду, это не AX 2012. Соответственно стандартно группы можно либо к доступу на форму привязать (а там создание - выше чем редактирование), либо к видимости данных по RLS (т.е. только спрятать после создания получится), поэтому по любому доработка.
__________________
Ivanhoe as is.. |
|
11.04.2018, 16:13 | #7 |
Участник
|
Цитата:
И делается это на уровне ядра, т.е. манипуляциями пользователя, программировать ничего не надо.
__________________
// no comments Последний раз редактировалось dech; 11.04.2018 в 16:15. |
|
11.04.2018, 16:28 | #8 |
Участник
|
Это вы к чему? Как RLS позволит решить задачу "одни создают", другие "редактируют"?
__________________
Ivanhoe as is.. |
|
12.04.2018, 07:39 | #9 |
Участник
|
Цитата:
Цитата:
Вы правы, здесь AX 4.0 |
|
12.04.2018, 09:46 | #10 |
Участник
|
Цитата:
Так вот это я к тому, что RLS в данном случае в принципе не подходит, человек создаст запись и тут же её потеряет.
__________________
// no comments |
|
12.04.2018, 10:46 | #11 |
Участник
|
Да, согласен, пункт Create включает в себя Edit.
__________________
// no comments |
|
12.04.2018, 10:52 | #12 |
Участник
|
Кто будет удалять созданные по ошибке договоры, бухгалтерия? Или в саппорт будет обращение? Добавить статусы более эфективно и понятно
|
|
12.04.2018, 12:39 | #13 |
Участник
|
|
|
12.04.2018, 13:45 | #14 |
Участник
|
Как и писал Иван, в той постановке как Вы написали задача не то, чтобы не решаема, но приведет к массе проблем и недоразумений под девизом: я не успел изменить, а оно уже сохранилось...
Если код не для примера и речь действительно идет о договорах, то в таблице договоров есть поле "Статус". Если не было переделок, то, по умолчанию, при создании нового договора, это поле будет иметь значение RContractStatus::Passive = 0 - "Не оформлен". Вот ориентируясь на значение этого поля и можно делать предположения о том, находится ли запись в стадии "создания" или уже "создано" Тогда примерный код будет выглядеть так \Forms\RContractTable\Data Sources\RContractTable\Methods\active X++: public int active() { boolean isCheckGroup; int ret; ret = super(); if (ret) { // Определение принадлежности к нужной группе можно вынести в init-формы isCheckGroup = UserInfoHelp::userInUserGroup(curUserId(), 'Закупка'); if (isCheckGroup) { if (RContractTable.RContractStatus == RContractStatus::Passive) { MyObject.AllowEdit(true); } else { MyObject.AllowEdit(false); } } } return ret; } Т.е. здесь нельзя использовать только if() без else. Обязательно надо как устанавливать, так и снимать блокировку. Если, конечно, пользователь относится к нужной группе. Также следует рассмотреть вариант блокировки не объекта на форме, а напрямую поля в DataSource формы. Ведь, в общем случае, одно и то же поле DataSource может быть указано как источник данных разных объектов на форме. Ну, например, отображается объект в Grid на закладке "Обзор" и в группе полей на закладке "Разное" Непосредственно в методе active это будет выглядеть так X++: this.object(fieldnum(RContractTable,RContractAccount)).allowEdit(true);
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
12.04.2018, 14:37 | #15 |
Участник
|
Цитата:
Сообщение от Владимир Максимов
Как и писал Иван, в той постановке как Вы написали задача не то, чтобы не решаема, но приведет к массе проблем и недоразумений под девизом: я не успел изменить, а оно уже сохранилось...
Если код не для примера и речь действительно идет о договорах, то в таблице договоров есть поле "Статус". Если не было переделок, то, по умолчанию, при создании нового договора, это поле будет иметь значение RContractStatus::Passive = 0 - "Не оформлен". Вот ориентируясь на значение этого поля и можно делать предположения о том, находится ли запись в стадии "создания" или уже "создано" Тогда примерный код будет выглядеть так \Forms\RContractTable\Data Sources\RContractTable\Methods\active X++: public int active() { boolean isCheckGroup; int ret; ret = super(); if (ret) { // Определение принадлежности к нужной группе можно вынести в init-формы isCheckGroup = UserInfoHelp::userInUserGroup(curUserId(), 'Закупка'); if (isCheckGroup) { if (RContractTable.RContractStatus == RContractStatus::Passive) { MyObject.AllowEdit(true); } else { MyObject.AllowEdit(false); } } } return ret; } Т.е. здесь нельзя использовать только if() без else. Обязательно надо как устанавливать, так и снимать блокировку. Если, конечно, пользователь относится к нужной группе. Также следует рассмотреть вариант блокировки не объекта на форме, а напрямую поля в DataSource формы. Ведь, в общем случае, одно и то же поле DataSource может быть указано как источник данных разных объектов на форме. Ну, например, отображается объект в Grid на закладке "Обзор" и в группе полей на закладке "Разное" Непосредственно в методе active это будет выглядеть так X++: this.object(fieldnum(RContractTable,RContractAccount)).allowEdit(true); Владимир, Вы правы, тут некоторые данные отображаются в Grid на закладке "Обзор" и в группе полей на закладке "Разное" и т.д. Поэтому как лучше и верно будет это сделать? |
|
12.04.2018, 19:23 | #16 |
Участник
|
Цитата:
- Запретить редактировать поле DataSourse - один объект - Запретить редактировать все объекты формы, у которых в качестве источника данных указано поле этого DataSource - много объектов Выбор зависит от конкретной постановки задачи и личных предпочтений программиста.
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
17.04.2018, 08:44 | #17 |
Участник
|
Цитата:
Сообщение от Владимир Максимов
Если будет блокировано поле на уровне DataSource, то разрешение редактирования на уровне объекта формы будет проигнорировано. Таким образом у Вас есть выбор
- Запретить редактировать поле DataSourse - один объект - Запретить редактировать все объекты формы, у которых в качестве источника данных указано поле этого DataSource - много объектов Выбор зависит от конкретной постановки задачи и личных предпочтений программиста. |
|
17.04.2018, 10:46 | #18 |
Участник
|
сделайте отдельный ключ безопасности, в active() проверяйте доступ к данному ключу и по нему определяйте возможность редактирования определенных полей
ключ безопасности можно дать группе "бухгалтерия" впоследствии, если появятся сотрудники в других отделах (а они скорее всего появятся), которым необходимо будет дать доступ на редактирование этих полей, вы сможете вынести ключ в отдельную группу безопасности |
|
17.04.2018, 12:53 | #19 |
Участник
|
Что-то не работает (
Цитата:
Сообщение от astralsun
сделайте отдельный ключ безопасности, в active() проверяйте доступ к данному ключу и по нему определяйте возможность редактирования определенных полей
ключ безопасности можно дать группе "бухгалтерия" впоследствии, если появятся сотрудники в других отделах (а они скорее всего появятся), которым необходимо будет дать доступ на редактирование этих полей, вы сможете вынести ключ в отдельную группу безопасности Как можно сделать ключ безопасности, не подскажете, может есть примеры? |
|
17.04.2018, 13:23 | #20 |
Участник
|
Цитата:
делаете новый ключ RcotractRestrictedFields в active() прописываете allowEdit = !(hassecuritykeyaccess(securitykeynum(RcotractRestrictedFields), AccessType::Edit) && RContractTable.RecId); this.object(fieldnum(RContractTable,RContractAccount)).allowEdit(allowEdit); и далее список ваших полей, к которым необходимо ограничить доступ |
|
|
За это сообщение автора поблагодарили: S.Kuskov (5). |
|
|