Графики работы / Расписание работы / Модуль формы

файл
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

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

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

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

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

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура РасписаниеРаботыПриОкончанииРедактирования(Элемент, НоваяСтрока, ОтменаРедактирования)
		
	Если ОтменаРедактирования Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ПереходящиеСмены Тогда
		ГрафикиРаботыКлиент.ВосстановитьПорядокСтрокКоллекцииПослеРедактирования(РасписаниеРаботы, "ВремяНачала", Элемент.ТекущиеДанные);
	КонецЕсли;
	
	ЗаполнитьОбщееВремя(ЭтотОбъект);
	
КонецПроцедуры

&НаКлиенте
Процедура РасписаниеРаботыПослеУдаления(Элемент)
	
	ЗаполнитьОбщееВремя(ЭтотОбъект);
	
КонецПроцедуры
#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ОК(Команда)
	
	ВыбратьИЗакрыть();
	
КонецПроцедуры

&НаКлиенте
Процедура Отмена(Команда)
	
	Модифицированность = Ложь;
	ОповеститьОВыборе(Неопределено);
	
КонецПроцедуры

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

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

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

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

&НаСервере
Процедура УточнитьФорматПолейВремени()
	
	ФорматВремени = ?(ГрафикиРаботы.ДвенадцатиЧасовойФорматВремени(),
		НСтр("ru = 'ДФ=''чч:мм вв''; ДП='"), НСтр("ru = 'ДФ=ЧЧ:мм; ДП='"));
	ФорматВремениРедактирования = ?(ГрафикиРаботы.ДвенадцатиЧасовойФорматВремени(),
		НСтр("ru = 'ДФ=''чч:мм вв'''"), НСтр("ru = 'ДФ=ЧЧ:мм'"));
	
	Элементы.РасписаниеРаботыВремяНачала.Формат = ФорматВремени;
	Элементы.РасписаниеРаботыВремяНачала.ФорматРедактирования = ФорматВремениРедактирования;
	
	Элементы.РасписаниеРаботыВремяОкончания.Формат = ФорматВремени;
	Элементы.РасписаниеРаботыВремяОкончания.ФорматРедактирования = ФорматВремениРедактирования;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ЗаполнитьОбщееВремя(Форма)
	
	Секунд = 0;
	
	Для каждого Строка Из Форма.РасписаниеРаботы Цикл
		Если Строка.ВремяНачала = Строка.ВремяОкончания Тогда
			СекундИнтервала = 86400;
		ИначеЕсли Строка.ВремяНачала < Строка.ВремяОкончания Тогда
			СекундИнтервала = Строка.ВремяОкончания - Строка.ВремяНачала;
		ИначеЕсли Не ЗначениеЗаполнено(Строка.ВремяОкончания) Тогда
			СекундИнтервала = КонецДня(Строка.ВремяОкончания) - Строка.ВремяНачала + 1;
		Иначе
			ОсновнаяЧасть = КонецДня(Строка.ВремяНачала) - Строка.ВремяНачала + 1;
			ПереходящаяЧасть = Строка.ВремяОкончания - НачалоДня(Строка.ВремяОкончания);
			СекундИнтервала = ОсновнаяЧасть + ПереходящаяЧасть;
		КонецЕсли;
		
		Секунд = Секунд + СекундИнтервала;
	КонецЦикла;
	
	Часов = Окр(Секунд / 3600, 1);
	
	Форма.Элементы.ОбщееВремя.Заголовок = СтрШаблон(НСтр("ru = 'Всего: %1 ч.'"), Часов);
	
КонецПроцедуры

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

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