src/Controller/Security/PagesController.php line 71

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Security;
  3. use App\Controller\API\ApiTrait;
  4. use App\Entity\Client;
  5. use App\Entity\Notary;
  6. use App\Entity\Order;
  7. use App\Entity\ServiceForm;
  8. use App\Enum\FormAssessmentType;
  9. use App\Enum\OrderStatus;
  10. use App\Form\ClientType;
  11. use App\Form\ForgotPasswordType;
  12. use App\Form\NotaryClientType;
  13. use App\Form\NotaryType;
  14. use App\Form\RequestConsultationType;
  15. use App\Message\NotaryRegisterMessage;
  16. use App\Service\Merchant\Exception\MerchantException;
  17. use App\Service\Merchant\MerchantBalanceServiceInterface;
  18. use App\Service\Merchant\MerchantPaymentInterface;
  19. use App\Service\Merchant\MerchantTransactionInterface;
  20. use App\Service\Notary\RegistrationEnvironmentResolver;
  21. use App\Service\ServiceForm\Pipeline\ServiceFormPipeline;
  22. use App\Service\ServiceForm\Context\ServiceFormContext;
  23. use App\ValueObject\ShopHost;
  24. use App\Repository\NotaryRepository;
  25. use App\Repository\OrderRepository;
  26. use App\Repository\ServiceFormRepository;
  27. use App\Repository\ServiceSectionGroupRepository;
  28. use App\Repository\ServiceSectionRepository;
  29. use App\Security\LoginFormAuthenticator;
  30. use App\Service\CallbackService\EmailCallbackService;
  31. use App\Service\CallbackService\Exception\TooOftenSendingException;
  32. use App\Service\CheckEmailService;
  33. use App\Service\ClientService;
  34. use App\Service\Notary\NotaryRegisterService;
  35. use App\Service\NotaryCodeService;
  36. use App\Service\OrderSaveManager;
  37. use App\Service\PaperCopyService;
  38. use App\Service\RecoveryPassword;
  39. use App\Service\VinParserManager;
  40. use Doctrine\ORM\EntityManagerInterface;
  41. use Psr\Log\LoggerInterface;
  42. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  43. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  44. use Symfony\Component\Form\FormError;
  45. use Symfony\Component\HttpFoundation\JsonResponse;
  46. use Symfony\Component\HttpFoundation\RedirectResponse;
  47. use Symfony\Component\HttpFoundation\Request;
  48. use Symfony\Component\HttpFoundation\Response;
  49. use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
  50. use Symfony\Component\Routing\Annotation\Route;
  51. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  52. use Symfony\Component\Security\Core\Security;
  53. use Symfony\Component\Security\Http\Authentication\UserAuthenticatorInterface;
  54. class PagesController extends AbstractController
  55. {
  56.     use ApiTrait;
  57.     public function __construct(
  58.         private readonly ParameterBagInterface $parameterBag,
  59.         private readonly Security $security,
  60.         private readonly ClientService $clientService,
  61.     ) {
  62.     }
  63.     /**
  64.      * @Route("/recovery-password", name="recovery-password", methods={"GET", "POST"})
  65.      */
  66.     public function recoveryPassword(Request $requestRecoveryPassword $recoveryPassword): Response
  67.     {
  68.         $isAjax $request->isXmlHttpRequest() || $request->headers->get('X-Requested-With') === 'XMLHttpRequest';
  69.         if ($isAjax) {
  70.             return $this->recoveryPasswordAjax($request$recoveryPassword);
  71.         }
  72.         $form $this->createForm(ForgotPasswordType::class, ['email' => null]);
  73.         $form->handleRequest($request);
  74.         $email '';
  75.         if ($form->isSubmitted() && $form->isValid()) {
  76.             $email = (string) $form->get('email')->getData();
  77.         }
  78.         $resultText '';
  79.         if ($email) {
  80.             $resultText $recoveryPassword->recoveryPassword($email);
  81.         }
  82.         return $this->render('security/recoveryPassword.html.twig', [
  83.             'form' => $form->createView(),
  84.             'resultText' => $resultText,
  85.         ]);
  86.     }
  87.     private function recoveryPasswordAjax(Request $requestRecoveryPassword $recoveryPassword): Response
  88.     {
  89.         $form $this->createForm(ForgotPasswordType::class, ['email' => null]);
  90.         $form->handleRequest($request);
  91.         if (!$form->isSubmitted()) {
  92.             return $this->response(['error' => 'Форма не была отправлена'], 400);
  93.         }
  94.         if (!$form->isValid()) {
  95.             $errors = [];
  96.             foreach ($form->getErrors(true) as $error) {
  97.                 $errors[] = $error->getMessage();
  98.             }
  99.             return $this->response(['error' => implode(', '$errors)], 400);
  100.         }
  101.         $email = (string)$form->get('email')->getData();
  102.         if (empty($email)) {
  103.             return $this->response(['error' => 'Email не указан'], 400);
  104.         }
  105.         $resultText $recoveryPassword->recoveryPassword($email);
  106.         if (str_contains($resultText'не существует')) {
  107.             return $this->response(['error' => $resultText], 400);
  108.         }
  109.         return $this->response([
  110.             'success' => true,
  111.             'message' => $resultText
  112.         ]);
  113.     }
  114.     /**
  115.      * @Route("/client-registry", name="clientRegistry")
  116.      */
  117.     public function clientRegistry(Request $request,
  118.                                    EntityManagerInterface $entityManager,
  119.                                    UserPasswordHasherInterface $passwordEncoder,
  120.                                    NotaryCodeService $codeService,
  121.                                    NotaryRepository $notaryRepository,
  122.                                    CheckEmailService $checkEmailService,
  123.                                    LoginFormAuthenticator $login,
  124.                                    UserAuthenticatorInterface $authenticator
  125.     ): Response
  126.     {
  127.         //Закрыт ЛК ФЛ
  128.         throw $this->createNotFoundException('Страница не найдена');
  129.         $client = new Client();
  130.         $form $this->createForm(ClientType::class, $client);
  131.         $newEmail $request->request->get('client') ? $request->request->get('client')['email'] : null;
  132.         if ($newEmail) {
  133.             if ($checkEmailService->isEmailFree(0$newEmail)) {
  134.                 $form->handleRequest($request);
  135.             } else {
  136.                 $form->get('email')->addError(new FormError('Нельзя использовать этот адрес электронной почты '));
  137.             }
  138.         }
  139.         if ($form->isSubmitted() && $form->isValid()) {
  140.             if ($notaryCode $form->get('notaryCode')->getData()) {
  141.                 if ($notaryId $codeService->getNotaryCodeFromString($notaryCode)) {
  142.                     if ($notary $notaryRepository->find($notaryId)) {
  143.                         $client->setNotary($notary);
  144.                     }
  145.                 }
  146.             }
  147. //
  148. //            $plainPassword = $client->getPassword();
  149. //
  150. //            $a = '0123456789abcdef';
  151. //            $secret = '';
  152. //            for ($i = 0; $i < 32; $i++) {
  153. //                $secret .= $a[rand(0, 15)];
  154. //            }
  155. //
  156. //            $plainPassword = !empty($plainPassword) ? $plainPassword : $secret;
  157. //            $client->setPassword(
  158. //                $passwordEncoder->hashPassword($client, $plainPassword)
  159. //            );
  160. //
  161. //            $client->setRoles(['ROLE_CLIENT']);
  162.             $entityManager->persist($client);
  163.             $entityManager->flush();
  164.             return $authenticator->authenticateUser($client$login$request);
  165.         }
  166.         return $this->render('area/client/forms/registry.html.twig', [
  167.             'client' => $client,
  168.             'form'   => $form->createView(),
  169.         ]);
  170.     }
  171.     /**
  172.      * Регистрация нотариуса, будущего рефовода. Не отправляем два красных уведомления
  173.      *
  174.      * @Route("/refovod-partner-registry", name="refovodNotaryRegistry")
  175.      */
  176.     public function refovodNotaryRegistry(
  177.         Request                         $request,
  178.         LoginFormAuthenticator          $login,
  179.         UserAuthenticatorInterface      $authenticator,
  180.         LoggerInterface                 $logger,
  181.         NotaryRegisterService           $notaryRegisterService,
  182.         RegistrationEnvironmentResolver $registrationEnvironmentResolver,
  183.     ): Response
  184.     {
  185.         $notary = new Notary();
  186.         $form $this->createForm(NotaryType::class, $notary);
  187.         $form->remove('payLinkReferralEnabled');
  188.         $form->handleRequest($request);
  189.         if ($form->isSubmitted() && $form->isValid()) {
  190.             $notary $notaryRegisterService->register(
  191.                 $notary,
  192.                 $registrationEnvironmentResolver->resolveByHost($request->getHost()),
  193.                 [3]
  194.             );
  195.             return $authenticator->authenticateUser($notary$login$request);
  196.         }
  197.         foreach ($form->getErrors(true) ?? [] as $error) {
  198.             $logger->error("[Ошибка формы регистрации] "$error->getOrigin()->getName() . " - " $error->getMessage() . " - " current($error->getMessageParameters()));
  199.         }
  200.         return $this->render('area/notary/forms/registry.html.twig', [
  201.             'client' => $notary,
  202.             'form'   => $form->createView(),
  203.         ]);
  204.     }
  205.     /**
  206.      * @Route("/services-client", name="publicServicesListClient")
  207.      */
  208.     public function servicesListClient(
  209.         ServiceFormRepository $serviceFormRepository,
  210.         ServiceSectionRepository $serviceSectionRepository,
  211.     ): Response
  212.     {
  213.         $sections $serviceSectionRepository->getList();
  214.         $serviceForms $serviceFormRepository->getFormsList();
  215.         foreach ($serviceForms as $form) {
  216.             $sectionId $form->getServiceSection()->getId();
  217.             $sections[$sectionId]['forms'][] = $form;
  218.         }
  219.         return $this->render('publicPages/servicesList.html.twig', [
  220.             'controller_name' => 'Услуги',
  221.             'isClientPage'    => true,
  222.             'sections'        => $sections,
  223.         ]);
  224.     }
  225.     /**
  226.      * @Route("/services", name="publicServicesList")
  227.      */
  228.     public function servicesList(
  229.         ServiceFormRepository $serviceFormRepository,
  230.         ServiceSectionRepository $serviceSectionRepository,
  231.     ): Response
  232.     {
  233.         $sections $serviceSectionRepository->getList();
  234.         $serviceForms $serviceFormRepository->getFormsList();
  235.         foreach ($serviceForms as $form) {
  236.             $sectionId $form->getServiceSection()?->getId();
  237.             if(!$sectionId) {
  238.                 continue;
  239.             }
  240.             $sections[$sectionId]['forms'][] = $form;
  241.         }
  242.         return $this->render('publicPages/servicesList.html.twig', [
  243.             'controller_name' => 'Услуги',
  244.             'isClientPage'    => false,
  245.             'sections'        => $sections,
  246.         ]);
  247.     }
  248.     /**
  249.      * @Route("/our-contacts",
  250.      *     host="%public_form_domain%",
  251.      *     name="publicContactsOldLogo")
  252.      */
  253.     public function publicContactsOldLogo()
  254.     {
  255.         return $this->render('publicPages/contactsOldLogo.html.twig', [
  256.             'controller_name' => 'Контакты',
  257.         ]);
  258.     }
  259.     /**
  260.      * Успешная оплата на стороне банка
  261.      *
  262.      * @Route("/pay-public/payment-success", name="successPaymentPublicOld")
  263.      */
  264.     public function successPaymentPublicOld(Request $requestMerchantTransactionInterface $merchantService): Response
  265.     {
  266.         $transactionUuid $request->query->get('trans');
  267.         $isSuccess $merchantService->successOrderByTransactionUuid($transactionUuid'successPaymentPublicOld'$this->isGranted('ROLE_WORKER'), true);
  268.         return $this->render('publicPages/old/pays/payResult.html.twig', [
  269.             'controller_name' => 'Заказ оплачен',
  270.             'message'         => $isSuccess
  271.         ]);
  272.     }
  273.     /**
  274.      * @Route("/pay-public/payment-success-callback", name="paymentSuccessCallback")
  275.      */
  276.     public function paymentSuccessCallback(
  277.         Request $request,
  278.         MerchantTransactionInterface $merchantService,
  279.         MerchantBalanceServiceInterface $merchantBalanceService,
  280.     ): Response
  281.     {
  282.         // todo нужна проверка ip адреса
  283.         $requestData json_decode($request->getContent(), true);
  284.         if ($requestData['event'] !== 'payment.succeeded') {
  285.             return new Response(sprintf('Event %s not supported'$requestData['event']), 400);
  286.         }
  287.         if (array_key_exists('transaction_uuid'$requestData['object']['metadata'])) {
  288.             $merchantService->successOrderByTransactionUuid(
  289.                 $requestData['object']['metadata']['transaction_uuid'],
  290.                 'paymentSuccessCallback',
  291.                 isWorker$this->isGranted('ROLE_WORKER'),
  292.                 isPublicFormtrue,
  293.                 skipStatusReChecktrue,
  294.             );
  295.             return new Response();
  296.         }
  297.         if (array_key_exists('operation_uuid'$requestData['object']['metadata'])) {
  298.             $merchantBalanceService->successTopUp(
  299.                 $requestData['object']['metadata']['operation_uuid'],
  300.                 skipStatusReChecktrue,
  301.             );
  302.             return new Response();
  303.         }
  304.         if (array_key_exists('trans'$requestData)) {
  305.             $merchantService->successOrderByTransactionUuid(
  306.                 $requestData['trans'],
  307.                 'paymentSuccessCallback',
  308.                 isWorker$this->isGranted('ROLE_WORKER'),
  309.                 isPublicFormtrue,
  310.                 skipStatusReChecktrue,
  311.             );
  312.             return new Response();
  313.         }
  314.         return new Response('Not supported object type'400);
  315.     }
  316.     #[Route(path:"/our-contacts"name:"publicOurContacts")]
  317.     #[Route(path:"/contacts"name:"publicContacts")]
  318.     public function publicContacts()
  319.     {
  320.         return $this->render('publicPages/contacts.html.twig', [
  321.             'controller_name' => 'Контакты',
  322.             'hideSpb'         => false
  323.         ]);
  324.     }
  325.     #[Route(path:"/about"name:"publicAbout")]
  326.     public function publicAbout(Request $request): Response
  327.     {
  328.         $form $this->createForm(RequestConsultationType::class);
  329.         $form->handleRequest($request);
  330.         if ($form->isSubmitted() && $form->isValid()) {
  331.         }
  332.         return $this->render('publicPages/about.html.twig', [
  333.             'controller_name'         => 'О компании',
  334.             'requestConsultationForm' => $form->createView(),
  335.         ]);
  336.     }
  337.     /**
  338.      * Загрузить файл из директории documents/common
  339.      *
  340.      * @Route("/downloadCommonFile/{filename}", name="downloadCommonFile")
  341.      *
  342.      * @param string $filename
  343.      * @return Response
  344.      */
  345.     public function downloadCommonFile(string $filename)
  346.     {
  347.         return $this->getFileResponse($filename'common/');
  348.     }
  349.     /**
  350.      * Посмотреть файл из директории documents/common
  351.      *
  352.      * @Route("/public-docs/{filename}", name="seeCommonFile")
  353.      *
  354.      * @param string $filename
  355.      * @return Response
  356.      */
  357.     public function seeCommonFile(string $filename)
  358.     {
  359.         return $this->redirect('/documents/' 'common/' $filename);
  360.     }
  361.     /**
  362.      * @Route("/send-phone", name="sendPhoneFromLandingPage")
  363.      */
  364.     public function sendPhoneFromLandingPage(Request $requestEmailCallbackService $callbackService): JsonResponse
  365.     {
  366.         $messageText $request->get('phone'null);
  367.         if (!$messageText) {
  368.             return new JsonResponse();
  369.         }
  370.         try {
  371.             $callbackService->sendCallback($messageText);
  372.         } catch (TooOftenSendingException $e) {
  373.             return $this->response(['error' => $e->getMessage()], 400);
  374.         }
  375.         return $this->response(['success' => 'Мы скоро свяжемся с вами!'], 200);
  376.     }
  377.     /**
  378.      * @Route("/welcome", name="welcome")
  379.      *
  380.      * @param ServiceSectionGroupRepository $serviceSectionGroupRepository
  381.      * @param Request                       $request
  382.      * @param EntityManagerInterface        $entityManager
  383.      * @param UserPasswordHasherInterface   $passwordEncoder
  384.      * @param LoginFormAuthenticator        $login
  385.      * @param UserAuthenticatorInterface    $authenticator
  386.      * @param ServiceFormRepository         $serviceFormRepository
  387.      * @return RedirectResponse|Response
  388.      * @throws \Exception
  389.      */
  390.     public function welcome(ServiceSectionGroupRepository $serviceSectionGroupRepository,
  391.                             Request $request,
  392.                             EntityManagerInterface $entityManager,
  393.                             UserPasswordHasherInterface $passwordEncoder,
  394.                             LoginFormAuthenticator $login,
  395.                             UserAuthenticatorInterface $authenticator,
  396.                             ServiceFormRepository $serviceFormRepository
  397.     )
  398.     {
  399.         $notary = new Notary();
  400.         $form $this->createForm(NotaryType::class, $notary);
  401.         $form->remove('payLinkReferralEnabled');
  402.         $form->handleRequest($request);
  403.         $groupsWithSections $serviceSectionGroupRepository->getList();
  404.         $services = [];
  405.         foreach ($serviceFormRepository->findAll() ?: [] as $service) {
  406.             /**
  407.              * @var ServiceForm $service
  408.              */
  409.             $services[$service->getId()] = $service;
  410.         }
  411.         /**
  412.          * @var array<int, mixed> $groupsWithSections
  413.          */
  414.         foreach ($groupsWithSections as $key => &$group) {
  415.             foreach ($group['sections'] as $sectionKey => &$section) {
  416.                 foreach ($section['serviceForms'] ?? [] as $serviceForm) {
  417.                     if($services[$serviceForm['id']]->getIcon() === 'paper-copy') {
  418.                         //Отдельно отчет
  419.                         $paperCopy $services[$serviceForm['id']];
  420.                         continue;
  421.                     }
  422.                     $groupsWithSections[$key]['sections'][$sectionKey]['forms'][] = $services[$serviceForm['id']];
  423.                 }
  424.             }
  425.             $group['sections'] = array_reverse($group['sections']);
  426.         }
  427.         if ($form->isSubmitted() && $form->isValid()) {
  428.             $plainPassword $notary->getPassword();
  429.             if (!$plainPassword) {
  430.                 $plainPassword $data['password'] = substr(sha1(random_bytes(10)), 010);
  431.             }
  432.             $notary->setPassword(
  433.                 $passwordEncoder->hashPassword($notary$plainPassword)
  434.             );
  435.             $notary->setRoles(['ROLE_NOTARY']);
  436.             $notary->setMoneyBalance(0);
  437.             $notary->setBonusBalance(0);
  438.             $notary->setRegistrationDateTime(new \DateTimeImmutable());
  439.             $notary->setUndrawableBonusBalance(Notary::START_BONUS_BALANCE);
  440.             $notary->setNotaryNumber('');
  441.             $entityManager->persist($notary);
  442.             $entityManager->flush();
  443.             $this->dispatchMessage(new NotaryRegisterMessage($notary));
  444.             return $authenticator->authenticateUser($notary$login$request);
  445.         }
  446.         return $this->render('publicPages/notaryLandingPage.html.twig', [
  447.             'controller_name' => 'Регистрация партнера',
  448.             'client'          => $notary,
  449.             'form'            => $form->createView(),
  450.             'group'           => $groupsWithSections[0],
  451.             'paperCopy'       => $paperCopy,
  452.             'is_login'        => true,
  453.         ]);
  454.     }
  455.     /**
  456.      * @Route("/welcome-client", name="welcomeForCLients")
  457.      *
  458.      * @param Request $request
  459.      * @param EntityManagerInterface $entityManager
  460.      * @param UserPasswordHasherInterface $passwordEncoder
  461.      * @param LoginFormAuthenticator $login
  462.      * @param UserAuthenticatorInterface $authenticator
  463.      * @param CheckEmailService $checkEmailService
  464.      * @param NotaryCodeService $codeService
  465.      * @param NotaryRepository $notaryRepository
  466.      * @return Response|null
  467.      * @throws \Exception
  468.      */
  469.     public function welcomeForCLients(Request $request,
  470.                                       EntityManagerInterface $entityManager,
  471.                                       UserPasswordHasherInterface $passwordEncoder,
  472.                                       LoginFormAuthenticator $login,
  473.                                       UserAuthenticatorInterface $authenticator,
  474.                                       CheckEmailService $checkEmailService,
  475.                                       NotaryCodeService $codeService,
  476.                                       NotaryRepository $notaryRepository
  477.     )
  478.     {
  479.         //Закрыт ЛК ФЛ
  480.         throw $this->createNotFoundException('Страница не найдена');
  481.         $client = new Client();
  482.         $form $this->createForm(ClientType::class, $client);
  483.         $form->remove('notaryCode');
  484.         $newEmail $request->request->get('client') ? $request->request->get('client')['email'] : null;
  485.         if ($newEmail) {
  486.             if ($checkEmailService->isEmailFree(0$newEmail)) {
  487.                 $form->handleRequest($request);
  488.             } else {
  489.                 $form->get('email')->addError(new FormError('Нельзя использовать этот адрес электронной почты '));
  490.             }
  491.         }
  492.         if ($form->isSubmitted() && $form->isValid()) {
  493. //            if ($notaryCode = $form->get('notaryCode')->getData()) {
  494. //                if ($notaryId = $codeService->getNotaryCodeFromString($notaryCode)) {
  495. //                    if ($notary = $notaryRepository->find($notaryId)) {
  496. //                        $client->setNotary($notary);
  497. //                    }
  498. //                }
  499. //            }
  500.             $plainPassword $client->getPassword();
  501.             if (!$plainPassword) {
  502.                 $plainPassword $data['password'] = substr(sha1(random_bytes(10)), 010);
  503.             }
  504. //            $client->setPassword(
  505. //                $passwordEncoder->hashPassword($client, $plainPassword)
  506. //            );
  507. //
  508. //            $client->setRoles(['ROLE_CLIENT']);
  509.             $entityManager->persist($client);
  510.             $entityManager->flush();
  511.             return $authenticator->authenticateUser($client$login$request);
  512.         }
  513.         return $this->render('publicPages/newRegistrationClient.html.twig', [
  514.             'client' => $client,
  515.             'form'   => $form->createView(),
  516.         ]);
  517.     }
  518.     /**
  519.      * Загрузить файл из директории documents
  520.      *
  521.      * @Route("/download/{filename}/{orderId}", name="downloadFile")
  522.      *
  523.      * @param string $filename
  524.      * @param int|null $orderId
  525.      * @return Response
  526.      */
  527.     public function downloadFile(string $filenameint $orderId null)
  528.     {
  529.         return $this->getFileResponse($filename);
  530.     }
  531.     /**
  532.      * Обновить статус просмотра заказа
  533.      *
  534.      * @Route("/setOrderViewed", name="setOrderViewed")
  535.      *
  536.      * @param Request $request
  537.      * @return Response
  538.      */
  539.     public function setOrderViewed(Request $request)
  540.     {
  541.         return $this->json($this->clientService->updateViewedStatusByOrderId($request->get('orderId')));
  542.     }
  543.     /**
  544.      * Обновить статус просмотра заказа
  545.      *
  546.      * @Route("/setClientViewed", name="setClientViewed")
  547.      *
  548.      * @param Request $request
  549.      * @return Response
  550.      */
  551.     public function setClientViewed(Request $request)
  552.     {
  553.         return $this->json($this->clientService->updateClientViewedStatus($request->get('clientId')));
  554.     }
  555.     /**
  556.      * Публичная страница для оплаты по ссылке
  557.      *
  558.      * @Route("/p/{orderId}", name="publicPay")
  559.      * @param int             $orderId
  560.      * @param OrderRepository $orderRepository
  561.      * @return Response
  562.      */
  563.     public function publicPay(int $orderIdOrderRepository $orderRepository): Response
  564.     {
  565.         $order $orderRepository->find($orderId);
  566.         if (!$order) {
  567.             throw $this->createNotFoundException('Ссылка на заказ не найдена');
  568.         }
  569.         if ($order->getStatus() === Order::STATUS_DRAFT) {
  570.             throw $this->createNotFoundException('Ссылка на заказ не найдена');
  571.         }
  572.         if ($order->getStatus() !== Order::STATUS_NEW) {
  573.             return $this->redirectToRoute('publicForm', ['id' => $orderId]);
  574.         }
  575.         return $this->render('publicPages/pays/payOrder.html.twig', [
  576.             'controller_name' => 'Оплата заказа №' $order->getId() . ' - ' $order->getOrderName(),
  577.             'order'           => $order,
  578.         ]);
  579.     }
  580.     /**
  581.      * Ссылка для создания платежа в банк
  582.      *
  583.      * @Route("/pay/createPayment/{id}", name="createPaymentPublic")
  584.      */
  585.     public function createPaymentPublic(
  586.         int $id,
  587.         Request $request,
  588.         MerchantPaymentInterface $merchantService,
  589.         OrderRepository $orderRepository,
  590.     ): Response
  591.     {
  592.         $order $orderRepository->find($id);
  593.         if (!$order) {
  594.             return $this->render('publicPages/pays/payResult.html.twig', [
  595.                 'controller_name' => 'Заказ не существует',
  596.                 'message'         => 'Запрашиваемый заказ не существует',
  597.             ]);
  598.         }
  599.         if ($order->isStatusPaid()) {
  600.             return $this->render('publicPages/pays/payResult.html.twig', [
  601.                 'controller_name' => 'Заказ оплачен',
  602.                 'message'         => 'Оплата завершена' "Мы приступили к выполнению вашего заказа №{$order->getId()} «{$order->getOrderName()}»",
  603.             ]);
  604.         }
  605.         $successLink $this->generateUrl('successPaymentPublic', [], UrlGeneratorInterface::ABSOLUTE_URL);
  606.         try {
  607.             $client $order->getRealClient();
  608.             if(!$client) {
  609.                 throw new \LogicException("В заказе #{$id} не заполнен клиент");
  610.             }
  611.             if(!$client instanceof \App\Entity\Client && !$client instanceof \App\Entity\Client\Client2) {
  612.                 throw new \LogicException("В заказе #{$id} указан клиент не известного типа");
  613.             }
  614.             $payment $merchantService->createPayment(
  615.                 shopHostShopHost::fromString($request->getHost()),
  616.                 order$order,
  617.                 returnUrl$successLink,
  618.                 payer$client,
  619.             );
  620.         } catch (MerchantException $e) {
  621.             return $this->render('publicPages/pays/payResult.html.twig', [
  622.                 'controller_name' => 'Произошла ошибка',
  623.                 'message'         => 'Попробуйте позже',
  624.             ]);
  625.         }
  626.         return $this->redirect($payment->confirmationUrl);
  627.     }
  628.     /**
  629.      * Успешная оплата на стороне банка
  630.      *
  631.      * @Route("/pay/payment-success", name="successPaymentPublic")
  632.      */
  633.     public function successPayment(
  634.         Request $request,
  635.         MerchantTransactionInterface $merchantService,
  636.     ): Response
  637.     {
  638.         $transactionUuid $request->query->get('trans');
  639.         $isSuccess $merchantService->successOrderByTransactionUuid($transactionUuid'successPaymentPublic'$this->isGranted('ROLE_WORKER'), true);
  640.         return $this->render('publicPages/pays/payResult.html.twig', [
  641.             'controller_name' => 'Заказ оплачен',
  642.             'message'         => $isSuccess 'Оплата завершена' 'Возникла проблема, попробуйте еще раз',
  643.         ]);
  644.     }
  645.     /**
  646.      * @Route("/area/partner/successBalanceOperation", name="area_notary_successBalanceOperation")
  647.      */
  648.     public function successBalanceOperation(Request $requestMerchantBalanceServiceInterface $merchantBalanceService): Response
  649.     {
  650.         $balanceOperationUuid $request->query->get('trans');
  651.         if (!$balanceOperationUuid) {
  652.             return $this->redirectToRoute('paymentCompletedPage');
  653.         }
  654.         $isSuccess $merchantBalanceService->successTopUp($balanceOperationUuid);
  655.         if (!$this->isGranted('ROLE_NOTARY')) {
  656.             return $this->redirectToRoute('paymentCompletedPage');
  657.         }
  658.         return $this->render('area/notary/successPayment.html.twig', [
  659.             'controller_name' => 'Баланс увеличен',
  660.             'message'         => $isSuccess 'Пополнение баланса завершено' 'Возникла проблема, попробуйте еще раз',
  661.         ]);
  662.     }
  663.     /**
  664.      * Пустышка для редиректа если человек вышел
  665.      *
  666.      * @Route("/payment-completed", name="paymentCompletedPage")
  667.      *
  668.      * @return Response
  669.      */
  670.     public function paymentCompletedPage(): Response
  671.     {
  672.         return $this->render('publicPages/pays/payResult.html.twig', [
  673.             'controller_name' => 'Заказ оплачен',
  674.             'message'         => 'Оплата завершена',
  675.         ]);
  676.     }
  677.     /**
  678.      * @Route("/pf/{id}", name="publicForm")
  679.      */
  680.     public function publicForm(
  681.         Order                 $order,
  682.         ServiceFormRepository $serviceFormRepository,
  683.         PaperCopyService      $paperCopyService,
  684.         ServiceFormPipeline   $serviceFormPipeline,
  685.     ): RedirectResponse|Response
  686.     {
  687.         if ($order->getClient2()) {
  688.             return $this->redirectToRoute('public_order_form', ['id' => $order->getId()]);
  689.         }
  690.         if ($order->getStatus_() !== OrderStatus::Draft) {
  691.             if ($order->getWhoPay() === 'client' && $order->getStatus_()->value === OrderStatus::New->value) {
  692.                 return $this->redirectToRoute('publicPay', ['orderId' => $order->getId()]);
  693.             }
  694.             return $this->render('publicPages/order_not_draft.html.twig', [
  695.                 'order_id' => $order->getId(),
  696.                 'order_status_name' => Order::API_STATUS_NAMES[$order->getStatus_()->value],
  697.             ]);
  698.         }
  699.         if ($order->isTranslation()) {
  700.             return $this->render('publicPages/translation/form.html.twig', ['id' => $order->getId()]);
  701.         }
  702.         $createClientForm $this->createForm(NotaryClientType::class, new Client());
  703.         // Используем пайплайн для обработки формы
  704.         $context = new ServiceFormContext(order$ordernotary$order->getNotary());
  705.         $form $serviceFormPipeline->process($order->getServiceFormId(), $context);
  706.         // Формируем overForm из данных заказа для фронта
  707.         $overForm array_reduce($order->getData(), function (array $carry, array $datum) {
  708.             if (!empty($datum['value'])) {
  709.                 $carry[] = ['name' => $datum['name'], 'value' => $datum['value']];
  710.             }
  711.             return $carry;
  712.         }, []);
  713.         $data = [
  714.             'controller_name'  => $form->getName(),
  715.             'form'             => $form,
  716.             'order'            => $order,
  717.             'clients'          => [],
  718.             'createClientForm' => $createClientForm->createView(),
  719.             'overForm'         => $overForm,
  720.             'pffSaveUrl'       => false,
  721.         ];
  722.         if (!$paperCopyService->isPaperCopy($form->getId())) {
  723.             $data['paperCopyPrice'] = $paperCopyService->getPaperCopyPriceCached();
  724.         }
  725.         $data['assessmentTypes'] = FormAssessmentType::getViewFormSelect($form);
  726.         $data['assessmentTypeHelpTexts'] = FormAssessmentType::getViewHelpText($form->getBitrixCategoryId());
  727.         return $this->render('publicPages/forms/form.html.twig'$data);
  728.     }
  729.     /**
  730.      * @Route("/pff/{id}", name="publicOnlyFilesForm")
  731.      * @param int $id
  732.      * @param OrderRepository $orderRepository
  733.      * @param ServiceFormRepository $serviceFormRepository
  734.      * @param PaperCopyService $paperCopyService
  735.      * @return Response
  736.      */
  737.     public function publicOnlyFilesForm(int                   $id,
  738.                                         OrderRepository       $orderRepository,
  739.                                         ServiceFormRepository $serviceFormRepository,
  740.                                         PaperCopyService      $paperCopyService,
  741.     ): Response
  742.     {
  743.         $order $orderRepository->find($id);
  744.         if ($order->getStatus() >= Order::STATUS_PAID) {
  745.             return $this->render('publicPages/forms/orderStatus.html.twig', ['order' => $order]);
  746.         }
  747.         if ($order->isTranslation()) {
  748.             return $this->render('publicPages/translation/form.html.twig', ['id' => $id]);
  749.         }
  750.         $form $serviceFormRepository->find($order->getServiceFormId());
  751.         $createClientForm $this->createForm(NotaryClientType::class, new Client());
  752.         if ($order->getRealClient()?->getPartner()?->getIsVip() && $form->getVipPrice()) {
  753.             $form->setPrice($form->getVipPrice());
  754.         }
  755.         if ($order->getRealClient()?->getPartner()?->getPayLinkReferralEnabled() && !$form->isSelfPaperForm()) {
  756.             $form->setPrice($form->getPrice() + OrderSaveManager::PUBLIC_FORM_MARGIN);
  757.         }
  758.         $fields $form->getFields();
  759.         $fields['existsOrderId'] = $order->getId();
  760.         //Удаляем все поля кроме полей с файлами
  761.         foreach ($fields['tabs'] ?? [] as $tabKey => $tab) {
  762.             if ($tab['title'] !== 'Загрузка файлов') {
  763.                 unset($fields['tabs'][$tabKey]);
  764.             }
  765.             //Удаление заполненных полей
  766.             foreach ($tab['fields'] as $fieldKey => $field) {
  767.                 if (
  768.                     !empty($order->getFieldByName($field['id'])) &&
  769.                     $order->getFieldByName($field['id']) !== '[]'
  770.                 ) {
  771.                     unset($fields['tabs'][$tabKey]['fields'][$fieldKey]);
  772.                 }
  773.             }
  774.         }
  775.         $form->setFields($fields);
  776.         $overForm = [];
  777.         if ($order->getFormAssessmentType() == FormAssessmentType::FOR_INHERITANCE->value) {
  778.             if ($placeOpen $order->getFieldByName('place-open')) {
  779.                 $form->setValueToFields('place-open'$placeOpen);
  780.             }
  781.             if ($testatorFIO $order->getFieldByName('testatorFIO')) {
  782.                 $form->setValueToFields('testatorFIO'$testatorFIO);
  783.             }
  784.             if ($deathDateTestator $order->getFieldByName('deathDateTestator')) {
  785.                 $form->setValueToFields('deathDateTestator'$deathDateTestator);
  786.             }
  787.             if ($numberDeathCertificate $order->getFieldByName('numberDeathCertificate')) {
  788.                 $form->setValueToFields('numberDeathCertificate'$numberDeathCertificate);
  789.             }
  790.         } else {
  791.             // Удалять поля из других видов оценок:
  792.             $form->unSetFieldByName('testatorFIO');
  793.             $form->unSetFieldByName('deathDateTestator');
  794.             $form->unSetFieldByName('numberDeathCertificate');
  795.             if ($formAssessmentType $order->getFieldByName('formAssessmentType')) {
  796.                 $overForm[] = ['name' => 'formAssessmentType''value' => $formAssessmentType];
  797.             }
  798.             if ($assessmentDate $order->getFieldByName('assessment-date')) {
  799.                 $overForm[] = ['name' => 'assessment-date''value' => $assessmentDate];
  800.             }
  801.             if ($ownerFullName $order->getFieldByName('owner-full-name')) {
  802.                 $overForm[] = ['name' => 'owner-full-name''value' => $ownerFullName];
  803.             }
  804.         }
  805.         $data = [
  806.             'controller_name'  => $form->getName(),
  807.             'form'             => $form,
  808.             'order'            => $order,
  809.             'clients'          => [],
  810.             'createClientForm' => $createClientForm->createView(),
  811.             'overForm'         => $overForm,
  812.             'pffSaveUrl'       => true,
  813.         ];
  814.         if (!$paperCopyService->isPaperCopy($form->getId())) {
  815.             $data['paperCopyPrice'] = $paperCopyService->getPaperCopyPriceCached();
  816.         }
  817.         return $this->render('publicPages/forms/form.html.twig'$data);
  818.     }
  819.     /**
  820.      * @Route("/public/vin-info", name="publicGetVinINFO")
  821.      */
  822.     public function publicGetVinINFO(
  823.         Request $request,
  824.         VinParserManager $vinParserManager,
  825.     ): JsonResponse
  826.     {
  827.         $result $vinParserManager->getData($request->get('typeParse''VIN'), $request->get('vin'));
  828.         return $this->response(['status' => 200'data' => $result]);
  829.     }
  830.     /**
  831.      * @param string $filename
  832.      * @param string $folder
  833.      * @return Response
  834.      */
  835.     private function getFileResponse(string $filenamestring $folder '')
  836.     {
  837.         if (!$this->security->isGranted('ROLE_USER')) {
  838.             return new Response('Access denied'403);
  839.         }
  840.         $path $this->parameterBag->get('kernel.project_dir') . "/public_html/documents/" $folder;
  841.         $content file_get_contents($path $filename);
  842.         $response = new Response();
  843.         //set headers
  844.         $response->headers->set('Content-Type''mime/type');
  845.         $response->headers->set('Content-Disposition''attachment;filename="' $filename);
  846.         $response->setContent($content);
  847.         return $response;
  848.     }
  849. }