Графики работы сотрудников / Модуль объекта

файл
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область ОписаниеПеременных

Перем ВыделятьНерабочиеДниОтдельнымВидомВремени;
Перем ВидыВремениВключаемыеВНорму;
Перем ОплачиваемыеНерабочиеПериоды;
Перем ПериодНерабочихДней;

#КонецОбласти

#Область ОбработчикиСобытий

Процедура ПередЗаписью(Отказ)
	
	Если ЗарплатаКадры.ОтключитьБизнесЛогикуПриЗаписи(ЭтотОбъект) Тогда
		Возврат;
	КонецЕсли;
	
	Если ЭтоГруппа Тогда 
		Возврат;
	КонецЕсли;			
	
	РабочихДнейВНеделе = 0;
	Если СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоНеделям Тогда
		Для Каждого СтрокаТаблицы Из ШаблонЗаполнения Цикл
			Если СтрокаТаблицы.ДеньВключенВГрафик Тогда
				РабочихДнейВНеделе = РабочихДнейВНеделе + 1;
			КонецЕсли;
		КонецЦикла;	
	КонецЕсли;	
	
	РежимРаботыПредыдущееЗначение = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Ссылка, "РежимРаботы");	
	ДополнительныеСвойства.Вставить("РежимРаботыПредыдущееЗначение", РежимРаботыПредыдущееЗначение);
КонецПроцедуры

Процедура ПриЗаписи(Отказ)
	Если ЗарплатаКадры.ОтключитьБизнесЛогикуПриЗаписи(ЭтотОбъект) Тогда
		Возврат;
	КонецЕсли;
	
	РежимРаботыПредыдущееЗначение = Неопределено;
	ДополнительныеСвойства.Свойство("РежимРаботыПредыдущееЗначение", РежимРаботыПредыдущееЗначение); 
	
	Если РежимРаботыПредыдущееЗначение <> РежимРаботы Тогда
		
		Если ЗначениеЗаполнено(РежимРаботы) Тогда
			УчетРабочегоВремениРасширенный.ОбновитьСреднемесячныеНормыПоРежимуРаботы(РежимРаботы);
		КонецЕсли;	
		
		Если ЗначениеЗаполнено(РежимРаботыПредыдущееЗначение) Тогда
			УчетРабочегоВремениРасширенный.ОбновитьСреднемесячныеНормыПоРежимуРаботы(РежимРаботыПредыдущееЗначение);
		КонецЕсли;			
	КонецЕсли;
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Процедура ЗаполнитьПараметрыГрафикаПоУмолчанию(РежимРаботыОснование = Неопределено) Экспорт
	Если ЗначениеЗаполнено(РежимРаботыОснование) Тогда
		ЗаполнитьПараметрыГрафикаПоРежимуРаботы(РежимРаботыОснование);
		Возврат;
	КонецЕсли;	
	
	ПроизводственныйКалендарь = КалендарныеГрафики.ОсновнойПроизводственныйКалендарь();
	
	ДлительностьРабочейНедели = 40;
	УчитыватьПраздники = Истина;
	СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоНеделям;
	
	ВидВремениЯвка = ОбщегоНазначения.ПредопределенныйЭлемент("Справочник.ВидыИспользованияРабочегоВремени.Явка");
	
	СтрокаВидВремени = ВидыВремени.Добавить();
	СтрокаВидВремени.ВидВремени = ВидВремениЯвка;
	
	Для НомерДня = 1 По 7 Цикл
		СтрокаШаблона = ШаблонЗаполнения.Добавить();
		СтрокаШаблона.ДеньВключенВГрафик = НомерДня < 6;
		
		СтрокаРасписания = ДанныеОРабочихЧасах.Добавить();
		СтрокаРасписания.ВидВремени = ВидВремениЯвка;
		СтрокаРасписания.НомерДняЦикла = НомерДня;
		СтрокаРасписания.Часов = ?(НомерДня < 6, 8, 0);
	КонецЦикла;
	
КонецПроцедуры

Процедура ЗаполнитьПараметрыГрафикаПоРежимуРаботы(РежимРаботыОснование)	
	РежимРаботы = РежимРаботыОснование;
	РежимРаботыОбъект = РежимРаботыОснование.ПолучитьОбъект();
		
	ЗаполнитьЗначенияСвойств(ЭтотОбъект, РежимРаботыОбъект, "ПроизводственныйКалендарь,СуммированныйУчетРабочегоВремени,ДлительностьРабочейНедели,УчитыватьПраздники,СпособЗаполнения,СпособОпределенияНормыСуммированногоУчета");
	
	Для Каждого СтрокаШаблонаРежимаРаботы Из РежимРаботыОбъект.ШаблонЗаполнения Цикл
		СтрокаШаблонаЗаполнения = ШаблонЗаполнения.Добавить();
		ЗаполнитьЗначенияСвойств(СтрокаШаблонаЗаполнения, СтрокаШаблонаРежимаРаботы); 
	КонецЦикла;		
КонецПроцедуры

Процедура ЗаписатьДанныеГрафика(ДанныеГрафика, НомерГода) Экспорт
	
	Записать();
	УчетРабочегоВремениРасширенный.ЗаписатьДанныеГрафика(Ссылка, ДанныеГрафика, НомерГода);
	
КонецПроцедуры	

#Область ЗаполнениеДанныхГрафика

Процедура ЗаполнитьДанныеГрафика(ДанныеГрафика, НомерТекущегоГода) Экспорт
	
	КоличествоДнейВЦикле = ШаблонЗаполнения.Количество();
	ПериодНерабочихДней = КалендарныеГрафики.ПериодыНерабочихДней(ПроизводственныйКалендарь, Новый СтандартныйПериод);
	ОплачиваемыеНерабочиеПериоды = УчетРабочегоВремениРасширенный.ОплачиваемыеНерабочиеПериоды(ПроизводственныйКалендарь);
	
	Если КоличествоДнейВЦикле = 0 Тогда
		Возврат;
	КонецЕсли;
	
	ПриоритетВидовВремениДляПредпраздничных = ПриоритетВидовВремениПредпраздничныхДней();
	ДлинаСуток = 86400;
	
	Если СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоЦикламПроизвольнойДлины
		Или СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоСменам Тогда
		ДатаНачалаИнтервалаЗаполнения = Макс(Дата(НомерТекущегоГода, 1, 1), ДатаОтсчета);
	Иначе
		ДатаНачалаИнтервалаЗаполнения = Дата(НомерТекущегоГода, 1, 1);
	КонецЕсли;
	ДатаОкончанияИнтервалаЗаполнения = КонецГода(ДатаНачалаИнтервалаЗаполнения);
	
	Если СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоНеделям Тогда
		НомерДняЦикла = ДеньНедели(ДатаНачалаИнтервалаЗаполнения);
	Иначе
		НомерДняЦикла = ((ДатаНачалаИнтервалаЗаполнения - ДатаОтсчета)/ДлинаСуток) % КоличествоДнейВЦикле + 1;
	КонецЕсли;
	
	ЧасыПоДнямЦикла = ЧасыПоДнямЦикла(ШаблонЗаполнения, ДанныеОРабочихЧасах, СпособЗаполнения);
	
	ДанныеПроизводственногоКалендаря = Справочники.ПроизводственныеКалендари.ДанныеПроизводственногоКалендаря(ПроизводственныйКалендарь, НомерТекущегоГода);
	
	ОбрабатываемаяДата = ДатаНачалаИнтервалаЗаполнения;
	ПустаяДата = '00010101';
	
	ОтражатьЧасыВДеньНачалаСмены = УчетРабочегоВремениРасширенный.НастройкиУчетаВремени().ОтражатьЧасыВДеньНачалаСмены;
	
	ПеренесенныеДни = Новый Массив;
	Пока ОбрабатываемаяДата <= ДатаОкончанияИнтервалаЗаполнения Цикл
		ДанныеПроизводственногоКалендаряЗаДень = ДанныеПроизводственногоКалендаря.Найти(ОбрабатываемаяДата, "Дата");
		
		Если ДанныеПроизводственногоКалендаряЗаДень = Неопределено Тогда
			ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Рабочий;
			ДатаПереноса = ПустаяДата;
		Иначе
			ВидДня = ДанныеПроизводственногоКалендаряЗаДень.ВидДня;
			ДатаПереноса = ДанныеПроизводственногоКалендаряЗаДень.ДатаПереноса;
		КонецЕсли;
		
		НомерДняМесяца = День(ОбрабатываемаяДата);
		
		Если СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоНеделям Тогда
			Если ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Суббота Тогда
				ЧасовЗаДень = ЧасыПоДнямЦикла[6];
				ПроверитьПереносДней(ОбрабатываемаяДата, ПеренесенныеДни, ДатаПереноса, ЧасовЗаДень, ЧасыПоДнямЦикла[НомерДняЦикла]);
			ИначеЕсли ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Воскресенье Тогда
				ЧасовЗаДень = ЧасыПоДнямЦикла[7];
				ПроверитьПереносДней(ОбрабатываемаяДата, ПеренесенныеДни, ДатаПереноса, ЧасовЗаДень, ЧасыПоДнямЦикла[НомерДняЦикла]);
			ИначеЕсли ДатаПереноса <> ПустаяДата Тогда
				ЧасовЗаДень = ЧасыПоДнямЦикла[ДеньНедели(ДатаПереноса)];
			Иначе
				ЧасовЗаДень = ЧасыПоДнямЦикла[НомерДняЦикла];
			КонецЕсли;
		Иначе
			ЧасовЗаДень = ЧасыПоДнямЦикла[НомерДняЦикла];
		КонецЕсли;
		
		Если ЗаполнятьВремяЗаДень(ОбрабатываемаяДата, ВидДня, ПеренесенныеДни) Тогда
			ЗаполнитьВремяЗаДень(ОбрабатываемаяДата, ВидДня, ЧасовЗаДень, ДанныеГрафика, ПриоритетВидовВремениДляПредпраздничных, ОтражатьЧасыВДеньНачалаСмены);
		КонецЕсли;
		
		ОбрабатываемаяДата = ОбрабатываемаяДата + ДлинаСуток;
		
		НомерДняЦикла = НомерДняЦикла + 1;
		Если НомерДняЦикла > КоличествоДнейВЦикле Тогда
			НомерДняЦикла = 1;
		КонецЕсли;
	КонецЦикла;
	
	Для Каждого СтрокаГрафика Из ДанныеГрафика Цикл
		УчетРабочегоВремениРасширенныйКлиентСервер.ДанныеГрафикаРассчитатьИтогоПоСтроке(СтрокаГрафика);
	КонецЦикла;
	
КонецПроцедуры

Процедура ПроверитьПереносДней(ОбрабатываемаяДата, ПеренесенныеДни, ДатаПереноса, ЧасовЗаДень, ЧасовЗаОбрабатываемыйДень)
	Если ДатаПереноса = '00010101' Тогда
		Возврат;
	КонецЕсли;
	
	Часы = 0;
	Для Каждого Данные Из ЧасовЗаДень Цикл
		Часы = Часы + Данные.Часов;
	КонецЦикла;
	Если Часы = 0 Тогда
		// День недели выходной
		ПеренесенныеДни.Добавить(ОбрабатываемаяДата);
	Иначе
		// День недели рабочий
		ЧасовЗаДень = ЧасовЗаОбрабатываемыйДень;
	КонецЕсли;
КонецПроцедуры

Функция ЗаполнятьВремяЗаДень(ОбрабатываемаяДата, ВидДня, ПеренесенныеДни)
	
	Если УчитыватьПраздники 
		И (ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Праздник
			Или ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Нерабочий)Тогда
		
		Возврат Ложь;
	КонецЕсли;
	
	Если УчитыватьНерабочиеДни И НерабочийДень(ОбрабатываемаяДата)Тогда
		Возврат ВыделятьНерабочиеДниОтдельнымВидомВремени;
	КонецЕсли;
	
	Если ПеренесенныеДни.Найти(ОбрабатываемаяДата) <> Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Функция ПриоритетВидовВремениПредпраздничныхДней()
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Ночные", ОбщегоНазначения.ПредопределенныйЭлемент("Справочник.ВидыИспользованияРабочегоВремени.РаботаНочныеЧасы"));
	Запрос.УстановитьПараметр("Вечерние", ОбщегоНазначения.ПредопределенныйЭлемент("Справочник.ВидыИспользованияРабочегоВремени.РаботаВечерниеЧасы"));
	Запрос.УстановитьПараметр("Явка", ОбщегоНазначения.ПредопределенныйЭлемент("Справочник.ВидыИспользованияРабочегоВремени.Явка"));
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	ВидыИспользованияРабочегоВремени.Ссылка,
	|	ВЫБОР
	|		КОГДА ВидыИспользованияРабочегоВремени.ОсновноеВремя = &Ночные
	|				И ВидыИспользованияРабочегоВремени.Ссылка <> &Ночные
	|			ТОГДА 1
	|		КОГДА ВидыИспользованияРабочегоВремени.ОсновноеВремя = &Ночные
	|			ТОГДА 2
	|		КОГДА ВидыИспользованияРабочегоВремени.ОсновноеВремя = &Вечерние
	|				И ВидыИспользованияРабочегоВремени.Ссылка <> &Вечерние
	|			ТОГДА 3
	|		КОГДА ВидыИспользованияРабочегоВремени.ОсновноеВремя = &Вечерние
	|			ТОГДА 4
	|		КОГДА ВидыИспользованияРабочегоВремени.ОсновноеВремя = &Явка
	|				И ВидыИспользованияРабочегоВремени.Ссылка <> &Явка
	|			ТОГДА 5
	|		КОГДА ВидыИспользованияРабочегоВремени.ОсновноеВремя = &Явка
	|			ТОГДА 6
	|		ИНАЧЕ 7
	|	КОНЕЦ КАК Приоритет
	|ИЗ
	|	Справочник.ВидыИспользованияРабочегоВремени КАК ВидыИспользованияРабочегоВремени
	|
	|УПОРЯДОЧИТЬ ПО
	|	Приоритет";
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	ПриоритетВидовВремениДляПредпраздничных = Новый Массив;
	
	Пока Выборка.Следующий() Цикл
		ПриоритетВидовВремениДляПредпраздничных.Добавить(Выборка.Ссылка);		
	КонецЦикла;	
	
	Возврат ПриоритетВидовВремениДляПредпраздничных;
КонецФункции	
	
Функция НовыйДанныеГрафика() Экспорт
	
	ДанныеГрафика = Новый ТаблицаЗначений;
	ДанныеГрафика.Колонки.Добавить("ВидВремени", Новый ОписаниеТипов("СправочникСсылка.ВидыИспользованияРабочегоВремени"));	
	ДанныеГрафика.Колонки.Добавить("НомерМесяца", Новый ОписаниеТипов("Число"));
	ДанныеГрафика.Колонки.Добавить("ИтогДни", Новый ОписаниеТипов("Число"));
	ДанныеГрафика.Колонки.Добавить("ИтогЧасы", Новый ОписаниеТипов("Число"));
	ДанныеГрафика.Колонки.Добавить("ПереходящаяЧастьСмены", Новый ОписаниеТипов("Булево"));	
	
	Для НомерДня = 1 По 31 Цикл
		ДанныеГрафика.Колонки.Добавить("День" + Формат(НомерДня, "ЧГ="), Новый ОписаниеТипов("Число"));
		ДанныеГрафика.Колонки.Добавить("Смена" + Формат(НомерДня, "ЧГ="), Новый ОписаниеТипов("СправочникСсылка.СменыРаботыСотрудников"));  
		ДанныеГрафика.Колонки.Добавить("ОтражатьЧасыВДеньНачалаСмены" + Формат(НомерДня, "ЧГ="), Новый ОписаниеТипов("Булево"));
	КонецЦикла;	
	
	Если СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоСменам Тогда
		ИспользуемыеВидыВремени = ДанныеОРабочихЧасахПоСменам(ШаблонЗаполнения);
		ИспользуемыеВидыВремени.Свернуть("ВидВремени");
	Иначе
		ИспользуемыеВидыВремени = ВидыВремени.Выгрузить();
	КонецЕсли;
	
	Если ВыделятьНерабочиеДниОтдельнымВидомВремени Тогда
		ИспользуемыеВидыВремени.Добавить().ВидВремени = 
			ОбщегоНазначения.ПредопределенныйЭлемент("Справочник.ВидыИспользованияРабочегоВремени.ОплачиваемыеНерабочиеДни");
	КонецЕсли;
	
	Для НомерМесяца = 1 По 12 Цикл
		
		Для Каждого СтрокаВидВремени Из ИспользуемыеВидыВремени Цикл
			ДанныеГрафикаЗаМесяц = ДанныеГрафика.Добавить();
			ДанныеГрафикаЗаМесяц.НомерМесяца = НомерМесяца;
			ДанныеГрафикаЗаМесяц.ВидВремени = СтрокаВидВремени.ВидВремени;
			
			Если СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоСменам Тогда
				ДанныеГрафикаЗаМесяц = ДанныеГрафика.Добавить();
				ДанныеГрафикаЗаМесяц.НомерМесяца = НомерМесяца;
				ДанныеГрафикаЗаМесяц.ВидВремени = СтрокаВидВремени.ВидВремени;
				ДанныеГрафикаЗаМесяц.ПереходящаяЧастьСмены = Истина;
			КонецЕсли;				
		КонецЦикла;	
	КонецЦикла;
	
	Возврат ДанныеГрафика;
	
КонецФункции
	
Процедура ЗаполнитьВремяЗаДень(ОбрабатываемаяДата, ВидДня, ЧасовЗаДень, ДанныеГрафика, ПриоритетВидовВремениДляПредпраздничных, ОтражатьЧасыВДеньНачалаСмены)
	
	СтрокиГрафикаЗаМесяц = Новый Соответствие;
	НомерДняМесяца = День(ОбрабатываемаяДата);
	
	СтруктураПоиска = Новый Структура("НомерМесяца, ВидВремени, ПереходящаяЧастьСмены");
	СтруктураПоиска.НомерМесяца = Месяц(ОбрабатываемаяДата);
	
	СтрокиГрафикаДляВычитанияПредпраздничныхЧасов = Новый Соответствие;
	
	Для Каждого ЧасыПоВидуВремени Из ЧасовЗаДень Цикл
		СтруктураПоиска.ВидВремени = ВидВремениПоВидуДня(ОбрабатываемаяДата, ЧасыПоВидуВремени.ВидВремени);
		СтруктураПоиска.ПереходящаяЧастьСмены = ЧасыПоВидуВремени.ПереходящаяЧастьСмены;
		НайденныеСтроки = ДанныеГрафика.НайтиСтроки(СтруктураПоиска);
		Если НайденныеСтроки.Количество() = 0 Тогда
			СтрокаТаблицыГрафика = ДанныеГрафика.Добавить();
			ЗаполнитьЗначенияСвойств(СтрокаТаблицыГрафика, СтруктураПоиска);
		Иначе
			СтрокаТаблицыГрафика = НайденныеСтроки[0];
		КонецЕсли;	
		
		СтрокиГрафикаЗаМесяц.Вставить(СтрокаТаблицыГрафика);
		
		СтрокаТаблицыГрафика["День" + НомерДняМесяца] = СтрокаТаблицыГрафика["День" + НомерДняМесяца] + ЧасыПоВидуВремени.Часов;
		СтрокаТаблицыГрафика["Смена" + НомерДняМесяца] = ЧасыПоВидуВремени.Смена;
		СтрокаТаблицыГрафика["ОтражатьЧасыВДеньНачалаСмены" + НомерДняМесяца] = ОтражатьЧасыВДеньНачалаСмены;
	КонецЦикла;	
	
	Если УчитыватьПраздники 
		И ПредпраздничныйДень(ОбрабатываемаяДата, ВидДня) Тогда
		
		УменьшитьКоличествоЧасовВПредпраздничныйДень(День(ОбрабатываемаяДата), СтрокиГрафикаЗаМесяц, ПриоритетВидовВремениДляПредпраздничных);
	КонецЕсли;
	
КонецПроцедуры

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

Функция НерабочийДень(ОбрабатываемаяДата)
	
	Для Каждого НерабочийПериод Из ПериодНерабочихДней Цикл
		Если ОбрабатываемаяДата >= НерабочийПериод.Период.ДатаНачала
			И ОбрабатываемаяДата <= НерабочийПериод.Период.ДатаОкончания Тогда
			
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

Функция ОплачиваемыйНерабочийДень(ОбрабатываемаяДата)
	
	Для Каждого ОплачиваемыйПериод Из ОплачиваемыеНерабочиеПериоды Цикл
		Если ОбрабатываемаяДата >= ОплачиваемыйПериод.Период.ДатаНачала
			И ОбрабатываемаяДата <= ОплачиваемыйПериод.Период.ДатаОкончания Тогда
			
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

Функция ПредпраздничныйДень(ОбрабатываемаяДата, ВидДня)
	
	Возврат ВидДня = Перечисления.ВидыДнейПроизводственногоКалендаря.Предпраздничный;
	
КонецФункции

Процедура УменьшитьКоличествоЧасовВПредпраздничныйДень(НомерДняМесяца, СтрокиГрафикаЗаМесяц, ПриоритетВидовВремениДляПредпраздничных)
	СтрокиПоВидамВремени = Новый Соответствие;
	
	Для Каждого СтрокаЗаМесяц Из СтрокиГрафикаЗаМесяц Цикл
		Если Не СтрокаЗаМесяц.Ключ.ПереходящаяЧастьСмены
			И СтрокаЗаМесяц.Ключ["День" + НомерДняМесяца] > 0 Тогда
			
			СтрокиПоВидамВремени.Вставить(СтрокаЗаМесяц.Ключ.ВидВремени, СтрокаЗаМесяц.Ключ);
		КонецЕсли;
	КонецЦикла;	
				
	ОсталосьВычестьЧасов = 1;
	Для Каждого ВидВремени Из ПриоритетВидовВремениДляПредпраздничных Цикл
		СтрокаТаблицыГрафика = СтрокиПоВидамВремени[ВидВремени];
		
		Если СтрокаТаблицыГрафика <> Неопределено Тогда
			ЧасовПоВидуВремени = СтрокаТаблицыГрафика["День" + НомерДняМесяца];
		Иначе
			Продолжить;                            
		КонецЕсли;	
		
		КоличествоВычитаемыхЧасов = Мин(СтрокаТаблицыГрафика["День" + НомерДняМесяца], 1);
		СтрокаТаблицыГрафика["День" + НомерДняМесяца] = СтрокаТаблицыГрафика["День" + НомерДняМесяца] - КоличествоВычитаемыхЧасов;
		ОсталосьВычестьЧасов = ОсталосьВычестьЧасов - КоличествоВычитаемыхЧасов;
		Если ОсталосьВычестьЧасов <= 0 Тогда
			Прервать;;
		КонецЕсли;	
	КонецЦикла;	
КонецПроцедуры	

Функция ЧасыПоДнямЦикла(ШаблонЗаполнения, ДанныеОРабочихЧасах, СпособЗаполнения) 
	Если СпособЗаполнения = Перечисления.СпособыЗаполненияГрафиковРаботыСотрудников.ПоСменам Тогда
		Возврат ЧасыПоДнямЦиклаПоСменам(ШаблонЗаполнения);	
	Иначе
		Возврат ЧасыПоДнямЦиклаПоДаннымОРабочихЧасах(ШаблонЗаполнения, ДанныеОРабочихЧасах);
	КонецЕсли;
КонецФункции

Функция ЧасыПоДнямЦиклаПоДаннымОРабочихЧасах(ШаблонЗаполнения, ДанныеОРабочихЧасах)	
	ЧасыПоДнямЦикла = Новый Соответствие;
	
	Для Каждого ДеньЦикла Из ШаблонЗаполнения Цикл
		ЧасыЗаДень = Новый Массив;
		
		ДанныеОВремениЗаДень = ДанныеОРабочихЧасах.НайтиСтроки(Новый Структура("НомерДняЦикла", ДеньЦикла.НомерСтроки));
		Для Каждого ДанныеВидуВремени Из ДанныеОВремениЗаДень Цикл
			СтруктураДанныхПоВидуВремени = СтруктураДанныхПоВидуВремени();
			СтруктураДанныхПоВидуВремени.ВидВремени = ДанныеВидуВремени.ВидВремени;
			СтруктураДанныхПоВидуВремени.Часов = ДанныеВидуВремени.Часов;
			ЧасыЗаДень.Добавить(СтруктураДанныхПоВидуВремени);
		КонецЦикла;
		
		ЧасыПоДнямЦикла.Вставить(ДеньЦикла.НомерСтроки, ЧасыЗаДень);
	КонецЦикла;
	
	Возврат ЧасыПоДнямЦикла;	
КонецФункции

Функция ЧасыПоДнямЦиклаПоСменам(ШаблонЗаполнения)	
	ЧасыПоДнямЦикла = Новый Соответствие;
	ДанныеОРабочихЧасахПоСменам = ДанныеОРабочихЧасахПоСменам(ШаблонЗаполнения);
	
	Для Каждого ДеньЦикла Из ШаблонЗаполнения Цикл
		ЧасыЗаДень = Новый Массив;
		ЧасыПоДнямЦикла.Вставить(ДеньЦикла.НомерСтроки, ЧасыЗаДень);
		
		Если Не ЗначениеЗаполнено(ДеньЦикла.Смена) Тогда
			Продолжить;
		КонецЕсли;	
		
		ДанныеОВремениЗаДень = ДанныеОРабочихЧасахПоСменам.НайтиСтроки(Новый Структура("Смена", ДеньЦикла.Смена));
		Для Каждого ДанныеВидуВремени Из ДанныеОВремениЗаДень Цикл
			СтруктураДанныхПоВидуВремени = СтруктураДанныхПоВидуВремени();
			СтруктураДанныхПоВидуВремени.ВидВремени = ДанныеВидуВремени.ВидВремени;
			СтруктураДанныхПоВидуВремени.Часов = ДанныеВидуВремени.Часов;
			СтруктураДанныхПоВидуВремени.Смена = ДанныеВидуВремени.Смена;
			СтруктураДанныхПоВидуВремени.ПереходящаяЧастьСмены = ДанныеВидуВремени.ПереходящаяЧастьСмены;
			ЧасыЗаДень.Добавить(СтруктураДанныхПоВидуВремени);
		КонецЦикла;
	КонецЦикла;
	
	Возврат ЧасыПоДнямЦикла;	
КонецФункции

Функция СтруктураДанныхПоВидуВремени()
	ДанныеПоВидуВремени = Новый Структура;
	ДанныеПоВидуВремени.Вставить("ВидВремени");
	ДанныеПоВидуВремени.Вставить("Смена");
	ДанныеПоВидуВремени.Вставить("Часов");
	ДанныеПоВидуВремени.Вставить("ПереходящаяЧастьСмены", Ложь);
	
	Возврат ДанныеПоВидуВремени;		
КонецФункции	

Функция ДанныеОРабочихЧасахПоСменам(ШаблонЗаполнения)
	СписокСмен = Новый Массив;
	
	Для Каждого СтрокаШаблонаЗаполнения Из ШаблонЗаполнения Цикл
		Если ЗначениеЗаполнено(СтрокаШаблонаЗаполнения.Смена) Тогда
			СписокСмен.Добавить(СтрокаШаблонаЗаполнения.Смена);
		КонецЕсли;
	КонецЦикла;
	
	СписокСмен = ОбщегоНазначенияКлиентСервер.СвернутьМассив(СписокСмен);
	ДанныеОЧасахПоСменам = Справочники.СменыРаботыСотрудников.ИнформацияОРабочемВремениСмен(СписокСмен);
	
	ДанныеОЧасахПоСменам.Свернуть("Смена, ВидВремени, ПереходящаяЧастьСмены", "Часов");
	
	Возврат ДанныеОЧасахПоСменам;
КонецФункции	

Функция ДанныеГрафикаПоНастройкам(НомерГода) Экспорт
	
	ДанныеГрафика = НовыйДанныеГрафика();
	ЗаполнитьДанныеГрафика(ДанныеГрафика, НомерГода);
	
	Возврат ДанныеГрафика;
	
КонецФункции	

#КонецОбласти

#КонецОбласти

#Область Инициализация

ВыделятьНерабочиеДниОтдельнымВидомВремени = УчетРабочегоВремениРасширенный.ВыделятьНерабочиеДниОтдельнымВидомВремени();
ВидыВремениВключаемыеВНорму = УчетРабочегоВремениРасширенный.ВидыВремениВключаемыеВНорму();

#КонецОбласти
	
#Иначе
ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'");
#КонецЕсли

Связанные материалы