src/MDS/AvexpressBundle/Controller/ProductsFilesController.php line 1828

Open in your IDE?
  1. <?php
  2. namespace App\MDS\AvexpressBundle\Controller;
  3. use App\Entity\Cities;
  4. use App\Entity\Client;
  5. use App\Entity\Configuration;
  6. use App\Entity\Country;
  7. use App\Entity\Destination;
  8. use App\Entity\Regions;
  9. use App\Entity\SettingsCompany;
  10. use App\Entity\Supplier;
  11. use App\Entity\User;
  12. use App\MDS\AvexpressBundle\Entity\AveDocInvoiceItems;
  13. use App\MDS\AvexpressBundle\Entity\AveDocProforma;
  14. use App\MDS\AvexpressBundle\Entity\AveDocProformaItems;
  15. use App\MDS\AvexpressBundle\Entity\AveFiles;
  16. use App\MDS\AvexpressBundle\Entity\AvePackageTemplate;
  17. use App\MDS\AvexpressBundle\Entity\AvePackageTemplateItems;
  18. use App\MDS\AvexpressBundle\Entity\AveProduct;
  19. use App\MDS\AvexpressBundle\Entity\AveProductFileLocationNames;
  20. use App\MDS\AvexpressBundle\Repository\AveProductFileLocationNamesRepository;
  21. use App\MDS\AvexpressBundle\Service\AvexpressCalculatorService;
  22. use App\Service\AvePackageDeployService;
  23. use DateTime;
  24. use App\Service\GlobalService;
  25. use Doctrine\ORM\EntityManagerInterface;
  26. use Symfony\Component\Routing\Annotation\Route;
  27. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use App\MDS\AvexpressBundle\Entity\AveProductFile;
  30. use App\MDS\AvexpressBundle\Entity\AveTemplate;
  31. use App\MDS\AvexpressBundle\Entity\AveTemplateItems;
  32. use App\MDS\DevelupBundle\Entity\MdvTelegramUser;
  33. use App\MDS\EventsBundle\Entity\Proposal;
  34. use App\MDS\EventsBundle\Entity\ProposalAgents;
  35. use App\MDS\EventsBundle\Entity\ProposalInvoice;
  36. use App\MDS\EventsBundle\Entity\ProposalSupplierControl;
  37. use App\MDS\EventsBundle\Entity\ProposalSupplierServices;
  38. use App\MDS\VenuesBundle\Entity\ReservationInvoice;
  39. use Swift_Mailer;
  40. use Swift_Message;
  41. use Swift_SmtpTransport;
  42. use Symfony\Contracts\Translation\TranslatorInterface;
  43. class ProductsFilesController extends AbstractController
  44. {
  45.     private $translator;
  46.     public function __construct(TranslatorInterface $translatorAvePackageDeployService $avePackageDeployServiceGlobalService $globalService) {
  47.         $this->translator $translator;
  48.         $this->avePackageDeployService $avePackageDeployService;
  49.         $this->globalService $globalService;
  50.     }
  51.     private $avePackageDeployService;
  52.     private $globalService;
  53.     
  54.     /**
  55.      * @Route("/productfileadd/",  name="ave_add_productfile")
  56.      * Agregar un producto a un expediente
  57.      */
  58.     public function addProductFileActionRequest $requestAvexpressCalculatorService $calculator)
  59.     {
  60.         $em $this->getDoctrine()->getManager();
  61.         $clients $em->getRepository(Client::class)->findAll();
  62.         $newRequest $request->request->get('productfile');
  63.         $editFile $em->getRepository(AveFiles::class)->findOneById($newRequest['fileId']);
  64.         $mdvProductSelected $em->getRepository(AveProduct::class)->findOneById($newRequest['productId']);
  65.         $logTelegram false;
  66.         /* Obtengo usuario logueado */
  67.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  68.         $user_id $user_logueado->getId();
  69.         $newProductFile = new AveProductFile();
  70.         $newProductFile->setProductName($mdvProductSelected->getName());
  71.         $newProductFile->setProductId($mdvProductSelected->getId());
  72.         $newProductFile->setType($mdvProductSelected->getType());
  73.         if (!empty($newRequest['servicePrice'])){
  74.             $newProductFile->setServicePrice($newRequest['servicePrice']);
  75.         } else {
  76.             // Si el precio viene vacio tomamos el valor por defecto del producto
  77.             $newProductFile->setServicePrice($mdvProductSelected->getPrice());
  78.         }
  79.         $newProductFile->setDescription($mdvProductSelected->getDescription());
  80.         $newProductFile->setFileId($newRequest['fileId']);
  81.         if (!empty($newRequest['dateStart'])) { $newProductFile->setDateStart(new \DateTime($newRequest['dateStart'].' '.$newRequest['hourStart'])); }
  82.         if (!empty($newRequest['dateEnd'])) { $newProductFile->setDateEnd(new \DateTime($newRequest['dateStart'].' '.$newRequest['hourEnd'])); }
  83.         $dataDates $this->obtenerFechas($newRequest['fileId'], $newProductFile->getDateStart(), $newProductFile->getDateEnd());
  84.         $newProductFile->setDateStart($dataDates['dateStart']);
  85.         $newProductFile->setDateEnd($dataDates['dateEnd']);
  86.         $newProductFile->setDateInAt($dataDates['dateStart']);
  87.         $newProductFile->setDateOutAt($dataDates['dateEnd']);
  88.         $newProductFile->setCreatedId($user_id);
  89.         $newProductFile->setUpdatedId($user_id);
  90.         $newProductFile->setCreatedAt(new \DateTime("now"));
  91.         $newProductFile->setUpdatedAt(new \DateTime("now"));
  92.         $newProductFile->setOpIva(true);
  93.         $newProductFile->setIva('21');
  94.         if (!empty($newRequest['supplierExt'])){
  95.             $supplier $em->getRepository(Supplier::class)->findOneById($newRequest['supplierExt']);
  96.             $newProductFile->setSupplierExt($supplier->getName());
  97.             $newProductFile->setSupplierExtId($newRequest['supplierExt']);
  98.         } else {
  99.             $newProductFile->setSupplierExt(null);
  100.             $newProductFile->setSupplierExtId(null);
  101.         }
  102.         if (empty($newProductFile->getType())){ $newProductFile->setType('Otros'); }
  103.         $dataRankQuoteAv $this->obtenerRankQuoteAv($newRequest['fileId']);
  104.         $newProductFile->setRankQuoteAv($dataRankQuoteAv);
  105.         $newProductFile->setDays((($newProductFile->getDateEnd()->diff($newProductFile->getDateStart()))->days 1));
  106.         $em->persist($newProductFile);
  107.         $em->flush();
  108.         $products $em->getRepository(AveProduct::class)->findAll();
  109.         $data $calculator->calculateFileTotals((int)$newRequest['fileId']);
  110.         $sumatoriaTotalNet 0;
  111.         $sumatoriaTotalVat 0;
  112.         $sumatoriaTotal 0;
  113.         $resultados = array(
  114.             'totalNeto' => $sumatoriaTotalNet,
  115.             'vat' => $sumatoriaTotalVat,
  116.             'total' => $sumatoriaTotal,
  117.         );
  118.         $productInFile $em->getRepository(AveProductFile::class)->findByFileId($newRequest['fileId']);
  119.         $numeroItems sizeof($productInFile);
  120.         $file $editFile;
  121.         // Si hay proposal se debe actualizar en el expediente de Eventos
  122.         if (!empty($file->getIdProposal()) and is_numeric($file->getIdProposal())){
  123.             // Buscamos el destino donde se encuentre Avexpress y ahi agregamos el servicio, si no se encuentra no se agregara el servicio
  124.             $control $em->getRepository(ProposalSupplierControl::class)->findOneBy(
  125.                 array(
  126.                     'supplierId' => 80,                                          // El supplier 80 es Avexpress
  127.                     'proposalId' => $file->getIdProposal(),
  128.                 )
  129.             );
  130.             if (!empty($control)){
  131.                 // Existe un destino con Avexpress como proveedor, hay se agregara el servicio
  132.                 $prpInv $em->getRepository(ProposalInvoice::class)->findOneByProposalId($file->getIdProposal());
  133.                 if (empty($prpInv)) { //Si hay factura en InOut no se debe modificar
  134.                     $logTelegram true;
  135.                     $service = new ProposalSupplierServices();
  136.                     $service->setServiceIdFather(0);
  137.                     $service->setControlId($control->getId());
  138.                     $service->setProposalId($file->getIdProposal());
  139.                     $service->setDestinationId($control->getDestinoId());
  140.                     $service->setSupplierId(80);
  141.                     $service->setIdeaId(null);
  142.                     $service->setServiceId($newProductFile->getProductId());
  143.                     $service->setServiceCatName('Av');
  144.                     $service->setServiceCatId(3);
  145.                     $service->setName($newProductFile->getProductName());
  146. //                $service->setPrice($mdvProductSelected->getPrice() * 1.21);
  147.                     $priceInOut $mdvProductSelected->getSubTotalPrice() / $mdvProductSelected->getPax();      // Se devuelve el calculo dividiendo entre personas
  148.                     $priceInOut $priceInOut $mdvProductSelected->getUnits();                                // Se devuelve el calculo dividiendo entre cantidades
  149.                     $priceInOut $priceInOut round($mdvProductSelected->getDays());                          // Se devuelve el calculo dividiendo entre dias, se redondea por si es 1.5
  150.                     // Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP),
  151.                     $priceInOut round($priceInOut2PHP_ROUND_HALF_UP);
  152.                     $service->setPrice($priceInOut);
  153. //                $service->setPrice($mdvProductSelected->getPrice());
  154.                     $service->setCurrency(null);
  155.                     $service->setUnits(1);
  156.                     $service->setCommission(0);
  157.                     $service->setOver(0);
  158.                     $service->setIva(21);
  159.                     $service->setPax(0);
  160.                     $service->setHour(null);
  161.                     $service->setDateInAt(new \DateTime("now"));
  162.                     $service->setDateOutAt(new \DateTime("now"));
  163.                     $service->setDirectPayment(0);
  164.                     $service->setStatus('Pending');
  165.                     $service->setStatusinternal('Additional');
  166.                     $service->setPreCommission(null);
  167.                     $service->setPreIva(null);
  168.                     $service->setDateBlockLimit(null);
  169.                     $service->setOpCommission(1);
  170.                     $service->setOpOver(1);
  171.                     $service->setOpIva(1);
  172.                     $service->setBreakdown(0);
  173.                     $service->setIsFather(0);
  174.                     $service->setRankQuote(1);
  175.                     $service->setOriginalopIva(1);
  176.                     $service->setOriginalIva(null);
  177.                     $service->setOriginalPrice(null);
  178.                     $service->setStatusRec('normal');
  179.                     $service->setAssistantId(null);
  180.                     $service->setCreatedId($user_id);
  181.                     $service->setUpdatedId($user_id);
  182.                     $service->setCreatedAt(new \DateTime("now"));
  183.                     $service->setUpdatedAt(new \DateTime("now"));
  184.                     $em->persist($service);
  185.                     $em->flush();
  186.                     // Guardamos el ID del servicio (Eventos) asociado al producto (AvExpress)
  187.                     $newProductFile->setOriginId($service->getId());
  188.                     $em->persist($newProductFile);
  189.                     $em->flush();
  190.                 }
  191.             }
  192.         }
  193.         //INICIO: Notificamos al agente por Telegram
  194.         if ($logTelegram){
  195.             //Buscamos todos los agentes del proposal
  196.             $proposalAgents $em->getRepository(ProposalAgents::class)->findOneByIdProp($file->getIdProposal());
  197.             //Buscamos el Destino
  198.             $proposalDestino $em->getRepository(Destination::class)->findOneById($control->getDestinoId());
  199.             //Buscamos el agente de AvExpress
  200.             $userData $em->getRepository(User::class)->findOneById($user_id);
  201.             if (!empty($proposalAgents) and !($user_id == 22)){
  202.                 if ((!empty($proposalAgents->getAgOne())) and (!($proposalAgents->getAgOne() == 0))){
  203.                     $this->sendTelegram($proposalAgents->getAgOne(),'1. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (Nuevo Servicio) __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  204.                 }
  205.                 if ((!empty($proposalAgents->getAgTwo())) and (!($proposalAgents->getAgTwo() == 0))){
  206.                     $this->sendTelegram($proposalAgents->getAgTwo(),'2. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (Nuevo Servicio) __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  207.                 }
  208.                 if ((!empty($proposalAgents->getAgThree())) and (!($proposalAgents->getAgThree() == 0))){
  209.                     $this->sendTelegram($proposalAgents->getAgThree(),'3. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (Nuevo Servicio) __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  210.                 }
  211.                 if ((!empty($proposalAgents->getAgFour())) and (!($proposalAgents->getAgFour() == 0))){
  212.                     $this->sendTelegram($proposalAgents->getAgFour(),'4. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (Nuevo Servicio) __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  213.                 }
  214.             }
  215.         }
  216.         //FIN: Notificamos al agente por Telegram
  217.         return $this->render('MDS/AvexpressBundle/Avexpress/edit-files.html.twig',
  218.             array(
  219.                 'id' => $newRequest['fileId'],
  220.                 'clients' => $clients,
  221.                 'clientId' => $editFile->getClient(),
  222.                 'file' => $editFile,
  223.                 'products' => $products,
  224.                 'numeroItems' => $numeroItems,
  225.                 'arrayProductFile' => $data['datasupplier']['product'],
  226.                 'services' => null,
  227.                 'facturas' => null,
  228.                 'paymentNotIvoiced' => null,
  229.                 'paymentsAll' => null,
  230.                 'resultados' => $resultados,
  231.                 'totales_global_con_iva' => $data['totales'], //$data['totales_global_con_iva'],
  232.                 'totales_global_iva' => $data['bases_imponibles']['ivaMontoVeintiUno'], //$data['totales_global_iva'],
  233.                 'totales_global_neto' => $data['totales_neto'], //$data['totales_global_neto'],
  234.                 'totales_global_servicios_con_iva' => 0//$data['totales_global_servicios_con_iva'],
  235.                 'totales_global_servicios_neto' => 0//$data['totales_global_servicios_neto'],
  236.                 'totales_global_servicios_iva' => 0//$data['totales_global_servicios_iva'],
  237.                 'sumatoria_totales_global_con_iva' => 0//$data['sumatoria_totales_global_con_iva'],
  238.                 'sumatoria_totales_global_neto' => 0//$data['sumatoria_totales_global_neto'],
  239.                 'sumatoria_totales_global_iva' => 0//$data['sumatoria_totales_global_iva'],
  240.             ));
  241.     }
  242.     /**
  243.      * @Route("/productfiledelete/{id}",  name="ave_delete_productfile")
  244.      * Eliminar un producto de un expediente
  245.      */
  246.     public function deleteProductFileAction($idRequest $request)
  247.     {
  248.         $em $this->getDoctrine()->getManager();
  249.         $mdvProductSelected $em->getRepository(AveProductFile::class)->findOneById($id);
  250.         $id $mdvProductSelected->getFileId();
  251.         $logTelegram false;
  252.         /* Obtengo usuario logueado */
  253.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  254.         $user_id $user_logueado->getId();
  255.         //INICIO: Si hay un ID origin se debe eliminar en Eventos
  256.         if (!empty($mdvProductSelected->getOriginId())){
  257.             $logTelegram true;
  258.             $delete $em->getRepository(ProposalSupplierServices::class)->findOneById($mdvProductSelected->getOriginId());
  259.             if (!empty($delete)) {
  260.                 $destinationId $delete->getDestinationId();
  261.                 $proposalId $delete->getProposalId();
  262.                 $prpInv $em->getRepository(ProposalInvoice::class)->findOneByProposalId($delete->getProposalId());
  263.                 if (empty($prpInv)) { //Si hay factura en InOut no se debe modificar
  264.                     if (!empty($delete)) {
  265.                         $delete_sub $em->getRepository(ProposalSupplierServices::class)->findByServiceIdFather($delete->getId());
  266.                         foreach ($delete_sub as $deletesub) {
  267.                             $em->remove($deletesub);
  268.                         }
  269.                         $em->remove($delete);
  270.                         $em->flush();
  271.                     }
  272.                 }
  273.             } else {
  274.                 // El servicio origen no se encontro
  275.                 $logTelegram false;
  276.             }
  277.         }
  278.         //INICIO: Notificamos al agente por Telegram
  279.         if ($logTelegram){
  280.             //Buscamos todos los agentes del proposal
  281.             $proposalAgents $em->getRepository(ProposalAgents::class)->findOneByIdProp($proposalId);
  282.             //Buscamos el Destino
  283.             $proposalDestino $em->getRepository(Destination::class)->findOneById($destinationId);
  284.             //Buscamos el agente de Develup
  285.             $userData $em->getRepository(User::class)->findOneById($user_id);
  286.             if (!empty($proposalAgents)){
  287.                 if ((!empty($proposalAgents->getAgOne())) and (!($proposalAgents->getAgOne() == 0))){
  288.                     $this->sendTelegram($proposalAgents->getAgOne(),'1. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  289.                 }
  290.                 if ((!empty($proposalAgents->getAgTwo())) and (!($proposalAgents->getAgTwo() == 0))){
  291.                     $this->sendTelegram($proposalAgents->getAgTwo(),'2. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  292.                 }
  293.                 if ((!empty($proposalAgents->getAgThree())) and (!($proposalAgents->getAgThree() == 0))){
  294.                     $this->sendTelegram($proposalAgents->getAgThree(),'3. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  295.                 }
  296.                 if ((!empty($proposalAgents->getAgFour())) and (!($proposalAgents->getAgFour() == 0))){
  297.                     $this->sendTelegram($proposalAgents->getAgFour(),'4. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  298.                 }
  299.             }
  300.         }
  301.         //FIN: Notificamos al agente por Telegram
  302.         //FIN: Si hay un ID origin se debe eliminar en Eventos
  303.         //INICIO: Si el producto se encuentra dentro de una proforma (Ave_Doc_Proforma_Items) se elimina tambiĆ©n
  304.         $productInProforma $em->getRepository(AveDocProformaItems::class)->findByControlId($mdvProductSelected->getId());
  305.         if (!empty($productInProforma)){
  306.             foreach ($productInProforma as $item){
  307.                 $item->setFileId((-1) * $item->getFileId());      // No lo vamos a eliminar, apuntarĆ” al fileId en negativo
  308.                 $em->persist($item);
  309.                 // $em->remove($item);
  310.                 $em->flush();
  311.             }
  312.         }
  313.         //FIN: Si el producto se encuentra dentro de una proforma (Ave_Doc_Proforma_Items) se elimina tambiĆ©n
  314.         $mdvProductSelected->setFileId((-1) * $mdvProductSelected->getFileId());      // No lo vamos a eliminar, apuntarĆ” al fileId en negativo
  315.         $em->persist($mdvProductSelected);
  316.         // $em->remove($mdvProductSelected);
  317.         $em->flush();
  318.         return $this->redirectToRoute('ave_edit_file', array('id' => $id));
  319.     }
  320.     /**
  321.      * @Route("/productfileproformadelete/{id}",  name="ave_delete_productfileproforma")
  322.      * Eliminar un producto de una proforma
  323.      */
  324.     public function deleteProductFileInProformaAction($idRequest $request)
  325.     {
  326.         $em $this->getDoctrine()->getManager();
  327.         $mdvProductSelected $em->getRepository(AveDocProformaItems::class)->findOneByControlId($id);
  328.         $id $mdvProductSelected->getFileId();
  329.         $em->remove($mdvProductSelected);
  330.         $em->flush();
  331.         return $this->redirectToRoute('ave_edit_file', array('id' => $id));
  332.     }
  333.     /**
  334.      * @Route("/updateproductfilegrid/",  name="ave_updategrid_productfile")
  335.      * Actualizar grid de productos de un expediente
  336.      */
  337.     public function updategridProductFileAction(Request $request)
  338.     {
  339.         $em $this->getDoctrine()->getManager();
  340.         $newRequest $request->request->get('product');
  341.         $fileId $request->request->get('fileId');
  342.         $logTelegram false;
  343.         $srvInconsistentes '';                    // Mensaje de alerta por inconsistencia en los servicios
  344.         $txtOfChanges '';
  345.         /* Obtengo usuario logueado */
  346.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  347.         $user_id $user_logueado->getId();
  348.         foreach ($newRequest as $key => $item) {
  349.             $txtWarning '';
  350.             if (!empty($item['name'])){
  351.                 if (is_numeric($item['price'])){
  352.                     $logTelegram true;
  353.                     $productInFile $em->getRepository(AveProductFile::class)->findOneById($key);
  354.                     if ($productInFile->getType() =='Paquete'){
  355.                         // Se llama la funcion que procesa la actualizacion de los paquetes
  356.                         if(!array_key_exists('location'$item)){ $item['location'] = null; }
  357.                         $data $this->avePackageDeployService->updatePackage$key$item['price'], $item['units'], $item['days'], $item['location']);
  358.                     } else {
  359.                         $productInFile->setProductName($item['name']);
  360.                         $productInFile->setServicePrice($item['price']);
  361.                         $productInFile->setUnits($item['units']);
  362.                         $productInFile->setDays($item['days']);
  363.                         $productInFile->setSubTotalPrice($item['price'] * $item['units'] * $item['days']);
  364.                         // *** Primero se debe calcular la comision y luego el over ***
  365.                         // Calculo de comision
  366.                         if ($productInFile->getOpCommission()) {
  367.                             //Over positivo
  368.                             if (!($productInFile->getCommission() == 0) and is_numeric($productInFile->getCommission())) {
  369.                                 $suma $productInFile->getCommission() / 100;
  370.                                 $suma $productInFile->getSubTotalPrice() * $suma;
  371.                                 $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() + $suma);
  372.                             }
  373.                         } else {
  374.                             //Over negativo
  375.                             if (!($productInFile->getCommission() == 0) and is_numeric($productInFile->getCommission())) {
  376.                                 $suma $productInFile->getCommission() / 100;
  377.                                 $suma $productInFile->getSubTotalPrice() * $suma;
  378.                                 if ($productInFile->getSubTotalPrice() > $suma) {            // La comision a restar no puede ser mayor que el precio total
  379.                                     $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() - $suma);
  380.                                 }
  381.                             }
  382.                         }
  383.                         // Calculo con OVER
  384.                         if ($productInFile->getOpOver()) {
  385.                             //Over positivo
  386.                             if (!($productInFile->getOver() == 0) and is_numeric($productInFile->getOver())) {
  387.                                 $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() + $productInFile->getOver());
  388.                             }
  389.                         } else {
  390.                             //Over negativo
  391.                             if (!($productInFile->getOver() == 0) and is_numeric($productInFile->getOver())) {
  392.                                 $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() + ((-1) * $productInFile->getOver()));
  393.                             }
  394.                         }
  395.                         // IVA
  396. //                    $productInFile->setDescription($item['description']);
  397.                         $productInFile->setUpdatedId($user_id);
  398.                         $productInFile->setUpdatedAt(new \DateTime("now"));
  399.                         //Si las fechas de inicio y fin no coinciden con el campo dias se debe enviar alerta
  400.                         $txtWarning = ($productInFile->getDateOutAt()->diff($productInFile->getDateInAt()))->days <> $productInFile->getDays() ? '<br>' $productInFile->getProductName() : '';
  401.                         if (!empty($txtWarning)) {
  402.                             if (empty($srvInconsistentes)) {
  403.                                 $srvInconsistentes 'Hay inconsistencias en: ' '<br>' $txtWarning;
  404.                             } else {
  405.                                 $srvInconsistentes $srvInconsistentes '<br>' $txtWarning;
  406.                             }
  407.                         }
  408.                     }
  409.                     $em->persist($productInFile);
  410.                     $em->flush();
  411.                     //INICIO: Duplicamos en Eventos
  412.                     $proposalId 0;
  413.                     if (!empty($productInFile->getOriginId())) {
  414.                         $serviceEvent $em->getRepository(ProposalSupplierServices::class)->findOneById($productInFile->getOriginId());
  415.                         $oldServiceEvent = array(
  416.                             'activityId' => $serviceEvent->getActivityId(),
  417.                             'assistantId' => $serviceEvent->getAssistantId(),
  418.                             'breakdown' => $serviceEvent->getBreakdown(),
  419.                             'commission' => $serviceEvent->getCommission(),
  420.                             'controlId' => $serviceEvent->getControlId(),
  421.                             'currency' => $serviceEvent->getCurrency(),
  422.                             'dateBlockLimit' => $serviceEvent->getDateBlockLimit(),
  423.                             'dateInAt' => $serviceEvent->getDateInAt(),
  424.                             'dateOutAt' => $serviceEvent->getDateOutAt(),
  425.                             'destinationId' => $serviceEvent->getDestinationId(),
  426.                             'directPayment' => $serviceEvent->getDirectPayment(),
  427.                             'hour' => $serviceEvent->getHour(),
  428.                             'ideaId' => $serviceEvent->getIdeaId(),
  429.                             'isFather' => $serviceEvent->getIsFather(),
  430.                             'iva' => $serviceEvent->getIva(),
  431.                             'name' => $serviceEvent->getName(),
  432.                             'opCommission' => $serviceEvent->getOpCommission(),
  433.                             'opIva' => $serviceEvent->getOpIva(),
  434.                             'opOver' => $serviceEvent->getOpOver(),
  435.                             'originalIva' => $serviceEvent->getOriginalIva(),
  436.                             'originalPrice' => $serviceEvent->getOriginalPrice(),
  437.                             'originalopIva' => $serviceEvent->getOriginalopIva(),
  438.                             'over' => $serviceEvent->getOver(),
  439.                             'pax' => $serviceEvent->getPax(),
  440.                             'preCommission' => $serviceEvent->getPreCommission(),
  441.                             'preIva' => $serviceEvent->getPreIva(),
  442.                             'price' => $serviceEvent->getPrice(),
  443.                             'proposalId' => $serviceEvent->getProposalId(),
  444.                             'rankquote' => $serviceEvent->getRankQuote(),
  445.                             'serviceCatId' => $serviceEvent->getServiceCatId(),
  446.                             'serviceCatName' => $serviceEvent->getServiceCatName(),
  447.                             'serviceId' => $serviceEvent->getServiceId(),
  448.                             'serviceIdFather' => $serviceEvent->getServiceIdFather(),
  449.                             'status' => $serviceEvent->getStatus(),
  450.                             'statusRec' => $serviceEvent->getStatusRec(),
  451.                             'statusinternal' => $serviceEvent->getStatusinternal(),
  452.                             'supplierId' => $serviceEvent->getSupplierId(),
  453.                             'units' => $serviceEvent->getUnits(),
  454.                         );
  455.                         if (!empty($serviceEvent)) {
  456.                             $proposalId $serviceEvent->getProposalId();
  457.                             $prpInv $em->getRepository(ProposalInvoice::class)->findOneByProposalId($serviceEvent->getProposalId());
  458.                             if (empty($prpInv)) { //Si hay factura en InOut no se debe modificar
  459. //                            $serviceEvent->setUnits(1);                             // Las unidades no se pueden replicar o se genera un sobre calculo del lado de Evenetos
  460.                                 $serviceEvent->setName($productInFile->getProductName());
  461.                                 $priceInOut $productInFile->getSubTotalPrice();
  462.                                 if (!($productInFile->getPax() == 0)) {
  463.                                     $priceInOut $priceInOut $productInFile->getPax();                    // Se devuelve el calculo dividiendo entre personas
  464.                                 }
  465.                                 if (!($productInFile->getUnits() == 0)) {
  466.                                     $priceInOut $priceInOut $productInFile->getUnits();                  // Se devuelve el calculo dividiendo entre cantidades
  467.                                 }
  468.                                 if (!($productInFile->getDays() == 0)) {
  469.                                     $priceInOut $priceInOut round($productInFile->getDays());            // Se devuelve el calculo dividiendo entre dias, se redondea por si es 1.5
  470.                                 }
  471.                                 // Se lleva a 2 decimales round($totales_neto_antes,2,PHP_ROUND_HALF_UP),
  472.                                 $priceInOut round($priceInOut2PHP_ROUND_HALF_UP);
  473.                                 $serviceEvent->setPrice($priceInOut);
  474.                                 // Se verifican los precios en ambas partes (AV Express e InOut)
  475.                                 if (!($serviceEvent->getPrice() == $productInFile->getServicePrice())) {
  476.                                     // Si ambos precios unitarios son distintos se ha modificado el numero de dĆ­as en Av Express
  477.                                     $newPriceInOut $this->precioPorVariacionDeDias($serviceEvent$productInFile);
  478.                                     $serviceEvent->setPrice($newPriceInOut);
  479.                                 } else {
  480.                                     // si son iguales tambien se deben verificar el numero de dias
  481.                                     if (!(($serviceEvent->getDateOutAt()->diff($serviceEvent->getDateInAt())->days 1) == $productInFile->getDays())) {
  482.                                         $newPriceInOut $this->precioPorVariacionDeDias($serviceEvent$productInFile);
  483.                                         $serviceEvent->setPrice($newPriceInOut);
  484.                                     }
  485.                                 }
  486.                                 $serviceEvent->setCurrency($productInFile->getCurrency());
  487.                                 $serviceEvent->setUnits($productInFile->getUnits());
  488. //                            $serviceEvent->setIva(21);
  489.                                 if (empty($productInFile->getPax())) {
  490.                                     $serviceEvent->setPax(1);
  491.                                 } else {
  492.                                     $serviceEvent->setPax($productInFile->getPax());
  493.                                 }
  494.                                 $serviceEvent->setDateInAt($productInFile->getDateInAt());
  495.                                 $serviceEvent->setDateOutAt($productInFile->getDateOutAt());
  496.                                 //Verificamos cambios e informamos al agente del proposal
  497.                                 $boolChanges false;
  498.                                 if (!($serviceEvent->getRankQuote() == $oldServiceEvent['rankquote'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Orden</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['rankquote'].', su nuevo valor es: '.$serviceEvent->getRankQuote().'<br>'$boolChanges true; }
  499.                                 if (!($serviceEvent->getName() == $oldServiceEvent['name'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Nombre</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['name'].', su nuevo valor es: '.$serviceEvent->getName().'<br>'$boolChanges true; }
  500.                                 if (!($serviceEvent->getPrice() == $oldServiceEvent['price'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Precio</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['price'].', su nuevo valor es: '.$serviceEvent->getPrice().'<br>'$boolChanges true; }
  501.                                 if (!($serviceEvent->getCurrency() == $oldServiceEvent['currency'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Moneda</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['currency'].', su nuevo valor es: '.$serviceEvent->getCurrency().'<br>'$boolChanges true; }
  502.                                 if (!($serviceEvent->getUnits() == $oldServiceEvent['units'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Cantidad</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['units'].', su nuevo valor es: '.$serviceEvent->getUnits().'<br>'$boolChanges true; }
  503.                                 if (!($serviceEvent->getPax() == $oldServiceEvent['pax'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Personas</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['pax'].', su nuevo valor es: '.$serviceEvent->getPax().'<br>'$boolChanges true; }
  504.                                 if (!($serviceEvent->getOpOver() == $oldServiceEvent['opOver'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Opción (-/+) del Over</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['opOver'].', su nuevo valor es: '.$serviceEvent->getOpOver().'<br>'$boolChanges true; }
  505.                                 if (!($serviceEvent->getOver() == $oldServiceEvent['over'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Over</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['over'].', su nuevo valor es: '.$serviceEvent->getOver().'<br>'$boolChanges true; }
  506.                                 if (!($serviceEvent->getOpCommission() == $oldServiceEvent['opCommission'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Opción (-/+) de la Comisión</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['opCommission'].', su nuevo valor es: '.$serviceEvent->getOpCommission().'<br>'$boolChanges true; }
  507.                                 if (!($serviceEvent->getCommission() == $oldServiceEvent['commission'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Comisión" ha sido modificado. Su valor era: '.$oldServiceEvent['commission'].', su nuevo valor es: '.$serviceEvent->getCommission().'<br>'$boolChanges true; }
  508.                                 if (!($serviceEvent->getOpIva() == $oldServiceEvent['opIva'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Opción (-/+) del Iva</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['opIva'].', su nuevo valor es: '.$serviceEvent->getOpIva().'<br>'$boolChanges true; }
  509.                                 if (!($serviceEvent->getIva() == $oldServiceEvent['iva'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Iva</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['iva'].', su nuevo valor es: '.$serviceEvent->getIva().'<br>'$boolChanges true; }
  510.                                 if (!($serviceEvent->getDateInAt()->format('H:i') == $oldServiceEvent['dateInAt']->format('H:i'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Hora inicio</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateInAt']->format('H:i').', su nuevo valor es: '.$serviceEvent->getDateInAt()->format('H:i').'<br>'$boolChanges true; }
  511.                                 if (!($serviceEvent->getDateInAt()->format('Ymd') == $oldServiceEvent['dateInAt']->format('Ymd'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Fecha inicio</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateInAt']->format('d/m/Y').', su nuevo valor es: '.$serviceEvent->getDateInAt()->format('d/m/Y').'<br>'$boolChanges true; }
  512.                                 if (!($serviceEvent->getDateOutAt()->format('H:i') == $oldServiceEvent['dateOutAt']->format('H:i'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Hora fin</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateOutAt']->format('H:i').', su nuevo valor es: '.$serviceEvent->getDateOutAt()->format('H:i').'<br>'$boolChanges true; }
  513.                                 if (!($serviceEvent->getDateOutAt()->format('Ymd') == $oldServiceEvent['dateOutAt']->format('Ymd'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Fecha fin</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateOutAt']->format('d/m/Y').', su nuevo valor es: '.$serviceEvent->getDateOutAt()->format('d/m/Y').'<br>'$boolChanges true; }
  514.                                 $em->persist($serviceEvent);
  515.                                 $em->flush();
  516.                             }
  517.                         }
  518.                     }
  519.                     //FIN: Duplicamos en Eventos
  520.                 }
  521.             }
  522.         }
  523.         // Notificamos al agente de InOut si se hicieron actualizaciones en los servicios desde AvExpress
  524.         if (!empty($txtOfChanges)) { $this->messageOfChangesToAgent($txtOfChanges$proposalId); }
  525.         $file $em->getRepository(AveFiles::class)->findOneById($fileId);
  526.         $event 'Servicios guardados correctamente.';
  527.         $successMessage $this->translator->trans($event);
  528.         $this->addFlash('mensajeav'$successMessage);
  529.         if (!empty($srvInconsistentes) and !empty($file->getIdProposal())){ $this->addFlash('mensajeaverror'$srvInconsistentes); }
  530.         // Si el proposalId esta vacio no se notifica a nadie por Telegram
  531.         if (empty($file->getIdProposal())){$logTelegram false;}
  532.         //INICIO: Notificamos al agente por Telegram
  533.         if ($logTelegram){
  534.             //Buscamos todos los agentes del proposal
  535.             $proposalAgents $em->getRepository(ProposalAgents::class)->findOneByIdProp($file->getIdProposal());
  536.             //Buscamos el Destino
  537. //            $proposalDestino = $em->getRepository(Destination::class)->findOneById($control->getDestinoId());
  538.             //Buscamos el agente de AVEXPRESS
  539.             $userData $em->getRepository(User::class)->findOneById($user_id);
  540.             if (!empty($proposalAgents) and !($user_id == 22)){
  541.                 if ((!empty($proposalAgents->getAgOne())) and (!($proposalAgents->getAgOne() == 0))){
  542.                     $this->sendTelegram($proposalAgents->getAgOne(),'1. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  543.                 }
  544.                 if ((!empty($proposalAgents->getAgTwo())) and (!($proposalAgents->getAgTwo() == 0))){
  545.                     $this->sendTelegram($proposalAgents->getAgTwo(),'2. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  546.                 }
  547.                 if ((!empty($proposalAgents->getAgThree())) and (!($proposalAgents->getAgThree() == 0))){
  548.                     $this->sendTelegram($proposalAgents->getAgThree(),'3. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  549.                 }
  550.                 if ((!empty($proposalAgents->getAgFour())) and (!($proposalAgents->getAgFour() == 0))){
  551.                     $this->sendTelegram($proposalAgents->getAgFour(),'4. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  552.                 }
  553.             }
  554.         }
  555.         //FIN: Notificamos al agente por Telegram
  556.         return $this->redirectToRoute('ave_edit_file', array('id' => $fileId));
  557.     }
  558.     /**
  559.      * @Route("/updateproductfilegridtwo/",  name="ave_update_productfile_grid_two")
  560.      * Editar todos los producto de un expediente con todos sus campos
  561.      */
  562.     public function updateProductFileGridTwoAction(Request $request){
  563.         $em $this->getDoctrine()->getManager();
  564.         $newRequest $request->request->get('services');
  565.         $fileId $request->request->get('fileId');
  566.         $logTelegram false;
  567.         $srvInconsistentes '';                    // Mensaje de alerta por inconsistencia en los servicios
  568.         /* Obtengo usuario logueado */
  569.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  570.         $user_id $user_logueado->getId();
  571.         $txtOfChanges ''$boolNotifyOfChanges false$proposalId 0;
  572.         foreach ($newRequest as $item) {
  573.             $productInFile $em->getRepository(AveProductFile::class)->findOneById($item['productFileId']);
  574.             $logTelegram true;
  575.             $txtWarning '';
  576.             $configItems = (str_contains($productInFile->getProductName(), '€')) ? 0;
  577.             $isPack = ($productInFile->getType() == 'Paquete');
  578.             if ($isPack and ($configItems == 1)){
  579.                 // Se llama la funcion que procesa la actualizacion de los paquetes
  580.                 $data $this->avePackageDeployService->updatePackage$productInFile->getId(), $item['price'], $item['units'], $item['days'],$item['location']);
  581.             } else {
  582.                 $productInFile->setProductName($item['name']);
  583.                 $productInFile->setServicePrice($item['price']);
  584. //            $productInFile->setDescription($item['description']);
  585.                 $productInFile->setCurrency($item['currency']);
  586.                 $productInFile->setUnits(empty($item['units']) ? $item['units']);
  587.                 $productInFile->setType(empty($item['prdType']) ? 'Otros' $item['prdType']);
  588.                 $productInFile->setLocation(empty($item['location']) ? null $item['location']);
  589.                 $itemLoc = empty($item['location']) ? null $item['location'];
  590.                 $idGpLounge $em->getRepository(AveProductFileLocationNames::class)->findOneByName($itemLoc);
  591.                 $idGpLounge = empty($idGpLounge) ? null $idGpLounge->getIdGpLounge();
  592.                 $productInFile->setIdGpLounge($idGpLounge);
  593.                 $productInFile->setRankQuoteAv(empty($item['rankquoteAV']) ? intval($item['rankquoteAV']));
  594.                 if (array_key_exists('dateInAt'$item)) {
  595.                     $productInFile->setDateStart(new \DateTime($item['dateInAt']));
  596.                     $productInFile->setDateInAt(new \DateTime($item['dateInAt']));
  597.                 } else {
  598.                     // No se requiere accion
  599.                 }
  600.                 if (array_key_exists('dateOutAt'$item)) {
  601.                     $productInFile->setDateEnd(new \DateTime($item['dateOutAt']));
  602.                     $productInFile->setDateOutAt(new \DateTime($item['dateOutAt']));
  603.                 } else {
  604.                     // No se requiere accion
  605.                 }
  606.                 if (empty($item['days'])) {
  607. //                $productInFile->setDays($days = (((new \DateTime($item['dateOutAt']))->diff(new \DateTime($item['dateInAt'])))->days + 1));
  608.                     $productInFile->setDays($days = (($productInFile->getDateOutAt()->diff($productInFile->getDateInAt()))->days 1));
  609.                 } else {
  610.                     $productInFile->setDays($item['days']);
  611.                 }
  612.                 $productInFile->setPax(empty($item['pax']) ? $item['pax']);
  613.                 $productInFile->setOpCommission($item['opCommission']);
  614.                 $productInFile->setCommission($item['commission']);
  615.                 $productInFile->setOpOver($item['opOver']);
  616.                 $productInFile->setOver($item['over']);
  617.                 $productInFile->setOpIva($item['opIva']);
  618.                 $productInFile->setIva($item['iva']);
  619.                 if (!empty($item['supplierExt'])) {
  620.                     $supplier $em->getRepository(Supplier::class)->findOneById($item['supplierExt']);
  621.                     $productInFile->setSupplierExt($supplier->getName());
  622.                     $productInFile->setSupplierExtId($item['supplierExt']);
  623.                 } else {
  624.                     $productInFile->setSupplierExt(null);
  625.                     $productInFile->setSupplierExtId(null);
  626.                 }
  627.                 $productInFile->setHourStart(substr($item['start'], 02));
  628.                 $productInFile->setMinStart(substr($item['start'], 32));
  629.                 $productInFile->setHourEnd(empty($item['end']) ? '00' substr($item['end'], 02));
  630.                 $productInFile->setMinEnd(empty($item['end']) ? '00' substr($item['end'], 32));
  631.                 $productInFile->setUpdatedId($user_id);
  632.                 $productInFile->setUpdatedAt(new \DateTime("now"));
  633.                 $productInFile->setSubTotalPrice($productInFile->getServicePrice());
  634.                 //INICIO: Validaciones para el sub total
  635.                 if (is_numeric($productInFile->getUnits())) {
  636.                     $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() * $productInFile->getUnits());
  637.                 }
  638.                 if (is_numeric($productInFile->getPax())) {
  639.                     $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() * $productInFile->getPax());
  640.                 }
  641.                 $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() * $productInFile->getDays());
  642.                 // *** Primero se debe calcular la comision y luego el over ***
  643.                 // Calculo de comision
  644.                 if ($productInFile->getOpCommission()) {
  645.                     //Over positivo
  646.                     if (!($productInFile->getCommission() == 0) and is_numeric($productInFile->getCommission())) {
  647.                         $suma $productInFile->getCommission() / 100;
  648.                         $suma $productInFile->getSubTotalPrice() * $suma;
  649.                         $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() + $suma);
  650.                     }
  651.                 } else {
  652.                     //Over negativo
  653.                     if (!($productInFile->getCommission() == 0) and is_numeric($productInFile->getCommission())) {
  654.                         $suma $productInFile->getCommission() / 100;
  655.                         $suma $productInFile->getSubTotalPrice() * $suma;
  656.                         if ($productInFile->getSubTotalPrice() > $suma) {            // La comision a restar no puede ser mayor que el precio total
  657.                             $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() - $suma);
  658.                         }
  659.                     }
  660.                 }
  661.                 // Calculo con OVER
  662.                 if ($productInFile->getOpOver()) {
  663.                     //Over positivo
  664.                     if (!($productInFile->getOver() == 0) and is_numeric($productInFile->getOver())) {
  665.                         $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() + $productInFile->getOver());
  666.                     }
  667.                 } else {
  668.                     //Over negativo
  669.                     if (!($productInFile->getOver() == 0) and is_numeric($productInFile->getOver())) {
  670.                         $productInFile->setSubTotalPrice($productInFile->getSubTotalPrice() + ((-1) * $productInFile->getOver()));
  671.                     }
  672.                 }
  673.                 // IVA
  674.                 //FIN: Validaciones para el sub total
  675.             }
  676.             //Si las fechas de inicio y fin no coinciden con el campo dias se debe enviar alerta
  677.             $txtWarning = ($productInFile->getDateOutAt()->diff($productInFile->getDateInAt()))->days <> $productInFile->getDays() ? '<br>'.$productInFile->getProductName() : '';
  678.             if (!empty($txtWarning)){
  679.                 if (empty($srvInconsistentes)){ $srvInconsistentes 'Hay inconsistencias en: '.'<br>'.$txtWarning; } else { $srvInconsistentes $srvInconsistentes.'<br>'.$txtWarning; }
  680.             }
  681.             $em->persist($productInFile);
  682.             $em->flush();
  683.             $em->clear();
  684.             //INICIO: Duplicamos en Eventos (SINCRONIZACION)
  685.             if (!empty($productInFile->getOriginId())){
  686.                 $serviceEvent $em->getRepository(ProposalSupplierServices::class)->findOneById($productInFile->getOriginId());
  687.                 $proposalId $serviceEvent->getProposalId();
  688.                 $oldServiceEvent = array(
  689.                     'activityId' => $serviceEvent->getActivityId(),
  690.                     'assistantId' => $serviceEvent->getAssistantId(),
  691.                     'breakdown' => $serviceEvent->getBreakdown(),
  692.                     'commission' => $serviceEvent->getCommission(),
  693.                     'controlId' => $serviceEvent->getControlId(),
  694.                     'currency' => $serviceEvent->getCurrency(),
  695.                     'dateBlockLimit' => $serviceEvent->getDateBlockLimit(),
  696.                     'dateInAt' => $serviceEvent->getDateInAt(),
  697.                     'dateOutAt' => $serviceEvent->getDateOutAt(),
  698.                     'destinationId' => $serviceEvent->getDestinationId(),
  699.                     'directPayment' => $serviceEvent->getDirectPayment(),
  700.                     'hour' => $serviceEvent->getHour(),
  701.                     'ideaId' => $serviceEvent->getIdeaId(),
  702.                     'isFather' => $serviceEvent->getIsFather(),
  703.                     'iva' => $serviceEvent->getIva(),
  704.                     'name' => $serviceEvent->getName(),
  705.                     'opCommission' => $serviceEvent->getOpCommission(),
  706.                     'opIva' => $serviceEvent->getOpIva(),
  707.                     'opOver' => $serviceEvent->getOpOver(),
  708.                     'originalIva' => $serviceEvent->getOriginalIva(),
  709.                     'originalPrice' => $serviceEvent->getOriginalPrice(),
  710.                     'originalopIva' => $serviceEvent->getOriginalopIva(),
  711.                     'over' => $serviceEvent->getOver(),
  712.                     'pax' => $serviceEvent->getPax(),
  713.                     'preCommission' => $serviceEvent->getPreCommission(),
  714.                     'preIva' => $serviceEvent->getPreIva(),
  715.                     'price' => $serviceEvent->getPrice(),
  716.                     'proposalId' => $serviceEvent->getProposalId(),
  717.                     'rankquote' => $serviceEvent->getRankQuote(),
  718.                     'serviceCatId' => $serviceEvent->getServiceCatId(),
  719.                     'serviceCatName' => $serviceEvent->getServiceCatName(),
  720.                     'serviceId' => $serviceEvent->getServiceId(),
  721.                     'serviceIdFather' => $serviceEvent->getServiceIdFather(),
  722.                     'status' => $serviceEvent->getStatus(),
  723.                     'statusRec' => $serviceEvent->getStatusRec(),
  724.                     'statusinternal' => $serviceEvent->getStatusinternal(),
  725.                     'supplierId' => $serviceEvent->getSupplierId(),
  726.                     'units' => $serviceEvent->getUnits(),
  727.                 );
  728.                 if (!empty($serviceEvent)) {
  729.                     $prpInv $em->getRepository(ProposalInvoice::class)->findOneByProposalId($serviceEvent->getProposalId());
  730.                     if (empty($prpInv)) { //Si hay factura en InOut no se debe modificar
  731.                         $serviceEvent->setName($productInFile->getProductName());
  732.                         // Se verifican los precios en ambas partes (AV Express e InOut)
  733.                         if (!($serviceEvent->getPrice() == $productInFile->getServicePrice())) {
  734.                             // Si ambos precios unitarios son distintos se ha modificado el numero de dĆ­as en Av Express
  735.                             $newPriceInOut $this->precioPorVariacionDeDias($serviceEvent$productInFile);
  736.                             $serviceEvent->setPrice($newPriceInOut);
  737.                         } else {
  738.                             // si son iguales tambien se deben verificar el numero de dias
  739.                             if (!(($serviceEvent->getDateOutAt()->diff($serviceEvent->getDateInAt())->days 1) == $productInFile->getDays())) {
  740.                                 $newPriceInOut $this->precioPorVariacionDeDias($serviceEvent$item);
  741.                                 $serviceEvent->setPrice($newPriceInOut);
  742.                             }
  743.                         }
  744.                         $serviceEvent->setCurrency($productInFile->getCurrency());
  745.                         $serviceEvent->setUnits($productInFile->getUnits());
  746.                         if (empty($productInFile->getPax())) {
  747.                             $serviceEvent->setPax(1);
  748.                         } else {
  749.                             $serviceEvent->setPax($productInFile->getPax());
  750.                         }
  751.                         $serviceEvent->setDateInAt($productInFile->getDateInAt());
  752.                         $serviceEvent->setDateOutAt($productInFile->getDateOutAt());
  753.                         // Se verifican los precios en ambas partes (AV Express e InOut)
  754.                         if (!($serviceEvent->getPrice() == $productInFile->getServicePrice())) {
  755.                             // Si ambos precios unitarios son distintos se ha modificado el numero de dĆ­as en Av Express
  756.                             $newPriceInOut $this->precioPorVariacionDeDias($serviceEvent$productInFile);
  757.                             $serviceEvent->setPrice($newPriceInOut);
  758.                         } else {
  759.                             // si son iguales tambien se deben verificar el numero de dias
  760.                             if (!(($serviceEvent->getDateOutAt()->diff($serviceEvent->getDateInAt())->days 1) == $productInFile->getDays())) {
  761.                                 $newPriceInOut $this->precioPorVariacionDeDias($serviceEvent$productInFile);
  762.                                 $serviceEvent->setPrice($newPriceInOut);
  763.                             }
  764.                         }
  765.                         //Verificamos cambios e informamos al agente del proposal
  766.                         $boolChanges false;
  767.                         if (!($serviceEvent->getRankQuote() == $oldServiceEvent['rankquote'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Orden</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['rankquote'].', su nuevo valor es: '.$serviceEvent->getRankQuote().'<br>'$boolChanges true; }
  768.                         if (!($serviceEvent->getName() == $oldServiceEvent['name'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Nombre</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['name'].', su nuevo valor es: '.$serviceEvent->getName().'<br>'$boolChanges true; }
  769.                         if (!($serviceEvent->getPrice() == $oldServiceEvent['price'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Precio</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['price'].', su nuevo valor es: '.$serviceEvent->getPrice().'<br>'$boolChanges true; }
  770.                         if (!($serviceEvent->getCurrency() == $oldServiceEvent['currency'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Moneda</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['currency'].', su nuevo valor es: '.$serviceEvent->getCurrency().'<br>'$boolChanges true; }
  771.                         if (!($serviceEvent->getUnits() == $oldServiceEvent['units'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Cantidad</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['units'].', su nuevo valor es: '.$serviceEvent->getUnits().'<br>'$boolChanges true; }
  772.                         if (!($serviceEvent->getPax() == $oldServiceEvent['pax'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Personas</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['pax'].', su nuevo valor es: '.$serviceEvent->getPax().'<br>'$boolChanges true; }
  773.                         if (!($serviceEvent->getOpOver() == $oldServiceEvent['opOver'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Opción (-/+) del Over</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['opOver'].', su nuevo valor es: '.$serviceEvent->getOpOver().'<br>'$boolChanges true; }
  774.                         if (!($serviceEvent->getOver() == $oldServiceEvent['over'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Over</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['over'].', su nuevo valor es: '.$serviceEvent->getOver().'<br>'$boolChanges true; }
  775.                         if (!($serviceEvent->getOpCommission() == $oldServiceEvent['opCommission'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Opción (-/+) de la Comisión</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['opCommission'].', su nuevo valor es: '.$serviceEvent->getOpCommission().'<br>'$boolChanges true; }
  776.                         if (!($serviceEvent->getCommission() == $oldServiceEvent['commission'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Comisión" ha sido modificado. Su valor era: '.$oldServiceEvent['commission'].', su nuevo valor es: '.$serviceEvent->getCommission().'<br>'$boolChanges true; }
  777.                         if (!($serviceEvent->getOpIva() == $oldServiceEvent['opIva'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Opción (-/+) del Iva</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['opIva'].', su nuevo valor es: '.$serviceEvent->getOpIva().'<br>'$boolChanges true; }
  778.                         if (!($serviceEvent->getIva() == $oldServiceEvent['iva'])){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Iva</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['iva'].', su nuevo valor es: '.$serviceEvent->getIva().'<br>'$boolChanges true; }
  779.                         if (!($serviceEvent->getDateInAt()->format('H:i') == $oldServiceEvent['dateInAt']->format('H:i'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Hora inicio</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateInAt']->format('H:i').', su nuevo valor es: '.$serviceEvent->getDateInAt()->format('H:i').'<br>'$boolChanges true; }
  780.                         if (!($serviceEvent->getDateInAt()->format('Ymd') == $oldServiceEvent['dateInAt']->format('Ymd'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Fecha inicio</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateInAt']->format('d/m/Y').', su nuevo valor es: '.$serviceEvent->getDateInAt()->format('d/m/Y').'<br>'$boolChanges true; }
  781.                         if (!($serviceEvent->getDateOutAt()->format('H:i') == $oldServiceEvent['dateOutAt']->format('H:i'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Hora fin</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateOutAt']->format('H:i').', su nuevo valor es: '.$serviceEvent->getDateOutAt()->format('H:i').'<br>'$boolChanges true; }
  782.                         if (!($serviceEvent->getDateOutAt()->format('Ymd') == $oldServiceEvent['dateOutAt']->format('Ymd'))){ if (!$boolChanges){ $txtOfChanges =  $txtOfChanges.'<br><br>En el servicio: '.$serviceEvent->getName().'<br>'; } $txtOfChanges $txtOfChanges '<br><br>El campo "<strong>Fecha fin</strong>" ha sido modificado. Su valor era: '.$oldServiceEvent['dateOutAt']->format('d/m/Y').', su nuevo valor es: '.$serviceEvent->getDateOutAt()->format('d/m/Y').'<br>'$boolChanges true; }
  783.                         $em->persist($serviceEvent);
  784.                         $em->flush();
  785.                         $em->clear();
  786.                     }
  787.                 }
  788.             }
  789.             //FIN: Duplicamos en Eventos
  790.         }
  791.         // Notificamos al agente de InOut si se hicieron actualizaciones en los servicios desde AvExpress
  792.         if (!empty($txtOfChanges)) { $this->messageOfChangesToAgent($txtOfChanges$proposalId); }
  793.         $file $em->getRepository(AveFiles::class)->findOneById($fileId);
  794.         $event 'Servicios guardados correctamente.';
  795.         $successMessage $this->translator->trans($event);
  796.         $this->addFlash('mensajeav'$successMessage);
  797.         if (!empty($srvInconsistentes) and !empty($file->getIdProposal())){ $this->addFlash('mensajeaverror'$srvInconsistentes); }
  798.         // Si el proposalId esta vacio no se notifica a nadie por Telegram
  799.         if (empty($file->getIdProposal())){$logTelegram false;}
  800.         //INICIO: Notificamos al agente por Telegram
  801.         if ($logTelegram){
  802.             //Buscamos todos los agentes del proposal
  803.             $proposalAgents $em->getRepository(ProposalAgents::class)->findOneByIdProp($file->getIdProposal());
  804.             //Buscamos el Destino
  805. //            $proposalDestino = $em->getRepository(Destination::class)->findOneById($control->getDestinoId());
  806.             //Buscamos el agente de Develup
  807.             $userData $em->getRepository(User::class)->findOneById($user_id);
  808.             if (!empty($proposalAgents) and !($user_id == 22)){
  809.                 if ((!empty($proposalAgents->getAgOne())) and (!($proposalAgents->getAgOne() == 0))){
  810.                     $this->sendTelegram($proposalAgents->getAgOne(),'1. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID2) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  811.                 }
  812.                 if ((!empty($proposalAgents->getAgTwo())) and (!($proposalAgents->getAgTwo() == 0))){
  813.                     $this->sendTelegram($proposalAgents->getAgTwo(),'2. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID2) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  814.                 }
  815.                 if ((!empty($proposalAgents->getAgThree())) and (!($proposalAgents->getAgThree() == 0))){
  816.                     $this->sendTelegram($proposalAgents->getAgThree(),'3. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID2) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  817.                 }
  818.                 if ((!empty($proposalAgents->getAgFour())) and (!($proposalAgents->getAgFour() == 0))){
  819.                     $this->sendTelegram($proposalAgents->getAgFour(),'4. PROPOSAL ACTUALIZADO DESDE AVEXPRESS (GRID2) __ ID: '.$file->getIdProposal().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  820.                 }
  821.             }
  822.         }
  823.         //FIN: Notificamos al agente por Telegram
  824.         return $this->redirectToRoute('ave_edit_file', array('id' => $fileId));
  825.     }
  826.     /**
  827.      * @Route("/productfilelistmultiple/{id}",  name="ave_list_multiple_productfile")
  828.      * Listar multiples productos para agregar en el expediente id
  829.      */
  830.     public function listMultipleProductFileAction$idRequest $request){
  831.         $em $this->getDoctrine()->getManager();
  832. //        $avs = $em->getRepository(AveProduct::class)->findAll();
  833.         // Listamos por orden alfabetico y se deja de primero a "Otro servicio"
  834.         $parameters = array();
  835.         $dql 'SELECT i
  836.                     FROM AvexpressBundle:AveProduct i
  837.                     ORDER BY i.name ASC';
  838.         $query $em->createQuery($dql)->setParameters($parameters);
  839.         $avs $query->getResult();
  840.         $newAvs = array();
  841.         foreach ($avs as $key => $item) {
  842.             if ($item->getName() == 'Otro servicio'){
  843.                 $item->setName('0 - Otro servicio');
  844.                 $newAvs = array($item);
  845.                 unset($avs[$key]);
  846.                 foreach ($avs as $keyTwo => $elem){
  847.                     $ind $keyTwo 1;
  848.                     $elem->setName($ind.' - '.$elem->getName());
  849.                     array_push($newAvs,$elem);
  850.                 }
  851.             }
  852.         }
  853.         $avs $newAvs;
  854.         /* av Description*/
  855.         $data_av = array();
  856.         foreach($avs as $av){
  857.             $data_av[] = array(
  858.                 'id' => $av->getId(),
  859.                 'name' => $av->getName(),
  860.                 'modules' => null,
  861.                 'type' => $av->getType(),
  862.                 'currency' => 'Euro',
  863.                 'price' => $av->getPrice(),
  864.                 'commission' => 0,
  865.                 'iva' => 21,
  866.                 'controlId' => 0,
  867.                 'description' => null
  868.             );
  869.         }
  870.         // Buscamos las plantilas precargadas
  871.         $parameters = array();
  872.         $dql 'SELECT i
  873.                     FROM AvexpressBundle:AveTemplate i
  874.                     ORDER BY i.name ASC';
  875.         $query $em->createQuery($dql)->setParameters($parameters);
  876.         $aveTemplates $query->getResult();
  877.         // Buscamos los paquetes
  878.         $dql 'SELECT i
  879.                 FROM AvexpressBundle:AvePackageTemplate i
  880.                 ORDER BY i.name ASC';
  881.         $query $em->createQuery($dql)->setParameters($parameters);
  882.         $avePackageTemplates $query->getResult();
  883.         // Buscamos las proformas
  884.         $proformas $em->getRepository(AveDocProforma::class)->findByFileId($id);
  885.         return $this->render('MDS/AvexpressBundle/Avexpress/add-services.html.twig',
  886.             array(
  887.                 'id' => $id,
  888.                 'avs' => $data_av,
  889.                 'newAvs' => $newAvs,
  890.                 'aveTemplates' => $aveTemplates,
  891.                 'proformas' => $proformas,
  892.                 'avePackageTemplates' => $avePackageTemplates,
  893.                 'technology' => null,
  894.             ));
  895.     }
  896.     /**
  897.      * @Route("/productfilemultipleadd/",  name="ave_add_multiple_productfile")
  898.      * Agregar multiples productos a un expediente
  899.      */
  900.     public function addMultipleProductFileActionEntityManagerInterface $em,  Request $request){
  901.         $logTelegram false;
  902.         $fileId $request->request->get('fileId');
  903.         $products $request->request->get('av');
  904.         $template $request->request->get('avexpress');
  905.         $template $template['template'];
  906.         $srvDestination $request->request->get('srvDestination');
  907.         $package $request->request->get('avexpress');
  908.         $packageId $package['package'];
  909.         $packageConfig $request->request->get('avexpress');
  910.         $packageConfig = (array_key_exists('packageConfig',$packageConfig)) ? ;   // 0 precio global, 1 precio detallado
  911.         /* Obtengo usuario logueado */
  912.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  913.         $user_id $user_logueado->getId();
  914. //        $em = $this->getDoctrine()->getManager();
  915.         $file $em->getRepository(AveFiles::class)->findOneById($fileId);
  916.         $template $em->getRepository(AveTemplate::class)->findOneById($template);
  917.         $package $em->getRepository(AvePackageTemplate::class)->findOneById($packageId);
  918.         // Buscamos los elementos del paquete seleccionado
  919.         $packageItems = [];
  920.         if(!empty($package)){
  921.             $data $this->avePackageDeployService->collapsePackage$packageId$fileId$packageConfig );
  922.         }
  923.         if(!empty($products)) {
  924.             foreach ($products as $item) {
  925.                 $mdvProductSelected $em->getRepository(AveProduct::class)->findOneById($item);
  926.                 $newProductFile = new AveProductFile();
  927.                 $newProductFile->setProductName($mdvProductSelected->getName());
  928.                 $newProductFile->setProductId($mdvProductSelected->getId());
  929.                 $newProductFile->setServicePrice($mdvProductSelected->getPrice());
  930.                 $newProductFile->setDescription($mdvProductSelected->getDescription());
  931.                 $newProductFile->setType($mdvProductSelected->getType());
  932.                 $newProductFile->setFileId($fileId);
  933.                 $newProductFile->setUnits('1');
  934.                 $newProductFile->setOpIva(true);
  935.                 $newProductFile->setIva('21');
  936.                 $newProductFile->setSupplierExt($mdvProductSelected->getSupplierExt());
  937.                 $newProductFile->setSupplierExtId($mdvProductSelected->getSupplierExtId());
  938.                 $dataDates $this->obtenerFechas($newProductFile->getFileId(), $newProductFile->getDateStart(), $newProductFile->getDateEnd());
  939.                 $newProductFile->setDateStart($dataDates['dateStart']);
  940.                 $newProductFile->setDateEnd($dataDates['dateEnd']);
  941.                 $newProductFile->setDateInAt($dataDates['dateStart']);
  942.                 $newProductFile->setDateOutAt($dataDates['dateEnd']);
  943.                 $dataRankQuoteAv $this->obtenerRankQuoteAv($fileId);
  944.                 $newProductFile->setRankQuoteAv($dataRankQuoteAv);
  945.                 $newProductFile->setCreatedId($user_id);
  946.                 $newProductFile->setUpdatedId($user_id);
  947.                 $newProductFile->setCreatedAt(new \DateTime("now"));
  948.                 $newProductFile->setUpdatedAt(new \DateTime("now"));
  949.                 if (empty($newProductFile->getType())){ $newProductFile->setType('Otros'); }
  950.                 $newProductFile->setDays((($newProductFile->getDateEnd()->diff($newProductFile->getDateStart()))->days 1));
  951.                 $newProductFile->setSubTotalPrice($newProductFile->getServicePrice() * $newProductFile->getDays());
  952.                 $em->persist($newProductFile);
  953.                 $em->flush();
  954.                 if (!($srvDestination == 0)){
  955.                     //Se debe agregar el producto a una proforma
  956.                     $this->addProductFileToProforma($fileId$newProductFile->getId(), $srvDestination);
  957.                 }
  958.                 // Si hay proposal se debe actualizar en el expediente de Eventos
  959.                 if (!empty($file->getIdProposal()) and is_numeric($file->getIdProposal())) {
  960.                     // Buscamos el destino donde se encuentre Av Express y ahi agregamos el servicio, si no se encuentra no se agregara el servicio
  961.                     $control $em->getRepository(ProposalSupplierControl::class)->findOneBy(
  962.                         array(
  963.                             'supplierId' => 80,                                          // El supplier 80 es AVEXPRESS
  964.                             'proposalId' => $file->getIdProposal(),
  965.                         )
  966.                     );
  967.                     if (!empty($control)) {
  968.                         // Existe un destino con Av Express como proveedor, hay se agregara el servicio
  969.                         $prpInv $em->getRepository(ProposalInvoice::class)->findOneByProposalId($file->getIdProposal());
  970.                         if (empty($prpInv)) { //Si hay factura en InOut no se debe modificar
  971.                             $logTelegram true;
  972.                             $service = new ProposalSupplierServices();
  973.                             $service->setServiceIdFather(0);
  974.                             $service->setControlId($control->getId());
  975.                             $service->setProposalId($file->getIdProposal());
  976.                             $service->setDestinationId($control->getDestinoId());
  977.                             $service->setSupplierId(80);
  978.                             $service->setIdeaId(null);
  979.                             $service->setServiceId($newProductFile->getProductId());
  980.                             $service->setServiceCatName('Av');
  981.                             $service->setServiceCatId(3);
  982.                             $service->setName($newProductFile->getProductName());
  983.                             $service->setPrice($newProductFile->getSubTotalPrice() / $newProductFile->getDays());
  984. //                        $priceInOut = $newProductFile->getSubTotalPrice() / $newProductFile->getPax();      // Se devuelve el calculo dividiendo entre personas
  985. //                        $priceInOut = $priceInOut / $newProductFile->getUnits();                            // Se devuelve el calculo dividiendo entre cantidades
  986. //                        $priceInOut = $priceInOut / round($newProductFile->getDays());                      // Se devuelve el calculo dividiendo entre dias, se redondea por si es 1.5
  987. //                        $service->setPrice($priceInOut);
  988.                             $service->setCurrency($newProductFile->getCurrency());
  989.                             $service->setUnits($newProductFile->getUnits());
  990.                             $service->setCommission(0);
  991.                             $service->setOver(0);
  992.                             $service->setIva(21);
  993.                             $service->setPax(1);
  994.                             $service->setHour(null);
  995.                             $service->setDateInAt($newProductFile->getDateInAt());
  996.                             $service->setDateOutAt($newProductFile->getDateOutAt());
  997.                             $service->setDirectPayment(0);
  998.                             $service->setStatus('Pending');
  999.                             $service->setStatusinternal('Additional');
  1000.                             $service->setPreCommission(null);
  1001.                             $service->setPreIva(null);
  1002.                             $service->setDateBlockLimit(null);
  1003.                             $service->setOpCommission(1);
  1004.                             $service->setOpOver(1);
  1005.                             $service->setOpIva(1);
  1006.                             $service->setBreakdown(0);
  1007.                             $service->setIsFather(0);
  1008.                             $service->setRankQuote(1);
  1009.                             $service->setOriginalopIva(1);
  1010.                             $service->setOriginalIva(null);
  1011.                             $service->setOriginalPrice(null);
  1012.                             $service->setStatusRec('normal');
  1013.                             $service->setAssistantId(null);
  1014.                             $service->setCreatedId($user_id);
  1015.                             $service->setUpdatedId($user_id);
  1016.                             $service->setCreatedAt(new \DateTime("now"));
  1017.                             $service->setUpdatedAt(new \DateTime("now"));
  1018.                             $em->persist($service);
  1019.                             $em->flush();
  1020.                             // Guardamos el ID del servicio (Eventos) asociado al producto (AvExpress)
  1021.                             $newProductFile->setOriginId($service->getId());
  1022.                             $em->persist($newProductFile);
  1023.                             $em->flush();
  1024.                         }
  1025.                     }
  1026.                 }
  1027.             }
  1028.         }
  1029.         // Buscamos los elementos de la plantilla seleccionada
  1030.         $templateItems = array();
  1031.         if(!empty($template)){
  1032.             $templateItems $em->getRepository(AveTemplateItems::class)->findByTemplateId($template);
  1033.         }
  1034.         foreach ($templateItems as $item){
  1035.             $newProductFile = new AveProductFile();
  1036.             $newProductFile->setProductName($item->getProductName());
  1037.             $newProductFile->setProductId($item->getProductId());
  1038.             $newProductFile->setServicePrice($item->getServicePrice());
  1039.             $newProductFile->setFileId($fileId);
  1040.             $newProductFile->setPax($item->getPax());
  1041.             $newProductFile->setType($item->getType());
  1042.             $newProductFile->setHourStart($item->getHourStart());
  1043.             $newProductFile->setMinStart($item->getMinStart());
  1044.             $newProductFile->setHourEnd($item->getHourEnd());
  1045.             $newProductFile->setMinEnd($item->getMinEnd());
  1046.             $newProductFile->setDescription($item->getDescription());
  1047.             $newProductFile->setSupplierExtId($item->getSupplierExtId());
  1048.             $newProductFile->setSupplierExt($item->getSupplierExt());
  1049.             $newProductFile->setServiceIdProposal($item->getServiceIdProposal());
  1050.             $newProductFile->setServiceIdFather($item->getServiceIdFather());
  1051.             $newProductFile->setControlId($item->getControlId());
  1052.             $newProductFile->setProposalId($item->getProposalId());
  1053.             $newProductFile->setDestinationId($item->getDestinationId());
  1054.             $newProductFile->setIdeaId($item->getIdeaId());
  1055.             $newProductFile->setActivityId($item->getActivityId());
  1056.             $newProductFile->setSupplierId($item->getSupplierId());
  1057.             $newProductFile->setAssistantId($item->getAssistantId());
  1058.             $newProductFile->setServiceId($item->getServiceId());
  1059.             $newProductFile->setServiceCatId($item->getServiceCatId());
  1060.             $newProductFile->setServiceCatName($item->getServiceCatName());
  1061.             $newProductFile->setName($item->getName());
  1062.             $newProductFile->setPrice($item->getPrice());
  1063.             $newProductFile->setCurrency($item->getCurrency());
  1064.             $newProductFile->setUnits($item->getUnits());
  1065.             $newProductFile->setOpCommission($item->getOpCommission());
  1066.             $newProductFile->setCommission($item->getCommission());
  1067.             $newProductFile->setOpOver($item->getOpOver());
  1068.             $newProductFile->setOver($item->getOver());
  1069.             $newProductFile->setOpIva($item->getOpIva());
  1070.             $newProductFile->setIva($item->getIva());
  1071.             $newProductFile->setHour($item->getHour());
  1072.             $dataDates $this->obtenerFechas($newProductFile->getFileId(), $newProductFile->getDateStart(), $newProductFile->getDateEnd());
  1073.             $newProductFile->setDateStart($dataDates['dateStart']);
  1074.             $newProductFile->setDateEnd($dataDates['dateEnd']);
  1075.             $newProductFile->setDateInAt($dataDates['dateStart']);
  1076.             $newProductFile->setDateOutAt($dataDates['dateEnd']);
  1077.             $newProductFile->setContcolor($item->getContcolor());
  1078.             $newProductFile->setRankQuote($item->getRankQuote());
  1079.             $dataRankQuoteAv $this->obtenerRankQuoteAv($fileId);
  1080.             $newProductFile->setRankQuoteAv($dataRankQuoteAv);
  1081.             $newProductFile->setRenovate($item->getRenovate());
  1082.             $newProductFile->setPay($item->getPay());
  1083.             $newProductFile->setDays($item->getDays());
  1084.             $newProductFile->setSubTotalPrice($item->getSubTotalPrice());
  1085.             $newProductFile->setCreatedId($user_id);
  1086.             $newProductFile->setUpdatedId($user_id);
  1087.             $newProductFile->setCreatedAt(new \DateTime("now"));
  1088.             $newProductFile->setUpdatedAt(new \DateTime("now"));
  1089.             if (empty($newProductFile->getType())){ $newProductFile->setType('Otros'); }
  1090.             $em->persist($newProductFile);
  1091.             $em->flush();
  1092.             if (!($srvDestination == 0)){
  1093.                 //Se debe agregar el producto a una proforma
  1094.                 $this->addProductFileToProforma($fileId$newProductFile->getId(), $srvDestination);
  1095.             }
  1096.             // Si hay proposal se debe actualizar en el expediente de Eventos
  1097.             if (!empty($file->getIdProposal()) and is_numeric($file->getIdProposal())){
  1098.                 // Buscamos el destino donde se encuentre Av Express y ahi agregamos el servicio, si no se encuentra no se agregara el servicio
  1099.                 $control $em->getRepository(ProposalSupplierControl::class)->findOneBy(
  1100.                     array(
  1101.                         'supplierId' => 80,                                          // El supplier 80 es AVEXPRESS
  1102.                         'proposalId' => $file->getIdProposal(),
  1103.                     )
  1104.                 );
  1105.                 if (!empty($control)){
  1106.                     // Existe un destino con Av Express como proveedor, hay se agregara el servicio
  1107.                     $prpInv $em->getRepository(ProposalInvoice::class)->findOneByProposalId($file->getIdProposal());
  1108.                     if (empty($prpInv)) { //Si hay factura en InOut no se debe modificar
  1109.                         $logTelegram true;
  1110.                         $service = new ProposalSupplierServices();
  1111.                         $service->setServiceIdFather(0);
  1112.                         $service->setControlId($control->getId());
  1113.                         $service->setProposalId($file->getIdProposal());
  1114.                         $service->setDestinationId($control->getDestinoId());
  1115.                         $service->setSupplierId(80);
  1116.                         $service->setIdeaId(null);
  1117.                         $service->setServiceId($newProductFile->getProductId());
  1118.                         $service->setServiceCatName('Av');
  1119.                         $service->setServiceCatId(3);
  1120.                         $service->setName($newProductFile->getProductName());
  1121.                         $service->setPrice($newProductFile->getSubTotalPrice());
  1122.                         $service->setCurrency(null);
  1123.                         $service->setUnits(1);
  1124.                         $service->setCommission(0);
  1125.                         $service->setOver(0);
  1126.                         $service->setIva(21);
  1127.                         $service->setPax(0);
  1128.                         $service->setHour(null);
  1129.                         $service->setDateInAt(new \DateTime("now"));
  1130.                         $service->setDateOutAt(new \DateTime("now"));
  1131.                         $service->setDirectPayment(0);
  1132.                         $service->setStatus('Pending');
  1133.                         $service->setStatusinternal('Additional');
  1134.                         $service->setPreCommission(null);
  1135.                         $service->setPreIva(null);
  1136.                         $service->setDateBlockLimit(null);
  1137.                         $service->setOpCommission(1);
  1138.                         $service->setOpOver(1);
  1139.                         $service->setOpIva(1);
  1140.                         $service->setBreakdown(0);
  1141.                         $service->setIsFather(0);
  1142.                         $service->setRankQuote(1);
  1143.                         $service->setOriginalopIva(1);
  1144.                         $service->setOriginalIva(null);
  1145.                         $service->setOriginalPrice(null);
  1146.                         $service->setStatusRec('normal');
  1147.                         $service->setAssistantId(null);
  1148.                         $service->setCreatedId($user_id);
  1149.                         $service->setUpdatedId($user_id);
  1150.                         $service->setCreatedAt(new \DateTime("now"));
  1151.                         $service->setUpdatedAt(new \DateTime("now"));
  1152.                         $em->persist($service);
  1153.                         $em->flush();
  1154.                         // Guardamos el ID del servicio (Eventos) asociado al producto (AvExpress)
  1155.                         $newProductFile->setOriginId($service->getId());
  1156.                         $em->persist($newProductFile);
  1157.                         $em->flush();
  1158.                     }
  1159.                 }
  1160.             }
  1161.         }
  1162.         //INICIO: Notificamos al agente por Telegram
  1163.         if ($logTelegram){
  1164.             //Buscamos todos los agentes del proposal
  1165.             $proposalAgents $em->getRepository(ProposalAgents::class)->findOneByIdProp($file->getIdProposal());
  1166.             //Buscamos el Destino
  1167.             $proposalDestino $em->getRepository(Destination::class)->findOneById($control->getDestinoId());
  1168.             //Buscamos el agente de AvExpress
  1169.             $userData $em->getRepository(User::class)->findOneById($user_id);
  1170.             if (!empty($proposalAgents) and !($user_id == 22)){
  1171.                 if ((!empty($proposalAgents->getAgOne())) and (!($proposalAgents->getAgOne() == 0))){
  1172.                     $this->sendTelegram($proposalAgents->getAgOne(),'1. PROPOSAL ACTUALIZADO DESDE AVEXPRESS __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1173.                 }
  1174.                 if ((!empty($proposalAgents->getAgTwo())) and (!($proposalAgents->getAgTwo() == 0))){
  1175.                     $this->sendTelegram($proposalAgents->getAgTwo(),'2. PROPOSAL ACTUALIZADO DESDE AVEXPRESS __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1176.                 }
  1177.                 if ((!empty($proposalAgents->getAgThree())) and (!($proposalAgents->getAgThree() == 0))){
  1178.                     $this->sendTelegram($proposalAgents->getAgThree(),'3. PROPOSAL ACTUALIZADO DESDE AVEXPRESS __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1179.                 }
  1180.                 if ((!empty($proposalAgents->getAgFour())) and (!($proposalAgents->getAgFour() == 0))){
  1181.                     $this->sendTelegram($proposalAgents->getAgFour(),'4. PROPOSAL ACTUALIZADO DESDE AVEXPRESS __ ID: '.$file->getIdProposal().' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1182.                 }
  1183.             }
  1184.         }
  1185.         //FIN: Notificamos al agente por Telegram
  1186.         return $this->redirectToRoute('ave_edit_file',
  1187.             array(
  1188.                 'id' => $fileId
  1189.             )
  1190.         );
  1191.     }
  1192.     /**
  1193.      * @Route("/productfileedit/{id}",  name="ave_productfile_edit")
  1194.      * Editar un producto de un expediente
  1195.      */
  1196.     public function editProductFileAction($idRequest $request)
  1197.     {
  1198.         $em $this->getDoctrine()->getManager();
  1199.         // Obtener el producto actual como array para optimizar memoria
  1200.         $productFile $em->createQueryBuilder()
  1201.             ->select('p')
  1202.             ->from(AveProductFile::class, 'p')
  1203.             ->where('p.id = :id')
  1204.             ->setParameter('id'$id)
  1205.             ->getQuery()
  1206.             ->getOneOrNullResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
  1207.         if (!$productFile) {
  1208.             throw $this->createNotFoundException('Producto no encontrado');
  1209.         }
  1210.         $fileId $productFile['fileId'];
  1211.         // Consulta Ćŗnica de todos los productos del expediente para evitar N+1
  1212.         $allProductFile $em->createQueryBuilder()
  1213.             ->select('p')
  1214.             ->from(AveProductFile::class, 'p')
  1215.             ->where('p.fileId = :fileId')
  1216.             ->setParameter('fileId'$fileId)
  1217.             ->getQuery()
  1218.             ->getArrayResult();
  1219.         // 1. Extraer ubicaciones manteniendo el orden de aparición
  1220.         $arrayLocation = [];
  1221.         $arrayLocationWithNull false;
  1222.         foreach ($allProductFile as $item) {
  1223.             if (!empty($item['location'])) {
  1224.                 $arrayLocation[$item['location']] = $item['location'];
  1225.             } else {
  1226.                 $arrayLocationWithNull true;
  1227.             }
  1228.         }
  1229.         if ($arrayLocationWithNull) {
  1230.             $arrayLocation['null'] = 'null';
  1231.         }
  1232.         $productInFile = [];
  1233.         foreach ($arrayLocation as $loc) {
  1234.             // Filtrar productos para esta ubicación
  1235.             $locProducts array_filter($allProductFile, function($p) use ($loc) {
  1236.                 return $loc === 'null' ? empty($p['location']) : $p['location'] === $loc;
  1237.             });
  1238.             // Clasificar por tipo (Video -> Sonido -> Iluminación -> Otros -> Nulos)
  1239.             $videos = [];
  1240.             $sonidos = [];
  1241.             $iluminaciones = [];
  1242.             $otros = [];
  1243.             $nulos = [];
  1244.             foreach ($locProducts as $p) {
  1245.                 $type $p['type'] ?? null;
  1246.                 if ($type === null) {
  1247.                     $nulos[] = $p;
  1248.                 } elseif ($type === 'VĆ­deo') {
  1249.                     $videos[] = $p;
  1250.                 } elseif ($type === 'Sonido') {
  1251.                     $sonidos[] = $p;
  1252.                 } elseif ($type === 'Iluminación') {
  1253.                     $iluminaciones[] = $p;
  1254.                 } else {
  1255.                     $otros[] = $p;
  1256.                 }
  1257.             }
  1258.             // Ordenar cada grupo por rankquoteAv ASC
  1259.             $sortFunc = function($a$b) {
  1260.                 return ($a['rankquoteAv'] ?? 0) <=> ($b['rankquoteAv'] ?? 0);
  1261.             };
  1262.             usort($videos$sortFunc);
  1263.             usort($sonidos$sortFunc);
  1264.             usort($iluminaciones$sortFunc);
  1265.             usort($otros$sortFunc);
  1266.             usort($nulos$sortFunc);
  1267.             // Unificar en el orden deseado
  1268.             $productInFile array_merge(
  1269.                 $productInFile,
  1270.                 $videos,
  1271.                 $sonidos,
  1272.                 $iluminaciones,
  1273.                 $otros,
  1274.                 $nulos
  1275.             );
  1276.         }
  1277.         // Consultas auxiliares optimizadas
  1278.         $suppliers $em->createQueryBuilder()
  1279.             ->select('s.id, s.name')
  1280.             ->from('App\Entity\Supplier''s')
  1281.             ->where('s.isSupplierAvExpress = TRUE')
  1282.             ->orderBy('s.name''ASC')
  1283.             ->getQuery()
  1284.             ->getArrayResult();
  1285.         $productsLocation $em->createQueryBuilder()
  1286.             ->select('l.name')
  1287.             ->from(AveProductFileLocationNames::class, 'l')
  1288.             ->getQuery()
  1289.             ->getArrayResult();
  1290.         // Quitar el elemento seleccionado para evitar duplicaciones
  1291.         foreach ($productInFile as $key => $item) {
  1292.             if ($productFile['id'] == $item['id']) {
  1293.                 unset($productInFile[$key]);
  1294.                 break;
  1295.             }
  1296.         }
  1297.         $numeroItems count($productInFile) + 1;
  1298.         return $this->render('MDS/AvexpressBundle/Avexpress/edit-productfiles.html.twig', [
  1299.             'id' => $fileId,
  1300.             'numeroItems' => $numeroItems,
  1301.             'arrayProductFile' => $productInFile,
  1302.             'services' => $productInFile,
  1303.             'product' => [$productFile],
  1304.             'suppliers' => $suppliers,
  1305.             'productsLocation' => $productsLocation,
  1306.         ]);
  1307.     }
  1308.     /**
  1309.      * @Route("/cleanproductfile/{id}",  name="ave_clean_productfile")
  1310.      * Eliminar los productos (y servicios en InOut) de un expediente que no estĆ©n relacionados con una factura o una proforma
  1311.      */
  1312.     public function cleanProductFileAction($idRequest $request)
  1313.     {
  1314.         $em $this->getDoctrine()->getManager();
  1315.         /* Obtengo usuario logueado */
  1316.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  1317.         $user_id $user_logueado->getId();
  1318.         $allMdvProductSelected $em->getRepository(AveProductFile::class)->findByFileId($id);
  1319.         // Si el ProductFile esta asociado a una factura o a una proforma se mantiene, de lo contrario se elimina y su evento asociado
  1320.         foreach ($allMdvProductSelected as $key => $item){
  1321.             $isInInvoice $em->getRepository(AveDocInvoiceItems::class)->findOneByPrdControlId($item->getId());
  1322.             $isInProforma $em->getRepository(AveDocProformaItems::class)->findOneByControlId($item->getId());
  1323.             if (!empty($isInInvoice) or !empty($isInProforma)){
  1324.                 //Lo sacamos de la lista de elementos a eliminar
  1325.                 unset($allMdvProductSelected[$key]);
  1326.             }
  1327.         }
  1328.         foreach ($allMdvProductSelected as $mdvProductSelected){
  1329.             $logTelegram false;
  1330.             //INICIO: Si hay un ID origin se debe eliminar en Eventos
  1331.             if (!empty($mdvProductSelected->getOriginId())){
  1332.                 $logTelegram true;
  1333.                 $delete $em->getRepository(ProposalSupplierServices::class)->findOneById($mdvProductSelected->getOriginId());
  1334.                 if (!empty($delete)) {
  1335.                     $destinationId $delete->getDestinationId();
  1336.                     $nameServEvents $delete->getName();
  1337.                     $proposalId $delete->getProposalId();
  1338.                     $prpInv $em->getRepository(ProposalInvoice::class)->findOneByProposalId($delete->getProposalId());
  1339.                     if (empty($prpInv)) { //Si hay factura en InOut no se debe modificar
  1340.                         if (!empty($delete)) {
  1341.                             $delete_sub $em->getRepository(ProposalSupplierServices::class)->findByServiceIdFather($delete->getId());
  1342.                             foreach ($delete_sub as $deletesub) {
  1343.                                 $em->remove($deletesub);
  1344.                             }
  1345.                             $em->remove($delete);
  1346.                             $em->flush();
  1347.                         }
  1348.                     }
  1349.                 } else {
  1350.                     // El servicio origen no se encontro
  1351.                     $logTelegram false;
  1352.                 }
  1353.             }
  1354.             //INICIO: Notificamos al agente por Telegram
  1355.             if ($logTelegram){
  1356.                 //Buscamos todos los agentes del proposal
  1357.                 $proposalAgents $em->getRepository(ProposalAgents::class)->findOneByIdProp($proposalId);
  1358.                 //Buscamos el Destino
  1359.                 $proposalDestino $em->getRepository(Destination::class)->findOneById($destinationId);
  1360.                 //Buscamos el agente de Develup
  1361.                 $userData $em->getRepository(User::class)->findOneById($user_id);
  1362.                 if (!empty($proposalAgents)){
  1363.                     if ((!empty($proposalAgents->getAgOne())) and (!($proposalAgents->getAgOne() == 0))){
  1364.                         $this->sendTelegram($proposalAgents->getAgOne(),'1. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1365.                     }
  1366.                     if ((!empty($proposalAgents->getAgTwo())) and (!($proposalAgents->getAgTwo() == 0))){
  1367.                         $this->sendTelegram($proposalAgents->getAgTwo(),'2. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1368.                     }
  1369.                     if ((!empty($proposalAgents->getAgThree())) and (!($proposalAgents->getAgThree() == 0))){
  1370.                         $this->sendTelegram($proposalAgents->getAgThree(),'3. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1371.                     }
  1372.                     if ((!empty($proposalAgents->getAgFour())) and (!($proposalAgents->getAgFour() == 0))){
  1373.                         $this->sendTelegram($proposalAgents->getAgFour(),'4. SERVICIO ELIMINADO DESDE AVEXPRESS __ ID: '.$proposalId.' __ DESTINO: '.$proposalDestino->getTitle().' __ PROVEEDOR: AvExpress __ CONTACTO: '.$userData->getName().' '.$userData->getLastName());
  1374.                     }
  1375.                 }
  1376.             }
  1377.             //FIN: Notificamos al agente por Telegram
  1378.             //FIN: Si hay un ID origin se debe eliminar en Eventos
  1379.             //INICIO: Si el producto se encuentra dentro de una proforma (Ave_Doc_Proforma_Items) se elimina tambiĆ©n
  1380.             $productInProforma $em->getRepository(AveDocProformaItems::class)->findOneByControlId($mdvProductSelected->getId());
  1381.             if (!empty($productInProforma)){
  1382.                 $productInProforma->setFileId((-1) * $productInProforma->getFileId());      // No lo vamos a eliminar, apuntarĆ” al fileId en negativo
  1383.                 $em->persist($productInProforma);
  1384.                 // $em->remove($productInProforma);
  1385.                 $em->flush();
  1386.             }
  1387.             //FIN: Si el producto se encuentra dentro de una proforma (Ave_Doc_Proforma_Items) se elimina tambiĆ©n
  1388.             $mdvProductSelected->setFileId((-1) * $mdvProductSelected->getFileId());      // No lo vamos a eliminar, apuntarĆ” al fileId en negativo
  1389.             $em->persist($mdvProductSelected);
  1390.             // $em->remove($mdvProductSelected);
  1391.             $em->flush();
  1392.         }
  1393.         return $this->redirectToRoute('ave_edit_file', array('id' => $id));
  1394.     }
  1395.     /**
  1396.      * @Route("/overallproductfile/",  name="ave_over_all_productfile")
  1397.      * Aplicar un Over a todos los productos de un expediente
  1398.      */
  1399.     public function overAllProductFileAction(Request $request){
  1400.         $fileId $request->request->get('fileId');
  1401.         $opOverAll $request->request->get('opOverAll');
  1402.         $overAll $request->request->get('overAll');
  1403.         $em $this->getDoctrine()->getManager();
  1404.         $productInFile $em->getRepository(AveProductFile::class)->findByFileId($fileId);
  1405.         foreach ($productInFile as $item){
  1406.             $itemId $item->getId();
  1407.             $item->setOpOver($opOverAll);
  1408.             $item->setOver($overAll);
  1409.             $em->persist($item);
  1410.             $em->flush();
  1411.         }
  1412.         return $this->redirectToRoute('ave_productfile_edit', array('id' => $itemId));
  1413.     }
  1414.     /**
  1415.      * @Route("/commissionallproductfile/",  name="ave_commission_all_productfile")
  1416.      * Aplicar una Comision a todos los productos de un expediente
  1417.      */
  1418.     public function commissionAllProductFileAction(Request $request){
  1419.         $fileId $request->request->get('fileId');
  1420.         $opCommissionAll $request->request->get('opCommissionAll');
  1421.         $commissionAll $request->request->get('commissionAll');
  1422.         $em $this->getDoctrine()->getManager();
  1423.         $productInFile $em->getRepository(AveProductFile::class)->findByFileId($fileId);
  1424.         foreach ($productInFile as $item){
  1425.             $itemId $item->getId();
  1426.             $item->setOpCommission($opCommissionAll);
  1427.             $item->setCommission($commissionAll);
  1428.             $em->persist($item);
  1429.             $em->flush();
  1430.         }
  1431.         return $this->redirectToRoute('ave_productfile_edit', array('id' => $itemId));
  1432.     }
  1433.     /**
  1434.      * @Route("/ivazeroallproductfile/",  name="ave_iva_zero_all_productfile")
  1435.      * Aplicar un IVA de cero a todos los productos de un expediente
  1436.      */
  1437.     public function ivaZeroAllProductFileAction(Request $request){
  1438.         $fileId $request->request->get('fileId');
  1439. //        $opCommissionAll = $request->request->get('opCommissionAll');
  1440. //        $commissionAll = $request->request->get('commissionAll');
  1441.         $em $this->getDoctrine()->getManager();
  1442.         $productInFile $em->getRepository(AveProductFile::class)->findByFileId($fileId);
  1443.         foreach ($productInFile as $item){
  1444.             $itemId $item->getId();
  1445.             $item->setOpIva(1);
  1446.             $item->setIva(0);
  1447.             
  1448.             $em->persist($item);
  1449.             $em->flush();
  1450.         }
  1451.         return $this->redirectToRoute('ave_productfile_edit', array('id' => $itemId));
  1452.     }
  1453.     
  1454.     /**
  1455.      * @Route("/productfilelocationadd/",  name="ave_add_productfilelocation")
  1456.      * Agregar una Ubicacion. Salas en donde estara el producto
  1457.      */
  1458.     public function addProductFileLocationActionRequest $request)
  1459.     {
  1460.         $em $this->getDoctrine()->getManager();
  1461.         $newRequest $request->request->get('product');
  1462.         /* Obtengo usuario logueado */
  1463.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  1464.         $user_id $user_logueado->getId();
  1465.         $newProductFile = new AveProductFileLocationNames();
  1466.         $newProductFile->setName($newRequest['name']);
  1467.         $newProductFile->setDescription($newRequest['description']);
  1468.         $newProductFile->setIdGpLounge(null);
  1469.         $newProductFile->setCreatedId($user_id);
  1470.         $newProductFile->setUpdatedId($user_id);
  1471.         $newProductFile->setCreatedAt(new \DateTime("now"));
  1472.         $newProductFile->setUpdatedAt(new \DateTime("now"));
  1473.         $em->persist($newProductFile);
  1474.         $em->flush();
  1475.         return $this->redirectToRoute('ave_list_productfilelocation');
  1476.     }
  1477.     /**
  1478.      * @Route("/productfilelocationlist/",  name="ave_list_productfilelocation")
  1479.      * Listar Ubicaciones para los productos
  1480.      */
  1481.     public function listProductFileLocationAction(Request $request){
  1482.         $em $this->getDoctrine()->getManager();
  1483.         /** @var AveProductFileLocationNamesRepository $repo */
  1484.         $repo $em->getRepository(AveProductFileLocationNames::class);
  1485.         $productsLocation $repo->findAllAsArray();
  1486.         return $this->render('MDS/AvexpressBundle/Avexpress/list-productsfile-locationnames.html.twig',
  1487.             array(
  1488.                 'productsLocation' => $productsLocation,
  1489.             ));
  1490.     }
  1491.     /**
  1492.      * @Route("/productfilelocationedit/{id}",  name="ave_edit_productfilelocation")
  1493.      * Editar una Ubicacion
  1494.      */
  1495.     public function editProductFileLocationAction$idRequest $request)
  1496.     {
  1497.         $em $this->getDoctrine()->getManager();
  1498.         $editProductLocation $em->getRepository(AveProductFileLocationNames::class)->findOneById($id);
  1499.         return $this->render('MDS/AvexpressBundle/Avexpress/edit-productsfiles-location.html.twig',
  1500.             array(
  1501.                 'id' => $editProductLocation->getId(),
  1502.                 'productLocation' => $editProductLocation,
  1503.             ));
  1504.     }
  1505.     /**
  1506.      * @Route("/productfilelocationupdate/",  name="ave_update_productfilelocation")
  1507.      * Update de una Ubicacion
  1508.      */
  1509.     public function updateProductFileLocationAction(Request $request)
  1510.     {
  1511.         $em $this->getDoctrine()->getManager();
  1512.         $newRequest $request->request->get('product');
  1513.         $id $newRequest['id'];
  1514.         $newProduct $em->getRepository(AveProductFileLocationNames::class)->findOneById($id);
  1515.         /* Obtengo usuario logueado */
  1516.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  1517.         $user_id $user_logueado->getId();
  1518.         if (!empty($newRequest['name'])){$newProduct->setName($newRequest['name']);}
  1519.         $newProduct->setDescription($newRequest['description']);
  1520.         $newProduct->setUpdatedId($user_id);
  1521.         $newProduct->setUpdatedAt(new \DateTime("now"));
  1522.         $em->persist($newProduct);
  1523.         $em->flush();
  1524.         return $this->redirectToRoute('ave_list_productfilelocation');
  1525.     }
  1526.     /**
  1527.      * @Route("/productfilelocationdelete/{id}",  name="ave_delete_productfilelocation")
  1528.      * Eliminar una Ubicacion
  1529.      */
  1530.     public function deleteProductAction($idRequest $request)
  1531.     {
  1532.         $em $this->getDoctrine()->getManager();
  1533.         $delProduct $em->getRepository(AveProductFileLocationNames::class)->findOneById($id);
  1534.         if (!empty($delProduct)){
  1535.             $em->remove($delProduct);
  1536.             $em->flush();
  1537.         }
  1538.         return $this->redirectToRoute('ave_list_productfilelocation');
  1539.     }
  1540.     private function obtenerRankQuoteAv($id)
  1541.     {
  1542.         // $id Id del Expediente (File)
  1543.         $em $this->getDoctrine()->getManager();
  1544.         $items $em->getRepository(AveProductFile::class)->findByFileId($id);
  1545.         if (empty($items)){ $num 1; } else { $num sizeof($items) + 1; }
  1546.         $data $num;
  1547.         return $data;
  1548.     }
  1549.     private function obtenerFechas($id$dateStart$dateEnd)
  1550.     {
  1551.         // $id Id del Expediente (File)
  1552.         // $dateStart Fecha de inicio (Producto)
  1553.         // $dateEnd Fecha de fin (Producto)
  1554.         $em $this->getDoctrine()->getManager();
  1555.         $file $em->getRepository(AveFiles::class)->findOneById($id);
  1556.         if (empty($dateStart)){ $newDateStart $file->getDateStart(); } else { $newDateStart $dateStart; }
  1557.         if (empty($dateEnd)){ $newDateEnd $file->getDateEnd(); } else { $newDateEnd $dateEnd; }
  1558.         $data = array(
  1559.             'dateStart' => $newDateStart,
  1560.             'dateEnd' => $newDateEnd,
  1561.         );
  1562.         return $data;
  1563.     }
  1564.     private function sendTelegram$id$text )
  1565.     {
  1566.         return true;
  1567.         $em $this->getDoctrine()->getManager();
  1568.         $telegUser $em->getRepository(MdvTelegramUser::class)->findOneByUserId($id);
  1569.         if (empty($telegUser)){return true;}
  1570.         $parameters = array(
  1571.             'chat_id' => $telegUser->getChatId(),
  1572.             'text' => $text,
  1573.         );
  1574.         $bot_token $telegUser->getBotToken();
  1575.         $url "https://api.telegram.org/bot$bot_token/sendMessage";
  1576.         if (!$curl curl_init()){
  1577.             exit();
  1578.         }
  1579.         curl_setopt($curl,CURLOPT_POST,true);
  1580.         curl_setopt($curl,CURLOPT_POSTFIELDS,$parameters);
  1581.         curl_setopt($curl,CURLOPT_URL,$url);
  1582.         curl_setopt($curl,CURLOPT_RETURNTRANSFER,true);
  1583.         $output curl_exec($curl);
  1584.         curl_close($curl);
  1585.         return true;
  1586.     }
  1587.     private function addProductFileToProforma$fileId$newProductId$proformaId )
  1588.     {
  1589.         $em $this->getDoctrine()->getManager();
  1590.         $file $em->getRepository(AveFiles::class)->findOneById($fileId);
  1591.         $productFile $em->getRepository(AveProductFile::class)->findOneById($newProductId);
  1592.         $proforma $em->getRepository(AveDocProforma::class)->findOneById($proformaId);
  1593.         if (!empty($file) and !empty($productFile) and !empty($proforma) ){
  1594.             $newProformaItem = new AveDocProformaItems();
  1595.             $newProformaItem->setControlId($newProductId);
  1596.             $newProformaItem->setType('PRODUCT');
  1597.             $newProformaItem->setFileId($fileId);
  1598.             $newProformaItem->setProformaId($proformaId);
  1599.             $em->persist($newProformaItem);
  1600.             $em->flush();
  1601.             return true;
  1602.         } else {
  1603.             return false;
  1604.         }
  1605.     }
  1606.     private function precioPorVariacionDeDias ($supplierService$productFile){
  1607.         $em $this->getDoctrine()->getManager();
  1608.         // El precio unitario debe ser dividido en funcion de los dias que tiene InOut y no en funcion de los dias de Av Express
  1609.         $days = ($supplierService->getDateOutAt()->diff($supplierService->getDateInAt())->days)===$supplierService->getDateOutAt()->diff($supplierService->getDateInAt())->days +1;
  1610.         if (array_key_exists('productFileId',$productFile)){
  1611.             // En el GridTwo viene es un arreglo no la entidad
  1612.             $productInFile $em->getRepository(AveProductFile::class)->findOneById($productFile['productFileId']);
  1613.             $newPrice $productInFile->getSubTotalPrice() / ( $days );
  1614.         } else {
  1615.             $newPrice $productFile->getSubTotalPrice() / ( $days );
  1616.         }
  1617.         $newPrice $newPrice $supplierService->getUnits();
  1618.         $newPrice round($newPrice,2,PHP_ROUND_HALF_UP);
  1619.         return $newPrice;
  1620.     }
  1621.     private function messageOfChangesToAgent($message$proposalId){
  1622.         // $message mensaje a enviar a los agentes del proposal
  1623.         if ($proposalId  == 0){ return true; }
  1624.         $em $this->getDoctrine()->getManager();
  1625.         $proposal $em->getRepository(Proposal::class)->findOneById($proposalId);
  1626.         /* Obtengo usuario logueado */
  1627.         $user_logueado $this->get('security.token_storage')->getToken()->getUser();
  1628.         $user_id $user_logueado->getId();
  1629.         $agent $em->getRepository(User::class)->findOneById($user_id);
  1630.         $message 'El proposal <strong>#'.$proposalId.' '.$proposal->getName().'</strong>'.' ha sido modificacdo por el agente: '.$agent->getName().' '.$agent->getLastName().'<br><br><br>'.$message;
  1631.         $proposalAgents $em->getRepository(ProposalAgents::class)->findOneByIdProp($proposalId);
  1632.         $mailArrayTo = array();
  1633.         if (!empty($agent)){ $mailArrayTo[$agent->getEmail()] = $agent->getEmail(); }
  1634.         if (!empty($proposalAgents)){
  1635.             if (!empty($proposalAgents->getAgOne())){
  1636.                 $agent $em->getRepository(User::class)->findOneById($proposalAgents->getAgOne());
  1637.                 $mailArrayTo[$agent->getEmail()] = $agent->getEmail();
  1638.             }
  1639.             if (!empty($proposalAgents->getAgTwo())){
  1640.                 $agent $em->getRepository(User::class)->findOneById($proposalAgents->getAgTwo());
  1641.                 $mailArrayTo[$agent->getEmail()] = $agent->getEmail();
  1642.             }
  1643.             if (!empty($proposalAgents->getAgThree())){
  1644.                 $agent $em->getRepository(User::class)->findOneById($proposalAgents->getAgThree());
  1645.                 $mailArrayTo[$agent->getEmail()] = $agent->getEmail();
  1646.             }
  1647.             if (!empty($proposalAgents->getAgFour())){
  1648.                 $agent $em->getRepository(User::class)->findOneById($proposalAgents->getAgFour());
  1649.                 $mailArrayTo[$agent->getEmail()] = $agent->getEmail();
  1650.             }
  1651.         }
  1652.         if (!empty($mailArrayTo)){
  1653.             $mailArrayTo[$agent->getEmail()] = $agent->getEmail();
  1654.             $replyTo = array();
  1655.             foreach ($mailArrayTo as $item){ $replyTo[$item] = $item; }
  1656.             $agentMail $agent->getEmail();
  1657.             //Se prepara el correo con los agentes a notificar
  1658.             $firmGmail $agent->getFirmGmail();
  1659.             $data = array(
  1660.                 'body' => $message,
  1661.                 'firm' => $firmGmail,
  1662.             );
  1663.             // EJECUTAR ENVIO DE ALERTA PARA EL AGENTE
  1664.             $transporter = new Swift_SmtpTransport();
  1665.             $transporter->setHost('smtp.gmail.com')
  1666.                 ->setEncryption('ssl')//ssl / tls
  1667.                 ->setPort(465)// 465 / 587
  1668.                 ->setUsername('desarrollo@develup.solutions')
  1669.                 ->setPassword('utvh hzoi wfdo ztjs');
  1670.             $mailer = new Swift_Mailer($transporter);
  1671.             $message = new Swift_Message();
  1672.             $message->setSubject('Actualización de servicios AvExpress del proposal: '$proposalId)
  1673.                 ->setSender($agentMail)
  1674.                 ->setFrom(array("desarrollo@develup.solutions" => "System Mante 3.0"))
  1675.                 ->setReplyTo($agentMail)
  1676.                 ->setTo($replyTo)
  1677.                 ->setBody(
  1678.                     $this->renderView(
  1679.                         'mail/structure-mail.html.twig',
  1680.                         array('data' => $data)
  1681.                     ),
  1682.                     'text/html'
  1683.                 );
  1684.             $mailer->send($message);
  1685.         }
  1686.         return true;
  1687.     }
  1688. };