Файл: автоматизация приема и обработки заявок отделом техподдержки ооо "компьютерные бизнес системы".pdf
Добавлен: 30.11.2023
Просмотров: 322
Скачиваний: 4
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
&НаКлиенте
Процедура ДеревоНоваяПодзадача(Команда)
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
//// вариант программного создания и записи нового документа
//НоваяПодЗадача = СоздатьПодзадачуНаСервере(); // создать новый документ и записать его
//ПутьВДереве
=
ПолучитьПутьВДереве(Элементы.ДеревоПодзадач.ТекущиеДанные,
НоваяПодЗадача); //сформировать массив подзадач от текущего узла до корня
//ДобавитьСуществующуюПодзадачуНаСервере(ЭтаЗадача,
НоваяПодЗадача); // добавить новую задачу в объект (в таб. часть)
//ЭтаФорма.Прочитать(); // перечитать данные формы
//ЗаполнитьДеревоПодзадач(); // перстроить дерево подзадач
//СпозиционироватьсяВДеревеПодзадач(ДеревоПодзадач,
ПутьВДереве,
ПутьВДереве.Количество()-1); // спозиционироваться на добавленной задаче
//П = Новый Структура;
//П.Вставить("Ключ", НоваяПодЗадача);
//ОткрытьФорму("Документ.Задача.ФормаОбъекта",
П);
// открыть отдельную форму редактирования новой задачи
Если ОбщийСрв.ВЗакрытомПериоде(ЭтаЗадача) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Находится в закрытом периоде. Редактирование невозможно");
Возврат;
КонецЕсли;
Если
Не
ОбщийСрв.ПроверкаПрав(ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача,
"Автор"), ОбщийСрв.ПолучитьГлПользователь()) Тогда
134
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Нет прав редактировать чужой документ");
Возврат;
КонецЕсли;
Если (ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача, "Проведен")) И
(ОбщийСрв.обПолучитьКонстанту("ЗапретПроведенных")) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача)
+
"Уже выполнена. Редактирование невозможно");
Возврат;
КонецЕсли;
// вариант открытия формы нового пустого документа
П = Новый Структура;
П.Вставить("ЭтоНовый", Истина);// признак того что форма открывается для нового документа
П.Вставить("Родитель", ЭтаЗадача);
ОткрытьФорму("Документ.Задача.ФормаОбъекта", П, ЭтотОбъект); // открыть отдельную форму редактирования новой задачи
// далее см. в ПриСозданииНаСервере - заполнение реквизитов и таб. частей нового документа на основании этого
// далее см. в ПослеЗаписи - запись новой задачи в тч Подзадачи родительской задачи
// далее см. в ОбработкаОповещения - в родительской задаче в дереве спозиционироваться на новой задаче
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьДеревоПоШаблону(Шаблон)
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
Если ОбщийСрв.ВЗакрытомПериоде(ЭтаЗадача) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Находится в закрытом периоде. Редактирование невозможно");
Возврат;
КонецЕсли;
Если
Не
ОбщийСрв.ПроверкаПрав(ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача,
"Автор"), ОбщийСрв.ПолучитьГлПользователь()) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Нет прав редактировать чужой документ");
Возврат;
КонецЕсли;
Если (ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача, "Проведен")) И
(ОбщийСрв.обПолучитьКонстанту("ЗапретПроведенных")) Тогда
135
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача)
+
"Уже выполнена. Редактирование невозможно");
Возврат;
КонецЕсли;
НоваяПодЗадача = СоздатьПодзадачуНаСервере(Шаблон, ЭтаЗадача); // создать новый документ и записать его
ДобавитьСуществующуюПодзадачуНаСервере(ЭтаЗадача, НоваяПодЗадача);
// добавить новую задачу в объект (в таб. часть)
ПутьВДереве
=
ПолучитьПутьВДереве(Элементы.ДеревоПодзадач.ТекущиеДанные,
НоваяПодЗадача); //сформировать массив подзадач от текущего узла до корня
ЗаполнитьПоШаблонуРекурсивно(Шаблон, НоваяПодЗадача);
ЭтаФорма.Прочитать(); // перечитать данные формы
ЗаполнитьДеревоПодзадач(); // перстроить дерево подзадач
Элементы.ДеревоПодзадач.ТекущаяСтрока
=
СпозиционироватьсяВДеревеПодзадач(ДеревоПодзадач,
ПутьВДереве,
ПутьВДереве.Количество()-1); // спозиционироваться на добавленной задаче
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьПоШаблонуРекурсивно(Шаблон, Основание)
ВыборкаСправочника = Справочники.Этапы.Выбрать(Шаблон);
Пока ВыборкаСправочника.Следующий() Цикл
НоваяПодЗадача
=
СоздатьПодзадачуНаСервере(ВыборкаСправочника, Основание); // создать новый документ и записать его
ДобавитьСуществующуюПодзадачуНаСервере(Основание,
НоваяПодЗадача); // добавить новую задачу в объект (в таб. часть)
ЗаполнитьПоШаблонуРекурсивно(ВыборкаСправочника.Ссылка,
НоваяПодЗадача);
КонецЦикла;
КонецПроцедуры
// открыть текущую подзадачу в дереве в отдельной форме. Вызываеися из Выбор и по команде Открыть
&НаКлиенте
Процедура ОткрытьПодзадачу()
ПодЗадача
=
ЭтотОбъект.Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача;
Если ПодЗадача = Неопределено Тогда
Возврат;
136
КонецЕсли;
Если ПодЗадача.Пустая() = Истина Тогда
Возврат;
КонецЕсли;
//ОткрытьЗначение(ПодЗадача);
П = Новый Структура;
П.Вставить("Ключ", ПодЗадача);
ОткрытьФорму("Документ.Задача.ФормаОбъекта", П); // открыть отдельную форму редактирования
КонецПроцедуры
// открыть форму выбора списка задач
&НаКлиенте
Процедура ДобавитьСуществующуюПодзадачу()
ПодЗадача
=
ЭтотОбъект.Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача;
П = Новый Структура;
П.Вставить("ПараметрТекущаяСтрока", ПодЗадача);
ОткрытьФорму("Документ.Задача.ФормаВыбора",
П,
ЭтотОбъект.Элементы.ДеревоПодзадач);
// результат выбора см. в ОбработкаВыбора элемента формы ДеревоПодзадач
КонецПроцедуры
// во внешней форме выбора завершили выбор существующей задачи - добавить ее в дерево подзадач
&НаКлиенте
Процедура
ДеревоПодзадачОбработкаВыбора(Элемент,
ВыбранноеЗначение,
СтандартнаяОбработка)
Если Не Элемент.Имя = "ДеревоПодзадач" Тогда // если выбор был не из дерева
Возврат;
КонецЕсли;
Если ВыбранноеЗначение = Неопределено Тогда // если ничего не было выбрано
Возврат;
КонецЕсли;
137
Если
Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача
=
ВыбранноеЗначение Тогда // зацикливание!
Сообщить("Нельзя вставлять задачу саму в себя!");
Возврат;
КонецЕсли;
Если
ЯвляетсяПредком(ВыбранноеЗначение,
Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача) Тогда // проврка на предка
Сообщить("Добавление приведет к зацикливанию!");
Возврат;
КонецЕсли;
Если
УжеЕстьВСпискеПодзадач(Элементы.ДеревоПодзадач.ТекущиеДанные,
ВыбранноеЗначение) Тогда // проврка на то, что уже есть
Сообщить("Выбранная подзадача уже является подзадачей данной задачи!");
Возврат;
КонецЕсли;
//ЭтаЗадача = Объект.Ссылка; // если в эту задачу
//Если Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача <> ЭтаЗадача
Тогда // если в какую-то подзадачу в дереве
//
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
//КонецЕсли;
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
ПутьВДереве
=
ПолучитьПутьВДереве(Элементы.ДеревоПодзадач.ТекущиеДанные,
ВыбранноеЗначение); //запомнить путь в дереве до нового выбранного значения
ДобавитьСуществующуюПодзадачуНаСервере(ЭтаЗадача,
ВыбранноеЗначение); // добавить выбранную задачу в объект
ЗаполнитьДеревоПодзадач(); // перстроить дерево подзадач
Элементы.ДеревоПодзадач.ТекущаяСтрока
=
СпозиционироватьсяВДеревеПодзадач(ДеревоПодзадач,
ПутьВДереве,
ПутьВДереве.Количество()-1); // спозиционироваться на добавленной задаче
Оповестить("Дерево", Новый Структура, ЭтотОбъект); // оповестить все формы об изменении - пусть они перестаивают свое дерево
КонецПроцедуры
//Проверка - является ли ДобавляемаяЗадача предком текущего узла (в который добавляют) на каком-либо уровне
&НаКлиенте
Функция ЯвляетсяПредком(ДобавляемаяЗадача, ВЗадачу)
138
СЗ = Новый СписокЗначений; // СЗ всех предков
ОбщийСрв.СформироватьСписокПредков(СЗ, ВЗадачу); // сформировать список всех предков
Если СЗ.НайтиПоЗначению(ДобавляемаяЗадача) = Неопределено Тогда // если входит в СЗ - значит на каком-то уровне является предком
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
// проверка - задача ВыбранноеЗначение уже есть в списке подзадач ВеткаДерева на одном уровне
&НаКлиенте
Функция УжеЕстьВСпискеПодзадач(ВеткаДерева, ВыбранноеЗначение)
Для Каждого Строка Из ВеткаДерева.ПолучитьЭлементы() Цикл
Если Строка.Подзадача = ВыбранноеЗначение Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
//сформировать массив подзадач от текущего узла до корня
&НаКлиенте
Функция ПолучитьПутьВДереве(УзелНачало, ВыбранноеЗначение = Неопределено
)
ПутьВДереве = Новый Массив;
Если Не ВыбранноеЗначение = Неопределено Тогда // включать
ВыбранноеЗначение в массив или нет
ПутьВДереве.Добавить(ВыбранноеЗначение);
КонецЕсли;
Если УзелНачало = Неопределено Тогда
Возврат ПутьВДереве;
КонецЕсли;
// рекурсивно для каждого уровня
ПолучитьПутьВДеревеРекурсивно(УзелНачало.ПолучитьИдентификатор(),
ПутьВДереве);
Возврат ПутьВДереве;
139
КонецФункции
//сформировать массив подзадач от текущего узла до корня
&НаСервере
Процедура ПолучитьПутьВДеревеРекурсивно(А, ПутьВДереве)
СтрокаДереваФормы = ДеревоПодзадач.НайтиПоИдентификатору(А);
ПутьВДереве.Добавить(СтрокаДереваФормы.ПодЗадача);
Если СтрокаДереваФормы.Подзадача = Объект.Ссылка Тогда // если это корень - то закончить рекурсию
Возврат;
КонецЕсли;
Родитель = СтрокаДереваФормы.ПолучитьРодителя();
Если Родитель = Неопределено Тогда
Возврат;
КонецЕсли;
ПолучитьПутьВДеревеРекурсивно(СтрокаДереваФормы.ПолучитьРодителя().Полу читьИдентификатор(), ПутьВДереве)
КонецПроцедуры
// в объект ВКакуюЗадачу добавить ЧтоДобавлять
&НаСервере
Процедура
ДобавитьСуществующуюПодзадачуНаСервере(ВКакуюЗадачу,
ЧтоДобавлять)
ВКакуюЗадачуОбъект = ВКакуюЗадачу.ПолучитьОбъект();
ЧтоДобавлятьОбъект = ЧтоДобавлять.ПолучитьОбъект();
НоваяСтрокаПодзадача = ВКакуюЗадачуОбъект.Подзадачи.Добавить();
НоваяСтрокаПодзадача.ПодЗадача = ЧтоДобавлять;
ВКакуюЗадачуОбъект.Записать(); // просто записать
// если добавляемая была головная - то больше она не головная
Если ЧтоДобавлять.Головная Тогда
ЧтоДобавлятьОбъект.Головная = Ложь;
ОбщийСрв.ЗаписьВедетИсполнитель(Истина);
ЧтоДобавлятьОбъект.Записать();
ОбщийСрв.ЗаписьВедетИсполнитель(Ложь);
КонецЕсли;
Если (ВКакуюЗадачу.Проведен) И (ЧтоДобавлять.Проведен = Ложь) Тогда // если эта задача была проведена, а новая нет - то распроводим эту
140
Сообщить("Выполнение задачи-родителя "
+
ОбщийСрв.ПредставлениеЗадачи(ВКакуюЗадачу) + " будет отменено");
ВКакуюЗадачуОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения,
РежимПроведенияДокумента.Неоперативный);
КонецЕсли;
КонецПроцедуры
// удалить Подзадача из объекта Задача (в БД)
&НаСервере
Процедура УдалитьПодзадачуНаСервере(Задача, Подзадача)
ЗадачаОбъект
= Задача.ПолучитьОбъект();
УдаляемаяСтрока = ЗадачаОбъект.Подзадачи.Найти(Подзадача);
Если Не УдаляемаяСтрока = Неопределено Тогда
ЗадачаОбъект.Подзадачи.Удалить(УдаляемаяСтрока);
ЗадачаОбъект.Записать();
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СохранитьДеревоНаСервере()
Для Каждого Строка Из ДеревоПодзадач.ПолучитьЭлементы() Цикл
СохранитьСтрокуДерева(Строка); // для каждой строки
КонецЦикла;
КонецПроцедуры
// сохранить строку дерева (со всеми ее подстроками)
&НаСервере
Процедура СохранитьСтрокуДерева(СтрокаДерева)
Задача = СтрокаДерева.ПодЗадача;
ЗадачаОбъект = Задача.ПолучитьОбъект();
ЗадачаОбъект.Подзадачи.Очистить(); // очистить таб. часть подзадачи
Для Каждого Строка Из СтрокаДерева.ПолучитьЭлементы() Цикл
Новая = ЗадачаОбъект.Подзадачи.Добавить();
// добавить из дерева каждую строку в таб часть
Новая.Подзадача = Строка.Подзадача;
Новая.Комментарий
= Строка.Комментарий;
СохранитьСтрокуДерева(Строка);
// рекрсивно для каждой строки
КонецЦикла;
ЗадачаОбъект.Записать();
КонецПроцедуры
141
// создать новую задачу (для варианта создания новой подзадачи программно, а не в пустой форме)
&НаСервере
Функция СоздатьПодзадачуНаСервере(Шаблон = Неопределено, Основание =
Неопределено)
// создать новый документ
НоваяПодЗадача = Документы.Задача.СоздатьДокумент();
НоваяПодЗадача.Дата = ТекущаяДата();
НоваяПодЗадача.УстановитьНовыйНомер();
// заполнить реквизиты по-умолчанию и из основания
ОбщийСрв.ПриВводеНовойЗадачи(НоваяПодЗадача, Основание, Ложь);
Если Не Шаблон = Неопределено Тогда // если шаблон задан, то часть реквизитов - из шаблона
НоваяПодЗадача.Наименование = Шаблон.Наименование;
Ответсвенный = Справочники.Сотрудники.ПустаяСсылка();
Если Не Шаблон.ОтветсвенныйСотрудник.Пустая() Тогда
Ответсвенный = Шаблон.ОтветсвенныйСотрудник;
Иначе
Ответсвенный
=
ОбщийСрв.ОтветсвенныйПоПодразделению(Шаблон.ОтветсвенноеПодразделение)
;
КонецЕсли;
Если Не Ответсвенный.Пустая() Тогда
НоваяПодЗадача.Отвественный
=
Ответсвенный;
//
Ответсвенный
НоваяСтрИсполнители
=
НоваяПодЗадача.Исполнители.Добавить();// он же - первый исполнитель
НоваяСтрИсполнители.Исполнитель = Ответсвенный;
НоваяСтрИсполнители.Процент = 100;
НоваяСтрИсполнители.Задание = Шаблон.Наименование;
КонецЕсли;
Если Не Шаблон.Статус.Пустая() Тогда
НоваяПодЗадача.Статус = Шаблон.Статус;
КонецЕсли;
Если Не Шаблон.Срок = 0 Тогда
НоваяПодЗадача.ОжидаемаяДатаВыполнения = ТекущаяДата() +
24*60*60*Шаблон.Срок;
КонецЕсли;
Если Не Шаблон.Объем = 0 Тогда
НоваяПодЗадача.Объем
= Шаблон.Объем;
КонецЕсли;
Если Не Шаблон.ЕдИзм.Пустая() Тогда
142
НоваяПодЗадача.ЕдИзм
= Шаблон.ЕдИзм;
КонецЕсли;
Если Не ПустаяСтрока(Шаблон.Комментарий) Тогда
НоваяПодЗадача.Комментарий = Шаблон.Комментарий;
КонецЕсли;
Если Не Шаблон.ВидЗадачи.Пустая() Тогда
НоваяПодЗадача.ВидЗадачи
= Шаблон.ВидЗадачи;
КонецЕсли;
КонецЕсли;
НоваяПодЗадача.Записать();
Возврат НоваяПодЗадача.Ссылка;
КонецФункции
// при любом изменении (в т.ч. проведении) оповестить другие открытые формы
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
П = Новый Структура;
Если Параметры.Свойство("ЭтоНовый") Тогда // если из вызывающей формы был пердан признак что это новый документ (кнопка Новая в Подзадачи)
Если Параметры.ЭтоНовый Тогда // то в родителя добавить эту задачу
ДобавитьСуществующуюПодзадачуНаСервере(Параметры.Родитель,
Объект.Ссылка); // добавить новую задачу в объект (в таб. часть)
П.Вставить("НоваяПодЗадача", Объект.Ссылка); // и пердаем новую задачу в ОбработкаОповещения
П.Вставить("ЭтоНовый", Параметры.ЭтоНовый);
КонецЕсли;
КонецЕсли;
Оповестить("Дерево",П, ЭтотОбъект); // оповестить об изменении, сделанном в этом форме, все остальные формы - пусть они перстаривают свое дерево
// далее см. в ОбработкаОповещения
КонецПроцедуры
// обработка оповещения о любых изменениях, проведенных в других формах
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия <> "Дерево" Тогда // не наш случай
Возврат;
КонецЕсли;
Процедура ДеревоНоваяПодзадача(Команда)
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
//// вариант программного создания и записи нового документа
//НоваяПодЗадача = СоздатьПодзадачуНаСервере(); // создать новый документ и записать его
//ПутьВДереве
=
ПолучитьПутьВДереве(Элементы.ДеревоПодзадач.ТекущиеДанные,
НоваяПодЗадача); //сформировать массив подзадач от текущего узла до корня
//ДобавитьСуществующуюПодзадачуНаСервере(ЭтаЗадача,
НоваяПодЗадача); // добавить новую задачу в объект (в таб. часть)
//ЭтаФорма.Прочитать(); // перечитать данные формы
//ЗаполнитьДеревоПодзадач(); // перстроить дерево подзадач
//СпозиционироватьсяВДеревеПодзадач(ДеревоПодзадач,
ПутьВДереве,
ПутьВДереве.Количество()-1); // спозиционироваться на добавленной задаче
//П = Новый Структура;
//П.Вставить("Ключ", НоваяПодЗадача);
//ОткрытьФорму("Документ.Задача.ФормаОбъекта",
П);
// открыть отдельную форму редактирования новой задачи
Если ОбщийСрв.ВЗакрытомПериоде(ЭтаЗадача) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Находится в закрытом периоде. Редактирование невозможно");
Возврат;
КонецЕсли;
Если
Не
ОбщийСрв.ПроверкаПрав(ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача,
"Автор"), ОбщийСрв.ПолучитьГлПользователь()) Тогда
134
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Нет прав редактировать чужой документ");
Возврат;
КонецЕсли;
Если (ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача, "Проведен")) И
(ОбщийСрв.обПолучитьКонстанту("ЗапретПроведенных")) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача)
+
"Уже выполнена. Редактирование невозможно");
Возврат;
КонецЕсли;
// вариант открытия формы нового пустого документа
П = Новый Структура;
П.Вставить("ЭтоНовый", Истина);// признак того что форма открывается для нового документа
П.Вставить("Родитель", ЭтаЗадача);
ОткрытьФорму("Документ.Задача.ФормаОбъекта", П, ЭтотОбъект); // открыть отдельную форму редактирования новой задачи
// далее см. в ПриСозданииНаСервере - заполнение реквизитов и таб. частей нового документа на основании этого
// далее см. в ПослеЗаписи - запись новой задачи в тч Подзадачи родительской задачи
// далее см. в ОбработкаОповещения - в родительской задаче в дереве спозиционироваться на новой задаче
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьДеревоПоШаблону(Шаблон)
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
Если ОбщийСрв.ВЗакрытомПериоде(ЭтаЗадача) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Находится в закрытом периоде. Редактирование невозможно");
Возврат;
КонецЕсли;
Если
Не
ОбщийСрв.ПроверкаПрав(ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача,
"Автор"), ОбщийСрв.ПолучитьГлПользователь()) Тогда
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача) + "Нет прав редактировать чужой документ");
Возврат;
КонецЕсли;
Если (ОбщийСрв.ПолучитьРеквизитЗадачи(ЭтаЗадача, "Проведен")) И
(ОбщийСрв.обПолучитьКонстанту("ЗапретПроведенных")) Тогда
135
Сообщить(ОбщийСрв.ПредставлениеЗадачи(ЭтаЗадача)
+
"Уже выполнена. Редактирование невозможно");
Возврат;
КонецЕсли;
НоваяПодЗадача = СоздатьПодзадачуНаСервере(Шаблон, ЭтаЗадача); // создать новый документ и записать его
ДобавитьСуществующуюПодзадачуНаСервере(ЭтаЗадача, НоваяПодЗадача);
// добавить новую задачу в объект (в таб. часть)
ПутьВДереве
=
ПолучитьПутьВДереве(Элементы.ДеревоПодзадач.ТекущиеДанные,
НоваяПодЗадача); //сформировать массив подзадач от текущего узла до корня
ЗаполнитьПоШаблонуРекурсивно(Шаблон, НоваяПодЗадача);
ЭтаФорма.Прочитать(); // перечитать данные формы
ЗаполнитьДеревоПодзадач(); // перстроить дерево подзадач
Элементы.ДеревоПодзадач.ТекущаяСтрока
=
СпозиционироватьсяВДеревеПодзадач(ДеревоПодзадач,
ПутьВДереве,
ПутьВДереве.Количество()-1); // спозиционироваться на добавленной задаче
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьПоШаблонуРекурсивно(Шаблон, Основание)
ВыборкаСправочника = Справочники.Этапы.Выбрать(Шаблон);
Пока ВыборкаСправочника.Следующий() Цикл
НоваяПодЗадача
=
СоздатьПодзадачуНаСервере(ВыборкаСправочника, Основание); // создать новый документ и записать его
ДобавитьСуществующуюПодзадачуНаСервере(Основание,
НоваяПодЗадача); // добавить новую задачу в объект (в таб. часть)
ЗаполнитьПоШаблонуРекурсивно(ВыборкаСправочника.Ссылка,
НоваяПодЗадача);
КонецЦикла;
КонецПроцедуры
// открыть текущую подзадачу в дереве в отдельной форме. Вызываеися из Выбор и по команде Открыть
&НаКлиенте
Процедура ОткрытьПодзадачу()
ПодЗадача
=
ЭтотОбъект.Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача;
Если ПодЗадача = Неопределено Тогда
Возврат;
136
КонецЕсли;
Если ПодЗадача.Пустая() = Истина Тогда
Возврат;
КонецЕсли;
//ОткрытьЗначение(ПодЗадача);
П = Новый Структура;
П.Вставить("Ключ", ПодЗадача);
ОткрытьФорму("Документ.Задача.ФормаОбъекта", П); // открыть отдельную форму редактирования
КонецПроцедуры
// открыть форму выбора списка задач
&НаКлиенте
Процедура ДобавитьСуществующуюПодзадачу()
ПодЗадача
=
ЭтотОбъект.Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача;
П = Новый Структура;
П.Вставить("ПараметрТекущаяСтрока", ПодЗадача);
ОткрытьФорму("Документ.Задача.ФормаВыбора",
П,
ЭтотОбъект.Элементы.ДеревоПодзадач);
// результат выбора см. в ОбработкаВыбора элемента формы ДеревоПодзадач
КонецПроцедуры
// во внешней форме выбора завершили выбор существующей задачи - добавить ее в дерево подзадач
&НаКлиенте
Процедура
ДеревоПодзадачОбработкаВыбора(Элемент,
ВыбранноеЗначение,
СтандартнаяОбработка)
Если Не Элемент.Имя = "ДеревоПодзадач" Тогда // если выбор был не из дерева
Возврат;
КонецЕсли;
Если ВыбранноеЗначение = Неопределено Тогда // если ничего не было выбрано
Возврат;
КонецЕсли;
137
Если
Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача
=
ВыбранноеЗначение Тогда // зацикливание!
Сообщить("Нельзя вставлять задачу саму в себя!");
Возврат;
КонецЕсли;
Если
ЯвляетсяПредком(ВыбранноеЗначение,
Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача) Тогда // проврка на предка
Сообщить("Добавление приведет к зацикливанию!");
Возврат;
КонецЕсли;
Если
УжеЕстьВСпискеПодзадач(Элементы.ДеревоПодзадач.ТекущиеДанные,
ВыбранноеЗначение) Тогда // проврка на то, что уже есть
Сообщить("Выбранная подзадача уже является подзадачей данной задачи!");
Возврат;
КонецЕсли;
//ЭтаЗадача = Объект.Ссылка; // если в эту задачу
//Если Элементы.ДеревоПодзадач.ТекущиеДанные.Подзадача <> ЭтаЗадача
Тогда // если в какую-то подзадачу в дереве
//
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
//КонецЕсли;
ЭтаЗадача = Элементы.ДеревоПодзадач.ТекущиеДанные.ПодЗадача;
ПутьВДереве
=
ПолучитьПутьВДереве(Элементы.ДеревоПодзадач.ТекущиеДанные,
ВыбранноеЗначение); //запомнить путь в дереве до нового выбранного значения
ДобавитьСуществующуюПодзадачуНаСервере(ЭтаЗадача,
ВыбранноеЗначение); // добавить выбранную задачу в объект
ЗаполнитьДеревоПодзадач(); // перстроить дерево подзадач
Элементы.ДеревоПодзадач.ТекущаяСтрока
=
СпозиционироватьсяВДеревеПодзадач(ДеревоПодзадач,
ПутьВДереве,
ПутьВДереве.Количество()-1); // спозиционироваться на добавленной задаче
Оповестить("Дерево", Новый Структура, ЭтотОбъект); // оповестить все формы об изменении - пусть они перестаивают свое дерево
КонецПроцедуры
//Проверка - является ли ДобавляемаяЗадача предком текущего узла (в который добавляют) на каком-либо уровне
&НаКлиенте
Функция ЯвляетсяПредком(ДобавляемаяЗадача, ВЗадачу)
138
СЗ = Новый СписокЗначений; // СЗ всех предков
ОбщийСрв.СформироватьСписокПредков(СЗ, ВЗадачу); // сформировать список всех предков
Если СЗ.НайтиПоЗначению(ДобавляемаяЗадача) = Неопределено Тогда // если входит в СЗ - значит на каком-то уровне является предком
Возврат Ложь;
КонецЕсли;
Возврат Истина;
КонецФункции
// проверка - задача ВыбранноеЗначение уже есть в списке подзадач ВеткаДерева на одном уровне
&НаКлиенте
Функция УжеЕстьВСпискеПодзадач(ВеткаДерева, ВыбранноеЗначение)
Для Каждого Строка Из ВеткаДерева.ПолучитьЭлементы() Цикл
Если Строка.Подзадача = ВыбранноеЗначение Тогда
Возврат Истина;
КонецЕсли;
КонецЦикла;
Возврат Ложь;
КонецФункции
//сформировать массив подзадач от текущего узла до корня
&НаКлиенте
Функция ПолучитьПутьВДереве(УзелНачало, ВыбранноеЗначение = Неопределено
)
ПутьВДереве = Новый Массив;
Если Не ВыбранноеЗначение = Неопределено Тогда // включать
ВыбранноеЗначение в массив или нет
ПутьВДереве.Добавить(ВыбранноеЗначение);
КонецЕсли;
Если УзелНачало = Неопределено Тогда
Возврат ПутьВДереве;
КонецЕсли;
// рекурсивно для каждого уровня
ПолучитьПутьВДеревеРекурсивно(УзелНачало.ПолучитьИдентификатор(),
ПутьВДереве);
Возврат ПутьВДереве;
139
КонецФункции
//сформировать массив подзадач от текущего узла до корня
&НаСервере
Процедура ПолучитьПутьВДеревеРекурсивно(А, ПутьВДереве)
СтрокаДереваФормы = ДеревоПодзадач.НайтиПоИдентификатору(А);
ПутьВДереве.Добавить(СтрокаДереваФормы.ПодЗадача);
Если СтрокаДереваФормы.Подзадача = Объект.Ссылка Тогда // если это корень - то закончить рекурсию
Возврат;
КонецЕсли;
Родитель = СтрокаДереваФормы.ПолучитьРодителя();
Если Родитель = Неопределено Тогда
Возврат;
КонецЕсли;
ПолучитьПутьВДеревеРекурсивно(СтрокаДереваФормы.ПолучитьРодителя().Полу читьИдентификатор(), ПутьВДереве)
КонецПроцедуры
// в объект ВКакуюЗадачу добавить ЧтоДобавлять
&НаСервере
Процедура
ДобавитьСуществующуюПодзадачуНаСервере(ВКакуюЗадачу,
ЧтоДобавлять)
ВКакуюЗадачуОбъект = ВКакуюЗадачу.ПолучитьОбъект();
ЧтоДобавлятьОбъект = ЧтоДобавлять.ПолучитьОбъект();
НоваяСтрокаПодзадача = ВКакуюЗадачуОбъект.Подзадачи.Добавить();
НоваяСтрокаПодзадача.ПодЗадача = ЧтоДобавлять;
ВКакуюЗадачуОбъект.Записать(); // просто записать
// если добавляемая была головная - то больше она не головная
Если ЧтоДобавлять.Головная Тогда
ЧтоДобавлятьОбъект.Головная = Ложь;
ОбщийСрв.ЗаписьВедетИсполнитель(Истина);
ЧтоДобавлятьОбъект.Записать();
ОбщийСрв.ЗаписьВедетИсполнитель(Ложь);
КонецЕсли;
Если (ВКакуюЗадачу.Проведен) И (ЧтоДобавлять.Проведен = Ложь) Тогда // если эта задача была проведена, а новая нет - то распроводим эту
140
Сообщить("Выполнение задачи-родителя "
+
ОбщийСрв.ПредставлениеЗадачи(ВКакуюЗадачу) + " будет отменено");
ВКакуюЗадачуОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения,
РежимПроведенияДокумента.Неоперативный);
КонецЕсли;
КонецПроцедуры
// удалить Подзадача из объекта Задача (в БД)
&НаСервере
Процедура УдалитьПодзадачуНаСервере(Задача, Подзадача)
ЗадачаОбъект
= Задача.ПолучитьОбъект();
УдаляемаяСтрока = ЗадачаОбъект.Подзадачи.Найти(Подзадача);
Если Не УдаляемаяСтрока = Неопределено Тогда
ЗадачаОбъект.Подзадачи.Удалить(УдаляемаяСтрока);
ЗадачаОбъект.Записать();
КонецЕсли;
КонецПроцедуры
&НаСервере
Процедура СохранитьДеревоНаСервере()
Для Каждого Строка Из ДеревоПодзадач.ПолучитьЭлементы() Цикл
СохранитьСтрокуДерева(Строка); // для каждой строки
КонецЦикла;
КонецПроцедуры
// сохранить строку дерева (со всеми ее подстроками)
&НаСервере
Процедура СохранитьСтрокуДерева(СтрокаДерева)
Задача = СтрокаДерева.ПодЗадача;
ЗадачаОбъект = Задача.ПолучитьОбъект();
ЗадачаОбъект.Подзадачи.Очистить(); // очистить таб. часть подзадачи
Для Каждого Строка Из СтрокаДерева.ПолучитьЭлементы() Цикл
Новая = ЗадачаОбъект.Подзадачи.Добавить();
// добавить из дерева каждую строку в таб часть
Новая.Подзадача = Строка.Подзадача;
Новая.Комментарий
= Строка.Комментарий;
СохранитьСтрокуДерева(Строка);
// рекрсивно для каждой строки
КонецЦикла;
ЗадачаОбъект.Записать();
КонецПроцедуры
141
// создать новую задачу (для варианта создания новой подзадачи программно, а не в пустой форме)
&НаСервере
Функция СоздатьПодзадачуНаСервере(Шаблон = Неопределено, Основание =
Неопределено)
// создать новый документ
НоваяПодЗадача = Документы.Задача.СоздатьДокумент();
НоваяПодЗадача.Дата = ТекущаяДата();
НоваяПодЗадача.УстановитьНовыйНомер();
// заполнить реквизиты по-умолчанию и из основания
ОбщийСрв.ПриВводеНовойЗадачи(НоваяПодЗадача, Основание, Ложь);
Если Не Шаблон = Неопределено Тогда // если шаблон задан, то часть реквизитов - из шаблона
НоваяПодЗадача.Наименование = Шаблон.Наименование;
Ответсвенный = Справочники.Сотрудники.ПустаяСсылка();
Если Не Шаблон.ОтветсвенныйСотрудник.Пустая() Тогда
Ответсвенный = Шаблон.ОтветсвенныйСотрудник;
Иначе
Ответсвенный
=
ОбщийСрв.ОтветсвенныйПоПодразделению(Шаблон.ОтветсвенноеПодразделение)
;
КонецЕсли;
Если Не Ответсвенный.Пустая() Тогда
НоваяПодЗадача.Отвественный
=
Ответсвенный;
//
Ответсвенный
НоваяСтрИсполнители
=
НоваяПодЗадача.Исполнители.Добавить();// он же - первый исполнитель
НоваяСтрИсполнители.Исполнитель = Ответсвенный;
НоваяСтрИсполнители.Процент = 100;
НоваяСтрИсполнители.Задание = Шаблон.Наименование;
КонецЕсли;
Если Не Шаблон.Статус.Пустая() Тогда
НоваяПодЗадача.Статус = Шаблон.Статус;
КонецЕсли;
Если Не Шаблон.Срок = 0 Тогда
НоваяПодЗадача.ОжидаемаяДатаВыполнения = ТекущаяДата() +
24*60*60*Шаблон.Срок;
КонецЕсли;
Если Не Шаблон.Объем = 0 Тогда
НоваяПодЗадача.Объем
= Шаблон.Объем;
КонецЕсли;
Если Не Шаблон.ЕдИзм.Пустая() Тогда
142
НоваяПодЗадача.ЕдИзм
= Шаблон.ЕдИзм;
КонецЕсли;
Если Не ПустаяСтрока(Шаблон.Комментарий) Тогда
НоваяПодЗадача.Комментарий = Шаблон.Комментарий;
КонецЕсли;
Если Не Шаблон.ВидЗадачи.Пустая() Тогда
НоваяПодЗадача.ВидЗадачи
= Шаблон.ВидЗадачи;
КонецЕсли;
КонецЕсли;
НоваяПодЗадача.Записать();
Возврат НоваяПодЗадача.Ссылка;
КонецФункции
// при любом изменении (в т.ч. проведении) оповестить другие открытые формы
&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)
П = Новый Структура;
Если Параметры.Свойство("ЭтоНовый") Тогда // если из вызывающей формы был пердан признак что это новый документ (кнопка Новая в Подзадачи)
Если Параметры.ЭтоНовый Тогда // то в родителя добавить эту задачу
ДобавитьСуществующуюПодзадачуНаСервере(Параметры.Родитель,
Объект.Ссылка); // добавить новую задачу в объект (в таб. часть)
П.Вставить("НоваяПодЗадача", Объект.Ссылка); // и пердаем новую задачу в ОбработкаОповещения
П.Вставить("ЭтоНовый", Параметры.ЭтоНовый);
КонецЕсли;
КонецЕсли;
Оповестить("Дерево",П, ЭтотОбъект); // оповестить об изменении, сделанном в этом форме, все остальные формы - пусть они перстаривают свое дерево
// далее см. в ОбработкаОповещения
КонецПроцедуры
// обработка оповещения о любых изменениях, проведенных в других формах
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия <> "Дерево" Тогда // не наш случай
Возврат;
КонецЕсли;