moduleUtil = $moduleUtil; } protected function authorizeAccess(): void { $business_id = request()->session()->get('user.business_id'); TelemarketingUtil::authorizeTelemarketing($this->moduleUtil, $business_id, 'crm.telemarketing.view_assessments'); } public function callQuality() { $this->authorizeAccess(); $business_id = request()->session()->get('user.business_id'); if (request()->ajax()) { $query = CrmCallAssessment::join('users', 'crm_call_assessments.assessed_by', '=', 'users.id') ->join('crm_phone_follow_ups', 'crm_call_assessments.phone_follow_up_id', '=', 'crm_phone_follow_ups.id') ->where('crm_phone_follow_ups.business_id', $business_id) ->select( 'users.id as user_id', DB::raw("CONCAT(COALESCE(users.first_name, ''), ' ', COALESCE(users.last_name, '')) as agent_name"), DB::raw('AVG(crm_call_assessments.reception_score) as avg_reception'), DB::raw('AVG(crm_call_assessments.cooperation_score) as avg_cooperation'), DB::raw('COUNT(crm_call_assessments.id) as total_assessments'), DB::raw("SUM(CASE WHEN crm_call_assessments.gatekeeper_blocked = 1 THEN 1 ELSE 0 END) as gatekeeper_count") ) ->groupBy('users.id', 'users.first_name', 'users.last_name'); return Datatables::of($query)->make(true); } return view('crm::telemarketing.reports.call_quality'); } public function funnel() { $this->authorizeAccess(); $business_id = request()->session()->get('user.business_id'); $stats = [ 'total_phones' => CrmPhoneFollowUp::where('business_id', $business_id)->count(), 'contacted' => CrmPhoneFollowUp::where('business_id', $business_id)->whereIn('status', ['contacted', 'interested', 'converted'])->count(), 'interested' => CrmPhoneFollowUp::where('business_id', $business_id)->where('status', 'interested')->count(), 'converted' => CrmPhoneFollowUp::where('business_id', $business_id)->where('status', 'converted')->count(), 'companies' => CrmCompany::where('business_id', $business_id)->count(), ]; if (request()->ajax()) { return response()->json($stats); } return view('crm::telemarketing.reports.funnel')->with(compact('stats')); } public function agentPerformance() { $this->authorizeAccess(); $business_id = request()->session()->get('user.business_id'); if (request()->ajax()) { return $this->agentPerformanceQuery($business_id); } return view('crm::telemarketing.reports.agent_performance'); } public function agentPerformanceApi() { $business_id = auth()->user()->business_id; return response()->json([ 'success' => true, 'data' => $this->agentPerformanceQuery($business_id, false), ]); } protected function agentPerformanceQuery(int $business_id, bool $datatable = true) { $query = CrmCallSession::where('crm_call_sessions.business_id', $business_id) ->join('users', 'crm_call_sessions.user_id', '=', 'users.id') ->leftJoin('crm_phone_follow_ups', 'crm_call_sessions.phone_follow_up_id', '=', 'crm_phone_follow_ups.id') ->select( 'users.id as user_id', DB::raw("CONCAT(COALESCE(users.first_name, ''), ' ', COALESCE(users.last_name, '')) as agent_name"), DB::raw('COUNT(crm_call_sessions.id) as total_calls'), DB::raw("SUM(CASE WHEN crm_call_sessions.outcome = 'answered' THEN 1 ELSE 0 END) as answered"), DB::raw('AVG(TIMESTAMPDIFF(SECOND, crm_call_sessions.started_at, crm_call_sessions.ended_at)) as avg_duration'), DB::raw('AVG(crm_phone_follow_ups.lead_score) as avg_lead_score') ) ->whereNotNull('crm_call_sessions.ended_at') ->groupBy('users.id', 'users.first_name', 'users.last_name'); if ($datatable) { return Datatables::of($query)->make(true); } return $query->get(); } public function offerConversion() { $this->authorizeAccess(); $business_id = request()->session()->get('user.business_id'); if (request()->ajax()) { $query = CrmCompanyOffer::join('crm_companies', 'crm_company_offers.company_id', '=', 'crm_companies.id') ->join('crm_offer_catalog', 'crm_company_offers.offer_catalog_id', '=', 'crm_offer_catalog.id') ->where('crm_companies.business_id', $business_id) ->select( 'crm_offer_catalog.name', DB::raw('COUNT(crm_company_offers.id) as total'), DB::raw("SUM(CASE WHEN crm_company_offers.status = 'accepted' THEN 1 ELSE 0 END) as accepted"), DB::raw('SUM(crm_offer_catalog.estimated_value) as total_value') ) ->groupBy('crm_offer_catalog.id', 'crm_offer_catalog.name'); return Datatables::of($query)->make(true); } return view('crm::telemarketing.reports.offer_conversion'); } }