ecm-administrator-manuals/docs/Admin manuals/СЭД/Настройка внутрисистемных у.../Настройка внутрисистемных у...

46 KiB
Raw Blame History

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

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

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

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

Меню

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

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

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

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

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

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

Заполненный конструктор{: .zoom}

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

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

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

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

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

Настройки

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

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

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

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

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

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

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

Пример:

insert into "#forInsNotification" ("DocflowUser", "txt", "Link", "DocType", "DocName", "DocSubject", "IdWorker", "DateBeg", "Days", "TypeVacation", "Vacation", "DateEnd", "CopyTo", "txtSMS", "txtTelegram")
select pc_ch."Code" as "User", null 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, coalesce(m."DaysPer",m."Days"), m."HolidayTypeGuid", coalesce(tw."Name",ex.name1c), coalesce(m."DateEndPer",m."DateEnd") , null, null as "txtSMS", null as "txtTelegram"
from  aw."RP_DocVacation" p
      join aw."RP_WorkerVacation" m on p."VCode" = m."Pcode"
      cross join (select  (now() + '8 day'::interval)::date as bd,   (now() + '8 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 p."COrg" <> 4 and 
        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"
                     join dfd."DocumentAdditionalAttribute" atr on "ud"."VCode" = atr."PCode"
					 join dfd."DocumentCategoryAttributeType" atrtype on "atr"."CategoryAttributeType" = atrtype."VCode" and "ud"."DocumentCategory" = atrtype."PCode" and atrtype."AttributeType" = 'Date' and atrtype."ColumnName" = '#bdate#'
 			   where "rl"."DocflowUser" = pc_ch."Code" and 			        
					 "ud"."TypeName" = 'NotificationLexema' and 
                      atr."DateValue" = coalesce(m."DateBegPer",m."DateBeg") 
						 --"ud"."Text" like '%'|| to_char(coalesce(m."DateBegPer",m."DateBeg")::date, 'DD.MM.YYYY') ||'%'
						)   and
           w_ch."DateEDM" is not null and
           w_ch."DateEnd" is null and
--проверка на созданное заявление с завершенным маршрутом, на отпуск или на перенос
           not exists (select 1 
			   from "dfd"."UniversalDocument" AS "ud" 
                                      join dfd."DocumentAdditionalAttribute" atr on "ud"."VCode" = atr."PCode"
				      join dfd."DocumentCategoryAttributeType" atrtype on "atr"."CategoryAttributeType" = atrtype."VCode" and "ud"."DocumentCategory" = atrtype."PCode" and atrtype."AttributeType" = 'Date' and atrtype."ColumnName" = '#bdate#'
                                     join dfd."DocumentConstructor" dc on "ud"."DocumentCategory" = dc."VCode"
                                     join dfd."DocumentSubtype" ds on dc."DocumentSubtype" = ds."VCode"
                                    join comdoc."Route" r on ud."VCode" = r."DocCode" and ud."TypeName" = r."DocType" and r."RouteStatus" = 3
			   where "ud"."TypeName" = 'EmployeeStatement'  and
                                        "ud"."IdWorker" = m."IdWorker" and
                                         atr."DateValue" = coalesce(m."DateBegPer",m."DateBeg") and
                                         ds."InternalName" in ('EmployeeStatementVacation','EmployeeStatementTransperVacation') and
                                         ud."Removed" is not true and 
                                        not exists (select 1 from dfd."CancellationAct" a where a."DocCode" = ud."VCode" and a."DocType" = ud."TypeName") and
not exists (select 1  
from comdoc."Route" r
	join comdoc."RouteStage" rs on r."VCode" = rs."PCode"
	join comdoc."StageItem" si on rs."VCode" = si."PCode"
	inner join comdoc."DocflowDocumentSettings" as sts on sts."DocType" = r."DocType"
	inner join comdoc."DocflowDocumentSettingsDetail" as dfs on dfs."PCode" = sts."VCode" and 
																dfs."DocumentAction" = si."DocumentAction" and 
																dfs."DocumentStatus" = si."DocumentStatus"
where r."DocCode" =  "ud"."VCode" and 
      r."DocType" = p."TypeName" and
	  dfs."NegativeStatus" is true)
	  )
		

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

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

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

Заполненная рассылка{: .zoom}

Далее необходимо настроить [задачу](https://lexema-ecm.readthedocs.io/ru/latest/Admin manuals/service/sheduler/Config/) c помощью планировщика (если не настроенно ранее) Уведомления Lexema.

Задача в шедулере{: .zoom}

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

Уведомление

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

Информационное письмо{: .zoom}

Внутри документа можно сразу создать заявление на отпуск. Для этого нажмите на кнопку "Операции" и выберите "Создать заявление от сотрудника". Автоматически откроется документ ["Заявления от сотрудника"](../../../User manuals/Кадровый ЭДО/Заявления от сотрудников.md)

Операция создания заявления из уведомления{: .zoom}

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

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

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

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

Получатель

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

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

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

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

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

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

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

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

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

Реестр

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

Текст уведомления{: .zoom}

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

Список рассылки{: .zoom}

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

Уведомление{: .zoom}

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

Ознакомление{: .zoom}

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

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

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" = 'Рассылка для менеджера по персоналу' указывается наименование [группы рассылки](../Справочники/Документооборот/Группы рассылки/Группы рассылки.md)

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"='Согласование руководителем' - указывается название этапа в [шаблоне маршруте](../Настройка шаблонов маршрутов/Настройка шаблонов маршрутов.md).

  В строке `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" = 'Рассылка для менеджера по персоналу' указывается наименование [группы рассылки](../Справочники/Документооборот/Группы рассылки/Группы рассылки.md)

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

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

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

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)

![Паспорт](../Рассылки системы/media/passport.png)

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

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" = 'Рассылка для менеджера по персоналу' указывается наименование [группы рассылки](../Справочники/Документооборот/Группы рассылки/Группы рассылки.md)

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

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

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" = 'Рассылка для менеджера по персоналу' указывается наименование [группы рассылки](../Справочники/Документооборот/Группы рассылки/Группы рассылки.md)

Юбилей