Примеры пользовательских процедур — различия между версиями
(не показано 7 промежуточных версии этого же участника) | |||
Строка 2: | Строка 2: | ||
__TOC__ | __TOC__ | ||
+ | |||
+ | Каждый раз когда задача выбирает абонента в исходящей задаче или поступает абонент по входящей, ей необходимо закрепить за ним оператора, который будет его обслуживать. Для этого используется опция "Вариант обхода операторов" в настройках задачи. Администраторы задачи могут выбрать один из 6 алгоритмов распределения или написать свой с помощью пользовательской процедуры. | ||
+ | |||
+ | Пользовательская процедура применяется в Call-центре для динамического распределения операторов внутри задачи. Процедура часто используется в тех случаях, когда каждому клиенту необходимо предоставлять различный набор операторов для обслуживания. В частности, формируемый список может зависеть от квалификации оператора и степени важности клиента. Нередко пользовательская процедура применяется для закрепления абонента за оператором, например в задачах с автоматическим перезвоном. | ||
+ | |||
+ | '''Техническая документация:''' [[Задачи:Ресурсы#procedura|Пользовательская процедура]] | ||
+ | |||
+ | Чтобы установить пользовательскую процедуру в задаче необходимо выполнить следующие шаги: | ||
+ | |||
+ | '''1.''' В настройках задачи на вкладке "'''Ресурсы'''" выберите "'''Вариант обхода операторов'''" - Пользовательская процедура. | ||
+ | |||
+ | |||
+ | [[Файл:Пример пользовательских процедур.png|center|600px]] | ||
+ | |||
+ | |||
+ | '''2.''' Измените текст хранимой процедуры A_TaskManager_OperatorsAll_Get_Custom. Запрос должен возвращать столбец с GUID-идентификаторами операторов в порядке уменьшения приоритета. Тип возвращаемых значений обязательно должен быть uniqueidentifier. В случае необходимости используйте функцию cast: | ||
+ | |||
+ | cast([user_id] as uniqueidentifier) | ||
+ | |||
+ | В процессе выделения оператора, задача пробегается по полученному от хранимой процедуры списку сверху вниз и берет первого доступного оператора, который работает по данной задаче (является ресурсом для данной задачи). В запросе вы можете использовать следующие входные переменные | ||
+ | *@idtask - идентификатор задачи | ||
+ | *@idlist - идентификатор таблицы абонентов | ||
+ | *@idabonent - номер абонента в списке, т.е. таблице абонентов по которой работает задача | ||
+ | *@idline - идентификатор внешней линии | ||
+ | *@dtnow - текущее время сервера | ||
+ | |||
+ | Чтобы пользовательская процедура срабатывала только для определенной задачи следует воспользоваться конструкцией ''if'': | ||
+ | |||
+ | if (@idtask = 'B77E5601-A103-4A41-B1FD-6E82EEB6B46A') | ||
+ | |||
+ | ID задачи можно узнать в таблице '''A_TaskManager_Tasks''' | ||
+ | |||
+ | |||
+ | Для изменения текста пользовательской процедуры используйте SQL Server Management Studio (SSMS). Найдите хранимую процедуру в списке и нажмите "Изменить". Запрос следует вставлять в специально предназначенное для этого место после комментария (см. рисунок). После изменения выполните запрос. | ||
+ | |||
+ | |||
+ | [[Файл:Перезвон-013.png|center|600px]] | ||
+ | |||
+ | |||
+ | Далее в статье представлены некоторые примеры пользовательских процедур, которые вы можете использовать для решения собственных задач. | ||
== Выбор оператора в зависимости от его приоритета == | == Выбор оператора в зависимости от его приоритета == | ||
− | + | Если в компании операторы имеют некоторое значение квалификации, можно настроить задачу таким образом, чтобы все поступающие абоненты приоритетно распределялись на менее опытных, а если они заняты - то на более опытных специалистов. Для этого создана таблица [oktell].[dbo].[Poryadok_operatory] с полями id (идентификатор оператора), name (имя оператора), mark (оценка квалификации). Хранимая процедура создана таким образом, что в случайном порядке берет менее опытных операторов с оценкой меньше 50, а затем добавляет к списку более опытных. | |
− | берет | + | |
− | + | ||
<pre> | <pre> | ||
− | + | if (@idtask = '703DDF3A-47E5-4C87-AF0C-5E90130819A8') | |
− | + | begin | |
− | + | select * | |
− | + | from ( | |
− | + | select top 1000 [id] | |
− | + | from [oktell].[dbo].[Poryadok_operatory] | |
− | + | where mark < 50 | |
− | + | order by NEWID() | |
− | + | ) a | |
− | + | ||
− | + | union all | |
− | + | ||
− | + | select * | |
− | + | from ( | |
+ | select top 1000 [id] | ||
+ | from [oktell].[dbo].[Poryadok_operatory] | ||
+ | where mark >= 50 | ||
+ | order by NEWID() | ||
+ | ) b | ||
+ | end | ||
</pre> | </pre> | ||
− | ==С закреплением оператора== | + | ==С закреплением оператора за абонентом== |
− | + | Данная пользовательская процедура позволяет прикрепить абонента за оператором. В таблице абонентов, по которой работает данная задача, должно быть поле operatorid. Для каждого абонента в этом поле указывается GUID-идентификатор прикрепленного оператора. Запрос работает таким образом, что если у абонента указан закрепленный за ним оператор, то возвращает только его GUID. Если закрепленного оператора нет возвращается список всех операторов в случайном порядке. | |
+ | |||
+ | Если вы используете данную процедуру для входящей задачи, то рекомендуется установить очередь ожидания. | ||
<pre> | <pre> | ||
− | + | if (@idtask = 'B8A22910-BFA4-480D-BFB1-151D0C06F93B') | |
− | + | begin | |
+ | select @Id = operatorid | ||
+ | from TableMain | ||
+ | where Id = @idabonent | ||
− | + | if (@Id is null) | |
− | + | begin | |
− | + | select u.Id | |
− | + | from A_Users u | |
− | + | inner join A_UserParams up on u.Id = up.Iduser | |
− | + | where IsOperator = 1 | |
− | + | order by NEWID() | |
− | + | end | |
− | + | else | |
− | + | begin | |
− | + | select @Id Id | |
− | + | end | |
− | + | end | |
− | + | ||
− | + | ||
− | + | ||
</pre> | </pre> | ||
− | ==С закреплением оператора и проверкой статуса == | + | ==С закреплением оператора за абонентом и проверкой статуса оператора == |
+ | |||
+ | Данная пользовательская процедура аналогична предыдущей с закреплением оператора, однако она также учитывает еще и текущий статус оператора. В таблице абонентов, по которой работает задача, должно быть поле idoperator. Для каждого абонента в этом поле указывается GUID-идентификатор прикрепленного оператора. Процедура учитывает статус оператора таким образом, что если его нет на месте или он не авторизован в клиентском приложении, то абонент распределяется на остальных операторов в случайном порядке. Если же оператор на месте, занят, в перерыве или недоступен, но у него включено клиентское приложение, считается, что он в системе, поэтому процедура выбирает только его. | ||
+ | |||
+ | Такой алгоритм изначально был реализован для исходящей задачи с перезвоном. Алгоритм позволяет обойти ситуацию, когда перезвон назначен, но ответственный оператор вдруг заболел. Тогда, задача распределяет перезвон на других операторов. | ||
<pre> | <pre> | ||
− | + | if (@idtask = 'B77E5601-A103-4A41-B1FD-6E82EEB6B46A') | |
− | + | begin | |
− | + | declare @state int | |
− | + | ||
− | + | select @ID = idoperator | |
− | + | from clients | |
− | + | where id = @idabonent | |
− | + | select top 1 @state = h.state | |
− | + | from A_Users u | |
− | + | left join ( | |
− | + | select h.* | |
− | + | from ( | |
− | + | select UserId | |
− | + | ,max(TimeChange) TimeChange | |
− | + | from A_UserStateHistory | |
− | + | group by UserId | |
− | + | ) t | |
− | + | join A_UserStateHistory h on t.UserId = h.UserId | |
− | + | and h.TimeChange = t.TimeChange | |
+ | ) h on h.UserId = u.Id | ||
+ | where u.id = @ID | ||
− | + | if ( | |
− | + | @state = 0 | |
− | + | or @state is null | |
− | + | ) | |
− | + | begin | |
− | + | select u.Id | |
− | + | from A_Users u | |
− | + | inner join A_UserParams up on u.Id = up.Iduser | |
− | + | where IsOperator = 1 | |
− | + | order by NEWID() | |
− | + | end | |
− | + | else | |
− | + | begin | |
− | + | select @ID Id | |
+ | end | ||
+ | end | ||
</pre> | </pre> |
Текущая версия на 12:43, 21 марта 2015
Содержание
Каждый раз когда задача выбирает абонента в исходящей задаче или поступает абонент по входящей, ей необходимо закрепить за ним оператора, который будет его обслуживать. Для этого используется опция "Вариант обхода операторов" в настройках задачи. Администраторы задачи могут выбрать один из 6 алгоритмов распределения или написать свой с помощью пользовательской процедуры.
Пользовательская процедура применяется в Call-центре для динамического распределения операторов внутри задачи. Процедура часто используется в тех случаях, когда каждому клиенту необходимо предоставлять различный набор операторов для обслуживания. В частности, формируемый список может зависеть от квалификации оператора и степени важности клиента. Нередко пользовательская процедура применяется для закрепления абонента за оператором, например в задачах с автоматическим перезвоном.
Техническая документация: Пользовательская процедура
Чтобы установить пользовательскую процедуру в задаче необходимо выполнить следующие шаги:
1. В настройках задачи на вкладке "Ресурсы" выберите "Вариант обхода операторов" - Пользовательская процедура.
2. Измените текст хранимой процедуры A_TaskManager_OperatorsAll_Get_Custom. Запрос должен возвращать столбец с GUID-идентификаторами операторов в порядке уменьшения приоритета. Тип возвращаемых значений обязательно должен быть uniqueidentifier. В случае необходимости используйте функцию cast:
cast([user_id] as uniqueidentifier)
В процессе выделения оператора, задача пробегается по полученному от хранимой процедуры списку сверху вниз и берет первого доступного оператора, который работает по данной задаче (является ресурсом для данной задачи). В запросе вы можете использовать следующие входные переменные
- @idtask - идентификатор задачи
- @idlist - идентификатор таблицы абонентов
- @idabonent - номер абонента в списке, т.е. таблице абонентов по которой работает задача
- @idline - идентификатор внешней линии
- @dtnow - текущее время сервера
Чтобы пользовательская процедура срабатывала только для определенной задачи следует воспользоваться конструкцией if:
if (@idtask = 'B77E5601-A103-4A41-B1FD-6E82EEB6B46A')
ID задачи можно узнать в таблице A_TaskManager_Tasks
Для изменения текста пользовательской процедуры используйте SQL Server Management Studio (SSMS). Найдите хранимую процедуру в списке и нажмите "Изменить". Запрос следует вставлять в специально предназначенное для этого место после комментария (см. рисунок). После изменения выполните запрос.
Далее в статье представлены некоторые примеры пользовательских процедур, которые вы можете использовать для решения собственных задач.
Выбор оператора в зависимости от его приоритета
Если в компании операторы имеют некоторое значение квалификации, можно настроить задачу таким образом, чтобы все поступающие абоненты приоритетно распределялись на менее опытных, а если они заняты - то на более опытных специалистов. Для этого создана таблица [oktell].[dbo].[Poryadok_operatory] с полями id (идентификатор оператора), name (имя оператора), mark (оценка квалификации). Хранимая процедура создана таким образом, что в случайном порядке берет менее опытных операторов с оценкой меньше 50, а затем добавляет к списку более опытных.
if (@idtask = '703DDF3A-47E5-4C87-AF0C-5E90130819A8') begin select * from ( select top 1000 [id] from [oktell].[dbo].[Poryadok_operatory] where mark < 50 order by NEWID() ) a union all select * from ( select top 1000 [id] from [oktell].[dbo].[Poryadok_operatory] where mark >= 50 order by NEWID() ) b end
С закреплением оператора за абонентом
Данная пользовательская процедура позволяет прикрепить абонента за оператором. В таблице абонентов, по которой работает данная задача, должно быть поле operatorid. Для каждого абонента в этом поле указывается GUID-идентификатор прикрепленного оператора. Запрос работает таким образом, что если у абонента указан закрепленный за ним оператор, то возвращает только его GUID. Если закрепленного оператора нет возвращается список всех операторов в случайном порядке.
Если вы используете данную процедуру для входящей задачи, то рекомендуется установить очередь ожидания.
if (@idtask = 'B8A22910-BFA4-480D-BFB1-151D0C06F93B') begin select @Id = operatorid from TableMain where Id = @idabonent if (@Id is null) begin select u.Id from A_Users u inner join A_UserParams up on u.Id = up.Iduser where IsOperator = 1 order by NEWID() end else begin select @Id Id end end
С закреплением оператора за абонентом и проверкой статуса оператора
Данная пользовательская процедура аналогична предыдущей с закреплением оператора, однако она также учитывает еще и текущий статус оператора. В таблице абонентов, по которой работает задача, должно быть поле idoperator. Для каждого абонента в этом поле указывается GUID-идентификатор прикрепленного оператора. Процедура учитывает статус оператора таким образом, что если его нет на месте или он не авторизован в клиентском приложении, то абонент распределяется на остальных операторов в случайном порядке. Если же оператор на месте, занят, в перерыве или недоступен, но у него включено клиентское приложение, считается, что он в системе, поэтому процедура выбирает только его.
Такой алгоритм изначально был реализован для исходящей задачи с перезвоном. Алгоритм позволяет обойти ситуацию, когда перезвон назначен, но ответственный оператор вдруг заболел. Тогда, задача распределяет перезвон на других операторов.
if (@idtask = 'B77E5601-A103-4A41-B1FD-6E82EEB6B46A') begin declare @state int select @ID = idoperator from clients where id = @idabonent select top 1 @state = h.state from A_Users u left join ( select h.* from ( select UserId ,max(TimeChange) TimeChange from A_UserStateHistory group by UserId ) t join A_UserStateHistory h on t.UserId = h.UserId and h.TimeChange = t.TimeChange ) h on h.UserId = u.Id where u.id = @ID if ( @state = 0 or @state is null ) begin select u.Id from A_Users u inner join A_UserParams up on u.Id = up.Iduser where IsOperator = 1 order by NEWID() end else begin select @ID Id end end