src/AdminBundle/Controller/TicketController.php line 743

Open in your IDE?
  1. <?php
  2. namespace AdminBundle\Controller;
  3. use Doctrine\ORM\EntityManagerInterface;
  4. use Sonata\AdminBundle\Admin\AdminHelper;
  5. use Sonata\AdminBundle\Admin\Pool;
  6. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  7. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  8. use DateTime;
  9. use CoreBundle\Services\Jira\JiraService;
  10. use CoreBundle\Entity\Ticket;
  11. use CoreBundle\Entity\TicketComment;
  12. use CoreBundle\Entity\TicketCommentFile;
  13. use CoreBundle\Entity\TicketFile;
  14. use CoreBundle\Entity\TicketTime;
  15. use CoreBundle\Entity\User;
  16. use CoreBundle\Entity\UserUtm;
  17. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  18. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  19. use Symfony\Component\HttpFoundation\File\UploadedFile;
  20. use Symfony\Component\HttpFoundation\JsonResponse;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  23. use Symfony\Component\Mailer\MailerInterface;
  24. use Symfony\Component\Mime\Address;
  25. use Symfony\Component\Mime\Email;
  26. use Symfony\Component\Routing\RouterInterface;
  27. class TicketController extends AbstractController
  28. {
  29.     protected \CoreBundle\Model\Ticket $ticketModel;
  30.     protected Pool $adminPool;
  31.     protected RouterInterface $router;
  32.     protected EntityManagerInterface $em;
  33.     public function __construct(\CoreBundle\Model\Ticket $ticketModelPool $adminPoolRouterInterface $routerEntityManagerInterface $em)
  34.     {
  35.         $this->ticketModel $ticketModel;
  36.         $this->adminPool $adminPool;
  37.         $this->router $router;
  38.         $this->em $em;
  39.     }
  40.     public function reportInit(Request $request): JsonResponse
  41.     {
  42.         $start = new DateTime($request->get('start'));
  43.         $end = new DateTime($request->get('end'));
  44.         $TiketTimes $this->em->getRepository(TicketTime::class)->getByPeriod($start,$end);
  45.         $result = [];
  46.         $prices = [
  47.             => 123,
  48.             11 => 107,
  49.             12 => 165,
  50.             13 => 165,
  51.         ];
  52.         /** @var TicketTime $tiketTime */
  53.         foreach ($TiketTimes as $tiketTime) {
  54.             $user $tiketTime->getTicket()->getDealer();
  55.             $userId $user $user->getId() : 'all';
  56.             $userName $user $user->getName() : 'Другие';
  57.             if(!isset($result[$userId])) {
  58.                 $result[$userId] = [
  59.                     'title' => $userName,
  60.                     'time' => [
  61.                         => 0,
  62.                         11 => 0,
  63.                         12 => 0,
  64.                         13 => 0,
  65.                     ],
  66.                     'task' => [],
  67.                 ];
  68.             }
  69.             $ticket $tiketTime->getTicket();
  70.             $result[$userId]['time'][$ticket->getWorkType()] = round(($result[$userId]['time'][$ticket->getWorkType()] + ($tiketTime->getTime()/60/60)),2);
  71.             $result[$userId]['cost'][$ticket->getWorkType()] = round(round($result[$userId]['time'][$ticket->getWorkType()],0)* $prices[$ticket->getWorkType()]);
  72.             if(!isset($result[$userId]['task'][$ticket->getId()])) {
  73.                 $result[$userId]['task'][$ticket->getId()] = [
  74.                     'title' => $ticket->getTitle(),
  75.                     'time' => 0,
  76.                 ];
  77.             }
  78.             $result[$userId]['task'][$ticket->getId()]['time'] = round(($result[$userId]['task'][$ticket->getId()]['time'] + ($tiketTime->getTime()/60/60)),2);
  79.         }
  80.         $userResult = [];
  81.         /** @var TicketTime $tiketTime */
  82.         foreach ($TiketTimes as $tiketTime) {
  83.             if(!$User $tiketTime->getUser()) {
  84.                 continue;
  85.             }
  86.             $name $User->getFullName();
  87.             $uId $User->getId();
  88.             $Date $tiketTime->getDateStart();
  89.             if(!isset($userResult[$uId])) {
  90.                 $userResult[$uId] = [
  91.                     'name' => $name,
  92.                     'total' => 0,
  93.                     'time' => [],
  94.                 ];
  95.             }
  96.             $fDate $Date->format('d.m.Y');
  97.             if(!isset($userResult[$uId]['time'][$fDate])) {
  98.                 $userResult[$uId]['time'][$fDate] = 0;
  99.             }
  100.             $userResult[$uId]['time'][$fDate] = round($userResult[$uId]['time'][$fDate]+($tiketTime->getTime()/60/60),2);
  101.             $userResult[$uId]['total'] = round($userResult[$uId]['total']+($tiketTime->getTime()/60/60),2);
  102.         }
  103.         return $this->json(['success' => true,'data' => $result'users' => $userResult]);
  104.     }
  105.     public function downloadReport2(Request $request): BinaryFileResponse
  106.     {   //отчет по UTM
  107.         $pDir $this->getParameter('kernel.project_dir');
  108.         $spreadsheet = new Spreadsheet();
  109.         $sheet $spreadsheet->getActiveSheet();
  110.         $sheet->setCellValue('A1'"Info_ID");
  111.         $sheet->getColumnDimension ('A') -> setWidth(10);
  112.         $sheet->setCellValue('B1''email');
  113.         $sheet->getColumnDimension ('B') -> setWidth(27);
  114.         $sheet->setCellValue('C1''Имя');
  115.         $sheet->getColumnDimension ('C') -> setWidth(14);
  116.         $sheet->setCellValue('D1''Фамилия');
  117.         $sheet->getColumnDimension ('D') -> setWidth(17);
  118.         $sheet->setCellValue('E1''Телефон');
  119.         $sheet->getColumnDimension ('E') -> setAutoSize (true);
  120.         $sheet->setCellValue('F1''Дата регистрации');
  121.         $sheet->getColumnDimension ('F') -> setWidth(27);
  122.         $sheet->setCellValue('G1''Тип');
  123.         $sheet->getColumnDimension ('G') -> setWidth(27);
  124.         $sheet->setCellValue('H1''URL');
  125.         $sheet->getColumnDimension ('H') -> setWidth(66);
  126.         $sheet->setCellValue('I1''Referrer');
  127.         $sheet->getColumnDimension ('I') -> setWidth(33);
  128.         //$sheet->getColumnDimension ('G') -> setAutoSize (true);
  129.         $sheet->setCellValue('J1''UTM1 NAME');
  130.         $sheet->getColumnDimension ('J') -> setAutoSize (true);
  131.         $sheet->setCellValue('K1''UTM1 VALUE');
  132.         $sheet->getColumnDimension ('K') -> setAutoSize (true);
  133.         $sheet->setCellValue('L1''UTM2 NAME');
  134.         $sheet->getColumnDimension ('L') -> setAutoSize (true);
  135.         $sheet->setCellValue('M1''UTM2 VALUE');
  136.         $sheet->getColumnDimension ('M') -> setAutoSize (true);
  137.         $sheet->setCellValue('N1''UTM3 NAME');
  138.         $sheet->getColumnDimension ('N') -> setAutoSize (true);
  139.         $sheet->setCellValue('O1''UTM3 VALUE');
  140.         $sheet->getColumnDimension ('O') -> setAutoSize (true);
  141.         $sheet->setCellValue('P1''UTM4 VALUE');
  142.         $sheet->getColumnDimension ('P') -> setAutoSize (true);
  143.         $sheet->setCellValue('Q1''UTM5 VALUE');
  144.         $sheet->getColumnDimension ('Q') -> setAutoSize (true);
  145.         $sheet->setCellValue('R1''UTM6 VALUE');
  146.         $sheet->getColumnDimension ('R') -> setAutoSize (true);
  147.         $sheet->calculateColumnWidths();
  148.         $start= new DateTime($request->get('start'));
  149.         $end= new DateTime($request->get('end'));
  150.         $userUtm$this->em->getRepository(UserUtm::class)->getUtmByPeriod($start,$end);
  151.             $i 1;
  152.         /** @var UserUtm $utm */
  153.             foreach ($userUtm as $utm) {
  154.                 if (strlen($utm->getReferrer())>1) {
  155.                     $refsrc explode("?"$utm->getReferrer());  //0-ссылка 1 - utm метки
  156.                 $i++;
  157.                 $i2 0;
  158.                 $pars explode("&"$refsrc[1]);
  159. //поля по БД
  160.                 $sheet->setCellValue('A' $i$utm->getId());
  161.                 $sheet->setCellValue('B' $i$utm->getUser()->getEmail());
  162.                 $sheet->setCellValue('C' $i$utm->getUser()->getFullName());
  163.                 $sheet->setCellValue('D' $i$utm->getUser()->getLastName());
  164.                 $sheet->setCellValue('E' $i$utm->getUser()->getPhone());
  165.                 $sheet->setCellValue('F' $i$utm->getCreatedAt()->format('d.m.Y H:m:s'));
  166.                     switch ($utm->getType()) {
  167.                         case User::UTM_REGISTRATION:
  168.                             $typeName 'Регистрация';
  169.                             break;
  170.                         case User::UTM_LOGIN:
  171.                             $typeName 'Авторизация';
  172.                             break;
  173.                         default:
  174.                             $typeName 'Не определено';
  175.                             break;
  176.                     }
  177.                 $sheet->setCellValue('G' $i$typeName);
  178.                 $sheet->setCellValue('H' $i$utm->getReferrer());
  179.                 $sheet->setCellValue('I' $i$refsrc[0]); // чистый реферрер до UTM меток
  180.                 //парсим поле с UTM метками и добавляем вправо данные по UTM1,2,3...
  181.                 foreach ($pars as $val1) {
  182.                     $i2++;
  183.                     $inpars explode("="$val1);
  184.                     if ($i2 == 1) {
  185.                         $sheet->setCellValue('J' $i$inpars[0]);
  186.                     } //UTM1 Name
  187.                     if ($i2 == 1) {
  188.                         $sheet->setCellValue('K' $i$inpars[1]);
  189.                     } //UTM1 Value
  190.                     if ($i2 == 2) {
  191.                         $sheet->setCellValue('L' $i$inpars[0]);
  192.                     } //UTM2 Name
  193.                     if ($i2 == 2) {
  194.                         $sheet->setCellValue('M' $i$inpars[1]);
  195.                     } //UTM2 Value
  196.                     if ($i2 == 3) {
  197.                         $sheet->setCellValue('N' $i$inpars[0]);
  198.                     } //UTM3 Name
  199.                     if ($i2 == 3) {
  200.                         $sheet->setCellValue('O' $i$inpars[1]);
  201.                     } //UTM3 Value
  202.                     if ($i2 == 4) {
  203.                         $sheet->setCellValue('P' $i$inpars[1]);
  204.                     } //UTM4 Value
  205.                     if ($i2 == 5) {
  206.                         $sheet->setCellValue('Q' $i$inpars[1]);
  207.                     } //UTM5 Value
  208.                     if ($i2 == 6) {
  209.                         $sheet->setCellValue('R' $i$inpars[1]);
  210.                     } //UTM6 Value
  211.                 }
  212.                     //if ($i2==5) {$sheet->setCellValue('J1', $inpars[0]);
  213.                 }
  214.                 }
  215.         $writer = new Xlsx($spreadsheet);
  216.         $name 'report_'.time().'.xlsx';
  217.         $writer->save($pDir.'/public/uploads/files/'.$name);
  218.         return $this->file($pDir.'/public/uploads/files/'.$name);
  219.     }
  220.     public function downloadReport(Request $request): BinaryFileResponse
  221.     {
  222.         $start = new DateTime($request->get('start'));
  223.         $end = new DateTime($request->get('end'));
  224.         $TiketTimes $this->em->getRepository(TicketTime::class)->getByPeriod($start,$end);
  225.         $result = [];
  226.         $prices = [
  227.             => 123,
  228.             11 => 107,
  229.             12 => 165,
  230.             13 => 165,
  231.         ];
  232.         /** @var TicketTime $tiketTime */
  233.         foreach ($TiketTimes as $tiketTime) {
  234.             $user $tiketTime->getTicket()->getDealer();
  235.             $userId $user $user->getId() : 'all';
  236.             $userName $user $user->getName() : 'На всех';
  237.             if(!isset($result[$userId])) {
  238.                 $result[$userId] = [
  239.                     'title' => $userName,
  240.                     'time' => [
  241.                         => 0,
  242.                         11 => 0,
  243.                         12 => 0,
  244.                         13 => 0,
  245.                     ],
  246.                     'task' => [],
  247.                 ];
  248.             }
  249.             $ticket $tiketTime->getTicket();
  250.             $result[$userId]['time'][$ticket->getWorkType()] = round(($result[$userId]['time'][$ticket->getWorkType()] + ($tiketTime->getTime()/60/60)),2);
  251.             $result[$userId]['cost'][$ticket->getWorkType()] = round(round($result[$userId]['time'][$ticket->getWorkType()],0)* $prices[$ticket->getWorkType()]);
  252.             if(!isset($result[$userId]['task'][$ticket->getId()])) {
  253.                 $result[$userId]['task'][$ticket->getId()] = [
  254.                     'title' => $ticket->getTitle(),
  255.                     'time' => 0,
  256.                 ];
  257.             }
  258.             $result[$userId]['task'][$ticket->getId()]['time'] = round(($result[$userId]['task'][$ticket->getId()]['time'] + ($tiketTime->getTime()/60/60)),2);
  259.         }
  260.         $pDir $this->getParameter('kernel.project_dir');
  261.         $spreadsheet = new Spreadsheet();
  262.         $sheet $spreadsheet->getActiveSheet();
  263.         $sheet->setCellValue('A1''Дилер');
  264.         $sheet->setCellValue('B1''Верстка (часы/гривны)');
  265.         $sheet->setCellValue('C1''Программирование (часы/гривны))');
  266.         $sheet->setCellValue('D1''Дизайн (часы/гривны');
  267.         $sheet->setCellValue('E1''Контент (часы/гривны)');
  268.         $sheet->setCellValue('F1''Итого, грн');
  269.         $i 1;
  270.         foreach ($result as $user) {
  271.             $i++;
  272.             $vTime $user['time'][13] ?? 0;
  273.             $pTime $user['time'][9] ?? 0;
  274.             $dTime $user['time'][12] ?? 0;
  275.             $cTime $user['time'][11] ?? 0;
  276.             $vCost $user['cost'][13] ?? 0;
  277.             $pCost $user['cost'][9] ?? 0;
  278.             $dCost $user['cost'][12] ?? 0;
  279.             $cCost $user['cost'][11] ?? 0;
  280.             $totalCost ceil($vCost+$pCost+$dCost+$cCost);
  281.             $sheet->setCellValue('A'.$i$user['title']);
  282.             $sheet->setCellValue('B'.$i$vTime.', ч. / '.$vCost.', грн');
  283.             $sheet->setCellValue('C'.$i$pTime.', ч. / '.$pCost.', грн');
  284.             $sheet->setCellValue('D'.$i$dTime.', ч. / '.$dCost.', грн');
  285.             $sheet->setCellValue('E'.$i$cTime.', ч. / '.$cCost.', грн');
  286.             $sheet->setCellValue('F'.$i$totalCost.', грн');
  287.         }
  288.         $writer = new Xlsx($spreadsheet);
  289.         $name 'report_'.time().'.xlsx';
  290.         $writer->save($pDir.'/public/uploads/files/'.$name);
  291.         return $this->file($pDir.'/public/uploads/files/'.$name);
  292.     }
  293.     public function uploadFiles(Request $requestEntityManagerInterface $emJiraService $jiraService): JsonResponse
  294.     {
  295.         $id $request->request->get('id');
  296.         $Ticket $em->getRepository(Ticket::class)->find($id);
  297.         if(!$Ticket) {
  298.             return $this->json(['success' => false]);
  299.         }
  300.         $files $request->files->get('fileInput');
  301.         foreach ($files as $file) {
  302.             $fileName $this->upload($file);
  303.             if($fileName) {
  304.                 $ticketFile = new TicketFile();
  305.                 $ticketFile->setFile($fileName);
  306.                 $ticketFile->setTicket($Ticket);
  307.                 $Ticket->addFile($ticketFile);
  308.                 $em->persist($ticketFile);
  309.                 $em->persist($Ticket);
  310.                 $em->flush();
  311.             }
  312.             if ($Ticket->getIssueId()) {
  313.                 $jiraService->sendFile($ticketFile$Ticket->getIssueId());
  314.             }
  315.         }
  316.         return $this->json(['success' => true'ticket' => $this->entityToArray($Ticket)]);
  317.     }
  318.     private function upload(UploadedFile $file)
  319.     {
  320.         $name $file->getClientOriginalName();
  321.         $rootDir $this->container->getParameter('kernel.project_dir');
  322.         $file->move(
  323.             $rootDir.'/public/uploads/files',
  324.             $name
  325.         );
  326.         return $name;
  327.     }
  328.     public function kanbanInit()
  329.     {
  330.         $User $this->getUser();
  331.         if(!$User) {
  332.             return new JsonResponse(['success' => false]);
  333.         }
  334.         $tickets $this->em->getRepository(Ticket::class)->getByState([],[8,3]);
  335.         $ticketsArray $this->ticketsToArray($tickets);
  336.         $userData = [
  337.             'id' => $User->getId(),
  338.             'name' => $User->getFullNAme(),
  339.         ];
  340.         $times = [
  341.             'month' => 0,
  342.             'yesterday' => 0,
  343.             'today' => 0,
  344.         ];
  345.         $now = new DateTime();
  346.         $yesterday = new DateTime('-1 day');
  347.         $start = new DateTime($now->format('Y-m-01 00:00:00'));
  348.         $Timers $this->em->getRepository(TicketTime::class)->getByPeriod($start,$now$this->getUser());
  349.         /** @var TicketTime $timer */
  350.         foreach ($Timers as $timer) {
  351.             $timerStart $timer->getDateStart();
  352.             $timerEnd $timer->getDateEnd() ?: new DateTime();
  353.             $diff $timerEnd->diff($timerStart);
  354.             $min = ($diff->24 60) + $diff->h*60 $diff->i;
  355.             $times['month'] += $min;
  356.             if($timerStart->format('Y-m-d') == $now->format('Y-m-d')) {
  357.                 $times['today'] += $min;
  358.             }
  359.             if($timerStart->format('Y-m-d') == $yesterday->format('Y-m-d')) {
  360.                 $times['yesterday'] += $min;
  361.             }
  362.         }
  363.         foreach ($times as $key => $min) {
  364.             $hours floor($min/60);
  365.             $min -= $hours*60;
  366.             $minStr $min 10 '0'.$min $min;
  367.             $times[$key] = $hours.':'.$minStr;
  368.         }
  369.         return new JsonResponse(['success' => true'time' => $times'types' => \CoreBundle\Model\Ticket::$works,  'priority' => \CoreBundle\Model\Ticket::$priority'tickets' => $ticketsArray'user' => $userData]);
  370.     }
  371.     private function ticketsToArray($tickets) {
  372.         $ticketsArray = [];
  373.         /** @var Ticket $ticket */
  374.         foreach ($tickets as $ticket) {
  375.             $ticketsArray[] = $this->entityToArray($ticket);
  376.         }
  377.         return $ticketsArray;
  378.     }
  379.     private function entityToArray(Ticket $ticket): array
  380.     {
  381.         $ticketItem = [
  382.             'id' => $ticket->getId(),
  383.             'title' => $ticket->getTitle(),
  384.             'content' => $ticket->getContent(),
  385.             'dateCreate' => $ticket->getDateCreate()->format('d.m.Y H:i'),
  386.             'state' => $ticket->getState(),
  387.             'priority' => $ticket->getPriority(),
  388.             'type' => $ticket->getWorkType(),
  389.             'totalTime' => $this->ticketModel->getTotalTime($ticket),
  390.             'editUrl' => $this->adminPool->getAdminByAdminCode('admin.ticket')->generateUrl('edit',['id' => $ticket->getId()]),
  391.             'showUrl' => $this->adminPool->getAdminByAdminCode('admin.ticket')->generateUrl('show',['id' => $ticket->getId()]),
  392.             'creator' => [
  393.                 'id' => $ticket->getCreator()->getId(),
  394.                 'name' => $ticket->getCreator()->getFullName(),
  395.             ],
  396.         ];
  397.         if($ticket->getAssigned()) {
  398.             $ticketItem['assigned'] = [
  399.                 'id' => $ticket->getAssigned()->getId(),
  400.                 'name' => $ticket->getAssigned()->getFullName(),
  401.             ];
  402.         }
  403.         if($ticket->getDealer()) {
  404.             $ticketItem['dealer'] = [
  405.                 'id' => $ticket->getDealer()->getId(),
  406.                 'name' => $ticket->getDealer()->getName(),
  407.             ];
  408.         }
  409.         if($Timer $this->ticketModel->getActiveTimer($ticket)) {
  410.             $now = new DateTime();
  411.             $start $Timer->getDateStart();
  412.             $diff $now->diff($start);
  413.             $ticketItem['activeTimer'] = [
  414.                 'id' => $Timer->getId(),
  415.                 'start' => $Timer->getDateStart()->format('m.d.Y H:i:s'),
  416.                 'time' => $diff->h.':'.$diff->i.':'.$diff->s,
  417.             ];
  418.         }
  419.         if($ticket->getFiles()->count()) {
  420.             $ticketItem['files'] = [];
  421.             /** @var TicketFile $file */
  422.             foreach ($ticket->getFiles() as $file) {
  423.                 $ticketItem['files'][] = [
  424.                     'name' => basename($file->getFile()),
  425.                     'href' => $this->router->generate('ticket_file_download',['id' => $file->getId()])
  426.                 ];
  427.             }
  428.         }
  429.         if($ticket->getComments()->count()) {
  430.             $ticketItem['comments'] = [];
  431.             /** @var TicketComment $comment */
  432.             foreach ($ticket->getComments() as $comment) {
  433.                 $commentItem = [
  434.                     'user' => $comment->getUser()->getFullName(),
  435.                     'date' => $comment->getDateCreate()->format('d.m.Y H:i'),
  436.                     'content' => $comment->getContent(),
  437.                     'files' => [],
  438.                 ];
  439.                 if(count($comment->getFiles())) {
  440.                     foreach ($comment->getFiles() as $file) {
  441.                         $commentItem['files'][] = [
  442.                             'name' => basename($file->getFile()),
  443.                             'href' => $this->router->generate('ticket_comment_file_download',['id' => $file->getId()])
  444.                         ];
  445.                     }
  446.                 }
  447.                 $ticketItem['comments'][] = $commentItem;
  448.             }
  449.         }
  450.         if($ticket->getTime()->count()) {
  451.             $ticketItem['times'] = [];
  452.             /** @var TicketTime $time */
  453.             foreach ($ticket->getTime() as $time) {
  454.                 $start $time->getDateStart();
  455.                 $end $time->getDateEnd();
  456.                 if(!$end) {
  457.                     $end = new DateTime();
  458.                 }
  459.                 $diff $end->diff($start);
  460.                 $min $diff->10 '0'.$diff->$diff->i;
  461.                 $ticketItem['times'][] = [
  462.                     'user' => $time->getUser() ? $time->getUser()->getFullName() : '',
  463.                     'dateStart' => $start->format('d.m.Y H:i'),
  464.                     'time' => $diff->h.':'.$min,
  465.                 ];
  466.             }
  467.         }
  468.         return $ticketItem;
  469.     }
  470.     public function changeState(Request $request)
  471.     {
  472.         $ticketId $request->get('ticketId');
  473.         $state $request->get('state');
  474.         $ticket $this->em->getRepository(Ticket::class)->find($ticketId);
  475.         $TicketModel $this->get('core.ticket.model');
  476.         switch ($state) {
  477.             case \CoreBundle\Model\Ticket::STATE_NEW:
  478.                 $TicketModel->toNew($ticket);
  479.                 break;
  480.             case \CoreBundle\Model\Ticket::STATE_DOING:
  481.                 $TicketModel->toDoing($ticket);
  482.                 break;
  483.             case \CoreBundle\Model\Ticket::STATE_WAIT:
  484.                 $TicketModel->toWait($ticket);
  485.                 break;
  486.             case \CoreBundle\Model\Ticket::STATE_DONE:
  487.                 $TicketModel->toDone($ticket);
  488.                 break;
  489.             case \CoreBundle\Model\Ticket::STATE_APPROVED:
  490.                 $TicketModel->toApproved($ticket);
  491.                 break;
  492.         }
  493.         $tickets $this->em->getRepository(Ticket::class)->getByState([],[\CoreBundle\Model\Ticket::STATE_APPROVED]);
  494.         $ticketsArray $this->ticketsToArray($tickets);
  495.         return new JsonResponse(['tickets' => $ticketsArray]);
  496.     }
  497.     public function deleteTicketFile($id)
  498.     {
  499.         $File $this->em->getRepository(TicketFile::class)->find($id);
  500.         if(!$File) {
  501.             return new JsonResponse(['success' => true]);
  502.         }
  503.         $rootDir $this->container->getParameter('kernel.project_dir');
  504.         $filePath $rootDir.'/public/uploads/files/'.$File->getFile();
  505.         if(file_exists($filePath)) {
  506.             unlink($filePath);
  507.         }
  508.         $this->em->remove($File);
  509.         $this->em->flush();
  510.         return new JsonResponse(['success' => true]);
  511.     }
  512.     public function downloadTicketFile($id): BinaryFileResponse
  513.     {
  514.         $File $this->em->getRepository(TicketFile::class)->find($id);
  515.         if(!$File) {
  516.             throw new NotFoundHttpException();
  517.         }
  518.         $rootDir $this->container->getParameter('kernel.project_dir');
  519.         $filePath $rootDir.'/public/uploads/files/'.$File->getFile();
  520.         if(!file_exists($filePath)) {
  521.             throw new NotFoundHttpException();
  522.         }
  523.         return $this->file($filePath);
  524.     }
  525.     public function downloadTicketCommentFile($id): BinaryFileResponse
  526.     {
  527.         $File $this->em->getRepository(TicketCommentFile::class)->find($id);
  528.         if(!$File) {
  529.             throw new NotFoundHttpException();
  530.         }
  531.         $rootDir $this->container->getParameter('kernel.project_dir');
  532.         $filePath $rootDir.'/public/uploads/files/'.$File->getFile();
  533.         if(!file_exists($filePath)) {
  534.             throw new NotFoundHttpException();
  535.         }
  536.         return $this->file($filePath);
  537.     }
  538.     public function timeStart(Request $request)
  539.     {
  540.         $ticketId $request->get('id');
  541.         $ticket $this->em->getRepository(Ticket::class)->find($ticketId);
  542.         if(!$ticket) {
  543.             return new JsonResponse(['success' => false'error' => 'Не удалось запустить таймер 1']);
  544.         }
  545.         if(!in_array($ticket->getState(),[\CoreBundle\Model\Ticket::STATE_DOING,\CoreBundle\Model\Ticket::STATE_STOP])) {
  546.             return new JsonResponse(['success' => false'error' => 'Не удалось запустить таймер 2']);
  547.         }
  548.         $user $this->getUser();
  549.         if($ticket && (!$ticket->getAssigned() || $ticket->getAssigned()->getId() != $user->getId())) {
  550.             return new JsonResponse(['success' => false'error' => 'Не удалось запустить таймер. Задача назначена на другого пользователя']);
  551.         }
  552.         if(!$user) {
  553.             return new JsonResponse(['success' => false'error' => 'Не удалось запустить таймер 3']);
  554.         }
  555.         $userTimers $this->em->getRepository(TicketTime::class)->findBy(['user' => $user'date_end' => null]);
  556.         if(count($userTimers)) {
  557.             foreach ($userTimers as $timer) {
  558.                 $timer->setDateEnd(new DateTime());
  559.                 $tTicket $timer->getTicket();
  560.                 $tTicket->setState(\CoreBundle\Model\Ticket::STATE_STOP);
  561.                 $this->em->persist($timer);
  562.                 $this->em->persist($tTicket);
  563.             }
  564.         }
  565.         $nTimer = new TicketTime();
  566.         $startDate = new DateTime();
  567.         $nTimer->setDateStart($startDate);
  568.         $nTimer->setUser($user);
  569.         $nTimer->setTicket($ticket);
  570.         $ticket->setState(\CoreBundle\Model\Ticket::STATE_DOING);
  571.         $this->em->persist($nTimer);
  572.         $this->em->persist($ticket);
  573.         $this->em->flush();
  574.         $this->ticketModel->sendChangeStatusNotify($ticket);
  575.         $tickets $this->em->getRepository(Ticket::class)->getByState([],[\CoreBundle\Model\Ticket::STATE_APPROVED]);
  576.         $ticketsArray $this->ticketsToArray($tickets);
  577.         return new JsonResponse(['success' => true'tickets' => $ticketsArray]);
  578.     }
  579.     public function timerStop(Request $request)
  580.     {
  581.         $timerId $request->get('id');
  582.         $user $this->getUser();
  583.         if(!$timerId || !$user) {
  584.             return new JsonResponse(['success' => false'error' => 'Не удалось остановить таймер']);
  585.         }
  586.         $timer $this->em->getRepository(TicketTime::class)->find($timerId);
  587.         if(!$timer || !$timer->getTicket()->getAssigned() || $timer->getTicket()->getAssigned()->getId() != $user->getId()) {
  588.             return new JsonResponse(['success' => false'error' => 'Не удалось остановить таймер']);
  589.         }
  590.         $timer->setDateEnd(new DateTime());
  591.         $tTicket $timer->getTicket();
  592.         $tTicket->setState(\CoreBundle\Model\Ticket::STATE_STOP);
  593.         $this->em->persist($timer);
  594.         $this->em->persist($tTicket);
  595.         $this->em->flush();
  596.         $this->ticketModel->sendChangeStatusNotify($tTicket);
  597.         $tickets $this->em->getRepository(Ticket::class)->getByState([],[\CoreBundle\Model\Ticket::STATE_APPROVED]);
  598.         $ticketsArray $this->ticketsToArray($tickets);
  599.         return new JsonResponse(['success' => true'tickets' => $ticketsArray]);
  600.     }
  601.     public function addComment(Request $requestMailerInterface $mailerRouterInterface $router): JsonResponse
  602.     {
  603.         $comment $request->get('comment');
  604.         $ticketId $request->get('id');
  605.         if(!$ticketId) {
  606.             return new JsonResponse(['success' => false]);
  607.         }
  608.         $ticket $this->em->getRepository(Ticket::class)->find($ticketId);
  609.         if(!$ticket) {
  610.             return new JsonResponse(['success' => false]);
  611.         }
  612.         $commentI = new TicketComment();
  613.         $commentI->setTicket($ticket);
  614.         $commentI->setUser($this->getUser());
  615.         $commentI->setContent($comment);
  616.         $commentI->setDateCreate(new DateTime());
  617.         $this->em->persist($commentI);
  618.         $this->em->flush($commentI);
  619.         $files $request->files->get('fileInput') ?? [];
  620.         foreach ($files as $file) {
  621.             $fileName $this->upload($file);
  622.             if($fileName) {
  623.                 $ticketCommentFile = new TicketCommentFile();
  624.                 $ticketCommentFile->setFile($fileName);
  625.                 $ticketCommentFile->setComment($commentI);
  626.                 $commentI->addFile($ticketCommentFile);
  627.                 $this->em->persist($ticketCommentFile);
  628.                 $this->em->persist($commentI);
  629.                 $this->em->flush();
  630.             }
  631.         }
  632.         $commentCreator $commentI->getUser();
  633.         $ticketCreator $ticket->getCreator();
  634.         $assigned $ticket->getAssigned();
  635.         $mailBody 'К задаче <b>'.$ticket->getTitle().'</b> добавлен новый комментарий.<br><b>'.$commentCreator->getFullName().':</b> '.$comment.'<br><a href="https://admin.vidi.ua'.$this->adminPool->getAdminByAdminCode('admin.ticket')->generateUrl('show',['id' => $ticket->getId()]).'">Подробнее</a>';
  636.         $message = (new Email())
  637.             ->subject('Новый коментарий к задачи.')
  638.             ->from(new Address($_ENV['DEFAULT_EMAIL_FROM'], 'TicketNotify'))
  639.             ->html($mailBody)
  640.         ;
  641.         if($commentCreator->getId() != $ticketCreator->getId()) {
  642.             $message->addTo($ticketCreator->getEmail());
  643.         }
  644.         if($assigned && $commentCreator->getId() != $assigned->getId()) {
  645.             $message->addTo($assigned->getEmail());
  646.         }
  647.         if ($message->getTo()){
  648.             $mailer->send($message);
  649.         }
  650.         $comment = [
  651.             'user' => $commentI->getUser()->getFullName(),
  652.             'date' => $commentI->getDateCreate()->format('d.m.Y H:i'),
  653.             'content' => $commentI->getContent(),
  654.             'files' => [],
  655.         ];
  656.         if(count($commentI->getFiles())) {
  657.             foreach ($commentI->getFiles() as $file) {
  658.                 $comment['files'][] = [
  659.                     'name' => basename($file->getFile()),
  660.                     'href' => $router->generate('ticket_comment_file_download',['id' => $file->getId()])
  661.                 ];
  662.             }
  663.         }
  664.         return new JsonResponse(['success' => true'comment' => $comment]);
  665.     }
  666.     public function init(): JsonResponse
  667.     {
  668.         $states = [
  669.             \CoreBundle\Model\Ticket::STATE_NEW,
  670.             \CoreBundle\Model\Ticket::STATE_CANCELED,
  671.             \CoreBundle\Model\Ticket::STATE_DONE,
  672.             \CoreBundle\Model\Ticket::STATE_STOP,
  673.             \CoreBundle\Model\Ticket::STATE_DOING,
  674.         ];
  675.         $users = [];
  676.         $creators = [];
  677.         $Tickets $this->em->getRepository(Ticket::class)->getToInit($states);
  678.         /** @var Ticket $ticket */
  679.         foreach($Tickets as $ticket) {
  680.             $user $ticket->getDealer();
  681.             $creator $ticket->getCreator();
  682.             if($user) {
  683.                 $users[$user->getId()] = $user->getName();
  684.             }
  685.             $creators[$creator->getId()] = $creator->getFullName();
  686.         }
  687.         $ticketsResult $this->ticketsToArray($Tickets);
  688.         $allStates \CoreBundle\Model\Ticket::$state;
  689.         foreach ($allStates as $key => $row) {
  690.             if(!in_array($key,$states) && $key != \CoreBundle\Model\Ticket::STATE_APPROVED) {
  691.                 unset($allStates[$key]);
  692.             }
  693.         }
  694.         return new JsonResponse([
  695.             'userId' => $this->getUser()->getId(),
  696.             'userName' => $this->getUser()->getFullName(),
  697.             'tickets' => $ticketsResult,
  698.             'states' => $allStates,
  699.             'dealers' => $users,
  700.             'creators' => $creators,
  701.             'types' => \CoreBundle\Model\Ticket::$works,
  702.             'priority' => \CoreBundle\Model\Ticket::$priority,
  703.         ]);
  704.     }
  705. }