You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

716 lines
27 KiB

#!/usr/bin/php -q
<?php
/* * *****************************************************************************************
* Data: 15/05/2015.
* Autor: Amarildo Pereira
* Descrição: Prove dados para sincronização de informações para agente e supervisor.
* Objetivo: Diminuir a concorrencia ao banco de dados, devido a cada agente ou super-
* visor fazerem consultas constantes para manter suas interfaces atualizadas. O serviço
* devera acessar o banco de diponibilizar os dados em memoria para sincronização das
* aplicacões clientes.
*
* Funcoes:
* -sGetConnection -> Retorna uma conexão para o banco de dados.
* -sGravaLog -> Grava log de erros gerados pelo serviço.
* -sCreateMemory -> Aloca memoria para sincronização de dados.
* ***************************************************************************************** */
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set("memory_limit", "512M");
/*
* Inclui funçoes genéricas.
*/
include("util/util.php");
include("util/sharedMem.php");
include("util/funcoesSsupervisor.php");
/*
* Para rodar como um processo normal é preciso passar "N" como primeiro parametro.
*/
$notDaemon = isset($argv[1]) && (strtoupper($argv[1]) === 'N');
/*
* Mostra o help quando passodo --help no primeiro argumento.
*/
GetSupervisorHelp();
/*
* Inicializa o daemom quando N não for informado.
*/
GetDaemon($notDaemon);
/*
* Conexão com o banco de dados.
*/
$conn = false;
/*
* Log do sistema
*/
$patLog = "/var/log/asterisk/ssupervisor.log";
/*
* Informações para controle
*/
$arDadosControle = array();
/*
* Indica que uma transação foi iniciada;
*/
$inTransaction = 0;
/*
* Armazena o número de ciclos, para controlar a consulta a
* chamdas abanconadas sem retorno, devera ser na ordem de
* 1 para 10 ou seja a cada 10 atualizações od supervisor
* faz uma para chamadas abandonadas sem retorno.
*/
$numCiclos = 0;
try {
declare(ticks=1);
$statusSignal = 0;
if (!$notDaemon) {
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");
pcntl_signal(SIGINT, "sig_handler");
}
sGravaLog(sprintf("Server Start: %s [ok]\n", date("Y-m-d H:i:s")));
/*
* Armazena dados da ultima consulta.
*/
$gOldAgt = array();
$gOlDac = array();
$gOldAbdsr = array();
/*
* Informações de erro ou outras mensagens.
*/
$gNumErros = 0;
$gArMsg = array();
$gUltMsg = '';
$idMsg = 0;
/*
* Cria segmento de memoria compartilhada.
* Controle -> Guarda a posição de escrita de um agente ou dac.
* O tamanho da memosia é calculado com base no espaco para mensagens(102400) e o restante
* o espaço necessario para as informações dos agentes pelos dacs.
*/
//$shmKeyCtrl = sCreateMemory(SHM_IPC_FILE_CONTROLE, array(102400,NUM_MAX_AGENTES_ON + NUM_MAX_DACS_ON, TAM_SEGMENTO_CONTROLE));
$shmKeyCtrl = sCreateMemory(SHM_IPC_FILE_CONTROLE, array(TAM_SEGMENTO_CONTROLE, 0, 0));
/*
* Cria segmento de memoria compartilhada.
* Dac -> Dados das filas de atendimento.
*/
$shmKeyDac = sCreateMemory(SHM_IPC_FILE_DAC, array(0, NUM_MAX_DACS_ON, TAM_SEGMENTO_DAC));
/*
* Cria segmento de memoria compartilhada.
* Agente -> Informaçoes sobre os PAs conectados.
*/
$shmKeyAgt = sCreateMemory(SHM_IPC_FILE_AGENTE, array(0, NUM_MAX_AGENTES_ON, TAM_SEGMENTO_AGENTE));
while (true) {
try {
/*
* Estabelece uma conexão com o banco de dados.
*/
if (!$conn) {
$conn = sGetConnection();
}
/*
* Basicamente copia os dados da tabela supervisor agentes, e informações d
* as filas para memoria
*/
$gOlDac = SetDadosDac($conn, $shmKeyDac, $gOlDac);
/*
* Basicamente copia os dados da tabela supervisor agentes, e informações d
* as filas para memoria
*/
$gOldAgt = SetDadosAgente($conn, $shmKeyAgt, $gOldAgt);
/*
* Encerra a conexao com banco de dados.
*/
// pg_close($conn);
$conn = null;
} catch (Exception $ex) {
/*
* Garante que a conexao ao banco seja reiniciada.
*/
//pg_close($conn);
$conn = false;
/**
* Registra a mensagem para o monitor.
*/
SeTinfoControle(TIPO_DADOS_MSG, $gUltMsg, true);
sGravaLog($ex->getMessage());
}
/*
* Verifica se o processo deve ser encerrado
*/
if (!$notDaemon && sig_status())
break;
/*
* Tempo do ciclo de atualizações.
*/
usleep(TEMPO_CICLO);
/*
* O numero de cliclose é zerado para cada consulta
* das chamadas abandonadas sem retorno.
*/
$numCiclos++;
}
/*
* Fecha os blocos de memória.
*/
ShmClose($shmKeyCtrl);
ShmClose($shmKeyDac);
ShmClose($shmKeyAgt);
sGravaLog(sprintf("Server Stop: %s [ok]\n", date("Y-m-d H:i:s")));
} catch (Exception $ex) {
sGravaLog($ex->getMessage());
}
function sGravaLog($log)
{
global $gUltMsg, $patLog, $shmKeyCtrl;
/*
* Controle para evitar que o log cresça rapidamente,
* levando em conta que o cliclo de atualizações é muito
* rápido, poderia gerar uma série de gravções desnecessários
* por exemplo perda de conexao.
*/
if ($log != $gUltMsg) {
$gUltMsg = $log;
/*
* Registra no arquivo de log do sistema.
*/
WriteLog(trim($log) . "\n", $patLog);
}
}
function GetDaemon($notDaemon)
{
/*
* Se o script não for chamado com daemon sai sem executar nada.
*/
if ($notDaemon) {
return 0;
}
$pid = pcntl_fork();
if ($pid) {
exit(0); //success
}
/* PIDFile SYSTEMD
* SYSTEMD irá monitorar esse pid para verificar se ainda ativo
*/
$PIDFile = fopen("/var/lock/subsys/supervisor.pid", "w+");
$pid = getmypid();
if ($pid == false) {
exit(1);
}
fwrite($PIDFile, $pid);
fclose($PIDFile);
// posix_setsid();
}
function GetSupervisorHelp()
{
global $argc, $argv;
$arg = isset($argv[1]) ? $argv[1] : '';
if ($argc && ((stripos($arg, '--h') !== false) || (stripos($arg, '-h') !== false) || (stripos($arg, '/h') !== false))) {
return displayUsage();
}
}
function displayUsage()
{
echo "-------------------------------------------------------------------------------------------------------\n";
echo "- Servico de sincronizacao de dados para o supervisor! -\n";
echo "-------------------------------------------------------------------------------------------------------\n";
echo "- Para rodar como um processo normal passe \"N\" como primeiro argumento:\"./ssupervisor.php N\"! -\n";
echo "- Para rodar como Daemon nao passe nenhum argumemento argumento:\"./ssupervisor.php \"! -\n";
echo "-------------------------------------------------------------------------------------------------------\n";
echo "\n";
exit(0);
}
//end displayUsage()
function sGetConnection()
{
/*
* Se precisar de uma conexão diferente da padrão, espcifique sua propria connection string.
* $connStr = sprintf("host='%s' port='%s' dbname='%s' user='%s' password='%s'", '127.0.0.1', '5432', 'pbx', 'contacte', 'ctepgSQL');
* $connStr = sprintf("host='%s' port='%s' dbname='%s' user='%s' password='%s'", '192.168.115.64', '5432', 'pbx', 'contacte', 'ctepgSQL');
*/
$connStr = '';
$connStr = !$connStr ? GetDefStrDb() : $connStr;
$conn = pg_connect($connStr);
if (!$conn) {
GeraExcept("Não foi possível estabelecer uma conexão com o banco de dados!");
}
return $conn;
}
function sSetTransaction($conn, $isolation = 'READ UNCOMMITTED')
{
/*
* Muda o isolamento da transação.
*/
return true;
$query = "SET TRANSACTION ISOLATION LEVEL $isolation";
$result = pg_query($conn, $query);
if (!$result) {
GeraExcept("Não foi possível definir o isolamento da transação!");
}
}
function sBeginTransaction($conn)
{
global $inTransaction;
/*
* Define o isolamento padrão para as transações.
*/
sSetTransaction($conn);
/*
* Inicia a Transacao
*/
$result = pg_query($conn, 'begin');
if (!$result) {
GeraExcept("Não foi possível iniciar uma transação!");
}
$inTransaction = 1;
}
function sCommitTransaction($conn)
{
global $inTransaction;
/*
* Fianaliza a Transacao corrente.
*/
$result = pg_query($conn, 'commit');
if (!$result) {
GeraExcept("Não foi possível finalizar a transação!");
}
$inTransaction = 0;
}
function sRollbackTransaction($conn)
{
global $inTransaction;
/*
* Cancela a transasação corrente.
*/
if ($inTransaction) {
pg_query($conn, 'rollback');
}
}
function SetDadosDac($conn, $shmKeyDac, $oldDac = array())
{
try {
/*
* Inicia uma transação com o banco de dados.
*/
sBeginTransaction($conn);
/*
* Pesquisa as ligacoes abandonadas sem retorno.
*/
$abdsr = GetAbdsr($conn);
$arDadosDac = [];
$query = GetQueryDac();
$result = pg_query($conn, $query);
if (!$result) {
GeraExcept("Não foi possível consultar os dados do supervisor!");
}
/*
* Finaliza a transação.
*/
sCommitTransaction($conn);
while ($dados = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$dac = $dados['dac'];
/*
* Pega as chamadas abandonada para fila que não tiveram retorno no dac.
*/
if (array_key_exists($dac, $abdsr)) {
$dados['abdsr'] = $abdsr[$dac];
} else {
$dados['abdsr'] = 0;
}
/*
* Armazena os dados por dac.
*/
$arDadosDac[$dac] = $dados;
}
/*
* Grava dados na memoria.
*/
ShmClear($shmKeyDac, 0, Malloc(array(0, NUM_MAX_DACS_ON, TAM_SEGMENTO_DAC)));
$sizeDac = ShmWriteVar($shmKeyDac, $arDadosDac, 0);
SeTinfoControle(TIPO_DADOS_DAC, $sizeDac);
if (!$sizeDac) {
GeraExcept("Não foi possível gravar os dados do supervisor!");
}
return $arDadosDac;
} catch (Exception $ex) {
/*
* Cancela a transação no banco de dados.
*/
sRollbackTransaction($conn);
/*
* Regera a excessao para o controle da aplidação.
*/
GeraExcept($ex->getMessage());
}
}
function GetDataSize($tipoDados)
{
global $arDadosControle;
return $arDadosControle[$tipoDados];
}
function GetAbdsr($conn)
{
global $gOldAbdsr, $numCiclos;
/*
* Faz a consulta a abandonadas sem retorno
* a cada n ciclos(CICLOS_ABSR) da consulta
* a informações para dac e agente.
*/
if (($numCiclos < CICLOS_ABSR) && (count($gOldAbdsr))) {
return $gOldAbdsr;
}
$numCiclos = 0;
$diasAbandon = GetDiasAbandonada($conn);
$abdsr = array();
$query = "SELECT b.fila, count(DISTINCT a.abdsr_uniqueid) AS qtde_fila
FROM pbx_abandonadas_semretorno a
INNER JOIN ast_eventos_dacs b ON b.uid2 = a.abdsr_uniqueid AND b.fila = a.abdsr_fila AND b.evento = 'ABANDON'
INNER JOIN ast_bilhetes c ON c.uniqueid = b.uid2
WHERE a.abdsr_data_hora_retorno IS NULL
AND a.abdsr_data >= (now()::date - $diasAbandon)
GROUP BY b.fila
ORDER BY 1";
$result = pg_query($conn, $query);
if (!$result) {
return array();
}
while ($dados = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$fila = trim($dados['fila']);
$abdsr[$fila] = $dados['qtde_fila'];
}
$gOldAbdsr = $abdsr;
return $abdsr;
}
function SetDadosAgente($conn, $shmKeyAgt, $oldAgt = array())
{
global $gOlDac;
try {
/*
* Esta variavel devera conter informações para atualizar o agente.
*/
$dadosMonitor = array(
"dac" => "", "qtde_fila" => 0, "duracao" => '00:00:00', "fone" => '-', "abandonadas" => '0', "tme" => '0', "tma" => '0', "atendidas_pa" => '0',
"num_protocolo" => '-', "ramal_monitor" => '', "dac_logado" => '-', "status_agente" => 'OFF', "tempo_logado" => '-', "uniqueid2" => 0, "tempo_atualiza" => 0,
"pausa_motivo_rt" => '-', "pausa_motivo_ausente" => 0, "uniqueid" => 0, 'matricula' => '-', "disponivel_atendimento" => 1, "uf_origem" => '', "mun_origem" => '',
"mun_id" => '0', "prefixo_fone" => '', "disponivelFila" => '1', "originadas_pa" => '0', "agente_anota_key" => "", "txt_cliente" => "", "chamada_classificado" => '2',
"chamada_classificado_txt" => '...', "chamada_classificado_exige" => '0', "prm_obs_pausaprod" => '0', "exibePesquisa" => '0', 'canal_transfer' => '', "abandonadasRet" => '0',
"tipo_ligacao" => '', "cont_identificador" => "", "status_discador" => 0, 'media' => 0, 'pa_fixo' => 0
);
$arDadosAgente = array();
/*
* Inicia a transacao no banco de dados.
*/
sBeginTransaction($conn);
/*
* Informações dos agentes obtidos da tabela pbx_supervisor_agentes.
* "tempo_logado";"fone";"status_agente";"duracao";"num_protocolo";"ramal_monitor";"uniqueid2";"tempo_atualiza";"pausa_motivo_rt";"uniqueid";"disponivel_atendimento";"chamada_classificado";"canal_transfer"
*/
$query = GetQueryAgenteRt();
$result = pg_query($conn, $query);
if (!$result) {
GeraExcept("Não foi possível consultar os dados do agente!");
}
/*
* Finaliza a transação.
*/
sCommitTransaction($conn);
while ($dados = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$agente = $dados["matricula"];
$arDadosMonitor = $dadosMonitor;
foreach ($dados as $key => $value) {
$arDadosMonitor[$key] = $value;
}
$chamadaAgt = $dados["originadas_pa"] + $dados["atendidas_pa"];
$arDadosMonitor['tma'] = SecondToStrTime($chamadaAgt ? round(($dados["tempo_atendimento"] / $chamadaAgt), 0) : 0);
$arDadosAgente[$agente] = $arDadosMonitor;
}
/*
* Informações sobre a fila de atendimento que o agente esta logado.
* campos constantes em $gOlDac: sel, dac, originadas, atendidas, abandonadas, espera, tempo_espera, tempo_nivel_servico, tipo, transbordando,
* transbordada, nao_classificado, id_dac, num_agente, ord
*/
$arInfoDac = array("atendidas" => "atendidas_pa", "originadas" => "originadas_pa", "tme" => "tme", "tma" => "tma", "abdsr" => "abandonadasRet", "abandonadas" => "abandonadas", "espera" => "qtde_fila");
$arInfoDac = array("tme" => "tme", "abdsr" => "abandonadasRet", "abandonadas" => "abandonadas", "espera" => "qtde_fila");
foreach ($arDadosAgente as $key => $infoAgt) {
$dac = $infoAgt["dac"];
if (!empty($gOlDac[$dac])) {
$arDac = $gOlDac[$dac];
foreach ($arInfoDac as $keyParam => $valParam) {
$infoAgt[$valParam] = $arDac[$keyParam];
}
$arDadosAgente[$key] = $infoAgt;
}
}
/*
* Grava os dados na memoria
*/
ShmClear($shmKeyAgt, 0, Malloc(array(0, NUM_MAX_AGENTES_ON, TAM_SEGMENTO_AGENTE)));
$sizeAgt = ShmWriteVar($shmKeyAgt, $arDadosAgente, 0);
SeTinfoControle(TIPO_DADOS_AGENTE, $sizeAgt);
if (!$sizeAgt) {
GeraExcept("Não foi possível gravar os dados dos agentes!");
}
return $arDadosAgente;
} catch (Exception $ex) {
/*
* Se ocorrerem erros no banco de dados cancela a transação.
*/
sRollbackTransaction($conn);
/*
* Devolve o controle de erros para a aplicação.
*/
GeraExcept($ex->getMessage());
}
}
function GetQueryAgenteRt()
{
return "SELECT a.dac,
a.ramal AS ramal_monitor,
a.matricula,
a.nome,
a.monitorar AS statusmonitorar,
a.intercalar AS statusintercalar,
( (EXTRACT(EPOCH FROM (now() - a.duracao)) / 60)) AS status_time,
a.disponivel_atendimento,
chamada_classificado,
(LOCALTIMESTAMP(0) - a.tempo_login) AS tempo_logado,
a.modo_atendimento,
a.origem_destino AS fone,
trim(status) AS status_agente,
CASE WHEN((a.status = 'PAUSA') AND (coalesce(a.motivo_pausa, '') <> ''))THEN a.status || '-' || upper(a.motivo_pausa) ELSE a.status END AS status,
(LOCALTIMESTAMP(0) - a.duracao) AS duracao,
protocolo AS num_protocolo,
uniqueid2,
extract(epoch FROM (NOW() - logado))::int AS tempo_atualiza,
trim(motivo_pausa) AS pausa_motivo_rt,
trim(uniqueid) AS uniqueid,
disponivel_atendimento,
chamada_classificado,
coalesce(canal_transfer, '') AS canal_transfer,
org_id,
tipo_ligacao, cont_identificador, status_discador,
(SELECT COUNT(*)
FROM ast_bilhetes x, ast_eventos_dacs y
WHERE y.uid2 = x.uniqueid
AND x.data_bilhete IN(a.tempo_login::date, NOW()::date)
AND y.fila = a.dac
AND y.agente = ('Agent/' || a.matricula)
AND y.evento IN('COMPLETAAGENT','COMPLETACALLER','TRANSFERORIG','BUSYS','NOANSWERS')
AND x.lastapp <> 'Transferred Call' ) AS originadas_pa,
(SELECT COUNT(*)
FROM ast_bilhetes x, ast_eventos_dacs y, ast_bilhetes_complemento z
WHERE y.uid2 = x.uniqueid
AND x.uniqueid = z.uniqueid2
AND z.direcao = 'fila-ramal'
AND x.data_bilhete IN(a.tempo_login::date, NOW()::date)
AND y.fila = a.dac
AND y.agente = ('Agent/' || a.matricula)
AND y.evento IN('COMPLETEAGENT','COMPLETECALLER', 'TRANSFER','COMPLETEAGENTRAMAL','COMPLETECALLERRAMAL')
AND x.lastapp <> 'Transferred Call' ) AS atendidas_pa,
(SELECT SUM(CASE WHEN ((y.evento = 'TRANSFER') OR (y.evento = 'TRANSFERORIG')) THEN strtoint(y.param4) ELSE strtoint(y.param2) END)
FROM ast_bilhetes x, ast_eventos_dacs y
WHERE y.uid2 = x.uniqueid
AND x.data_bilhete IN(a.tempo_login::date, NOW()::date)
AND y.fila = a.dac
AND y.agente = ('Agent/' || a.matricula)
AND y.evento IN('COMPLETEAGENT','COMPLETECALLER', 'TRANSFER','COMPLETEAGENTRAMAL','COMPLETECALLERRAMAL', 'COMPLETAAGENT','COMPLETACALLER','TRANSFERORIG')
AND x.lastapp <> 'Transferred Call') AS tempo_atendimento, (SELECT coalesce(pa_fixo, 0) FROM pbx_usuarios WHERE matricula = a.matricula) AS pa_fixo
FROM pbx_supervisor_agentes a
WHERE 1=1
ORDER BY a.dac, a.nome";
}
function SeTinfoControle($tipoDados, $dados, $silent = false)
{
global $shmKeyCtrl, $arDadosControle, $gNumErros, $gArMsg, $idMsg;
if ($tipoDados != TIPO_DADOS_MSG) {
$arDadosControle[$tipoDados] = $dados;
$arDadosControle["ultAtulizacao"] = time();
} else {
$arDadosControle["numErros"] = ++$gNumErros;
$arDadosControle["ultMsg"] = $gArMsg[$idMsg++] = substr($dados, 0, 1024);
$arDadosControle["ultRegMsg"] = date("Y-m-d H:i:s");
}
$arDadosControle["dataHora"] = date("Y-m-d H:i:s");
/*
* armazena até 100 mensagens.
*/
if ($idMsg > 99) {
$idMsg = 0;
}
/*
* Grava os dados na memoria.
*/
ShmClear($shmKeyCtrl, 0, Malloc(array(TAM_SEGMENTO_CONTROLE, 0, 0)));
if (!ShmWriteVar($shmKeyCtrl, $arDadosControle, 0)) {
if (!$silent) {
GeraExcept("Não foi possível gravar os dados do controle!");
}
}
}
function GetQueryDac()
{
return "SELECT DISTINCT coalesce(sel, 0) AS sel,
e.dac, coalesce(originadas_pa,0) AS originadas,
coalesce(a.atendidas, 0) AS atendidas,
coalesce(a.abandonadas::int, 0) AS abandonadas,
coalesce(e.espera::int, 0) AS espera,
( coalesce(e.tempo_espera::int, 0) * INTERVAL '1 SECOND') AS tempo_espera,
coalesce(e.tempo_espera::int, 0) AS tempo_espera_int,
( round(coalesce(a.inb,0),0)::text || '%') AS tempo_nivel_servico,
'D' AS tipo,
transbordando,
transbordada,
tme,
tma,
nao_classificado,
id_dac,
(SELECT count(*) FROM pbx_supervisor_agentes WHERE dac = e.dac) AS num_agente, 1 AS ord,
org_id
FROM pbx_supervisor_dacs e
LEFT JOIN (
SELECT 0 as sel, DAC, ID_DAC,
DATA,
ABANDONADAS
,ATENDIDAS_PA AS ATENDIDAS
,ORIGINADAS_PA
,ESPERA
,round( CASE WHEN(ESPERA = 0)THEN 0 ELSE (TEMPO_ESPERA / ESPERA) END ) * INTERVAL '1 SECOND' AS TME
,round( CASE WHEN(ATENDIDAS_PA = 0)THEN 0 ELSE (TEMPO_ATENDIMENTO / (ATENDIDAS_PA + ORIGINADAS_PA))END) * INTERVAL '1 SECOND' AS TMA
,round(CASE WHEN(ABANDONADAS = 0)THEN 0 ELSE (TEMPO_ABANDONO / ABANDONADAS) END) * INTERVAL '1 SECOND' AS TMAB
,(CASE WHEN((ATENDIDAS_PA::FLOAT + ABANDONADAS::FLOAT) = 0)THEN 0 ELSE ATENDIDAS_30::FLOAT / (ATENDIDAS_PA::FLOAT + ABANDONADAS::FLOAT) END * 100)::numeric(5,2) as INB
,(CASE WHEN(OFERECIDAS::FLOAT = 0)THEN 0 ELSE (ABANDONADAS::FLOAT / OFERECIDAS::FLOAT) END * 100)::numeric(5,2) as IAB
,TEMPO_ESPERA
,TEMPO_ATENDIMENTO
,TEMPO_ABANDONO
,TRANSBORDANDO
,TRANSBORDADA
,NAO_CLASSIFICADO
FROM (
SELECT DATA,
DAC, ID_DAC, org_id
,SUM (CASE WHEN EVENTO = 'ENTERQUEUE' THEN 1 ELSE 0 END) AS OFERECIDAS
,SUM (CASE WHEN EVENTO = 'ENTERQUEUE' THEN 1 ELSE 0 END) AS ATENDIDAS_URA
,SUM (CASE WHEN EVENTO = 'ABANDON' THEN 1 ELSE 0 END) AS ABANDONADAS
,SUM (CASE WHEN EVENTO IN ('COMPLETEAGENT','COMPLETECALLER', 'TRANSFER','COMPLETEAGENTRAMAL','COMPLETECALLERRAMAL') THEN 1 ELSE 0 END) AS ATENDIDAS_PA
,SUM (CASE WHEN EVENTO IN ('COMPLETAAGENT','COMPLETACALLER','TRANSFERORIG','BUSYS','NOANSWERS') THEN 1 ELSE 0 END) AS ORIGINADAS_PA
,SUM (CASE WHEN EVENTO IN ('COMPLETEAGENT','COMPLETECALLER', 'TRANSFER','COMPLETEAGENTRAMAL','COMPLETECALLERRAMAL') AND strtoint(param1) <= (SELECT a.tempo_nivel_servico FROM pbx_supervisor_dacs a WHERE a.dac = fila)::FLOAT THEN 1 ELSE 0 END) AS ATENDIDAS_30
,SUM (CASE WHEN EVENTO IN ('TRANSFER') THEN 1 ELSE 0 END) AS TRANSFERIDAS
,SUM (CASE WHEN EVENTO IN ('CONNECT') AND strtoint(param1) > '3' THEN 1 ELSE 0 END) AS ESPERA
,SUM (CASE WHEN (EVENTO IN ('CONNECT') AND strtoint(param1) > '3') THEN strtoint(param1) ELSE 0 END) AS TEMPO_ESPERA
,SUM (CASE WHEN EVENTO IN ('COMPLETEAGENT','COMPLETECALLER','TRANSFER','COMPLETEAGENTRAMAL','COMPLETECALLERRAMAL') AND strtoint((case when(param2 = '')then '0' else param2 end)) > '1' THEN strtoint((case when(param2 = '')then '0' else param2 end)) ELSE 0 END) AS TEMPO_ATENDIMENTO
,SUM (CASE WHEN EVENTO IN ('ABANDON') THEN strtoint(param3) ELSE 0 END) AS TEMPO_ABANDONO
,SUM (CASE WHEN EVENTO IN('TRANSBORDANDO') THEN 1 ELSE 0 END) AS TRANSBORDANDO
,SUM (transbordada) AS TRANSBORDADA
,SUM (CASE WHEN EVENTO IN ('COMPLETEAGENT','COMPLETECALLER', 'TRANSFER','COMPLETEAGENTRAMAL','COMPLETECALLERRAMAL') THEN nao_classificado ELSE 0 END) AS nao_classificado
FROM (
SELECT a.data_bilhete as data, b.fila as dac, d.id as id_dac, b.fila,b.evento,b.param1,b.param2,b.param3,b.param4,
case when(evento = 'TRANSBORDADO')then 1 else 0 end as transbordada, case when( exists( select '' from pbx_classifica_reg WHERE id_bilhetes = a.uniqueid) )then 0 else 1 end as nao_classificado,
d.org_id
FROM (select data_bilhete, uniqueid from ast_bilhetes where data_bilhete = now()::date and lastapp <> 'Transferred Call') a
INNER JOIN ast_eventos_dacs b on a.uniqueid = b.uid2
INNER JOIN pbx_queues_grupos d on d.nome = b.fila and d.status = 'A'
WHERE b.evento in ('ABANDON','COMPLETEAGENT','COMPLETECALLER', 'CONNECT','ENTERQUEUE','TRANSFER', 'COMPLETAAGENT','COMPLETACALLER', 'TRANSFERORIG', 'TRANSBORDANDO', 'TRANSBORDADO','COMPLETEAGENTRAMAL','COMPLETECALLERRAMAL','BUSYS','NOANSWERS')
) AS DADOS
GROUP BY DATA, DAC, ID_DAC, org_id
) AS DADOS ORDER BY 1
) a ON e.dac = a.dac ORDER BY 2";
}
function sig_handler($signo)
{
global $statusSignal;
$statusSignal = 1;
}
function sig_status()
{
global $statusSignal;
pcntl_signal_dispatch();
return $statusSignal;
}
?>