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.

759 lines
33 KiB

#!/usr/bin/php -q
<?php
/* * *****************************************************************************************
* Data: 15/05/2015.
* Autor: Amarildo Pereira
* Descri<EFBFBD><EFBFBD>o: Prove dados para sincroniza<EFBFBD><EFBFBD>o de informa<EFBFBD><EFBFBD>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<EFBFBD>o
* devera acessar o banco de diponibilizar os dados em memoria para sincroniza<EFBFBD><EFBFBD>o das
* aplicac<EFBFBD>es clientes.
*
* Funcoes:
* -sGetConnection -> Retorna uma conex<EFBFBD>o para o banco de dados.
* -sGravaLog -> Grava log de erros gerados pelo servi<EFBFBD>o.
* -sCreateMemory -> Aloca memoria para sincroniza<EFBFBD><EFBFBD>o de dados.
* ***************************************************************************************** */
error_reporting(E_ERROR);
ini_set('display_errors', 0);
ini_set("memory_limit", "512M");
/*
* Inclui fun<EFBFBD>oes gen<EFBFBD>ricas.
*/
include("util/util.php");
include("util/sharedMem.php");
include("util/funcoesSsupervisor.php");
/*
* Para rodar como um processo normal <EFBFBD> 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<EFBFBD>o for informado.
*/
GetDaemon($notDaemon);
/*
* Conex<EFBFBD>o com o banco de dados.
*/
$conn = false;
/*
* Log do sistema
*/
$patLog = "/var/log/asterisk/ssupervisor.log";
/*
* Informa<EFBFBD><EFBFBD>es para controle
*/
$arDadosControle = array();
/*
* Indica que uma transa<EFBFBD><EFBFBD>o foi iniciada;
*/
$inTransaction = 0;
/*
* Armazena o n<EFBFBD>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<EFBFBD><EFBFBD>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<EFBFBD><EFBFBD>es de erro ou outras mensagens.
*/
$gNumErros = 0;
$gArMsg = array();
$gUltMsg = '';
$idMsg = 0;
/*
* Cria segmento de memoria compartilhada.
* Controle -> Guarda a posi<EFBFBD><EFBFBD>o de escrita de um agente ou dac.
* O tamanho da memosia <EFBFBD> calculado com base no espaco para mensagens(102400) e o restante
* o espa<EFBFBD>o necessario para as informa<EFBFBD><EFBFBD>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<EFBFBD>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<EFBFBD>o com o banco de dados.
*/
if (!$conn) {
$conn = sGetConnection();
}
/*
* Basicamente copia os dados da tabela supervisor agentes, e informa<EFBFBD><EFBFBD>es d
* as filas para memoria
*/
$gOlDac = SetDadosDac($conn, $shmKeyDac, $gOlDac);
/*
* Basicamente copia os dados da tabela supervisor agentes, e informa<EFBFBD><EFBFBD>es d
* as filas para memoria
*/
$gOldAgt = SetDadosAgente($conn, $shmKeyAgt, $gOldAgt);
/*
* Encerra a conexao com banco de dados.
*/
pg_close($conn);
$conn = false;
} 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<EFBFBD><EFBFBD>es.
*/
usleep(TEMPO_CICLO);
/*
* O numero de cliclose <EFBFBD> zerado para cada consulta
* das chamadas abandonadas sem retorno.
*/
$numCiclos++;
}
/*
* Fecha os blocos de mem<EFBFBD>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<EFBFBD>a rapidamente,
* levando em conta que o cliclo de atualiza<EFBFBD><EFBFBD>es <EFBFBD> muito
* r<EFBFBD>pido, poderia gerar uma s<EFBFBD>rie de grav<EFBFBD><EFBFBD>es desnecess<EFBFBD>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<EFBFBD>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<EFBFBD> monitorar esse pid para verificar se ainda ativo
*/
$PIDFile = fopen( "/var/lock/subsys/superivisor.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<EFBFBD>o diferente da padr<EFBFBD>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<EFBFBD>o foi poss<EFBFBD>vel estabelecer uma conex<EFBFBD>o com o banco de dados!");
}
return $conn;
}
function sSetTransaction($conn, $isolation = 'READ UNCOMMITTED') {
/*
* Muda o isolamento da transa<EFBFBD><EFBFBD>o.
*/
return true;
$query = "SET TRANSACTION ISOLATION LEVEL $isolation";
$result = pg_query($conn, $query);
if (!$result) {
GeraExcept("N<EFBFBD>o foi poss<EFBFBD>vel definir o isolamento da transa<EFBFBD><EFBFBD>o!");
}
}
function sBeginTransaction($conn) {
global $inTransaction;
/*
* Define o isolamento padr<EFBFBD>o para as transa<EFBFBD><EFBFBD>es.
*/
sSetTransaction($conn);
/*
* Inicia a Transacao
*/
$result = pg_query($conn, 'begin');
if (!$result) {
GeraExcept("N<EFBFBD>o foi poss<EFBFBD>vel iniciar uma transa<EFBFBD><EFBFBD>o!");
}
$inTransaction = 1;
}
function sCommitTransaction($conn) {
global $inTransaction;
/*
* Fianaliza a Transacao corrente.
*/
$result = pg_query($conn, 'commit');
if (!$result) {
GeraExcept("N<EFBFBD>o foi poss<EFBFBD>vel finalizar a transa<EFBFBD><EFBFBD>o!");
}
$inTransaction = 0;
}
function sRollbackTransaction($conn) {
global $inTransaction;
/*
* Cancela a transasa<EFBFBD><EFBFBD>o corrente.
*/
if ($inTransaction) {
pg_query($conn, 'rollback');
}
}
function SetDadosDac($conn, $shmKeyDac, $oldDac = array()) {
try {
/*
* Inicia uma transa<EFBFBD><EFBFBD>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<EFBFBD>o foi poss<EFBFBD>vel consultar os dados do supervisor!");
}
/*
* Finaliza a transa<EFBFBD><EFBFBD>o.
*/
sCommitTransaction($conn);
while ($dados = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$dac = $dados['dac'];
/*
* Pega as chamadas abandonada para fila que n<EFBFBD>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<EFBFBD>o foi poss<EFBFBD>vel gravar os dados do supervisor!");
}
return $arDadosDac;
} catch (Exception $ex) {
/*
* Cancela a transa<EFBFBD><EFBFBD>o no banco de dados.
*/
sRollbackTransaction($conn);
/*
* Regera a excessao para o controle da aplida<EFBFBD><EFBFBD>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<EFBFBD><EFBFBD>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<EFBFBD><EFBFBD>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<EFBFBD><EFBFBD>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<EFBFBD>o foi poss<EFBFBD>vel consultar os dados do agente!");
}
/*
* Finaliza a transa<EFBFBD><EFBFBD>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<EFBFBD><EFBFBD>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<EFBFBD>o foi poss<EFBFBD>vel gravar os dados dos agentes!");
}
return $arDadosAgente;
} catch (Exception $ex) {
/*
* Se ocorrerem erros no banco de dados cancela a transa<EFBFBD><EFBFBD>o.
*/
sRollbackTransaction($conn);
/*
* Devolve o controle de erros para a aplica<EFBFBD><EFBFBD>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,
media,
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')
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<EFBFBD> 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<EFBFBD>o foi poss<EFBFBD>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
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
,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
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_dacs 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
) AS DADOS ORDER BY 1
) a on e.dac = a.dac order by 2";
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,
(select count(*) from pbx_nao_classificado where fila = a.dac and data_bilhete = a.data) as nao_classificado, id_dac,
(select count(*) from pbx_supervisor_agentes where dac = e.dac) as num_agente, 1 as ord
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
FROM (
SELECT DATA,
DAC, ID_DAC
,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
FROM (
SELECT D.NOME AS DAC, d.id as ID_DAC, a.calldate::date AS DATA, a.calldate,b.fila,b.evento,b.param1,b.param2,b.param3,b.param4,
case when(evento = 'TRANSBORDADO')then 1 else 0 end as transbordada
FROM ast_eventos_dacs b INNER JOIN ast_bilhetes a on a.uniqueid = b.uid2 and a.lastapp <> 'Transferred Call'
INNER JOIN pbx_dacs 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')
AND a.data_bilhete = now()::date
) AS DADOS
GROUP BY DATA, DAC, ID_DAC
) 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;
}
?>