PluginProbe
Fluent Support – Helpdesk & Customer Support Ticket System / trunk
Fluent Support – Helpdesk & Customer Support Ticket System vtrunk
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
fluent-support / app / Http / Controllers / ReportingController.php

ReportingController.php in Fluent Support – Helpdesk & Customer Support Ticket System trunk, at app/Http/Controllers/ReportingController.php

262 lines 8.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentSupport\App\Http\Controllers;
4
5 use FluentSupport\App\Modules\Reporting\Reporting;
6 use FluentSupport\App\Modules\StatModule;
7 use FluentSupport\App\Services\Helper;
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;
13
14 /**
15 * ReportingController class for REST API
16 * This class is responsible for getting data for all request related to report
17 * @package FluentSupport\App\Http\Controllers
18 *
19 * @version 1.0.0
20 */
21 class ReportingController extends Controller
22 {
23 public static function getSanitizedDateRange(Request $request)
24 {
25 $dateRange = $request->get('date_range', []);
26
27 if (is_array($dateRange) && count($dateRange) >= 2) {
28 return [
29 sanitize_text_field($dateRange[0] ?? ''),
30 sanitize_text_field($dateRange[1] ?? '')
31 ];
32 }
33
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 }
41
42 return ['', ''];
43 }
44
45 public static function getAgentIdsForGroup(Request $request)
46 {
47 $groupId = $request->getSafe('agent_group_id', 'intval');
48 if (!$groupId) {
49 return null;
50 }
51
52 return TagPivot::where('source_type', 'agent_group')
53 ->where('tag_id', $groupId)
54 ->pluck('source_id')
55 ->toArray();
56 }
57
58 public function getActiveTicketsByProduct()
59 {
60 return [
61 'stats' => StatModule::getActiveTicketsByProductStats()
62 ];
63 }
64
65 /**
66 * getAgentOverallReports method will return the overall statistics report for logged-in agent
67 * @param Request $request
68 * @return array
69 */
70 public function getAgentOverallReports(Request $request): array
71 {
72 $agent = Helper::getAgentByUserId(get_current_user_id());
73
74 return [
75 'overall_reports' => StatModule::getAgentOverallStats($agent->id),
76 'today_reports' => StatModule::getTodayStats($agent->id)
77 ];
78 }
79
80 /**
81 * getAgentResolveChart method will generate ticket data for resolved ticket
82 * @param Request $request
83 * @param Reporting $reporting
84 * @return array
85 */
86 public function getAgentResolveChart(Request $request, Reporting $reporting)
87 {
88 //Get logged in agent information
89 $agent = Helper::getAgentByUserId(get_current_user_id());
90 list($from, $to) = self::getSanitizedDateRange($request);
91
92 return [
93 'stats' => $reporting->getTicketResolveGrowth($from, $to, ['agent_id' => $agent->id])
94 ];
95 }
96
97 /**
98 * getAgentResponseChart method will generate the statistics of response by agent in tickets within date range
99 * @param Request $request
100 * @param Reporting $reporting
101 * @return array
102 */
103 public function getAgentResponseChart(Request $request, Reporting $reporting)
104 {
105 $agent = Helper::getAgentByUserId(get_current_user_id());
106 list($from, $to) = self::getSanitizedDateRange($request);
107
108 return [
109 'stats' => $reporting->getResponseGrowth($from, $to, ['person_id' => $agent->id])
110 ];
111 }
112
113 /**
114 * getPersonalSummary method will generate summary for specific agent
115 * This method will count closed tickets, open tickets, responses/interactions with ticket by agent within a date range
116 * @param Reporting $reporting
117 * @param Request $request
118 * @return array
119 */
120 public function getPersonalSummary(Reporting $reporting, Request $request)
121 {
122 $agent = Helper::getAgentByUserId(get_current_user_id());
123
124 return [
125 'summary' => $reporting->agentSummary($request->getSafe('from', 'sanitize_text_field'), $request->getSafe('to', 'sanitize_text_field'), $agent->id)
126 ];
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
261 }
262