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/Http/Controllers/ReportingController.php +166 -81 1.5.52.4.0 View file →
@@ -1,13 +1,16 @@
1 1 <?php
2 2
3 3 namespace FluentSupport\App\Http\Controllers;
4 4
5 -use FluentSupport\App\Models\Agent;
6 5 use FluentSupport\App\Modules\Reporting\Reporting;
7 6 use FluentSupport\App\Modules\StatModule;
8 7 use FluentSupport\App\Services\Helper;
9 -use FluentSupport\Framework\Request\Request;
8 +use FluentSupport\Framework\Http\Request\Request;
9 +use FluentSupport\App\Models\Ticket;
10 +use FluentSupport\App\Services\Tickets\AgentTicketAccess;
11 +use FluentSupport\App\Models\Conversation;
12 +use FluentSupport\App\Models\TagPivot;
10 13
11 14 /**
12 15 * ReportingController class for REST API
13 16 * This class is responsible for getting data for all request related to report
@@ -16,98 +19,47 @@
16 19 * @version 1.0.0
17 20 */
18 21 class ReportingController extends Controller
19 22 {
20 - /**
21 - * getOverallReports method will return the overall statistics of all ticket by ticket statuses
22 - * The response will have an array with ticket number by ticket status
23 - * @param Request $request
24 - * @return array
25 - */
26 - public function getOverallReports(Request $request)
23 + public static function getSanitizedDateRange(Request $request)
27 24 {
28 - return [
29 - 'overall_reports' => StatModule::getOverAllStats(),
30 - 'today_reports' => StatModule::getTodayStats()
31 - ];
32 - }
25 + $dateRange = $request->get('date_range', []);
33 26
34 - /**
35 - * getTicketsChart method will generate statistics for all tickets within a date range and return ticket number by date
36 - * @param Request $request
37 - * @param Reporting $reporting
38 - * @return array
39 - */
40 - public function getTicketsChart(Request $request, Reporting $reporting)
41 - {
42 - list($from, $to) = $request->get('date_range') ?: ['', ''];
43 - $filter = [];
44 - $stats = $reporting->getTicketsGrowth($from, $to);
45 -
46 - if($agent_id = $request->get('agent_id')) {
47 - $filter['agent_id'] = $agent_id;
48 - $stats = $reporting->getTicketsGrowth($from, $to, $filter);
27 + if (is_array($dateRange) && count($dateRange) >= 2) {
28 + return [
29 + sanitize_text_field($dateRange[0] ?? ''),
30 + sanitize_text_field($dateRange[1] ?? '')
31 + ];
49 32 }
50 - return [
51 - 'stats' => $stats
52 - ];
53 - }
54 33
55 - /**
56 - * getResolveChart method will generate statistics for closed tickets within a date range and return ticket number by date
57 - * @param Request $request
58 - * @param Reporting $reporting
59 - * @return array
60 - */
61 - public function getResolveChart(Request $request, Reporting $reporting)
62 - {
63 - list($from, $to) = $request->get('date_range') ?: ['', ''];
64 - $filter = [];
65 - $stats = $reporting->getTicketResolveGrowth($from, $to);
66 -
67 - if($agent_id = $request->get('agent_id')) {
68 - $filter['agent_id'] = $agent_id;
69 - $stats = $reporting->getTicketResolveGrowth($from, $to, $filter);
34 + if (is_string($dateRange)) {
35 + $parts = array_map('trim', explode(',', $dateRange));
36 + return [
37 + sanitize_text_field($parts[0] ?? ''),
38 + sanitize_text_field($parts[1] ?? '')
39 + ];
70 40 }
71 41
72 - return [
73 - 'stats' => $stats
74 - ];
42 + return ['', ''];
75 43 }
76 44
77 - /**
78 - * getResponseChart method will generate response statistics for ticket by date range
79 - * @param Request $request
80 - * @param Reporting $reporting
81 - * @return array
82 - */
83 - public function getResponseChart(Request $request, Reporting $reporting)
45 + public static function getAgentIdsForGroup(Request $request)
84 46 {
85 - list($from, $to) = $request->get('date_range') ?: ['', ''];
86 - $filter = [];
87 - $stats = $reporting->getResponseGrowth($from, $to);
88 -
89 - if($person_id = $request->get('agent_id')) {
90 - $filter['person_id'] = $person_id;
91 - $stats = $reporting->getResponseGrowth($from, $to, $filter);
47 + $groupId = $request->getSafe('agent_group_id', 'intval');
48 + if (!$groupId) {
49 + return null;
92 50 }
93 51
94 - return [
95 - 'stats' => $stats
96 - ];
52 + return TagPivot::where('source_type', 'agent_group')
53 + ->where('tag_id', $groupId)
54 + ->pluck('source_id')
55 + ->toArray();
97 56 }
98 57
99 - /**
100 - * getAgentsSummary method will generate summary for agent
101 - * This method will count closed tickets, open tickets, responses/interactions with ticket by agent within a date range
102 - * @param Request $request
103 - * @param Reporting $reporting
104 - * @return array
105 - */
106 - public function getAgentsSummary(Request $request, Reporting $reporting)
58 + public function getActiveTicketsByProduct()
107 59 {
108 60 return [
109 - 'summary' => $reporting->agentSummary($request->get('from'), $request->get('to'))
61 + 'stats' => StatModule::getActiveTicketsByProductStats()
110 62 ];
111 63 }
112 64
113 65 /**
@@ -114,9 +66,9 @@
114 66 * getAgentOverallReports method will return the overall statistics report for logged-in agent
115 67 * @param Request $request
116 68 * @return array
117 69 */
118 - public function getAgentOverallReports(Request $request)
70 + public function getAgentOverallReports(Request $request): array
119 71 {
120 72 $agent = Helper::getAgentByUserId(get_current_user_id());
121 73
122 74 return [
@@ -134,9 +86,9 @@
134 86 public function getAgentResolveChart(Request $request, Reporting $reporting)
135 87 {
136 88 //Get logged in agent information
137 89 $agent = Helper::getAgentByUserId(get_current_user_id());
138 - list($from, $to) = $request->get('date_range') ?: ['', ''];
90 + list($from, $to) = self::getSanitizedDateRange($request);
139 91
140 92 return [
141 93 'stats' => $reporting->getTicketResolveGrowth($from, $to, ['agent_id' => $agent->id])
142 94 ];
@@ -150,9 +102,9 @@
150 102 */
151 103 public function getAgentResponseChart(Request $request, Reporting $reporting)
152 104 {
153 105 $agent = Helper::getAgentByUserId(get_current_user_id());
154 - list($from, $to) = $request->get('date_range') ?: ['', ''];
106 + list($from, $to) = self::getSanitizedDateRange($request);
155 107
156 108 return [
157 109 'stats' => $reporting->getResponseGrowth($from, $to, ['person_id' => $agent->id])
158 110 ];
@@ -169,8 +121,141 @@
169 121 {
170 122 $agent = Helper::getAgentByUserId(get_current_user_id());
171 123
172 124 return [
173 - 'summary' => $reporting->agentSummary($request->get('from'), $request->get('to'), $agent->id)
125 + 'summary' => $reporting->agentSummary($request->getSafe('from', 'sanitize_text_field'), $request->getSafe('to', 'sanitize_text_field'), $agent->id)
174 126 ];
175 127 }
128 +
129 + /**
130 + * getStats method will return statistics similar to getOverallReports but with filters
131 + * Returns: New Tickets, Active Tickets, Closed Tickets, and Responses
132 + * Filters: date_range, mailbox_id (business_box), product_id, agent_id, customer_id
133 + * @param Request $request
134 + * @return array
135 + */
136 + public function getStats(Request $request)
137 + {
138 + list($from, $to) = self::getSanitizedDateRange($request);
139 +
140 + $filters = [
141 + 'mailbox_id' => $request->getSafe('mailbox_id', 'intval') ?: $request->getSafe('business_box', 'intval'),
142 + 'product_id' => $request->getSafe('product_id', 'intval'),
143 + 'agent_id' => $request->getSafe('agent_id', 'intval'),
144 + 'customer_id' => $request->getSafe('customer_id', 'intval'),
145 + ];
146 +
147 + $agentIds = self::getAgentIdsForGroup($request);
148 +
149 + $access = new AgentTicketAccess();
150 +
151 + // Bound first: a caller-supplied mailbox_id below is not proof of access.
152 + $baseQuery = $access->applyMailboxRestrictionScope(Ticket::query());
153 +
154 + foreach ($filters as $field => $value) {
155 + if ($value) {
156 + $baseQuery->where($field, $value);
157 + }
158 + }
159 +
160 + if ($agentIds !== null) {
161 + $baseQuery->whereIn('agent_id', $agentIds);
162 + }
163 +
164 + $applyDateRange = function($query, $dateField = 'created_at') use ($from, $to) {
165 + if ($from && $to) {
166 + $query->whereBetween($dateField, ["$from 00:00:00", "$to 23:59:59"]);
167 + } elseif ($from) {
168 + $query->where($dateField, '>=', "$from 00:00:00");
169 + } elseif ($to) {
170 + $query->where($dateField, '<=', "$to 23:59:59");
171 + }
172 + };
173 +
174 + $countTickets = function($status, $dateField = 'created_at') use ($baseQuery, $applyDateRange) {
175 + $query = clone $baseQuery;
176 + $query->where('status', $status);
177 + $applyDateRange($query, $dateField);
178 + return $query->count();
179 + };
180 +
181 + $newTickets = $countTickets('new');
182 + $closedTickets = $countTickets('closed', 'resolved_at');
183 +
184 + $openQuery = clone $baseQuery;
185 + $openQuery->where('status', '!=', 'closed');
186 + $applyDateRange($openQuery);
187 + $openTickets = $openQuery->count();
188 +
189 + $responsesQuery = $access->applyMailboxRestrictionScopeViaTicket(
190 + Conversation::query()->where('conversation_type', 'response')
191 + );
192 +
193 + if (array_filter($filters) || $agentIds !== null) {
194 + $responsesQuery->whereHas('ticket', function ($q) use ($filters, $agentIds) {
195 + foreach ($filters as $field => $value) {
196 + if ($value) {
197 + $q->where($field, $value);
198 + }
199 + }
200 + if ($agentIds !== null) {
201 + $q->whereIn('agent_id', $agentIds);
202 + }
203 + });
204 + }
205 +
206 + $applyDateRange($responsesQuery, 'created_at');
207 + $responses = $responsesQuery->count();
208 +
209 + $agentId = $filters['agent_id'];
210 +
211 + if ($agentId) {
212 + $repliesQuery = $access->applyMailboxRestrictionScopeViaTicket(
213 + Conversation::query()
214 + ->where('person_id', $agentId)
215 + ->where('conversation_type', 'response')
216 + );
217 +
218 + $applyDateRange($repliesQuery, 'created_at');
219 + $totalReplies = $repliesQuery->count();
220 +
221 + $stats = [
222 + 'total_replies' => $totalReplies,
223 + 'new_tickets' => $newTickets,
224 + 'closed_tickets' => $closedTickets,
225 + 'responses' => $responses,
226 + 'open_tickets' => $openTickets,
227 + ];
228 + } else {
229 + $activeTickets = $countTickets('active');
230 +
231 + $stats = [
232 + 'new_tickets' => $newTickets,
233 + 'active_tickets' => $activeTickets,
234 + 'closed_tickets' => $closedTickets,
235 + 'responses' => $responses,
236 + 'open_tickets' => $openTickets,
237 + ];
238 + }
239 +
240 + $labels = [
241 + 'total_replies' => __('Total Replies', 'fluent-support'),
242 + 'new_tickets' => __('New Tickets', 'fluent-support'),
243 + 'active_tickets' => __('Active Tickets', 'fluent-support'),
244 + 'closed_tickets' => __('Closed Tickets', 'fluent-support'),
245 + 'responses' => __('Responses', 'fluent-support'),
246 + 'open_tickets' => __('Open Tickets', 'fluent-support'),
247 + ];
248 +
249 + $overallReports = [];
250 + foreach ($stats as $key => $count) {
251 + $overallReports[$key] = [
252 + 'title' => $labels[$key] ?? ucwords(str_replace('_', ' ', (string) $key)),
253 + 'key' => $key,
254 + 'count' => $count,
255 + ];
256 + }
257 +
258 + return ['overall_reports' => $overallReports];
259 + }
260 +
176 261 }