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.         foreach($usersAvailable as $type=>$data){
  145.             if($type=='all')break;
  146.             $total intval($this->getLicenseField($company,'user_'.$type));
  147.             $inUse 0;
  148.             $available 0;
  149.             if($total>0){
  150.                 $users $this->em->getRepository(User::class)->findBy(['company'=>$company,'role'=>$data['role']]);
  151.                 $inUse $users count($users) : 0;
  152.                 $available=($total-$inUse)>$total-$inUse 0;
  153.             }
  154.             $usersAvailable[$type]['total']=$total;
  155.             $usersAvailable[$type]['in_use']=$inUse;
  156.             $usersAvailable[$type]['available']=$available;
  157.             $usersAvailable['all']['total']+=$total;
  158.             $usersAvailable['all']['in_use']+=$inUse;
  159.             $usersAvailable['all']['available']+=$available;
  160.         }
  161.         return $usersAvailable;
  162.     }
  163.     public function getCompanySuscriptionAvailable(LicenseCompany $licenseActive){
  164.         $company $licenseActive->getCompany();
  165.         $users $this->getCompanyUsersAvailable($company);
  166.         $partTotal $this->getLicenseField($company,'part_num');
  167.         $partInUse count($this->em->getRepository(Part::class)->findBy(['company'=>$company]));
  168.         $libTotal $this->getLicenseField($company,'part_library');
  169.         $libInUse count($this->em->getRepository(Library::class)->findBy(['company'=>$company]));
  170.         $suscriptionData = [
  171.             'license'=>$licenseActive->getLicense(),
  172.             'users'=>$users,
  173.             'parts'=>['total'=>$partTotal,'in_use'=>$partInUse,'available'=>($partTotal-$partInUse>0?$partTotal-$partInUse:0)],
  174.             'libraries'=>['total'=>$libTotal,'in_use'=>$libInUse,'available'=>($libTotal-$libInUse>0?$libTotal-$libInUse:0)],
  175.         ];
  176.         return $suscriptionData;
  177.     }
  178.     public function getCompanyFileMaxsizes(Company $company){
  179.         $fileMaxsizes = ['cad'=>0,'stl'=>0,'fab'=>0,'ver'=>0,'2d'=>0,'others'=>0,'budget'=>0,'report'=>0];
  180.         foreach($fileMaxsizes as $field=>$num){
  181.             if(in_array($field,['others','budget','report'])){
  182.                 $fileMaxsizes[$field] = intval(round($this->getLicenseField($company,'maxsize_'.$field)/5));
  183.             }
  184.             else{
  185.                 $fileMaxsizes[$field] = intval($this->getLicenseField($company,'maxsize_'.$field));
  186.             }
  187.             if($fileMaxsizes[$field]<1){
  188.                 $fileMaxsizes[$field]=1;
  189.             }
  190.         }
  191.         return $fileMaxsizes;
  192.     }
  193.     public function getActiveLicense(Company $company){
  194.         $license null;
  195.         $lc =$this->em->getRepository(LicenseCompany::class)->findOneBy(['company'=>$company,'state'=>2]);
  196.         if(!empty($lc)){
  197.             $license $lc->getLicense();
  198.         }
  199.         return $license;
  200.     }
  201.     public function getLicenseData(LicenseCompany $licenseActive){
  202.         $trans $this->translator;
  203.         $license $licenseActive->getLicense();
  204.         $licenseData = [
  205.             'general' => [
  206.                 'label' => $trans->trans('General'),
  207.                 'fields' => [
  208.                     'id'=>['label'=> $trans->trans('Id'),'data'=>$licenseActive->getId(),'type'=>'integer'],
  209.                     'name'=>['label'=> $trans->trans('Nombre'),'data'=>$license->getName(),'type'=>'string'],
  210.                     'added'=>['label'=> $trans->trans('Alta'),'data'=>$licenseActive->getDateAdded()->format('d-m-Y H:i'),'type'=>'string'],
  211.                     'start'=>['label'=> $trans->trans('Inicio'),'data'=>$licenseActive->getDateStart()->format('d-m-Y'),'type'=>'string'],
  212.                     'end'=>['label'=> $trans->trans('Fin'),'data'=>$licenseActive->getDateEnd()->format('d-m-Y'),'type'=>'string'],
  213.                 ]
  214.             ],
  215.             'users' => [
  216.                 'label' => $trans->trans('Usuarios'),
  217.                 'fields' => [
  218.                     'user_client'=>['label'=> $trans->trans('Clientes')],
  219.                     'user_user'=>['label'=> $trans->trans('Generales')],
  220.                     'user_chief'=>['label'=> $trans->trans('Administradores')],
  221.                     'user_supplier'=>['label'=> $trans->trans('Proveedores')],
  222.                     'user_supplier_chief'=>['label'=> $trans->trans('Proveedores (adm)')]
  223.                 ],
  224.             ],
  225.             'inventory' => [
  226.                 'label' => $trans->trans('Inventario digital'),
  227.                 'fields' => [
  228.                     'part_library_type'=>['label'=> $trans->trans('Tipo')],
  229.                     'part_num'=>['label'=> $trans->trans('Piezas')],
  230.                     'part_library'=>['label'=> $trans->trans('Bibliotecas')],
  231.                     'part_version'=>['label'=> $trans->trans('Versionado')],
  232.                     'part_locked'=>['label'=> $trans->trans('Bloqueado')],
  233.                     'maxsize_cad'=>['label'=> $trans->trans('MS-CAD')],
  234.                     'maxsize_stl'=>['label'=> $trans->trans('MS-STL')],
  235.                     'maxsize_fab'=>['label'=> $trans->trans('MS-FAB')],
  236.                     'maxsize_ver'=>['label'=> $trans->trans('MS-VERIF')],
  237.                     'maxsize_2d'=>['label'=> $trans->trans('MS-2D')],
  238.                     'maxsize_others'=>['label'=> $trans->trans('MS-OTHERS')]
  239.                 ],
  240.             ],
  241.             'production' => [
  242.                 'label' => $trans->trans('Gestión de producción'),
  243.                 'fields' => [
  244.                     'wo_external'=>['label'=> $trans->trans('Externas')],
  245.                     'wo_internal'=>['label'=> $trans->trans('Internas')],
  246.                     'marketplace'=>['label'=> $trans->trans('Marketplace')],
  247.                     'wo_custom'=>['label'=> $trans->trans('Personalizable')],
  248.                     'search_supplier_cif'=>['label'=> $trans->trans('Búsqueda CT por CIF')],
  249.                     'search_supplier_marketplace'=>['label'=> $trans->trans('Búsqueda en MP')],
  250.                     'maxsize_budget'=>['label'=> $trans->trans('MS-BUDGET')],
  251.                     'maxsize_report'=>['label'=> $trans->trans('MS-REPORT')]
  252.                 ],
  253.             ],
  254.             'utilities'=>[
  255.                 'label' => $trans->trans('Utilidades'),
  256.                 'fields' => [
  257.                     'dashboard'=>['label'=> $trans->trans('Dashboard')],
  258.                     'massive_upload'=>['label'=>'Carga masiva'],
  259.                     'advanced_filter_search'=>['label'=>'Filtro y búsquedas avanzada'],
  260.                     'configurable_listings'=>['label'=>'Listados configurables'],
  261.                     'grid_display'=>['label'=>'Vista cuadrícula'],
  262.                     'hosting'=>['label'=> $trans->trans('Hosting')],
  263.                     'multi_select'=>['label'=> $trans->trans('Selección múltiple')],
  264.                     'graphic_custom'=>['label'=> $trans->trans('Personalización gráfica')],
  265.                     'part_comparison'=>['label'=> $trans->trans('Comparación piezas')],
  266.                 ],
  267.             ]
  268.         ];
  269.         $selects = [
  270.             'part_library_type' => [0=>'-',1=>$trans->trans('Simple'),2=>$trans->trans('Árbol')],
  271.             'wo_external' => [0=>'-',1=>$trans->trans('Recibir'),2=>$trans->trans('Enviar'),3=>$trans->trans('Recibir/enviar')],
  272.             'dashboard' => [0=>'-',1=>$trans->trans('Simple'),2=>$trans->trans('Personalizable')],
  273.             'hosting' => [0=>'-',1=>$trans->trans('Cloud'),2=>$trans->trans('Cloud/On-Premise')]
  274.         ];
  275.         foreach($licenseData as $catName=>$catData){
  276.             if($catName!='general'){
  277.                 foreach($catData['fields'] as $field=>$data){
  278.                     $fieldExplode explode('_',$field);
  279.                     $get 'get';
  280.                     foreach($fieldExplode as $part){
  281.                         $get.= ucfirst($part);
  282.                     }
  283.                     try {
  284.                         $value $license->$get();
  285.                         $value array_key_exists($field,$selects) && !empty($selects[$field][$value]) ? $selects[$field][$value] : $value;
  286.                     } catch (\Throwable $e) {
  287.                         $value='-';
  288.                     }
  289.                     $licenseData[$catName]['fields'][$field]['data']=$value;
  290.                     $licenseData[$catName]['fields'][$field]['type']=gettype($value);
  291.                 }
  292.             }
  293.         }
  294.         return $licenseData;
  295.     }
  296.     //Se elimina toda la actividad de la empresa.
  297.     //Solo quedan los datos de la empresa y las licencias contratadas
  298.     public function rmAccount(Company $company$entities=['library','user']){
  299.         $em $this->em;
  300.         $fs = new Filesystem();
  301.         $rootDir $this->rootDir;
  302.         $ds DIRECTORY_SEPARATOR;
  303.         $result = ['error'=>false,'msg'=>''];
  304.         try{
  305.             //Ordenes de trabajo
  306.             $orders $em->getRepository(Order::class)->findBy(['company'=>$company]);
  307.             if(!empty($orders)){
  308.                 $ordersDir $rootDir.$ds.'public'.$ds.'orders'.$ds;
  309.                 foreach($orders as $order){
  310.                     $files explode(',',$order->getFilesSupplier());
  311.                     if(!empty($files)){
  312.                         foreach($files as $file){
  313.                             if($fs->exists($ordersDir.$file) && !empty($file)){
  314.                                 $fs->remove($ordersDir.$file);
  315.                             }
  316.                         }
  317.                     }
  318.                     $em->remove($order);
  319.                 }
  320.                 $em->flush();
  321.             }
  322.             //Piezas
  323.             $parts $em->getRepository(Part::class)->findBy(['company'=>$company]);
  324.             if(!empty($parts)){
  325.                 $partsDir $rootDir.$ds.'public'.$ds.'parts'.$ds;
  326.                 $excelDir $partsDir.'excel'.$ds;
  327.                 foreach($parts as $part){
  328.                     $getters = ['getFilename','getFileCad','getFileStl','getFile2d','getFileFab','getFileVerif','getFile01','getFile02','getFile03','getFile04','getFile05','getBulkImportFile'];
  329.                     $files = [];
  330.                     $excelFile '';
  331.                     foreach($getters as $get){
  332.                         if($part->$get()){
  333.                             if($get=='getBulkImportFile'){
  334.                                 $excelFile=$part->$get();
  335.                             }
  336.                             else{
  337.                                 $files[]=$part->$get();
  338.                             }
  339.                         }
  340.                     }
  341.                     if(!empty($files)){
  342.                         foreach($files as $file){
  343.                             if($fs->exists($partsDir.$file) && !empty($file)){
  344.                                 $fs->remove($partsDir.$file);
  345.                             }
  346.                         }
  347.                     }
  348.                     if(!empty($excelFile)){
  349.                         if($fs->exists($excelDir.$excelFile)){
  350.                             $fs->remove($excelDir.$excelFile);
  351.                         }
  352.                     }
  353.                     $em->remove($part);
  354.                 }
  355.                 $em->flush();
  356.             }
  357.             //Equipos
  358.             $equipments $em->getRepository(Equipment::class)->findBy(['company'=>$company]);
  359.             if(!empty($equipments)){
  360.                 $dir $rootDir.$ds.'public'.$ds.'supplier';
  361.                 $getters = ['getImages','getFiles'];
  362.                 foreach($equipments as $entity){
  363.                     $filenames = [];
  364.                     foreach($getters as $getter){
  365.                         if($entity->$getter()){
  366.                             $filenames array_merge($filenamesexplode(',',$entity->$getter()));
  367.                         }
  368.                     }
  369.                     foreach($filenames as $fileToRemove){
  370.                         if($fs->exists($dir.$ds.$fileToRemove) && !empty($fileToRemove)){
  371.                             $fs->remove($dir.$ds.$fileToRemove);
  372.                         }
  373.                     }
  374.                     $em->remove($entity);
  375.                 }
  376.                 $em->flush();
  377.             }
  378.             //Materiales
  379.             $materials $em->getRepository(Material::class)->findBy(['company'=>$company]);
  380.             if(!empty($materials)){
  381.                 $dir $rootDir.$ds.'public'.$ds.'supplier';
  382.                 $getters = ['getImages','getTechnicalFiles','getOtherFiles'];
  383.                 foreach($materials as $entity){
  384.                     $filenames = [];
  385.                     foreach($getters as $getter){
  386.                         if($entity->$getter()){
  387.                             $filenames array_merge($filenamesexplode(',',$entity->$getter()));
  388.                         }
  389.                     }
  390.                     foreach($filenames as $fileToRemove){
  391.                         if($fs->exists($dir.$ds.$fileToRemove) && !empty($fileToRemove)){
  392.                             $fs->remove($dir.$ds.$fileToRemove);
  393.                         }
  394.                     }
  395.                     $em->remove($entity);
  396.                 }
  397.                 $em->flush();
  398.             }
  399.             //Bibliotecas / usuarios / proveedores [user=delete:cascade]
  400.             if(in_array('library'$entities)){
  401.                 $em->createQuery("DELETE App:Library e WHERE e.company = {$company->getId()}")->execute();
  402.             }
  403.             if(in_array('user'$entities)){
  404.                 $em->createQuery("DELETE App:User e WHERE e.company = {$company->getId()}")->execute();
  405.             }
  406.             return $result;
  407.         }
  408.         catch (IOExceptionInterface $e) {
  409.             $msg "An error occurred while creating your directory at ".$e->getPath();
  410.             $this->logger->error($msg);
  411.             return ['error'=>true,'msg'=>$msg];
  412.         }
  413.         catch (\Doctrine\DBAL\Exception $e){
  414.             $msg "An error has occurred trying to remove company data - Error: {$e->getMessage()}. Line : {$e->getLine()}";
  415.             $this->logger->error($msg);
  416.             return ['error'=>true,'msg'=>$msg];
  417.         }
  418.         catch (\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.     }
  424.     public function email($tostring $subject, array $contextstring $template$from=null, ?array $addTo=null){
  425.         $result = ['error'=>false,'msg'=>''];
  426.         $from $from $from $this->emailApp;
  427.         $email = (new TemplatedEmail())
  428.             ->from(new Address($from'Addvance3D'))
  429.             ->to($to)
  430.             ->subject($subject)
  431.             ->htmlTemplate($template)
  432.             ->context($context);
  433.         if($addTo){
  434.             foreach($addTo as $to){
  435.                 $email->addTo($to);
  436.             }
  437.         }
  438.         try {
  439.             $this->mailer->send($email);
  440.             return $result;
  441.         } catch (TransportExceptionInterface $e) {
  442.             return ['error'=>true,'msg'=>$e->getMessage()];
  443.         }
  444.     }
  445.     public function notifications(Company $companyint $group, array $data, ?User $author=null, ?int $idForeign=null){
  446.         $message = !empty($data['message']) ? $data['message'] : '';
  447.         $messageAux = !empty($data['message_aux']) ? $data['message_aux'] : '';
  448.         $name = !empty($data['name']) ? $data['name'] : '';
  449.         $reference = !empty($data['reference']) ? $data['reference'] : '';
  450.         $path_name = !empty($data['path_name']) ? $data['path_name'] : '';
  451.         $path_parameters = !empty($data['path_parameters']) ? $data['path_parameters'] : '';
  452.         $n = new Notifications;
  453.         $n->setCompany($company);
  454.         $n->setCreatedAt(new \DateTime());
  455.         $n->setGroup($group);
  456.         $n->setUser($author);
  457.         $n->setMessage($this->cutText($message,500));
  458.         $n->setMessageAux($this->cutText($messageAux));
  459.         $n->setName($name);
  460.         $n->setReference($reference);
  461.         $n->setPathName($path_name);
  462.         $n->setPathParameters($path_parameters);
  463.         $n->setIdForeign($idForeign);
  464.         $this->em->persist($n);
  465.         $this->em->flush();
  466.         //Notificaciones por email
  467.         $usersCompany $this->em->getRepository(User::class)->findBy(['company'=>$company]);
  468.         switch($group){
  469.             case 1$getGroup 'getGroupUser'; break;
  470.             case 2$getGroup 'getGroupPart'; break;
  471.             case 3$getGroup 'getGroupOrder'; break;
  472.             case 4$getGroup 'getGroupCollabExt'; break;
  473.             case 5$getGroup 'getGroupLibrary'; break;
  474.             default : $getGroup 'getGroupUser';
  475.         }
  476.         $addTo = [];
  477.         foreach($usersCompany as $user){
  478.             if($user->getNotificationsConfig() && $user->getNotificationsConfig()->$getGroup()==2){
  479.                 $addTo[]=$user->getEmail();
  480.             }
  481.         }
  482.         if($addTo){
  483.             $to array_shift($addTo);
  484.             if($messageAux){
  485.                 $context = ['msg' =>'<p>'.$this->translator->trans($message,['{aux}'=>$messageAux]). '</p>'];
  486.             }
  487.             else{
  488.                 $context = ['msg' =>'<p>'.$this->translator->trans($message). '</p>'];
  489.             }
  490.             $this->email($to$this->translator->trans('Notificaciones'), $context'common/email.html.twig'null$addTo);
  491.         }
  492.     }
  493.     public function getCssCorporateColor(Company $company){
  494.         $color $company->getCorporateColor();
  495.         $css = <<<EOT
  496.             <style>
  497.                 /*Top-menu*/
  498.                 .topbar {
  499.                     background: #color# !important;
  500.                 }
  501.                 /*Left-menu*/
  502.                 .sidebar-nav > ul > li.active > a {
  503.                     border-color: #color#;
  504.                 }
  505.                 .sidebar-nav ul li a.active i, .sidebar-nav ul li a:hover i {
  506.                     color: #color#;
  507.                 }
  508.                 /*Buttons*/
  509.                 .bg-primary {
  510.                     background-color: #color# !important;
  511.                 }
  512.                 .btn-info, .btn-info:hover, .btn-primary, .btn-primary:hover, .dt-buttons .dt-button, .btn-success {
  513.                     background: #color# !important;
  514.                     background-color: #color# !important;
  515.                     border: 1px solid #color#;
  516.                 }
  517.                 .btn-inverse {
  518.                     border: 1px solid #color#;
  519.                 }
  520.                 .btn-inverse.active, .btn-inverse.focus, .btn-inverse:active, .btn-inverse:focus, .btn-inverse:hover, .btn-inverse:hover, .open>.dropdown-toggle.btn-inverse {
  521.                     border: 1px solid #color#;
  522.                 }
  523.                 .btn-inverse.active, .btn-inverse.focus, .btn-inverse:active, .btn-inverse:focus, .btn-inverse:hover, .btn-inverse:hover, .open>.dropdown-toggle.btn-inverse {
  524.                     background-color: #AAA;
  525.                 }
  526.                 .btn-success.disabled:hover, .btn-success:hover {
  527.                     background: #color#;
  528.                     border: 1px solid #color#;
  529.                 }
  530.                 /*Forms and tables*/
  531.                 .paginate_button.current, .paginate_button:hover {
  532.                     background-color: #color# !important;
  533.                     border: 1px solid #color# !important;
  534.                     color: white !important;
  535.                 }
  536.                 /*Index*/
  537.                 #notifications_header .card-text {
  538.                     color: #color# !important;
  539.                 }
  540.                 /*Others*/
  541.                 .text-primary {
  542.                     color: #color# !important;
  543.                 }
  544.                 .profile-tab li a.nav-link.active, .customtab li a.nav-link.active {
  545.                     border-bottom: 2px solid #color#;
  546.                     color: #color#;
  547.                 }
  548.                 .msg_txt_end {
  549.                     border-radius: 15px;
  550.                     padding: 5px 10px;
  551.                     border: 1px solid #color# !important;
  552.                     font-size: 14px;
  553.                 }
  554.                 .dropdown-item.active {
  555.                     background: #color# !important;
  556.                     color: white;
  557.                 }
  558.                 .manual h1 {
  559.                     color: #color# !important;
  560.                     font-weight: bold;
  561.                     font-family: "Poppins", sans-serif;
  562.                     margin-bottom: 20px;
  563.                     margin-top: 60px;
  564.                 }
  565.                 .manual h2  {
  566.                     color: #color# !important;
  567.                     font-family: "Poppins", sans-serif;
  568.                     margin-bottom: 20px;
  569.                     margin-top: 60px;
  570.                 }
  571.                 .manual #myBtn {
  572.                     display: none; /* Hidden by default */
  573.                     position: fixed; /* Fixed/sticky position */
  574.                     bottom: 20px; /* Place the button at the bottom of the page */
  575.                     right: 30px; /* Place the button 30px from the right */
  576.                     z-index: 99; /* Make sure it does not overlap */
  577.                     border: none; /* Remove borders */
  578.                     outline: none; /* Remove outline */
  579.                     background-color: #color# !important; /* Set a background color */
  580.                     color: white; /* Text color */
  581.                     cursor: pointer; /* Add a mouse pointer on hover */
  582.                     padding: 15px; /* Some padding */
  583.                     font-size: 18px; /* Increase font size */
  584.                 }
  585.                 .manual #myBtn:hover {
  586.                     background-color: #555; /* Add a dark-grey background on hover */
  587.                 }
  588.                 .manual strong {
  589.                     font-weight: bold;
  590.                 }
  591.                 .badge {
  592.                     background-color: #color# !important;
  593.                 }
  594.             </style>
  595.         EOT;
  596.         if($color){
  597.             return str_replace('#color#',$company->getCorporateColor(),$css);
  598.         }
  599.         return '';
  600.     }
  601.     public function fromHexToRgb(string $hex):string
  602.     {
  603.         $corporateColorArray str_split(str_replace('#','',$hex), 2);
  604.         $corporateColorRGB = [];
  605.         $rgb '';
  606.         if(count($corporateColorArray)===3){
  607.             foreach($corporateColorArray as $cc){
  608.                 $one = (int) str_replace(['A','B','C','D','E','F'],[10,11,12,13,14,15],substr(strtoupper($cc),0,1));
  609.                 $two = (int) str_replace(['A','B','C','D','E','F'],[10,11,12,13,14,15],substr(strtoupper($cc),1,1));
  610.                 $corporateColorRGB[]=$one*16 $two;
  611.             }
  612.             $rgb implode(',',$corporateColorRGB);
  613.         }
  614.         return $rgb;
  615.     }
  616.     /**
  617.      * $q Cantidad de iteraciones
  618.      * $t Tipo de dato [1:hexadecimal,2:rgb]
  619.     */
  620.     public function createRgbVersions(string $colorint $q=2$t=1):array
  621.     {
  622.         $versions = [];
  623.         $rgb $t==$this->fromHexToRgb($color) : $color;
  624.         $rgbArray explode(',',$rgb);
  625.         if(count($rgbArray)===&& $q>0){
  626.             $ratio min(0.31/$q);
  627.             $max max($rgbArray);
  628.             $factor $max 128 1+$ratio 1-$ratio;
  629.             $versions[]=$rgbArray;
  630.             for($i=2;$i<=$q;$i++){
  631.                 $newVersion = [];
  632.                 foreach(end($versions) as $v){
  633.                     $newVersion[]=$factor*$v;
  634.                 }
  635.                 $versions[]=$newVersion;
  636.             }
  637.         }
  638.         foreach($versions as $k=>$v){
  639.             $versions[$k]=implode(',',$v);
  640.         }
  641.         return $versions;
  642.     }
  643.     public function getRole($role)
  644.     {
  645.         switch ($role){
  646.             case 'ROLE_USER'$name 'General'; break;
  647.             case 'ROLE_CHIEF'$name 'Administrador'; break;
  648.             case 'ROLE_SUPPLIER'$name 'Proveedor'; break;
  649.             case 'ROLE_SUPPLIER_CHIEF'$name 'Proveedor (Administrador)'; break;
  650.             case 'ROLE_ADMIN'$name 'Superadministrador'; break;
  651.             case 'ROLE_CLIENT'$name 'Cliente'; break;
  652.             case 'ROLE_LOCAL_ADMIN'$name 'Superadministrador Local'; break;
  653.             default: $name 'General';
  654.         }
  655.         return $name;
  656.     }
  657.     public function fileIsEncrypted($filename,$ext='.packaged'){
  658.         $len strlen($ext);
  659.         $start strlen($filename)-$len;
  660.         return substr($filename$start,$len) == $ext;
  661.     }
  662. }