src/Controller/App/AcessoClienteController.php line 304

Open in your IDE?
  1. <?php
  2. namespace App\Controller\App;
  3. use App\Application\Sonata\UserBundle\Entity\User;
  4. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  5. use Symfony\Component\Routing\Annotation\Route;
  6. use Symfony\Component\HttpFoundation\JsonResponse;
  7. use Symfony\Component\HttpFoundation\Request;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\Serializer\Encoder\JsonEncoder;
  10. use App\Entity\AcessoCliente;
  11. use App\Entity\Cliente;
  12. use App\Entity\RelatorioTecnico;
  13. use App\Entity\OrdemDeServico;
  14. use App\Entity\Concretagem;
  15. use App\Entity\RelatorioIndividualMassa;
  16. use App\Entity\RelatorioTecnicoMassa;
  17. use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
  18. use Knp\Snappy\Pdf;
  19. class AcessoClienteController extends AbstractController
  20. {
  21.     
  22.     private $snappyPDF;
  23.     
  24.     public function __construct(Pdf $snappyPDF)
  25.     {
  26.         $this->snappyPDF $snappyPDF;
  27.     }
  28.     
  29.     /**
  30.      * @Route("/acesso-cliente", name="acesso_cliente", methods={"GET"})
  31.      */
  32.     public function acessoCliente(Request $request)
  33.     {
  34.         return $this->render('acessoCliente/index.html.twig');
  35.     }
  36.     
  37.     ##### API PUBLICA CLIENTE #####\
  38.     
  39.     /**
  40.      * @Route("/acesso-cliente/relatorio-pdf-os/{id}/{token}", name="acesso_cliente_relatorio_pdf_os", methods={"GET"})
  41.      */
  42.     public function acessoRelatorioClienteOs(Request $request$id$token)
  43.     {
  44.         $acessoCliente $this->userIsValid($token);
  45.         if(!$acessoCliente instanceof AcessoCliente){
  46.             return new JsonResponse(['message'=>'Usuário não autenticado'], Response::HTTP_FORBIDDEN);
  47.         }
  48.         
  49.         $relatorio $this->getDoctrine()->getRepository(RelatorioTecnico::class)->find($id);
  50.         if(!$relatorio instanceof RelatorioTecnico){
  51.             return new JsonResponse(['message'=>sprintf('Relatório não localizado com o id: %s'$id)], Response::HTTP_FORBIDDEN);
  52.         }
  53.         
  54.         // Esse Relatório é desse cliente
  55.         if($relatorio->getOrdemServico()->getProposta()->getCliente()->getId() != $acessoCliente->getCliente()->getId()){
  56.             return new JsonResponse(['message'=>sprintf('Relatório não localizado com o id para este cliente: %s'$id)], Response::HTTP_FORBIDDEN);
  57.         }
  58.         
  59.         $basedir $this->getParameter('kernel.root_dir') . '/../public' $request->getBasePath();
  60.         
  61.         if($relatorio->getRelatorioAnexo()){
  62.             
  63.             $file=$basedir '/' $relatorio->getRelatorioAnexo();
  64.             header('Content-type: application/pdf');
  65.             header('Content-Disposition: inline; filename="the.pdf"');
  66.             header('Content-Transfer-Encoding: binary');
  67.             header('Content-Length: ' filesize($file));
  68.             @readfile($file);
  69.             
  70.         } else {
  71.             
  72.         
  73.         #### MOCKUP RELATORIO
  74.         $imagensCadastradasNaOsParaCada = [];
  75.         /** @var ImagemRelatorio $imagem */
  76.         foreach ($relatorio->getImagensrelatorio() as $imagem) {
  77.             $imagensCadastradasNaOsParaCada[] = [
  78.                 'resultado_id'=> $imagem->getId(),
  79.                 'resultado_figura' => $basedir '/uploads/' $imagem->getLogo(),
  80.                 'resultado_titulo' => $imagem->getTitulo(),
  81.                 'servico_id' => $imagem->getId(),
  82.                 'servico_titulo' => $imagem->getTitulo()
  83.             ];
  84.         }
  85.         ### MOCKUP RELATORIO
  86.         $params = [
  87.             'basedir' => $basedir,
  88.             'relatorio' => $relatorio,
  89.             'resultados' => $imagensCadastradasNaOsParaCada,
  90.             'total_paginas_resultados' => count($imagensCadastradasNaOsParaCada)+4,
  91.             'figura_resumo' => $relatorio->getLogoOriginal(),
  92.         ];
  93.         $headerHtml $this->renderView(
  94.             'RelatoriosTecnicos/header-relatorio-tecnico-pdf.html.twig'$params
  95.         );
  96.         $footerHtml $this->renderView(
  97.             'RelatoriosTecnicos/footer-relatorio-tecnico-pdf.html.twig'$params
  98.         );
  99.         $html $this->renderView('RelatoriosTecnicos/relatorio-tecnico-pdf.html.twig'$params);
  100.         return new PdfResponse(
  101.             $this->snappyPDF->getOutputFromHtml($html, [
  102.                 'orientation' => 'Portrait',
  103.                 'encoding' => 'utf-8',
  104.                 //'header-html' => $headerHtml,
  105.                 'header-spacing' => 0,
  106.                 //'footer-right' => 'Pagina [page]/[toPage]',
  107.                 'footer-html' => $footerHtml,
  108.                 'footer-font-size' => '9',
  109.                 'footer-spacing' => 4,
  110.                 'margin-top' => '12mm'// Para aparecer o header
  111.                 'margin-bottom' => '30mm'// Para aparecer o footer
  112.             ]),
  113.             'Relatorio Tecnico-'.$relatorio->getId().'.pdf',
  114.             'application/pdf',
  115.             'inline'
  116.         );
  117.         }
  118.         
  119.         exit();
  120.     }
  121.     
  122.     // Base64 URL encode
  123.     private function base64UrlEncode($data) {
  124.         return rtrim(strtr(base64_encode($data), '+/''-_'), '=');
  125.     }
  126.     
  127.     private function acessFileGoogleDrive($relatoriosMassaIndividual) {
  128.         
  129.         $filderGoogleDriveID '1iYGbxxixMt9_QWfbSFI-FDoN8G0FP8PP';
  130.         
  131.         $nomeArquivo basename($relatoriosMassaIndividual->getPathFile()); // garante só o nome
  132.         
  133.         $service_account_key '{
  134.           "type": "service_account",
  135.           "project_id": "ltec-arquivos",
  136.           "private_key_id": "bcec8a138b5a1731bc6a487b2f64a747c1b5246f",
  137.           "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCTBQKc11cVrUe5\nUaeKfHf3wlqbOQSJxEIOblZRaHYB+h+QdQPeZR442fx6Mfn4R6O0MJ82wnqtqvCr\nyI1DE7MA9Tv5XCpb9szUUiiqXPXkGu+4fKuogBWr5wDxX3+uJSI5x/wSq10aN1Rg\nUikYFkCtRYCO/JwtrC4JqpnhlqQB1Gx42Y1iTFqlVEGDMiafTO+ZZYaW8000jeED\nFWcQmyRMZfu++ywHHUUIbHwAxXg8cuaNEqLcXbRILJhsNOw20W7qJfGw0m8FiJfl\n0IOfDl9b6SmMCVh0cRAJndmPMLMQaZlK6NVKaicONYDG3RKSY4+gDtybUSzFkhWJ\n++zk0jBBAgMBAAECggEAAgGOPtIgZdMSuLhgwx6+K1MLVfVh9rhHF3fRdTRp8c52\nKkwydJEoJ6nvzEIM0WK23OFR9tcSAfckaA+pP8pPxbpS6mzjxhP4yQfi9qokj8t/\nTGLlG7w9r3YMOP7u2NM4Y5XzPlT4xQAOxm6wkVvSX5rkbW8MeYIRMcASb/XUgJLe\naBRTL3dd8mcVgDETNMLZobWqqH8SwDy+54IjSPLP2XI45p08VPUi1lwpEa3Z+97n\nXu4Ye1f+Cya1tLfDfEpw73ZlrQZ2PZRtUcYP4SrJBw1Q/ixZFcDTdZLcHgoEId/v\nJyalUbB/ofujXFVtFP1t9NkvhaNVvn4rPpRSH3lWwQKBgQDLpp1r15MhoksJZCG+\n4XZeqsGTChtFwNHfXEeehd8D63pHrlmsUUJWrJEWORhRKzbDpLBVlMoQEZFuwyyk\n/LDOda9IXsqDHSPD0a+7cMfEmJnE28dbyNh4H+XxE2bURLRwLT34hvxzAj6VW3Ob\n0zXCRlPA9NSy+Vp/q4wWH+v5EQKBgQC4z7w78FXpIs2ztmjSSDw5UL8vZ/3RZpEY\nsgcrNcFoqQqFhVHb1cirFe90/5gQmlIJ6AknJqmlLJXoVs8bxP21TxTJsQjGm9bd\nnH/six/UkK814sJOg/kBuD6wMCyV5hjrQacBmMEhn4hR14qNdT7Zy6CFjOfcrtPS\noYN2Wo9EMQKBgQCiK3/YTMahVfei9tXYhvoX0KptSPMGzNFTqMxvc/Nvz6iERFas\nXdkR5EF1DOpMWLk3eoHg5KczvImvRkTa7U5uWlDGtJVXa3D7kpL6FIlACLUKimlq\nsbmPjvcwzl5oUn3Nhnl+2x9VBkiH71dUkxCQMCip0009aEuktxrK04i5wQKBgGND\nMFcBPyN5DgL4dlR7d91RAV70+978t/ILrM4IkVklcgFFGjJ5IM7DeVnd7k78lBO+\nDSx6F6QfzmR8O8EujRZU41VxQMVr7nwZEpx6HR6Ol4zZvoNtXtENpJ39QfVBISE6\nofi5kwH8LbvHiSNxVdClDhKtG9vsCtmW5oUrHsgBAoGAOMx5OQ/uh66j1NoAN9Mp\nFyFOnns6GJABY9YxfMmHrW8kxkrrWzX/Hi7B9c8UDNL6GgrwIAWRlaVXrEzQYix2\na9dvoCJq0YUfM0i50oWZZ+9R7A16zIqRksmBPtB7+IvNZ0v0apAjfZ8nijlea92X\nfrxazWURBLkmCEtLv5Bml/I=\n-----END PRIVATE KEY-----\n",
  138.           "client_email": "ltec-acesso-arquivos@ltec-arquivos.iam.gserviceaccount.com",
  139.           "client_id": "113733670713829067657",
  140.           "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  141.           "token_uri": "https://oauth2.googleapis.com/token",
  142.           "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  143.           "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/ltec-acesso-arquivos%40ltec-arquivos.iam.gserviceaccount.com",
  144.           "universe_domain": "googleapis.com"
  145.         }';
  146.         // 2) Obter access_token da service account (seu código atual aqui)
  147.         $sa json_decode($service_account_keytrue);
  148.         
  149.         $header = [
  150.             "alg" => "RS256",
  151.             "typ" => "JWT"
  152.         ];
  153.         
  154.         $now time();
  155.         $payload = [
  156.             "iss"   => $sa["client_email"],
  157.             "scope" => "https://www.googleapis.com/auth/drive.readonly",
  158.             "aud"   => $sa["token_uri"],
  159.             "exp"   => $now 3600,
  160.             "iat"   => $now
  161.         ];
  162.         
  163.         $jwtHeader  $this->base64UrlEncode(json_encode($header));
  164.         $jwtPayload $this->base64UrlEncode(json_encode($payload));
  165.         $jwtUnsigned $jwtHeader "." $jwtPayload;
  166.         
  167.         openssl_sign($jwtUnsigned$signature$sa["private_key"], "sha256WithRSAEncryption");
  168.         $jwtSignature $this->base64UrlEncode($signature);
  169.         
  170.         $jwt $jwtUnsigned "." $jwtSignature;
  171.         
  172.         // 3) Troca JWT por access_token
  173.         $urlToken $sa["token_uri"];
  174.         $ch curl_init($urlToken);
  175.         curl_setopt($chCURLOPT_POSTtrue);
  176.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  177.         curl_setopt($chCURLOPT_POSTFIELDShttp_build_query([
  178.             "grant_type" => "urn:ietf:params:oauth:grant-type:jwt-bearer",
  179.             "assertion"  => $jwt
  180.         ]));
  181.         $responseToken curl_exec($ch);
  182.         curl_close($ch);
  183.         
  184.         $token json_decode($responseTokentrue);
  185.         
  186.         if (!isset($token["access_token"])) {
  187.             die("Erro ao obter access_token:\n" $responseToken);
  188.         }
  189.         
  190.         $accessToken $token['access_token'];
  191.         
  192.         // 5) Buscar o arquivo pelo nome dentro da pasta imported
  193.         // Monta a query: name='xxx.pdf' and 'PASTA_ID' in parents
  194.         // IMPORTANTE: escapar aspas simples
  195.         $nomeEscapado str_replace("'""\\'"$nomeArquivo);
  196.         $q "name='{$nomeEscapado}' and '{$filderGoogleDriveID}' in parents";
  197.         $qUrl urlencode($q);
  198.         
  199.         $urlBusca "https://www.googleapis.com/drive/v3/files"
  200.             "?q={$qUrl}"
  201.             "&fields=files(id,name,mimeType)";
  202.         
  203.         $ch curl_init($urlBusca);
  204.         curl_setopt($chCURLOPT_HTTPHEADER, [
  205.             "Authorization: Bearer $accessToken"
  206.         ]);
  207.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  208.         $responseBusca curl_exec($ch);
  209.         curl_close($ch);
  210.         
  211.         $resultBusca json_decode($responseBuscatrue);
  212.         
  213.         // DEBUG opcional:
  214.         // echo "<pre>"; var_dump($resultBusca); echo "</pre>"; exit;
  215.         
  216.         // 6) Verifica se achou algum arquivo
  217.         if (!isset($resultBusca["files"][0])) {
  218.             http_response_code(404);
  219.             die("Arquivo '{$nomeArquivo}' não encontrado na pasta imported.");
  220.         }
  221.         
  222.         $fileId   $resultBusca["files"][0]["id"];
  223.         $mimeType $resultBusca["files"][0]["mimeType"] ?? 'application/pdf';
  224.         
  225.         // 7) Baixar o arquivo pelo ID
  226.         $urlDownload "https://www.googleapis.com/drive/v3/files/{$fileId}?alt=media";
  227.         
  228.         $ch curl_init($urlDownload);
  229.         curl_setopt($chCURLOPT_HTTPHEADER, [
  230.             "Authorization: Bearer $accessToken"
  231.         ]);
  232.         curl_setopt($chCURLOPT_RETURNTRANSFERtrue);
  233.         $data curl_exec($ch);
  234.         $httpCode curl_getinfo($chCURLINFO_HTTP_CODE);
  235.         curl_close($ch);
  236.         
  237.         if ($httpCode !== 200) {
  238.             echo "Erro ao baixar arquivo. HTTP {$httpCode}<br><pre>";
  239.             var_dump($data);
  240.             echo "</pre>";
  241.             exit;
  242.         }
  243.         
  244.         // 8) Devolver o PDF
  245.         header("Content-Type: $mimeType");
  246.         header("Content-Disposition: inline; filename=\"{$nomeArquivo}\"");
  247.         echo $data;
  248.         exit;
  249.     }
  250.     
  251.     /**
  252.      * @Route("/acesso-cliente/relatorio-individual/{id}/{token}", name="acesso_cliente_relatorio_individual_pdf", methods={"GET"})
  253.      */
  254.     public function acessoRelatorioClienteIndividual(Request $request$id$token)
  255.     {
  256.         
  257.         //exit('Indisponível no momento. Este sistema está em manutenção.');
  258.         
  259.         
  260.         $dirSave "/www/wwwroot/gestor.ltec.eng.br/public/uploads/relatorios_massa/imported";
  261.         $relatoriosMassaIndividual $this->getDoctrine()->getRepository(RelatorioIndividualMassa::class)->find($id);
  262.         
  263.         if(!$relatoriosMassaIndividual instanceof RelatorioIndividualMassa){
  264.             exit('Arquivo não localizado');
  265.         }
  266.         
  267.         //$titulo = $this->criarSlug($relatoriosMassaIndividual->getTitulo());
  268.         //$titulo = str_ireplace('PDF', '', $titulo);
  269.         
  270.         $nomeArquivoLocal $dirSave '/' $relatoriosMassaIndividual->getPathFile();
  271.         // Verifique se o arquivo existe
  272.         if (file_exists($nomeArquivoLocal)) {
  273.             // Defina os cabeçalhos apropriados para PDF
  274.             header('Content-Type: application/pdf');
  275.             header('Content-Disposition: inline; filename="' $relatoriosMassaIndividual->getTitulo() . '.pdf"');
  276.             header('Content-Length: ' filesize($nomeArquivoLocal));
  277.         
  278.             // Abra o arquivo em modo binário para leitura
  279.             $arquivo fopen($nomeArquivoLocal'rb');
  280.         
  281.             // Envie o conteúdo binário do arquivo para o navegador
  282.             while (!feof($arquivo)) {
  283.                 echo fread($arquivo8192); // Leia e envie em pedaços
  284.             }
  285.         
  286.             // Feche o arquivo
  287.             fclose($arquivo);
  288.         } else {
  289.             $this->acessFileGoogleDrive($relatoriosMassaIndividual);
  290.         }
  291.         exit($titulo);
  292.     }
  293.     
  294.     function criarSlug($nomeArquivo) {
  295.         // Remove a acentuação
  296.         $nomeArquivo strtr($nomeArquivo'àáâãäåæçèéêëìíîïðñòóôõöøùúûüýÿ''aaaaaaaceeeeiiiinoooooouuuuyy');
  297.         
  298.         // Converte para maiúsculas
  299.         $nomeArquivo strtoupper($nomeArquivo);
  300.         
  301.         // Substitui espaços em branco por hífens
  302.         $nomeArquivo preg_replace('/\s+/''-'$nomeArquivo);
  303.         
  304.         // Remove caracteres especiais
  305.         $nomeArquivo preg_replace('/[^A-Za-z0-9\-]/'''$nomeArquivo);
  306.         
  307.         return $nomeArquivo;
  308.     }
  309.     
  310.     /**
  311.      * @Route("/acesso-cliente/relatorio-pdf/{id}/{token}", name="acesso_cliente_relatorio_pdf", methods={"GET"})
  312.      */
  313.     public function acessoRelatorioCliente(Request $request$id$token)
  314.     {
  315.         $acessoCliente $this->userIsValid($token);
  316.         if(!$acessoCliente instanceof AcessoCliente){
  317.             return new JsonResponse(['message'=>'Usuário não autenticado'], Response::HTTP_FORBIDDEN);
  318.         }
  319.         
  320.         // Tenho o cliente
  321.         
  322.         // Preciso pegar todas as os do cliente
  323.         $ossByClienteEntity $this->getDoctrine()->getRepository(OrdemDeServico::class)->findByCliente($acessoCliente->getCliente());
  324.         $relatorios = [];
  325.        
  326.         foreach ($ossByClienteEntity as $os) {
  327.             
  328.             // Pegar os moldes dentro do intervalo liberado
  329.             // (['os'=>$os],['ordemRelatorio'=>'asc','createdAt'=>'desc']
  330.             $moldesDaOsPorIntervalo $this->getDoctrine()->getRepository(Concretagem::class)->findByOsEIntervalo(
  331.                 $os,
  332.                 $acessoCliente->getDataInicial(), 
  333.                 $acessoCliente->getDataFinal()
  334.             );
  335.             
  336.             foreach ($moldesDaOsPorIntervalo as $molde) {
  337.                 
  338.                     $repo $this->getDoctrine()->getRepository(Concretagem::class);
  339.                     $id $molde->getId();
  340.                     $molde $repo->find($id);
  341.                     if(!$molde instanceof Concretagem) {
  342.                         throw new NotFoundHttpException(sprintf('Molde não localizado com o id: %s'$id));
  343.                     }
  344.                     
  345.                     // Criar um array de cps agrupados por prova e contraprova
  346.                     
  347.                     $linhasCP = [];
  348.                     
  349.                     
  350.                     $diasTestados = [];
  351.                     foreach($molde->getMoldes() as $moldeItem){
  352.                         // Busca se já tem alguem com o mesmo dia
  353.                         $key 'dias_'.$moldeItem->getDiasRompimento();
  354.                         
  355.                         if(array_key_exists($key,$linhasCP)){
  356.                             $linhasCP[$key][] = $moldeItem;
  357.                         } else {
  358.                             $diasTestados[] = $moldeItem->getDiasRompimento();
  359.                             $linhasCP[$key] = [$moldeItem];
  360.                         }
  361.                         
  362.                     }
  363.                     
  364.                     asort($diasTestados);
  365.                     
  366.                     $maiorValorCP 0;
  367.                     foreach($molde->getMoldes() as $moldeItem){
  368.                         if($moldeItem->getValorRompimento()>$maiorValorCP){
  369.                             $maiorValorCP $moldeItem->getValorRompimento();
  370.                         }
  371.                     }
  372.                     
  373.                     $valores = [];
  374.                     
  375.                     foreach($diasTestados as $diaTestado){
  376.                         $valores[$diaTestado] = 0;
  377.                     }
  378.                     
  379.                     foreach($linhasCP as $linha){
  380.                         $valores[$linha[0]->getDiasRompimento()] = $linha[0]->getValorRompimento();
  381.                     }
  382.                     
  383.                     $valores implode($valores,',');
  384.                     $diasTestados implode($diasTestados,'|');
  385.                     $maiorValorCPCalculado 0;
  386.                     
  387.                     
  388.                     $maiorValorCPCalculado = (($maiorValorCP*1000)/78.54)/10;
  389.             
  390.                     $params = [
  391.                         'molde' => $molde,
  392.                         'moldes' => $linhasCP,
  393.                         'maiorValor' => ceil($maiorValorCP),
  394.                         'maiorValorCalculado' => $maiorValorCPCalculado,
  395.                         'valores' => $valores,
  396.                         'diasTestados' => $diasTestados
  397.                     ];
  398.                     
  399.                     $relatorios[] = $params;
  400.                 
  401.             }
  402.             
  403.         }
  404.         
  405.         $html $this->renderView('Os/relatorios_cps.html.twig', ['relatorios'=>$relatorios]);
  406.         //return $this->render('Os/relatorio_cp.html.twig',$params);
  407.         return new PdfResponse(
  408.             $this->snappyPDF->getOutputFromHtml($html, [
  409.                 'orientation' => 'Portrait',
  410.                 'encoding' => 'utf-8',
  411.                 //'header-html' => $headerHtml,
  412.                 'header-spacing' => 0,
  413.                 //'footer-right' => 'Pagina [page]/[toPage]',
  414.                 //'footer-html' => $footerHtml,
  415.                 //'footer-font-size' => '9',
  416.                 //'footer-spacing' => 4,
  417.                 'margin-top' => '10mm'// Para aparecer o header
  418.                 'margin-bottom' => '5mm'// Para aparecer o footer
  419.             ]),
  420.             'Relatorio-cp-os-'.$id.'.pdf',
  421.             'application/pdf',
  422.             'inline'
  423.         );
  424.     }
  425.     
  426.     /**
  427.      * @Route("/acesso-cliente/login", name="acesso_cliente_login", methods={"POST"})
  428.      */
  429.     public function acessoClienteLogin(Request $request)
  430.     {
  431.         $data json_decode($request->getContent(), false);
  432.         
  433.         $acessoCliente $this->getDoctrine()->getRepository(AcessoCliente::class)->findOneBy(['email'=>$data->username,'senha'=>$data->senha]);
  434.         if(!$acessoCliente instanceof AcessoCliente) {
  435.             return new JsonResponse([], 400);
  436.         }
  437.         
  438.         // Refresh token
  439.         $acessoCliente->setToken($this->generateToken(40));
  440.         $this->getDoctrine()->getManager()->flush();
  441.         
  442.         return new JsonResponse([
  443.             'token'=>$acessoCliente->getToken()
  444.         ], Response::HTTP_OK);
  445.     }
  446.     
  447.     /**
  448.      * @Route("/acesso-cliente/relatorios-disponiveis", name="acesso_cliente_relatorios", methods={"POST"})
  449.      */
  450.     public function getRelatoriosDisponiveis(Request $request)
  451.     {
  452.         $data json_decode($request->getContent(), false);
  453.        
  454.         $user $this->userIsValid($data->token);
  455.         if(!$user instanceof AcessoCliente){
  456.             return new JsonResponse(['message'=>'Usuário não autenticado'], Response::HTTP_FORBIDDEN);
  457.         }
  458.         
  459.         $relatoriosCp = [];
  460.         
  461.         $relatoriosEntity $this->getDoctrine()->getRepository(AcessoCliente::class)->findBy([
  462.             'email'=>$user->getEmail(),
  463.             'token'=>$user->getToken(),
  464.         ]);
  465.         
  466.         $osPermitidas = [];
  467.         if(count($relatoriosEntity)){
  468.             if($relatoriosEntity[0]->getOsAcessos() != null){
  469.               if(count($relatoriosEntity[0]->getOsAcessos())>0){
  470.                     foreach($relatoriosEntity[0]->getOsAcessos() as $oss){
  471.                         $osPermitidas[] = $oss->getId();
  472.                     }
  473.               }  
  474.             }
  475.         }
  476.         
  477.         foreach ($relatoriosEntity as $relatorio) {
  478.             $dataInicial $relatorio->getDataInicial();
  479.             $dataFinal $relatorio->getDataFinal();
  480.         
  481.             if ($dataInicial instanceof \DateTimeInterface) {
  482.                 // Se dataFinal for null, adiciona 1 mês à dataInicial
  483.                 if (!$dataFinal) {
  484.                     $dataFinal = (clone $dataInicial)->add(new \DateInterval('P1M'));
  485.                 }
  486.         
  487.                 $relatoriosCp[] = [
  488.                     'id' => $relatorio->getId(),
  489.                     'finalidade' => 'Finalidade',
  490.                     'dataInicial' => $dataInicial->format('d/m/Y'),
  491.                     'dataFinal'   => $dataFinal->format('d/m/Y'),
  492.                     'tipo' => 'cp'
  493.                 ];
  494.             }
  495.         }
  496.         
  497.         // Get relatórios plataforma
  498.         $relatoriosData = [];
  499.         if(count($relatoriosEntity)){
  500.             if($relatoriosEntity[0]->getCliente() instanceof Cliente){
  501.                 
  502.                 $relatorios $this->getDoctrine()->getRepository(RelatorioTecnico::class)->findPorCliente($relatoriosEntity[0]->getCliente());
  503.                 foreach ($relatorios as $relatorio){
  504.                     
  505.                     if(!in_array($relatorio->getOrdemServico()->getId(), $osPermitidas) && count($osPermitidas)>0){
  506.                         continue;
  507.                     }
  508.                     
  509.                     $relatoriosData[] = [
  510.                         'id'=>$relatorio->getId(),
  511.                         'data'=>$relatorio->getCreatedAt()->format('d/m/Y'), 
  512.                         'os'=>$relatorio->getOrdemServico()->getProposta()->getNumeroFormatado(),
  513.                         'relatorioAnexo' => $relatorio->getRelatorioAnexo(),
  514.                         'isLiberadoParaCliente' => $relatorio->getIsLiberadoParaCliente(),
  515.                         'tipo' => 'os'
  516.                     ];
  517.                 }
  518.                 
  519.             }
  520.         }
  521.         
  522.         $relatoriosAgregados = [];
  523.         if(count($relatoriosEntity)){
  524.             if($relatoriosEntity[0]->getCliente() instanceof Cliente){
  525.                 $relatorios $this->getDoctrine()->getRepository(RelatorioTecnicoMassa::class)->findPorClienteAgregados($relatoriosEntity[0]->getCliente());
  526.                 foreach ($relatorios as $relatorio){
  527.                     
  528.                     if(!in_array($relatorio->getOs()->getId(), $osPermitidas) && count($osPermitidas)>0){
  529.                         continue;
  530.                     }
  531.                    
  532.                     $relatoriosInternos = [];
  533.                     
  534.                     $relatoriosMassaIndividual $this->getDoctrine()->getRepository(RelatorioIndividualMassa::class)->findBy(['relatorioTecnicoMassa'=>$relatorio], ['numero'=>'ASC''titulo'=>'ASC']);
  535.                     foreach ($relatoriosMassaIndividual as $relatorioMassaIndividual) {
  536.                         $relatoriosInternos[] = [
  537.                             'id' => $relatorioMassaIndividual->getId(),
  538.                             'titulo'=>str_ireplace('.pdf'''$relatorioMassaIndividual->getTitulo()), 
  539.                             'data'=>$relatorioMassaIndividual->getData()->format('d/m/Y'),
  540.                             'numero'=>str_pad($relatorioMassaIndividual->getNumero(), 3"0"STR_PAD_LEFT),
  541.                             'pecaConcretada'=>$relatorioMassaIndividual->getPecaConcretada(),
  542.                             'file'=>$relatorioMassaIndividual->getPathFile(),
  543.                         ];
  544.                     }
  545.                     
  546.                     $relatoriosAgregados[] = [
  547.                         'id'=>$relatorio->getId(),
  548.                         'data'=>$relatorio->getCreatedAt()->format('d/m/Y'), 
  549.                         'os'=>$relatorio->getOs()->getProposta()->getNumeroFormatado(),
  550.                         'relatorioAnexo' => '',
  551.                         'isLiberadoParaCliente' => true,
  552.                         'tipo' => 'agregado',
  553.                         'sub' => $relatoriosInternos
  554.                     ];
  555.                 }
  556.             }
  557.         }
  558.         
  559.         $showDocumentsDownload false;
  560.         
  561.         if(count($relatoriosEntity)>0) {
  562.             $showDocumentsDownload = ($relatoriosEntity[0]->getCliente()->getFranquia()->getId() == 1) ? true false;
  563.         }
  564.         
  565.         $relatoriosResult = ['cp'=>$relatoriosCp'plataforma'=>$relatoriosData'agregados' => $relatoriosAgregados
  566.         'showDocumentsDownload'=>$showDocumentsDownload'cnpj'=>''];
  567.         return new JsonResponse($relatoriosResultResponse::HTTP_OK);
  568.     }
  569.     
  570.     /**
  571.      * @Route("/acesso-cliente/muda-senha", name="muda_senha_acesso_cliente", methods={"PUT"})
  572.      */
  573.     public function mudaSenhaPeloCliente(Request $request)
  574.     {
  575.         return new JsonResponse([], Response::HTTP_OK);
  576.     }
  577.     
  578.     
  579.     #### TOOLS ####
  580.     private function generateToken($length 20
  581.     {
  582.         $characters '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  583.         $charactersLength strlen($characters);
  584.         $randomString '';
  585.         for ($i 0$i $length$i++) {
  586.             $randomString .= $characters[rand(0$charactersLength 1)];
  587.         }
  588.         return $randomString;
  589.     }
  590.     
  591.     private function userIsValid($token) {
  592.         $acessoCliente $this->getDoctrine()->getRepository(AcessoCliente::class)->findOneBy(['token'=>$token]);
  593.         if(!$acessoCliente instanceof AcessoCliente) {
  594.             return false;
  595.         }
  596.         
  597.         return $acessoCliente;
  598.     }
  599. }