false], methods: ['GET', 'POST'])] public function devis( EventDispatcherInterface $eventDispatcher, EntityManagerInterface $entityManager, DevisRepository $devisRepository, AppLogger $appLogger, PaginatorInterface $paginator, Request $request, KernelInterface $kernel, ): Response { // Gestion du renvoi de la signature if ($request->query->has('resend')) { $quoteId = $request->query->get('resend'); $quote = $devisRepository->find($quoteId); if ($quote instanceof Devis) { $quote->setState("created_waitsign"); $entityManager->persist($quote); $entityManager->flush(); // Déclenchement de l'événement de renvoi $event = new DevisSend($quote); $eventDispatcher->dispatch($event); // Journalisation et notification $appLogger->record('RESEND', 'Relance signature pour le devis ' . $quote->getNum()); $this->addFlash("success", "Le lien de signature pour le devis " . $quote->getNum() . " a été renvoyé au client."); return $this->redirectToRoute('app_crm_devis'); } $this->addFlash("error", "Devis introuvable."); } $appLogger->record('VIEW', 'Consultation de la liste des devis'); // Pagination (Tri décroissant sur la date de création pour voir les plus récents en premier) $pagination = $paginator->paginate( $devisRepository->findBy([], ['createA' => 'DESC']), $request->query->getInt('page', 1), 20 ); return $this->render('dashboard/devis/list.twig', [ 'quotes' => $pagination, ]); } #[Route(path: '/crm/devis/delete/{id}', name: 'app_crm_devis_delete', options: ['sitemap' => false], methods: ['GET', 'POST'])] public function devisDelete(string $id, AppLogger $appLogger, Client $client, Request $request, DevisRepository $devisRepository, EntityManagerInterface $entityManager): Response { $customer = $devisRepository->find($id); if (!$customer) { $this->addFlash('error', 'Le devis demandé n\'existe pas.'); return $this->redirectToRoute('app_crm_devis'); } $token = $request->query->get('_token'); if ($this->isCsrfTokenValid('delete' . $customer->getId(), $token)) { $appLogger->record('DELETE', sprintf('Suppression définitive du devis : %s', $customer->getNum())); if ($customer->getSignatureId() != "") { $client->cancelSign($customer->getSignatureId()); } foreach ($customer->getDevisLines() as $devisLine) { $entityManager->remove($devisLine); } foreach ($customer->getDevisOptions() as $devisOption) { $entityManager->remove($devisOption); } $entityManager->remove($customer); $entityManager->flush(); $this->addFlash('success', sprintf('Le devis %s a été supprimé définitivement.', $customer->getNum())); } else { $this->addFlash('error', 'Jeton de sécurité invalide. La suppression a été annulée.'); } return $this->redirectToRoute('app_crm_devis'); } #[Route(path: '/crm/devis/add', name: 'app_crm_devis_add', options: ['sitemap' => false], methods: ['GET', 'POST'])] public function devisAdd(Client $client, OptionsRepository $optionsRepository, EventDispatcherInterface $eventDispatcher, KernelInterface $kernel, CustomerAddressRepository $customerAddress, ProductRepository $productRepository, EntityManagerInterface $entityManager, CustomerRepository $customerRepository, DevisRepository $devisRepository, AppLogger $appLogger, Request $request): Response { $devisNumber = "DEVIS-" . sprintf('%05d', $devisRepository->count() + 1); $appLogger->record('VIEW', 'Consultation de la création d\'un devis'); $devis = new Devis(); $devis->setNum($devisNumber); $devis->setState("draft"); $devis->setCreateA(new \DateTimeImmutable()); $devis->setUpdateAt(new \DateTimeImmutable()); $form = $this->createForm(NewDevisType::class, $devis); if ($request->isMethod('POST')) { $devis->setStartAt(new DateTimeImmutable($_POST['new_devis']['startAt'])); $devis->setEndAt(new DateTimeImmutable($_POST['new_devis']['endAt'])); $interval = $devis->getStartAt()->diff($devis->getEndAt()); $day = $interval->days; $devis->setBillAddress($customerAddress->find($_POST['devis']['bill_address'])); $devis->setAddressShip($customerAddress->find($_POST['devis']['ship_address'])); $devis->setCustomer($customerRepository->find($_POST['new_devis']['customer'])); foreach ($_POST['lines'] as $cd => $line) { $rLine = new DevisLine(); $rLine->setDevi($devis); $rLine->setPos($cd); $rLine->setProduct($line['product']); $rLine->setDay($day); $rLine->setPriceHt(floatval($line['price_ht'])); $rLine->setPriceHtSup(floatval($line['price_sup_ht'])); $entityManager->persist($rLine); } foreach ($_POST['options'] as $line) { $rLineOptions = new DevisOptions(); $rLineOptions->setDevis($devis); $rLineOptions->setOption($line['product']); $rLineOptions->setPriceHt(floatval($line['price_ht'])); $entityManager->persist($rLineOptions); } $entityManager->persist($devis); $entityManager->flush(); $docusealService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class),true); $contentDocuseal = $docusealService->generate(); $tmpPathDocuseal = sys_get_temp_dir() . '/docuseal_' . uniqid() . '.pdf'; file_put_contents($tmpPathDocuseal, $contentDocuseal); $fileDocuseal = new UploadedFile($tmpPathDocuseal, 'dc_' . $devis->getNum() . '.pdf', 'application/pdf', 0, true); $devis->setDevisDocuSealFile($fileDocuseal); $devisService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class), false); $contentDevis = $devisService->generate(); $tmpPathDevis = sys_get_temp_dir() . '/devis_' . uniqid() . '.pdf'; file_put_contents($tmpPathDevis, $contentDevis); $fileDevis = new UploadedFile($tmpPathDevis, 'devis_' . $devis->getNum() . '.pdf', 'application/pdf', 0, true); $devis->setDevisFile($fileDevis); $devis->setState("wait-send"); $devis->setUpdateAt(new \DateTimeImmutable()); $entityManager->flush(); $client->createSubmissionDevis($devis); $this->addFlash('success', sprintf('Le devis %s a été crée.', $devis->getNum())); return $this->redirectToRoute('app_crm_devis'); } return $this->render('dashboard/devis/add.twig', [ 'form' => $form->createView(), 'lines' => [ [ 'product' => '', 'days'=>'', 'price_ht' => '', 'price_sup_ht' =>'' ], ], 'options' => [ [ 'product' => '', 'details' => '', 'price_ht' => '', ] ] ]); } #[Route(path: '/crm/devis/{id}', name: 'app_crm_devis_edit', options: ['sitemap' => false], methods: ['GET', 'POST'])] public function devisEdit(?Devis $devis,Client $client,DevisLineRepository $devisLineRepository,DevisOptionsRepository $devisOptionsRepository, OptionsRepository $optionsRepository, EventDispatcherInterface $eventDispatcher, KernelInterface $kernel, CustomerAddressRepository $customerAddress, ProductRepository $productRepository, EntityManagerInterface $entityManager, CustomerRepository $customerRepository, DevisRepository $devisRepository, AppLogger $appLogger, Request $request): Response { $appLogger->record('VIEW', 'Consultation pour modifier le devis '.$devis->getNum()); $form = $this->createForm(NewDevisType::class, $devis); if ($request->isMethod('POST')) { $devis->setStartAt(new DateTimeImmutable($_POST['new_devis']['startAt'])); $devis->setEndAt(new DateTimeImmutable($_POST['new_devis']['endAt'])); $devis->setBillAddress($customerAddress->find($_POST['devis']['bill_address'])); $devis->setAddressShip($customerAddress->find($_POST['devis']['ship_address'])); $devis->setCustomer($customerRepository->find($_POST['new_devis']['customer'])); $interval = $devis->getStartAt()->diff($devis->getEndAt()); $day = $interval->days; foreach ($_POST['lines'] as $cd => $line) { if($line['id'] != "") { $rLine = $devisLineRepository->find($line['id']); } else { $rLine = new DevisLine(); $rLine->setDevi($devis); $rLine->setPos($cd); } $rLine->setDay($day); $rLine->setProduct($line['product']); $rLine->setPriceHt(floatval($line['price_ht'])); $rLine->setPriceHtSup(floatval($line['price_sup_ht'])); $entityManager->persist($rLine); } foreach ($_POST['options'] as $line) { if($line['id'] != "") { $rLineOptions = $devisOptionsRepository->find($line['id']); } else { $rLineOptions = new DevisOptions(); $rLineOptions->setDevis($devis); } $rLineOptions->setOption($line['product']); $rLineOptions->setDetails($line['details']); $rLineOptions->setPriceHt(floatval($line['price_ht'])); $entityManager->persist($rLineOptions); } $entityManager->persist($devis); $entityManager->flush(); $docusealService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class),true); $contentDocuseal = $docusealService->generate(); $tmpPathDocuseal = sys_get_temp_dir() . '/docuseal_' . uniqid() . '.pdf'; file_put_contents($tmpPathDocuseal, $contentDocuseal); $fileDocuseal = new UploadedFile($tmpPathDocuseal, 'dc_' . $devis->getNum() . '.pdf', 'application/pdf', 0, true); $devis->setDevisDocuSealFile($fileDocuseal); $devisService = new DevisPdfService($kernel, $devis, $entityManager->getRepository(Product::class),false); $contentDevis = $devisService->generate(); $tmpPathDevis = sys_get_temp_dir() . '/devis_' . uniqid() . '.pdf'; file_put_contents($tmpPathDevis, $contentDevis); $fileDevis = new UploadedFile($tmpPathDevis, 'devis_' . $devis->getNum() . '.pdf', 'application/pdf', 0, true); $devis->setDevisFile($fileDevis); $devis->setUpdateAt(new \DateTimeImmutable()); $devis->setState("wait-send"); $entityManager->flush(); $client->createSubmissionDevis($devis); $this->addFlash('success', sprintf('Le devis %s a été modifiée.', $devis->getNum())); return $this->redirectToRoute('app_crm_devis'); } $lines =[ [ 'id' => '', 'product' => '', 'days'=>'', 'price_ht' => '', 'price_sup_ht' =>'' ] ]; $options = [ [ 'id' => '', 'product' => '', 'details' => '', 'price_ht' => '', ] ]; $shipAddress = []; $billAddress =[]; foreach ($devis->getDevisLines() as $key => $line) { $lines[$key] = [ 'id' => $line->getId(), 'product' => $line->getProduct(), 'days' => $line->getDay(), 'price_ht' => $line->getPriceHt(), 'price_sup_ht' => $line->getPriceHtSup() ]; } foreach ($devis->getDevisOptions() as $key => $line) { $options[$key] = [ 'id' => $line->getId(), 'details' => $line->getDetails(), 'product' => $line->getOption(), 'price_ht' => $line->getPriceHt(), ]; } foreach ($devis->getCustomer()->getCustomerAddresses() as $customerAddress) { $shipAddress[$customerAddress->getId()] = $customerAddress->getAddress()." ".$customerAddress->getZipcode()." ".$customerAddress->getCity(); $billAddress[$customerAddress->getId()] = $customerAddress->getAddress()." ".$customerAddress->getZipcode()." ".$customerAddress->getCity(); } return $this->render('dashboard/devis/add.twig', [ 'form' => $form->createView(), 'devis' => $devis, 'lines' => $lines, 'options' => $options, 'products' => $productRepository->findAll(), 'optionsList' => $optionsRepository->findAll(), 'shipAddress' => $shipAddress, 'billAddress' => $billAddress, ]); } }