Загрузка данных
#Область ПрограммныйИнтерфейс
// Создает обязательные настройки доработки и обрабатывает наряды,
// находящиеся в состоянии "Запрос информации".
//
// Параметры:
// Нет.
//
// Возвращаемое значение:
// Нет.
Процедура ОбработатьНаряды() Экспорт
СостояниеЗапросИнформации = ПодготовитьНастройки();
Если Не ЗначениеЗаполнено(СостояниеЗапросИнформации) Тогда
Возврат;
КонецЕсли;
ВремяОжиданияЧасов = Константы.КРДВ_ВремяОжиданияОбратнойСвязи.Получить();
Если ВремяОжиданияЧасов <= 0 Тогда
Возврат;
КонецЕсли;
ВыборкаНарядов = ПолучитьНарядыКОбработке(СостояниеЗапросИнформации);
Пока ВыборкаНарядов.Следующий() Цикл
ОбработатьНаряд(ВыборкаНарядов, СостояниеЗапросИнформации, ВремяОжиданияЧасов);
КонецЦикла;
КонецПроцедуры
// Создает обязательные настройки доработки.
//
// Возвращаемое значение:
// СправочникСсылка.СостоянияНарядов - состояние наряда "Запрос информации".
Функция ПодготовитьНастройки() Экспорт
Возврат ОбеспечитьНастройки();
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ОбеспечитьНастройки()
ШаблонУведомления = ОбеспечитьШаблонУведомления();
СостояниеОжидание = Справочники.СостоянияИнцидентов.НайтиПоНаименованию("Ожидание", Истина);
Если Не ЗначениеЗаполнено(СостояниеОжидание) Тогда
ЗаписатьОшибку("Не найдено состояние обращения ""Ожидание""");
Возврат Справочники.СостоянияНарядов.ПустаяСсылка();
КонецЕсли;
СостояниеНаряда = Справочники.СостоянияНарядов.НайтиПоНаименованию("Запрос информации", Истина);
Если Не ЗначениеЗаполнено(СостояниеНаряда) Тогда
ОбъектСостояния = Справочники.СостоянияНарядов.СоздатьЭлемент();
ОбъектСостояния.Наименование = "Запрос информации";
НужноЗаписатьСостояние = Истина;
Иначе
ОбъектСостояния = СостояниеНаряда.ПолучитьОбъект();
НужноЗаписатьСостояние = Ложь;
КонецЕсли;
Если ОбъектСостояния.СостоянияИнцидента <> СостояниеОжидание Тогда
ОбъектСостояния.СостоянияИнцидента = СостояниеОжидание;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если ОбъектСостояния.Закрыт Тогда
ОбъектСостояния.Закрыт = Ложь;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если ОбъектСостояния.Выполнение Тогда
ОбъектСостояния.Выполнение = Ложь;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если ОбъектСостояния.ТребоватьЗаполнениеКодаЗакрытия Тогда
ОбъектСостояния.ТребоватьЗаполнениеКодаЗакрытия = Ложь;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если Не ОбъектСостояния.ОтправлятьУведомлениеПользователю Тогда
ОбъектСостояния.ОтправлятьУведомлениеПользователю = Истина;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если Не ОбъектСостояния.ОтправлятьУведомленияОтв Тогда
ОбъектСостояния.ОтправлятьУведомленияОтв = Истина;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если ЗначениеЗаполнено(ШаблонУведомления)
И Не ЗначениеЗаполнено(ОбъектСостояния.Шаблон) Тогда
ОбъектСостояния.Шаблон = ШаблонУведомления;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если ЗначениеЗаполнено(ШаблонУведомления)
И Не ЗначениеЗаполнено(ОбъектСостояния.ШаблонОтветственного) Тогда
ОбъектСостояния.ШаблонОтветственного = ШаблонУведомления;
НужноЗаписатьСостояние = Истина;
КонецЕсли;
Если НужноЗаписатьСостояние Тогда
ОбъектСостояния.Записать();
КонецЕсли;
СостояниеНаряда = ОбъектСостояния.Ссылка;
Если Константы.ИТ_СостояниеНарядаПриостановлен.Получить() <> СостояниеНаряда Тогда
Константы.ИТ_СостояниеНарядаПриостановлен.Установить(СостояниеНаряда);
КонецЕсли;
ОбеспечитьКодЗакрытия();
ОбеспечитьКатегориюЗакрытия();
Возврат СостояниеНаряда;
КонецФункции
Функция ОбеспечитьШаблонУведомления()
Шаблон = Справочники.ШаблоныСообщений.НайтиПоНаименованию("Запрос информации по наряду", Истина);
Если ЗначениеЗаполнено(Шаблон) Тогда
Возврат Шаблон;
КонецЕсли;
ОбъектШаблона = Справочники.ШаблоныСообщений.СоздатьЭлемент();
ОбъектШаблона.Наименование = "Запрос информации по наряду";
ОбъектШаблона.ЗаголовокПисьма = "Требуется дополнительная информация по наряду";
ОбъектШаблона.ТекстПисьма = "Наряд переведен в состояние ""Запрос информации"". Предоставьте необходимую информацию ответным письмом.";
ОбъектШаблона.ТекстНапоминания = ОбъектШаблона.ТекстПисьма;
ОбъектШаблона.ОтправлятьПочту = Истина;
ОбъектШаблона.ОтправлятьНапоминания = Истина;
ОбъектШаблона.Записать();
Возврат ОбъектШаблона.Ссылка;
КонецФункции
Функция ОбеспечитьКодЗакрытия()
КодЗакрытия = Справочники.ИТ_КодыЗакрытияНарядов.НайтиПоНаименованию("Отклонено", Истина);
Если ЗначениеЗаполнено(КодЗакрытия) Тогда
Возврат КодЗакрытия;
КонецЕсли;
ОбъектКода = Справочники.ИТ_КодыЗакрытияНарядов.СоздатьЭлемент();
ОбъектКода.Наименование = "Отклонено";
ОбъектКода.Описание = "Наряд отклонен";
ОбъектКода.Записать();
Возврат ОбъектКода.Ссылка;
КонецФункции
Функция ОбеспечитьКатегориюЗакрытия()
НаименованиеКатегории = "Не предоставлена необходимая информация инициатором";
Категория = Справочники.ИТ_Категории.НайтиПоНаименованию(НаименованиеКатегории, Истина);
Если ЗначениеЗаполнено(Категория) Тогда
Возврат Категория;
КонецЕсли;
ОбъектКатегории = Справочники.ИТ_Категории.СоздатьЭлемент();
ОбъектКатегории.Наименование = НаименованиеКатегории;
ОбъектКатегории.Процесс = Перечисления.Процессы.УправлениеНарядами;
ОбъектКатегории.Описание = "Автоматическое закрытие при отсутствии обратной связи от инициатора";
ОбъектКатегории.Записать();
Возврат ОбъектКатегории.Ссылка;
КонецФункции
Функция ПолучитьНарядыКОбработке(СостояниеЗапросИнформации)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Наряд.Ссылка КАК Наряд,
| МАКСИМУМ(Состояния.Период) КАК ПериодСостояния
|ИЗ
| Документ.Наряд КАК Наряд
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.Состояния КАК Состояния
| ПО Наряд.Ссылка = Состояния.ИспользуемыйДокумент
|ГДЕ
| НЕ Наряд.ПометкаУдаления
| И Наряд.Состояние = &Состояние
| И Состояния.Состояние = &Состояние
|
|СГРУППИРОВАТЬ ПО
| Наряд.Ссылка";
Запрос.УстановитьПараметр("Состояние", СостояниеЗапросИнформации);
Возврат Запрос.Выполнить().Выбрать();
КонецФункции
Процедура ОбработатьНаряд(ДанныеНаряда, СостояниеЗапросИнформации, ВремяОжиданияЧасов)
ТекущаяДата = ЧасовыеПоясаСервер.ТекущееВремяИБ();
ОбъектНаряда = ДанныеНаряда.Наряд.ПолучитьОбъект();
Если ОбъектНаряда.ПометкаУдаления
Или ОбъектНаряда.Состояние <> СостояниеЗапросИнформации
Или Не СостояниеНарядаВРегистреАктуально(ДанныеНаряда.Наряд, СостояниеЗапросИнформации,
ДанныеНаряда.ПериодСостояния) Тогда
Возврат;
КонецЕсли;
Обращение = ПолучитьСвязанноеОбращение(ОбъектНаряда);
Если Обращение = Неопределено Тогда
Возврат;
КонецЕсли;
Если Не ЗначениеЗаполнено(Обращение) Тогда
ЗаписатьПредупреждение(
"Наряд пропущен: не найдено связанное обращение для проверки входящих писем",
ДанныеНаряда.Наряд);
Возврат;
КонецЕсли;
КрайнийСрокОжидания = ДанныеНаряда.ПериодСостояния + ВремяОжиданияЧасов * 3600;
КонецПериодаПроверки = Мин(ТекущаяДата, КрайнийСрокОжидания);
Если ЕстьВходящееПисьмо(Обращение, ДанныеНаряда.ПериодСостояния, КонецПериодаПроверки) Тогда
ВернутьНарядВРаботу(ОбъектНаряда, ДанныеНаряда.ПериодСостояния, ТекущаяДата);
Возврат;
КонецЕсли;
Если ТекущаяДата >= КрайнийСрокОжидания Тогда
ЗакрытьНаряд(ОбъектНаряда);
КонецЕсли;
КонецПроцедуры
Функция СостояниеНарядаВРегистреАктуально(Наряд, ОжидаемоеСостояние, ОжидаемыйПериод)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Состояния.Состояние КАК Состояние,
| Состояния.Период КАК ПериодСостояния
|ИЗ
| РегистрСведений.Состояния КАК Состояния
|ГДЕ
| Состояния.ИспользуемыйДокумент = &Наряд
|
|УПОРЯДОЧИТЬ ПО
| Состояния.Период УБЫВ";
Запрос.УстановитьПараметр("Наряд", Наряд);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Возврат Выборка.Следующий()
И Выборка.Состояние = ОжидаемоеСостояние
И Выборка.ПериодСостояния = ОжидаемыйПериод;
КонецФункции
Функция ПолучитьСвязанноеОбращение(ОбъектНаряда)
Если ТипЗнч(ОбъектНаряда.ГлавныйДокумент) = Тип("ДокументСсылка.Инцидент") Тогда
Возврат ОбъектНаряда.ГлавныйДокумент;
КонецЕсли;
Если ТипЗнч(ОбъектНаряда.ДокОснование) = Тип("ДокументСсылка.Инцидент") Тогда
Возврат ОбъектНаряда.ДокОснование;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВЫРАЗИТЬ(СвязанныеДокументы.Документ2 КАК Документ.Инцидент) КАК Обращение
|ИЗ
| РегистрСведений.СвязанныеДокументы КАК СвязанныеДокументы
|ГДЕ
| СвязанныеДокументы.Документ1 = &Наряд
| И СвязанныеДокументы.Документ2 ССЫЛКА Документ.Инцидент
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| ВЫРАЗИТЬ(СвязанныеДокументы.Документ1 КАК Документ.Инцидент)
|ИЗ
| РегистрСведений.СвязанныеДокументы КАК СвязанныеДокументы
|ГДЕ
| СвязанныеДокументы.Документ2 = &Наряд
| И СвязанныеДокументы.Документ1 ССЫЛКА Документ.Инцидент";
Запрос.УстановитьПараметр("Наряд", ОбъектНаряда.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Не Выборка.Следующий() Тогда
Возврат Документы.Инцидент.ПустаяСсылка();
КонецЕсли;
Обращение = Выборка.Обращение;
Если Выборка.Следующий() Тогда
ЗаписатьПредупреждение(
"Наряд пропущен: найдено несколько связанных обращений; автоматическое изменение не выполнено",
ОбъектНаряда.Ссылка);
Возврат Неопределено;
КонецЕсли;
Возврат Обращение;
КонецФункции
Функция ЕстьВходящееПисьмо(Обращение, НачалоПериода, КонецПериода)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ДействияПисем.ВходящееПисьмо КАК ВходящееПисьмо
|ИЗ
| РегистрСведений.ДействияВходящихПисемПоОбращениям КАК ДействияПисем
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ЭлектронноеПисьмоВходящее КАК Письмо
| ПО ДействияПисем.ВходящееПисьмо = Письмо.Ссылка
|ГДЕ
| ДействияПисем.ИспользуемыйДокумент = &Обращение
| И НЕ Письмо.ПометкаУдаления
| И Письмо.ДатаПолучения >= &НачалоПериода
| И Письмо.ДатаПолучения <= &КонецПериода";
Запрос.УстановитьПараметр("Обращение", Обращение);
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
РезультатЗапроса = Запрос.Выполнить();
Возврат Не РезультатЗапроса.Пустой();
КонецФункции
Процедура ВернутьНарядВРаботу(ОбъектНаряда, ПериодСостояния, ТекущаяДата)
СостояниеНазначен = Справочники.СостоянияНарядов.НайтиПоНаименованию("Назначен", Истина);
Если Не ЗначениеЗаполнено(СостояниеНазначен) Тогда
ЗаписатьОшибку("Не найдено состояние наряда ""Назначен""", Неопределено, ОбъектНаряда.Ссылка);
Возврат;
КонецЕсли;
ОбъектНаряда.Состояние = СостояниеНазначен;
ОбъектНаряда.ПриИзмененииСостояния(ОбъектНаряда.Работы);
Если ОбъектНаряда.ДатаОкончанияПлан > ПериодСостояния Тогда
ВремяОжидания = ТекущаяДата - ПериодСостояния;
ОстатокSLA = ОбъектНаряда.ДатаОкончанияПлан - ПериодСостояния;
ДобавляемоеВремя = Мин(ВремяОжидания, Макс(ОстатокSLA, 0));
ОбъектНаряда.ДатаОкончанияПлан = ОбъектНаряда.ДатаОкончанияПлан + ДобавляемоеВремя;
КонецЕсли;
ОбъектНаряда.Записать();
КонецПроцедуры
Процедура ЗакрытьНаряд(ОбъектНаряда)
СостояниеЗакрыт = Справочники.СостоянияНарядов.НайтиПоНаименованию("Закрыт", Истина);
КодЗакрытия = ОбеспечитьКодЗакрытия();
Категория = ОбеспечитьКатегориюЗакрытия();
Если Не ЗначениеЗаполнено(СостояниеЗакрыт)
Или Не ЗначениеЗаполнено(КодЗакрытия)
Или Не ЗначениеЗаполнено(Категория) Тогда
ЗаписатьОшибку("Не найдены обязательные значения для автоматического закрытия", Неопределено, ОбъектНаряда.Ссылка);
Возврат;
КонецЕсли;
ОбъектНаряда.Состояние = СостояниеЗакрыт;
ОбъектНаряда.КодЗакрытия = КодЗакрытия;
ОбъектНаряда.Категория = Категория;
ОбъектНаряда.Решение = "Превышен срок ожидания обратной связи от инициатора";
ОбъектНаряда.ПриИзмененииСостояния(ОбъектНаряда.Работы);
ОбъектНаряда.Записать();
КонецПроцедуры
Процедура ЗаписатьОшибку(ТекстОшибки, ИнформацияОбОшибке = Неопределено, Данные = Неопределено)
Если ИнформацияОбОшибке = Неопределено Тогда
Комментарий = ТекстОшибки;
Иначе
Комментарий = ТекстОшибки + Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
КонецЕсли;
ЗаписьЖурналаРегистрации(
"КРДВ.АвтозакрытиеНарядов",
УровеньЖурналаРегистрации.Ошибка,
Метаданные.ОбщиеМодули.КРДВ_АвтозакрытиеНарядовСервер,
Данные,
Комментарий);
КонецПроцедуры
Процедура ЗаписатьПредупреждение(ТекстПредупреждения, Данные = Неопределено)
ЗаписьЖурналаРегистрации(
"КРДВ.АвтозакрытиеНарядов",
УровеньЖурналаРегистрации.Предупреждение,
Метаданные.ОбщиеМодули.КРДВ_АвтозакрытиеНарядовСервер,
Данные,
ТекстПредупреждения);
КонецПроцедуры
#КонецОбласти