src/Controller/UserController.php line 80

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\CompanyClient;
  4. use App\Entity\ResetPasswordRequest;
  5. use App\Entity\User;
  6. use App\Entity\Company;
  7. use App\Entity\Supplier;
  8. use App\Entity\CompanySupplier;
  9. use App\Entity\NotificationsConfig;
  10. use App\Form\ClientSearchType;
  11. use App\Form\UserFormType;
  12. use App\Form\UserAutoEditFormType;
  13. use App\Form\UserSearchType;
  14. use App\Repository\CompanyClientRepository;
  15. use App\Repository\UserRepository;
  16. use App\Repository\SupplierRepository;
  17. use App\Service\UtilService;
  18. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  19. use Symfony\Component\HttpFoundation\Request;
  20. use Symfony\Component\HttpFoundation\Response;
  21. use Symfony\Component\Routing\Annotation\Route;
  22. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  23. use Symfony\Component\Mime\Address;
  24. use App\Security\EmailVerifier;
  25. use App\Security\Voter\UserVoter;
  26. use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
  27. use Knp\Component\Pager\PaginatorInterface;
  28. use Symfony\Component\Mailer\MailerInterface;
  29. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  30. use Symfony\Component\Security\Core\Security;
  31. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  32. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  33. use Symfony\Component\HttpFoundation\StreamedResponse;
  34. use Symfony\Contracts\Translation\TranslatorInterface;
  35. use Symfony\Component\Translation\TranslatableMessage;
  36. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  37. use Doctrine\Persistence\ManagerRegistry;
  38. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  39. /**
  40.  * @Route({"en": "/user",
  41.  *          "es": "/usuario"})
  42.  */
  43. class UserController extends AbstractController
  44. {
  45.     private $emailVerifier;
  46.     private $emailApp;
  47.     public const PAGE_ELEMENTS 25;
  48.     private $translator;
  49.     private $util;
  50.     private $params;
  51.     private $security;
  52.     private $em;
  53.     public function __construct(
  54.         EmailVerifier $emailVerifier,
  55.         string $emailApp,
  56.         Security $security,
  57.         TranslatorInterface $translator,
  58.         ParameterBagInterface $params,
  59.         ManagerRegistry $doctrine,
  60.         UtilService $utilService)
  61.     {
  62.         $this->emailVerifier $emailVerifier;
  63.         $this->emailApp $emailApp;
  64.         $this->security $security;
  65.         $this->translator $translator;
  66.         $this->util $utilService;
  67.         $this->params $params;
  68.         $this->em $doctrine->getManager();
  69.     }
  70.     /**
  71.      * @Route({"en": "/list",
  72.      *         "es": "/listado"}, name="user_index", methods={"GET","POST"})
  73.      */
  74.     public function index(Request $requestUserRepository $userRepositoryPaginatorInterface $paginator): Response
  75.     {
  76.         $admin =$this->getUser();
  77.         $this->denyAccessUnlessGranted(UserVoter::EDIT$admin);
  78.         $searchUser = [];
  79.         $usersAvailable $this->util->getCompanyUsersAvailable($admin->getCompany());
  80.         $form $this->createForm(UserSearchType::class, $searchUser, ['user_admin' => $admin,'users_available'=>$usersAvailable,'method' => 'GET']);
  81.         $form->handleRequest($request);
  82.         $orderBy null;
  83.         $filters = [
  84.             ['field'=>'company','title'=>'Empresa'],
  85.             ['field'=>'ref','title'=>'Referencia'],
  86.             ['field'=>'name','title'=>'Nombre'],
  87.             ['field'=>'surname','title'=>'Apellidos'],
  88.             ['field'=>'role','title'=>'Rol'],
  89.             ['field'=>'email','title'=>'Email'],
  90.             ['field'=>'active','title'=>'Activo']
  91.         ];
  92.         if ($form->isSubmitted() && $form->isValid())
  93.         {
  94.             $orderBy $request->query->get('order_by');
  95.             $users $userRepository->findByName($form->getData(), $admin$orderBy);
  96.         } else {
  97.             $users $userRepository->buscarTodos($admin);
  98.         }
  99.         // Creating pagnination
  100.         $pagination $paginator->paginate(
  101.             $users,
  102.             $request->query->getInt('page'1),
  103.             self::PAGE_ELEMENTS
  104.         );
  105.         return $this->render('user/index.html.twig', [
  106.             'pagination' => $pagination,
  107.             'search_form' => $form->createView(),
  108.             'filters' => $filters,
  109.             'order_by' => $orderBy,
  110.             'user_logged' => $this->getUser(),
  111.             'navbarTitle' => $this->translator->trans("Usuarios")
  112.         ]);
  113.     }
  114.     /**
  115.      * @Route({"en": "/new",
  116.      *         "es": "/nuevo"}, name="user_new", methods={"GET","POST"})
  117.      */
  118.     public function new(Request $requestUserRepository $userRepositorySupplierRepository $supplierRepository): Response
  119.     {
  120.         $admin $this->getUser();
  121.         // check for "edit" access: calls all voters
  122.         $this->denyAccessUnlessGranted(UserVoter::EDIT$admin);
  123.         $em $this->em;
  124.         $usersAvailable $this->util->getCompanyUsersAvailable($admin->getCompany());
  125.         $formWcErrors null;
  126.         $formCliErrors null;
  127.         $allowNew true;
  128.         if($admin->getRole()!='ROLE_ADMIN'){
  129.             //límites licencia
  130.             $usersAvailable $this->util->getCompanyUsersAvailable($admin->getCompany());
  131.             $allowNew = !empty($usersAvailable['all']['available']);
  132.         }
  133.         $user = new User();
  134.         $license null;
  135.         if($request->getMethod()=='POST'){
  136.             $cid = !empty($request->request->get('user_form')['company']) ? intval($request->request->get('user_form')['company']) : 0;
  137.             if($cid){
  138.                 $company $em->getRepository(Company::class)->find($cid);
  139.                 $usersAvailable $this->util->getCompanyUsersAvailable($company);
  140.                 $license $this->util->getActiveLicense($company);
  141.             }
  142.         }
  143.         $form $this->createForm(UserFormType::class, $user, ['user_admin' => $admin,'users_available'=>$usersAvailable,'license'=>$license]);
  144.         $form->handleRequest($request);
  145.         $this->vichUploaderFixBug($request$user); //corregimos bug
  146.         if ($form->isSubmitted() && $form->isValid()) {
  147.             $company $form->get('company')->getData();
  148.             $role $form->get('role')->getData();
  149.             $wc_name = !empty($request->request->get('user_form')['wc_name']) ? $request->request->get('user_form')['wc_name'] : '';
  150.             $wc_address = !empty($request->request->get('user_form')['wc_address']) ? $request->request->get('user_form')['wc_address'] : '';
  151.             $wc_collab = !empty($request->request->get('user_form')['wc_collab']) ? true false;
  152.             $cli_name = !empty($request->request->get('user_form')['cli_name']) ? $request->request->get('user_form')['cli_name'] : '';
  153.             $cli_nif = !empty($request->request->get('user_form')['cli_nif']) ? $request->request->get('user_form')['cli_nif'] : '';
  154.             $cli_address = !empty($request->request->get('user_form')['cli_address']) ? $request->request->get('user_form')['cli_address'] : '';
  155.             $cli_description = !empty($request->request->get('user_form')['cli_description']) ? $request->request->get('user_form')['cli_description'] : '';
  156.             //límites licencia
  157.             if($admin->getRole()!='ROLE_ADMIN'){
  158.                 $usersAvailable $this->util->getCompanyUsersAvailable($admin->getCompany());
  159.                 $userType strtolower(str_replace('ROLE_','',$role));
  160.                 $allowNew = !empty($usersAvailable[$userType]['available']);
  161.                 if(!$allowNew){
  162.                     $msg_name in_array($userType,['supplier','user','client']) ? $this->translator->trans('usuarios') : $this->translator->trans('administradores');
  163.                     $user->setPhotoFile(null); //corregimos bug
  164.                     $this->addFlash('danger'$this->translator->trans('Ha alcanzado el límite de {name} para su licencia.',['{name}'=>$msg_name]));
  165.                     return $this->redirectToRoute('user_index');
  166.                 }
  167.             }
  168.             if($admin->getRole()=='ROLE_ADMIN' && empty($company)){
  169.                 try{
  170.                     $nif $this->params->get('app.addvance3d_nif');
  171.                 }
  172.                 catch(\Exception $e){
  173.                     $nif 'B88352091';
  174.                 }
  175.                 $company $em->getRepository(Company::class)->findOneBy(['nif'=>$nif]);
  176.                 $user->setCompany($company);
  177.                 if(empty($company)){
  178.                     $user->setPhotoFile(null); //corregimos bug
  179.                     $this->addFlash('danger'$this->translator->trans('No se ha encontrado a la empresa Addvance3d con NIF {nif}',['{nif}'=>$nif]));
  180.                     return $this->redirectToRoute('user_index');
  181.                 }
  182.             }
  183.             if(in_array($form->get('role')->getData(),['ROLE_SUPPLIER','ROLE_SUPPLIER_CHIEF'])){
  184.                 if(empty($wc_name)){
  185.                     $formWcErrors['wc_name']=true;
  186.                 }
  187.                 if(empty($wc_address)){
  188.                     $formWcErrors['wc_address']=true;
  189.                 }
  190.             }
  191.             if(in_array($form->get('role')->getData(),['ROLE_CLIENT'])){
  192.                 if(empty($cli_name)){
  193.                     $formCliErrors['cli_name']=true;
  194.                 }
  195.                 if(empty($cli_nif)){
  196.                     $formCliErrors['cli_nif']=true;
  197.                 }
  198.                 if(empty($cli_address)){
  199.                     $formCliErrors['cli_address']=true;
  200.                 }
  201.             }
  202.             if(empty($formWcErrors) && empty($formCliErrors)){
  203.                 $lastId $userRepository->findLastRef($company);
  204.                 $user->setRef($lastId);
  205.                 $user->setType($company->getType());
  206.                 $em->persist($user);
  207.                 $em->flush();
  208.                 $user->setPhotoFile(null); //corregimos bug
  209.                 if(!empty($wc_name) && !empty($wc_address)){
  210.                     $supplier = new Supplier();
  211.                     $supplier->setCompany($company);
  212.                     $supplier->setUser($user);
  213.                     $supplier->setAddress($wc_address);
  214.                     $supplier->setName($wc_name);
  215.                     $supplier->setCollab($wc_collab);
  216.                     $supplier->setCertifications('');
  217.                     $lastRef $supplierRepository->findLastRef();
  218.                     $supplier->setRef($lastRef);
  219.                     $em->persist($supplier);
  220.                     $user->setSupplier($supplier);
  221.                     $em->flush();
  222.                     $cs = new CompanySupplier();
  223.                     $cs->setCompany($company);
  224.                     $cs->setSupplier($supplier);
  225.                     $cs->setConfigStepBudget(true);
  226.                     $cs->setConfigStepChiefConfirm(true);
  227.                     $cs->setConfigStepInDelivery(true);
  228.                     $cs->setType(1);
  229.                     $em->persist($cs);
  230.                     $em->flush();
  231.                 }
  232.                 if(!empty($cli_name) && !empty($cli_nif) && !empty($cli_address)){
  233.                     $cli = new CompanyClient();
  234.                     $cli->setCompany($company);
  235.                     $cli->setName($cli_name);
  236.                     $cli->setNif($cli_nif);
  237.                     $cli->setAddress($cli_address);
  238.                     $cli->setDescription($cli_description);
  239.                     $cli->setUser($user);
  240.                     $em->persist($cli);
  241.                     $user->setCompanyClient($cli);
  242.                     $em->flush();
  243.                 }
  244.                 $this->addFlash('success'$this->translator->trans('Usuario creado correctamente'));
  245.                 // Notificaciones
  246.                 $data['message']='Nuevo usuario';
  247.                 $data['name']=$user->getName();
  248.                 $data['reference']=$user->getRef();
  249.                 $data['path_name']='user_show';
  250.                 $data['path_parameters']='id:'.$user->getId();
  251.                 $this->util->notifications($user->getCompany(), 1$data$this->getUser());
  252.                 // generate a signed url and email it to the user
  253.                 $this->emailVerifier->sendEmailConfirmation('app_validate_user'$user,
  254.                     (new TemplatedEmail())
  255.                         ->from(new Address($this->emailApp'Addvance3D'))
  256.                         ->to($user->getEmail())
  257.                         ->subject('Please confirm your Email')
  258.                         ->htmlTemplate('registration/confirmation_email.html.twig')
  259.                         ->context([
  260.                             'user' => $user,
  261.                         ])
  262.                 );
  263.                 return $this->redirectToRoute('user_index');
  264.             }
  265.         }
  266.         return $this->render('user/new.html.twig', [
  267.             'user' => $user,
  268.             'form' => $form->createView(),
  269.             'allowNew' => $allowNew,
  270.             'formWcErrors' => $formWcErrors,
  271.             'formCliErrors' => $formCliErrors,
  272.             'navbarTitle' => $this->translator->trans("Crear nuevo usuario")
  273.         ]);
  274.     }
  275.     /**
  276.      * @Route({"en": "/show/{id}",
  277.      *         "es": "/mostrar/{id}"}, name="user_show", methods={"GET"})
  278.      */
  279.     public function show(User $user): Response
  280.     {
  281.         return $this->render('user/show.html.twig', [
  282.             'user' => $user,
  283.             'navbarTitle' => $this->translator->trans("Usuario")
  284.         ]);
  285.     }
  286.     /**
  287.      * @Route({"en": "/edit/{id}",
  288.      *         "es": "/editar/{id}"}, name="user_edit", methods={"GET","POST"})
  289.      */
  290.     public function edit(Request $requestUser $userUserPasswordHasherInterface $passwordEncoder): Response
  291.     {
  292.         // check for "edit" access: calls all voters
  293.         $this->denyAccessUnlessGranted(UserVoter::EDIT$user);
  294.         $admin $this->getUser();
  295.         $adminRole $admin->getRole();
  296.         $userRole $user->getRole();
  297.         $userActive $user->getActive();
  298.         $autoedit $admin->getId() === $user->getId() ? true false;
  299.         $usersAvailable $this->util->getCompanyUsersAvailable($admin->getCompany());
  300.         if ($autoedit)
  301.         {
  302.             $form $this->createForm(UserAutoEditFormType::class, $user, ['user_admin' => $admin]);
  303.         }else
  304.         {
  305.             $form $this->createForm(UserFormType::class, $user, ['user_admin' => $admin,'users_available'=>$usersAvailable]);
  306.         }
  307.         $form->handleRequest($request);
  308.         $this->vichUploaderFixBug($request$user$autoedit); //corregimos bug
  309.         if ($form->isSubmitted() && $form->isValid()) {
  310.             if ($form->has('newPassword'))
  311.             {
  312.                 if ($form->get('newPassword')->getData() !== null && $form->get('oldPassword')->getData() !== null) {
  313.                     if ( $passwordEncoder->isPasswordValid($user$form->get('oldPassword')->getData()) )
  314.                     {
  315.                         $user->setPassword(
  316.                             $passwordEncoder->hashPassword(
  317.                                 $user,
  318.                                 $form->get('newPassword')->getData()
  319.                             )
  320.                         );
  321.                     }else{
  322.                         $user->setPhotoFile(null); //corregimos bug
  323.                         $this->addFlash('error'$this->translator->trans('Clave introducida incorrecta'));
  324.                         return $this->redirectToRoute('user_edit',['id'=>$user->getId()]);
  325.                     }
  326.                 }
  327.             }
  328.             if (!$autoedit){
  329.                 //Control de roles
  330.                 $newRole $user->getRole();
  331.                 if($userRole != $newRole){
  332.                     $error false;
  333.                     $cType $user->getCompany()->getType();
  334.                     if($adminRole=='ROLE_ADMIN'){
  335.                         if( ($cType==&& !in_array($newRole,['ROLE_CLIENT','ROLE_USER','ROLE_CHIEF','ROLE_ADMIN'])) || ($cType==&& !in_array($newRole,['ROLE_SUPPLIER','ROLE_SUPPLIER_CHIEF'])) ){
  336.                             $error 'Los roles no son intercambiables entre usuarios OEMs y Service bureaus';
  337.                         }
  338.                     }
  339.                     else{
  340.                         $userType strtolower(str_replace('ROLE_','',$newRole));
  341.                         $allowNew = !empty($usersAvailable[$userType]['available']);
  342.                         if(!$allowNew){
  343.                             $msg_name in_array($userType,['supplier','user','client']) ? $this->translator->trans('usuarios') : $this->translator->trans('administradores');
  344.                             $error $this->translator->trans('Ha alcanzado el límite de {name} para su licencia.',['{name}'=>$msg_name]);
  345.                         }
  346.                     }
  347.                     if(!$error){
  348.                         //Si se quita un usuario administrador verificamos que exista otro
  349.                         if($userRole=='ROLE_CHIEF' || $userRole=='ROLE_SUPPLIER_CHIEF'){
  350.                             $usersChief $this->em->getRepository(User::class)->findBy(['company'=>$user->getCompany(),'role'=>$userRole]);
  351.                             if(empty($usersChief) || count($usersChief)==1){
  352.                                 $error 'Como mínimo debe haber un usuario administrador por empresa';
  353.                             }
  354.                         }
  355.                     }
  356.                     if($error){
  357.                         $user->setPhotoFile(null); //corregimos bug
  358.                         $this->addFlash('error'$this->translator->trans($error));
  359.                         return $this->redirectToRoute('user_index');
  360.                     }
  361.                 }
  362.                 //Activar usuario sin verificar con password genérico
  363.                 if($adminRole=='ROLE_ADMIN' && $form->has('not_verified') && $form->get('not_verified')->getData()){
  364.                     $user->setActive(true);
  365.                     $user->setPassword(
  366.                         $passwordEncoder->hashPassword(
  367.                             $user,
  368.                             123456
  369.                         )
  370.                     );
  371.                 }
  372.             }
  373.             $cli_name = !empty($request->request->get('user_form')['cli_name']) ? $request->request->get('user_form')['cli_name'] : '';
  374.             $cli_nif = !empty($request->request->get('user_form')['cli_nif']) ? $request->request->get('user_form')['cli_nif'] : '';
  375.             $cli_address = !empty($request->request->get('user_form')['cli_address']) ? $request->request->get('user_form')['cli_address'] : '';
  376.             $cli_description = !empty($request->request->get('user_form')['cli_description']) ? $request->request->get('user_form')['cli_description'] : '';
  377.             $cli $user->getCompanyClient();
  378.             if($cli_name != null) { $cli->setName($cli_name); }
  379.             if($cli_nif != null) { $cli->setNif($cli_nif); }
  380.             if($cli_address != null) { $cli->setAddress($cli_address); }
  381.             if($cli_description != null) { $cli->setDescription($cli_description); }
  382.             $this->em->persist($cli);
  383.             $this->em->flush();
  384.             $user->markAsUpdated();
  385.             $this->em->flush();
  386.             $user->setPhotoFile(null); //corregimos bug
  387.             $this->addFlash('success'$this->translator->trans('Usuario editado correctamente'));
  388.             if($user->getActive()!=$userActive){
  389.                 // Notificaciones
  390.                 $data['message']=$user->getActive()?'Usuario activado':'Usuario desactivado';
  391.                 $data['name']=$user->getName();
  392.                 $data['reference']=$user->getRef();
  393.                 $data['path_name']='user_show';
  394.                 $data['path_parameters']='id:'.$user->getId();
  395.                 $this->util->notifications($user->getCompany(), 1$data$this->getUser());
  396.             }
  397.             if ($autoedit)
  398.             {
  399.                 return $this->redirectToRoute('app_index');
  400.             }else
  401.             {
  402.                 return $this->redirectToRoute('user_index');
  403.             }
  404.         }
  405.         return $this->render('user/edit.html.twig', [
  406.             'user' => $user,
  407.             'form' => $form->createView(),
  408.             'formHasErrors' => $form->isSubmitted() && !$form->isValid(),
  409.             'autoedit' => $autoedit,
  410.             'navbarTitle' => $this->translator->trans("Editar usuario")
  411.         ]);
  412.     }
  413.     //Requerido para evitar bug VichUploaderBundle
  414.     private function vichUploaderFixBug(Request $requestUser $user$autoedit=false){
  415.         $formName $autoedit 'user_auto_edit_form' 'user_form';
  416.         if (!empty($request->files->get($formName)['photoFile']['file'])) {
  417.             $file $request->files->get($formName)['photoFile']['file'];
  418.             $mimesAllowed = ["image/jpeg""image/gif""image/png"];
  419.             $errorMsg '';
  420.             if($file->getSize()>20000000){
  421.                 $errorMsg.= $this->translator->trans('El tamaño máximo permitido del archivo es {limit} MB.',['{limit}'=>2]).'<br>';
  422.             }
  423.             if(!in_array($file->getMimeType(),$mimesAllowed)){
  424.                 $errorMsg.= $this->translator->trans('Los tipos de archivos permitidos son : {mime}',['{mime}'=>implode(',',$mimesAllowed)]);
  425.             }
  426.             if(!empty($errorMsg)){
  427.                 $user->setPhotoFile(null); //corregimos bug
  428.                 $this->addFlash('danger'$this->translator->trans($errorMsg));
  429.                 if($user->getId()>0){
  430.                     return $this->redirectToRoute('user_edit',['id'=>$user->getId()]);
  431.                 }
  432.                 else{
  433.                     return $this->redirectToRoute('user_new');
  434.                 }
  435.             }
  436.         }
  437.     }
  438.     /**
  439.      * @Route({"en": "/delete/{id}",
  440.      *         "es": "/borrar/{id}"}, name="user_delete", methods={"DELETE"})
  441.      */
  442.     public function delete(Request $requestUser $userMailerInterface $mailer): Response
  443.     {
  444.         $this->denyAccessUnlessGranted(UserVoter::DELETE$user);
  445.         if ($this->isCsrfTokenValid('delete'.$user->getId(), $request->request->get('_token'))) {
  446.             $entityManager $this->em;
  447.             try
  448.             {
  449.                 $admin $this->getUser();
  450.                 $userEmail $user->getEmail();
  451.                 $entityManager->remove($user);
  452.                 $entityManager->flush();
  453.                 $this->addFlash('success'$this->translator->trans('Usuario eliminado correctamente'));
  454.                 // Notificaciones
  455.                 $data['message']='Usuario borrado';
  456.                 $data['name']=$user->getName();
  457.                 $data['reference']=$user->getRef();
  458.                 $data['path_name']='user_index';
  459.                 $this->util->notifications($user->getCompany(), 1$data$this->getUser());
  460.             } catch (ForeignKeyConstraintViolationException $e) {
  461.                 $this->addFlash('danger'$this->translator->trans('No se puede eliminar un usuario asociado') );
  462.                 return $this->redirectToRoute('user_index');
  463.             }
  464.         }
  465.         return $this->redirectToRoute('user_index');
  466.     }
  467.     /**
  468.      * @Route({"en": "/export",
  469.      *         "es": "/exportar"}, name="user_export")
  470.      */
  471.     public function export(UserRepository $userRepository)
  472.     {
  473.         $admin =$this->getUser();
  474.         $company $admin->getCompany();
  475.         $colorARGB $company && $company->getCorporateColor() ? str_replace('#','',$company->getCorporateColor()) : 'DD9933';
  476.         $spreadsheet = new Spreadsheet();
  477.         $sheet $spreadsheet->getActiveSheet();
  478.         $sheet->setTitle('Addvance '.$this->translator->trans('Usuarios'));
  479.         $cells = ['A1','B1','C1','D1','E1','F1','G1','H1','I1','J1','K1','L1','M1','N1','O1'];
  480.         $fields = ['Referencia','Nombre','Apellidos','Rol','Email','Activo','Centro de trabajo','Departamento','Puesto','Teléfono',
  481.                    'Terminos aceptados','Aceptado el','Verificado','Fecha creación','Fecha modificación'];
  482.         if($admin->getRole()=='ROLE_ADMIN'){
  483.             array_unshift($fields,'Empresa');
  484.             $cells[]='P1';
  485.         }
  486.         foreach($fields as $k=>$field){
  487.             $sheet->getCell($cells[$k])->setValue($this->translator->trans($field));
  488.         }
  489.         $styleArrayFirstRow = [
  490.             'font' => [
  491.                 'bold' => true,
  492.                 'color' => array('rgb' => 'FFFFFF'),
  493.             ]
  494.         ];
  495.         $lastCell end($cells);
  496.         $sheet->getStyle('A1:'.$lastCell)->applyFromArray($styleArrayFirstRow);
  497.         $sheet
  498.             ->getStyle('A1:'.$lastCell)
  499.             ->getFill()
  500.             ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  501.             ->getStartColor()
  502.             ->setARGB($colorARGB);
  503.         $sheet->getDefaultColumnDimension()->setWidth(30);
  504.         // Increase row cursor after header write
  505.         $sheet->fromArray($userRepository->generateExport($admin),null'A2'true);
  506.         $writer = new Xlsx($spreadsheet);
  507.         $response =  new StreamedResponse(
  508.             function () use ($writer) {
  509.                 $writer->save('php://output');
  510.             }
  511.         );
  512.         $filename $this->translator->trans("AD2_usuarios_"). time() . ".xlsx";
  513.         $response->headers->set('Content-Type''application/vnd.ms-excel');
  514.         $response->headers->set('Content-Disposition''attachment;filename="'.$filename.'"');
  515.         $response->headers->set('Cache-Control','max-age=0');
  516.         return $response;
  517.     }
  518.     /**Clientes **********************************************************/
  519.     /**
  520.      * @Route({"en": "/client/list",
  521.      *         "es": "/clientes/listado"}, name="client_index", methods={"GET","POST"})
  522.      */
  523.     public function client(Request $requestCompanyClientRepository $ccRepositoryPaginatorInterface $paginator): Response
  524.     {
  525.         $admin =$this->getUser();
  526.         $search = [];
  527.         $usersAvailable $this->util->getCompanyUsersAvailable($admin->getCompany());
  528.         $form $this->createForm(ClientSearchType::class, $search, ['user_admin' => $admin,'users_available'=>$usersAvailable,'method' => 'GET']);
  529.         $form->handleRequest($request);
  530.         $orderBy null;
  531.         $filters = [
  532.             ['field'=>'company','title'=>'Empresa'],
  533.             ['field'=>'name','title'=>'Nombre'],
  534.             ['field'=>'nif','title'=>'NIF'],
  535.             ['field'=>'address','title'=>'Dirección'],
  536.             ['field'=>'description','title'=>'Descripción']
  537.         ];
  538.         if ($form->isSubmitted() && $form->isValid())
  539.         {
  540.             $orderBy $request->query->get('order_by');
  541.             $clients $ccRepository->findClient($form->getData(), $admin$orderBy);
  542.         } else {
  543.             $clients $ccRepository->findClient([],$admin);
  544.         }
  545.         // Creating pagnination
  546.         $pagination $paginator->paginate(
  547.             $clients,
  548.             $request->query->getInt('page'1),
  549.             self::PAGE_ELEMENTS
  550.         );
  551.         return $this->render('user/client.html.twig', [
  552.             'pagination' => $pagination,
  553.             'search_form' => $form->createView(),
  554.             'filters' => $filters,
  555.             'order_by' => $orderBy,
  556.             'user_logged' => $this->getUser(),
  557.             'navbarTitle' => $this->translator->trans("Clientes")
  558.         ]);
  559.     }
  560.     /**
  561.      * @Route({"en": "/manual",
  562.      *         "es": "/manual"}, name="user_manual", methods={"GET","POST"})
  563.      */
  564.     public function manual(Request $request) {
  565.         $webPath $this->getParameter('kernel.project_dir') . '/public/';
  566.         if($request->getLocale() == 'es') {
  567.             $md file_get_contents('user-manual/manual_ES.md');
  568.         } else {
  569.             $md file_get_contents('user-manual/manual_EN.md');
  570.         }
  571.         return $this->render('user/manual.html.twig', [
  572.             'md' => $md,
  573.             'navbarTitle' => $this->translator->trans("Manual de usuario")
  574.         ]);
  575.     }
  576. }