На данном форуме уже есть несколько статей по созданию замещений в конкретных организациях (Пример: https://club.directum.ru/award/64706 или https://club.directum.ru/award/64767), только без открытого кода, без должного описания и даже без разработки. Так что я решил заполнить это пробел.
Ни для кого не секрет, что у наших пользователей нет прав на многие технические справочники, в том числе и на справочник "замещения пользователей", в связи с чем - пишутся заявки и нагружаются администраторы и разработчики. Чтобы этого избежать, всю техническую кухню, надо спрятать в подкорку несложного процесса, и вот его уже передать пользователям. Уже не одна компания реализует подобный подход к делу через Мастера действий или маршруты, чтобы минимизировать кол-во заявок в Service-Desk.
И так - начнем:
Для этого создадим новую Функцию и наполним ее нужными нам параметрами:
После этого заводим внутрь код:
Zameshenie = References.ЗМЩ.CreateNew // Созщдаем новую запись в справочнике "ЗМЩ"
Zameshenie.ISBReplaceableUser = Замещаемый // Пользователь
Zameshenie.ISBSubstitutingUser = Заместитель // Заместитель
Zameshenie.ISBSubstituteStart = ДатаНачала // Дата Начала замещения
Zameshenie.ISBSubstituteFinish = ДатаКонца // Дата Конца замещения
Zameshenie.КСтрока = Обоснование // Примичание
if ТипЗамещения // тип замещения: Полное или Ассистент
Zameshenie.ISBSubstituteType = 'Полное'
else
Zameshenie.ISBSubstituteType = 'Ассистент'
endif
Zameshenie.Save // Сохраняем запись
Result = Zameshenie.SYSREQ_ID // Выводим в результат ИД новой записи
Готово. Теперь у нас есть функция создающая запись в справочнике по вводимой информации и не требующую никаких сверх-естественных прав от пользователя.
Справка: В данном коде присутствует параметр "Тип Замещения", который в примере не участвует. Я его не стал убирать, так как он может и пригодиться в другом месте. Например в маршруте по согласованию приказа, где будет возможность не только делегировать какую-либо задачу, но и сразу выдать замещение (полное или на уровне Ассистента), у вас же есть для этого функция. Можно часть кода убрать и оставить только строку "Zameshenie.ISBSubstituteType = 'Полное'" - смотрите сами.
Называем его как угодно и даем новому маршруту уникальный Код:
Теперь заполняем его параметры:
Далее - создаем схему. Нам она сложной и не нужна, так что идем по минимальной тропке:
Собственно на этом этапе можно добавить согласование с руководителем, внести блок с созданием документа по шаблону с просьбой его оформить, передать оповещение в отдел кадров для учета и так далее - все в ваших руках. Я на примере буду уведомлять только 2 заинтересованных лиц: Замещаемого и заместителя (хотя отсюда первого можно и выкинуть, он же и так в курсе, кто его будет замещать)
Далее указываем и запрашиваемые параметры:
Поясню ситуацию: Чем больше пользователь умеет, тем больше надо делать проверок на корректность данных, поэтому я предлагаю ограничить выбор Замещаемого (что бы избежать экспериментов с возможностями и простых ошибок с выбором) - каждый выбирает себе заместителя и не далее. Начало периода я тоже убрал, хотя вы можете его запрашивать - никто нге мешает, но на мой взгляд, замещение делается все равно за сутки-двое до отпуска, и нет ничего страшного, что человек который и так будет все видеть послезавтра, увидит что-то сегодня. Но это только мое мнение. Просто надо всегда помнить, что "человеческий фактор" - это самое больное наше место...
Тут я делал все под себя, но вы можете сделать и иначе:
Начало выбора:
Params = Sender.WorkFlowParams
CurrentUser = ServiceFactory.GetUserByName(Application.Connection.UserName)
Params.ValueByName("Инициатор").Value = CurrentUser
Params.ValueByName("НачалоПериода").Value = Today()
Object.Subject = Format("Создается замещение от %s от %s)"; ArrayOf(CurrentUser.FullName; Today()))
Думаю, тут пояснения излишни - все просто.
Возможность старта:
Params = Sender.WorkFlowParams
if Params.ValueByName("НачалоПериода").Value >= Params.ValueByName("КонецПериода").Value
Raise(СоздатьИсключение('ВНИМАНИЕ!'; 'Конец периода должен быть после начала периода!' &CR&'Можете начинать процедуру заново.'))
endif
if Params.ValueByName("Инициатор").Value == Params.ValueByName("Заместитель").Value
Raise(СоздатьИсключение('ВНИМАНИЕ!'; 'Неверно выбран заместитель!' &CR& 'Вы выбрали себя!' &CR&'Можете начинать процедуру заново.'))
endif
ИНЗ = ТМПолучитьПараметрЗадачи('Инициатор')
ЗАМ = ТМПолучитьПараметрЗадачи('Заместитель')
Замещаемый = ServiceFactory.GetUserByName(ИНЗ).FullName
Заместитель = ServiceFactory.GetUserByName(ЗАМ).FullName
FullText = 'Создано замещение!' & CR
FullText = FullText & 'Замещаемый: ' & Замещаемый & CR
FullText = FullText & 'Заместитель: ' & Заместитель & CR
FullText = FullText & 'Начало периода замещения: ' & Params.ValueByName("НачалоПериода").Value & CR
FullText = FullText & 'Конец периода замещения: ' & Params.ValueByName("КонецПериода").Value & CR
FullText = FullText & 'Обоснование замещения: ' & Params.ValueByName("Обоснование").Value & CR
Object.ActiveText = FullText
Здесь немного сложнее, так как я посадил в вычисления 2 проверки: Проверка на последовательность дат и выбор замещаемого (здесь же можно сделать проверку на группу выбираемого сотрудника, чтобы никто не смог выбрать высшее руководство, но я это пропустил). Так же в активное поле комментариев выгружается вся полученная информация чтобы было легко все найти и рассмотреть.
Завершение выбора - тут на ваше усмотрение, я вот сделал так:
Sender.Start // Стартуем сразу, зачем кнопки часто нажимать?
Теперь осталось добавить стандартные блоки тем для уведомлений и само вычисление.
Уведомление для Инициатора:
Params = Object.WorkFlowParams
ЗАМ = ТМПолучитьПараметрЗадачи('Заместитель')
Заместитель = ServiceFactory.GetUserByName(ЗАМ).FullName
Начало = Params.ValueByName("НачалоПериода").Value
Конец = Params.ValueByName("КонецПериода").Value
Sender.Properties.ValueByName(JOB_BLOCK_SUBJECT_PROPERTY).Value = Format("Вас замещает %s с %s по %s"; ArrayOf(Заместитель;Начало;Конец))
Object.ActiveText = Params.ValueByName("ИДЗамещения").Value
Тоже все понятно, кроме "ИДЗамещения", его мы как раз получим чуть ранее из блока вычисления:
Вычисления в блоке "Создание Замещения":
Params = Object.WorkFlowParams
Инициатор = ServiceFactory.GetUserByName(ТМПолучитьПараметрЗадачи('Инициатор')).Code
Заместитель = ServiceFactory.GetUserByName(ТМПолучитьПараметрЗадачи('Заместитель')).Code
ДатаНачала = Params.ValueByName('НачалоПериода').Value
ДатаКонца = Params.ValueByName('КонецПериода').Value
Обоснование = Params.ValueByName('Обоснование').Value
ИДЗамещения = СоздатьЗамещение(Инициатор;Заместитель;ДатаНачала;ДатаКонца;Обоснование)
Params.ValueByName('ИДЗамещения').Value = Trim(ИДЗамещения)
Просто как 5 копеек. И наличие полученного ИД, позволит Администратору или Разработчику быстрее найти ошибочное замещение и убить его.
Теперь посмотрим скриншотики по работе этого скрипта)))
Как видно - задача уже стартована! Это из-за моей строки "Sender.Start"
И проверяем создание записи в справочнике:
Вот по сути и все - больше не надо получать письма с просьбой создать замещение - бросайтесь в людей инструкциями и да познаете вы Дзэн...
Почему подобное в стандартной коробке досихпор не реализовано? Ведь потребность оперативного назначения "зама" на период резкого отбытия по служебным/прочим делам, - довольно частая практическая задача.
Мне кажется, сразу же не стоит делать новую запись в справочник замещений, а на ответственного (того же администратора) назначать задание, чтобы он подтвердил замещение. Предоставь пользователю лишнюю свободу действий - и он ей обязательно воспользуется.
А так идея интересная и актуальная. Спасибо!
Прикреплен файл: Wizards.rar
И сама разработка
Добрый вечер!
Судя по коду "Raise(СоздатьИсключение('ВНИМАНИЕ!'; 'Конец периода должен быть после начала периода!' &CR&'Можете начинать процедуру заново.'))"
у вас не реализовано создание замещения на 1 день ?
Ольга, Верно - мы на это не размениваемся))) Ну а если честно, то мы заметили, что при замещении на 1 день, отказывается работать Подпись документов по праву заместителя, так что мы от этого отказались. Сутки и без зама работа не остановится.
Прикреплен файл: Замещение.rar
Обновляю разработку (МД, Маршрут, Функция)
А на какой версии Вы писали разработку? Для мастера действий в событиях выдается ошибка "
" - не нравится - "НайтиРеквизитПоФИО"
P.S. Нашел вашу функцию в других сообщениях.
Дмитрий, "НайтиРеквизитПоФИО", это самописная функция, которую я несколько раз расписывал и в этой статье пренебрег этим знанием. Вы можете создать ее сами:
FIO = ФИО Reference = References.РАБ.GetComponent Podrazd = '' AddWhere = Reference.AddWhere(Format("%0:s.%1:s = '%2:s'"; ArrayOf(Reference.TableName; Reference.Requisites('Дополнение').FieldName; FIO))) Reference.Open if Вариант == "Подразделение" if Reference.RecordCount > 0 Code = Reference.Requisites('Подразделение').AsString Podrazd = ReferenceRequisiteValue('ПОД';Code;'Наименование') endif Result = Podrazd endif if Вариант == "Пользователь" UserCod = '' if Reference.RecordCount > 0 Code = Reference.Requisites('Пользователь').AsString UserCod = ReferenceRequisiteValue('ПОЛ';Code;'Код') endif Result = UserCod endif if Вариант == "Подразделение_GUID" PodrazdGUID = '' if Reference.RecordCount > 0 Code = Reference.Requisites('Подразделение').AsString PodrazdGUID = ReferenceRequisiteValue('ПОД';Code;'GUID') endif Result = PodrazdGUID endif if Вариант == "Email" Email = '' if Reference.RecordCount > 0 Email = Reference.Requisites('Email').AsString endif Result = Email endif Reference.Close Reference.DelWhere(AddWhere) Reference = nil
Опробовал работу вашей разработки на версии 5.8. Работоспособно, но есть нюансы:
2 года прошло. Для 5.8. я бы использовал Мастер действия и Серверное событие. Тогда и маршрут не нужен и проблем куда меньше)
Авторизуйтесь, чтобы написать комментарий