src/Controller/PartController.php line 115

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Company;
  4. use App\Entity\CompanyClient;
  5. use App\Entity\Library;
  6. use App\Entity\Order;
  7. use App\Entity\Part;
  8. use App\Entity\Supplier;
  9. use App\Entity\CompanySupplier;
  10. use App\Entity\Equipment;
  11. use App\Entity\Material;
  12. use App\Form\OrderType;
  13. use App\Form\PartSearchType;
  14. use App\Form\PartImportType;
  15. use App\Form\PartType;
  16. use App\Repository\CompanyClientRepository;
  17. use App\Repository\PartRepository;
  18. use App\Repository\CompanySupplierRepository;
  19. use App\Service\EncryptDecryptService;
  20. use App\Service\Part\EditPartService;
  21. use App\Service\UtilService;
  22. use App\Service\PartService;
  23. use App\Service\LibraryService;
  24. use App\Security\Voter\PartVoter;
  25. use App\Entity\LicenseCompany;
  26. use PHPSTL\Handler\DimensionsHandler;
  27. use PHPSTL\Handler\SurfaceHandler;
  28. use PHPSTL\Handler\VolumeHandler;
  29. use PHPSTL\Model\STLModel;
  30. use PHPSTL\Reader\STLReader;
  31. use Psr\Container\ContainerInterface;
  32. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  33. use Symfony\Component\Form\FormInterface;
  34. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  35. use Symfony\Component\HttpFoundation\File\Exception\FileException;
  36. use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
  37. use Symfony\Component\Filesystem\Filesystem;
  38. use Symfony\Component\HttpFoundation\Request;
  39. use Symfony\Component\HttpFoundation\Response;
  40. use Symfony\Component\HttpFoundation\JsonResponse;
  41. use Symfony\Component\Routing\Annotation\Route;
  42. use Symfony\Component\Validator\Constraints\Url as ConstraintsUrl;
  43. use Symfony\Component\HttpFoundation\StreamedResponse;
  44. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  45. use Symfony\Component\String\Slugger\AsciiSlugger;
  46. use Symfony\Contracts\Translation\TranslatorInterface;
  47. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  48. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  49. use PhpOffice\PhpSpreadsheet\IOFactory;
  50. use Knp\Component\Pager\PaginatorInterface;
  51. use Knp\Snappy\Pdf;
  52. use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
  53. use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
  54. use Doctrine\Persistence\ManagerRegistry;
  55. /**
  56.  * @Route({"en": "/part",
  57.  *          "es": "/pieza"})
  58.  */
  59. class PartController extends AbstractController
  60. {
  61.     private const PAGE_ELEMENTS 25;
  62.     private $translator;
  63.     private $util;
  64.     private $pdf;
  65.     private $partService;
  66.     private $libService;
  67.     private $csRepository;
  68.     private $em;
  69.     private $partDir;
  70.     /**
  71.      * @var EditPartService
  72.      */
  73.     private $editPartService;
  74.     /**
  75.      * PartController constructor.
  76.      * @param EditPartService $editPartService
  77.      */
  78.     public function __construct(
  79.         EditPartService $editPartService,
  80.         TranslatorInterface $translator,
  81.         UtilService $utilService,
  82.         PartService $partService,
  83.         LibraryService $libService,
  84.         CompanySupplierRepository $csRepository,
  85.         Pdf $knpSnappyPdf,
  86.         ManagerRegistry $doctrine,
  87.         string $partDir,
  88.         private EncryptDecryptService $encryptDecryptService
  89.     )
  90.     {
  91.         $this->editPartService $editPartService;
  92.         $this->translator $translator;
  93.         $this->util $utilService;
  94.         $this->partService $partService;
  95.         $this->libService $libService;
  96.         $this->csRepository $csRepository;
  97.         $this->pdf $knpSnappyPdf;
  98.         $this->em $doctrine->getManager();
  99.         $this->partDir $partDir;
  100.     }
  101.     /**
  102.      * @Route({"en": "/list",
  103.      *         "es": "/listado"}, name="part_index", methods={"GET","POST"})
  104.      */
  105.     public function index(Request $requestPartRepository $partRepositoryPaginatorInterface $paginator): Response
  106.     {
  107.         $admin $this->getUser();
  108.         $ms $this->util->getLicenseField($admin->getCompany(),'multi_select') && $admin->getRole()!='ROLE_CLIENT';
  109.         $part = [];
  110.         $form $this->createForm(PartSearchType::class, $part, ['user_admin' => $admin,'method' => 'GET']);
  111.         $form->handleRequest($request);
  112.         $orderBy null;
  113.         $filters = [
  114.             ['field'=>'company','title'=>'Empresa'],
  115.             ['field'=>'ref','title'=>'Referencia'],
  116.             ['field'=>'name','title'=>'Nombre'],
  117.             ['field'=>'description','title'=>'Descripción'],
  118.             ['field'=>'technology','title'=>'Tecnología'],
  119.             ['field'=>'material','title'=>'Material'],
  120.             ['field'=>'updated_at','title'=>'Última modificación'],
  121.         ];
  122.         if ($form->isSubmitted() && $form->isValid()) {
  123.             $orderBy $request->query->get('order_by');
  124.             $parts $partRepository->findByName($form->getData(), $admin$orderBy);
  125.         } else {
  126.             $parts $partRepository->buscarTodos($admin);
  127.         }
  128.         if($request->isMethod('POST')){
  129.             if($request->request->get('libraries_update')){
  130.                 $libraryIds $request->request->get('libraryIds',null);
  131.                 $partIds $request->request->get('partIds',null);
  132.                 $rmCurrentLibs $request->request->get('currentLibs',null) ? true false;
  133.                 if($partIds && $libraryIds){
  134.                     $parts explode(','$partIds);
  135.                     foreach($parts as $partId){
  136.                         $part $this->em->getRepository(Part::class)->find($partId);
  137.                         $this->partService->updateLibs($part,$libraryIds,$rmCurrentLibs);
  138.                     }
  139.                     $this->addFlash('success'$this->translator->trans('Bibliotecas editadas correctamente'));
  140.                     return $this->redirectToRoute('part_index');
  141.                 }
  142.             }
  143.             if($request->request->get('parts_delete')){
  144.                 $delIds $request->request->get('delIds',null);
  145.                 if($delIds){
  146.                     $parts explode(','$delIds);
  147.                     $successMsg '';
  148.                     $errorMsg '';
  149.                     foreach($parts as $partId){
  150.                         $part $this->em->getRepository(Part::class)->find($partId);
  151.                         if($part){
  152.                             if($part->getLocked()){
  153.                                 $errorMsg.= $this->translator->trans('Error pieza {ref} : ',['{ref}'=>$part->getRef()]) . $this->translator->trans('Pieza bloqueada') .'<br>';
  154.                             }
  155.                             else{
  156.                                 $rmPart $this->partService->rmPart($part);
  157.                                 if($rmPart['error']){
  158.                                     $errorMsg.= $this->translator->trans('Error pieza {ref} : ',['{ref}'=>$part->getRef()]) . $rmPart['msg'].'<br>';
  159.                                 }
  160.                                 else{
  161.                                     $successMsg.= $this->translator->trans('Pieza {ref} eliminada correctamente',['{ref}'=>$part->getRef()]).'<br>';
  162.                                 }
  163.                             }
  164.                         }
  165.                     }
  166.                     if($successMsg){
  167.                         $this->addFlash('success'$successMsg);
  168.                     }
  169.                     if($errorMsg){
  170.                         $this->addFlash('danger'$errorMsg);
  171.                     }
  172.                     return $this->redirectToRoute('part_index');
  173.                 }
  174.             }
  175.             if($request->request->get('parts_download')){
  176.                 $downIds $request->request->get('downIds',null);
  177.                 $downIds explode(','$downIds);
  178.                 $zip =$this->multiplePartZip($partRepository,$downIds);
  179.                 $response = new BinaryFileResponse($zip[0].'/'.$zip[1]);
  180.                 $response->setStatusCode(200);
  181.                 $response->headers->set('Content-Type''application/zip');
  182.                 $response->headers->set('Content-Disposition''attachment; filename="'.basename($zip[1]).'"');
  183.                 $response->headers->set('Content-Length'filesize($zip[0].'/'.$zip[1]));
  184.                 return $response;
  185.             }
  186.             if($request->request->get('parts_order')){
  187.                 $partIds $request->request->get('partIds',null);
  188.                 if($partIds){
  189.                     $partIds explode(',',$partIds);
  190.                     $partIdsChecked = [];
  191.                     foreach($partIds as $partId){
  192.                         $part $this->em->getRepository(Part::class)->find($partId);
  193.                         if($part && $part->getSupplier() && $part->getCompany()==$admin->getCompany()){
  194.                             $partIdsChecked[] = $partId;
  195.                         }
  196.                     }
  197.                     if($partIdsChecked){
  198.                         return $this->redirectToRoute('order_bulk_new',['partIds'=>base64_encode(implode(',',$partIdsChecked))]);
  199.                     }
  200.                     else{
  201.                         $this->addFlash('danger''Error inesperado');
  202.                         return $this->redirectToRoute('part_index');
  203.                     }
  204.                 }
  205.                 else{
  206.                     $this->addFlash('danger''Error inesperado');
  207.                     return $this->redirectToRoute('part_index');
  208.                 }
  209.             }
  210.         }
  211.         // Creating pagnination
  212.         $pagination $paginator->paginate(
  213.             $parts,
  214.             $request->query->getInt('page'1),
  215.             self::PAGE_ELEMENTS
  216.         );
  217.         return $this->render('part/index.html.twig', [
  218.             'pagination' => $pagination,
  219.             'search_form' => $form->createView(),
  220.             'filters' => $filters,
  221.             'order_by' => $orderBy,
  222.             'ms' => $ms,
  223.             'company' => $admin->getCompany(),
  224.             'user' => $admin,
  225.             'license' => $this->util->getActiveLicense($admin->getCompany()),
  226.             'navbarTitle' => $this->translator->trans("Piezas")
  227.         ]);
  228.     }
  229.     /**
  230.      * @Route({"en": "/new",
  231.      *         "es": "/nueva"}, name="part_new", methods={"GET","POST"})
  232.      */
  233.     public function new(Request $requestPartRepository $partRepositoryCompanyClientRepository $ccRepository): Response
  234.     {
  235.         $em $this->em;
  236.         $admin $this->getUser();
  237.         $orderPrototypeId $request->request->get('orderPrototypeId');
  238.         $orderCompanyId $request->request->get('orderCompanyId');
  239.         $part = new Part();
  240.         $part->setCompany($admin->getCompany());
  241.         if($orderPrototypeId != null  ) {
  242.             $part->setType(2);
  243.             $order $em->getRepository(Order::class)->findOneBy(array('id' => $orderPrototypeId));
  244.             $part->setSupplier($order->getSupplier());
  245.             $part->setPrototypeOrder($orderPrototypeId);
  246.             $company $em->getRepository(Company::class)->findOneBy(array('id' => $orderCompanyId));
  247.             $part->setCompany($company);
  248.             if($order->getUser()->getRole() == "ROLE_CLIENT") {
  249.                 $part->setCompanyClient($order->getUser()->getCompanyClient());
  250.             }
  251.         } else {
  252.             $part->setType(1);
  253.             $part->setCompany($admin->getCompany());
  254.         }
  255.         $fileMaxsizes $this->util->getCompanyFileMaxsizes($part->getCompany());
  256.         $cc $ccRepository->findClient([],$admin)->getArrayResult();
  257.         $form $this->createForm(PartType::class, $part, ['user_admin' => $admin'file_maxsizes' => $fileMaxsizes'cc'=>$cc]);
  258.         $form->handleRequest($request);
  259.         $errors = [];
  260.         $errorsSubmitted = [];
  261.         if ($form->isSubmitted() && $form->isValid()) {
  262.             $data $request->request->all();
  263.             $optionsEncrypt = [
  264.                 'encryptSTL' => (isset($request->request->get('part')['encryptSTL'])) ? $request->request->get('part')['encryptSTL'] : null,
  265.                 'encryptCAD' => (isset($request->request->get('part')['encryptCAD'])) ? $request->request->get('part')['encryptCAD'] : null,
  266.                 'encryptFAB' => (isset($request->request->get('part')['encryptFAB'])) ? $request->request->get('part')['encryptFAB'] : null,
  267.                 'encryptVER' => (isset($request->request->get('part')['encryptVER'])) ? $request->request->get('part')['encryptVER'] : null,
  268.                 'encrypt2D' => (isset($request->request->get('part')['encrypt2D'])) ? $request->request->get('part')['encrypt2D'] : null,
  269.                 'encryptOthers' => (isset($request->request->get('part')['encryptOthers'])) ? $request->request->get('part')['encryptOthers'] : null,
  270.             ];
  271.             $libraryIds $request->request->get('libraryIds',null);
  272.             $company $form->get('company')->getData();
  273.             if(is_string($company)){
  274.                 $company $em->getRepository(Company::class)->findOneBy(array('name' => $company));
  275.             }
  276.             $supplier $form->get('supplier')->getData();
  277.             //límites licencia
  278.             if(!($admin->getRole()=='ROLE_ADMIN')){
  279.                 $licenseLimit $this->util->getLicenseField($admin->getCompany(),'part_num');
  280.                 $currentNum count($em->getRepository(Part::class)->findBy(['company'=>$admin->getCompany()]));
  281.                 if(!$licenseLimit || ($currentNum>=$licenseLimit)){
  282.                     $this->addFlash('danger'$this->translator->trans('Ha alcanzado el límite de {name} para su licencia.',['{name}'=>$this->translator->trans('piezas')]));
  283.                     return $this->redirectToRoute('part_index');
  284.                 }
  285.             }
  286.             $fileStl $form->get('fileStlFile')->getData();
  287.             if($fileStl){
  288.                 $fileName explode('.'$fileStl->getClientOriginalName());
  289.                 if($fileName){
  290.                     $fileExt $fileName[count($fileName)-1];
  291.                     if(strtoupper($fileExt)!='STL'){
  292.                         $this->addFlash('error'$this->translator->trans('El archivo Stl adjunto no tiene la extensión correcta'));
  293.                         return $this->redirectToRoute('part_index');
  294.                     }
  295.                 }
  296.             }
  297.             $name$form->get('name')->getData();
  298.             $nameExists $partRepository->nameExists($name,$company->getId());
  299.             $companyClientId $form->get('client_name')->getData();
  300.             if($companyClientId) {
  301.                 $companyClient $em->getRepository(CompanyClient::class)->findOneBy(array('id' => $companyClientId));
  302.                 $part->setCompanyClient($companyClient);
  303.             }
  304.             if($nameExists){
  305.                 $errorMsg $this->translator->trans('El nombre de la pieza ya existe');
  306.                 $errors['tab_datosbasicos']['name'][]=$errorMsg;
  307.                 $errorsSubmitted['name'][]=$errorMsg;
  308.                 $this->addFlash('error'$errorMsg);
  309.             }
  310.             else{
  311.                 $this->processOtherFiles($form$part5, !empty($optionsEncrypt['encryptOthers']));
  312.                 $this->processFiles($form,$part,false$optionsEncrypt);
  313.                 $lastRef $partRepository->findLastRef($company);
  314.                 $part->setSupplier($supplier);
  315.                 $part->setRef($lastRef);
  316.                 $part->setVersion(1);
  317.                 $part->setAutor($admin->getName());
  318.                 //START Equipos y materiales
  319.                 $eid $form->get('equipment_id')->getData();
  320.                 $mid $form->get('material_id')->getData();
  321.                 $equipo $form->get('equipo')->getData();
  322.                 $material $form->get('material')->getData();
  323.                 $orderPrototypeId $form->get('prototypeOrder')->getData();
  324.                 if($orderPrototypeId !== null)  {
  325.                     $part->setType(2);
  326.                     $part->setPrototypeStatus(Part::UNDER_PREPARATION);
  327.                 } else {
  328.                     $part->setType(1);
  329.                 }
  330.                 if($eid>&& $eid==$equipo){
  331.                     $entity $em->getRepository(Equipment::class)->find($eid);
  332.                     if($entity){
  333.                         $equipo $entity->getName();
  334.                         $part->setEquipmentId($entity);
  335.                     }
  336.                 }
  337.                 else{
  338.                     $eid null;
  339.                     $part->setEquipmentId(null);
  340.                 }
  341.                 if($mid>&& $mid==$material){
  342.                     $entity $em->getRepository(Material::class)->find($mid);
  343.                     if($entity){
  344.                         $material $entity->getName();
  345.                         $part->setMaterialId($entity);
  346.                     }
  347.                 }
  348.                 else{
  349.                     $mid null;
  350.                     $part->setMaterialId(null);
  351.                 }
  352.                 $part->setEquipo($equipo);
  353.                 $part->setMaterial($material);
  354.                 //END Equipos y materiales
  355.                 //Check supplier collab
  356.                 if($company && $supplier && !$this->csRepository->collabExist($company,$supplier)){
  357.                     $cs = new CompanySupplier();
  358.                     $cs->setCompany($company);
  359.                     $cs->setSupplier($supplier);
  360.                     $cs->setConfigStepBudget(true);
  361.                     $cs->setConfigStepChiefConfirm(true);
  362.                     $cs->setConfigStepInDelivery(true);
  363.                     $cs->setType(2);
  364.                     $cs->setCollab(true);
  365.                     $cs->setMarketplace(true);
  366.                     $em->persist($cs);
  367.                 }
  368.                 $em->persist($part);
  369.                 $em->flush();
  370.                 $this->partService->updateLibs($part,$libraryIds);
  371.                 if($part->getFileStl()) {
  372.                     $reader STLReader::forFile('parts/'.$part->getFileStl());
  373.                     $reader->setHandler(new VolumeHandler());
  374.                     $volume $reader->readModel();
  375.                     $reader->setHandler(new SurfaceHandler());
  376.                     $surface $reader->readModel();
  377.                     $reader->setHandler(new DimensionsHandler());
  378.                     $dimension $reader->readModel();
  379.                     $stlData = array(
  380.                         'volumen' => $volume,
  381.                         'surface' => $surface,
  382.                         'dimension' => $dimension
  383.                     );
  384.                     $part->setData(json_encode($stlData));
  385.                     $em->persist($part);
  386.                     $em->flush();
  387.                 }
  388.                 if($part->getType() == 1) {
  389.                     $message $this->translator->trans('Pieza creada correctamente');
  390.                     $data['message']='Nueva pieza creada';
  391.                 } else {
  392.                     $message $this->translator->trans('Prototipo creado correctamente');
  393.                     $data['message']='Nuevo prototipo creado';
  394.                 }
  395.                 $this->addFlash('success',$message );
  396.                 $data['name']=$part->getName();
  397.                 $data['reference']=$part->getRef();
  398.                 $data['path_name']='part_show';
  399.                 $data['path_parameters']='id:'.$part->getId();
  400.                 $this->util->notifications($part->getCompany(), 2$data$this->getUser());
  401.                 if($part->getType() == 1) {
  402.                     return $this->redirectToRoute('part_index');
  403.                 } else {
  404.                     return $this->redirectToRoute('order_index');
  405.                 }
  406.             }
  407.         }
  408.         elseif ($form->isSubmitted()){
  409.             $errors $this->partService->processTabErrors($form);
  410.             $this->addFlash('error'$this->translator->trans('Ha habido un error al procesar el formulario, revise los campos'));
  411.         }
  412.         if($part->getType() == 1) {
  413.             $title $this->translator->trans("Crear nueva pieza");
  414.             $navbarIcon 'bi bi-badge-3d';
  415.         } else {
  416.             $title =  $this->translator->trans("Crear nuevo prototipo");
  417.             $navbarIcon 'bi bi-p-square';
  418.         }
  419.         return $this->render('part/new.html.twig', [
  420.             'user' => $admin,
  421.             'part' => $part,
  422.             'fileMaxsizes' => $fileMaxsizes,
  423.             'form' => $form->createView(),
  424.             'errors' => json_encode($errors),
  425.             'errorsSubmitted' => json_encode($errorsSubmitted),
  426.             'license' => $this->util->getActiveLicense($admin->getCompany()),
  427.             'navbarTitle' => $title,
  428.             'navbarIcon' => $navbarIcon
  429.         ]);
  430.     }
  431.     /**
  432.      * @Route({"en": "/show/{id}",
  433.      *         "es": "/mostrar/{id}"}, name="part_show", methods={"GET", "POST"})
  434.      */
  435.     public function show(Request $requestPart $partPartRepository $partRepository): Response
  436.     {
  437.         $this->denyAccessUnlessGranted(PartVoter::VIEW$part);
  438.         $em $this->em;
  439.         $user $this->getUser();
  440.         //Libraries
  441.         $libraries = [];
  442.         foreach($part->getLibraries() as $library){
  443.             $libraries[] = $this->libService->getFullPath($library);
  444.         }
  445.         if($request->query->get('download')){
  446.             $pdfData $this->htmlForPdf($part,$user);
  447.             return new PdfResponse(
  448.                 $this->pdf->getOutputFromHtml($pdfData['html'], $pdfData['options']),
  449.                 $part->getRef().'.pdf'
  450.             );
  451.         }
  452.         if ($request->isMethod('POST')) {
  453.             if($request->request->get('part_copy_submit')){
  454.                 //Versionar
  455.                 $newPart = clone $part;
  456.                 $newPart->setId(null);
  457.                 $company $part->getCompany();
  458.                 $ref $part->getRef();
  459.                 $splits explode("-"$ref);
  460.                 $refPartNumber $splits[1];
  461.                 $version $partRepository->setAmount($refPartNumber$part->getCompany(), $user);
  462.                 $splits[2] = $version;
  463.                 $newPart->setVersion(ltrim($version"0"));
  464.                 $newRef implode("-"$splits);
  465.                 $newPart->setEditRef($newRef);
  466.                 $newPart->setAutor($user->getName());
  467.                 $newPart->setLocked(null);
  468.                 $newPart->markAsCreatedAt();
  469.                 $em->persist($newPart);
  470.                 $em->flush();
  471.                 $part->setPrototypeStatus();
  472.                 $this->addFlash('success'$this->translator->trans('Versión de pieza creada correctamente'));
  473.                 return $this->redirectToRoute('part_index');
  474.             }
  475.             if($request->request->get('libraries_update')){
  476.                 $libraryIds $request->request->get('libraryIds',null);
  477.                 $this->partService->updateLibs($part,$libraryIds);
  478.                 $this->addFlash('success'$this->translator->trans('Bibliotecas editadas correctamente'));
  479.                 return $this->redirectToRoute('part_show',['id'=>$part->getId()]);
  480.             }
  481.         }
  482.         if($part->getType() == 1) {
  483.             $title $this->translator->trans("Pieza").' - '.$part->getName() . ($part->getVersion()>' V'.$part->getVersion() : '');
  484.             $navbarIcon 'bi bi-badge-3d';
  485.         } else {
  486.             $title $this->translator->trans("Prototipo").' - '.$part->getName() . ($part->getVersion()>' V'.$part->getVersion() : '');
  487.             $navbarIcon 'bi bi-p-square';
  488.         }
  489.         return $this->render('part/show.html.twig', [
  490.             'part' => $part,
  491.             'libraries' => $libraries,
  492.             'user' => $user,
  493.             'edit' => $this->isGranted(PartVoter::EDIT$part),
  494.             'navbarTitle' => $title,
  495.             'navbarIcon' => $navbarIcon
  496.         ]);
  497.     }
  498.     /**
  499.      * @Route({"en": "/edit/{id}",
  500.      *         "es": "/editar/{id}"}, name="part_edit", methods={"GET","POST"})
  501.      */
  502.     public function edit(Request $requestPart $partPartRepository $partRepositorystring $partDirCompanyClientRepository $ccRepository): Response
  503.     {
  504.         $admin $this->getUser();
  505.         $this->denyAccessUnlessGranted(PartVoter::EDIT$part);
  506.         $originalType $part->getType();
  507.         $em $this->em;
  508.         $fileMaxsizes $this->util->getCompanyFileMaxsizes($part->getCompany());
  509.         $cc $ccRepository->findClient([],$admin)->getArrayResult();
  510.         $form $this->createForm(PartType::class, $part, ['user_admin' => $admin'file_maxsizes' => $fileMaxsizes'cc'=>$cc]);
  511.         $form->handleRequest($request);
  512.         $errors = [];
  513.         $errorsSubmitted = [];
  514.         if ($form->isSubmitted() && $form->isValid()) {
  515.             $actionType $request->request->get('submit');
  516.             $libraryIds $request->request->get('libraryIds',null);
  517.             $company $part->getCompany();
  518.             $supplier $form->get('supplier')->getData();
  519.             $cc $form->get('client_name')->getData();
  520.             $fileStl $form->get('fileStlFile')->getData();
  521.             if($fileStl){
  522.                 $fileName explode('.'$fileStl->getClientOriginalName());
  523.                 if($fileName){
  524.                     $fileExt $fileName[count($fileName)-1];
  525.                     if(strtoupper($fileExt)!='STL'){
  526.                         $this->addFlash('error'$this->translator->trans('El archivo Stl adjunto no tiene la extensión correcta'));
  527.                         return $this->redirectToRoute('part_index');
  528.                     }
  529.                 }
  530.             }
  531.             $optionsEncrypt = [
  532.                 'encryptSTL' => (isset($request->request->get('part')['encryptSTL'])) ? $request->request->get('part')['encryptSTL'] : null,
  533.                 'encryptCAD' => (isset($request->request->get('part')['encryptCAD'])) ? $request->request->get('part')['encryptCAD'] : null,
  534.                 'encryptFAB' => (isset($request->request->get('part')['encryptFAB'],)) ? $request->request->get('part')['encryptFAB'] : null,
  535.                 'encryptVER' => (isset($request->request->get('part')['encryptVER'],)) ? $request->request->get('part')['encryptVER'] : null,
  536.                 'encrypt2D' => (isset($request->request->get('part')['encrypt2D'],)) ? $request->request->get('part')['encrypt2D'] : null,
  537.                 'encryptOthers' => (isset($request->request->get('part')['encryptOthers'])) ? $request->request->get('part')['encryptOthers'] : null,
  538.             ];
  539.             $this->processOtherFiles($form$part5, !empty($optionsEncrypt['encryptOthers']));
  540.             $this->processFiles($form,$part,$actionType==1$optionsEncrypt);
  541.             //START Equipos y materiales
  542.             $eid $form->get('equipment_id')->getData();
  543.             $mid $form->get('material_id')->getData();
  544.             $equipo $form->get('equipo')->getData();
  545.             $material $form->get('material')->getData();
  546.             if($eid>&& $eid==$equipo){
  547.                 $entity $em->getRepository(Equipment::class)->find($eid);
  548.                 if($entity){
  549.                     $equipo $entity->getName();
  550.                     $part->setEquipmentId($entity);
  551.                 }
  552.             }
  553.             else{
  554.                 $eid null;
  555.                 $part->setEquipmentId(null);
  556.             }
  557.             if($mid>&& $mid==$material){
  558.                 $entity $em->getRepository(Material::class)->find($mid);
  559.                 if($entity){
  560.                     $material $entity->getName();
  561.                     $part->setMaterialId($entity);
  562.                 }
  563.             }
  564.             else{
  565.                 $mid null;
  566.                 $part->setMaterialId(null);
  567.             }
  568.             $part->setEquipo($equipo);
  569.             $part->setMaterial($material);
  570.             $part->setType($originalType);
  571.             //END Equipos y materiales
  572.             //Check supplier collab
  573.             if($company && $supplier && !$this->csRepository->collabExist($company,$supplier)){
  574.                 $cs = new CompanySupplier();
  575.                 $cs->setCompany($company);
  576.                 $cs->setSupplier($supplier);
  577.                 $cs->setConfigStepBudget(true);
  578.                 $cs->setConfigStepChiefConfirm(true);
  579.                 $cs->setConfigStepInDelivery(true);
  580.                 $cs->setType(2);
  581.                 $cs->setCollab(true);
  582.                 $cs->setMarketplace(true);
  583.                 $em->persist($cs);
  584.             }
  585.             //Process client
  586.             if(!empty($cc['choiceType']) || !empty($cc['choiceInput'])){
  587.                 if(!empty($cc['choiceType'])){
  588.                     $cc $em->getRepository(CompanyClient::class)->find($cc['choiceType']);
  589.                     if($cc){
  590.                         $part->setCompanyClient($cc);
  591.                     }
  592.                 }
  593.                 else{
  594.                     $part->setClientName($cc['choiceInput']);
  595.                 }
  596.             }
  597.             if($actionType==1){
  598.                 //Guardar
  599.                 $part->setSupplier($supplier);
  600.                 $part->markAsUpdated();
  601.                 $em->persist($part);
  602.                 $em->flush();
  603.                 $this->partService->updateLibs($part,$libraryIds);
  604.                 $this->addFlash('success'$this->translator->trans('Pieza editada correctamente'));
  605.                 $data['message']='Pieza editada';
  606.                 $data['name']=$part->getName();
  607.                 $data['reference']=$part->getRef();
  608.                 $data['path_name']='part_show';
  609.                 $data['path_parameters']='id:'.$part->getId();
  610.                 $this->util->notifications($part->getCompany(), 2$data$this->getUser(),$part->getId());
  611.             }
  612.             else{
  613.                 //Versionar
  614.                 $newPart = clone $part;
  615.                 $em->refresh($part);
  616.                 $newPart->setSupplier($supplier);
  617.                 $newPart->setId(null);
  618.                 $ref $part->getRef();
  619.                 $splits explode("-"$ref);
  620.                 $refPartNumber $splits[1];
  621.                 $version $partRepository->setAmount($refPartNumber$part->getCompany(), $admin);
  622.                 $splits[2] = $version;
  623.                 $newPart->setVersion(ltrim($version"0"));
  624.                 $newRef implode("-"$splits);
  625.                 $newPart->setEditRef($newRef);
  626.                 $newPart->setAutor($admin->getName());
  627.                 $newPart->setLocked(null);
  628.                 $newPart->markAsCreatedAt();
  629.                 $newPart->markAsUpdated();
  630.                 $newPart->setPrototypeStatus(Part::UNDER_PREPARATION);
  631.                 $em->persist($newPart);
  632.                 $em->flush();
  633.                 $this->partService->updateLibs($newPart$libraryIds);
  634.                 $this->addFlash('success'$this->translator->trans('Versión de pieza creada correctamente'));
  635.                 $data['message']='Pieza versionada';
  636.                 $data['name']=$part->getName();
  637.                 $data['reference']=$part->getRef();
  638.                 $data['path_name']='part_show';
  639.                 $data['path_parameters']='id:'.$part->getId();
  640.                 $this->util->notifications($part->getCompany(), 2$data$this->getUser());
  641.             }
  642.             //START Process remove
  643.             $partToRemove $actionType==&& $newPart $newPart $part;
  644.             if(!empty($request->request->get('filesToDelete'))){
  645.                 $fields explode(',',$request->request->get('filesToDelete'));
  646.                 foreach($fields as $field){
  647.                     if($field){
  648.                         $this->processRm($partToRemove$field);
  649.                     }
  650.                 }
  651.             }
  652.             if(!empty($request->request->get('filesOthersToDelete')) || $request->request->get('filesOthersToDelete')==='0'){
  653.                 $indexes explode(',',$request->request->get('filesOthersToDelete'));
  654.                 $this->processRm($partToRemove'others'$indexes);
  655.             }
  656.             //END Process remove
  657.             return $this->redirectToRoute('part_index');
  658.         }
  659.         elseif ($form->isSubmitted()){
  660.             $errors $this->partService->processTabErrors($form);
  661.             $this->addFlash('error'$this->translator->trans('Ha habido un error al procesar el formulario, revise los campos'));
  662.         }
  663.         if($part->getType() == 1) {
  664.             $title $this->translator->trans("Editar Pieza").' - '.$part->getName() . ($part->getVersion()>' V'.$part->getVersion() : '');
  665.             $navbarIcon 'bi bi-badge-3d';
  666.         } else {
  667.             $title $this->translator->trans("Editar Prototipo").' - '.$part->getName() . ($part->getVersion()>' V'.$part->getVersion() : '');
  668.             $navbarIcon 'bi bi-p-square';
  669.         }
  670.         return $this->render('part/edit.html.twig', [
  671.             'user' => $admin,
  672.             'part' => $part,
  673.             'fileMaxsizes' => $fileMaxsizes,
  674.             'form' => $form->createView(),
  675.             'errors' => json_encode($errors),
  676.             'errorsSubmitted' => json_encode($errorsSubmitted),
  677.             'license' => $this->util->getActiveLicense($admin->getCompany()),
  678.             'navbarTitle' => $title,
  679.             'navbarIcon' => $navbarIcon
  680.         ]);
  681.     }
  682.     private function processRm(Part $part$field$indexes=[]){
  683.         $result = ['error'=>false'msg'=>''];
  684.         $em $this->em;
  685.         $fs = new Filesystem();
  686.         $ds DIRECTORY_SEPARATOR;
  687.         $fields = [
  688.             'cad'=>'FileCad',
  689.             'stl'=>'FileStl',
  690.             'fab'=>'FileFab',
  691.             'verif'=>'FileVerif',
  692.             '2d'=>'File2d',
  693.             'others'=>'FileOthers'];
  694.         if(!empty($fields[$field])){
  695.             $getter 'get'.$fields[$field];
  696.             $setter 'set'.$fields[$field];
  697.             $fileToRemove $part->$getter();
  698.             $filesToRemove = [];
  699.             $setterData null;
  700.             if($field == 'others'){
  701.                 if(count($indexes)>0){
  702.                     $filenames =  explode(',',$fileToRemove);
  703.                     foreach($indexes as $index){
  704.                         if($index != '' && !empty($filenames[$index])){
  705.                             $filesToRemove[] = $filenames[$index];
  706.                             unset($filenames[$index]);
  707.                         }
  708.                     }
  709.                     $setterData count($filenames)>implode(',',$filenames) : null;
  710.                 }
  711.             }
  712.             else{
  713.                 $filesToRemove[]=$fileToRemove;
  714.             }
  715.             foreach($filesToRemove as $fileToRemove){
  716.                 if($fileToRemove){
  717.                     $part->$setter($setterData);
  718.                     $em->flush();
  719.                     //Verificamos si el archivo se usa en otra pieza versionada
  720.                     $fileInVersions $this->partService->fileInVersions($part,$field,$fileToRemove);
  721.                     if(!$fileInVersions && $fs->exists($this->partDir.$ds.$fileToRemove)){
  722.                         try {
  723.                             $fs->remove($this->partDir.$ds.$fileToRemove);
  724.                         } catch (IOExceptionInterface $exception) {
  725.                             $result = ['error'=>true,'msg'=>$this->translator->trans('No se ha podido eliminar el archivo')];
  726.                         }
  727.                     }
  728.                 }
  729.             }
  730.         }
  731.         return $result;
  732.     }
  733.     private function processOtherFiles(FormInterface $formPart $part$limit=5$encrypt false){
  734.         $files $form->get('fileOthers')->getData();
  735.         if(count($files)>0){
  736.             $slugger = new AsciiSlugger();
  737.             $filenames = !empty($part->getFileOthers()) ? explode(',',$part->getFileOthers()) : [];
  738.             try {
  739.                 foreach($files as $file)
  740.                 {
  741.                     $originalFilename pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
  742.                     $safeFilename $slugger->slug($originalFilename);
  743.                     $newFilename $safeFilename.'-'.uniqid().'.'.$file->getClientOriginalExtension();
  744.                     if(!in_array($newFilename,$filenames)){
  745.                         if(count($filenames)>$limit){
  746.                             $this->addFlash('warning'$this->translator->trans('Se excedió el ḿaximo de archivos que se pueden cargar'));
  747.                             break;
  748.                         }
  749.                         else{
  750.                             $file->move($this->partDir$newFilename);
  751.                             if ($encrypt){
  752.                                 try {
  753.                                     $this->encryptDecryptService->encryptData($newFilename);
  754.                                     $newFilename $newFilename.'.packaged';
  755.                                 } catch (\Exception $e) {
  756.                                     $this->addFlash('warning'$e->getMessage());
  757.                                 }
  758.                             }
  759.                             $filenames[]=$newFilename;
  760.                             $part->setFileOthers(implode(',',$filenames));
  761.                         }
  762.                     }
  763.                 }
  764.             }
  765.             catch (FileException $e) {
  766.                 $this->addFlash('danger'$this->translator->trans('Fallo en la carga de fichero'));
  767.             }
  768.         }
  769.     }
  770.     private function processFiles(FormInterface $formPart $partbool $checkVersions=false$optionsEncrypt=[]){
  771.         $fs = new Filesystem;
  772.         $ds DIRECTORY_SEPARATOR;
  773.         $slugger = new AsciiSlugger();
  774.         $fields = [
  775.             'fileCadFile'=>'FileCad',
  776.             'fileStlFile'=>'FileStl',
  777.             'fileFabFile'=>'FileFab',
  778.             'fileVerifFile'=>'FileVerif',
  779.             'file2dFile'=>'File2d'];
  780.         $encryptFields = [
  781.             'fileCadFile'=>'encryptCAD',
  782.             'fileStlFile'=>'encryptSTL',
  783.             'fileFabFile'=>'encryptFAB',
  784.             'fileVerifFile'=>'encryptVER',
  785.             'file2dFile'=>'encrypt2D'
  786.         ];
  787.         foreach($fields as $field=>$aux){
  788.             $setter 'set'.$aux;
  789.             $getter 'get'.$aux;
  790.             $file $form->get($field)->getData();
  791.             if ($file) {
  792.                 $originalFilename pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
  793.                 $safeFilename $slugger->slug($originalFilename);
  794.                 $newFilename $safeFilename.'-'.uniqid().'.'.($field=='fileStlFile' 'stl' $file->getClientOriginalExtension());
  795.                 try {
  796.                     $file->move($this->partDir,$newFilename);
  797.                     if(!empty($optionsEncrypt[$encryptFields[$field]])){
  798.                         try {
  799.                             $this->encryptDecryptService->encryptData($newFilename);
  800.                             $newFilename $newFilename.'.packaged';
  801.                         } catch (\Exception $e) {
  802.                             $this->addFlash('warning'$e->getMessage());
  803.                         }
  804.                     }
  805.                     //dd($this->partDir, $newFilename, $optionsEncrypt);
  806.                 } catch (FileException $e) {
  807.                     $this->addFlash('danger'$this->translator->trans('Fallo en la carga de fichero').' ['.$e->getMessage().']');
  808.                 }
  809.                 if($checkVersions && !empty($part->$getter())){
  810.                     //Verificamos si el archivo se usa en otra pieza versionada
  811.                     $fileInVersions $this->partService->fileInVersions($partstrtolower(str_replace('File','',$aux)), $part->$getter());
  812.                     $oldFilePath $this->partDir.$ds.$part->$getter();
  813.                     if(!$fileInVersions && $fs->exists($oldFilePath)){
  814.                         try {
  815.                             $fs->remove($oldFilePath);
  816.                         } catch (IOExceptionInterface $e) {
  817.                             $this->addFlash('warning'$this->translator->trans('No se ha podido eliminar el archivo'));
  818.                         }
  819.                     }
  820.                 }
  821.                 $part->$setter($newFilename);
  822.                 if($aux=='FileStl'){
  823.                     $part->setFilePreview(null);
  824.                 }
  825.             }
  826.         }
  827.     }
  828.     /**
  829.      * @Route({"en": "/delete/{id}",
  830.      *         "es": "/borrar/{id}"}, name="part_delete", methods={"DELETE"})
  831.      */
  832.     public function delete(Request $requestPart $part): Response
  833.     {
  834.         $this->denyAccessUnlessGranted(PartVoter::DELETE$part);
  835.         if($request->request->get('redirect_to_name')){
  836.             if($request->request->get('redirect_to_id')){
  837.                 $redirect_to $this->redirectToRoute(
  838.                     $request->request->get('redirect_to_name'),
  839.                     ['id'=>$request->request->get('redirect_to_id')]);
  840.             }
  841.             else{
  842.                 $redirect_to $this->redirectToRoute($request->request->get('redirect_to_name'));
  843.             }
  844.         }
  845.         else{
  846.             $redirect_to $this->redirectToRoute('part_index');
  847.         }
  848.         if ($this->isCsrfTokenValid('delete' $part->getId(), $request->request->get('_token'))) {
  849.             $rmPart $this->partService->rmPart($part);
  850.             if($rmPart['error']){
  851.                 $this->addFlash('danger'$rmPart['msg']);
  852.             }
  853.             else{
  854.                 $this->addFlash('success'$this->translator->trans('Pieza eliminada correctamente'));
  855.             }
  856.         }
  857.         return $redirect_to;
  858.     }
  859.     /**
  860.      * @Route({"en": "/preview/{id}",
  861.      *         "es": "/preview/{id}"}, name="part_preview", methods={"POST"})
  862.      */
  863.     public function partPreview(Request $requestPart $part): Response
  864.     {
  865.         $this->denyAccessUnlessGranted(PartVoter::VIEW$part);
  866.         $result = ['error'=>false,'msg'=>'','data'=>''];
  867.         $fs = new Filesystem();
  868.         $ds DIRECTORY_SEPARATOR;
  869.         $em $this->em;
  870.         $file $request->request->get('file');
  871.         if ($file && $part) {
  872.             $filedata explode(','$file);
  873.             if(count($filedata)==2){
  874.                 $filename 'part_peview_' $part->getId() . '.jpg';
  875.                 $result['file']=$filedata[1];
  876.                 $filedata base64_decode($filedata[1]);
  877.                 $filepath $this->partDir$ds $filename;
  878.                 //if(!$fs->exists($filepath)){
  879.                     $fs->dumpFile($filepath$filedata);
  880.                     $part->setFilePreview($filename);
  881.                     $em->flush();
  882.                 //}
  883.             }
  884.         }
  885.         return new JsonResponse($result);
  886.     }
  887.     /**
  888.      * @Route({"en": "/lock_unlock/{id}",
  889.      *         "es": "/bloquear_desbloquear/{id}"}, name="part_lock_unlock", methods={"POST"})
  890.      */
  891.     public function lockUnlock(Request $requestPart $part): Response
  892.     {
  893.         $this->denyAccessUnlessGranted(PartVoter::DELETE$part);
  894.         if ($this->isCsrfTokenValid('delete' $part->getId(), $request->request->get('_token'))) {
  895.             $em $this->em;
  896.             if($part->getLocked()){
  897.                 $part->setLocked(false);
  898.             }
  899.             else{
  900.                 $part->setLocked(true);
  901.             }
  902.             $part->setLockedAt(new \DateTime());
  903.             $part->setLockedUser($this->getUser());
  904.             $em->flush();
  905.             $successMsg $part->getLocked() ? 'Pieza bloqueada correctamente' 'Pieza desbloqueada correctamente';
  906.             $this->addFlash('success'$this->translator->trans($successMsg));
  907.         }
  908.         if($request->query->get('lib')){
  909.             return $this->redirectToRoute('library_show',['id'=>$request->query->get('lib')]);
  910.         }
  911.         else{
  912.             return $this->redirectToRoute('part_index');
  913.         }
  914.     }
  915.     /**
  916.      * @Route({"en": "/export/{library?}",
  917.      *         "es": "/exportar/{library?}"}, name="part_export" , methods={"GET"})
  918.      */
  919.     public function export(Request $requestPartRepository $partRepository, ?Library $library null, ?int $part)
  920.     {
  921.         $trans $this->translator;
  922.         if (null !== $library) {
  923.             $filename 'AD2_'.$trans->trans('librería').'_' $library->getName() . '_' date("dmY.His") . ".xlsx";
  924.         } else {
  925.             if (null !== $part) {
  926.                 $filename 'AD2_'.$trans->trans('pieza').'_' $part->getRef() . '_' date("dmY.His") . ".xlsx";
  927.             } else {
  928.                 $filename 'AD2_'.$trans->trans('listado').'_'.$trans->trans('piezas').'_' date("dmY.His") . ".xlsx";
  929.             }
  930.         }
  931.         $part null;
  932.         if (null !== $request->query->get('id')) {
  933.                 $part $partRepository->find($request->query->get('id'));
  934.         }
  935.         $spreadsheet $this->generateXls($library,$partRepository,$part);
  936.         $writer = new Xlsx($spreadsheet);
  937.         $response = new StreamedResponse(
  938.             function () use ($writer) {
  939.                 $writer->save('php://output');
  940.             }
  941.         );
  942.         $response->headers->set('Content-Type''application/vnd.ms-excel');
  943.         $response->headers->set('Content-Disposition''attachment;filename="' $filename);
  944.         $response->headers->set('Cache-Control''max-age=0');
  945.         return $response;
  946.     }
  947.     /**
  948.      * @Route({"en": "/prototypeAccept/{id}",
  949.      *         "es": "/aceptar_prototipo/{id}"}, name="part_prototype_accept", methods={"GET"})
  950.      */
  951.     public function prototypeAccept(Part $part): Response
  952.     {
  953.         $em $this->em;
  954.         $user $this->getUser();
  955.         $part->setType(1);
  956.         $em->persist($part);
  957.         $em->flush();
  958.         $order =$this->em->getRepository(Order::class)->findOneBy(['id'=> $part->getPrototypeOrder()]);
  959.         if($order->getType() !== )  {
  960.             $order->setState(5);
  961.             $order->markAsCompleted();
  962.             $order->setCompleteUser($user);
  963.             $order->setCompleteDate(new \DateTime());
  964.             $em->persist($order);
  965.             $em->flush();
  966.         }
  967.         $successMsg ='Pieza creada correctamente';
  968.         $this->addFlash('success'$this->translator->trans($successMsg));
  969.         return $this->redirectToRoute('part_show', ['id'=>$part->getId()]);
  970.     }
  971.     /**
  972.      * @Route({"en": "/prototypeDecline/{id}",
  973.      *         "es": "/rechazar_prototipo/{id}"}, name="part_prototype_decline", methods={"GET"})
  974.      */
  975.     public function prototypeDecline(Part $part): Response
  976.     {
  977.         $em $this->em;
  978.         $user $this->getUser();
  979.         $part->setPrototypeStatus(Part::REFUSED);
  980.         $em->persist($part);
  981.         $em->flush();
  982.         $order =$this->em->getRepository(Order::class)->findOneBy(['id'=> $part->getPrototypeOrder()]);
  983.         $order->setState(ORDER::IN_PREPARATION);
  984.         $em->persist($order);
  985.         $em->flush();
  986.         $successMsg ='Prototipo rechazado';
  987.         $this->addFlash('success'$this->translator->trans($successMsg));
  988.         $data['message']='Prototipo rechazado';
  989.         $data['name']=$part->getName();
  990.         $data['reference']=$part->getRef();
  991.         $data['path_name']='part_show';
  992.         $data['path_parameters']='id:'.$part->getId();
  993.         $this->util->notifications($part->getCompany(), 2$data$this->getUser());
  994.         if($part->getType() == 2){
  995.             //Notificaciones - proveedor
  996.             $this->util->notifications($order->getSupplier()->getCompany(), 3$data$order->getSupplier()->getUser(), $order->getId());
  997.         }
  998.         return $this->redirectToRoute('order_show', ['id'=>$order->getId()]);
  999.     }
  1000.     /**
  1001.      * @Route({"en": "/import",
  1002.      *         "es": "/importar"}, name="part_import" , methods={"GET", "POST"})
  1003.      */
  1004.     public function import(Request $requestPartRepository $partRepositorystring $excelDirstring $partDir)
  1005.     {
  1006.         $this->denyAccessUnlessGranted(PartVoter::IMPORT, new Part);
  1007.         $fs = new Filesystem();
  1008.         $admin $this->getUser();
  1009.         $licenseLimit 0;
  1010.         //límites licencia
  1011.         if(!($admin->getRole()=='ROLE_ADMIN')){
  1012.             $lc =$this->em->getRepository(LicenseCompany::class)->findOneBy(['company'=>$admin->getCompany(),'state'=>2]);
  1013.             if($lc){
  1014.                 $licenseData $this->util->getCompanySuscriptionAvailable($lc);
  1015.                 if(!empty($licenseData['parts']['available'])){
  1016.                     $licenseLimit=intval($licenseData['parts']['available']);
  1017.                 }
  1018.             }
  1019.         }
  1020.         else{
  1021.             $licenseLimit=-1;
  1022.         }
  1023.         $report = ['loaded'=>[],'errors'=>[]];
  1024.         $part = new Part();
  1025.         $form $this->createForm(PartImportType::class, $part, ['user_admin' => $admin]);
  1026.         $form->handleRequest($request);
  1027.         if ($form->isSubmitted()) {
  1028.             $filenames = [];
  1029.             $up 0;
  1030.             if ($stlFiles $form['stlFiles']->getData()) {
  1031.                 try {
  1032.                     if(!$fs->exists($partDir)){
  1033.                         $fs->mkdir($partDir);
  1034.                     }
  1035.                     foreach($stlFiles as $stl)
  1036.                     {
  1037.                         $ext $stl->getClientOriginalExtension();
  1038.                         if ($ext == 'stl') {
  1039.                             $fileName pathinfo($stl->getClientOriginalName(), PATHINFO_FILENAME);
  1040.                             $filenames[$up][0] = $fileName;
  1041.                             $fileName $fileName '_' date("dmY.His") . '.' $ext;
  1042.                             $filenames[$up][1] = $fileName;
  1043.                             $stl->move($partDir$fileName);
  1044.                             $up++;
  1045.                         }
  1046.                     }
  1047.                 }catch (FileException $e) {
  1048.                     $this->addFlash('danger'$this->translator->trans('Fallo en la carga masiva de fichero STL').' : '.$e->getMessage());
  1049.                     return $this->redirectToRoute('part_import');
  1050.                 }
  1051.                 catch (IOExceptionInterface $e) {
  1052.                     $this->addFlash('danger'$this->translator->trans('Fallo en la carga masiva de fichero STL').' : '.$e->getPath());
  1053.                     return $this->redirectToRoute('part_import');
  1054.                 }
  1055.             }
  1056.             if(empty($filenames) || (empty($form['excelFile']->getData()) || $form['excelFile']->getData()->guessExtension()!='xlsx')){
  1057.                 $this->addFlash('danger'$this->translator->trans('Los ficheros Excel y STL son requeridos y deben ser del tipo establecido'));
  1058.                 return $this->redirectToRoute('part_import');
  1059.             }
  1060.             if ($excel $form['excelFile']->getData()) {
  1061.                 try {
  1062.                     if(!$fs->exists($excelDir)){
  1063.                         $fs->mkdir($excelDir);
  1064.                     }
  1065.                     //cogemos la extensión y comprobamos antes de continuar
  1066.                     $fileName pathinfo($excel->getClientOriginalName(), PATHINFO_FILENAME);
  1067.                     $fileName $fileName '_' date("dmY.His") . '.xlsx';
  1068.                     $excel->move($excelDir$fileName);
  1069.                     $routeFileName $excelDir '/' $fileName;
  1070.                     /**  Identify the type of $inputFileName  **/
  1071.                     $inputFileType IOFactory::identify($routeFileName);
  1072.                     /**  Create a new Reader of the type that has been identified  **/
  1073.                     $reader IOFactory::createReader($inputFileType);
  1074.                     $reader->setReadDataOnly(false);
  1075.                     /**  Load $inputFileName to a Spreadsheet Object  **/
  1076.                     $spreadsheet $reader->load($routeFileName);
  1077.                     $sheet $spreadsheet->getActiveSheet();
  1078.                     $x 0;
  1079.                     $z 0;
  1080.                     foreach ($sheet->getColumnIterator() as $column) {
  1081.                         $cellIterator $column->getCellIterator();
  1082.                         foreach ($cellIterator as $cell) {
  1083.                             $value $cell->getValue();
  1084.                             $piezaMasiva[$x][$z] = $value;
  1085.                             $z++;
  1086.                         }
  1087.                         if($x !== 0){
  1088.                             $company $admin->getCompany();
  1089.                             $partName $piezaMasiva[$x][1];
  1090.                             if($piezaMasiva[$x][1] == ''){
  1091.                                 $this->importReportProcess($report);
  1092.                                 return $this->redirectToRoute('part_index');
  1093.                             }
  1094.                             $nameExists $partRepository->nameExists($partName,$company->getId());
  1095.                             if($nameExists){
  1096.                                 $report['errors'][1][] = $piezaMasiva[$x][1];
  1097.                             }
  1098.                             elseif($licenseLimit==0){
  1099.                                 $report['errors'][3] = true;
  1100.                                 break;
  1101.                             }
  1102.                             else{
  1103.                                 $newMasivePart = new Part();
  1104.                                 $newMasivePart->setBulkImportFile($fileName);
  1105.                                 //Datos Básicos
  1106.                                 $newMasivePart->setCompany($company);
  1107.                                 $newMasivePart->setName($piezaMasiva[$x][1]);
  1108.                                 $piezaMasiva[$x][2] == '' null $newMasivePart->setDescription($piezaMasiva[$x][2]);
  1109.                                 $piezaMasiva[$x][3] == '' null $newMasivePart->setClientName($piezaMasiva[$x][3]);
  1110.                                 $piezaMasiva[$x][4] == '' null $newMasivePart->setClientRefPart($piezaMasiva[$x][4]);
  1111.                                 $piezaMasiva[$x][5] == '' null $newMasivePart->setPartNumber($piezaMasiva[$x][5]);
  1112.                                 $piezaMasiva[$x][6] == '' null $newMasivePart->setSerial($piezaMasiva[$x][6]);
  1113.                                 $piezaMasiva[$x][7] == '' null $newMasivePart->setNotes($piezaMasiva[$x][7]);
  1114.                                 //Fabricacion
  1115.                                 $piezaMasiva[$x][10] == '' null $newMasivePart->setTechnology($piezaMasiva[$x][10]);
  1116.                                 $piezaMasiva[$x][11] == '' null $newMasivePart->setEquipo($piezaMasiva[$x][11]);
  1117.                                 $piezaMasiva[$x][12] == '' null $newMasivePart->setMaterial($piezaMasiva[$x][12]);
  1118.                                 $piezaMasiva[$x][13] == '' null $newMasivePart->setPrintMode($piezaMasiva[$x][13]);
  1119.                                 $piezaMasiva[$x][14] == '' null $newMasivePart->setAlturaCapa($piezaMasiva[$x][14]);
  1120.                                 $piezaMasiva[$x][15] == '' null $newMasivePart->setAlturaCapaTol($piezaMasiva[$x][15]);
  1121.                                 $piezaMasiva[$x][16] == '' null $newMasivePart->setDiamBoquilla($piezaMasiva[$x][16]);
  1122.                                 $piezaMasiva[$x][17] == '' null $newMasivePart->setDiamBoquillaTol($piezaMasiva[$x][17]);
  1123.                                 $piezaMasiva[$x][18] == '' null $newMasivePart->setTmpBoquilla($piezaMasiva[$x][18]);
  1124.                                 $piezaMasiva[$x][19] == '' null $newMasivePart->setTmpBoquillaTol($piezaMasiva[$x][19]);
  1125.                                 $piezaMasiva[$x][20] == '' null $newMasivePart->setTmpCama($piezaMasiva[$x][20]);
  1126.                                 $piezaMasiva[$x][21] == '' null $newMasivePart->setTmpCamaTol($piezaMasiva[$x][21]);
  1127.                                 $piezaMasiva[$x][22] == '' null $newMasivePart->setTmpCamara($piezaMasiva[$x][22]);
  1128.                                 $piezaMasiva[$x][23] == '' null $newMasivePart->setTmpCamaraTol($piezaMasiva[$x][23]);
  1129.                                 $piezaMasiva[$x][24] == '' null $newMasivePart->setVelocidadImpresion($piezaMasiva[$x][24]);
  1130.                                 $piezaMasiva[$x][25] == '' null $newMasivePart->setVelocidadImpresionTol($piezaMasiva[$x][25]);
  1131.                                 $piezaMasiva[$x][26] == '' null $newMasivePart->setPerimetroRelleno($piezaMasiva[$x][26]);
  1132.                                 $piezaMasiva[$x][27] == '' null $newMasivePart->setSoportes($piezaMasiva[$x][27]);
  1133.                                 $piezaMasiva[$x][28] == '' null $newMasivePart->setPuntoLaser($piezaMasiva[$x][28]);
  1134.                                 $piezaMasiva[$x][29] == '' null $newMasivePart->setPuntoLaserTol($piezaMasiva[$x][29]);
  1135.                                 $piezaMasiva[$x][30] == '' null $newMasivePart->setPotenciaFuente($piezaMasiva[$x][30]);
  1136.                                 $piezaMasiva[$x][31] == '' null $newMasivePart->setPotenciaFuenteTol($piezaMasiva[$x][31]);
  1137.                                 $piezaMasiva[$x][32] == '' null $newMasivePart->setTamPixel($piezaMasiva[$x][32]);
  1138.                                 $piezaMasiva[$x][33] == '' null $newMasivePart->setTamPixelTol($piezaMasiva[$x][33]);
  1139.                                 $piezaMasiva[$x][34] == '' null $newMasivePart->setTiempoExpos($piezaMasiva[$x][34]);
  1140.                                 $piezaMasiva[$x][35] == '' null $newMasivePart->setTiempoExposTol($piezaMasiva[$x][35]);
  1141.                                 $piezaMasiva[$x][36] == '' null $newMasivePart->setDistanHatch($piezaMasiva[$x][36]);
  1142.                                 $piezaMasiva[$x][37] == '' null $newMasivePart->setDistanHatchTol($piezaMasiva[$x][37]);
  1143.                                 $piezaMasiva[$x][38] == '' null $newMasivePart->setVelocidadRecoater($piezaMasiva[$x][38]);
  1144.                                 $piezaMasiva[$x][39] == '' null $newMasivePart->setVelocidadRecoaterTol($piezaMasiva[$x][39]);
  1145.                                 $piezaMasiva[$x][40] == '' null $newMasivePart->setEnfriamiento($piezaMasiva[$x][40]);
  1146.                                 $piezaMasiva[$x][41] == '' null $newMasivePart->setAtmosfera($piezaMasiva[$x][41]);
  1147.                                 $piezaMasiva[$x][42] == '' null $newMasivePart->setSaturacion($piezaMasiva[$x][42]);
  1148.                                 $piezaMasiva[$x][43] == '' null $newMasivePart->setObservacionesFab($piezaMasiva[$x][43]);
  1149.                                 //Validación
  1150.                                 $piezaMasiva[$x][46] == '' null $newMasivePart->setCompMatPrima($piezaMasiva[$x][46]);
  1151.                                 $piezaMasiva[$x][47] == '' null $newMasivePart->setCertMatPrima($piezaMasiva[$x][47]);
  1152.                                 $piezaMasiva[$x][48] == '' null $newMasivePart->setColorMatPrima($piezaMasiva[$x][48]);
  1153.                                 $piezaMasiva[$x][49] == '' null $newMasivePart->setCertProceso($piezaMasiva[$x][49]);
  1154.                                 $piezaMasiva[$x][50] == '' null $newMasivePart->setCertPart($piezaMasiva[$x][50]);
  1155.                                 $piezaMasiva[$x][51] == '' null $newMasivePart->setApplicableRegulations($piezaMasiva[$x][51]);
  1156.                                 $piezaMasiva[$x][52] == '' null $newMasivePart->setProcAcabado($piezaMasiva[$x][52]);
  1157.                                 $piezaMasiva[$x][53] == '' null $newMasivePart->setOtrosTrat($piezaMasiva[$x][53]);
  1158.                                 $piezaMasiva[$x][54] == '' null $newMasivePart->setObsVal($piezaMasiva[$x][54]);
  1159.                                 //stl
  1160.                                 $stlFound false;
  1161.                                 if($piezaMasiva[$x][57] !== ''){
  1162.                                     foreach($filenames as $k=>$name){
  1163.                                         $fn $piezaMasiva[$x][57];
  1164.                                         if(strrpos($fn".")){
  1165.                                             $fn substr($fn0, (strrpos($fn".")));
  1166.                                         }
  1167.                                         if($name[0] == $fn){
  1168.                                             unset($filenames[$k]);
  1169.                                             $newMasivePart->setFileStl($name[1]);
  1170.                                             $stlFound true;
  1171.                                             break;
  1172.                                         }
  1173.                                     }
  1174.                                 }
  1175.                                 if(!$stlFound){
  1176.                                     $report['errors'][2][] = $piezaMasiva[$x][1];
  1177.                                 }
  1178.                                 else{
  1179.                                     //Dependientes
  1180.                                     $newMasivePart->setRef($partRepository->findLastRef($company));
  1181.                                     $newMasivePart->setVersion(1);
  1182.                                     $newMasivePart->setAutor($admin->getName());
  1183.                                     $entityManager $this->em;
  1184.                                     $entityManager->persist($newMasivePart);
  1185.                                     $entityManager->flush();
  1186.                                     $report['loaded'][] = $piezaMasiva[$x][1];
  1187.                                     $licenseLimit--;
  1188.                                 }
  1189.                             }
  1190.                         }
  1191.                         $x++;
  1192.                         $z 0;
  1193.                     }
  1194.                 } catch (FileException $e) {
  1195.                     $this->addFlash('danger'$this->translator->trans('Fallo en la carga masiva de piezas').' : '.$e->getMessage());
  1196.                     return $this->redirectToRoute('part_import');
  1197.                 }
  1198.                 catch (IOExceptionInterface $e) {
  1199.                     $this->addFlash('danger'$this->translator->trans('Fallo en la carga masiva de piezas').' : '.$e->getPath());
  1200.                     return $this->redirectToRoute('part_import');
  1201.                 }
  1202.             }
  1203.             //Si quedan archivos sin asignar los eliminamos
  1204.             if($filenames){
  1205.                 foreach($filenames as $k=>$name){
  1206.                     if(!empty($name[1])){
  1207.                         $filepath $partDir.DIRECTORY_SEPARATOR.$name[1];
  1208.                         if($fs->exists($filepath)){
  1209.                             $fs->remove($filepath);
  1210.                         }
  1211.                     }
  1212.                 }
  1213.             }
  1214.             $this->importReportProcess($report);
  1215.             return $this->redirectToRoute('part_index');
  1216.         }
  1217.         return $this->render('part/import.html.twig', [
  1218.             'user' => $admin,
  1219.             //'part' => $part,
  1220.             'locale'=> $this->translator->getLocale(),
  1221.             'excel_form' => $form->createView(),
  1222.             'navbarTitle' => $this->translator->trans("Subida masiva de piezas")
  1223.         ]);
  1224.     }
  1225.     /**
  1226.      * @Route({"en": "/zip/{library?}",
  1227.      *         "es": "/zip/{library?}"}, name="part_zip", methods={"GET"})
  1228.      */
  1229.     public function partZip(Request $requestPartRepository $partRepository, ?Library $library null,?int $part)
  1230.     {
  1231.         $user $this->getUser();
  1232.         $part $partRepository->find($request->query->get('id'));
  1233.         $part_id $part->getId();
  1234.         $company_id $part->getCompany()->getId();
  1235.         $structure 'parts/zip/'.$company_id.'/'.$part_id;
  1236.         if (!file_exists($structure)) {
  1237.             if (!mkdir($structure0777true)) {
  1238.                 die('Fallo al crear las carpetas...');
  1239.             }
  1240.         }
  1241.         // Generate PDF
  1242.         $pdfData $this->htmlForPdf($part,$user);
  1243.         $this->pdf->generateFromHtml($pdfData['html'], $structure.'/'.$part->getRef().'.pdf',$pdfData['options'],true);
  1244.         // generate XLS
  1245.         $trans $this->translator;
  1246.         if (null !== $library) {
  1247.             $filename 'AD2_'.$trans->trans('librería').'_' $library->getName() .".xlsx";
  1248.         } else {
  1249.             if (null !== $part) {
  1250.                 $filename 'AD2_'.$trans->trans('pieza').'_' $part->getRef() .".xlsx";
  1251.             } else {
  1252.                 $filename 'AD2_'.$trans->trans('listado').'_'.$trans->trans('piezas').".xlsx";
  1253.             }
  1254.         }
  1255.         $spreadsheet $this->generateXls($library,$partRepository,$part);
  1256.         $writer = new Xlsx($spreadsheet);
  1257.         $writer->save($structure.'/'.$filename);
  1258.         $basename preg_replace('/[^a-zA-Z0-9_\-\s]/'''$part->getName());
  1259.         $basename str_replace(' ''-'$basename);
  1260.         $basename $part->getRef().'_'.$basename;
  1261.         $basename substr($basename040);
  1262.         // ZIP all
  1263.         $zipName $basename.'.zip';
  1264.         $zip = new \ZipArchive();
  1265.         if ($zip->open($structure.'/'.$zipName$zip::CREATE) === TRUE)
  1266.         {
  1267.             if($part->getFileStl() && file_exists('parts/'.$part->getFileStl())) {
  1268.                 $zip->addFile('parts/'.$part->getFileStl(),'files/'.$part->getFileStl());
  1269.             }
  1270.             if($part->getFileCad() && file_exists('parts/'.$part->getFileCad())) {
  1271.                 $zip->addFile('parts/'.$part->getFileCad(),'files/'.$part->getFileCad());
  1272.             }
  1273.             if($part->getFileFab() && file_exists('parts/'.$part->getFileFab())) {
  1274.                 $zip->addFile('parts/'.$part->getFileFab(),'files/'.$part->getFileFab());
  1275.             }
  1276.             if($part->getFileVerif() && file_exists('parts/'.$part->getFileVerif())) {
  1277.                 $zip->addFile('parts/'.$part->getFileVerif(),'files/'.$part->getFileVerif());
  1278.             }
  1279.             if($part->getFile2d() && file_exists('parts/'.$part->getFile2d())) {
  1280.                 $zip->addFile('parts/'.$part->getFile2d(),'files/'.$part->getFile2d());
  1281.             }
  1282.             if($part->getFileOthers() && file_exists('parts/'.$part->getFileOthers())) {
  1283.                 $zip->addFile('parts/'.$part->getFileOthers(),'files/'.$part->getFileOthers());
  1284.             }
  1285.             if($part->getFilePreview() && file_exists('parts/'.$part->getFilePreview())) {
  1286.                 if($this->util->fileIsEncrypted($part->getFileStl())) {
  1287.                     $img 'images/file_encrypted.png';
  1288.                 } else {
  1289.                     $img 'parts/' $part->getFilePreview();
  1290.                 }
  1291.                 $extension pathinfo($part->getFilePreview(), PATHINFO_EXTENSION);
  1292.                 $zip->addFile($img,$basename.'.'.$extension);
  1293.             }
  1294.             $zip->addFile($structure.'/'.$part->getRef().'.pdf','pdfs/'.$part->getRef().'.pdf');
  1295.             $zip->addFile($structure.'/'.$filename,'xls/'.$filename);
  1296.             // All files are added, so close the zip file.
  1297.             $zip->close();
  1298.         }
  1299.         // delete temporally files
  1300.         unlink($structure.'/'.$part->getRef().'.pdf');
  1301.         unlink($structure.'/'.$filename);
  1302.         $response = new BinaryFileResponse($structure.'/'.$zipName);
  1303.         $response->setStatusCode(200);
  1304.         $response->headers->set('Content-Type''application/zip');
  1305.         $response->headers->set('Content-Disposition''attachment; filename="'.basename($zipName).'"');
  1306.         $response->headers->set('Content-Length'filesize($structure.'/'.$zipName));
  1307.         return $response;
  1308.     }
  1309.     public function multiplePartZip(PartRepository $partRepository,$partIds) {
  1310.         $user $this->getUser();
  1311.         // generate XLS
  1312.         $trans $this->translator;
  1313.         $basename preg_replace('/[^a-zA-Z0-9_\-\s]/''''AD2_Download_'.$user->getCompany()->getName());
  1314.         $basename str_replace(' ''-'$basename);
  1315.         //$basename = date('Ymdhis').'_'.$basename;
  1316.         $basename substr($basename040);
  1317.         $structure 'parts/zipPack/user/' $user->getId();
  1318.         if (!file_exists($structure)) {
  1319.             if (!mkdir($structure0777true)) {
  1320.                 die('Fallo al crear las carpetas...');
  1321.             }
  1322.         }
  1323.         $zipName $basename.'.zip';
  1324.         $zip = new \ZipArchive();
  1325.         //borramos el existente
  1326.         if(file_exists($structure.'/'.$zipName)) {
  1327.             unlink($structure.'/'.$zipName);
  1328.         }
  1329.         if ($zip->open($structure.'/'.$zipName$zip::CREATE) === TRUE) {
  1330.             foreach ($partIds as $part_id) {
  1331.                 $part $partRepository->find($part_id);
  1332.                 if($part) {
  1333.                     // Generate PDF
  1334.                     $pdfData $this->htmlForPdf($part$user);
  1335.                     $this->pdf->generateFromHtml($pdfData['html'], $structure '/' $part->getRef() . '.pdf'$pdfData['options'], true);
  1336.                     $filename 'AD2_' $trans->trans('pieza') . '_' $part->getRef() . ".xlsx";
  1337.                     $foldername 'AD2_' $part->getRef() . '_' $part->getName();
  1338.                     $foldername preg_replace('/[^a-zA-Z0-9_\-\s]/'''$foldername);
  1339.                     $foldername str_replace(' ''-'$foldername);
  1340.                     $foldername substr($foldername040);
  1341.                     $spreadsheet $this->generateXls(null$partRepository$part);
  1342.                     $writer = new Xlsx($spreadsheet);
  1343.                     $writer->save($structure '/' $filename);
  1344.                     if ($part->getFileStl() && file_exists('parts/' $part->getFileStl())) {
  1345.                         $zip->addFile('parts/' $part->getFileStl(), $foldername.'/files/'$part->getFileStl());
  1346.                     }
  1347.                     if ($part->getFileCad() && file_exists('parts/' $part->getFileCad())) {
  1348.                         $zip->addFile('parts/' $part->getFileCad(), $foldername.'/files/'$part->getFileCad());
  1349.                     }
  1350.                     if ($part->getFileFab() && file_exists('parts/' $part->getFileFab())) {
  1351.                         $zip->addFile('parts/' $part->getFileFab(), $foldername.'/files/'.  $part->getFileFab());
  1352.                     }
  1353.                     if ($part->getFileVerif() && file_exists('parts/' $part->getFileVerif())) {
  1354.                         $zip->addFile('parts/' $part->getFileVerif(), $foldername.'/files/'.  $part->getFileVerif());
  1355.                     }
  1356.                     if ($part->getFile2d() && file_exists('parts/' $part->getFile2d())) {
  1357.                         $zip->addFile('parts/' $part->getFile2d(), $foldername.'/files/'.  $part->getFile2d());
  1358.                     }
  1359.                     if ($part->getFileOthers() && file_exists('parts/' $part->getFileOthers())) {
  1360.                         $zip->addFile('parts/' $part->getFileOthers(), $foldername.'/files/'$part->getFileOthers());
  1361.                     }
  1362.                     if ($part->getFilePreview() && file_exists('parts/' $part->getFilePreview())) {
  1363.                         if($this->util->fileIsEncrypted($part->getFileStl())) {
  1364.                             $img 'images/file_encrypted.png';
  1365.                         } else {
  1366.                             $img 'parts/' $part->getFilePreview();
  1367.                         }
  1368.                         $extension pathinfo($part->getFilePreview(), PATHINFO_EXTENSION);
  1369.                         $zip->addFile($img,  'AD2_' $part->getRef() . '_' $part->getName() . '.' $extension);
  1370.                     }
  1371.                     $zip->addFile($structure '/' $part->getRef() . '.pdf'$foldername.'/pdfs/'$part->getRef() . '.pdf');
  1372.                     $zip->addFile($structure '/' $filename$foldername.'/xls/' $filename);
  1373.                 }
  1374.             }//endforeach
  1375.             // All files are added, so close the zip file.
  1376.             $zip->close();
  1377.         }
  1378.         foreach ($partIds as $part_id) {
  1379.             if($part) {
  1380.                 // delete temporally files
  1381.                 $part $partRepository->find($part_id);
  1382.                 $filename 'AD2_' $trans->trans('pieza') . '_' $part->getRef() . ".xlsx";
  1383.                 unlink($structure '/' $part->getRef() . '.pdf');
  1384.                 unlink($structure '/' $filename);
  1385.             }
  1386.         }
  1387.         return array($structure,$zipName);
  1388.     }
  1389.     private function importReportProcess($report){
  1390.         //Loaded
  1391.         $loaded $report['loaded'];
  1392.         if(empty($loaded)){
  1393.             $message $nData['message'] = 'No se han podido cargado piezas';
  1394.         }
  1395.         else{
  1396.             $stringLoaded implode(', ',$loaded);
  1397.             $message "Se han cargado correctamente las siguientes piezas : $stringLoaded";
  1398.             $nData['message'] = "Se han cargado correctamente las siguientes piezas : {aux}";
  1399.             $nData['message_aux'] = $stringLoaded;
  1400.         }
  1401.         $nData['path_name']='part_index';
  1402.         $this->util->notifications($this->getUser()->getCompany(), 2$nData$this->getUser());
  1403.         $this->addFlash(empty($loaded) ? 'danger' 'success'$this->translator->trans($message));
  1404.         //Errors
  1405.         $errors $report['errors'];
  1406.         if(!empty($errors)){
  1407.             $message $this->translator->trans('Se han producido los siguientes errores : ');
  1408.             $message.= '<br>';
  1409.             if(!empty($errors[1])){
  1410.                 $error_1 count($errors[1])>array_slice($errors[1],0,5).' ...' $errors[1];
  1411.                 $message.= $this->translator->trans('Piezas con el nombre duplicado : ') . implode(', ',$error_1). '<br>';
  1412.             }
  1413.             if(!empty($errors[2])){
  1414.                 $error_2 count($errors[2])>array_slice($errors[2],0,5).' ...' $errors[2];
  1415.                 $message.= $this->translator->trans('Piezas sin archivo STL : ') . implode(', ',$error_2);
  1416.             }
  1417.             if(!empty($errors[3])){
  1418.                 $message.= $this->translator->trans("Se han agotado las piezas disponibles para su licencia") . '<br>';
  1419.             }
  1420.             $this->addFlash('danger'$this->translator->trans($message));
  1421.         }
  1422.     }
  1423.     /**
  1424.      * @param $part
  1425.      * @param $user
  1426.      * @return array
  1427.      * HTML FOR PDF
  1428.      */
  1429.     private function htmlForPdf($part,$user) {
  1430.         $url $this->generateUrl('part_show',['id'=>$part->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
  1431.         $qr $this->util->generateQrCode($url);
  1432.         if($this->util->fileIsEncrypted($part->getFileStl())) {
  1433.             $img =  $this->partDir DIRECTORY_SEPARATOR 'file_encrypted.png';
  1434.         } else {
  1435.             $img $this->partDir DIRECTORY_SEPARATOR $part->getFilePreview();
  1436.         }
  1437.         $header $this->renderView'part/pdf/pdf_header.html.twig',[
  1438.             'part' => $part,
  1439.             'partByCat' => $this->partService->getPartByCat($part),
  1440.             'orders' => $part->getOrders(),
  1441.             'qr' => $qr,
  1442.             'preview' => $part->getFilePreview() ? $img '',
  1443.             'user' => $user
  1444.         ] );
  1445.         $footer $this->renderView'part/pdf/pdf_footer.html.twig',[
  1446.             'part' => $part,
  1447.             'partByCat' => $this->partService->getPartByCat($part),
  1448.             'orders' => $part->getOrders(),
  1449.             'qr' => $qr,
  1450.             'user' => $user
  1451.         ] );
  1452.         $options = [
  1453.             'header-html' => $header,
  1454.             'footer-html' => $footer,
  1455.             'page-size' => 'A4'
  1456.         ];
  1457.         $html =$this->renderView('part/pdf/pdf.html.twig', [
  1458.             'part' => $part,
  1459.             'stl' => json_decode($part->getData(),true),
  1460.             'partByCat' => $this->partService->getPartByCat($part),
  1461.             'orders' => $part->getOrders(),
  1462.             'qr' => $qr,
  1463.             'user' => $user
  1464.         ]);
  1465.         return array(
  1466.             'html' =>$html,
  1467.             'options' => $options
  1468.         );
  1469.     }
  1470.     private function generateXls($library,PartRepository $partRepository,$part null) {
  1471.         $trans $this->translator;
  1472.         $admin $this->getUser();
  1473.         $company $admin->getCompany();
  1474.         $colorARGB $company && $company->getCorporateColor() ? str_replace('#','',$company->getCorporateColor()) : 'DD9933';
  1475.         $isSupplier in_array($admin->getRole(),['ROLE_SUPPLIER_CHIEF','ROLE_SUPPLIER']);
  1476.         $spreadsheet = new Spreadsheet();
  1477.         $sheet $spreadsheet->getActiveSheet();
  1478.         $sheet->setTitle(date("F j, Y"));
  1479.         $row 1;
  1480.         $titles = ['A'.$row];
  1481.         $sheet->setCellValue('A'.$row++, $trans->trans('Datos Básicos'));
  1482.         $sheet->setCellValue('A'.$row++, $trans->trans('Autor'));
  1483.         $sheet->setCellValue('A'.$row++, $trans->trans('Fecha Creación'));
  1484.         $sheet->setCellValue('A'.$row++, $trans->trans('Fecha Revisión'));
  1485.         $sheet->setCellValue('A'.$row++, $trans->trans('Nombre de pieza'));
  1486.         $sheet->setCellValue('A'.$row++, $trans->trans('Referencia'));
  1487.         if(!$isSupplier){
  1488.             $sheet->setCellValue('A'.$row++, $trans->trans('Descripcion'));
  1489.             $sheet->setCellValue('A'.$row++, $trans->trans('Nombre de Cliente'));
  1490.             $sheet->setCellValue('A'.$row++, $trans->trans('Referencia pieza Cliente'));
  1491.             $sheet->setCellValue('A'.$row++, $trans->trans('Part number'));
  1492.             $sheet->setCellValue('A'.$row++, $trans->trans('Serial number'));
  1493.         }
  1494.         $sheet->setCellValue('A'.$row++, $trans->trans('Observaciones'));
  1495.         $sheet->setCellValue('A'.$row++, '');
  1496.         $titles[]='A'.$row;
  1497.         $sheet->setCellValue('A'.$row++, $trans->trans('Fabricación'));
  1498.         $sheet->setCellValue('A'.$row++, $trans->trans('Centro de trabajo'));
  1499.         $sheet->setCellValue('A'.$row++, $trans->trans('Tecnología'));
  1500.         $sheet->setCellValue('A'.$row++, $trans->trans('Equipo'));
  1501.         $sheet->setCellValue('A'.$row++, $trans->trans('Material'));
  1502.         $sheet->setCellValue('A'.$row++, $trans->trans('Modo impresión'));
  1503.         $sheet->setCellValue('A'.$row++, $trans->trans('Altura capa (μm)') . ' [' $trans->trans('Tolerancia').']');
  1504.         $sheet->setCellValue('A'.$row++, $trans->trans('Diam. boquilla (mm)') . ' [' $trans->trans('Tolerancia').']');
  1505.         $sheet->setCellValue('A'.$row++, $trans->trans('Temperatura extrusor (ºC)') . ' [' $trans->trans('Tolerancia').']');
  1506.         $sheet->setCellValue('A'.$row++, $trans->trans('Temperatura cama (ºC)') . ' [' $trans->trans('Tolerancia').']');
  1507.         $sheet->setCellValue('A'.$row++, $trans->trans('Temperatura cámara (ºC)') . ' [' $trans->trans('Tolerancia').']');
  1508.         $sheet->setCellValue('A'.$row++, $trans->trans('Velocidad de impresión (mm/s)') . ' [' $trans->trans('Tolerancia').']');
  1509.         $sheet->setCellValue('A'.$row++, $trans->trans('Perímetros y relleno'));
  1510.         $sheet->setCellValue('A'.$row++, $trans->trans('Soportes'));
  1511.         $sheet->setCellValue('A'.$row++, $trans->trans('Punto láser (μm)') . ' [' $trans->trans('Tolerancia').']');
  1512.         $sheet->setCellValue('A'.$row++, $trans->trans('Potencia Fuente (%)') . ' [' $trans->trans('Tolerancia').']');
  1513.         $sheet->setCellValue('A'.$row++, $trans->trans('Tamaño pixel (μm)') . ' [' $trans->trans('Tolerancia').']');
  1514.         $sheet->setCellValue('A'.$row++, $trans->trans('Tiempo Exposición (s)') . ' [' $trans->trans('Tolerancia').']');
  1515.         $sheet->setCellValue('A'.$row++, $trans->trans('Distancia hatch (μm)') . ' [' $trans->trans('Tolerancia').']');
  1516.         $sheet->setCellValue('A'.$row++, $trans->trans('Velocidad recoater (mm/s)') . ' [' $trans->trans('Tolerancia').']');
  1517.         $sheet->setCellValue('A'.$row++, $trans->trans('Enfriamiento').' (h)');
  1518.         $sheet->setCellValue('A'.$row++, $trans->trans('Atmósfera controlada'));
  1519.         $sheet->setCellValue('A'.$row++, $trans->trans('Saturación (%)'));
  1520.         $sheet->setCellValue('A'.$row++, $trans->trans('Observaciones de fabricación'));
  1521.         $sheet->setCellValue('A'.$row++, '');
  1522.         $titles[]='A'.$row;
  1523.         $sheet->setCellValue('A'.$row++, $trans->trans('Validación'));
  1524.         $sheet->setCellValue('A'.$row++, $trans->trans('Composición materia prima'));
  1525.         $sheet->setCellValue('A'.$row++, $trans->trans('Certificación materia prima'));
  1526.         $sheet->setCellValue('A'.$row++, $trans->trans('Color materia prima'));
  1527.         $sheet->setCellValue('A'.$row++, $trans->trans('Certificación proceso'));
  1528.         $sheet->setCellValue('A'.$row++, $trans->trans('Certificación pieza'));
  1529.         $sheet->setCellValue('A'.$row++, $trans->trans('Normativa aplicable'));
  1530.         $sheet->setCellValue('A'.$row++, $trans->trans('Procesos de acabado'));
  1531.         $sheet->setCellValue('A'.$row++, $trans->trans('Otros tratamientos'));
  1532.         $sheet->setCellValue('A'.$row++, $trans->trans('Observaciones'));
  1533.         $sheet->setCellValue('A'.$row++, '');
  1534.         $titles[]='A'.$row;
  1535.         $sheet->setCellValue('A'.$row++, $trans->trans('Adjuntos'));
  1536.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo CAD (.step, otros)'));
  1537.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo Stl'));
  1538.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo Fabricación (.gcode, .pdf, otros)'));
  1539.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo Verificación (.txt, .pdf, .doc)'));
  1540.         $sheet->setCellValue('A'.$row++, $trans->trans('Planos 2D (.pdf)'));
  1541.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo N01'));
  1542.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo N02'));
  1543.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo N03'));
  1544.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo N04'));
  1545.         $sheet->setCellValue('A'.$row++, $trans->trans('Archivo N05'));
  1546.         $sheet->setCellValue('A'.$row++, '');
  1547.         if(!$isSupplier){
  1548.             $titles[]='A'.$row;
  1549.             $sheet->setCellValue('A'.$row++, $trans->trans('Biblioteca'));
  1550.             $sheet->setCellValue('A'.$row++, $trans->trans('Bibliotecas'));
  1551.         }
  1552.         $sheet->setCellValue('A'.$row++, '');
  1553.         $titles[]='A'.$row;
  1554.         $sheet->setCellValue('A'.$row++, $trans->trans('Datos STL'));
  1555.         $sheet->setCellValue('A'.$row++, $trans->trans('Volumen'));
  1556.         $sheet->setCellValue('A'.$row++, $trans->trans('Superficie'));
  1557.         $sheet->setCellValue('A'.$row++, $trans->trans('Altura'));
  1558.         $sheet->setCellValue('A'.$row++, $trans->trans('Ancho'));
  1559.         $sheet->setCellValue('A'.$row++, $trans->trans('Largo'));
  1560.         //$spreadsheet->createSheet();
  1561.         $styleArrayFirstRow = [
  1562.             'font' => [
  1563.                 'bold' => true,
  1564.             ]
  1565.         ];
  1566.         $highestColumn $sheet->getHighestColumn();
  1567.         $sheet->getStyle($titles[0])->applyFromArray($styleArrayFirstRow);
  1568.         $sheet->getStyle($titles[1])->applyFromArray($styleArrayFirstRow);
  1569.         $sheet->getStyle($titles[2])->applyFromArray($styleArrayFirstRow);
  1570.         $sheet->getStyle($titles[3])->applyFromArray($styleArrayFirstRow);
  1571.         if(!$isSupplier){
  1572.             $sheet->getStyle($titles[4])->applyFromArray($styleArrayFirstRow);
  1573.         }
  1574.         //$sheet->getStyle('A')->getFont()->setBold(true);
  1575.         $sheet->getColumnDimension('A')->setWidth(36);
  1576.         $sheet->getDefaultColumnDimension()->setWidth(30);
  1577.         $sheet->freezePaneByColumnAndRow(21);
  1578.         $styleArrayFirstRow = [
  1579.             'font' => [
  1580.                 'bold' => true,
  1581.                 'color' => array('rgb' => 'FFFFFF'),
  1582.             ]
  1583.         ];
  1584.         $sheet
  1585.             ->getStyle($titles[0])
  1586.             ->getFill()
  1587.             ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  1588.             ->getStartColor()
  1589.             ->setARGB($colorARGB);
  1590.         $sheet->getStyle($titles[0])->applyFromArray($styleArrayFirstRow);
  1591.         $sheet
  1592.             ->getStyle($titles[1])
  1593.             ->getFill()
  1594.             ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  1595.             ->getStartColor()
  1596.             ->setARGB($colorARGB);
  1597.         $sheet->getStyle($titles[1])->applyFromArray($styleArrayFirstRow);
  1598.         $sheet
  1599.             ->getStyle($titles[2])
  1600.             ->getFill()
  1601.             ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  1602.             ->getStartColor()
  1603.             ->setARGB($colorARGB);
  1604.         $sheet->getStyle($titles[2])->applyFromArray($styleArrayFirstRow);
  1605.         $sheet
  1606.             ->getStyle($titles[3])
  1607.             ->getFill()
  1608.             ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  1609.             ->getStartColor()
  1610.             ->setARGB($colorARGB);
  1611.         $sheet->getStyle($titles[3])->applyFromArray($styleArrayFirstRow);
  1612.         if(!$isSupplier){
  1613.             $sheet
  1614.                 ->getStyle($titles[4])
  1615.                 ->getFill()
  1616.                 ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  1617.                 ->getStartColor()
  1618.                 ->setARGB($colorARGB);
  1619.             $sheet->getStyle($titles[4])->applyFromArray($styleArrayFirstRow);
  1620.         }
  1621.         $sheet
  1622.             ->getStyle($titles[5])
  1623.             ->getFill()
  1624.             ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
  1625.             ->getStartColor()
  1626.             ->setARGB($colorARGB);
  1627.         $sheet->getStyle($titles[5])->applyFromArray($styleArrayFirstRow);
  1628.         $arrayParts $partRepository->generateExport($admin$library$part);
  1629.         $column 2;
  1630.         $row 2;
  1631.         //dd($arrayParts);
  1632.         foreach ($arrayParts as $mypPart) {
  1633.             //Autor
  1634.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[42]);
  1635.             //Fecha creación
  1636.             $sheet->setCellValueByColumnAndRow($column$row++, ( $mypPart[73] ? $mypPart[73]->format('d-m-y H:i') : '' ));
  1637.             //Fecha modificación
  1638.             $sheet->setCellValueByColumnAndRow($column$row++, ( $mypPart[73] ? $mypPart[74]->format('d-m-y H:i') : '' ));
  1639.             //Nombre Pieza
  1640.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[3]);
  1641.             //Referencia
  1642.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[1]);
  1643.             if(!$isSupplier){
  1644.                 //Description
  1645.                 $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[4]);
  1646.                 //Nombre de Cliente
  1647.                 $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[7]);
  1648.                 //Referencia Pieza Cliente
  1649.                 $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[8]);
  1650.                 //Part Number
  1651.                 $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[2]);
  1652.                 //Serial Number
  1653.                 $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[9]);
  1654.             }
  1655.             //Observaciones (Notes?)
  1656.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[12]);
  1657.             $row++;
  1658.             $row++;
  1659.             //Proveedor
  1660.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[43]);
  1661.             //Tecnologia
  1662.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[13]);
  1663.             //Equipo
  1664.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[44]);
  1665.             //Material
  1666.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[5]);
  1667.             //Modo impresión
  1668.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[75]);
  1669.             //Altura Capa
  1670.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[45] > $mypPart[45] : '-') . ' ' . ($mypPart[76] > '[+/-'.$mypPart[76].']' ''));
  1671.             //Diam boquilla
  1672.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[46] > $mypPart[46] : '-') . ' ' . ($mypPart[77] > '[+/-'.$mypPart[77].']' ''));
  1673.             //Tmp extrusor
  1674.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[47] > $mypPart[47] : '-') . ' ' . ($mypPart[78] > '[+/-'.$mypPart[78].']' ''));
  1675.             //Tmp cama
  1676.             $sheet->setCellValueByColumnAndRow($column$row++,($mypPart[48] > $mypPart[48] : '-') . ' ' . ($mypPart[79] > '[+/-'.$mypPart[79].']' ''));
  1677.             //Tmp camara
  1678.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[49] > $mypPart[49] : '-') . ' ' . ($mypPart[80] > '[+/-'.$mypPart[80].']' ''));
  1679.             //Veloc Impresion
  1680.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[50] > $mypPart[50] : '-') . ' ' . ($mypPart[81] > '[+/-'.$mypPart[81].']' ''));
  1681.             //Perim y relleno
  1682.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[51]);
  1683.             //Soportes
  1684.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[52]);
  1685.             //Punto laser
  1686.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[54] > $mypPart[54] : '-') . ' ' . ($mypPart[83] > '[+/-'.$mypPart[83].']' ''));
  1687.             //Pot fuente
  1688.             $sheet->setCellValueByColumnAndRow($column$row++,  ($mypPart[55] > $mypPart[55] : '-') . ' ' . ($mypPart[84] > '[+/-'.$mypPart[84].']' ''));
  1689.             //Tam pixel
  1690.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[56] > $mypPart[56] : '-') . ' ' . ($mypPart[85] > '[+/-'.$mypPart[85].']' ''));
  1691.             //Tpo Expos
  1692.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[57] > $mypPart[57] : '-') . ' ' . ($mypPart[86] > '[+/-'.$mypPart[86].']' ''));
  1693.             //Dist HAtch
  1694.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[58] > $mypPart[58] : '-') . ' ' . ($mypPart[87] > '[+/-'.$mypPart[87].']' ''));
  1695.             //Vel recoaster
  1696.             $sheet->setCellValueByColumnAndRow($column$row++, ($mypPart[59] > $mypPart[59] : '-') . ' ' . ($mypPart[82] > '[+/-'.$mypPart[82].']' ''));
  1697.             //Enfriam
  1698.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[60]);
  1699.             //Atmosf
  1700.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[61]);
  1701.             //Saturac
  1702.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[62]);
  1703.             //Obs Fab
  1704.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[53]);
  1705.             $row++;
  1706.             $row++;
  1707.             //Composición materia prima
  1708.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[14]);
  1709.             //Certificación materia prima
  1710.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[15]);
  1711.             //Color materia prima
  1712.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[16]);
  1713.             //Certificación proceso
  1714.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[17]);
  1715.             //Certificación pieza
  1716.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[18]);
  1717.             //Normativa aplicable
  1718.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[19]);
  1719.             //Proceso acabado
  1720.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[20]);
  1721.             //Otros tratamientos
  1722.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[21]);
  1723.             //Observaciones
  1724.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[22]);
  1725.             $row++;
  1726.             $row++;
  1727.             //Archivo CAD (.step, otros)
  1728.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[63]);
  1729.             //Archivo STL
  1730.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[64]);
  1731.             //Archivo Fabricación (.gcode, .pdf, otros)
  1732.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[66]);
  1733.             //Archivo Verificación (.txt, .pdf, .doc)
  1734.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[67]);
  1735.             //Planos 2D (.pdf)
  1736.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[65]);
  1737.             //Archivo N01
  1738.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[68]);
  1739.             //Archivo N02
  1740.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[69]);
  1741.             //Archivo N03
  1742.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[70]);
  1743.             //Archivo N04
  1744.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[71]);
  1745.             //Archivo N05
  1746.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[72]);
  1747.             if(!$isSupplier){
  1748.                 $row++;
  1749.                 $row++;
  1750.                 //Bibliotecas
  1751.                 $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[88]);
  1752.             }
  1753.             $row++;
  1754.             $row++;
  1755.             //STL DATA
  1756.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[89]);
  1757.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[90]);
  1758.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[91]);
  1759.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[92]);
  1760.             $sheet->setCellValueByColumnAndRow($column$row++, $mypPart[93]);
  1761.             $row 2;
  1762.             $column++;
  1763.         }
  1764.         return $spreadsheet;
  1765.     }
  1766.     /**
  1767.      * @Route({"en": "/prototype_ready/{id}",
  1768.      *         "es": "/prototipo_listo/{id}"}, name="prototipe_ready", methods={"GET", "POST"})
  1769.      */
  1770.     public function prototypeReady(Part $part)
  1771.     {
  1772.         $em $this->em;
  1773.         $part->setPrototypeStatus(Part::UNDER_VALIDATION);
  1774.         $em->persist($part);
  1775.         $orderId $part->getPrototypeOrder();
  1776.         $order $em->getRepository(Order::class)->findOneBy(array('id' => $orderId));
  1777.         $order->setState(4);
  1778.         $order->setPart($part);
  1779.         $em->persist($order);
  1780.         $em->flush();
  1781.         $successMsg "Prototipo enviado al cliente correctamente";
  1782.         $this->addFlash('success'$this->translator->trans($successMsg));
  1783.         $data['message']='Nuevo prototipo creado';
  1784.         $data['name']=$part->getName();
  1785.         $data['reference']=$part->getRef();
  1786.         $data['path_name']='part_show';
  1787.         $data['path_parameters']='id:'.$part->getId();
  1788.         $this->util->notifications($part->getCompany(), 2$data$this->getUser());
  1789.         if($part->getType() == 2){
  1790.             $this->util->notifications($order->getCompany(), 3$data$order->getUser(), $order->getId());
  1791.         }
  1792.         return $this->redirectToRoute('order_index');
  1793.     }
  1794. }