Учет опозданий сотрудников
Задача: вести статистику по опозданиям сотрудников.
Каждый руководитель хочет быть уверен в соблюдении правил внутреннего распорядка своими сотрудниками. Одним из критериев ответственности сотрудника является время появления на работе. Oktell позволяет автоматизировать эту проверку.
Содержание
Способы проверки
Существует несколько способов проверки появления сотрудника на работе. Рассмотрим их на примере. Пусть компания начинает работу в 9-00.
Способ 1. Проверка дозвоном.
Каждый день в 9-05 производится обзвон всех сотрудников. Если сотрудник снимает трубку, то считается, что он на рабочем месте.
Достоинства:
- Проверяет наличие сотрудника на рабочем месте
Недостатки:
- Вместо проверяемого сотрудника, трубку может снять его коллега.
- Возможность установить софтфон на телефоне, используя технологию SIP Forking, позволяет сотруднику взять трубку где угодно при наличии интернета. Однако, чаще всего сотрудники не знают паролей от своих устройств.
Способ 2. Проверка по клиентскому приложению.
В 9-05 служебный сценарий обращается в таблицу [oktell].[dbo].[A_CallCenter_UserStateHistory]. В этой таблице хранится время запуска клиентского приложения (столбец TimeEnter) и время, когда клиентское приложение было закрыто (столбец TimeLeave). Для того, чтобы использовать эту идею необходимо включенное клиентское приложение.
Достоинства:
- Не отвлекает сотрудника от работы
Недостатки:
- Клиентское приложение должно быть обязательно включено
- При наличии домена для веб-клиента или веб-оператора, сотрудник может отметиться, зайдя на веб-сервис со своего смартфона.
Способ 3. Смешанный вариант.
Если при проверке SQL-запросом сотрудник показан, как отсутствующий в системе (не включено клиентское приложение), то вполне возможно, что он забыл включить клиентское приложение или возникли технические неполадки. Если сотрудник отмечен как пользователь по умолчанию для своего телефона, то ему можно сделать дозвон и проверить на месте ли он находится.
Достоинства:
- Если у сотрудника не включено клиентское приложение, система пытается дозвонится до сотрудника.
Недостатки:
- Такие же, как у варианта 1 - трубку могут поднять другие сотрудники. Однако, этот вариант можно обработать отдельно и записать в отчет с особой пометкой.
В этой статье рассматривается смешанный вариант учета опозданий.
Создание таблицы
Предварительно создается таблица latecomers, в которой будет храниться вся информация по сотрудникам. Таблица имеет следующие поля:
- Id - номер записи в списке. Тип Int, создается автоматически.
- date - дата и время проверки. Тип Datetime.
- user - имя пользователя. Тип NVarchar (auto).
- status - результат проверки. Тип NVarchar (auto).
- time - время, с которого у пользователя включено клиентское приложение. Тип Datetime.
- iduser - идентификатор пользователя. Нужен для нахождения внутреннего номера. Тип NVarchar (auto).
Реализация сценария
Сценарий выглядит следующим образом:
Структурно сценарий состоит из
- SQL-запроса проверки включенных клиентских приложений
- Цикла по пользователям. Блок взят из статьи Построковая обработка sql выборки в сценарии (Вариант 1)
- Дозвон до пользователя и занесение результата
Компонент "Проверка по таблице" - SQL-запрос определяет запущено ли клиентское приложение у сотрудника и записывает результаты в таблицу.
with ausers as ( select getdate() ddt,us.Name,'На месте' status,uh.TimeEnter, us.ID from [oktell].[dbo].[A_CallCenter_UserStateHistory] uh inner join A_Users us on uh.operatorid=us.ID where GETDATE()>TimeEnter and (GETDATE()<TimeLeave or TimeLeave is null) and uh.State =0 ) insert into latecomers (date,[user],status,time,iduser) select * from ausers union all select getdate(),Name,'0',null, ID from A_Users where id not in (select id from ausers)
Компонент "id_before" - присваивает переменной id_before (строковая) значение "-1000". Нужен для перебора сотрудников в таблице latecomers, у которых еще нет статуса (не определены с прошлого шага).
Компонент "Определяем следующего" - SQL-запрос определяет следующего пользователя в таблице latecomers, которому нужно позвонить.
select top 1 @id=id, @iduser=iduser, @user=[user] from latecomers where id > @id_before and status='0' and cast(floor(cast(getdate() as float)) as datetime) = cast(floor(cast(date as float)) as datetime) set @rowcount=@@rowcount
где
- @id - переменная id_after (строковая). Переменная содержит номер найденного пользователя в таблице latecomers.
- @id_before - переменная id_before.
- @iduser - переменная iduser (строковая). Переменная содержит id пользователя.
- @rowcount - переменная rowcount (строковая). Переменная содержит количество найденных строк.
- @user - переменная user (строковая). Переменная содержит имя пользователя.
Компонент "Проверка на завершение" - определяет завершен ли перебор по пользователям. Сравнение переменной rowcount с "0".
Компонент "id_before=id_after" - переприсваивает переменную id_before, чтобы найти следующего пользователя. Также обнуляет переменную prefix.
- переменной idbefore присваивает переменную id_after
- переменной prefix присваивает пустую строку
Компонент "Внутренний номер по id" - SQL-запрос находит по таблице внутренний номер пользователя по его идентификатору iduser.
ВНИМАНИЕ: У пользователя должен быть "нативный" номер, то есть такой стандартный внутренний номер, в котором только один объект - данный пользователь. Иначе запрос не найдет внутренний номер этого пользователя.
SELECT TOP 1 @prefix=np.Prefix FROM A_NumberPlan np INNER JOIN A_NumberPlanAction npa ON np.ID=npa.NumID AND npa.ExtraId IN (SELECT RuleID FROM A_RuleRecords WHERE reactid=@userid AND InnerAddressType=0 AND RuleID IN (SELECT RuleID FROM A_RuleRecords GROUP BY RuleID HAVING COUNT(*)=1)) ORDER BY np.Prefix
где
- @prefix - переменная prefix, содержит внутренний номер пользователя
- @userid - переменная iduser
Компонент "Дозвон" - происходит дозвон до пользователя. Если пользователь поднимет трубку или занят (в разговоре) - считается, что он на месте.
- Номер/команда - prefix
- Среда - Внутренний номерной план
- Обслуживание - IVR
- Сценарий IVR - предварительно созданный IVR сценарий "Учет опозданий IVR". Сценарий достаточно простой - после того, как сотрудник берет трубку, связь обрывается. Здесь можно поставить звуковое оповещение сотрудника о том, что это проверка.
- Caller ID - "Proverka" (устанавливается по желанию, сотрудники будут видеть это название на табло телефона)
- Caller Name - "Proverka" (аналогично полю Caller ID)
- Очередь ожидания - Нет
- Время ожидания - 40 секунд. Максимальное время за которое сотрудник должен поднять трубку, чтобы система отметила его как на месте.
Компоненты "На месте" , "Занято" или "Нет на месте" - SQL-запросы для обновления статуса в таблице latecomers. Переход к этим компонентам происходит по веткам от предыдущего компонента "Дозвон". Соответственно:
update latecomers set status = 'На месте (Взял трубку)' where iduser=@iduser
update latecomers set status = 'На месте (Занято)' where iduser=@iduser
update latecomers set status = 'Нет на месте' where iduser=@iduser
где
- @iduser - переменная iduser (во всех запросах).
Создание служебной задачи
Результат работы
Запрос для создания таблицы:
USE [oktell] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[latecomers]( [Id] [int] IDENTITY(1,1) NOT NULL, [date] [datetime] NULL, [user] [nvarchar](2000) NULL, [status] [nvarchar](2000) NULL, [time] [datetime] NULL, [iduser] [nvarchar](2000) NULL, PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO