src/Controller/WorkingHoursController.php line 18

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  4. use Symfony\Component\HttpFoundation\Request;
  5. use Symfony\Component\HttpFoundation\Response;
  6. use Symfony\Component\HttpFoundation\JsonResponse;
  7. use Symfony\Component\Routing\Annotation\Route;
  8. class WorkingHoursController extends AbstractController
  9. {
  10.     public function workingHoursAction(): Response
  11.     {
  12.         return $this->render('reports/working-hours.html.twig');
  13.     }
  14.     public function getWorkingHoursStatusAction(): JsonResponse
  15.     {
  16.         $timezones = [
  17.             'Argentina' => 'America/Argentina/Buenos_Aires',
  18.             'Colombia' => 'America/Bogota',
  19.             'Mexico' => 'America/Mexico_City',
  20.             'Perú' => 'America/Lima',
  21.             'España' => 'Europe/Madrid'
  22.         ];
  23.         $status = [];
  24.         $now = new \DateTime('now', new \DateTimeZone('UTC'));
  25.         
  26.         // Obtener agentes agrupados por región
  27.         $entityManager $this->getDoctrine()->getManager();
  28.         $agentsQuery $entityManager->createQuery("
  29.             SELECT 
  30.                 a.id as agentId,
  31.                 a.firstName,
  32.                 a.lastName,
  33.                 a.email,
  34.                 a.isEnabled,
  35.                 a.lastactivity,
  36.                 a.idor,
  37.                 sg.name as supportGroupName,
  38.                 sg.description as supportGroupDescription,
  39.                 sr.code as supportRoleCode
  40.             FROM UVDeskCoreFrameworkBundle:User a
  41.             JOIN UVDeskCoreFrameworkBundle:UserInstance ui WITH a.id = ui.user
  42.             JOIN UVDeskCoreFrameworkBundle:SupportRole sr WITH ui.supportRole = sr.id
  43.             LEFT JOIN UVDeskCoreFrameworkBundle:SupportGroup sg WITH a.idor = sg.id
  44.             WHERE a.isEnabled = 1
  45.             AND sr.code = 'ROLE_AGENT'
  46.             ORDER BY a.firstName, a.lastName
  47.         ");
  48.         
  49.         $agents $agentsQuery->getResult();
  50.         
  51.         // Agrupar agentes por región
  52.         $agentsByRegion = [];
  53.         foreach ($agents as $agent) {
  54.             $regionName $agent['supportGroupName'] ?: 'Sin región asignada';
  55.             if (!isset($agentsByRegion[$regionName])) {
  56.                 $agentsByRegion[$regionName] = [];
  57.             }
  58.             $agentsByRegion[$regionName][] = [
  59.                 'id' => $agent['agentId'],
  60.                 'name' => $agent['firstName'] . ' ' $agent['lastName'],
  61.                 'email' => $agent['email'],
  62.                 'isActive' => $agent['isEnabled'],
  63.                 'lastActivity' => $agent['lastactivity'] ? $agent['lastactivity']->format('Y-m-d H:i:s') : 'N/A',
  64.                 'idor' => $agent['idor'],
  65.                 'role' => $agent['supportRoleCode']
  66.             ];
  67.         }
  68.         foreach ($timezones as $country => $timezone) {
  69.             $localTime = new \DateTime('now', new \DateTimeZone($timezone));
  70.             $dayOfWeek = (int)$localTime->format('N'); // 1 = Monday, 7 = Sunday
  71.             $hour = (int)$localTime->format('G'); // 0-23 hour format
  72.             
  73.             // Check if it's a working day (Monday to Friday)
  74.             $isWorkingDay $dayOfWeek >= && $dayOfWeek <= 5;
  75.             
  76.             // Check if it's within working hours (9 AM to 6 PM)
  77.             $isWorkingHours $hour >= && $hour 18;
  78.             
  79.             // Determine status
  80.             if ($isWorkingDay && $isWorkingHours) {
  81.                 $statusCode 'open';
  82.                 $statusText 'Abierto';
  83.                 $statusColor 'green';
  84.             } else {
  85.                 $statusCode 'closed';
  86.                 $statusText 'Cerrado';
  87.                 $statusColor 'red';
  88.             }
  89.             
  90.             // Buscar agentes para este país basándose en el nombre del país
  91.             $countryAgents = [];
  92.             foreach ($agentsByRegion as $regionName => $regionAgents) {
  93.                 if (stripos($regionName$country) !== false || 
  94.                     stripos($country$regionName) !== false ||
  95.                     $this->isCountryInRegion($country$regionName)) {
  96.                     $countryAgents array_merge($countryAgents$regionAgents);
  97.                 }
  98.             }
  99.             $status[$country] = [
  100.                 'country' => $country,
  101.                 'timezone' => $timezone,
  102.                 'localTime' => $localTime->format('H:i:s'),
  103.                 'localDate' => $localTime->format('Y-m-d'),
  104.                 'dayOfWeek' => $localTime->format('l'),
  105.                 'isWorkingDay' => $isWorkingDay,
  106.                 'isWorkingHours' => $isWorkingHours,
  107.                 'status' => $statusCode,
  108.                 'statusText' => $statusText,
  109.                 'statusColor' => $statusColor,
  110.                 'workingHours' => '9:00 AM - 6:00 PM',
  111.                 'workingDays' => 'Lunes a Viernes',
  112.                 'agents' => $countryAgents
  113.             ];
  114.         }
  115.         return new JsonResponse($status);
  116.     }
  117.     
  118.     private function isCountryInRegion($country$regionName): bool
  119.     {
  120.         // Mapeo de países a posibles nombres de regiones
  121.         $countryRegionMap = [
  122.             'Argentina' => ['argentina''argentine''buenos aires''córdoba''rosario'],
  123.             'Colombia' => ['colombia''bogotá''medellín''cali''barranquilla'],
  124.             'Mexico' => ['mexico''méxico''ciudad de mexico''cdmx''guadalajara''monterrey'],
  125.             'Perú' => ['peru''perú''lima''arequipa''trujillo'],
  126.             'España' => ['españa''spain''madrid''barcelona''valencia''sevilla']
  127.         ];
  128.         
  129.         if (isset($countryRegionMap[$country])) {
  130.             foreach ($countryRegionMap[$country] as $regionKeyword) {
  131.                 if (stripos($regionName$regionKeyword) !== false) {
  132.                     return true;
  133.                 }
  134.             }
  135.         }
  136.         
  137.         return false;
  138.     }
  139.     public function getRecentTicketsAction(): JsonResponse
  140.     {
  141.         $entityManager $this->getDoctrine()->getManager();
  142.         
  143.         // Query para obtener los últimos 5 tickets con información del cliente y región
  144.         $query $entityManager->createQuery("
  145.             SELECT 
  146.                 t.id as ticketId,
  147.                 t.subject,
  148.                 s.code as status,
  149.                 p.code as priority,
  150.                 t.createdAt,
  151.                 t.updatedAt,
  152.                 c.id as customerId,
  153.                 c.firstName as customerFirstName,
  154.                 c.lastName as customerLastName,
  155.                 c.email as customerEmail,
  156.                 c.idor,
  157.                 sg.name as supportGroupName,
  158.                 sg.description as supportGroupDescription,
  159.                 a.id as agentId,
  160.                 a.firstName as agentFirstName,
  161.                 a.lastName as agentLastName,
  162.                 a.email as agentEmail
  163.             FROM UVDeskCoreFrameworkBundle:Ticket t
  164.             JOIN UVDeskCoreFrameworkBundle:User c WITH t.customer = c.id
  165.             LEFT JOIN UVDeskCoreFrameworkBundle:TicketStatus s WITH t.status = s.id
  166.             LEFT JOIN UVDeskCoreFrameworkBundle:TicketPriority p WITH t.priority = p.id
  167.             LEFT JOIN UVDeskCoreFrameworkBundle:SupportGroup sg WITH c.idor = sg.id
  168.             LEFT JOIN UVDeskCoreFrameworkBundle:User a WITH t.agent = a.id
  169.             WHERE t.isTrashed = 0
  170.             ORDER BY t.createdAt DESC
  171.         ");
  172.         
  173.         $query->setMaxResults(5);
  174.         $tickets $query->getResult();
  175.         
  176.         // Formatear los datos para la respuesta
  177.         $formattedTickets = [];
  178.         foreach ($tickets as $ticket) {
  179.             $formattedTickets[] = [
  180.                 'ticketId' => $ticket['ticketId'],
  181.                 'subject' => $ticket['subject'],
  182.                 'status' => $ticket['status'],
  183.                 'priority' => $ticket['priority'],
  184.                 'createdAt' => $ticket['createdAt']->format('Y-m-d H:i:s'),
  185.                 'updatedAt' => $ticket['updatedAt'] ? $ticket['updatedAt']->format('Y-m-d H:i:s') : null,
  186.                 'customer' => [
  187.                     'id' => $ticket['customerId'],
  188.                     'name' => $ticket['customerFirstName'] . ' ' $ticket['customerLastName'],
  189.                     'email' => $ticket['customerEmail'],
  190.                     'idor' => $ticket['idor']
  191.                 ],
  192.                 'region' => [
  193.                     'name' => $ticket['supportGroupName'] ?: 'Sin región asignada',
  194.                     'description' => $ticket['supportGroupDescription'] ?: ''
  195.                 ],
  196.                 'agent' => $ticket['agentId'] ? [
  197.                     'id' => $ticket['agentId'],
  198.                     'name' => $ticket['agentFirstName'] . ' ' $ticket['agentLastName'],
  199.                     'email' => $ticket['agentEmail']
  200.                 ] : null
  201.             ];
  202.         }
  203.         
  204.         return new JsonResponse($formattedTickets);
  205.     }
  206.     public function getAgentsAction(): JsonResponse
  207.     {
  208.         $entityManager $this->getDoctrine()->getManager();
  209.         $query $entityManager->createQuery("
  210.             SELECT 
  211.                 a.id as agentId,
  212.                 a.firstName,
  213.                 a.lastName,
  214.                 a.email,
  215.                 a.isEnabled,
  216.                 a.lastactivity,
  217.                 a.idor,
  218.                 sg.name as supportGroupName,
  219.                 sg.description as supportGroupDescription,
  220.                 sr.code as supportRoleCode
  221.             FROM UVDeskCoreFrameworkBundle:User a
  222.             JOIN UVDeskCoreFrameworkBundle:UserInstance ui WITH a.id = ui.user
  223.             JOIN UVDeskCoreFrameworkBundle:SupportRole sr WITH ui.supportRole = sr.id
  224.             LEFT JOIN UVDeskCoreFrameworkBundle:SupportGroup sg WITH a.idor = sg.id
  225.             WHERE a.isEnabled = 1
  226.             AND sr.code = 'ROLE_AGENT'
  227.             ORDER BY a.firstName, a.lastName
  228.         ");
  229.         
  230.         $agents $query->getResult();
  231.         
  232.         $formattedAgents = [];
  233.         foreach ($agents as $agent) {
  234.             $formattedAgents[] = [
  235.                 'id' => $agent['agentId'],
  236.                 'name' => $agent['firstName'] . ' ' $agent['lastName'],
  237.                 'email' => $agent['email'],
  238.                 'isActive' => $agent['isEnabled'],
  239.                 'lastActivity' => $agent['lastactivity'] ? $agent['lastactivity']->format('Y-m-d H:i:s') : 'N/A',
  240.                 'idor' => $agent['idor'],
  241.                 'role' => $agent['supportRoleCode'],
  242.                 'region' => [
  243.                     'name' => $agent['supportGroupName'] ?: 'Sin región asignada',
  244.                     'description' => $agent['supportGroupDescription'] ?: 'No hay descripción disponible'
  245.                 ]
  246.             ];
  247.         }
  248.         
  249.         return new JsonResponse($formattedAgents);
  250.     }
  251.     
  252.     public function assignAgentAction(Request $request): JsonResponse
  253.     {
  254.         try {
  255.             $data json_decode($request->getContent(), true);
  256.             
  257.             if (!isset($data['ticketId']) || !isset($data['agentId'])) {
  258.                 return new JsonResponse([
  259.                     'success' => false,
  260.                     'message' => 'Se requieren ticketId y agentId'
  261.                 ], 400);
  262.             }
  263.             
  264.             $ticketId = (int) $data['ticketId'];
  265.             $agentId = (int) $data['agentId'];
  266.             
  267.             $entityManager $this->getDoctrine()->getManager();
  268.             
  269.             // Verificar que el ticket existe
  270.             $ticket $entityManager->getRepository('UVDeskCoreFrameworkBundle:Ticket')->find($ticketId);
  271.             if (!$ticket) {
  272.                 return new JsonResponse([
  273.                     'success' => false,
  274.                     'message' => 'El ticket especificado no existe'
  275.                 ], 404);
  276.             }
  277.             
  278.             // Verificar que el agente existe y está activo
  279.             $agent $entityManager->getRepository('UVDeskCoreFrameworkBundle:User')->find($agentId);
  280.             if (!$agent) {
  281.                 return new JsonResponse([
  282.                     'success' => false,
  283.                     'message' => 'El agente especificado no existe'
  284.                 ], 404);
  285.             }
  286.             
  287.             if (!$agent->getIsEnabled()) {
  288.                 return new JsonResponse([
  289.                     'success' => false,
  290.                     'message' => 'El agente especificado no está activo'
  291.                 ], 400);
  292.             }
  293.             
  294.             // Verificar que el usuario tiene rol de agente
  295.             $userInstance $entityManager->getRepository('UVDeskCoreFrameworkBundle:UserInstance')
  296.                 ->findOneBy(['user' => $agentId]);
  297.             
  298.             if (!$userInstance) {
  299.                 return new JsonResponse([
  300.                     'success' => false,
  301.                     'message' => 'El usuario especificado no tiene instancia de agente'
  302.                 ], 400);
  303.             }
  304.             
  305.             $supportRole $userInstance->getSupportRole();
  306.             if (!$supportRole || $supportRole->getCode() !== 'ROLE_AGENT') {
  307.                 return new JsonResponse([
  308.                     'success' => false,
  309.                     'message' => 'El usuario especificado no tiene rol de agente'
  310.                 ], 400);
  311.             }
  312.             
  313.             // Asignar el agente al ticket
  314.             $ticket->setAgent($agent);
  315.             
  316.             // Persistir los cambios
  317.             $entityManager->flush();
  318.             
  319.             return new JsonResponse([
  320.                 'success' => true,
  321.                 'message' => 'Ticket asignado exitosamente al agente',
  322.                 'data' => [
  323.                     'ticketId' => $ticketId,
  324.                     'agentId' => $agentId,
  325.                     'agentName' => $agent->getFirstName() . ' ' $agent->getLastName()
  326.                 ]
  327.             ]);
  328.             
  329.         } catch (\Exception $e) {
  330.             return new JsonResponse([
  331.                 'success' => false,
  332.                 'message' => 'Error interno del servidor: ' $e->getMessage()
  333.             ], 500);
  334.         }
  335.     }
  336. }