PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / 2.4.0
Fluent Support – Helpdesk & Customer Support Ticket System v2.4.0
2.4.0 2.3.2 2.3.1 2.3.0 2.2.1 2.2.0 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.4.0 1.4.1 1.4.2 1.4.5 1.4.6 1.4.7 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 All 68 releases
← All changes | app/Modules/StatModule.php +87 -55 1.10.02.4.0 View file →
@@ -5,8 +5,9 @@
5 5 use FluentSupport\App\Models\Agent;
6 6 use FluentSupport\App\Models\Conversation;
7 7 use FluentSupport\App\Models\Ticket;
8 8 use FluentSupport\App\Models\Product;
9 +use FluentSupport\App\Services\Tickets\AgentTicketAccess;
9 10
10 11 /**
11 12 * StatModule class is responsible for getting data related to report
12 13 * @package FluentSupport\App\Modules
@@ -30,40 +31,44 @@
30 31 $startDate = $currentDate;
31 32 $endDate = $currentDate;
32 33 }
33 34
34 - $startDate = date('Y-m-d 00:00.01', strtotime($startDate));
35 - $endDate = date('Y-m-d 23:59.59', strtotime($endDate));
35 + $startDate = gmdate('Y-m-d 00:00.01', strtotime($startDate));
36 + $endDate = gmdate('Y-m-d 23:59.59', strtotime($endDate));
36 37
38 + $access = new AgentTicketAccess();
39 +
37 40 //Get list of new ticket by agent
38 - $newTickets = Ticket::where('agent_id', $agentId)
39 - ->where('status', 'new')
40 - ->count();
41 + $newTickets = $access->applyMailboxRestrictionScope(
42 + Ticket::where('agent_id', $agentId)->where('status', 'new')
43 + )->count();
41 44
42 45 //Get list of active ticket by agent
43 - $activeTickets = Ticket::where('agent_id', $agentId)
44 - ->where('status', 'active')
45 - ->count();
46 + $activeTickets = $access->applyMailboxRestrictionScope(
47 + Ticket::where('agent_id', $agentId)->where('status', 'active')
48 + )->count();
46 49
47 50 //Get list of closed ticket by agent within a date range(default today)
48 - $closedTickets = Ticket::where('agent_id', $agentId)
49 - ->where('status', 'closed')
50 - ->whereBetween('resolved_at', [$startDate, $endDate])
51 - ->count();
51 + $closedTickets = $access->applyMailboxRestrictionScope(
52 + Ticket::where('agent_id', $agentId)
53 + ->where('status', 'closed')
54 + ->whereBetween('resolved_at', [$startDate, $endDate])
55 + )->count();
52 56
53 57 //Get list of response by agent id within a date range(default today)
54 - $responses = Conversation::where('conversation_type', 'response')
55 - ->where('person_id', $agentId)
56 - ->whereBetween('created_at', [$startDate, $endDate])
57 - ->count();
58 + $responses = $access->applyMailboxRestrictionScopeViaTicket(
59 + Conversation::where('conversation_type', 'response')
60 + ->where('person_id', $agentId)
61 + ->whereBetween('created_at', [$startDate, $endDate])
62 + )->count();
58 63
59 64 //Count the response in tickets within a date range(default today) for agent
60 - $interactions = Conversation::where('person_id', $agentId)
61 - ->where('conversation_type', 'response')
62 - ->whereBetween('created_at', [$startDate, $endDate])
63 - ->groupBy('ticket_id')
64 - ->get()
65 - ->count();
65 + $interactions = $access->applyMailboxRestrictionScopeViaTicket(
66 + Conversation::where('person_id', $agentId)
67 + ->where('conversation_type', 'response')
68 + ->whereBetween('created_at', [$startDate, $endDate])
69 + ->groupBy('ticket_id')
70 + )->get()->count();
66 71
67 72 return [
68 73 'new_tickets' => [
69 74 'title' => __('New Tickets', 'fluent-support'),
@@ -94,19 +99,23 @@
94 99 * @return array[]
95 100 */
96 101 public static function getOverAllStats()
97 102 {
98 - $newTickets = Ticket::where('status', 'new')
103 + $access = new AgentTicketAccess();
104 +
105 + // Same mailbox boundary as the ticket list; these totals are agent-facing.
106 + $newTickets = $access->applyMailboxRestrictionScope(Ticket::where('status', 'new'))
99 107 ->count();
100 108
101 - $activeTickets = Ticket::where('status', 'active')
109 + $activeTickets = $access->applyMailboxRestrictionScope(Ticket::where('status', 'active'))
102 110 ->count();
103 111
104 - $closedTickets = Ticket::where('status', 'closed')
112 + $closedTickets = $access->applyMailboxRestrictionScope(Ticket::where('status', 'closed'))
105 113 ->count();
106 114
107 - $responses = Conversation::where('conversation_type', 'response')
108 - ->count();
115 + $responses = $access->applyMailboxRestrictionScopeViaTicket(
116 + Conversation::where('conversation_type', 'response')
117 + )->count();
109 118
110 119 return [
111 120 'new_tickets' => [
112 121 'title' => __('New Tickets', 'fluent-support'),
@@ -133,23 +142,31 @@
133 142 * @param bool|int $agentId By default value set to false however when it gets an agent id it will fetch
134 143 * the result by this id
135 144 * @return array result in array format
136 145 */
137 - public static function getTodayStats($agentId = false)
146 + public static function getTodayStats($agentId = false, ?AgentTicketAccess $access = null)
138 147 {
139 - $start = date('Y-m-d 00:00.01');
140 - $end = date('Y-m-d 23:59.59');
148 + $start = gmdate('Y-m-d 00:00.01');
149 + $end = gmdate('Y-m-d 23:59.59');
141 150
142 - $newTickets = Ticket::whereBetween('created_at', [$start, $end]);
151 + $access = $access ?: new AgentTicketAccess();
143 152
144 - $closedTickets = Ticket::where('status', 'closed')->whereBetween('resolved_at', [$start, $end]);
153 + $newTickets = $access->applyMailboxRestrictionScope(
154 + Ticket::whereBetween('created_at', [$start, $end])
155 + );
145 156
146 - $responses = Conversation::where('conversation_type', 'response')
147 - ->whereHas('person', function ($q) {
148 - $q->where('person_type', 'agent');
149 - })
150 - ->whereBetween('created_at', [$start, $end]);
157 + $closedTickets = $access->applyMailboxRestrictionScope(
158 + Ticket::where('status', 'closed')->whereBetween('resolved_at', [$start, $end])
159 + );
151 160
161 + $responses = $access->applyMailboxRestrictionScopeViaTicket(
162 + Conversation::where('conversation_type', 'response')
163 + ->whereHas('person', function ($q) {
164 + $q->where('person_type', 'agent');
165 + })
166 + ->whereBetween('created_at', [$start, $end])
167 + );
168 +
152 169 if ($agentId) {
153 170 $newTickets->where('agent_id', $agentId);
154 171 $closedTickets->where('agent_id', $agentId);
155 172 $responses->where('person_id', $agentId);
@@ -178,19 +195,23 @@
178 195 */
179 196 public static function getAgentOverallStats($agentId)
180 197 {
181 198 //Get count of response by the agent
182 - $replies_count = Conversation::where('person_id', $agentId)->count();
199 + $replies_count = (new AgentTicketAccess())->applyMailboxRestrictionScopeViaTicket(
200 + Conversation::where('person_id', $agentId)
201 + )->count();
183 202
184 203 //Get the number of interactions/responses by agent with tickets
185 - $interactions_count = Conversation::where('person_id', $agentId)
186 - ->where('conversation_type', 'response')
187 - ->groupBy('ticket_id')
188 - ->get()
189 - ->count();
204 + $interactions_count = (new AgentTicketAccess())->applyMailboxRestrictionScopeViaTicket(
205 + Conversation::where('person_id', $agentId)
206 + ->where('conversation_type', 'response')
207 + ->groupBy('ticket_id')
208 + )->get()->count();
190 209
191 210 //Get the number of tickets that are closed by this agent
192 - $total_closed = Ticket::where('agent_id', $agentId)->where('status', 'closed')->count();
211 + $total_closed = (new AgentTicketAccess())->applyMailboxRestrictionScope(
212 + Ticket::where('agent_id', $agentId)->where('status', 'closed')
213 + )->count();
193 214
194 215 return [
195 216 'replies_count' => [
196 217 'title' => __('Total Replies', 'fluent-support'),
@@ -195,12 +216,12 @@
195 216 'replies_count' => [
196 217 'title' => __('Total Replies', 'fluent-support'),
197 218 'count' => $replies_count
198 219 ],
199 - 'interactions_count' => [
200 - 'title' => __('Total Interactions', 'fluent-support'),
201 - 'count' => $interactions_count
202 - ],
220 + // 'interactions_count' => [
221 + // 'title' => __('Total Interactions', 'fluent-support'),
222 + // 'count' => $interactions_count
223 + // ],
203 224 'total_closed' => [
204 225 'title' => __('Total Closed', 'fluent-support'),
205 226 'count' => $total_closed
206 227 ]
@@ -214,13 +235,14 @@
214 235 public static function getActiveTicketsByProductStats()
215 236 {
216 237 $products = Product::all();
217 238 $result = [];
239 + $access = new AgentTicketAccess();
218 240
219 241 foreach ($products as $product) {
220 242 $result[$product->id] = [
221 243 'title' => $product->title,
222 - 'count' => static::countAwaitingTickets('product_id', $product->id)
244 + 'count' => static::countAwaitingTickets('product_id', $product->id, $access)
223 245 ];
224 246 }
225 247
226 248 return $result;
@@ -232,16 +254,19 @@
232 254 * @param string $whereClause // This is the where clause that will be used in the query
233 255 * @param string $whereClauseValue // This is the value of the where clause
234 256 * @return int $awatingTicketCount
235 257 */
236 - public static function countAwaitingTickets($whereClause = null, $whereClauseValue = null)
258 + public static function countAwaitingTickets($whereClause = null, $whereClauseValue = null, ?AgentTicketAccess $access = null)
237 259 {
238 - $ticket = new Ticket;
260 + // Must be a builder: ->where() on a bare model returns a new one, losing the scope.
261 + $ticket = Ticket::query();
239 262
240 263 if ($whereClause && $whereClauseValue) {
241 264 $ticket = $ticket->where(sanitize_text_field($whereClause), sanitize_text_field($whereClauseValue));
242 265 }
243 266
267 + $ticket = ($access ?: new AgentTicketAccess())->applyMailboxRestrictionScope($ticket);
268 +
244 269 $awatingTicketCount = $ticket->where('status', '!=', 'closed')
245 270 ->where(function ($query) {
246 271 $query->whereColumn('last_agent_response', '<', 'last_customer_response')
247 272 ->orWhereNull('last_agent_response')
@@ -257,14 +282,21 @@
257 282 */
258 283 public static function getAgentTodayStats()
259 284 {
260 285 $stats = [];
261 - Agent::select(['id', 'first_name'])->get()->each(function ($agent) use (&$stats) {
262 - $agentStat = static::getTodayStats($agent->id);
263 - $waiting = static::countAwaitingTickets('agent_id', $agent->id);
286 + // One instance for the whole loop: resolving restrictions costs an agent and
287 + // meta read, and a fresh instance per agent would repeat it 44 times.
288 + $access = new AgentTicketAccess();
289 +
290 + Agent::get()->each(function ($agent) use (&$stats, $access) {
291 + $agentStat = static::getTodayStats($agent->id, $access);
292 + $waiting = static::countAwaitingTickets('agent_id', $agent->id, $access);
264 293 if(!empty($agentStat['responses']['count']) || $waiting) {
265 294 $stats[] = [
266 - 'agent_name' => $agent->first_name,
295 + 'agent_id' => $agent->id,
296 + 'agent_name' => $agent->full_name,
297 + 'agent_email' => $agent->email,
298 + 'avatar' => $agent->photo,
267 299 'stats' => array_merge(
268 300 [
269 301 'waiting_today' => [
270 302 'title' => __('Waiting Today', 'fluent-support'),