src/Controller/EntrypointController.php line 330

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Certificate;
  4. use App\Entity\Order;
  5. use App\Entity\OrderItem;
  6. use App\Entity\Widget;
  7. use App\Entity\WidgetUser;
  8. use App\Helpers\TiberiumHelper;
  9. use App\Helpers\WidgetHelper;
  10. use App\Message\CharityMessage;
  11. use App\Message\GetCertificatesMessage;
  12. use App\Repository\OrderRepository;
  13. use App\Repository\WidgetRepository;
  14. use App\Request\WidgetOrderXlsRequest;
  15. use App\Request\WidgetUploadCoverRequest;
  16. use App\Services\BarcodeService;
  17. use App\Services\CertificateService;
  18. use App\Services\Contracts\CertificateServiceInterface;
  19. use App\Services\Contracts\FileServiceInterface;
  20. use App\Services\Contracts\CertificateCoverServiceInterface;
  21. use App\Services\Contracts\OrderServiceInterface;
  22. use App\Services\Contracts\WholesaleServiceInterface;
  23. use App\Services\LogService\BaseLogDataService;
  24. use App\Services\LogService\LogsService;
  25. use App\Services\WidgetInfoService;
  26. use App\Utils\Notification\OrderRemainderNotification;
  27. use App\Utils\Notification\PaymentRemainderNotification;
  28. use App\Utils\Notification\WidgetRemainderNotification;
  29. use App\Utils\Tiberium;
  30. use App\Utils\UploadedBase64File;
  31. use Doctrine\ORM\EntityManagerInterface;
  32. use Exception;
  33. use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
  34. use Knp\Snappy\Pdf;
  35. use Liip\ImagineBundle\Imagine\Cache\CacheManager;
  36. use Psr\Log\LoggerInterface;
  37. use Psr\Log\LogLevel;
  38. use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
  39. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  40. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  41. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  42. use Symfony\Component\HttpFoundation\File\UploadedFile;
  43. use Symfony\Component\HttpFoundation\JsonResponse;
  44. use Symfony\Component\HttpFoundation\Request;
  45. use Symfony\Component\HttpFoundation\RequestStack;
  46. use Symfony\Component\HttpFoundation\Response;
  47. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  48. use Symfony\Component\Messenger\MessageBusInterface;
  49. use Symfony\Component\Routing\Annotation\Route;
  50. use Symfony\Component\Validator\Validator\ValidatorInterface;
  51. use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
  52. use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
  53. use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
  54. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  55. use YooKassa\Client as YooKassaClient;
  56. use YooKassa\Common\Exceptions\ApiException;
  57. use YooKassa\Common\Exceptions\BadApiRequestException;
  58. use YooKassa\Common\Exceptions\ExtensionNotFoundException;
  59. use YooKassa\Common\Exceptions\ForbiddenException;
  60. use YooKassa\Common\Exceptions\InternalServerError;
  61. use YooKassa\Common\Exceptions\NotFoundException;
  62. use YooKassa\Common\Exceptions\ResponseProcessingException;
  63. use YooKassa\Common\Exceptions\TooManyRequestsException;
  64. use YooKassa\Common\Exceptions\UnauthorizedException;
  65. use YooKassa\Model\Notification\NotificationFactory;
  66. use YooKassa\Model\NotificationEventType;
  67. class EntrypointController extends AbstractController
  68. {
  69.     /**
  70.      * @param Request $request
  71.      * @param Pdf $pdf
  72.      * @param Certificate $certificate
  73.      * @param Tiberium $tiberium
  74.      * @param BaseLogDataService $dataService
  75.      * @param CertificateServiceInterface $certificateService
  76.      * @return Response
  77.      * @Route("/certificate/pdf/{id}", name="show_pdf_certificate")
  78.      */
  79.     public function showPdf(Request $requestPdf $pdfCertificate $certificateTiberium $tiberiumBaseLogDataService $dataServiceCertificateServiceInterface $certificateService)
  80.     {
  81.         $tiberium->setDsn($certificate->getOrderItem()->getWidgetOrder()->getWidget()->getOrderServiceDsn());
  82.         $orderItem $certificate->getOrderItem();
  83.         $nominal $certificate->getNominal();
  84.         $currency $certificate->getCurrency();
  85.         if (in_array(null,[$nominal$currency])) {
  86.             try {
  87.                 $productTiberiumData $tiberium->getProduct($orderItem->getProductId());
  88.                 $productData TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
  89.                 $productNominal TiberiumHelper::getProductNominalFromData($productData);
  90.                 $productPrice TiberiumHelper::getProductPriceFromData($productData);
  91.                 $nominal $productNominal['nominal'] ? $productNominal['nominal'] : $productPrice;
  92.                 $currency $productNominal['currency'] ? $productNominal['currency'] : 'руб.';
  93.             } catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
  94.             }
  95.         }
  96.         $certificate->setAmount($nominal);
  97.         $qr $certificateService->generateQrBase64($certificate);
  98.         $barcode $certificateService->generateBarcodeBase64($certificate);
  99.         $template $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getMailTemplate()->getFilename();
  100.         $widget $certificate->getOrderItem()->getWidgetOrder()->getWidget();
  101.         $usageRules WidgetHelper::convertUsageRulesToFrontend($widget);
  102.         $html $this->renderView('@templates/' basename($template) . '/certificate.html.twig', [
  103.             'certificate' => $certificate,
  104.             'usageRules' => $usageRules,
  105.             'iconsColor' => $widget->getIconsColor(),
  106.             'basename' => basename($template),
  107.             'public' => '/app/public/',
  108.             'currency' => $currency,
  109.             'qr' => $qr,
  110.             'backgroundImage' => $widget->getBackgroundImage(),
  111.             'user_files_dir' => $this->getParameter('app.user_files_dir')  . '/' hash('sha256'$certificate->getOrderItem()->getWidgetOrder()->getWidget()->getId()) . '/',
  112.             'barcode' => $barcode,
  113.         ]);
  114.         $disposition 'inline';
  115.         $logAction BaseLogDataService::PRINT_CERTIFICATE_NAME;
  116.         if ($request->query->get('download')) {
  117.             $disposition 'attachment';
  118.             $logAction BaseLogDataService::DOWNLOAD_CERTIFICATE_NAME;
  119.         }
  120.         $dataService->prepareBaseData(__CLASS____FUNCTION__$logActionLogLevel::INFOBaseLogDataService::TYPE_GOALsprintf("Action %s from Certificate: %s"$logAction$certificate->getId()->toString()));
  121.         $dataService->prepareDataFromRequest($request);
  122.         $dataService->prepareDataFromCertificate($certificate);
  123.         LogsService::sendLog($dataService->getMethodName(), $dataService->getData(), $dataService->getTypeStorageTime(), $dataService->getParams(),''$dataService->getClassShortName(), __FUNCTION__null);
  124.         return new PdfResponse($pdf->getOutputFromHtml($html),
  125.             $certificate->getId().'.pdf',
  126.             'application/pdf',
  127.             $disposition
  128.         );
  129.     }
  130.     /**
  131.      * @param Request $request
  132.      * @param Widget $widget
  133.      * @param Pdf $pdf
  134.      * @param Tiberium $tiberium
  135.      * @param CertificateServiceInterface $certificateService
  136.      * @return PdfResponse
  137.      * @throws Exception
  138.      */
  139.     #[Route('/widget/{id}/preview'name'certificate_preview'methods: ['GET'])]
  140.     public function showPreview(Request $requestWidget $widgetPdf $pdfTiberium $tiberiumCertificateServiceInterface $certificateService)
  141.     {
  142.         $tiberium->setDsn($widget->getOrderServiceDsn());
  143.         //$json = json_decode($request->getContent(), true);
  144.         $req = [
  145.             'template_id' => $request->get('template_id'),
  146.             'product_id' => $request->get('product_id'),
  147.         ];
  148.         $certificate = new Certificate();
  149.         $orderItem = new OrderItem();
  150.         $order = new Order();
  151.         $covers $widget->getCovers();
  152.         $cover $covers[$req['template_id'] ?? 0] ;
  153.         $orderItem->setCover($cover['file']);
  154.         $nominal 0;
  155.         $currency '';
  156.         try {
  157.             $productTiberiumData $tiberium->getProduct($req['product_id']);
  158.             $productData TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
  159.             $productNominal TiberiumHelper::getProductNominalFromData($productData);
  160.             $productPrice TiberiumHelper::getProductPriceFromData($productData);
  161.             $nominal $productNominal['nominal']?$productNominal['nominal']:$productPrice;
  162.             $currency $productNominal['currency']?$productNominal['currency']:'руб.';
  163.         } catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
  164.         }
  165.         $certificate->setAmount($nominal)
  166.             ->setCreatedAt(new \DateTimeImmutable())
  167.             ->setSerial('A1B2C3D4E5F6')
  168.             ->setExpireAt(new \DateTimeImmutable('+1 year'))
  169.             ->setPin('1234')
  170.             ->setNominal($nominal)
  171.             ;
  172.         $certificate->setOrderItem($orderItem);
  173.         $orderItem->setWidgetOrder($order);
  174.         $order->setWidget($widget);
  175.         $qr $certificateService->generateQrBase64($certificate);
  176.         $barcode $certificateService->generateBarcodeBase64($certificate);
  177.         $template $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getMailTemplate()->getFilename();
  178.         $html $this->renderView('@templates/' basename($template) . '/certificate.html.twig', [
  179.             'certificate' => $certificate,
  180.             'basename' => basename($template),
  181.             'public' => '/app/public/',
  182.             'currency' => $currency,
  183.             'qr' => $qr,
  184.             'user_files_dir' => $this->getParameter('app.user_files_dir')  . '/' hash('sha256'$certificate->getOrderItem()->getWidgetOrder()->getWidget()->getId()) . '/',
  185.             'barcode' => $barcode,
  186.         ]);
  187.         $disposition $request->query->get('download')?'attachment':'inline';
  188.         return new PdfResponse(
  189.             $pdf->getOutputFromHtml($html),
  190.             'preview_'.random_int(9999999999999999).'.pdf',
  191.             'application/pdf',
  192.             $disposition
  193.         );
  194.     }
  195.     /**
  196.      * @param Widget $widget
  197.      * @param Tiberium $tiberium
  198.      * @return Response
  199.      * @throws Exception
  200.      */
  201.     #[Route('/widget/{id}/products'name"products"methods: ['GET'])]
  202.     public function products(Widget $widgetTiberium $tiberium)
  203.     {
  204.         $tiberium->setDsn($widget->getOrderServiceDsn());
  205.         $products explode(','$widget->getProducts());
  206.         $productsJson = [];
  207.         foreach($products as $row){
  208.             $productData null;
  209.             try {
  210.                 $productData $tiberium->getProduct($row);
  211.             } catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
  212.                 continue;
  213.             }
  214.             $product TiberiumHelper::getProductFromTiberiumData($productData);
  215.             if (is_null($product)){
  216.                 continue;
  217.             }
  218.             $productsJson[$product['Id']] = [
  219.                 'Name' => $product['Name'],
  220.                 'InStock' => $product['InStock'],
  221.                 'Price' => $product['Price'],
  222.                 'Params' => $product['Params'],
  223.             ];
  224.         }
  225.         return $this->json($productsJson);
  226.     }
  227.     /**
  228.      * @param Request $request
  229.      * @param Widget $widget
  230.      */
  231.     #[Route("/order/notification/widget/{id}"name"create_order_notification"methods: ['POST'])]
  232.     public function createOrderNotification(Request $requestWidget $widgetOrderRemainderNotification $notification)
  233.     {
  234.         $notification->send(
  235.             $widget,
  236.             $request->toArray()['client'],
  237.             $request->toArray()['email'],
  238.             $request->toArray()['nominal'],
  239.             $request->toArray()['quantity'],
  240.             $request->toArray()['remainder']
  241.         );
  242.         return new JsonResponse(['status' => 'ok']);
  243.     }
  244.     /**
  245.      * @param Request $request
  246.      * @param Widget $widget
  247.      */
  248.     #[Route("/getTiberiumOrderStatus/{id}"name"get_tiberium_order_status"methods: ['GET'])]
  249.     public function getTiberiumOrderStatus(Request $requestTiberium $tiberium): Response
  250.     {
  251.         return new JsonResponse$tiberium->getOrderStatus($request->get('id')) );
  252.     }
  253.     /**
  254.      * @param Widget $widget
  255.      * @param Certificate $certificate
  256.      * @param RequestStack $requestStack
  257.      * @param BaseLogDataService $dataService
  258.      * @param CertificateServiceInterface $certificateService
  259.      * @return JsonResponse
  260.      * @Route("/{widget_id}/view/{id}", name="show_certificate", methods={"GET"})
  261.      * @ParamConverter("widget", options={"id" = "widget_id"})
  262.      */
  263.     public function showCertificate(Widget $widgetCertificate $certificateRequestStack $requestStackBaseLogDataService $dataServiceCertificateServiceInterface $certificateService): JsonResponse
  264.     {
  265.         $widget $certificate->getOrderItem()->getWidgetOrder()->getWidget();
  266.         $cover 'https://api.'.
  267.             str_replace('api.'''$certificate->getOrderItem()->getWidgetOrder()->getPaymentData()['metadata']['http_host']). '/' .
  268.             basename($this->getParameter('app.user_files_dir'))  . '/' hash('sha256'$certificate->getOrderItem()->getWidgetOrder()->getWidget()->getId()) . '/' .
  269.             basename($this->getParameter('app.cover_dir')) . '/' $certificate->getCoverPath();
  270.         $qr $certificateService->generateQrBase64($certificate);
  271.         $barcode $certificateService->generateBarcodeBase64($certificate);
  272.         $json = [
  273.             'id' => $certificate->getId(),
  274.             'serial' => $certificate->getSerial(),
  275.             'expire_at' => $certificate->getExpireAt(),
  276.             'amount' => $certificate->getAmount(),
  277.             'pin' => $certificate->getPin(),
  278.             'cover' => $cover,
  279.             'qr' => $qr,
  280.             'sender_name' => $certificate->getOrderItem()->getSenderName(),
  281.             'recipient_name' => $certificate->getOrderItem()->getRecipientName(),
  282.             'recipient_type' => $certificate->getOrderItem()->getRecipientType(),
  283.             'message' => $certificate->getOrderItem()->getMessage(),
  284.             'faq' => $widget->getFaq(),
  285.             'favicon' => 'https://api.widget2.mgc-loyalty.ru/' basename($this->getParameter('app.favicon_dir')) . '/' $widget->getFaviconImage(),
  286.             'support_email' => $widget->getSupportEmail(),
  287.             'support_msisdn' => $widget->getSupportTelNumber(),
  288.             'template' => $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getMailTemplate()->getName(),
  289.             'barcode' => $barcode,
  290.         ];
  291.         $logAction BaseLogDataService::VIEW_CERTIFICATE_NAME;
  292.         $dataService->prepareBaseData(__CLASS____FUNCTION__$logActionLogLevel::INFOBaseLogDataService::TYPE_GOALsprintf("Action %s from Certificate: %s"$logAction$certificate->getId()->toString()));
  293.         $dataService->prepareDataFromRequest($requestStack->getCurrentRequest());
  294.         $dataService->prepareDataFromCertificate($certificate);
  295.         LogsService::sendLog($dataService->getMethodName(), $dataService->getData(), $dataService->getTypeStorageTime(), $dataService->getParams(),''$dataService->getClassShortName(), __FUNCTION__null);
  296.         return $this->json($json);
  297.     }
  298.     /**
  299.      * @Route("/", name="entrypoint")
  300.      */
  301.     public function index(): Response
  302.     {
  303.         return $this->redirect('backend/orders/statistics');
  304.     }
  305.     /**
  306.      * @param Order $order
  307.      * @param WidgetUser $user
  308.      * @param MessageBusInterface $messageBus
  309.      * @return Response
  310.      * @IsGranted("ROLE_SUPERADMINISTRATOR")
  311.      * @Route("/pushmeto/{id}", name="push")
  312.      */
  313.     public function push(Order $orderEntityManagerInterface $entityManagerMessageBusInterface $messageBus)
  314.     {
  315.         $widgetUser $entityManager->getRepository('App\Entity\WidgetUser')->find($this->getUser());
  316.         $getCertificatesMessage = new GetCertificatesMessage($order);
  317.         $getCertificatesMessage->setClient($widgetUser);
  318.         $messageBus->dispatch($getCertificatesMessage);
  319.         return new Response('ok');
  320.     }
  321.     /**
  322.      * @param Order $order
  323.      * @param Tiberium $tiberium
  324.      * @param LoggerInterface $logger
  325.      * @return JsonResponse
  326.      * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
  327.      */
  328.     #[Route('/confirmator/{id}'name"confirmator"methods: ['GET'])]
  329.     public function confirmOrder(
  330.         Order $order,
  331.         Tiberium $tiberium,
  332.         LoggerInterface $logger,
  333.         PaymentRemainderNotification $notification
  334.     )
  335.     {
  336.         try {
  337.             $tiberium->setDsn($order->getWidget()->getOrderServiceDsn());
  338.             foreach ($order->getOrderItems() as $item) {
  339.                 $response $tiberium->confirmOrder($item->getTiberiumOrderId());
  340.                 $logger->info("response from Tiberium for MANUAL confirmOrder " $item->getTiberiumOrderId() . ' is : ' print_r($response));
  341.                 if (isset($response['Error']) && !empty($response['Error'])) {
  342.                     $notification->configure(
  343.                         $order->getWidget(),
  344.                         $order->getId(),
  345.                         $item->getTiberiumOrderId(),
  346.                         $response['Error']['ErrorMessage']
  347.                     );
  348.                     $notification->commit();
  349.                 }
  350.             }
  351.             return new JsonResponse(['status' => 'ok']);
  352.         } catch (Exception $error) {
  353.             foreach ($order->getOrderItems() as $item) {
  354.                 $notification->configure(
  355.                     $order->getWidget(),
  356.                     $order->getId(),
  357.                     $item->getTiberiumOrderId(),
  358.                     $error->getMessage()
  359.                 );
  360.                 $notification->commit();
  361.             }
  362.             return new JsonResponse(['status' => 'error''message' => $error->getMessage()]);
  363.         }
  364.     }
  365.     /**
  366.      * @param Request $request
  367.      * @param OrderRepository $orderRepository
  368.      * @param EntityManagerInterface $entityManager
  369.      * @param LoggerInterface $logger
  370.      * @param MessageBusInterface $messageBus
  371.      * @return Response
  372.      * @Route("/callback/yookassa", name="yookassa_callback")
  373.      */
  374.     public function YooKassaCallback(
  375.         Request                      $request,
  376.         OrderRepository              $orderRepository,
  377.         EntityManagerInterface       $entityManager,
  378.         MessageBusInterface          $messageBus,
  379.         Tiberium                     $tiberium,
  380.         LoggerInterface              $logger,
  381.         PaymentRemainderNotification $notification):Response
  382.     {
  383.         $msg json_decode($request->getContent(), true);
  384.         $factory = new NotificationFactory();
  385.         $notificationObject $factory->factory($msg);
  386.         $response $notificationObject->getObject();
  387.         $logger->info(sprintf('get callback from ykassa for order #%s'$response->getMetadata()['order_id']));
  388.         $logger->info('get callback from ykassa data:'json_encode($response));
  389.         if (in_array($notificationObject->getEvent(), [
  390.             NotificationEventType::PAYMENT_SUCCEEDED,
  391.             NotificationEventType::PAYMENT_CANCELED,
  392.         ])) {
  393.             $order_id $response->getMetadata()['order_id'];
  394.             $status $response->getStatus();
  395.             $order $orderRepository->findOneBy(['id' => $order_id]);
  396.             $tiberium->setDsn($order->getWidget()->getOrderServiceDsn());
  397.             if(null !== $order) {
  398.                 $order->setPaymentStatus($status);
  399.                 $entityManager->persist($order);
  400.                 $entityManager->flush();
  401.                 if($notificationObject->getEvent() === NotificationEventType::PAYMENT_SUCCEEDED) { // проверяем, благотворительность или нет
  402.                     // в случае если $response->getStatus() === canceled
  403.                     // $response->getPaymentMethod()->getType() 500 т.к. нет getPaymentMethod()
  404.                     $payment_type $response->getPaymentMethod()->getType();
  405.                     $payment_type_id = match ($payment_type) {
  406.                         'bank_card' => 1,
  407.                         'sbp' => 4,
  408.                         default => 3
  409.                     };
  410.                     $logger->info(sprintf('order id is %s and delivery type is %s'$order->getId(), $order->getWidget()->getDeliveryVariants()[0]));
  411.                     if($order->getWidget()->getDeliveryVariants()[0] == 'Charity') {
  412.                         $message = new CharityMessage($order->getId());
  413.                     } else {
  414.                         $message = new GetCertificatesMessage($order);
  415.                         foreach ($order->getOrderItems() as $item) {
  416.                             $logger->info(sprintf('send confirmOrder to Tiberium for order 'print_r($responsetrue)));
  417.                             $response $tiberium->confirmOrder($item->getTiberiumOrderId());
  418.                             $logger->info("response from Tiberium for confirmOrder " $item->getTiberiumOrderId() . ' is : ' print_r($responsetrue));
  419.                             if (isset($response['Error']) && !empty($response['Error'])) {
  420.                                 $notification->configure(
  421.                                     $order->getWidget(),
  422.                                     $order->getId(),
  423.                                     $item->getTiberiumOrderId(),
  424.                                     $response['Error']['ErrorMessage']
  425.                                 );
  426.                                 $notification->commit();
  427.                             }else{
  428.                                 $data_payment = [[
  429.                                     'PaymentMethod' => [
  430.                                         'PaymentMethodID' => $payment_type_id,
  431.                                         'Sum' => $item->getAmount()
  432.                                     ]
  433.                                 ]];
  434.                                 $tiberium->setPaymentMethod($item->getTiberiumOrderId(), $data_payment);
  435.                             }
  436.                         }
  437.                     }
  438.                     $messageBus->dispatch($message);
  439.                 }
  440.             }
  441.             return new Response('ok');
  442.         }
  443.         return new Response('not found'404);
  444.     }
  445.     /**
  446.      * @param Request $request
  447.      * @param Widget $widget
  448.      * @param Tiberium $tiberium
  449.      * @param YooKassaClient $ykclient
  450.      * @param EntityManagerInterface $entityManager
  451.      * @param LoggerInterface $logger
  452.      * @param CertificateCoverServiceInterface $coverService
  453.      * @return JsonResponse|Response
  454.      * @throws TransportExceptionInterface
  455.      * @throws ApiException
  456.      * @throws BadApiRequestException
  457.      * @throws ExtensionNotFoundException
  458.      * @throws ForbiddenException
  459.      * @throws InternalServerError
  460.      * @throws NotFoundException
  461.      * @throws ResponseProcessingException
  462.      * @throws TooManyRequestsException
  463.      * @throws UnauthorizedException
  464.      * @Route("/widget/{id}/order", name="make_order", methods={"POST"})
  465.      */
  466.     public function order(
  467.         Request                $request,
  468.         Widget                 $widget,
  469.         Tiberium               $tiberium,
  470.         YooKassaClient         $ykclient,
  471.         EntityManagerInterface $entityManager,
  472.         LoggerInterface        $logger,
  473.         CertificateCoverServiceInterface $coverService,
  474.         OrderServiceInterface $orderService,
  475.     )
  476.     {
  477.         $tiberium->setDsn($widget->getOrderServiceDsn());
  478.         $ykassaDsn = [];
  479.         preg_match('/(.*):(.*)/'$widget->getYkassaDsn(), $ykassaDsn);
  480.         if(sizeof($ykassaDsn) === 3) {
  481.             $ykclient->setAuth($ykassaDsn[1], $ykassaDsn[2]);
  482.         }
  483.         $logger->info('REQUEST FROM FRONTEND: ' $request->getContent());
  484.         $orderItems json_decode($request->getContent(), true);
  485.         $orderType $orderService->getTypeFromCreateOrderData($orderItems);
  486.         $order = new Order();
  487.         $order->setWidget($widget)
  488.             ->setCreatedAt(new \DateTimeImmutable())
  489.             ->setPaymentStatus('created')
  490.             ->setUpdatedAt(new \DateTimeImmutable())
  491.             ->setType($orderType)
  492.         ;
  493.         $entityManager->persist($order);
  494.         $amount 0;
  495.         foreach ($orderItems as $item) {
  496.             $cover $coverService->getCoverFromCreateOrderItemData($item$widget);
  497.             if (null === $cover) {
  498.                 return new JsonResponse(['status' => 'error''message' => 'Invalid cover id']);
  499.             }
  500.             $products array_map(function ($el) {
  501.                 return trim($el);
  502.             }, explode(','$widget->getProducts()));
  503.             if (!in_array($item['certificate']['product']['product_id'], $products) && 'Charity' != $widget->getDeliveryVariants()[0]) {
  504.                 return new JsonResponse(['status' => 'error''message' => 'Invalid product id']);
  505.             }
  506.             $orderItem = new OrderItem();
  507.             $last_id round(microtime(true)*1000);
  508.             $logger->info(sprintf('Widget with id %s delivery variant 0 is: %s'$widget->getId(), $widget->getDeliveryVariants()[0]));
  509.             if('Charity' == $widget->getDeliveryVariants()[0]) {
  510.                 $amount $item['certificate']['product']['amount'];
  511.             } else {
  512.                 $logger->info("getting the product id " print_r($orderItem->getProductId(), true));
  513.                 try {
  514.                     $productTiberiumData $tiberium->getProduct($item['certificate']['product']['product_id']);
  515.                 } catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
  516.                     continue;
  517.                 }
  518.                 $productData TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
  519.                 if (is_null($productData)){
  520.                     continue;
  521.                 }
  522.                 $productPrice TiberiumHelper::getProductPriceFromData($productData);
  523.                 $amount $productPrice;
  524.             }
  525.             $orderItem
  526.                 ->setWidgetOrder($order)
  527.                 ->setTiberiumOrderId($last_id)
  528.                 ->setCover($cover)
  529.                 ->setMessage($item['certificate']['message'] ?? null)
  530.                 ->setBasketKey($item['certificate']['basket_key'])
  531.                 ->setProductId($item['certificate']['product']['product_id'])
  532.                 ->setQuantity($item['certificate']['product']['quantity'] ?? 1)
  533.                 ->setDeliveryType($item['certificate']['delivery_type'] ?? 'Email')
  534.                 ->setRecipientType($item['recipient']['type'] ?? 'me')
  535.                 ->setRecipientName(strtolower($item['recipient']['name'] ?? 'no name'))
  536.                 ->setRecipientEmail($item['recipient']['email'] ?? $item['sender']['email'] ?? 'no-email@dev.null')
  537.                 ->setRecipientMsisdn($item['recipient']['msisdn'] ?? '+70000000000')
  538.                 ->setAmount($amount)
  539.                 ->setSenderEmail($item['sender']['email'] ?? $orderItem->getRecipientEmail())
  540.                 ->setSenderName($item['sender']['name'] ?? $orderItem->getRecipientName())
  541.                 ->setUtm($item['utm'] ?? null)
  542.             ;
  543.             $logger->info("FRONTEND decoded are " json_encode($item));
  544.             $orderItem->setTimeToSend(isset($item['time_to_send']) ? (new \DateTimeImmutable($item['time_to_send']))->setTimezone(new \DateTimeZone('Europe/Moscow')) : new \DateTimeImmutable());
  545.             $entityManager->persist($orderItem);
  546.             $order->addOrderItem($orderItem);
  547.             $entityManager->flush();
  548.         }
  549.         if('Charity' != $widget->getDeliveryVariants()[0]) {
  550.             $amount 0;
  551.             foreach ($order->getOrderItems() as $orderItem) {
  552.                 $basket = [];
  553.                 $basket[] = [
  554.                     'id' => $orderItem->getProductId(),
  555.                     'quantity' => $orderItem->getQuantity(),
  556.                 ];
  557.                 $logger->info(sprintf('basket is %s'print_r($baskettrue)));
  558.                 $price $orderItem->getAmount();
  559.                 $entityManager->persist($orderItem);
  560.                 $amount += $price $orderItem->getQuantity();
  561.                 if ($last_id 10000) { // Кирилл просил сделать так...
  562.                     $last_id $this->getParameter('minTiberiumOrderId') + 1;
  563.                 }
  564.                 $logger->info(sprintf("make orderItem with tiberiumOrderId %s. "$orderItem->getTiberiumOrderId()));
  565.                 $entityManager->flush();
  566.                 $response $tiberium->getDeliveryVariants($basket$orderItem->getTiberiumOrderId());
  567.                 $logger->info("response to the getDeliveryVariants: " print_r($responsetrue));
  568.                 if ($response['Status'] == 2) {
  569.                     $RecipientContact $orderItem->getRecipientMsisdn() ?? $orderItem->getRecipientEmail();
  570.                     $comment 'Отправитель: Имя: ' $orderItem->getSenderName() . ' Почта: ' $orderItem->getSenderEmail() . ' Получатель: Имя: ' $orderItem->getRecipientName() . ' Почта/SMS: ' $RecipientContact;
  571.                     $tiberium->makeOrder($basket$orderItem->getTiberiumOrderId(), $orderItem->getTiberiumOrderId(), $orderItem->getSenderName(), $orderItem->getSenderEmail(), $orderItem->getRecipientMsisdn(), $comment);
  572.                 } else {
  573.                     return new Response('cannot make order'500);
  574.                 }
  575.             }
  576.         }
  577.         // now create payment
  578.         $response $ykclient->createPayment([
  579.             'amount' => [
  580.                 'value' => $amount,
  581.                 'currency' => 'RUB',
  582.             ],
  583.             'capture' => true,
  584.             'confirmation' => [
  585.                 'type' => 'embedded',
  586.             ],
  587.             'description' => 'Оплата заказа №' $order->getId()->toString() . ' для ' $order->getOrderItems()[0]->getSenderEmail(),
  588.             'metadata' => [
  589.                 'order_id' => $order->getId(),
  590.                 'http_host' => $request->getHttpHost(),
  591.                 'host' => $request->getHost(),
  592.             ],
  593.         ],
  594.             $order->getId());
  595.         $confirmation_token $response->getConfirmation()->getConfirmationToken();
  596.         $order->setPaymentStatus($response->getPaid());
  597.         $order->setPaymentData($response->toArray());
  598.         $order->setPaymentToken($confirmation_token);
  599.         $entityManager->persist($order);
  600.         $entityManager->flush();
  601.         return new JsonResponse([
  602.             'status' => 'ok',
  603.             'message' => 'success',
  604.             'confirmation_token' => $order->getPaymentToken(),
  605.         ]);
  606.     }
  607.     /**
  608.      * @param Order $order
  609.      * @param Tiberium $tiberium
  610.      * @param LoggerInterface $logger
  611.      * @return JsonResponse
  612.      * @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
  613.      */
  614.     #[Route('/reorder/{id}'name"reorder"methods: ['GET'])]
  615.     public function reOrder(
  616.         Order $order,
  617.         Tiberium $tiberium,
  618.         LoggerInterface $logger,
  619.         PaymentRemainderNotification $notification
  620.     )
  621.     {
  622.         try {
  623.             $tiberium->setDsn($order->getWidget()->getOrderServiceDsn());
  624.             foreach ($order->getOrderItems() as $item) {
  625.                 $basket = [];
  626.                 $basket[] = [
  627.                     'id' => $item->getProductId(),
  628.                     'quantity' => $item->getQuantity(),
  629.                 ];
  630.                 $RecipientContact $item->getRecipientMsisdn() ?? $item->getRecipientEmail();
  631.                 $comment 'Отправитель: Имя: ' $item->getSenderName() . ' Почта: ' $item->getSenderEmail() . ' Получатель: Имя: ' $item->getRecipientName() . ' Почта/SMS: ' $RecipientContact;
  632.                 $response $tiberium->makeOrder($basket$item->getTiberiumOrderId(), $item->getTiberiumOrderId(), $item->getSenderName(), $item->getSenderEmail(), $item->getRecipientMsisdn(), $comment);
  633.                 $logger->info("response from Tiberium for MANUAL makeOrder " $item->getTiberiumOrderId() . ' is : ' print_r($response));
  634.                 if (isset($response['Error']) && !empty($response['Error'])) {
  635.                     $notification->configure(
  636.                         $order->getWidget(),
  637.                         $order->getId(),
  638.                         $item->getTiberiumOrderId(),
  639.                         $response['Error']['ErrorMessage']
  640.                     );
  641.                     $notification->commit();
  642.                 }
  643.             }
  644.             return new JsonResponse(['status' => 'ok']);
  645.         } catch (Exception $error) {
  646.             foreach ($order->getOrderItems() as $item) {
  647.                 $notification->configure(
  648.                     $order->getWidget(),
  649.                     $order->getId(),
  650.                     $item->getTiberiumOrderId(),
  651.                     $error->getMessage()
  652.                 );
  653.                 $notification->commit();
  654.             }
  655.             return new JsonResponse(['status' => 'error''message' => $error->getMessage()]);
  656.         }
  657.     }
  658.     /**
  659.      * @param Request $request
  660.      * @param WidgetRepository $widgetRepository
  661.      * @param CacheManager $cacheManager
  662.      * @param Tiberium $tiberium
  663.      * @param LoggerInterface $logger
  664.      * @param WidgetRemainderNotification $notification
  665.      * @param string|null $term
  666.      * @return JsonResponse
  667.      */
  668.     #[Route("/widget/{term}"name"widget_entrypoint"methods: ["GET"])]
  669.     #[Route("/widget"name"widget_by_hostname"methods: ["GET"])]
  670.     public function getWidget(
  671.         Request $request,
  672.         WidgetRepository $widgetRepository,
  673.         CacheManager $cacheManager,
  674.         Tiberium $tiberium,
  675.         LoggerInterface $logger,
  676.         WidgetRemainderNotification $notification,
  677.         WidgetInfoService $infoService,
  678.         string $term null,
  679.     ): JsonResponse
  680.     {
  681.         if(null === $term) {
  682.             $term $request->headers->get('refferer');
  683.         }
  684.         $widget $widgetRepository->findWidgetByDomainOrId($term);
  685.         if(null === $widget) {
  686.             throw new NotFoundHttpException();
  687.         }
  688.         $activeNominal $request->query->get('active_nominal') ? $request->query->get('active_nominal') : null;
  689.         $productIdFilter $request->query->get('product_id') ? $request->query->get('product_id') : null;
  690.         $logger->warning("DSN: " $widget->getOrderServiceDsn());
  691.         $tiberium->setDsn($widget->getOrderServiceDsn());
  692.         $rules str_replace("\r\n""<br>"$widget->getRulesText());
  693.         $covers = [];
  694.         foreach ($widget->getCovers() as $cover) {
  695.             $parseUrl parse_url($cacheManager->getBrowserPath(
  696.                 basename($this->getParameter('app.user_files_dir')) . '/' .
  697.                 hash('sha256'$widget->getId()) .'/cover/' $cover['file'],
  698.                 'thumb'));
  699.             $covers[] = [
  700.                 'id' => $cover['sortOrder'],
  701.                 'src' => '//'.$parseUrl['host'].$parseUrl['path']
  702.             ];
  703.             uasort($covers, function ($a,$b) { return $a['id'] >= $b['id'] ? : -1; } );
  704.         }
  705.         $amounts = [];
  706.         $limits = [];
  707.         if('Charity' === $widget->getDeliveryVariants()[0]) {
  708.             $info $tiberium->getCardsList();
  709.             if($info['Status'] == 2) {
  710.                 $limits['min'] = $info['Products']['Product']['minimumSum'];
  711.                 $limits['max'] = $info['Products']['Product']['maximumSum'];
  712.             }
  713.         } else {
  714.             //если с фронта приходит productId, то возвращаем данные только по 1 товару
  715.             $productIds $widget->getProductsAsArray();
  716.             if (null != $productIdFilter){
  717.                 $productIds array_intersect($productIds, array($productIdFilter));
  718.             }
  719.             $productTiberiumData $tiberium->getProducts($productIds);
  720.             $productsData TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
  721.             $productsData TiberiumHelper::prepareProductsDataAsArray($productsData);
  722.             foreach ($productsData as $productData) {
  723.                 if (empty($productData)) {
  724.                     continue;
  725.                 }
  726.                 if ($productData['InStock'] == "0") {
  727.                     $notification->configure($widget$productData['Id']);
  728.                     $notification->commit();
  729.                     continue;
  730.                 }
  731.                 $productNominal TiberiumHelper::getProductNominalFromData($productData);
  732.                 $nominal $productNominal['nominal'];
  733.                 $currency $productNominal['currency'];
  734.                 $amounts[] = [
  735.                     'id' => $productData['Id'],
  736.                     'amount' => $productData['Price'],
  737.                     'nominal' => $nominal ?: $productData['Price'],
  738.                     'currency' => $currency ?: 'руб.',
  739.                     'saleImage' => null,
  740.                     'saleColor' => null
  741.                 ];
  742.             }
  743.             $amounts WidgetInfoService::sortNominalsByWidgetSettings($amounts$widget);
  744.         }
  745.         $usageRules WidgetHelper::convertUsageRulesToFrontend($widget);
  746.         $saleLabel $infoService->getSaleLabel($widget$request->getHttpHost());
  747.         $amounts $infoService->addSaleLabelToAmounts($amounts$saleLabel);
  748.         $data = [
  749.             'main' => [
  750.                 'version' => 1.0,
  751.                 'uuid' => $widget->getId(),
  752.                 'name' => $widget->getName(),
  753.                 'domain' => $widget->getDomain(),
  754.                 'meta_title' => $widget->getMetaTitle(),
  755.                 'meta_description' => $widget->getMetaDescription(),
  756.                 'support_tel_number' => $widget->getSupportTelNumber(),
  757.                 'support_email' => $widget->getSupportEmail(),
  758.                 'delivery_variants' => $widget->getDeliveryVariants(),
  759.                 'send_to_friend' => $widget->getSendToFriend(),
  760.                 'offer_text' => $widget->getOffer(),
  761.                 'faq' => $widget->getFaq(),
  762.                 'rules_text' => $rules,
  763.                 'hiw_create_title' => $widget->getHiwCreateTitle(),
  764.                 'hiw_create_text' => $widget->getHiwCreateText(),
  765.                 'hiw_receive_title' => $widget->getHiwReceiveTitle(),
  766.                 'hiw_receive_text' => $widget->getHiwReceiveText(),
  767.                 'hiw_glad_title' => $widget->getHiwGladTitle(),
  768.                 'hiw_glad_text' => $widget->getHiwGladText(),
  769.                 'template' => $widget->getMailTemplate()->getName(),
  770.                 'id_metric_yandex' => $widget->getIdMetricYandex(),
  771.                 'id_gtm' => $widget->getIdMetricGoogle(),
  772.                 'custom_design' => (bool)$widget->getCustomDesign(),
  773.                 'usage_rules' => $usageRules,
  774.                 'icons_color' => $widget->getIconsColor(),
  775.                 'active_nominal' => $activeNominal,
  776.                 'can_wholesale' => $widget->getCanWholesale(),
  777.                 'wholesale_example_phone' => $widget->getCanWholesale() ?
  778.                     'https://' .
  779.                     $request->getHttpHost() . $this->getParameter('wholesale.example_file_phone')
  780.                     : null,
  781.                 'wholesale_example_email' => $widget->getCanWholesale() ?
  782.                     'https://' .
  783.                     $request->getHttpHost() . $this->getParameter('wholesale.example_file_email')
  784.                     : null,
  785.                 'active_nominal' => $activeNominal,
  786.                 'corporate_purchase' => $widget->getEnableBxCorporateScript(),
  787.                 'script_from_admin' => $widget->getEnableBxCorporateScript() ? $widget->getBxCorporateScript() : null,
  788.                 'ai_image_enable' => $widget->isAiImageEnable(),
  789.                 'ai_text_enable' => $widget->isAiTextEnable(),
  790.             ],
  791.             'style' => [
  792.                 'primary_color' => $widget->getPrimaryColor(),
  793.                 'primary_background_color' => $widget->getPrimaryBackgroundColor(),
  794.                 'icons_color' => $widget->getIconsColor(),
  795.                 'circles_color' => $widget->getCirclesColor(),
  796.                 'stars_color' => $widget->getStarsColor(),
  797.                 'logotype_image' => 'https://' .
  798.                     $request->getHttpHost() . '/user_files/' .
  799.                     hash('sha256'$widget->getId()) .'/logo/'.
  800.                     $widget->getLogotypeImage(),
  801.                 'logotype_link' => $widget->getLogotypeLink(),
  802.                 'favicon_image' => 'https://' .
  803.                     $request->getHttpHost() . '/user_files/' .
  804.                     hash('sha256'$widget->getId()) .'/favicon/' .
  805.                     $widget->getFaviconImage(),
  806.                 'font' => $widget->getFont(),
  807.                 'external_css_file' => $widget->getExternalCssFile() !== null 'https://' $request->getHttpHost() . '/user_files/' .
  808.                     hash('sha256'$widget->getId()) . '/css/' $widget->getExternalCssFile() : false,
  809.                 'products' => [
  810.                     'covers' => $covers,
  811.                 ],
  812.                 'amounts' => $amounts,
  813.                 'limits' => $limits,
  814.                 'backgroundImage' => $widget->getBackgroundImage() ?
  815.                     'https://' .
  816.                     $request->getHttpHost() . '/user_files/' hash('sha256'$widget->getId()) . '/background/' .
  817.                     $widget->getBackgroundImage()
  818.                     : null,
  819.             ],
  820.         ];
  821.         return new JsonResponse($data);
  822.     }
  823.     /**
  824.      * @Route("/backend", name="backend_index", priority="0")
  825.      * @Security("is_granted('ROLE_CLIENT') or is_granted('ROLE_MERCHANT') or is_granted('ROLE_MANAGER') or is_granted('ROLE_SUPERADMINISTRATOR')")
  826.      */
  827.     public function backend(): Response
  828.     {
  829.         return $this->redirect('backend/orders/statistics');
  830.     }
  831.     /**
  832.      * @Route("/widget/order/xls", name="parse_order_xls", methods={"POST"})
  833.      */
  834.     public function parseFromXlsx(WidgetOrderXlsRequest $requestValidatorInterface $validatorWholesaleServiceInterface $wholesaleService): JsonResponse
  835.     {
  836.         $response = [
  837.             'status' => 'ok',
  838.             'data' => null,
  839.             'message' => null
  840.         ];
  841.         $errors $validator->validate($request);
  842.         if (count($errors) > 0) {
  843.             $response['status'] = 'error';
  844.             $response['message'] = $errors[0]->getMessage();
  845.             return new JsonResponse($response);
  846.         }
  847.         $file $request->file;
  848.         $recipientType $request->recipientType;
  849.         try {
  850.             if (!$wholesaleService->importFromXls($file$recipientType)) {
  851.                 $response['status'] = 'error';
  852.                 $response['message'] = 'В файле присутствуют ошибки';
  853.                 $response['data'] = $wholesaleService->getErrorRows();
  854.                 return new JsonResponse($response);
  855.             }
  856.             $response['data'] = $wholesaleService->getValidRows();
  857.         } catch (Exception $e) {
  858.             $response['message'] = $e->getMessage();
  859.             $response['status'] = 'error';
  860.             return new JsonResponse($response);
  861.         }
  862.         return new JsonResponse($response);
  863.     }
  864.     /**
  865.      * Загрузить кастомное изображение для сертификата
  866.      *
  867.      * @param Widget $widget
  868.      * @param WidgetUploadCoverRequest $request
  869.      * @param ValidatorInterface $validator
  870.      * @param FileServiceInterface $fileService
  871.      * @return JsonResponse
  872.      * @Route("/widget/{id}/upload-cover", name="upload_custom_cover", methods={"POST"})
  873.      */
  874.     public function uploadCustomCover(Widget $widgetWidgetUploadCoverRequest $requestValidatorInterface $validatorFileServiceInterface $fileService): JsonResponse
  875.     {
  876.         $response = [
  877.             'status' => 'ok',
  878.             'data' => null,
  879.             'message' => null
  880.         ];
  881.         $errors $validator->validate($request);
  882.         if (count($errors) > 0) {
  883.             $response['status'] = 'error';
  884.             $response['message'] = $errors[0]->getMessage();
  885.             return new JsonResponse($response);
  886.         }
  887.         try {
  888.             $fileName $fileService->uploadCustomCover($request->file$widget);
  889.             $fileFullPath $request->schemeAndHttpHost $fileService->getCustomCoverPathByWidget($widget) . $fileName;
  890.             $response['data']['fileName'] = $fileName;
  891.             $response['data']['fileUrl'] = $fileService->getPublicPathByFullPath($fileFullPath);
  892.         } catch (Exception $e) {
  893.             $response['message'] = 'Не удалось сохранить файл: ' $e->getMessage();
  894.             $response['status'] = 'error';
  895.             return new JsonResponse($response);
  896.         }
  897.         return new JsonResponse($response);
  898.     }
  899. }