OmniBoard/app/Http/Controllers/Api/AmiEventController.php

149 lines
4.7 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Tenant;
use App\Models\Queue;
use App\Models\WaitingList;
use App\Models\DailyMetric;
use Carbon\Carbon;
class AmiEventController extends Controller
{
public function handle(Request $request)
{
// 1. Autenticação via Token (Header: X-Tenant-Token)
$token = $request->header('X-Tenant-Token');
$tenant = Tenant::where('api_key', $token)->first();
if (!$tenant) {
return response()->json(['error' => 'Unauthorized'], 401);
}
// 2. Dados do Evento
$data = $request->all();
$eventName = $data['Event'] ?? null;
$queueName = $data['Queue'] ?? null;
if (!$eventName || !$queueName) {
return response()->json(['status' => 'ignored']);
}
// DEPOIS (Correto)
$queue = Queue::where('tenant_id', $tenant->id)
->where('source_id', $queueName) // Procura "08000" na coluna source_id
->first();;
// Se a fila não existe no banco, ignoramos ou criamos automaticamente (opcional)
if (!$queue) {
return response()->json(['error' => 'Fila não encontrada'], 404);
}
// 4. Processar Lógica de Negócio
switch ($eventName) {
case 'QueueCallerJoin':
$this->handleJoin($queue, $data);
break;
case 'AgentConnect':
$this->handleConnect($queue, $data);
break;
case 'AgentComplete': // Ou QueueCallerLeave com TalkTime
$this->handleComplete($queue, $data);
break;
case 'QueueCallerAbandon':
$this->handleAbandon($queue, $data);
break;
}
return response()->json(['status' => 'success']);
}
// LÓGICA DE NEGÓCIO (A mesma do script anterior, mas agora com Eloquent)
private function handleJoin($queue, $data)
{
// Adiciona na Lista de Espera COM TENANT_ID
WaitingList::create([
'tenant_id' => $queue->tenant_id, // <--- ADICIONE ESTA LINHA
'queue_id' => $queue->id,
'caller_number' => $data['CallerIDNum'],
'caller_name' => $data['CallerIDName'] ?? 'Desconhecido',
'entered_at' => now(),
]);
// Incrementa Total do Dia
$this->updateMetric($queue, 'received_count', 1);
}
private function handleConnect($queue, $data)
{
// Remove da Lista de Espera
WaitingList::where('queue_id', $queue->id)
->where('caller_number', $data['CallerIDNum'])
->delete();
// Atualiza TME (Média Ponderada)
// Nota: Isso é simplificado. Em produção real, calcular média ponderada em SQL é melhor.
$metric = $this->getTodayMetric($queue);
$holdTime = intval($data['HoldTime'] ?? 0);
// Novo TME = ((Atual * Qtd) + Novo) / (Qtd + 1)
$newAvg = (($metric->avg_wait_time * $metric->answered_count) + $holdTime) / ($metric->answered_count + 1);
$metric->avg_wait_time = $newAvg;
$metric->answered_count += 1;
$metric->save();
}
private function handleComplete($queue, $data)
{
$talkTime = intval($data['TalkTime'] ?? 0);
$metric = $this->getTodayMetric($queue);
// Evita divisão por zero se o connect falhou
if ($metric->answered_count > 0) {
// Novo TMA = ((Atual * (Qtd-1)) + Novo) / Qtd
// Nota: Usamos Qtd (answered_count) como divisor pois a chamada já foi contada no Connect
$newAvg = (($metric->avg_talk_time * ($metric->answered_count - 1)) + $talkTime) / $metric->answered_count;
$metric->avg_talk_time = $newAvg;
$metric->save();
}
}
private function handleAbandon($queue, $data)
{
// Remove da Espera
WaitingList::where('queue_id', $queue->id)
->where('caller_number', $data['CallerIDNum'])
->delete();
// Incrementa Abandonos
$this->updateMetric($queue, 'abandoned_count', 1);
}
// Helpers
private function getTodayMetric($queue)
{
return DailyMetric::firstOrCreate(
[
'queue_id' => $queue->id,
'date' => Carbon::today()
],
[
'tenant_id' => $queue->tenant_id, // <--- O PULO DO GATO: Herda o ID da Fila
'received_count' => 0,
'answered_count' => 0,
'abandoned_count' => 0
]
);
}
private function updateMetric($queue, $field, $value)
{
$metric = $this->getTodayMetric($queue);
$metric->increment($field, $value);
}
}