'api.home.browse', 'create' => 'api.home.create', 'update' => 'api.home.update', 'destroy' => 'api.home.destroy' ]; // Needed for notifications protected $showRoute = 'api.home.show'; protected $storeRequest = HomeApiRequest::class; protected $updateRequest = HomeApiRequest::class; protected $moduleName = 'reporting'; protected $SettingsHelper; public function __construct() { parent::__construct(); $this->SettingsHelper = new SettingsHelper(); } public function home(){ $user = auth()->user(); dd($user); } public function calls(Request $request) { try { $user = Auth::user(); $conds = $this->SettingsHelper->defaultConds(); if ($request->has('daterange')) { $range = explode(' - ', $request->daterange); $conds['from'] = Carbon::parse($range[0])->format('Y-m-d 00:00:00'); $conds['to'] = Carbon::parse($range[1])->format('Y-m-d 23:59:59'); } $query = DB::table('calls') ->leftJoin('calls_dict_direction', 'calls.direction_id', '=', 'calls_dict_direction.id') ->leftJoin('calls_dict_status', 'calls.status_id', '=', 'calls_dict_status.id') ->leftJoin('accounts', 'calls.account_id', '=', 'accounts.id') ->leftJoin('deals', 'calls.deal_id', '=', 'deals.id') ->leftJoin('contacts', 'calls.contact_id', '=', 'contacts.id') ->leftJoin('leads', 'calls.lead_id', '=', 'leads.id') ->leftJoin('users', 'calls.owned_by_id', '=', 'users.id') ->select( 'calls.id', 'calls.call_date', 'calls.phone_number', 'calls.duration', 'calls.ringtime', 'calls.talktime', 'calls.created_at', 'calls.updated_at', 'calls.linkedid', 'calls_dict_direction.name as direction', 'calls_dict_status.name as status', 'deals.name as deal_name', 'accounts.name as account_name', 'contacts.full_name as contact_name', 'leads.full_name as lead_name', 'calls.owned_by_id as user_id', 'users.name as user_name', ) ->orderBy('calls.created_at', 'DESC'); if ($user->hasRole('admin')) { } elseif ($user->hasRole('company_manager')) { $query->where('calls.company_id', $user->company_id); } else { $query->where('calls.owned_by_type', 'Modules\Platform\User\Entities\User') ->where('calls.owned_by_id', $user->id); } $query->whereBetween('calls.created_at', [$conds['from'], $conds['to']]); if ($request->has('call_date')) { $callDate = Carbon::parse($request->call_date)->format('Y-m-d'); $query->whereDate('calls.call_date', $callDate); } if ($request->has('owner')) { $keyword = strtolower(trim($request->owner)); $query->where(function ($q) use ($keyword) { $q->orWhere(DB::raw('LOWER(users.name)'), 'LIKE', '%' . $keyword . '%') ->orWhere(DB::raw('LOWER(users.first_name)'), 'LIKE', '%' . $keyword . '%') ->orWhere(DB::raw('LOWER(users.last_name)'), 'LIKE', '%' . $keyword . '%'); }); } if ($request->has('direction')) { $query->where('calls_dict_direction.name', $request->direction); } if ($request->has('status')) { $query->where('calls_dict_status.name', $request->status); } if ($request->has('search')) { $searchValue = strtolower(trim($request->search)); $query->where(function ($q) use ($searchValue) { $q->orWhere(DB::raw('LOWER(calls.subject)'), 'LIKE', '%' . $searchValue . '%') ->orWhere(DB::raw('LOWER(calls.description)'), 'LIKE', '%' . $searchValue . '%') ->orWhere(DB::raw('LOWER(accounts.name)'), 'LIKE', '%' . $searchValue . '%') ->orWhere(DB::raw('LOWER(contacts.full_name)'), 'LIKE', '%' . $searchValue . '%') ->orWhere(DB::raw('LOWER(leads.full_name)'), 'LIKE', '%' . $searchValue . '%') ->orWhere(DB::raw('LOWER(deals.name)'), 'LIKE', '%' . $searchValue . '%') ->orWhere(DB::raw('LOWER(users.name)'), 'LIKE', '%' . $searchValue . '%'); }); } if ($request->has('missed') && $request->missed == true) { $query->where(function($q) { $q->where('calls_dict_direction.name', 'incoming') ->where('calls_dict_status.name','!=', 'UP - ANSWERED'); }) ->groupBy('calls.linkedid'); } $perPage = $request->get('per_page', 10); $data = $query->paginate($perPage); $data->getCollection()->transform(function ($item) { $item->call_date = date('Y-m-d h:i:s A', strtotime($item->call_date)); $item->created_at = date('Y-m-d h:i:s A', strtotime($item->created_at)); $item->updated_at = date('Y-m-d h:i:s A', strtotime($item->updated_at)); if ($item->duration) { $minutes = floor($item->duration / 60); $seconds = $item->duration % 60; $item->duration_formatted = sprintf('%02d:%02d', $minutes, $seconds); } else { $item->duration_formatted = '00:00'; } if ($item->ringtime) { $minutes = floor($item->ringtime / 60); $seconds = $item->ringtime % 60; $item->ringtime_formatted = sprintf('%02d:%02d', $minutes, $seconds); } else { $item->ringtime_formatted = '00:00'; } if ($item->talktime) { $minutes = floor($item->talktime / 60); $seconds = $item->talktime % 60; $item->talktime_formatted = sprintf('%02d:%02d', $minutes, $seconds); } else { $item->talktime_formatted = '00:00'; } $item->recording_path = "/api/reporting/listen/" . $item->linkedid; return $item; }); // Additional data for filters $filters = [ 'daterange' => $conds['from'] . ' - ' . $conds['to'], 'call_date' => $request->call_date ?? null, 'owner' => $request->owner ?? null, 'direction' => $request->direction ?? null, 'status' => $request->status ?? null, 'search' => $request->search ?? null ]; // Available filter options $filterOptions = [ 'directions' => DB::table('calls_dict_direction')->pluck('name', 'name')->toArray(), 'statuses' => DB::table('calls_dict_status')->pluck('name', 'name')->toArray(), 'owners' => DB::table('users') ->when(!Auth::user()->hasRole('admin'), function ($query) use ($user) { if ($user->hasRole('company_manager') || $user->access_to_all_entity == true) { $query->where('company_id', $user->company_id); } else { $query->where('id', $user->id); } }) ->select('id', DB::raw('CONCAT(first_name, " ", last_name) as name')) ->pluck('name', 'id') ->toArray() ]; return response()->json([ 'success' => true, 'data' => [ 'calls' => $data, 'filters' => $filters, 'filter_options' => $filterOptions ], 'message' => 'Calls retrieved successfully' ]); } catch (\Throwable $th) { return response()->json([ 'success' => false, 'message' => 'Internal Server Error', 'error' => $th->getMessage() ], 500); } } public function listenFile($id) { try { $record = \DB::table('asteriskcdrdb.cdr') ->where('linkedid', $id) ->where('recordingfile', 'like', "%$id%") ->first(); if (!$record) { return response()->json([ 'success' => false, 'message' => 'Recording not found' ], 404); } $calldate = date('Y/m/d', strtotime($record->calldate)); $recordName = $record->recordingfile; if (empty($recordName)) { return response()->json([ 'success' => false, 'message' => 'Recording file missing' ], 404); } $filePath = "/var/spool/asterisk/monitor/{$calldate}/{$recordName}"; if (!file_exists($filePath)) { return response()->json([ 'success' => false, 'message' => 'Recording file not found on server' ], 404); } return response()->stream(function () use ($filePath) { readfile($filePath); }, 200, [ 'Content-Type' => mime_content_type($filePath), 'Content-Length' => filesize($filePath), 'Content-Disposition' => 'inline; filename="' . basename($filePath) . '"', ]); } catch (\Throwable $th) { return response()->json([ 'success' => false, 'message' => 'Server error', 'error' => $th->getMessage() ], 500); } } }