ultimatepos/Modules/Crm/Http/Controllers/TelemarketingDashboardController.php

121 lines
4.9 KiB
PHP

<?php
namespace Modules\Crm\Http\Controllers;
use App\User;
use App\Utils\ModuleUtil;
use Carbon\Carbon;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\DB;
use Modules\Crm\Entities\CrmCallAssessment;
use Modules\Crm\Entities\CrmCallQueue;
use Modules\Crm\Entities\CrmCallSession;
use Modules\Crm\Entities\CrmCompany;
use Modules\Crm\Entities\CrmPhoneFollowUp;
use Modules\Crm\Utils\TelemarketingUtil;
class TelemarketingDashboardController extends Controller
{
protected $moduleUtil;
public function __construct(ModuleUtil $moduleUtil)
{
$this->moduleUtil = $moduleUtil;
}
protected function authorizeAccess(): void
{
$business_id = request()->session()->get('user.business_id');
TelemarketingUtil::authorizeTelemarketing($this->moduleUtil, $business_id, 'crm.telemarketing.supervisor_dashboard');
}
public function index()
{
$this->authorizeAccess();
return view('crm::telemarketing.dashboard.index');
}
public function stats()
{
$this->authorizeAccess();
$business_id = request()->session()->get('user.business_id');
$today = Carbon::today();
$activeCalls = CrmCallSession::where('business_id', $business_id)
->whereNull('ended_at')
->count();
$queueRemaining = CrmCallQueue::where('business_id', $business_id)
->whereIn('status', ['available', 'locked'])
->whereHas('phoneFollowUp', function ($q) {
$q->where('status', 'pending');
})
->count();
$todaySessions = CrmCallSession::where('business_id', $business_id)
->whereDate('started_at', $today)
->get();
$answered = $todaySessions->where('outcome', 'answered')->count();
$total = $todaySessions->count();
$topAgents = CrmCallSession::where('crm_call_sessions.business_id', $business_id)
->whereDate('crm_call_sessions.started_at', $today)
->join('crm_phone_follow_ups', 'crm_call_sessions.phone_follow_up_id', '=', 'crm_phone_follow_ups.id')
->join('users', 'crm_call_sessions.user_id', '=', 'users.id')
->select(
'users.id',
DB::raw("CONCAT(COALESCE(users.first_name, ''), ' ', COALESCE(users.last_name, '')) as name"),
DB::raw('COUNT(crm_call_sessions.id) as call_count'),
DB::raw('AVG(crm_phone_follow_ups.lead_score) as avg_lead_score')
)
->groupBy('users.id', 'users.first_name', 'users.last_name')
->orderByDesc('call_count')
->limit(10)
->get();
$agents = User::where('business_id', $business_id)->user()->count();
return response()->json([
'active_calls' => $activeCalls,
'queue_remaining' => $queueRemaining,
'agents_total' => $agents,
'today_total' => $total,
'today_answered' => $answered,
'answer_rate' => $total > 0 ? round(($answered / $total) * 100, 1) : 0,
'top_agents' => $topAgents,
'companies_count' => CrmCompany::where('business_id', $business_id)->count(),
'interested_today' => CrmPhoneFollowUp::where('business_id', $business_id)
->where('status', 'interested')
->whereDate('last_follow_up_at', $today)
->count(),
'avg_lead_score' => round((float) CrmPhoneFollowUp::where('business_id', $business_id)
->whereDate('last_follow_up_at', $today)
->whereNotNull('lead_score')
->avg('lead_score'), 1),
'outcomes' => CrmCallSession::where('business_id', $business_id)
->whereDate('started_at', $today)
->select('outcome', DB::raw('COUNT(*) as cnt'))
->groupBy('outcome')
->pluck('cnt', 'outcome'),
'live_sessions' => CrmCallSession::where('crm_call_sessions.business_id', $business_id)
->whereNull('crm_call_sessions.ended_at')
->join('crm_phone_follow_ups', 'crm_call_sessions.phone_follow_up_id', '=', 'crm_phone_follow_ups.id')
->join('users', 'crm_call_sessions.user_id', '=', 'users.id')
->select(
'crm_call_sessions.id',
'crm_phone_follow_ups.mobile_number',
'crm_phone_follow_ups.company_name',
DB::raw("CONCAT(COALESCE(users.first_name, ''), ' ', COALESCE(users.last_name, '')) as agent_name"),
'crm_call_sessions.started_at'
)
->orderBy('crm_call_sessions.started_at')
->get(),
'avg_assessment' => round((float) CrmCallAssessment::whereHas('callSession', function ($q) use ($business_id, $today) {
$q->where('business_id', $business_id)->whereDate('started_at', $today);
})->avg('reception_score'), 1),
]);
}
}