Задача:
пользователю без полных прав необходимо предоставить полномочия для отмены редактирования файлов, занятых другими пользователями.
Решение:
- создаем расширение конфигурации, добавляем в нем новую роль. Я назвал ее РСФ_СнятиеБлокировкиПрисоединенныхФайлов.
- в модуле РаботаСФайламиСлужебный заимствуем процедуру ДобавитьНастройкиРаботыСФайлами и вносим в нее изменения
- в модуле РаботаСФайлами заимствуем процедуру ВыполнитьДействияПередЗаписьюПрисоединенногоФайла и вносим в нее изменения
- создаем профиль групп доступа с нашим правом, группу доступа с этим профилем и добавляем в нее пользователей
&После("ДобавитьНастройкиРаботыСФайлами")
Процедура РСФ_ДобавитьНастройкиРаботыСФайлами(ОбщиеНастройки, ПерсональныеНастройки)
// Предоставляем права доступа к файлам, если у пользователя есть наше право.
ПерсональныеНастройки.ЭтоПолноправныйПользователь = ПерсональныеНастройки.ЭтоПолноправныйПользователь ИЛИ Пользователи.РолиДоступны("РСФ_СнятиеБлокировкиПрисоединенныхФайлов");
КонецПроцедуры
&ИзменениеИКонтроль("ВыполнитьДействияПередЗаписьюПрисоединенногоФайла")
Процедура РСФ_ВыполнитьДействияПередЗаписьюПрисоединенногоФайла(Источник, Отказ)
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Если Источник.ДополнительныеСвойства.Свойство("КонвертацияФайлов") Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(Источник) = Тип("СправочникОбъект.ВерсииФайлов") Тогда
Если Не Источник.ЭтоНовый() И Не Пользователи.ЭтоПолноправныйПользователь() Тогда
ПрежниеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, "Автор");
ПроверитьИзменениеАвтораФайла(ПрежниеЗначения, Источник);
КонецЕсли;
Возврат;
КонецЕсли;
Если Источник.ЭтоНовый() Тогда
// Проверка права "Добавление".
Если НЕ РаботаСФайламиСлужебный.ЕстьПраво("ДобавлениеФайлов", Источник.ВладелецФайла) Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Недостаточно прав для добавления файлов в папку ""%1"".';
|en = 'Insufficient rights to add files to folder ""%1.""'"),
Строка(Источник.ВладелецФайла));
КонецЕсли;
Иначе
#Удаление
Если Пользователи.ЭтоПолноправныйПользователь() Тогда
#КонецУдаления
#Вставка
// Очевидная ошибка 1С. Права доступа к файлам уже определены в параметрах пользователя.
Если Пользователи.ЭтоПолноправныйПользователь() ИЛИ НастройкиРаботыСФайлами().ЭтоПолноправныйПользователь Тогда
#КонецВставки
ПрежниеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, "ПометкаУдаления");
Иначе
ПрежниеЗначения = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка, "ПометкаУдаления, Автор, Редактирует, Изменил");
ПроверитьИзменениеАвтораФайла(ПрежниеЗначения, Источник);
КонецЕсли;
ИзмененаПометкаУдаления = Источник.ПометкаУдаления <> ПрежниеЗначения.ПометкаУдаления;
Если ИзмененаПометкаУдаления Тогда
// Проверка права "Пометка на удаление".
Если НЕ РаботаСФайламиСлужебный.ЕстьПраво("ПометкаУдаленияФайлов", Источник.ВладелецФайла) Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Недостаточно прав для пометки файлов на удаление в папке ""%1"".';
|en = 'Insufficient rights to mark files in folder ""%1"" for deletion.'"),
Строка(Источник.ВладелецФайла));
КонецЕсли;
КонецЕсли;
Если ИзмененаПометкаУдаления И ЗначениеЗаполнено(Источник.Редактирует) Тогда
Если Источник.Редактирует = Пользователи.АвторизованныйПользователь() Тогда
ТекстОшибки = НСтр("ru = 'Действие недоступно, так как файл ""%1"" занят для редактирования.';
|en = 'Cannot perform the operation because file ""%1"" file is locked for editing.'");
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки, Источник.Наименование);
Иначе
ТекстОшибки = НСтр("ru = 'Действие недоступно, так как файл ""%1"" занят для редактирования
|пользователем %2.';
|en = 'Cannot perform the operation because user %2
|is editing file ""%1"".'");
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки,
Источник.Наименование, Строка(Источник.Редактирует));
КонецЕсли;
КонецЕсли;
ЗаписьПодписанногоОбъекта = Ложь;
Если Источник.ДополнительныеСвойства.Свойство("ЗаписьПодписанногоОбъекта") Тогда
ЗаписьПодписанногоОбъекта = Источник.ДополнительныеСвойства.ЗаписьПодписанногоОбъекта;
КонецЕсли;
Если ЗаписьПодписанногоОбъекта <> Истина Тогда
СтруктураРеквизитов = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.Ссылка,
"ПодписанЭП, Зашифрован, Редактирует");
СсылкаПодписан = СтруктураРеквизитов.ПодписанЭП;
СсылкаЗашифрован = СтруктураРеквизитов.Зашифрован;
СсылкаЗанят = ЗначениеЗаполнено(СтруктураРеквизитов.Редактирует);
Занят = ЗначениеЗаполнено(Источник.Редактирует);
Если Не Источник.ЭтоГруппа И Источник.ПодписанЭП И СсылкаПодписан И Занят И Не СсылкаЗанят Тогда
ВызватьИсключение НСтр("ru = 'Подписанный файл нельзя редактировать.';
|en = 'Cannot edit the file because it has been signed.'");
КонецЕсли;
Если Не Источник.ЭтоГруппа И Источник.Зашифрован И СсылкаЗашифрован И Источник.ПодписанЭП И НЕ СсылкаПодписан Тогда
ВызватьИсключение НСтр("ru = 'Зашифрованный файл нельзя подписывать.';
|en = 'Cannot sign an encrypted file.'");
КонецЕсли;
КонецЕсли;
СправочникПоддерживаетВозможностьХранитьВерсии = ОбщегоНазначения.ЕстьРеквизитОбъекта("ТекущаяВерсия", Метаданные.НайтиПоТипу(ТипЗнч(Источник)));
Если Не Источник.ЭтоГруппа И СправочникПоддерживаетВозможностьХранитьВерсии И ЗначениеЗаполнено(Источник.ТекущаяВерсия) Тогда
РеквизитыТекущейВерсии = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(Источник.ТекущаяВерсия, "Наименование");
// Проверим равенство имени файла и его текущей версии.
// Если имена отличаются - имя у версии должно стать как у карточки с файлом.
Если РеквизитыТекущейВерсии.Наименование <> Источник.Наименование
И ЗначениеЗаполнено(Источник.ТекущаяВерсия) Тогда
БлокировкаДанных = Новый БлокировкаДанных;
ЭлементБлокировкиДанных = БлокировкаДанных.Добавить(
Метаданные.НайтиПоТипу(ТипЗнч(Источник.ТекущаяВерсия)).ПолноеИмя());
ЭлементБлокировкиДанных.УстановитьЗначение("Ссылка", Источник.ТекущаяВерсия);
БлокировкаДанных.Заблокировать();
Объект = Источник.ТекущаяВерсия.ПолучитьОбъект();
Если Объект <> Неопределено Тогда
УстановитьПривилегированныйРежим(Истина);
Объект.Наименование = Источник.Наименование;
// Чтобы не сработала подписка СкопироватьРеквизитыВерсииФайловВФайл.
Объект.ДополнительныеСвойства.Вставить("ПереименованиеФайла", Истина);
Объект.Записать();
УстановитьПривилегированныйРежим(Ложь);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
Если Не ЗначениеЗаполнено(Источник.ВладелецФайла) Тогда
ОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Не заполнен владелец в файле
|""%1"".';
|en = 'The owner of file
|""%1"" is blank.'"), Источник.Наименование);
Если ОбновлениеИнформационнойБазы.ВыполняетсяОбновлениеИнформационнойБазы() Тогда
ЗаписьЖурналаРегистрации(НСтр("ru = 'Файлы.Ошибка записи файла при обновлении ИБ';
|en = 'Files.Error writing file during infobase update'", ОбщегоНазначения.КодОсновногоЯзыка()),
УровеньЖурналаРегистрации.Ошибка,, Источник.Ссылка, ОписаниеОшибки);
Иначе
ВызватьИсключение ОписаниеОшибки;
КонецЕсли;
КонецЕсли;
Если Источник.ЭтоГруппа Тогда
Источник.ИндексКартинки = 2;
Иначе
Источник.ИндексКартинки = РаботаСФайламиСлужебныйКлиентСервер.ПолучитьИндексПиктограммыФайла(Источник.Расширение);
КонецЕсли;
Если Источник.ЭтоНовый() И Не ЗначениеЗаполнено(Источник.Автор) Тогда
Источник.Автор = Пользователи.АвторизованныйПользователь();
КонецЕсли;
КонецПроцедуры