Как стать автором
Обновить
0
True Engineering
Лаборатория технологических инноваций

Сервис управления заявками на отпуска для SharePoint 2013 в интеграции с БОСС-Кадровик

Время на прочтение 8 мин
Количество просмотров 12K
Полгода назад мы рассказывали о том, как реализовали сервис бронирования переговорных комнат у крупного заказчика с территориально разнесенными офисами и штатом несколько тысяч человек. Мы продолжаем работать с SharePoint-порталом этой компании, в рамках его развития специалисты EastBanc Technologies создали еще один модуль — сервис управления заявками на отпуска в интеграции с автоматизированной системой управления персоналом БОСС-Кадровик.

Назначение этого сервиса, как нам кажется, не нуждается в пространном разъяснении: попросту говоря, сервис автоматизирует учет отпусков в компании. Гораздо интересней, какие практические задачи стояли перед нами в данной конкретной компании, об этом — дальше.

Анализ

В соответствии с ТК РФ, ежегодный основной оплачиваемый отпуск предоставляется работнику по истечении 6 месяцев с первого дня работы в компании, и затем каждый год на основании приказа о предоставлении отпуска, оформленного в соответствии с графиком отпусков. Каждый месяц работы «на счету» сотрудника копится 2,33 дня оплачиваемого отпуска. Оплачиваемый отпуск бывает: основным ежегодным, дополнительным, основным оплачиваемым отпуском авансом, дополнительным отпуском авансом. И отдельным типом идет административный отпуск.

Заявки на эти типы отпусков нам предстояло автоматизировать. В наши задачи входило:

  1. Предоставить сотрудникам удобный интерфейс на корпоративном портале для оформления и согласования заявок на отпуск. Сотрудник должен видеть, сколько свободных дней есть в его распоряжении, иметь возможность отправить заявку на согласование руководителю.
  2. Дать возможность руководителю сотрудника согласовывать заявки на отпуска в автоматическом режиме.
  3. Синхронизовать фактические данные с плановыми данными, которые есть у отдела персонала (хранятся в системе БОСС-Кадровик).
  4. Минимизировать бумажный документооборот.

С технической точки зрения нужно было учесть следующее:

  1. Сервис нужно было интегрировать в личный кабинет, сохранив стилистику и логику уже знакомого сервиса бронирования переговорок.
  2. Решение реализовывалось на MS SharePoint 2010, но все участники процесса разработки уже понимали необходимость перехода на 2013-ый, который позже провели специалисты EastBanc Technologies.

UI

Здесь все было просто: действовать в том же духе, что и с переговорками (картинки кликабельные, открывать в новом окне).


«Мой кабинет»: видим доступное нам количество дней отпуска на заданный период, собственные заявки и их статусы, а в разделе «Архив» — заявки подчиненных, также со статусами. Особняком стоит кнопка «Добавить заявку».


«Мой кабинет» сотрудника отдела кадров: здесь все то же самое, только добавляется раздел «Заявки на согласование», которые прилетают кадровику со всей компании.


Заявка на отпуск — с точки зрения сотрудника. Эту форму он заполняет и отправляет на согласование начальнику своего подразделения, после чего она летит кадровикам.


Заявка на отпуск от сотрудника — в таком виде она приходит непосредственному руководителю сотрудника (начальнику подразделения).


Заявка на отпуск от сотрудника — в таком виде она приходит кадровику после согласования у непосредственного руководителя сотрудника.


Годовой график отпусков по конкретно взятому отделу — как его видит кадровик.


График отпусков по отделу на месяц — как его видит кадровик.

Хранение заявок на портале

Для хранения информации о фактических и запланированных отпусках мы создали список в SharePoint:



Интеграция с БОСС-Кадровик

Информация в SharePoint поступает из системы БОСС-Кадровик по средством обмена файлами с помощью SharePoint Job. Так же информацию о согласованных заявках мы отправляем обратно в БОСС-Кадровик.

Для связывания табельного номера сотрудника с учетной записью в ActiveDirectory было добавлено поле employeeID и «прокинуто» в SharePoint при помощи User Profile Service:



Отдельной проблемой стал график отпусков, т.к. в списке фактических и запланированных отпусков порядка 100 тысяч строк, и определять сотрудника через User Profile Service было трудозатратно. Поэтому мы настроили Search Service Application, и при помощи измененного в SharePoint 2013 механизма KeywordQuery достаем всю необходимую информацию о пользователях:

ResultTableCollection rtc = null;

var kwq = new KeywordQuery(site)     {
   QueryText = String.Format(querySchema, employeeIdField, nameField, departmentField, department, officeField, office),
   ResultTypes = ResultType.RelevantResults,
   KeywordInclusion = KeywordInclusion.AllKeywords,
   HiddenConstraints = "scope:" + "\"People\""        
};

SearchExecutor se = new SearchExecutor();
rtc = se.ExecuteQuery(kwq);


Для соблюдения ТК РФ мы сделали проверку на заявку пользователя: длительность основного оплачиваемого отпуска кратна 7 дням, и один из отпусков должен длиться не менее двух недель. Помимо данной проверки добавлена дополнительная проверка на «свободные дни»: из БОСС-Кадровик приходит информация о планируемых командировках или отгулах — на эти дни подавать заявку на отпуск запрещено.
Также отпуска можно «складывать»: например, к основному оплачиваемому отпуску из 14 дней «прицепить» административный отпуск из 7 дней.

Форматы данных, которые использовались для обмена:

1. Фактический и запланированный отпуска (из БОСС-Кадровик и в БОСС-Кадровик — формат идентичный)

imployeeId;fromDate;toDate;type
59;2010-08-09 00:00:00;2010-08-22 00:00:00;0
59;2007-06-01 00:00:00;2007-06-15 00:00:00;0
59;2007-08-15 00:00:00;2007-09-04 00:00:00;0
59;2012-06-25 00:00:00;2012-07-15 00:00:00;0
59;2012-09-01 00:00:00;2012-09-07 00:00:00;0
59;2013-04-29 00:00:00;2013-05-06 00:00:00;0
59;2013-07-01 00:00:00;2013-07-21 00:00:00;0

2. Доступно дней для отпуска (из БОСС-Кадровик)

imployeeId;fromDate;toDate;mainVacationDays;additionalVacationDays
59;2013-06-20 00:00:00;2014-06-19 00:00:00;14,0000;3,0000
59;2012-06-20 00:00:00;2013-06-19 00:00:00;,0000;3,0000
59;2011-06-20 00:00:00;2012-06-19 00:00:00;,0000;3,0000
59;2008-06-20 00:00:00;2009-06-19 00:00:00;1,0000;,0000
59;2007-06-20 00:00:00;2008-06-19 00:00:00;3,0000;,0000

3. Информация о прогулах, отгулах, командировках (из БОСС-Кадровик)

imployeeId;fromDate;toDate;type
5236;2007-03-12 00:00:00;2007-03-16 00:00:00; Командировка
5249;2007-03-09 00:00:00;2007-03-18 00:00:00; Командировка
209;2007-03-19 00:00:00;2007-03-19 00:00:00; Выходной день родителей детей инвалидов

Реализация

Для реализации форм создания/редактирования/просмотра заявок мы переопределили стандартные диалоги редактирования элементов SharePoint в schema.xml соответствующего списка при помощи атрибута UseLegacyForm:

<Forms>
   <Form Type="DisplayForm" Url="DisplayForm.aspx" WebPartZoneID="Main" UseLegacyForm="TRUE" />
   <Form Type="EditForm" Url="EditForm.aspx" WebPartZoneID="Main" UseLegacyForm="TRUE" />
   <Form Type="NewForm" Url="NewForm.aspx" WebPartZoneID="Main" UseLegacyForm="TRUE" />
</Forms>


Как видно из определения, это по сути обычные aspx-страницы, но с уникальными content placeholder’ами.
Например для тэга title:

<asp:Content ID="Content1" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server">
  Заявление на отпуск
</asp:Content>


Более подробно описано здесь office.microsoft.com/en-us/sharepoint-designer-help/working-with-content-placeholder-controls-HA102265026.aspx

Для UI мы использовали jQuery UI.

Также во всплывающем окне просмотра заявки нам нужно было отображать историю согласования данной заявки. Для этого мы создали список «история согласования заявки» с lookup-полем на список заявок. И определили представление с использованием CAML-запроса:

<Query>
  <Where>
    <Eq>
      <FieldRef Name="Request" LookupId="TRUE" />
      <Value Type="Lookup">
        <GetVar Scope="Request" Name="Id"/>
      </Value>
    </Eq>
  </Where>          
  <OrderBy>
    <FieldRef Name="ID"></FieldRef>
  </OrderBy>
</Query>


Параметр Id (это Id из списка заявок) приходит из параметров запроса, что в общем-то понятно, т.к. ссылка, формируемая SharePoint на открытие формы просмотра элемента, выглядит следующим образом:

{$HttpVDir}/_layouts/15/listform.aspx?PageType=6&ListId={$List}&ID={$ID}


Далее для нашего списка истории согласования, его представления для конкретной заявки и aspx-страницы отображения заявки было объявлено xls-представление:

<File Path="RequestList/DisplayForm.aspx" Url="Lists/RequestList/DisplayForm.aspx">
      <View WebPartOrder="1" WebPartZoneID="Main" BaseViewID="2" List="$Resources:core,lists_Folder;/RequestHistoryList" >
        <![CDATA[
	  <webParts>
		  <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
			  <data>
				  <properties>
				          ....
					  <property name="XslLink" type="string">/_layouts/15/ETR.VacationRequest/xsl/history.xsl</property>
			                  ....
				  </properties>
			  </data>
		  </webPart>
	  </webParts>
	  ]]>
      </View>
    </File>


Из кода очевидно, что представление будет расположено на странице Lists/RequestList/DisplayForm.aspx в вебпарт зоне WebPartZoneID=«Main». Осталось лишь убедиться, что такая зона у нас присутствует на странице:

<WebPartPages:WebPartZone runat="server" FrameType="None" ID="Main" Title="loc:Main" />


С графиком отпусков мы пошли дальше, т.к. стандартное представление списка в виде календаря не устраивало ни нас, ни заказчика. Поэтому мы дали задание нашим дизайнерам, и они нарисовали этот красивый календарь:



Получив одобрение заказчика, мы принялись за работу: первым делом, по примеру нашего сервиса бронирования переговорок, мы написали WCF-сервис, который возвращает json и при этом работает в контексте SharePoint’a.

Определили DataContract:

[DataContract(Name = "Vacation")]
	public class Vacation
	{
        [DataMember(Name = "fromDate")]
		public DateTime FromDate { get; set; }

        [DataMember(Name = "toDate")]
        public DateTime ToDate { get; set; }

        [DataMember(Name = "type")]
        public int Type { get; set; }
	}

    [DataContract(Name = "employeeData")]
    public class EmployeeData
    {
        [DataMember(Name = "id")]
        public int Id { get; set; }

        [DataMember(Name = "name")]
        public string Name { get; set; }

        [DataMember(Name = "vacations")]
        public List<Vacation> Vacations { get; set; }
    }

    [DataContract(Name = "departmentData")]
    public class DepartmentData
    {
        [DataMember(Name = "name")]
        public string Name { get; set; }

        [DataMember(Name = "office")]
        public string Office { get; set; }

        [DataMember(Name = "employees")]
        public List<EmployeeData> Employees { get; set; }
    }


Собрали данные о пользователе при помощи KeywordQuery, а данные об отпусках при помощи несложного CAML-запроса. Сделали кастомную верстку и связке jQuery с KnockOut реализовали требуемый интерфейс.

Результат

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

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

Но больше всех выиграл, конечно, отдел кадров: во-первых, сервис подачи заявок на отпуск — это защита от случайных ошибок в цифрах, во-вторых, он существенно сокращает бумажный документооборот, который обычно неизбежно разрастается вокруг каждого отпускника, в-третьих, интеграция с БОСС-Кадровик позволяет кадровому отделу эффективно вести аналитический учет затрат на персонал и оплату труда.
Теги:
Хабы:
+1
Комментарии 8
Комментарии Комментарии 8

Публикации

Информация

Сайт
www.trueengineering.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия

Истории