gifts2017

Контроль записи/проведения документов в заданном интервале дней

Опубликовал Vinni Pooh (vinni_pooh) в раздел Администрирование - Защита, права, пароли

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

Решение не претендует на оригинальность, но, возможно, поможет кому-нибудь.

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

Настройка правил

Кроме регистра добавлена подписка на событие записи документа.

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

 

Функция ПроверитьВозможностьЗаписиДокумента(СсылкаДок, Пользователь, РежимЗаписи)
	КолДней = Неопределено;
	
	//проверим есть ли в регистре правила контроля по данному документу для переданного
	//пользователя, либо группы в которую он входит
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	ПравилаКонтроляДокументов.КолДнейПроведение КАК КолДнейПроведение,
	|	ПравилаКонтроляДокументов.КолДнейЗапись КАК КолДнейЗапись
	|ИЗ
	|	РегистрСведений.ПравилаКонтроляДокументов КАК ПравилаКонтроляДокументов
	|ГДЕ
	|	ПравилаКонтроляДокументов.Пользователь = &Пользователь
	|	И ТИПЗНАЧЕНИЯ(ПравилаКонтроляДокументов.Документ) = ТИПЗНАЧЕНИЯ(&Документ)
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ГруппыДоступа.Ссылка КАК ГруппаДоступа,
	|	ПравилаКонтроля.КолДнейПроведение КАК КолДнейПроведение,
	|	ПравилаКонтроля.КолДнейЗапись КАК КолДнейЗапись
	|ИЗ
	|	Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступа
	|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПравилаКонтроляДокументов КАК ПравилаКонтроля
	|		ПО (ПравилаКонтроля.Пользователь = ГруппыДоступа.Ссылка)
	|ГДЕ
	|	ГруппыДоступа.Пользователь = &Пользователь
	|	И ТИПЗНАЧЕНИЯ(ПравилаКонтроля.Документ) = ТИПЗНАЧЕНИЯ(&Документ)
	|";
	
	Запрос.УстановитьПараметр("Документ", СсылкаДок.Ссылка);
	Запрос.УстановитьПараметр("Пользователь", Пользователь);
		
	РезультатЗапроса = Запрос.ВыполнитьПакет();
	
	//сначала проверим есть ли правило для пользователя
	Выборка = РезультатЗапроса[0].Выбрать();
	Если Выборка.Следующий() Тогда
		КолДней = ?(РежимЗаписи = РежимЗаписиДокумента.Запись, Выборка.КолДнейЗапись, Выборка.КолДнейПроведение);
	КонецЕсли; 
	
	//для пользователя правил нету, возможно есть правило для групп в которых находится пользователь
	Если КолДней = Неопределено Тогда
		ПравилаПоГруппам = РезультатЗапроса[1].Выгрузить();
		Если ПравилаПоГруппам.Количество() Тогда
			КолДнейПроведение = Неопределено;
			КолДнейЗапись = Неопределено;
			//выбираем наименьшее количество дней из выбранных правил
			Для каждого ТекПравило Из ПравилаПоГруппам Цикл
				КолДнейПроведение = ?((КолДнейПроведение = Неопределено) 
					ИЛИ (ТекПравило.КолДнейПроведение < КолДнейПроведение И ТекПравило.КолДнейПроведение <> -1), 
					ТекПравило.КолДнейПроведение, КолДнейПроведение);
				КолДнейЗапись = ?((КолДнейЗапись = Неопределено) 
					ИЛИ (ТекПравило.КолДнейЗапись < КолДнейЗапись И ТекПравило.КолДнейЗапись <> -1), 
					ТекПравило.КолДнейЗапись, КолДнейЗапись);	
			КонецЦикла; 
			
			КолДней = ?(РежимЗаписи = РежимЗаписиДокумента.Запись, КолДнейЗапись, КолДнейПроведение);
		КонецЕсли; 
	КонецЕсли; 
	
	Если КолДней <> Неопределено И КолДней <> -1 Тогда 
		//ищем разницу в днях между текущей датой и датой документа, 
		//проверяем чтобы она не превышала заданое в правилах количество
		Запрос = Новый Запрос;
		Запрос.Текст = 
		"ВЫБРАТЬ
		|   РАЗНОСТЬДАТ(&ДатаДокумента, &ТекущаяДата, ДЕНЬ) КАК РазностьДат
		|";
		
		Запрос.УстановитьПараметр("ДатаДокумента", СсылкаДок.Дата);
		Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДата());
		
		Выборка = Запрос.Выполнить().Выбрать();
		Если Выборка.Следующий() Тогда
			Если Выборка.РазностьДат > КолДней Тогда
				Возврат Ложь;
			КонецЕсли; 
		КонецЕсли; 
	КонецЕсли; 
	
	//по данному документу для пользователя не заданно явных правил, контроль пройден
	Возврат Истина;
КонецФункции

Процедура ПодпискаНаСобытиеЗаписиДокументаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
	//Проверяем есть ли заданное количество дней для данного документа
	КонтрольПройден = ПроверитьВозможностьЗаписиДокумента(Источник, ПараметрыСеанса.ТекущийПользователь, РежимЗаписи);
	Если НЕ КонтрольПройден Тогда
		Отказ = Истина;
		Сообщение = Новый СообщениеПользователю;
		Сообщение.Текст = "Согласно правилам контроля документов, вам отказано в "
			+ ?(РежимЗаписи = РежимЗаписиДокумента.Запись, "записи",
				?(РежимЗаписи = РежимЗаписиДокумента.Проведение, "проведении", "отмене проведения")) 
			+ " документа! Обратитесь к системному администратору!";
		Сообщение.Сообщить();
	КонецЕсли; 
КонецПроцедуры


Данное решение в минимальное объеме использует функционал типовых решений 1С. Достаточно просто встраивается в типовые решения, для самописных придется немного поработать напильником. Для этого вам потребуется перенести в свою конфигурацию: регистр сведений "ПравилаКонтроляДокументов", общий модуль "МодульКонтроляДокументов" и подписку на событие "ПодпискаНаСобытиеЗаписиДокумента". Используются управляемые формы.

Решение прошло обкатку на УТ 11.

Скачать файлы

Наименование Файл Версия Размер
Конфигурация с объектами 3
.cf 23,31Kb
17.11.15
3
.cf 23,31Kb Скачать

См. также

Подписаться Добавить вознаграждение
В этой теме еще нет сообщений.