applyMailboxRestrictionScope( Ticket::where('agent_id', $agentId)->where('status', 'new') )->count(); //Get list of active ticket by agent $activeTickets = $access->applyMailboxRestrictionScope( Ticket::where('agent_id', $agentId)->where('status', 'active') )->count(); //Get list of closed ticket by agent within a date range(default today) $closedTickets = $access->applyMailboxRestrictionScope( Ticket::where('agent_id', $agentId) ->where('status', 'closed') ->whereBetween('resolved_at', [$startDate, $endDate]) )->count(); //Get list of response by agent id within a date range(default today) $responses = $access->applyMailboxRestrictionScopeViaTicket( Conversation::where('conversation_type', 'response') ->where('person_id', $agentId) ->whereBetween('created_at', [$startDate, $endDate]) )->count(); //Count the response in tickets within a date range(default today) for agent $interactions = $access->applyMailboxRestrictionScopeViaTicket( Conversation::where('person_id', $agentId) ->where('conversation_type', 'response') ->whereBetween('created_at', [$startDate, $endDate]) ->groupBy('ticket_id') )->get()->count(); return [ 'new_tickets' => [ 'title' => __('New Tickets', 'fluent-support'), 'count' => $newTickets ], 'active_tickets' => [ 'title' => __('Active Tickets', 'fluent-support'), 'count' => $activeTickets ], 'closed_tickets' => [ 'title' => __('Closed Tickets', 'fluent-support'), 'count' => $closedTickets ], 'responses' => [ 'title' => __('Responses', 'fluent-support'), 'count' => $responses ], 'interactions' => [ 'title' => __('Interactions', 'fluent-support'), 'count' => $interactions ] ]; } /** * getOverAllStats method will return the overall statistics for all tickets * This method will count the ticket number by ticket status and return the array * @return array[] */ public static function getOverAllStats() { $access = new AgentTicketAccess(); // Same mailbox boundary as the ticket list; these totals are agent-facing. $newTickets = $access->applyMailboxRestrictionScope(Ticket::where('status', 'new')) ->count(); $activeTickets = $access->applyMailboxRestrictionScope(Ticket::where('status', 'active')) ->count(); $closedTickets = $access->applyMailboxRestrictionScope(Ticket::where('status', 'closed')) ->count(); $responses = $access->applyMailboxRestrictionScopeViaTicket( Conversation::where('conversation_type', 'response') )->count(); return [ 'new_tickets' => [ 'title' => __('New Tickets', 'fluent-support'), 'count' => $newTickets ], 'active_tickets' => [ 'title' => __('Active Tickets', 'fluent-support'), 'count' => $activeTickets ], 'closed_tickets' => [ 'title' => __('Closed Tickets', 'fluent-support'), 'count' => $closedTickets ], 'responses' => [ 'title' => __('Responses', 'fluent-support'), 'count' => $responses ] ]; } /** * getTodayStats method will return a stats of today's tickets * This method will count the ticket number by ticket status and return the array * @param bool|int $agentId By default value set to false however when it gets an agent id it will fetch * the result by this id * @return array result in array format */ public static function getTodayStats($agentId = false, ?AgentTicketAccess $access = null) { $start = gmdate('Y-m-d 00:00.01'); $end = gmdate('Y-m-d 23:59.59'); $access = $access ?: new AgentTicketAccess(); $newTickets = $access->applyMailboxRestrictionScope( Ticket::whereBetween('created_at', [$start, $end]) ); $closedTickets = $access->applyMailboxRestrictionScope( Ticket::where('status', 'closed')->whereBetween('resolved_at', [$start, $end]) ); $responses = $access->applyMailboxRestrictionScopeViaTicket( Conversation::where('conversation_type', 'response') ->whereHas('person', function ($q) { $q->where('person_type', 'agent'); }) ->whereBetween('created_at', [$start, $end]) ); if ($agentId) { $newTickets->where('agent_id', $agentId); $closedTickets->where('agent_id', $agentId); $responses->where('person_id', $agentId); } return [ 'new_tickets' => [ 'title' => __('New Tickets', 'fluent-support'), 'count' => $newTickets->count() ], 'closed_tickets' => [ 'title' => __('Closed Tickets', 'fluent-support'), 'count' => $closedTickets->count() ], 'responses' => [ 'title' => __('Responses', 'fluent-support'), 'count' => $responses->count() ] ]; } /** * getAgentOverallStats method will produce overall statistics by agent * @param $agentId * @return array[] */ public static function getAgentOverallStats($agentId) { //Get count of response by the agent $replies_count = (new AgentTicketAccess())->applyMailboxRestrictionScopeViaTicket( Conversation::where('person_id', $agentId) )->count(); //Get the number of interactions/responses by agent with tickets $interactions_count = (new AgentTicketAccess())->applyMailboxRestrictionScopeViaTicket( Conversation::where('person_id', $agentId) ->where('conversation_type', 'response') ->groupBy('ticket_id') )->get()->count(); //Get the number of tickets that are closed by this agent $total_closed = (new AgentTicketAccess())->applyMailboxRestrictionScope( Ticket::where('agent_id', $agentId)->where('status', 'closed') )->count(); return [ 'replies_count' => [ 'title' => __('Total Replies', 'fluent-support'), 'count' => $replies_count ], // 'interactions_count' => [ // 'title' => __('Total Interactions', 'fluent-support'), // 'count' => $interactions_count // ], 'total_closed' => [ 'title' => __('Total Closed', 'fluent-support'), 'count' => $total_closed ] ]; } /** * This `getActiveTicketsByProductStats` method will count today's tickets by product that are waiting for reply * @return array $result */ public static function getActiveTicketsByProductStats() { $products = Product::all(); $result = []; $access = new AgentTicketAccess(); foreach ($products as $product) { $result[$product->id] = [ 'title' => $product->title, 'count' => static::countAwaitingTickets('product_id', $product->id, $access) ]; } return $result; } /** * This will count the number of tickets that are waiting for response also it can receive parameters * @param string $whereClause // This is the where clause that will be used in the query * @param string $whereClauseValue // This is the value of the where clause * @return int $awatingTicketCount */ public static function countAwaitingTickets($whereClause = null, $whereClauseValue = null, ?AgentTicketAccess $access = null) { // Must be a builder: ->where() on a bare model returns a new one, losing the scope. $ticket = Ticket::query(); if ($whereClause && $whereClauseValue) { $ticket = $ticket->where(sanitize_text_field($whereClause), sanitize_text_field($whereClauseValue)); } $ticket = ($access ?: new AgentTicketAccess())->applyMailboxRestrictionScope($ticket); $awatingTicketCount = $ticket->where('status', '!=', 'closed') ->where(function ($query) { $query->whereColumn('last_agent_response', '<', 'last_customer_response') ->orWhereNull('last_agent_response') ->orWhere('status', 'new'); })->count(); return $awatingTicketCount; } /** * This method will return a summary of today's stats of all agent * @return array */ public static function getAgentTodayStats() { $stats = []; // One instance for the whole loop: resolving restrictions costs an agent and // meta read, and a fresh instance per agent would repeat it 44 times. $access = new AgentTicketAccess(); Agent::get()->each(function ($agent) use (&$stats, $access) { $agentStat = static::getTodayStats($agent->id, $access); $waiting = static::countAwaitingTickets('agent_id', $agent->id, $access); if(!empty($agentStat['responses']['count']) || $waiting) { $stats[] = [ 'agent_id' => $agent->id, 'agent_name' => $agent->full_name, 'agent_email' => $agent->email, 'avatar' => $agent->photo, 'stats' => array_merge( [ 'waiting_today' => [ 'title' => __('Waiting Today', 'fluent-support'), 'count' => $waiting ] ], $agentStat ) ]; } }); return $stats; } }