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 +152 -160 1.10.42.4.0 View file →
@@ -4,10 +4,13 @@
4 4
5 5 use FluentSupport\App\Modules\Reporting\Reporting;
6 6 use FluentSupport\App\Modules\StatModule;
7 7 use FluentSupport\App\Services\Helper;
8 -use FluentSupport\Framework\Request\Request;
8 +use FluentSupport\Framework\Http\Request\Request;
9 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,109 +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 - public function getActiveTicketsByProduct()
35 - {
36 - return [
37 - 'stats' => StatModule::getActiveTicketsByProductStats()
38 - ];
39 - }
27 + if (is_array($dateRange) && count($dateRange) >= 2) {
28 + return [
29 + sanitize_text_field($dateRange[0] ?? ''),
30 + sanitize_text_field($dateRange[1] ?? '')
31 + ];
32 + }
40 33
41 - /**
42 - * getTicketsChart method will generate statistics for all tickets within a date range and return ticket number by date
43 - * @param Request $request
44 - * @param Reporting $reporting
45 - * @return array
46 - */
47 - public function getTicketsChart(Request $request, Reporting $reporting)
48 - {
49 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
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 + ];
40 + }
50 41
51 - $filter = [
52 - 'agent_id' => $request->getSafe('agent_id', 'intval') ?: null,
53 - 'product_id' => $request->getSafe('product_id', 'intval') ?: null,
54 - 'mailbox_id' => $request->getSafe('mailbox_id', 'intval') ?: null,
55 - ];
56 -
57 - $stats = $reporting->getTicketsGrowth($from, $to, $filter);
58 -
59 - return [
60 - 'stats' => $stats
61 - ];
42 + return ['', ''];
62 43 }
63 44
64 - /**
65 - * getResolveChart method will generate statistics for closed tickets within a date range and return ticket number by date
66 - * @param Request $request
67 - * @param Reporting $reporting
68 - * @return array
69 - */
70 - public static function getResolveChart(Request $request, Reporting $reporting): array
45 + public static function getAgentIdsForGroup(Request $request)
71 46 {
72 - $type = $request->getSafe('type', 'sanitize_text_field');
73 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
74 -
75 - $filter = [
76 - 'agent_id' => $request->getSafe('agent_id', 'intval') ?: null,
77 - 'product_id' => $request->getSafe('product_id', 'intval') ?: null,
78 - 'mailbox_id' => $request->getSafe('mailbox_id', 'intval') ?: null,
79 - ];
80 -
81 - $stats = $reporting->getTicketResolveGrowth($from, $to, $filter,$type);
82 -
83 - return [
84 - 'stats' => $stats
85 - ];
86 - }
87 -
88 - /**
89 - * getResponseChart method will generate response statistics for ticket by date range
90 - * @param Request $request
91 - * @param Reporting $reporting
92 - * @return array
93 - */
94 - public function getResponseChart(Request $request, Reporting $reporting)
95 - {
96 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
97 - $filter = [];
98 - $stats = $reporting->getResponseGrowth($from, $to);
99 -
100 - if($person_id = $request->getSafe('agent_id', 'intval')) {
101 - $filter['person_id'] = $person_id;
102 - $stats = $reporting->getResponseGrowth($from, $to, $filter);
47 + $groupId = $request->getSafe('agent_group_id', 'intval');
48 + if (!$groupId) {
49 + return null;
103 50 }
104 51
105 - return [
106 - 'stats' => $stats
107 - ];
52 + return TagPivot::where('source_type', 'agent_group')
53 + ->where('tag_id', $groupId)
54 + ->pluck('source_id')
55 + ->toArray();
108 56 }
109 57
110 - /**
111 - * getAgentsSummary method will generate summary for agent
112 - * This method will count closed tickets, open tickets, responses/interactions with ticket by agent within a date range
113 - * @param Request $request
114 - * @param Reporting $reporting
115 - * @return array
116 - */
117 - public function getAgentsSummary(Request $request, Reporting $reporting)
58 + public function getActiveTicketsByProduct()
118 59 {
119 60 return [
120 - 'summary' => $reporting->agentSummary($request->getSafe('from'), $request->getSafe('to'))
61 + 'stats' => StatModule::getActiveTicketsByProductStats()
121 62 ];
122 63 }
123 64
124 65 /**
@@ -136,60 +77,8 @@
136 77 ];
137 78 }
138 79
139 80 /**
140 - * getResponseGrowthChart method will generate response statistics for ticket by date range for product or mailbox
141 - * @param Request $request
142 - * @param Reporting $reporting
143 - * @return array
144 - */
145 - public static function getResponseGrowthChart(Request $request,Reporting $reporting): array
146 - {
147 - $type = $request->getSafe('type', 'sanitize_text_field');
148 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
149 -
150 - $filter = [
151 - 'product_id' => $request->getSafe('product_id', 'intval') ?: null,
152 - 'mailbox_id' => $request->getSafe('mailbox_id', 'intval') ?: null,
153 - ];
154 -
155 - $stats = $reporting->getResponseGrowthChart($from, $to, $filter,$type);
156 -
157 - return [
158 - 'stats' => $stats
159 - ];
160 - }
161 -
162 - /**
163 - * getProductsSummary method will generate summary for product
164 - * This method will count closed tickets, open tickets, responses, interactions with ticket by agent within a date range
165 - * @param Request $request
166 - * @param Reporting $reporting
167 - * @return array
168 - */
169 - public static function getProductsSummary(Request $request,Reporting $reporting): array
170 - {
171 - return [
172 - 'summary' => $reporting->getSummary('product',$request->getSafe('from', 'sanitize_text_field'), $request->getSafe('to', 'sanitize_text_field'))
173 - ];
174 -
175 - }
176 -
177 - /**
178 - * getMailBoxesSummary method will generate summary for mailbox
179 - * This method will count closed tickets, open tickets, responses, interactions with ticket by agent within a date range
180 - * @param Request $request
181 - * @param Reporting $reporting
182 - * @return array
183 - */
184 - public static function getMailBoxesSummary(Request $request,Reporting $reporting): array
185 - {
186 - return [
187 - 'summary' => $reporting->getSummary('mailbox',$request->getSafe('from'), $request->getSafe('to'))
188 - ];
189 - }
190 -
191 - /**
192 81 * getAgentResolveChart method will generate ticket data for resolved ticket
193 82 * @param Request $request
194 83 * @param Reporting $reporting
195 84 * @return array
@@ -197,9 +86,9 @@
197 86 public function getAgentResolveChart(Request $request, Reporting $reporting)
198 87 {
199 88 //Get logged in agent information
200 89 $agent = Helper::getAgentByUserId(get_current_user_id());
201 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
90 + list($from, $to) = self::getSanitizedDateRange($request);
202 91
203 92 return [
204 93 'stats' => $reporting->getTicketResolveGrowth($from, $to, ['agent_id' => $agent->id])
205 94 ];
@@ -213,9 +102,9 @@
213 102 */
214 103 public function getAgentResponseChart(Request $request, Reporting $reporting)
215 104 {
216 105 $agent = Helper::getAgentByUserId(get_current_user_id());
217 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
106 + list($from, $to) = self::getSanitizedDateRange($request);
218 107
219 108 return [
220 109 'stats' => $reporting->getResponseGrowth($from, $to, ['person_id' => $agent->id])
221 110 ];
@@ -236,34 +125,137 @@
236 125 'summary' => $reporting->agentSummary($request->getSafe('from', 'sanitize_text_field'), $request->getSafe('to', 'sanitize_text_field'), $agent->id)
237 126 ];
238 127 }
239 128
240 - public function dayTimeStats(Reporting $reporting, Request $request)
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)
241 137 {
242 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
138 + list($from, $to) = self::getSanitizedDateRange($request);
243 139
244 - $filter = [
245 - 'report_type' => $request->getSafe('report_type', 'sanitize_text_field') ?: null,
246 - 'agent_id' => $request->getSafe('agent_id', 'intval') ?: null,
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'),
247 145 ];
248 146
249 - $results = $reporting->getQueryResults($from, $to, $filter);
147 + $agentIds = self::getAgentIdsForGroup($request);
250 148
251 - return $this->send([
252 - 'stats' => $results
253 - ]);
254 - }
149 + $access = new AgentTicketAccess();
255 150
256 - public function ticketResponseStats(Reporting $reporting, Request $request)
257 - {
151 + // Bound first: a caller-supplied mailbox_id below is not proof of access.
152 + $baseQuery = $access->applyMailboxRestrictionScope(Ticket::query());
258 153
259 - list($from, $to) = $request->getSafe('date_range', 'sanitize_text_field') ?: ['', ''];
154 + foreach ($filters as $field => $value) {
155 + if ($value) {
156 + $baseQuery->where($field, $value);
157 + }
158 + }
260 159
261 - $filter = [
262 - 'person_type' => $request->getSafe('person_type', 'sanitize_text_field') ?: null,
263 - 'person_id' => $request->getSafe('person_id', 'intval') ?: null,
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'),
264 247 ];
265 248
266 - return $reporting->getTicketResponseStats($from, $to, $filter);
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];
267 259 }
268 260
269 261 }