forked from SimplesIP/pabx-app
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.
749 lines
33 KiB
749 lines
33 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_ERROR); |
|
ini_set('display_errors', 0); |
|
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; |
|
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 = 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 (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 |
|
} |
|
|
|
// 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(); |
|
$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, |
|
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é 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 |
|
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; |
|
} |
|
?>
|