Перейти к содержанию

Настройка внутрисистемных уведомлений#

На проекте есть возможность настроить уведомления для пользователей. Для этого необходимо произвести настройку (сделаем на примере оповещения о начале отпуска по основному месту работы). Пользователь должен обладать правами Администратора.

Конструктор документов#

  • Перейдите Администрирование - Документооборот - Кадровый ЭДО - Конструктор документов

Меню

В открывшемся реестре проверьте, не присутствует ли уже добавленный ранее шаблон "Уведомления Lexema". Если присутствует, то пропустите шаг по по созданию конструктора документов и перейдите в раздел Справочник рассылок для документа Уведомление Lexema. Данный шаблон конструктора должен быть в единичном экземпляре. Если он отсутствует, то его необходимо создать. Для этого в реестре шаблонов нажмите Создать. Подробнее про конструктор документов можно узнать в статье Конструктор документов.

В поле Группа выберите Уведомления Lexema. Если она отсутствует, то ее необходимо создать в Настройках документов

В поле Служебное наименование введите NotificationLexema.

В поле Подтип документа выберите Уведомления Lexema. Если такого подтипа нет, его необходимо создать. Настройка документов относится к полю Группа (см. комм. выше).

Поставьте галочку напротив Автоматически формировать маршрут.

Нажмите сохранить и закрыть.

Заполненный конструктор

Справочник рассылок для документа Уведомление Lexema#

Данный документ предназначен для формирования рассылки уведомлений для действующего/применяемого для определённого набора сотрудников. С помощью данного справочника в системе электронного документооборота можно направлять пользователям уведомления, и они будут находиться у них в панели документооборота как напоминание. В справочнике содержатся преднастроенные задачи, которые можно по необходимости включать и выключать на проекте. При необходимости появления новой задачи для рассылки её вносят в справочник рассылок.

Для создания рассылки, перейдите Администрирование - Рассылка электронных писем - Справочник рассылок для документа Уведомление Lexema.

Справочник рассылок

В открывшемся реестре нажмите кнопку "Создать".

Настройки#

В открывшейся вкладке необходимо заполнить следующие поля:

Подтип документов - из выпадающего списка выбирается подтип документа, по которому будет действовать справочник рассылок.

Наименование задачи, которое будет отображаться в качестве названия задачи.

Состояние "Включено" данного реквизита означает выполнение задачи в планировщике, если галочка не стоит,значит задача выполняться не будет.

Проверять отправку уведомления в течение дней: проверяет в течение определенного количества дней ушло ли уведомление пользователю. Проверка осуществляется с помощью таблицы уведомлений. Она находится в процедуре, которая вызывается при отработке ее в планировщике задач.

В блоке Настройка расписания рассылки выбирается, в какой день недели какого месяца и т.д. будет выполняться рассылка

В тексте задачи указывается часть с динамическим запросом, содержащим непосредственно текст для генерации документа.

Пример:

iinsert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker", "DateBeg", "Days", "TypeVacation", "Vacation", "DateEnd", "CopyTo")
select pc_ch."Code" as "User", '<font size="4"> </font><p style="text-align: center;">' || p_ch."Name" || ' ' || coalesce(p_ch."Father", '') || ', добрый день!</p><p style="text-align: center;"><br></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;На основании
статьи 123 Трудового кодекса Российской Федерации и согласно утвержденному&nbsp;графику отпусков на ' || p."Year"::text ||' год информируем о дате начала Вашего оплачиваемого отпуска (<b>' ||  coalesce(tw."Name",ex.name1c,'')||') </b> с <strong>' || to_char(coalesce(m."DateBegPer",m."DateBeg")::date, 'DD.MM.YYYY') ||  '</strong> сроком на <strong>' || coalesce(m."DaysPer",m."Days")::text
|| '</strong> календарных
дня(ей). Дата выхода на работу <strong>' ||to_char((coalesce(m."DateEndPer",m."DateEnd") +  '1 day'::interval)::date, 'DD.MM.YYYY')  
|| '</strong>. В случае, если дата выхода на
работу приходится на выходной день, она переносится на ближайший рабочий день.</p>

<p>&nbsp;</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ВАЖНО! </p>

<p><em>В связи с
вышеизложенным Вам следует подать заявление о предоставлении отпуска для
своевременного проведения расчетов и подготовки соответствующих документов. </em></p>

<p><em>Если Вы не
планируете использовать отпуск в указанные даты, обязательно сформируйте
заявление о переносе отпуска. </em></p>

<p><strong>&nbsp;</strong></p>

<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Заявление на
отпуск или перенос отпуска необходимо сформировать в системе КЭДО Lexema по
соответствующей операции через кнопку «Операции» на панели инструментов данного
уведомления.</strong></p>

<p><strong>&nbsp;</strong></p>

<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Уведомление
можно закрыть только после выполнения одного из действий.</strong></p>

<p><br>
Приятного отдыха! </p>
<font size="4"></font>'   as txt,
p."VCode" as "link",p."TypeName", 
null /*case when "TypeName" = 'Base.RP_DocVacationChanges' then 'Переносы отпусков' else 'График отпусков' end*/,
 null, /*'Уведомление работника о времени начала отпуска',*/
 m."IdWorker", 
coalesce(m."DateBegPer",m."DateBeg")::date as "DateBeg", coalesce(m."DaysPer",m."Days") as "Days", 
m."HolidayTypeGuid", coalesce(tw."Name",ex.name1c), coalesce(m."DateEndPer",m."DateEnd") as "DateEnd", null as "CopyTo"
from  aw."RP_DocVacation" p
      join aw."RP_WorkerVacation" m on p."VCode" = m."Pcode"
      cross join (select  (now() + '1 day'::interval)::date as bd,   (now() + '6 day'::interval)::date as ed  ) dt 
      cross join (select "LocationProtocol" || '//' || "LocationHostName" as "link_txt" from comdoc."DocflowSettings") l
      join rp."RP_Worker" w_ch on w_ch."VCode" = m."IdWorker"
      join rp."RP_Person" p_ch on w_ch."IdPerson" = p_ch."VCode"
      join rp."RP_PersonContact" pc_ch on p_ch."VCode" = pc_ch."Pcode" and pc_ch."IdTypeContact" = 6
      left join odata.exchange1cguids ex on m."HolidayTypeGuid" = ex.guid and ex.atype = 'TypeVacation' and ex.corg= p."COrg"
     left join aw."VTypeTimeWork" tw on m."TypeVacation" = tw."VCode"
where coalesce(m."DateBegPer",m."DateBeg")>= dt.bd and coalesce(m."DateBegPer",m."DateBeg") <=dt.ed and
            not exists (select 1 
               from "dfd"."UniversalDocument" AS "ud"
                     join comdoc."ReadListItem" "rl" on "ud"."VCode" = "rl"."DocCode"
                     join comdoc."DocflowLink" "dl" on "dl"."DocCode2" = p."VCode" and "dl"."DocCode1" = "ud"."VCode"
               where "rl"."DocflowUser" = pc_ch."Code" and
                     "ud"."TypeName" = 'NotificationLexema' and 
                     "ud"."Text" like '%'|| to_char(coalesce(m."DateBegPer",m."DateBeg")::date, 'DD.MM.YYYY') ||'%') 
             and 1 = coalesce((select "IdTypeBusy"
                                from rp."RP_WorkerMove" rpwm 
                                where rpwm."IdWorker" = w_ch."VCode"
                                     and (rpwm."DateEnd" is null 
                                          OR (now()::date <= coalesce(rpwm."DateEnd", '2100-01-01'::date)))
                                limit 1)
                              , 1)  

Таблица "#forInsNotification" представляет собой список логинов и текстов сообщений:

"DocflowUser" логин пользователя, кому будет отправлено сообщение
"txt" текст сообщения
"Link" код документа для записи в Связанные документы
"DocType" тип связанного документа
"DocName" наименование связанного документа
"DocSubject" описание связанного документа
В cross join указывается количество дней за сколько до начала отпуска будет направляться уведомление (например 14)

После заполнения всех полей нажмите Сохранить и закрыть.

Заполненная рассылка

Далее необходимо настроить задачу c помощью планировщика (если не настроенно ранее) Уведомления Lexema.

Задача в шедулере

Задача отслеживает дату начала отпуска при заданных конфигурационных параметрах, и за указанное ранее количество дней отправляет пользователю уведомление. Оно появляется в Документообороте. В данном примере указано что 03.06.2022 было отправлено уведомление о начале отпуска сотрудника с 10.06.2022.

Уведомление

Внутри документа будет уведомление о приближающейся дате начала отпуска. В документ можно перейти по ссылке, или по вложенным документам.

Информационное письмо

Внутри документа можно сразу создать заявление на отпуск. Для этого нажмите на кнопку "Операции" и выберите "Создать заявление от сотрудника". Автоматически откроется документ "Заявления от сотрудника"

Операция создания заявления из уведомления

Настройки рассылки#

На данной вкладке в блоке заполняется при необходимости дополнительная информация:

Не создавать документ Уведомление при включенной функции уведомление будет направлено только на почту пользователю, без создания документа "Уведомления".

Email получателей - указывается электронная почта кому необходимо направить уведомление. Чтобы добавить несколько получателей необходимо нажать кнопку "+ Получателя". Во всплывающем окне выбрать дополнительных получателей и нажать "Добавить".

Получатель

Email копия - указывается электронная почта кому необходимо направить уведомление в копию. Добавление несколько получателей производится аналогично как добавление основных получателей.

По вопросу - указывается тема уведомления.

Документ - указывается наименование документа для отображения в системе.

Добавить ссылку на документ - при включенной галочке в текст уведомления добавляется ссылка на документ.

Текст для ссылки - в данном поле можно задавать свой текст для гиперссылки.

Исключить пользователей из рассылки выбираются пользователи, которые не должны получать уведомление по данной задаче.

Настройка рассылки

Ручное создание уведомления#

Для ручного создания уведомления, перейдите в Меню - Кадровый документооборот. Реестры - Уведомления. В открывшемся реестре необходимо нажать кнопку "Создать".

Реестр

В блоке "Основной текст" заполните необходимый текст уведомления.

Текст уведомления

В меню "Рассылка" добавьте и выберите пользователей, которым необходимо отправить уведомление, после чего нажмите кнопку "Отправить"

Список рассылки

В документообороте у пользователя, которому было направлено уведомление, появится соответствующий документ на обработку.

Уведомление

Для ознакомления с данным документом нажмите на кнопку "Рассылка" после этого внутри всплывающего окна кнопку"Подтвердить ознакомление"

Ознакомление

Примеры рассылок#

Уведомления об отпуске на основании Графика отпусков по внешним совместителям#

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker", "DateBeg", "Days", "TypeVacation", "Vacation", "DateEnd", "CopyTo")
select "User", "txt", "link", "TypeName", "DocName", "DocSubject"
, "IdWorker"
, "DateBeg", "Days", "TypeVacation", "Vacation", "DateEnd", "CopyTo"
from (
    select distinct pc_ch."Code" as "User", '<font size="4"> </font><p style="text-align: center;">' || p_ch."Name" || ' ' || coalesce(p_ch."Father", '') || ', добрый день!</p><p style="text-align: center;"><br></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;На основании
статьи 123 Трудового кодекса Российской Федерации и согласно утвержденному&nbsp;графику отпусков на ' || p."Year"::text ||' год информируем о дате начала Вашего оплачиваемого отпуска (<b>' ||  coalesce(tw."Name",ex.name1c,'')||') </b> с <strong>' || to_char(coalesce(m."DateBegPer",m."DateBeg")::date, 'DD.MM.YYYY') ||  '</strong> сроком на <strong>' || coalesce(m."DaysPer",m."Days")::text
|| '</strong> календарных
дня(ей). Дата выхода на работу <strong>' ||to_char((coalesce(m."DateEndPer",m."DateEnd") +  '1 day'::interval)::date, 'DD.MM.YYYY')  
|| '</strong>. В случае, если дата выхода на
работу приходится на выходной день, она переносится на ближайший рабочий день.</p>

<p>&nbsp;</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ВАЖНО! </p>

<p><em>В связи с
вышеизложенным Вам следует подать заявление о предоставлении отпуска для
своевременного проведения расчетов и подготовки соответствующих документов. </em></p>

<p><em>Если Вы не
планируете использовать отпуск в указанные даты, обязательно сформируйте
заявление о переносе отпуска. </em></p>

<p><strong>&nbsp;</strong></p>

<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Заявление на
отпуск или перенос отпуска необходимо сформировать в системе КЭДО Lexema при 
помощи кнопки «Операции» на панели инструментов данного
уведомления.</strong></p>

<p><strong>&nbsp;</strong></p>

<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Уведомление
можно закрыть только после выполнения одного из действий.</strong></p>

<p><br>
Приятного отдыха! </p>
<font size="4"></font>'   as txt,
    p."VCode" as "link",p."TypeName", 
null as "DocName" /*case when "TypeName" = 'Base.RP_DocVacationChanges' then 'Переносы отпусков' else 'График отпусков' end*/,
 null as "DocSubject", /*'Уведомление работника о времени начала отпуска',*/
 m."IdWorker",  coalesce(m."DateBegPer",m."DateBeg")::date as "DateBeg", coalesce(m."DaysPer",m."Days") as "Days", 
    m."HolidayTypeGuid" as "TypeVacation", coalesce(tw."Name",ex.name1c) as "Vacation", 
    coalesce(m."DateEndPer",m."DateEnd") as "DateEnd", null as "CopyTo", "IdTypeBusy", "IdPerson"
    from  aw."RP_DocVacation" p
          join aw."RP_WorkerVacation" m on p."VCode" = m."Pcode"
          cross join (select  (now() + '1 day'::interval)::date as bd,   (now() + '6 day'::interval)::date as ed  ) dt 
          cross join (select "LocationProtocol" || '//' || "LocationHostName" as "link_txt" from comdoc."DocflowSettings") l
          join rp."RP_Worker" w_ch on w_ch."VCode" = m."IdWorker"
          join rp."RP_WorkerMove" rpwm on rpwm."IdWorker" = w_ch."VCode"
          join rp."RP_Person" p_ch on w_ch."IdPerson" = p_ch."VCode"
          join rp."RP_PersonContact" pc_ch on p_ch."VCode" = pc_ch."Pcode" and pc_ch."IdTypeContact" = 6
          left join odata.exchange1cguids ex on m."HolidayTypeGuid" = ex.guid and ex.atype = 'TypeVacation' and ex.corg= p."COrg"
         left join aw."VTypeTimeWork" tw on m."TypeVacation" = tw."VCode"
    where coalesce(m."DateBegPer",m."DateBeg")>= dt.bd and coalesce(m."DateBegPer",m."DateBeg") <=dt.ed and
                not exists (select 1 
                   from "dfd"."UniversalDocument" AS "ud"
                         join comdoc."ReadListItem" "rl" on "ud"."VCode" = "rl"."DocCode"
                         join comdoc."DocflowLink" "dl" on "dl"."DocCode2" = p."VCode" and "dl"."DocCode1" = "ud"."VCode"
                   where "rl"."DocflowUser" = pc_ch."Code" and
                         "ud"."TypeName" = 'NotificationLexema' and 
                         "ud"."Text" like '%'|| to_char(coalesce(m."DateBegPer",m."DateBeg")::date, 'DD.MM.YYYY') ||'%') 
                 and (rpwm."DateEnd" is null 
                      OR (now()::date <= coalesce(rpwm."DateEnd", '2100-01-01'::date)))
                 and coalesce(rpwm."IdTypeBusy",1) = 3
        ) as v
        where not exists(select 1 
                            from aw."RP_WorkerVacation" t_wv
                                join rp."RP_Worker" t_w on t_w."VCode" = t_wv."IdWorker"
                                join rp."RP_WorkerMove" t_rpwm on t_rpwm."IdWorker" = t_w."VCode"
                                join rp."RP_Person" t_p on t_p."VCode" = t_w."IdPerson"
                            where t_p."VCode" = v."IdPerson"
                                and (t_rpwm."DateEnd" is null 
                                    OR (now()::date <= coalesce(t_rpwm."DateEnd", '2100-01-01'::date)))
                                and v."DateBeg" = coalesce(t_wv."DateBegPer",t_wv."DateBeg")
                                and v."Days" = coalesce(t_wv."DaysPer",t_wv."Days")
                                and coalesce(t_rpwm."IdTypeBusy",1) in (1,2)
                        )

Уведомления об отпуске на основании Графика отпусков по внутренним совместителям#

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker", "DateBeg", "Days", "TypeVacation", "Vacation", "DateEnd", "CopyTo")
select pc_ch."Code" as "User", '<font size="4"> </font><p style="text-align: center;">' || p_ch."Name" || ' ' || coalesce(p_ch."Father", '') || ', добрый день!</p><p style="text-align: center;"><br></p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;На основании
статьи 123 Трудового кодекса Российской Федерации и согласно утвержденному&nbsp;графику отпусков на ' || p."Year"::text ||' год информируем о дате начала Вашего оплачиваемого отпуска (<b>' ||  coalesce(tw."Name",ex.name1c,'')||') </b> с <strong>' || to_char(coalesce(m."DateBegPer",m."DateBeg")::date, 'DD.MM.YYYY') ||  '</strong> сроком на <strong>' || coalesce(m."DaysPer",m."Days")::text
|| '</strong> календарных
дня(ей). Дата выхода на работу <strong>' ||to_char((coalesce(m."DateEndPer",m."DateEnd") +  '1 day'::interval)::date, 'DD.MM.YYYY')  
|| '</strong>. В случае, если дата выхода на
работу приходится на выходной день, она переносится на ближайший рабочий день.</p>

<p>&nbsp;</p>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ВАЖНО! </p>

<p><em>В связи с
вышеизложенным Вам следует подать заявление о предоставлении отпуска для
своевременного проведения расчетов и подготовки соответствующих документов. </em></p>

<p><em>Если Вы не
планируете использовать отпуск в указанные даты, обязательно сформируйте
заявление о переносе отпуска. </em></p>

<p><strong>&nbsp;</strong></p>

<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Заявление на
отпуск или перенос отпуска необходимо сформировать в системе КЭДО Lexema по
соответствующей операции через кнопку «Операции» на панели инструментов данного
уведомления.</strong></p>

<p><strong>&nbsp;</strong></p>

<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Уведомление
можно закрыть только после выполнения одного из действий.</strong></p>

<p><br>
Приятного отдыха! </p>
<font size="4"></font>'   as txt,
p."VCode" as "link",p."TypeName", 
null /*case when "TypeName" = 'Base.RP_DocVacationChanges' then 'Переносы отпусков' else 'График отпусков' end*/,
 null, /*'Уведомление работника о времени начала отпуска',*/
 m."IdWorker", 
coalesce(m."DateBegPer",m."DateBeg")::date as "DateBeg", coalesce(m."DaysPer",m."Days") as "Days", 
m."HolidayTypeGuid", coalesce(tw."Name",ex.name1c), coalesce(m."DateEndPer",m."DateEnd") as "DateEnd", null as "CopyTo"
from  aw."RP_DocVacation" p
      join aw."RP_WorkerVacation" m on p."VCode" = m."Pcode"
      cross join (select  (now() + '1 day'::interval)::date as bd,   (now() + '6 day'::interval)::date as ed  ) dt 
      cross join (select "LocationProtocol" || '//' || "LocationHostName" as "link_txt" from comdoc."DocflowSettings") l
      join rp."RP_Worker" w_ch on w_ch."VCode" = m."IdWorker"
      join rp."RP_Person" p_ch on w_ch."IdPerson" = p_ch."VCode"
      join rp."RP_PersonContact" pc_ch on p_ch."VCode" = pc_ch."Pcode" and pc_ch."IdTypeContact" = 6
      left join odata.exchange1cguids ex on m."HolidayTypeGuid" = ex.guid and ex.atype = 'TypeVacation' and ex.corg= p."COrg"
     left join aw."VTypeTimeWork" tw on m."TypeVacation" = tw."VCode"
where coalesce(m."DateBegPer",m."DateBeg")>= dt.bd and coalesce(m."DateBegPer",m."DateBeg") <=dt.ed and
            not exists (select 1 
               from "dfd"."UniversalDocument" AS "ud"
                     join comdoc."ReadListItem" "rl" on "ud"."VCode" = "rl"."DocCode"
                     join comdoc."DocflowLink" "dl" on "dl"."DocCode2" = p."VCode" and "dl"."DocCode1" = "ud"."VCode"
               where "rl"."DocflowUser" = pc_ch."Code" and
                     "ud"."TypeName" = 'NotificationLexema' and 
                     "ud"."Text" like '%'|| to_char(coalesce(m."DateBegPer",m."DateBeg")::date, 'DD.MM.YYYY') ||'%') 
             and 2 = coalesce((select "IdTypeBusy"
                                from rp."RP_WorkerMove" rpwm 
                                where rpwm."IdWorker" = w_ch."VCode"
                                     and (rpwm."DateEnd" is null 
                                          OR (now()::date <= coalesce(rpwm."DateEnd", '2100-01-01'::date)))
                                limit 1)
                              , 1)

Документы не пришедшие на подписание в систему из 1С#

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker")
select distinct  rlU."DocflowUser" ,  'Следующие документы не пришли на подписание из 1С: :  <br/>' || 
         string_agg(dd."txt", ',  <br/>') ,
          null::bigint as "link", 'Первичный документ', 'Первичный документ',  
          'Информационное сообщение о документах, не пришедших из 1С', 
         (select w."VCode" 
            from rp."RP_Worker" w
                   join rp."RP_PersonContact" pc on w."IdPerson" = pc."Pcode" and pc."IdTypeContact" = 6 and pc."Code" = rlU."DocflowUser"
            order by w."DateBeg" desc
            limit 1
            ) as "IdWorker"
from (
    select r."name1c" || ' ' || "Workers" || ' (' || to_char(r."WDate"::date, 'DD.MM.YYYY')   || ')' || '<a href=' || l."link_txt" || '#/view/'|| r."TypeName" ||'Form' ||'/' ||  r."VCode" ||  '> перейти ' || l."link_txt" || '#/view/'|| r."TypeName" ||'Form' ||'/' ||  r."VCode" || '</a>' as txt
    from odata."getExchange1CGuidsRegistry"(null, null, null, null, null, null, null, null, null, null) r
        cross join (select "LocationProtocol" || '//' || "LocationHostName" as "link_txt" from comdoc."DocflowSettings") l
    where r."VCode" is not null and 
          r."DFS_VCode" is null and
      r."guid" is not null and
          r.name1c not ilike '%больнич%' and
          r. "DocumentDate" >= '20221001')
dd
         join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' and rl."DocTypes" ilike '%NotificationLexema%'
         join comdoc."ReadListGroupUsers" rlU on rl."VCode" = rlU."PCode"
group by    rlU."DocflowUser"   

Примечание

В строке join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' указывается наименование группы рассылки

1С

Напоминание об обработке документа руководителю на этапе "Согласование"#

with "approve" as
( select distinct   r."Initiator", i."StageUser",  r."DocName",  i."BeginDate",
    i."ActionDate", i."DaysForAction", r."DocType", 
    (select "LocationProtocol" || '//' || "LocationHostName" || coalesce(':'||"LocationPort",'') from comdoc."DocflowSettings" order by "CDate" desc limit 1)
    || '/#/view/' || se."DocForm" || '/' || r."DocCode" as "ref",
    r."DocCode",
    false as "Terminal", coalesce(dd."COrg", comdoc."getFilial"()) as "Org"
from comdoc."StageItem" i 
    join comdoc."RouteStage" st on st."VCode" = i."PCode"
    join comdoc."Route" r on r."VCode" = st."PCode"
    join dfd."UniversalDocument" dd on r."DocCode" = dd."VCode" AND r."DocType" = dd."TypeName"
    join comdoc."DocflowUser" du on i."StageUser" = du."UserName"
    join comdoc."DocflowUser" dui on r."Initiator" = dui."UserName"
    join comdoc."DocflowDocumentSettings" se on r."DocType" = se."DocType"
    left join dfd."DocumentConstructor" cons on dd."DocumentCategory" = cons."VCode"

where   (coalesce(st."IsMarked",false)!=true)
    AND r."RouteStatus" = 2
    AND i."StageItemStatus" = 2
    AND st."Status" = 2
    and "DocumentAction"= 1
    and st."StageName"='Согласование руководителем'
 )

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker")

 select a."StageUser"   as "DocflowUser",

 'Добрый день, ' || '<b> '|| du."SmallName" ||' </b>' ||'.   <br>' || 

 '<br>  Вам поступил документ на обработку.'||
'<br> Организация: ' || f."Name" ||
'<br> Задача: Согласовать' ||
'<br> Документ: ' || a."ref" ||
'<br> Предыдущий этап маршрута: Инициатор ' 
'<br>' || dui."SmallName" || '- Подписан ЭП ' 
  as "txt",
 null as "Link", null as "DocType", a."DocName" as "DocName", --это для физ уведомления
 'Lexema. ' || f."Name" || 'Согласовать. ' || a."DocName"  as "DocSubject",

 (select w."VCode" 
      from rp."RP_Worker" w
           join rp."RP_PersonContact" pc on w."IdPerson" = pc."Pcode" and pc."IdTypeContact" = 6 and pc."Code" = a."StageUser"
      order by w."DateBeg" desc
      limit 1
      ) as "IdWorker"
from "approve" a
    join comdoc."DocflowUser" du  on a."StageUser" = du."UserName"
    join comdoc."DocflowUser" dui on a."Initiator" = dui."UserName"
    join comdoc."VFilials" f on a."Org" = f."VCode"
where  now() > a."BeginDate" + '2 hour'::interval 
and  a."StageUser" = 'HRDirector'
;

Примечание

В строке and st."StageName"='Согласование руководителем' - указывается название этапа в шаблоне маршруте.

В строке and a."StageUser" = 'HRDirector' - указывается логин пользователя руководителя

Обработка документа

Об окончании испытательного срока#

В настройках учетной политики необходимо указать константу СЭД_Уведомления_Предупреждение_об_окончании_испытательного_срока и заполнить значение в календарных дней.

Константа

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker")
select distinct  rlU."DocflowUser" ,  '<font size="3"> <b>Уведомляем об окончании испытательного срока сотрудников :  </b> <br/>' || 
         string_agg(dd."txt", ',  <br/>') || '</font>' ,
          null::bigint as "link", 'Первичный документ', 'Первичный документ',  
          'Инф. сообщение об окончании испыт. срока', 
         (select w."VCode" 
            from rp."RP_Worker" w
                   join rp."RP_PersonContact" pc on w."IdPerson" = pc."Pcode" and pc."IdTypeContact" = 6 and pc."Code" = rlU."DocflowUser"
            order by w."DateBeg" desc
            limit 1
            ) as "IdWorker"
from (select  w."NameFull" || ' ' || coalesce(w."NumTab", '')  || ' (' || coalesce(dep."Name", '') || case when coalesce(wm."IdPost",0) <>0 then ', '  else '' end || coalesce(post."Name", '')  || case when coalesce(wm."IdPost",0) <>0 or coalesce(wm."IdDepartment",0) > 0 then ', '  else '' end || ' Испыт.срок: ' || wm."Probation"::text || 'мес. Дата приема: '||to_char(w."DateBeg", 'DD.MM.YYYY') || ')' as txt
from rp."RP_Worker" w
     join rp."RP_WorkerMove" wm on w."VCode" = wm."IdWorker" and now() between coalesce(wm."DateBeg", '20010101') and coalesce(wm."DateEnd", '20700101')
        left join comdoc."Department" dep on wm."IdDepartment" = dep."VCode"
left join rp."RP_Post" post on wm."IdPost" = post."VCode"
     LEFT JOIN LATERAL comdoc."getAccountingConstantValues"(w."COrg", 'СЭД_Уведомления_Предупреждение_об_окончании_испытательного_срока', NULL) cv on true
where now() between  (w."DateBeg" + (wm."Probation"::text || ' month')::interval) -  (coalesce(cv."valueConst",14)||' day')::interval   and   (w."DateBeg" + (wm."Probation"::text || ' month')::interval) and
      w."DateEnd" is null and 
          coalesce(wm."Probation",0) > 0
    )
dd
         join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' and rl."DocTypes" ilike '%NotificationLexema%'
         join comdoc."ReadListGroupUsers" rlU on rl."VCode" = rlU."PCode"
group by    rlU."DocflowUser"

Примечание

В строке join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' указывается наименование группы рассылки

Испытательный срок

Отсутствие планового графика отпусков по подразделению#

В настройках учетной политики необходимо указать константу срок подготовки планового графика отпусков и заполнить значение в календарных дней за сколько дней направлять руководителю уведомление.

with "chiefStruct" as
(select * from vac."SendingLateApplicationNotice"())
insert into "#forInsNotification" ("DocflowUser","CopyTo", "txt")   
select  /*main."ChiefLogin"*/ 'Loginovasa@lexema.ru', (select  DISTINCT string_agg(coalesce(ch."ChiefLogin",''),', ') from "chiefStruct" ch
                           where ch."IdWorker" = main."Chief" and main."ChiefLogin"<>coalesce(ch."ChiefLogin",'')),  
'Добрый день, ' || '<b>'||RTRIM(coalesce(du."FirstName",'') || ' ' || coalesce(du."MiddleName",''))||'</b>' ||
 '.   <br><br>' ||
 '<br> По следующим сотрудникам не сформированы заявки на отпуск на '||main."planYear"::text||' год:'||
 '<br><br>' ||
replace(
replace(replace(
'<table style = "border-collapse:collapse">
  <tr>
    <th style="text-align:center; border-left: 1px solid black; border-right: 1px solid black; border-bottom: 1px solid black; border-top: 1px solid black">Организация</th>
    <th style="text-align:center; border-right: 1px solid black; border-bottom: 1px solid black; border-top: 1px solid black">Подразделение</th>
    <th style="text-align:center; border-right: 1px solid black; border-bottom: 1px solid black; border-top: 1px solid black">Работник</th>
    <th style="text-align:center; border-right: 1px solid black; border-bottom: 1px solid black; border-top: 1px solid black">Должность</th>
  </tr>'||  
(SELECT DISTINCT string_agg(x."link", '') 
     FROM(select  '<tr><td style="text-align:center; border-left: 1px solid black; border-right: 1px solid black; border-bottom: 1px solid black">'||fil||'</td>
            <td style="text-align:center; border-right: 1px solid black; border-bottom: 1px solid black">'||dep||'</td>
            <td style="text-align:center; border-right: 1px solid black; border-bottom: 1px solid black;">'||fio||'</td>
            <td style="text-align:center; border-right: 1px solid black; border-bottom: 1px solid black;">'||post||'</td>
        </tr>' as "link" from (select distinct f."Name" as fil, coalesce(dep."Name",'') as "dep", coalesce(w."NameShort",w."NameFull",'') as fio , coalesce(rp."Name",'') as post
                         from "chiefStruct" p2 
                          left join rp."RP_Worker" w on w."VCode" = p2."IdWorker"         
                          left join comdoc."Department" dep on dep."VCode" = p2."IdDepartment"
                          left join rp."RP_Post" rp on rp."VCode" = p2."IdPost"
                          left join comdoc."VFilials" f on w."COrg" = f."VCode"
                          where coalesce(p2."ChiefLogin",'') = coalesce(main."ChiefLogin",'')) qw
                        order by fil, "dep", fio ) as x)||'</table>'
,'&lt;','<'),'&gt;','>'),
'&amp;','&') as "Body"
 from "chiefStruct" main
inner join comdoc."DocflowUser" du on main."ChiefLogin" = du."UserName"
group by  main."Chief", coalesce(du."FirstName",''), coalesce(du."MiddleName",''), main."ChiefLogin", main."planYear";

Отсутствие отпуска

Оповещение о необходимости замены паспорта#

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker")                  
select distinct  pc."Code" ,  '<font size="3"> <b>Настоящим сообщаем, что приближается срок замены паспорта </b> <br/>' || '</font>' ,
          null::bigint as "link", '', '',  
          'Инф. сообщение о замене паспорта', 
           w."VCode" as "IdWorker"
from rp."RP_Person" p
     join rp."RP_Worker" w on p."VCode" = w."IdPerson"
     join rp."RP_WorkerMove" wm on w."VCode" = wm."IdWorker" and now() between coalesce(wm."DateBeg", '20010101') and coalesce(wm."DateEnd", '20700101')
     left join comdoc."Department" dep on wm."IdDepartment" = dep."VCode"
     left join rp."RP_Post" post on wm."IdPost" = post."VCode"
     left join rp."RP_PersonContact" pc on p."VCode" = pc."Pcode" and pc."IdTypeContact" = 6
     LEFT JOIN LATERAL comdoc."getAccountingConstantValues"(w."COrg", 'СЭД_Уведомления_Сообщения_о_замене_паспорта', NULL) cv on true
where 
      now() between p."DateBirth" - (coalesce(cv."valueConst",30) || ' day')::interval + (date_part('year',age(p."DateBirth"))+1 || 'year')::interval and
                    p."DateBirth" + (date_part('year',age(p."DateBirth"))+1 || 'year')::interval and
      date_part('year',age(p."DateBirth" -  (coalesce(cv."valueConst",30) || ' day')::interval ))::int in (20,45)
Паспорт

Сообщения о приближающемся юбилее работы в компании#

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker")                  
select distinct  rlU."DocflowUser" ,  '<font size="3"> <b>Список юбиляров :  </b> <br/>' || 
         string_agg(dd."txt", ',  <br/>') || '</font>' ,
          null::bigint as "link", '', '',  
          'Инф. сообщение о юбилее работы в компании', 
         (select w."VCode" 
            from rp."RP_Worker" w
                   join rp."RP_PersonContact" pc on w."IdPerson" = pc."Pcode" and pc."IdTypeContact" = 6 and pc."Code" = rlU."DocflowUser"
            order by w."DateBeg" desc
            limit 1
            ) as "IdWorker"
from (select  w."NameFull" || ' ' || coalesce(w."NumTab", '')  || ' (' || coalesce(dep."Name", '') 
             || case when coalesce(wm."IdPost",0) <>0 then ', '  else '' end || coalesce(post."Name", '') 
             || ' Дата приема: '||to_char(w."DateBeg", 'DD.MM.YYYY') || ')' as txt
from rp."RP_Worker" w 
     join rp."RP_WorkerMove" wm on w."VCode" = wm."IdWorker" and now() between coalesce(wm."DateBeg", '20010101') and coalesce(wm."DateEnd", '20700101')
     left join comdoc."Department" dep on wm."IdDepartment" = dep."VCode"
     left join rp."RP_Post" post on wm."IdPost" = post."VCode"
     LEFT JOIN LATERAL comdoc."getAccountingConstantValues"(w."COrg", 'СЭД_Уведомления_Сообщения_о_юбилее_работы_в_компании', NULL) cv on true
where 
     w."DateEnd" is null  and
      date_part('year',age(w."DateBeg"- (coalesce(cv."valueConst",30) || ' day')::interval))::int >1 and
          date_part('year',age(w."DateBeg" - (coalesce(cv."valueConst",30) || ' day')::interval))::int % 5 = 0 and
now() between w."DateBeg" - (coalesce(cv."valueConst",30) || ' day')::interval + (date_part('year',age(w."DateBeg"))+1 || 'year')::interval and
                    w."DateBeg" + (date_part('year',age(w."DateBeg"))+1 || 'year')::interval) dd
         join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' and rl."DocTypes" ilike '%NotificationLexema%'
         join comdoc."ReadListGroupUsers" rlU on rl."VCode" = rlU."PCode"
group by    rlU."DocflowUser"                                       

Примечание

В строке join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' указывается наименование группы рассылки

Юбилей в компании

Сообщение о приближающихся юбилеях#

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker")                  
select distinct  rlU."DocflowUser" ,  '<font size="3"> <b>Список юбиляров :  </b> <br/>' || 
         string_agg(dd."txt", ',  <br/>') || '</font>' ,
          null::bigint as "link", '', '',  
          'Инф. сообщение о юбилярах', 
         (select w."VCode" 
            from rp."RP_Worker" w
                   join rp."RP_PersonContact" pc on w."IdPerson" = pc."Pcode" and pc."IdTypeContact" = 6 and pc."Code" = rlU."DocflowUser"
            order by w."DateBeg" desc
            limit 1
            ) as "IdWorker"
from (select  w."NameFull" || ' ' || coalesce(w."NumTab", '')  || ' (' || coalesce(dep."Name", '') 
             || case when coalesce(wm."IdPost",0) <>0 then ', '  else '' end || coalesce(post."Name", '') 
             || ' Дата рождения: '||to_char(p."DateBirth", 'DD.MM.YYYY') || ')' as txt
from rp."RP_Person" p
     join rp."RP_Worker" w on p."VCode" = w."IdPerson"
     join rp."RP_WorkerMove" wm on w."VCode" = wm."IdWorker" and now() between coalesce(wm."DateBeg", '20010101') and coalesce(wm."DateEnd", '20700101')
     left join comdoc."Department" dep on wm."IdDepartment" = dep."VCode"
     left join rp."RP_Post" post on wm."IdPost" = post."VCode"
     LEFT JOIN LATERAL comdoc."getAccountingConstantValues"(w."COrg", 'СЭД_Уведомления_Сообщения_о_юбилярах', NULL) cv on true
where 
      now() between p."DateBirth" - (coalesce(cv."valueConst",30) || ' day')::interval + (date_part('year',age(p."DateBirth"))+1 || 'year')::interval and
                    p."DateBirth" + (date_part('year',age(p."DateBirth"))+1 || 'year')::interval and
      date_part('year',age(p."DateBirth" -  (coalesce(cv."valueConst",30) || ' day')::interval ))::int % 5 = 0
        ) dd
         join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' and rl."DocTypes" ilike '%NotificationLexema%'
         join comdoc."ReadListGroupUsers" rlU on rl."VCode" = rlU."PCode"
group by    rlU."DocflowUser"                   

Примечание

В строке join comdoc."ReadListGroup" rl on rl."Name" = 'Рассылка для менеджера по персоналу' указывается наименование группы рассылки

Юбилей