src/Service/UtilService.php line 67

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\NotificationsConfig;
  4. use App\Entity\User;
  5. use App\Entity\Company;
  6. use App\Entity\License;
  7. use App\Entity\LicenseCompany;
  8. use App\Entity\Order;
  9. use App\Entity\Part;
  10. use App\Entity\Library;
  11. use App\Entity\Equipment;
  12. use App\Entity\Material;
  13. use App\Entity\Notifications;
  14. use Doctrine\ORM\EntityManagerInterface;
  15. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  16. use Psr\Log\LoggerInterface;
  17. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  18. use Symfony\Component\HttpFoundation\ParameterBag;
  19. use Symfony\Component\Security\Core\Security;
  20. use Endroid\QrCode\Builder\Builder;
  21. use Endroid\QrCode\Encoding\Encoding;
  22. use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
  23. use Endroid\QrCode\Label\Alignment\LabelAlignmentCenter;
  24. use Endroid\QrCode\Label\Font\NotoSans;
  25. use Endroid\QrCode\RoundBlockSizeMode\RoundBlockSizeModeMargin;
  26. use Endroid\QrCode\Writer\PngWriter;
  27. use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
  28. use Symfony\Component\Filesystem\Filesystem;
  29. use Symfony\Component\Filesystem\Path;
  30. use Symfony\Contracts\Translation\TranslatorInterface;
  31. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  32. use Symfony\Component\Mime\Address;
  33. use Symfony\Component\Mailer\MailerInterface;
  34. use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
  35. class UtilService
  36. {
  37.     private $em;
  38.     private $logger;
  39.     private $params;
  40.     private $user;
  41.     private $mailer;
  42.     private $emailApp;
  43.     private $rootDir;
  44.     private $env;
  45.     private $translator;
  46.     public function __construct(
  47.         EntityManagerInterface $em
  48.         LoggerInterface $logger
  49.         ParameterBagInterface $params,
  50.         TranslatorInterface $translator,
  51.         Security $security,
  52.         MailerInterface $mailer,
  53.         string $emailApp,
  54.         string $projectDir,
  55.         string $environment)
  56.     {        
  57.         $this->em $em;
  58.         $this->logger $logger;
  59.         $this->params $params;
  60.         $this->user $security->getUser();
  61.         $this->mailer $mailer;
  62.         $this->emailApp $emailApp;
  63.         $this->rootDir $projectDir;
  64.         $this->env $environment;
  65.         $this->translator $translator;
  66.     }
  67.     public function upload($uploadDir$file$filename)
  68.     {
  69.         try {
  70.             $file->move($uploadDir$filename);
  71.         } catch (FileException $e){
  72.             $this->logger->error('failed to upload image: ' $e->getMessage());
  73.             throw new FileException('Failed to upload file');
  74.         }
  75.     }
  76.     public function cutText(?string $txt$limit=255,$dots=true){
  77.         if($txt && strlen($txt)>$limit){
  78.             $txt substr($txt,0,$limit-4);
  79.             if($dots){
  80.                 $txt.=' ...';
  81.             }
  82.         }
  83.         return $txt;
  84.     }
  85.     /**
  86.      * @param string $msg
  87.      * @param int $type [1:info,2:notice,3:debug,4:error,5:warning,6:alert,7:critical]
  88.     */
  89.     public function setLog(string $msg,$type=1){
  90.         switch ($type){
  91.             case 1$this->logger->info($msg); break;
  92.             case 2$this->logger->notice($msg); break;
  93.             case 3$this->logger->debug($msg); break;
  94.             case 4$this->logger->error($msg); break;
  95.             case 5$this->logger->warning($msg); break;
  96.             case 6$this->logger->alert($msg); break;
  97.             case 7$this->logger->critical($msg); break;
  98.         }
  99.     }
  100.     public function generateQrCode(String $data,String $label=''$size=300$margin=10$base64=true){
  101.         $builder Builder::create()
  102.             ->writer(new PngWriter())
  103.             ->writerOptions([])
  104.             ->data($data)
  105.             ->labelText($label)
  106.             ->encoding(new Encoding('UTF-8'))
  107.             ->errorCorrectionLevel(new ErrorCorrectionLevelHigh())
  108.             ->size($size)
  109.             ->margin($margin)
  110.             ->roundBlockSizeMode(new RoundBlockSizeModeMargin())            
  111.             ->labelFont(new NotoSans(20))
  112.             ->labelAlignment(new LabelAlignmentCenter());
  113.         if($base64){
  114.             $file $builder->build();
  115.             return "data:image/png;base64,".base64_encode($file->getString());
  116.         }
  117.         else{
  118.             return $builder->build();
  119.         }
  120.     }
  121.     public function getLicenseField(Company $companystring $field){
  122.         $value null;
  123.         $fieldExplode explode('_',$field);
  124.         $get 'get';
  125.         foreach($fieldExplode as $part){
  126.             $get.= ucfirst($part);
  127.         }
  128.         $license =$this->em->getRepository(LicenseCompany::class)->findOneBy(['company'=>$company,'state'=>2]);
  129.         if(!empty($license)){
  130.             $value $license->getLicense()->$get();           
  131.         }
  132.         return $value;        
  133.     }
  134.     public function getCompanyUsersAvailable(Company $company){
  135.         $usersAvailable = [
  136.             'admin'=>['total'=>0,'in_use'=>0,'available'=>0,'role'=>'ROLE_ADMIN','label'=>'Superadministrador'],
  137.             'chief'=>['total'=>0,'in_use'=>0,'available'=>0,'role'=>'ROLE_CHIEF','label'=>'Administrador'],
  138.             'user'=>['total'=>0,'in_use'=>0,'available'=>0,'role'=>'ROLE_USER','label'=>'General'],
  139.             'client'=>['total'=>0,'in_use'=>0,'available'=>0,'role'=>'ROLE_CLIENT','label'=>'Cliente'],
  140.             'supplier'=>['total'=>0,'in_use'=>0,'available'=>0,'role'=>'ROLE_SUPPLIER','label'=>'Proveedor'],
  141.             'supplier_chief'=>['total'=>0,'in_use'=>0,'available'=>0,'role'=>'ROLE_SUPPLIER_CHIEF','label'=>'Proveedor (Administrador)'],
  142.             'all'=>['total'=>0,'in_use'=>0,'available'=>0],
  143.         ];
  144.         
  145.         foreach($usersAvailable as $type=>$data){  
  146.             if($type=='all')break;
  147.             $total intval($this->getLicenseField($company,'user_'.$type));   
  148.             $inUse 0;     
  149.             $available 0;            
  150.             if($total>0){
  151.                 $users $this->em->getRepository(User::class)->findBy(['company'=>$company,'role'=>$data['role']]);
  152.                 $inUse $users count($users) : 0;
  153.                 $available=($total-$inUse)>$total-$inUse 0;
  154.             }
  155.                 
  156.             $usersAvailable[$type]['total']=$total;
  157.             $usersAvailable[$type]['in_use']=$inUse;
  158.             $usersAvailable[$type]['available']=$available;
  159.             $usersAvailable['all']['total']+=$total;
  160.             $usersAvailable['all']['in_use']+=$inUse;
  161.             $usersAvailable['all']['available']+=$available;
  162.         }
  163.         return $usersAvailable;        
  164.     }
  165.     public function getCompanySuscriptionAvailable(LicenseCompany $licenseActive){
  166.         $company $licenseActive->getCompany();
  167.         $users $this->getCompanyUsersAvailable($company);
  168.         $partTotal $this->getLicenseField($company,'part_num');
  169.         $partInUse count($this->em->getRepository(Part::class)->findBy(['company'=>$company])); 
  170.         $libTotal $this->getLicenseField($company,'part_library');
  171.         $libInUse count($this->em->getRepository(Library::class)->findBy(['company'=>$company])); 
  172.         $suscriptionData = [
  173.             'license'=>$licenseActive->getLicense(),
  174.             'users'=>$users,
  175.             'parts'=>['total'=>$partTotal,'in_use'=>$partInUse,'available'=>($partTotal-$partInUse>0?$partTotal-$partInUse:0)],
  176.             'libraries'=>['total'=>$libTotal,'in_use'=>$libInUse,'available'=>($libTotal-$libInUse>0?$libTotal-$libInUse:0)],
  177.         ];
  178.         return $suscriptionData;
  179.     }
  180.     public function getCompanyFileMaxsizes(Company $company){
  181.         $fileMaxsizes = ['cad'=>0,'stl'=>0,'fab'=>0,'ver'=>0,'2d'=>0,'others'=>0,'budget'=>0,'report'=>0];
  182.         
  183.         foreach($fileMaxsizes as $field=>$num){    
  184.             if(in_array($field,['others','budget','report'])){
  185.                 $fileMaxsizes[$field] = intval(round($this->getLicenseField($company,'maxsize_'.$field)/5));
  186.             }
  187.             else{
  188.                 $fileMaxsizes[$field] = intval($this->getLicenseField($company,'maxsize_'.$field));
  189.             }
  190.             
  191.             if($fileMaxsizes[$field]<1){
  192.                 $fileMaxsizes[$field]=1;
  193.             }                        
  194.         }
  195.         return $fileMaxsizes;        
  196.     }
  197.     public function getActiveLicense(Company $company){
  198.         $license null;
  199.         $lc =$this->em->getRepository(LicenseCompany::class)->findOneBy(['company'=>$company,'state'=>2]);
  200.         if(!empty($lc)){
  201.             $license $lc->getLicense();           
  202.         }
  203.         return $license;        
  204.     }
  205.     public function getLicenseData(LicenseCompany $licenseActive){
  206.         $trans $this->translator;
  207.         $license $licenseActive->getLicense();
  208.         $licenseData = [
  209.             'general' => [
  210.                 'label' => $trans->trans('General'),
  211.                 'fields' => [
  212.                     'id'=>['label'=> $trans->trans('Id'),'data'=>$licenseActive->getId(),'type'=>'integer'],
  213.                     'name'=>['label'=> $trans->trans('Nombre'),'data'=>$license->getName(),'type'=>'string'],
  214.                     'added'=>['label'=> $trans->trans('Alta'),'data'=>$licenseActive->getDateAdded()->format('d-m-Y H:i'),'type'=>'string'],
  215.                     'start'=>['label'=> $trans->trans('Inicio'),'data'=>$licenseActive->getDateStart()->format('d-m-Y'),'type'=>'string'],
  216.                     'end'=>['label'=> $trans->trans('Fin'),'data'=>$licenseActive->getDateEnd()->format('d-m-Y'),'type'=>'string'],
  217.                 ]                    
  218.             ],                
  219.             'users' => [
  220.                 'label' => $trans->trans('Usuarios'),
  221.                 'fields' => [
  222.                     'user_client'=>['label'=> $trans->trans('Clientes')],
  223.                     'user_user'=>['label'=> $trans->trans('Generales')],
  224.                     'user_chief'=>['label'=> $trans->trans('Administradores')],
  225.                     'user_supplier'=>['label'=> $trans->trans('Proveedores')],
  226.                     'user_supplier_chief'=>['label'=> $trans->trans('Proveedores (adm)')]
  227.                 ],                    
  228.             ],
  229.             'inventory' => [
  230.                 'label' => $trans->trans('Inventario digital'),
  231.                 'fields' => [
  232.                     'part_library_type'=>['label'=> $trans->trans('Tipo')],
  233.                     'part_num'=>['label'=> $trans->trans('Piezas')],
  234.                     'part_library'=>['label'=> $trans->trans('Bibliotecas')],
  235.                     'part_version'=>['label'=> $trans->trans('Versionado')],
  236.                     'part_locked'=>['label'=> $trans->trans('Bloqueado')],
  237.                     'maxsize_cad'=>['label'=> $trans->trans('MS-CAD')],
  238.                     'maxsize_stl'=>['label'=> $trans->trans('MS-STL')],
  239.                     'maxsize_fab'=>['label'=> $trans->trans('MS-FAB')],
  240.                     'maxsize_ver'=>['label'=> $trans->trans('MS-VERIF')],
  241.                     'maxsize_2d'=>['label'=> $trans->trans('MS-2D')],
  242.                     'maxsize_others'=>['label'=> $trans->trans('MS-OTHERS')]
  243.                 ],                    
  244.             ],
  245.             'production' => [
  246.                 'label' => $trans->trans('Gestión de producción'),
  247.                 'fields' => [
  248.                     'wo_external'=>['label'=> $trans->trans('Externas')],
  249.                     'wo_internal'=>['label'=> $trans->trans('Internas')],
  250.                     'marketplace'=>['label'=> $trans->trans('Marketplace')],
  251.                     'wo_custom'=>['label'=> $trans->trans('Personalizable')],
  252.                     'search_supplier_cif'=>['label'=> $trans->trans('Búsqueda CT por CIF')],
  253.                     'search_supplier_marketplace'=>['label'=> $trans->trans('Búsqueda en MP')],
  254.                     'maxsize_budget'=>['label'=> $trans->trans('MS-BUDGET')],
  255.                     'maxsize_report'=>['label'=> $trans->trans('MS-REPORT')]
  256.                 ],                    
  257.             ],
  258.             'utilities'=>[
  259.                 'label' => $trans->trans('Utilidades'),
  260.                 'fields' => [
  261.                     'dashboard'=>['label'=> $trans->trans('Dashboard')],
  262.                     'massive_upload'=>['label'=>'Carga masiva'],
  263.                     'advanced_filter_search'=>['label'=>'Filtro y búsquedas avanzada'],
  264.                     'configurable_listings'=>['label'=>'Listados configurables'],
  265.                     'grid_display'=>['label'=>'Vista cuadrícula'],
  266.                     'hosting'=>['label'=> $trans->trans('Hosting')],
  267.                     'multi_select'=>['label'=> $trans->trans('Selección múltiple')],
  268.                     'graphic_custom'=>['label'=> $trans->trans('Personalización gráfica')],                    
  269.                     'part_comparison'=>['label'=> $trans->trans('Comparación piezas')],
  270.                 ],                    
  271.             ]
  272.         ];
  273.         $selects = [
  274.             'part_library_type' => [0=>'-',1=>$trans->trans('Simple'),2=>$trans->trans('Árbol')],
  275.             'wo_external' => [0=>'-',1=>$trans->trans('Recibir'),2=>$trans->trans('Enviar'),3=>$trans->trans('Recibir/enviar')],
  276.             'dashboard' => [0=>'-',1=>$trans->trans('Simple'),2=>$trans->trans('Personalizable')],
  277.             'hosting' => [0=>'-',1=>$trans->trans('Cloud'),2=>$trans->trans('Cloud/On-Premise')]
  278.         ];
  279.         foreach($licenseData as $catName=>$catData){
  280.             if($catName!='general'){
  281.                 foreach($catData['fields'] as $field=>$data){
  282.                     $fieldExplode explode('_',$field);
  283.                     $get 'get';
  284.                     foreach($fieldExplode as $part){
  285.                         $get.= ucfirst($part);
  286.                     }
  287.                     try {
  288.                         $value $license->$get();
  289.                         $value array_key_exists($field,$selects) && !empty($selects[$field][$value]) ? $selects[$field][$value] : $value;
  290.                     } catch (\Throwable $e) {
  291.                         $value='-';
  292.                     }
  293.                     
  294.                     $licenseData[$catName]['fields'][$field]['data']=$value;
  295.                     $licenseData[$catName]['fields'][$field]['type']=gettype($value);                    
  296.                 }
  297.             }
  298.         }
  299.         return $licenseData;
  300.     }
  301.     //Se elimina toda la actividad de la empresa. 
  302.     //Solo quedan los datos de la empresa y las licencias contratadas 
  303.     public function rmAccount(Company $company$entities=['library','user']){
  304.         $em $this->em;
  305.         $fs = new Filesystem();
  306.         $rootDir $this->rootDir;
  307.         $ds DIRECTORY_SEPARATOR;
  308.         $result = ['error'=>false,'msg'=>''];
  309.         try{
  310.             //Ordenes de trabajo
  311.             $orders $em->getRepository(Order::class)->findBy(['company'=>$company]);
  312.             if(!empty($orders)){
  313.                 $ordersDir $rootDir.$ds.'public'.$ds.'orders'.$ds;
  314.                 foreach($orders as $order){
  315.                     $files explode(',',$order->getFilesSupplier());
  316.                     if(!empty($files)){
  317.                         foreach($files as $file){
  318.                             if($fs->exists($ordersDir.$file) && !empty($file)){
  319.                                 $fs->remove($ordersDir.$file);
  320.                             }
  321.                         }
  322.                     }
  323.                     $em->remove($order);
  324.                 }
  325.                 $em->flush();
  326.             }
  327.             //Piezas
  328.             $parts $em->getRepository(Part::class)->findBy(['company'=>$company]);
  329.             if(!empty($parts)){
  330.                 $partsDir $rootDir.$ds.'public'.$ds.'parts'.$ds;
  331.                 $excelDir $partsDir.'excel'.$ds;
  332.                 foreach($parts as $part){
  333.                     $getters = ['getFilename','getFileCad','getFileStl','getFile2d','getFileFab','getFileVerif','getFile01','getFile02','getFile03','getFile04','getFile05','getBulkImportFile'];
  334.                     $files = [];
  335.                     $excelFile '';
  336.                     foreach($getters as $get){                        
  337.                         if($part->$get()){
  338.                             if($get=='getBulkImportFile'){
  339.                                 $excelFile=$part->$get();
  340.                             }
  341.                             else{
  342.                                 $files[]=$part->$get();
  343.                             }                            
  344.                         }
  345.                     }
  346.                     if(!empty($files)){
  347.                         foreach($files as $file){
  348.                             if($fs->exists($partsDir.$file) && !empty($file)){
  349.                                 $fs->remove($partsDir.$file);
  350.                             }
  351.                         }
  352.                     }
  353.                     if(!empty($excelFile)){
  354.                         if($fs->exists($excelDir.$excelFile)){
  355.                             $fs->remove($excelDir.$excelFile);
  356.                         }
  357.                     }
  358.                     $em->remove($part);
  359.                 }
  360.                 $em->flush();
  361.             }
  362.             //Equipos
  363.             $equipments $em->getRepository(Equipment::class)->findBy(['company'=>$company]);
  364.             if(!empty($equipments)){
  365.                 $dir $rootDir.$ds.'public'.$ds.'supplier';                   
  366.                 $getters = ['getImages','getFiles'];
  367.                 foreach($equipments as $entity){
  368.                     $filenames = [];
  369.                     foreach($getters as $getter){
  370.                         if($entity->$getter()){
  371.                             $filenames array_merge($filenamesexplode(',',$entity->$getter()));
  372.                         }
  373.                     }
  374.                     foreach($filenames as $fileToRemove){
  375.                         if($fs->exists($dir.$ds.$fileToRemove) && !empty($fileToRemove)){
  376.                             $fs->remove($dir.$ds.$fileToRemove);
  377.                         }   
  378.                     }
  379.                     $em->remove($entity);
  380.                 }
  381.                 $em->flush();
  382.             }
  383.             //Materiales
  384.             $materials $em->getRepository(Material::class)->findBy(['company'=>$company]);
  385.             if(!empty($materials)){
  386.                 $dir $rootDir.$ds.'public'.$ds.'supplier';                   
  387.                 $getters = ['getImages','getTechnicalFiles','getOtherFiles'];
  388.                 foreach($materials as $entity){
  389.                     $filenames = [];
  390.                     foreach($getters as $getter){
  391.                         if($entity->$getter()){
  392.                             $filenames array_merge($filenamesexplode(',',$entity->$getter()));
  393.                         }
  394.                     }
  395.                     foreach($filenames as $fileToRemove){
  396.                         if($fs->exists($dir.$ds.$fileToRemove) && !empty($fileToRemove)){
  397.                             $fs->remove($dir.$ds.$fileToRemove);
  398.                         }   
  399.                     }
  400.                     $em->remove($entity);
  401.                 }
  402.                 $em->flush();
  403.             }
  404.             //Bibliotecas / usuarios / proveedores [user=delete:cascade]
  405.             if(in_array('library'$entities)){
  406.                 $em->createQuery("DELETE App:Library e WHERE e.company = {$company->getId()}")->execute();
  407.             }
  408.             if(in_array('user'$entities)){
  409.                 $em->createQuery("DELETE App:User e WHERE e.company = {$company->getId()}")->execute();
  410.             }
  411.             return $result;           
  412.         }
  413.         catch (IOExceptionInterface $e) {
  414.             $msg "An error occurred while creating your directory at ".$e->getPath();
  415.             $this->logger->error($msg);
  416.             return ['error'=>true,'msg'=>$msg];
  417.         }
  418.         catch (\Doctrine\DBAL\Exception $e){
  419.             $msg "An error has occurred trying to remove company data - Error: {$e->getMessage()}. Line : {$e->getLine()}";
  420.             $this->logger->error($msg);
  421.             return ['error'=>true,'msg'=>$msg];
  422.         }
  423.         catch (\Exception $e){
  424.             $msg "An error has occurred trying to remove company data - Error: {$e->getMessage()}. Line : {$e->getLine()}";
  425.             $this->logger->error($msg);
  426.             return ['error'=>true,'msg'=>$msg];
  427.         }
  428.     }
  429.     public function email($tostring $subject, array $contextstring $template$from=null, ?array $addTo=null){
  430.         $result = ['error'=>false,'msg'=>''];
  431.         $from $from $from $this->emailApp;
  432.         $email = (new TemplatedEmail())
  433.             ->from(new Address($from'Addvance3D'))
  434.             ->to($to)            
  435.             ->subject($subject)
  436.             ->htmlTemplate($template)
  437.             ->context($context); 
  438.         if($addTo){
  439.             foreach($addTo as $to){
  440.                 $email->addTo($to);
  441.             }
  442.             
  443.         }
  444.         try {
  445.             $this->mailer->send($email);
  446.             return $result;
  447.         } catch (TransportExceptionInterface $e) {
  448.             return ['error'=>true,'msg'=>$e->getMessage()];
  449.         }
  450.     }
  451.     public function notifications(Company $companyint $group, array $data, ?User $author=null, ?int $idForeign=null){   
  452.         $message = !empty($data['message']) ? $data['message'] : '';   
  453.         $messageAux = !empty($data['message_aux']) ? $data['message_aux'] : '';
  454.         $name = !empty($data['name']) ? $data['name'] : '';
  455.         $reference = !empty($data['reference']) ? $data['reference'] : '';
  456.         $path_name = !empty($data['path_name']) ? $data['path_name'] : '';
  457.         $path_parameters = !empty($data['path_parameters']) ? $data['path_parameters'] : '';
  458.         $n = new Notifications;
  459.         $n->setCompany($company);
  460.         $n->setCreatedAt(new \DateTime());
  461.         $n->setGroup($group);
  462.         $n->setUser($author);
  463.         $n->setMessage($this->cutText($message,500));
  464.         $n->setMessageAux($this->cutText($messageAux));
  465.         $n->setName($name);
  466.         $n->setReference($reference);
  467.         $n->setPathName($path_name);
  468.         $n->setPathParameters($path_parameters);
  469.         $n->setIdForeign($idForeign);
  470.         $this->em->persist($n);
  471.         $this->em->flush();
  472.         //Notificaciones por email
  473.         $usersCompany $this->em->getRepository(User::class)->findBy(['company'=>$company]);
  474.         switch($group){
  475.             case 1$getGroup 'getGroupUser'; break;
  476.             case 2$getGroup 'getGroupPart'; break;
  477.             case 3$getGroup 'getGroupOrder'; break;
  478.             case 4$getGroup 'getGroupCollabExt'; break;
  479.             case 5$getGroup 'getGroupLibrary'; break;
  480.             default : $getGroup 'getGroupUser';
  481.         }
  482.         $addTo = [];
  483.         foreach($usersCompany as $user){
  484.             if($user->getNotificationsConfig() && $user->getNotificationsConfig()->$getGroup()==2){
  485.                 $addTo[]=$user->getEmail();
  486.             }
  487.         }
  488.         if($addTo){
  489.             $to array_shift($addTo);
  490.             if($messageAux){
  491.                 $context = ['msg' =>'<p>'.$this->translator->trans($message,['{aux}'=>$messageAux]). '</p>'];
  492.             }
  493.             else{
  494.                 $context = ['msg' =>'<p>'.$this->translator->trans($message). '</p>'];
  495.             }
  496.             
  497.             $this->email($to$this->translator->trans('Notificaciones'), $context'common/email.html.twig'null$addTo);            
  498.         }
  499.     }
  500.     public function getCssCorporateColor(Company $company){
  501.         $color $company->getCorporateColor();
  502.         $css = <<<EOT
  503.             <style>
  504.                 /*Top-menu*/
  505.                 .topbar {
  506.                     background: #color# !important;
  507.                 }
  508.                 /*Left-menu*/
  509.                 .sidebar-nav > ul > li.active > a {
  510.                     border-color: #color#;
  511.                 }
  512.                 .sidebar-nav ul li a.active i, .sidebar-nav ul li a:hover i {
  513.                     color: #color#;
  514.                 }
  515.                 /*Buttons*/
  516.                 .bg-primary {
  517.                     background-color: #color# !important;
  518.                 }  
  519.                 .btn-info, .btn-info:hover, .btn-primary, .btn-primary:hover, .dt-buttons .dt-button, .btn-success {
  520.                     background: #color# !important;
  521.                     background-color: #color# !important;
  522.                     border: 1px solid #color#;
  523.                 }
  524.                 .btn-inverse {
  525.                     border: 1px solid #color#;
  526.                 }
  527.                 .btn-inverse.active, .btn-inverse.focus, .btn-inverse:active, .btn-inverse:focus, .btn-inverse:hover, .btn-inverse:hover, .open>.dropdown-toggle.btn-inverse {
  528.                     border: 1px solid #color#;
  529.                 }
  530.                 .btn-inverse.active, .btn-inverse.focus, .btn-inverse:active, .btn-inverse:focus, .btn-inverse:hover, .btn-inverse:hover, .open>.dropdown-toggle.btn-inverse {
  531.                     background-color: #AAA;
  532.                 }
  533.                 .btn-success.disabled:hover, .btn-success:hover {
  534.                     background: #color#;
  535.                     border: 1px solid #color#;
  536.                 }
  537.                 /*Forms and tables*/
  538.                 .paginate_button.current, .paginate_button:hover {
  539.                     background-color: #color# !important;
  540.                     border: 1px solid #color# !important;
  541.                     color: white !important;
  542.                 }                   
  543.                 /*Index*/
  544.                 #notifications_header .card-text {
  545.                     color: #color# !important;
  546.                 }
  547.                 /*Others*/
  548.                 .text-primary {
  549.                     color: #color# !important;
  550.                 }
  551.                 .profile-tab li a.nav-link.active, .customtab li a.nav-link.active {
  552.                     border-bottom: 2px solid #color#;
  553.                     color: #color#;
  554.                 }
  555.                 .msg_txt_end {
  556.                     border-radius: 15px;
  557.                     padding: 5px 10px;
  558.                     border: 1px solid #color# !important;
  559.                     font-size: 14px;
  560.                 }
  561.                 .dropdown-item.active {
  562.                     background: #color# !important;
  563.                     color: white;
  564.                 }
  565.             </style> 
  566.         EOT;
  567.         if($color){
  568.             return str_replace('#color#',$company->getCorporateColor(),$css);
  569.         }
  570.         
  571.         return '';
  572.     }
  573.     public function fromHexToRgb(string $hex):string
  574.     {
  575.         $corporateColorArray str_split(str_replace('#','',$hex), 2);
  576.         $corporateColorRGB = [];
  577.         $rgb '';
  578.         if(count($corporateColorArray)===3){
  579.             foreach($corporateColorArray as $cc){
  580.                 $one = (int) str_replace(['A','B','C','D','E','F'],[10,11,12,13,14,15],substr(strtoupper($cc),0,1));
  581.                 $two = (int) str_replace(['A','B','C','D','E','F'],[10,11,12,13,14,15],substr(strtoupper($cc),1,1));
  582.                 $corporateColorRGB[]=$one*16 $two;
  583.             }
  584.             $rgb implode(',',$corporateColorRGB);
  585.         }    
  586.         return $rgb;
  587.     }
  588.     /**
  589.      * $q Cantidad de iteraciones
  590.      * $t Tipo de dato [1:hexadecimal,2:rgb]
  591.     */
  592.     public function createRgbVersions(string $colorint $q=2$t=1):array
  593.     {
  594.         $versions = [];
  595.         $rgb $t==$this->fromHexToRgb($color) : $color;
  596.         $rgbArray explode(',',$rgb);
  597.         if(count($rgbArray)===&& $q>0){
  598.             $ratio min(0.31/$q);
  599.             $max max($rgbArray);
  600.             $factor $max 128 1+$ratio 1-$ratio;
  601.             $versions[]=$rgbArray;
  602.             
  603.             for($i=2;$i<=$q;$i++){
  604.                 $newVersion = [];
  605.                 foreach(end($versions) as $v){
  606.                     $newVersion[]=$factor*$v;
  607.                 }    
  608.                 $versions[]=$newVersion;
  609.             }
  610.         }
  611.         foreach($versions as $k=>$v){
  612.             $versions[$k]=implode(',',$v);
  613.         }
  614.         return $versions;
  615.     }
  616.     public function getRole($role)
  617.     {
  618.         switch ($role){
  619.             case 'ROLE_USER'$name 'General'; break;
  620.             case 'ROLE_CHIEF'$name 'Administrador'; break;
  621.             case 'ROLE_SUPPLIER'$name 'Proveedor'; break;
  622.             case 'ROLE_SUPPLIER_CHIEF'$name 'Proveedor (Administrador)'; break;
  623.             case 'ROLE_ADMIN'$name 'Superadministrador'; break;
  624.             case 'ROLE_CLIENT'$name 'Cliente'; break;
  625.             default: $name 'General';
  626.         }        
  627.         return $name;
  628.     }
  629.     public function fileIsEncrypted($filename,$ext='.packaged'){
  630.         $len strlen($ext);
  631.         $start strlen($filename)-$len;
  632.         return substr($filename$start,$len) == $ext;
  633.     }
  634.     
  635. }