vendor/uvdesk/core-framework/Controller/Chart.php line 44

Open in your IDE?
  1. <?php
  2. namespace Webkul\UVDesk\CoreFrameworkBundle\Controller;
  3. use Webkul\UVDesk\CoreFrameworkBundle\Entity;
  4. use Webkul\UVDesk\CoreFrameworkBundle\Form;
  5. use Webkul\UVDesk\CoreFrameworkBundle\Entity\User;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\Response;
  8. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportGroup;
  9. use Webkul\UVDesk\CoreFrameworkBundle\Entity\SupportTeam;
  10. use Webkul\UVDesk\CoreFrameworkBundle\Entity\UserInstance;
  11. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  12. use Webkul\UVDesk\CoreFrameworkBundle\Services\UserService;
  13. use Webkul\UVDesk\CoreFrameworkBundle\Services\UVDeskService;
  14. use Webkul\UVDesk\CoreFrameworkBundle\Services\ReportService;
  15. use Symfony\Contracts\Translation\TranslatorInterface;
  16. use Knp\Component\Pager\PaginatorInterface;
  17. use Doctrine\ORM\Query;
  18. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  19. use Symfony\Component\DependencyInjection\ContainerInterface;
  20. use Webkul\UVDesk\CoreFrameworkBundle\Entity\TicketRating;
  21. use Webkul\UVDesk\CoreFrameworkBundle\Entity\Ticket;
  22. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  23. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  24. class Chart extends AbstractController
  25. {
  26.     private $userService;
  27.     private $reportService;
  28.     private $uvdeskService;
  29.     private $paginator;
  30.     private $translator;
  31.     public function __construct(UserService $userServiceUVDeskService $uvdeskService,ReportService $reportServicePaginatorInterface $paginatorTranslatorInterface $translator)
  32.     {
  33.         $this->userService $userService;
  34.         $this->reportService $reportService;
  35.         $this->uvdeskService $uvdeskService;
  36.         $this->paginator $paginator;
  37.         $this->translator $translator;
  38.     }
  39.     public function listReportActivity(Request $request)
  40.     {
  41.         if (!$this->userService->isAccessAuthorized('ROLE_AGENT_MANAGE_AGENT_ACTIVITY')){
  42.             return $this->redirect($this->generateUrl('helpdesk_member_dashboard'));
  43.         }
  44.         return $this->render('@UVDeskCoreFramework/Reports/listReport.html.twig', [
  45.             'agents' => $this->userService->getAgentsPartialDetails(),
  46.         ]);
  47.     }
  48.     public function agentChartXHR(Request $request)
  49.     {
  50.         $json = [];
  51.         if ($request->isXmlHttpRequest()) {
  52.             $json $this->agentChartData($request);
  53.         }
  54.         return new Response(json_encode($json), 200, ['Content-Type' => 'application/json']);
  55.     }
  56.   public function agentChartData(Request $request)
  57. {
  58.     if (!$this->userService->isAccessAuthorized('ROLE_AGENT_MANAGE_AGENT_ACTIVITY')) {
  59.         throw new \Exception('Access Denied'403);
  60.     }
  61.     $reportService $this->reportService;
  62.     $reportService->parameters $request->query->all();
  63.     $startDate $reportService->parameters['after'] ?? null;
  64.     $endDate   $reportService->parameters['before'] ?? null;
  65.     // guard for dates (optional)
  66.     if (!$startDate || !$endDate) {
  67.         throw new \InvalidArgumentException('Missing required date filters: after / before');
  68.     }
  69.     $agentIds = [];
  70.     if (isset($reportService->parameters['agent']) && $reportService->parameters['agent'] !== '') {
  71.         $agentIds explode(','$reportService->parameters['agent']);
  72.     }
  73.     $from $startDate ' 00:00:01';
  74.     $to   $endDate   ' 23:59:59';
  75.     // Build the base query
  76.     $qb $reportService->getAgentChartData($agentIds$from$to);
  77.     // Pagination inputs
  78.     $page    max(1, (int) $request->query->get('page'1));
  79.     $perPage 8;
  80.     // Paginate
  81.     $paginator $this->paginator;
  82.     $results   $paginator->paginate(
  83.         // You can pass the QueryBuilder directly; KnpPaginator will handle it.
  84.         $qb,
  85.         $page,
  86.         $perPage,
  87.         array('distinct' => true)
  88.     );
  89.     // Build pagination metadata + URL template
  90.     $paginationData   $results->getPaginationData();
  91.     $queryParameters  $results->getParams();
  92.     $queryParameters['page'] = 'replacePage';
  93.     $paginationData['url']   = '#' $this->uvdeskService->buildPaginationQuery($queryParameters);
  94.     // Transform rows
  95.     $data        = [];
  96.     $ticketIds   = [];
  97.     $agentsUsed  = [];
  98.     $now = new \DateTimeImmutable('now');
  99.     foreach ($results as $activity) {
  100.         // $activity already has the fields you selected in getAgentChartData()
  101.         // so avoid N+1: do NOT re-fetch Ticket by id.
  102.         $activityDateTime $activity['createdAt'] instanceof \DateTimeInterface
  103.             $activity['createdAt']
  104.             : new \DateTimeImmutable((string) $activity['createdAt']);
  105.         $diffSeconds $now->getTimestamp() - $activityDateTime->getTimestamp();
  106.         $lastReply   $reportService->time2string($diffSeconds);
  107.         $ticketViewURL $this->get('router')->generate(
  108.             'helpdesk_member_ticket',
  109.             ['ticketId' => $activity['ticketId']],
  110.             UrlGeneratorInterface::ABSOLUTE_URL
  111.         );
  112.         $data[] = [
  113.             'agentName'   => $activity['agentName'],
  114.             'ticketId'     => $activity['ticketId'],
  115.             'agentId'      => $activity['agentId'],
  116.             'ticketURL'    => $ticketViewURL,
  117.             'customerName' => $activity['customerName'],
  118.             'threadType'   => $activity['threadType'],
  119.             'createdAt'    => $activity['createdAt'],
  120.             'subject'      => $activity['subject'],
  121.             'lastReply'    => $lastReply,
  122.             'dueDate'      => $activity['dueDate'],
  123.             'dueDate' => $activity['dueDate'] instanceof \DateTime
  124.     $activity['dueDate']->format('Y-m-d')   // Example: 2025-03-06
  125.     null,
  126.             'userID'       => $activity['userId'],
  127.             'firstName'    => $activity['firstName'],
  128.             'lastName'     => $activity['lastName'],
  129.             'ticketStatus' => $activity['ticketStatus'],
  130.         ];
  131.         $ticketIds[]  = $activity['ticketId'];
  132.         $agentsUsed[] = $activity['agentId'];
  133.     }
  134.     // Compute totals for tickets shown on THIS PAGE only
  135.     $threadDetails = [];
  136.     if (!empty($ticketIds)) {
  137.         $threadDetails $reportService->getTotalReplies(array_unique($ticketIds), array_unique($agentsUsed), $from$to);
  138.         // index by ticketId for O(1) lookups
  139.         $byTicket = [];
  140.         foreach ($threadDetails as $detail) {
  141.             $byTicket[(string) $detail['ticketId']] = (int) $detail['ticketCount'];
  142.         }
  143.         foreach ($data as &$row) {
  144.             $tid = (string) $row['ticketId'];
  145.             $row['totalReply'] = $byTicket[$tid] ?? 0;
  146.         }
  147.         unset($row);
  148.     }
  149.     // FINAL payload — note: NO all-pages aggregation
  150.     $agentActivity = [
  151.         'data'            => $data,            // max 20 items for the requested page
  152.         'pagination_data' => $paginationData,  // has pageCount, current, next, previous, etc.
  153.     ];
  154.     // Persist in session if you need it elsewhere
  155.     $request->getSession()->set('agentActivity'$agentActivity);
  156.     return $agentActivity;
  157. }
  158.    
  159. }