<?php
namespace App\Controller;
use App\Entity\Certificate;
use App\Entity\Order;
use App\Entity\OrderItem;
use App\Entity\Widget;
use App\Entity\WidgetUser;
use App\Helpers\TiberiumHelper;
use App\Helpers\WidgetHelper;
use App\Message\CharityMessage;
use App\Message\GetCertificatesMessage;
use App\Repository\OrderRepository;
use App\Repository\WidgetRepository;
use App\Request\WidgetOrderXlsRequest;
use App\Request\WidgetUploadCoverRequest;
use App\Services\BarcodeService;
use App\Services\CertificateService;
use App\Services\Contracts\CertificateServiceInterface;
use App\Services\Contracts\FileServiceInterface;
use App\Services\Contracts\CertificateCoverServiceInterface;
use App\Services\Contracts\OrderServiceInterface;
use App\Services\Contracts\WholesaleServiceInterface;
use App\Services\LogService\BaseLogDataService;
use App\Services\LogService\LogsService;
use App\Services\WidgetInfoService;
use App\Utils\Notification\OrderRemainderNotification;
use App\Utils\Notification\PaymentRemainderNotification;
use App\Utils\Notification\WidgetRemainderNotification;
use App\Utils\Tiberium;
use App\Utils\UploadedBase64File;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Knp\Bundle\SnappyBundle\Snappy\Response\PdfResponse;
use Knp\Snappy\Pdf;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\RedirectionExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\ServerExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
use YooKassa\Client as YooKassaClient;
use YooKassa\Common\Exceptions\ApiException;
use YooKassa\Common\Exceptions\BadApiRequestException;
use YooKassa\Common\Exceptions\ExtensionNotFoundException;
use YooKassa\Common\Exceptions\ForbiddenException;
use YooKassa\Common\Exceptions\InternalServerError;
use YooKassa\Common\Exceptions\NotFoundException;
use YooKassa\Common\Exceptions\ResponseProcessingException;
use YooKassa\Common\Exceptions\TooManyRequestsException;
use YooKassa\Common\Exceptions\UnauthorizedException;
use YooKassa\Model\Notification\NotificationFactory;
use YooKassa\Model\NotificationEventType;
class EntrypointController extends AbstractController
{
/**
* @param Request $request
* @param Pdf $pdf
* @param Certificate $certificate
* @param Tiberium $tiberium
* @param BaseLogDataService $dataService
* @param CertificateServiceInterface $certificateService
* @return Response
* @Route("/certificate/pdf/{id}", name="show_pdf_certificate")
*/
public function showPdf(Request $request, Pdf $pdf, Certificate $certificate, Tiberium $tiberium, BaseLogDataService $dataService, CertificateServiceInterface $certificateService)
{
$tiberium->setDsn($certificate->getOrderItem()->getWidgetOrder()->getWidget()->getOrderServiceDsn());
$orderItem = $certificate->getOrderItem();
$nominal = $certificate->getNominal();
$currency = $certificate->getCurrency();
if (in_array(null,[$nominal, $currency])) {
try {
$productTiberiumData = $tiberium->getProduct($orderItem->getProductId());
$productData = TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
$productNominal = TiberiumHelper::getProductNominalFromData($productData);
$productPrice = TiberiumHelper::getProductPriceFromData($productData);
$nominal = $productNominal['nominal'] ? $productNominal['nominal'] : $productPrice;
$currency = $productNominal['currency'] ? $productNominal['currency'] : 'руб.';
} catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
}
}
$certificate->setAmount($nominal);
$qr = $certificateService->generateQrBase64($certificate);
$barcode = $certificateService->generateBarcodeBase64($certificate);
$template = $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getMailTemplate()->getFilename();
$widget = $certificate->getOrderItem()->getWidgetOrder()->getWidget();
$usageRules = WidgetHelper::convertUsageRulesToFrontend($widget);
$html = $this->renderView('@templates/' . basename($template) . '/certificate.html.twig', [
'certificate' => $certificate,
'usageRules' => $usageRules,
'iconsColor' => $widget->getIconsColor(),
'basename' => basename($template),
'public' => '/app/public/',
'currency' => $currency,
'qr' => $qr,
'backgroundImage' => $widget->getBackgroundImage(),
'user_files_dir' => $this->getParameter('app.user_files_dir') . '/' . hash('sha256', $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getId()) . '/',
'barcode' => $barcode,
]);
$disposition = 'inline';
$logAction = BaseLogDataService::PRINT_CERTIFICATE_NAME;
if ($request->query->get('download')) {
$disposition = 'attachment';
$logAction = BaseLogDataService::DOWNLOAD_CERTIFICATE_NAME;
}
$dataService->prepareBaseData(__CLASS__, __FUNCTION__, $logAction, LogLevel::INFO, BaseLogDataService::TYPE_GOAL, sprintf("Action %s from Certificate: %s", $logAction, $certificate->getId()->toString()));
$dataService->prepareDataFromRequest($request);
$dataService->prepareDataFromCertificate($certificate);
LogsService::sendLog($dataService->getMethodName(), $dataService->getData(), $dataService->getTypeStorageTime(), $dataService->getParams(),'', $dataService->getClassShortName(), __FUNCTION__, null);
return new PdfResponse($pdf->getOutputFromHtml($html),
$certificate->getId().'.pdf',
'application/pdf',
$disposition
);
}
/**
* @param Request $request
* @param Widget $widget
* @param Pdf $pdf
* @param Tiberium $tiberium
* @param CertificateServiceInterface $certificateService
* @return PdfResponse
* @throws Exception
*/
#[Route('/widget/{id}/preview', name: 'certificate_preview', methods: ['GET'])]
public function showPreview(Request $request, Widget $widget, Pdf $pdf, Tiberium $tiberium, CertificateServiceInterface $certificateService)
{
$tiberium->setDsn($widget->getOrderServiceDsn());
//$json = json_decode($request->getContent(), true);
$req = [
'template_id' => $request->get('template_id'),
'product_id' => $request->get('product_id'),
];
$certificate = new Certificate();
$orderItem = new OrderItem();
$order = new Order();
$covers = $widget->getCovers();
$cover = $covers[$req['template_id'] ?? 0] ;
$orderItem->setCover($cover['file']);
$nominal = 0;
$currency = '';
try {
$productTiberiumData = $tiberium->getProduct($req['product_id']);
$productData = TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
$productNominal = TiberiumHelper::getProductNominalFromData($productData);
$productPrice = TiberiumHelper::getProductPriceFromData($productData);
$nominal = $productNominal['nominal']?$productNominal['nominal']:$productPrice;
$currency = $productNominal['currency']?$productNominal['currency']:'руб.';
} catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
}
$certificate->setAmount($nominal)
->setCreatedAt(new \DateTimeImmutable())
->setSerial('A1B2C3D4E5F6')
->setExpireAt(new \DateTimeImmutable('+1 year'))
->setPin('1234')
->setNominal($nominal)
;
$certificate->setOrderItem($orderItem);
$orderItem->setWidgetOrder($order);
$order->setWidget($widget);
$qr = $certificateService->generateQrBase64($certificate);
$barcode = $certificateService->generateBarcodeBase64($certificate);
$template = $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getMailTemplate()->getFilename();
$html = $this->renderView('@templates/' . basename($template) . '/certificate.html.twig', [
'certificate' => $certificate,
'basename' => basename($template),
'public' => '/app/public/',
'currency' => $currency,
'qr' => $qr,
'user_files_dir' => $this->getParameter('app.user_files_dir') . '/' . hash('sha256', $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getId()) . '/',
'barcode' => $barcode,
]);
$disposition = $request->query->get('download')?'attachment':'inline';
return new PdfResponse(
$pdf->getOutputFromHtml($html),
'preview_'.random_int(99999, 99999999999).'.pdf',
'application/pdf',
$disposition
);
}
/**
* @param Widget $widget
* @param Tiberium $tiberium
* @return Response
* @throws Exception
*/
#[Route('/widget/{id}/products', name: "products", methods: ['GET'])]
public function products(Widget $widget, Tiberium $tiberium)
{
$tiberium->setDsn($widget->getOrderServiceDsn());
$products = explode(',', $widget->getProducts());
$productsJson = [];
foreach($products as $row){
$productData = null;
try {
$productData = $tiberium->getProduct($row);
} catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
continue;
}
$product = TiberiumHelper::getProductFromTiberiumData($productData);
if (is_null($product)){
continue;
}
$productsJson[$product['Id']] = [
'Name' => $product['Name'],
'InStock' => $product['InStock'],
'Price' => $product['Price'],
'Params' => $product['Params'],
];
}
return $this->json($productsJson);
}
/**
* @param Request $request
* @param Widget $widget
*/
#[Route("/order/notification/widget/{id}", name: "create_order_notification", methods: ['POST'])]
public function createOrderNotification(Request $request, Widget $widget, OrderRemainderNotification $notification)
{
$notification->send(
$widget,
$request->toArray()['client'],
$request->toArray()['email'],
$request->toArray()['nominal'],
$request->toArray()['quantity'],
$request->toArray()['remainder']
);
return new JsonResponse(['status' => 'ok']);
}
/**
* @param Request $request
* @param Widget $widget
*/
#[Route("/getTiberiumOrderStatus/{id}", name: "get_tiberium_order_status", methods: ['GET'])]
public function getTiberiumOrderStatus(Request $request, Tiberium $tiberium): Response
{
return new JsonResponse( $tiberium->getOrderStatus($request->get('id')) );
}
/**
* @param Widget $widget
* @param Certificate $certificate
* @param RequestStack $requestStack
* @param BaseLogDataService $dataService
* @param CertificateServiceInterface $certificateService
* @return JsonResponse
* @Route("/{widget_id}/view/{id}", name="show_certificate", methods={"GET"})
* @ParamConverter("widget", options={"id" = "widget_id"})
*/
public function showCertificate(Widget $widget, Certificate $certificate, RequestStack $requestStack, BaseLogDataService $dataService, CertificateServiceInterface $certificateService): JsonResponse
{
$widget = $certificate->getOrderItem()->getWidgetOrder()->getWidget();
$cover = 'https://api.'.
str_replace('api.', '', $certificate->getOrderItem()->getWidgetOrder()->getPaymentData()['metadata']['http_host']). '/' .
basename($this->getParameter('app.user_files_dir')) . '/' . hash('sha256', $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getId()) . '/' .
basename($this->getParameter('app.cover_dir')) . '/' . $certificate->getCoverPath();
$qr = $certificateService->generateQrBase64($certificate);
$barcode = $certificateService->generateBarcodeBase64($certificate);
$json = [
'id' => $certificate->getId(),
'serial' => $certificate->getSerial(),
'expire_at' => $certificate->getExpireAt(),
'amount' => $certificate->getAmount(),
'pin' => $certificate->getPin(),
'cover' => $cover,
'qr' => $qr,
'sender_name' => $certificate->getOrderItem()->getSenderName(),
'recipient_name' => $certificate->getOrderItem()->getRecipientName(),
'recipient_type' => $certificate->getOrderItem()->getRecipientType(),
'message' => $certificate->getOrderItem()->getMessage(),
'faq' => $widget->getFaq(),
'favicon' => 'https://api.widget2.mgc-loyalty.ru/' . basename($this->getParameter('app.favicon_dir')) . '/' . $widget->getFaviconImage(),
'support_email' => $widget->getSupportEmail(),
'support_msisdn' => $widget->getSupportTelNumber(),
'template' => $certificate->getOrderItem()->getWidgetOrder()->getWidget()->getMailTemplate()->getName(),
'barcode' => $barcode,
];
$logAction = BaseLogDataService::VIEW_CERTIFICATE_NAME;
$dataService->prepareBaseData(__CLASS__, __FUNCTION__, $logAction, LogLevel::INFO, BaseLogDataService::TYPE_GOAL, sprintf("Action %s from Certificate: %s", $logAction, $certificate->getId()->toString()));
$dataService->prepareDataFromRequest($requestStack->getCurrentRequest());
$dataService->prepareDataFromCertificate($certificate);
LogsService::sendLog($dataService->getMethodName(), $dataService->getData(), $dataService->getTypeStorageTime(), $dataService->getParams(),'', $dataService->getClassShortName(), __FUNCTION__, null);
return $this->json($json);
}
/**
* @Route("/", name="entrypoint")
*/
public function index(): Response
{
return $this->redirect('backend/orders/statistics');
}
/**
* @param Order $order
* @param WidgetUser $user
* @param MessageBusInterface $messageBus
* @return Response
* @IsGranted("ROLE_SUPERADMINISTRATOR")
* @Route("/pushmeto/{id}", name="push")
*/
public function push(Order $order, EntityManagerInterface $entityManager, MessageBusInterface $messageBus)
{
$widgetUser = $entityManager->getRepository('App\Entity\WidgetUser')->find($this->getUser());
$getCertificatesMessage = new GetCertificatesMessage($order);
$getCertificatesMessage->setClient($widgetUser);
$messageBus->dispatch($getCertificatesMessage);
return new Response('ok');
}
/**
* @param Order $order
* @param Tiberium $tiberium
* @param LoggerInterface $logger
* @return JsonResponse
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
#[Route('/confirmator/{id}', name: "confirmator", methods: ['GET'])]
public function confirmOrder(
Order $order,
Tiberium $tiberium,
LoggerInterface $logger,
PaymentRemainderNotification $notification
)
{
try {
$tiberium->setDsn($order->getWidget()->getOrderServiceDsn());
foreach ($order->getOrderItems() as $item) {
$response = $tiberium->confirmOrder($item->getTiberiumOrderId());
$logger->info("response from Tiberium for MANUAL confirmOrder " . $item->getTiberiumOrderId() . ' is : ' . print_r($response));
if (isset($response['Error']) && !empty($response['Error'])) {
$notification->configure(
$order->getWidget(),
$order->getId(),
$item->getTiberiumOrderId(),
$response['Error']['ErrorMessage']
);
$notification->commit();
}
}
return new JsonResponse(['status' => 'ok']);
} catch (Exception $error) {
foreach ($order->getOrderItems() as $item) {
$notification->configure(
$order->getWidget(),
$order->getId(),
$item->getTiberiumOrderId(),
$error->getMessage()
);
$notification->commit();
}
return new JsonResponse(['status' => 'error', 'message' => $error->getMessage()]);
}
}
/**
* @param Request $request
* @param OrderRepository $orderRepository
* @param EntityManagerInterface $entityManager
* @param LoggerInterface $logger
* @param MessageBusInterface $messageBus
* @return Response
* @Route("/callback/yookassa", name="yookassa_callback")
*/
public function YooKassaCallback(
Request $request,
OrderRepository $orderRepository,
EntityManagerInterface $entityManager,
MessageBusInterface $messageBus,
Tiberium $tiberium,
LoggerInterface $logger,
PaymentRemainderNotification $notification):Response
{
$msg = json_decode($request->getContent(), true);
$factory = new NotificationFactory();
$notificationObject = $factory->factory($msg);
$response = $notificationObject->getObject();
$logger->info(sprintf('get callback from ykassa for order #%s', $response->getMetadata()['order_id']));
$logger->info('get callback from ykassa data:'. json_encode($response));
if (in_array($notificationObject->getEvent(), [
NotificationEventType::PAYMENT_SUCCEEDED,
NotificationEventType::PAYMENT_CANCELED,
])) {
$order_id = $response->getMetadata()['order_id'];
$status = $response->getStatus();
$order = $orderRepository->findOneBy(['id' => $order_id]);
$tiberium->setDsn($order->getWidget()->getOrderServiceDsn());
if(null !== $order) {
$order->setPaymentStatus($status);
$entityManager->persist($order);
$entityManager->flush();
if($notificationObject->getEvent() === NotificationEventType::PAYMENT_SUCCEEDED) { // проверяем, благотворительность или нет
// в случае если $response->getStatus() === canceled
// $response->getPaymentMethod()->getType() 500 т.к. нет getPaymentMethod()
$payment_type = $response->getPaymentMethod()->getType();
$payment_type_id = match ($payment_type) {
'bank_card' => 1,
'sbp' => 4,
default => 3
};
$logger->info(sprintf('order id is %s and delivery type is %s', $order->getId(), $order->getWidget()->getDeliveryVariants()[0]));
if($order->getWidget()->getDeliveryVariants()[0] == 'Charity') {
$message = new CharityMessage($order->getId());
} else {
$message = new GetCertificatesMessage($order);
foreach ($order->getOrderItems() as $item) {
$logger->info(sprintf('send confirmOrder to Tiberium for order '. print_r($response, true)));
$response = $tiberium->confirmOrder($item->getTiberiumOrderId());
$logger->info("response from Tiberium for confirmOrder " . $item->getTiberiumOrderId() . ' is : ' . print_r($response, true));
if (isset($response['Error']) && !empty($response['Error'])) {
$notification->configure(
$order->getWidget(),
$order->getId(),
$item->getTiberiumOrderId(),
$response['Error']['ErrorMessage']
);
$notification->commit();
}else{
$data_payment = [[
'PaymentMethod' => [
'PaymentMethodID' => $payment_type_id,
'Sum' => $item->getAmount()
]
]];
$tiberium->setPaymentMethod($item->getTiberiumOrderId(), $data_payment);
}
}
}
$messageBus->dispatch($message);
}
}
return new Response('ok');
}
return new Response('not found', 404);
}
/**
* @param Request $request
* @param Widget $widget
* @param Tiberium $tiberium
* @param YooKassaClient $ykclient
* @param EntityManagerInterface $entityManager
* @param LoggerInterface $logger
* @param CertificateCoverServiceInterface $coverService
* @return JsonResponse|Response
* @throws TransportExceptionInterface
* @throws ApiException
* @throws BadApiRequestException
* @throws ExtensionNotFoundException
* @throws ForbiddenException
* @throws InternalServerError
* @throws NotFoundException
* @throws ResponseProcessingException
* @throws TooManyRequestsException
* @throws UnauthorizedException
* @Route("/widget/{id}/order", name="make_order", methods={"POST"})
*/
public function order(
Request $request,
Widget $widget,
Tiberium $tiberium,
YooKassaClient $ykclient,
EntityManagerInterface $entityManager,
LoggerInterface $logger,
CertificateCoverServiceInterface $coverService,
OrderServiceInterface $orderService,
)
{
$tiberium->setDsn($widget->getOrderServiceDsn());
$ykassaDsn = [];
preg_match('/(.*):(.*)/', $widget->getYkassaDsn(), $ykassaDsn);
if(sizeof($ykassaDsn) === 3) {
$ykclient->setAuth($ykassaDsn[1], $ykassaDsn[2]);
}
$logger->info('REQUEST FROM FRONTEND: ' . $request->getContent());
$orderItems = json_decode($request->getContent(), true);
$orderType = $orderService->getTypeFromCreateOrderData($orderItems);
$order = new Order();
$order->setWidget($widget)
->setCreatedAt(new \DateTimeImmutable())
->setPaymentStatus('created')
->setUpdatedAt(new \DateTimeImmutable())
->setType($orderType)
;
$entityManager->persist($order);
$amount = 0;
foreach ($orderItems as $item) {
$cover = $coverService->getCoverFromCreateOrderItemData($item, $widget);
if (null === $cover) {
return new JsonResponse(['status' => 'error', 'message' => 'Invalid cover id']);
}
$products = array_map(function ($el) {
return trim($el);
}, explode(',', $widget->getProducts()));
if (!in_array($item['certificate']['product']['product_id'], $products) && 'Charity' != $widget->getDeliveryVariants()[0]) {
return new JsonResponse(['status' => 'error', 'message' => 'Invalid product id']);
}
$orderItem = new OrderItem();
$last_id = round(microtime(true)*1000);
$logger->info(sprintf('Widget with id %s delivery variant 0 is: %s', $widget->getId(), $widget->getDeliveryVariants()[0]));
if('Charity' == $widget->getDeliveryVariants()[0]) {
$amount = $item['certificate']['product']['amount'];
} else {
$logger->info("getting the product id " . print_r($orderItem->getProductId(), true));
try {
$productTiberiumData = $tiberium->getProduct($item['certificate']['product']['product_id']);
} catch (ClientExceptionInterface|RedirectionExceptionInterface|ServerExceptionInterface|TransportExceptionInterface $e) {
continue;
}
$productData = TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
if (is_null($productData)){
continue;
}
$productPrice = TiberiumHelper::getProductPriceFromData($productData);
$amount = $productPrice;
}
$orderItem
->setWidgetOrder($order)
->setTiberiumOrderId($last_id)
->setCover($cover)
->setMessage($item['certificate']['message'] ?? null)
->setBasketKey($item['certificate']['basket_key'])
->setProductId($item['certificate']['product']['product_id'])
->setQuantity($item['certificate']['product']['quantity'] ?? 1)
->setDeliveryType($item['certificate']['delivery_type'] ?? 'Email')
->setRecipientType($item['recipient']['type'] ?? 'me')
->setRecipientName(strtolower($item['recipient']['name'] ?? 'no name'))
->setRecipientEmail($item['recipient']['email'] ?? $item['sender']['email'] ?? 'no-email@dev.null')
->setRecipientMsisdn($item['recipient']['msisdn'] ?? '+70000000000')
->setAmount($amount)
->setSenderEmail($item['sender']['email'] ?? $orderItem->getRecipientEmail())
->setSenderName($item['sender']['name'] ?? $orderItem->getRecipientName())
->setUtm($item['utm'] ?? null)
;
$logger->info("FRONTEND decoded are " . json_encode($item));
$orderItem->setTimeToSend(isset($item['time_to_send']) ? (new \DateTimeImmutable($item['time_to_send']))->setTimezone(new \DateTimeZone('Europe/Moscow')) : new \DateTimeImmutable());
$entityManager->persist($orderItem);
$order->addOrderItem($orderItem);
$entityManager->flush();
}
if('Charity' != $widget->getDeliveryVariants()[0]) {
$amount = 0;
foreach ($order->getOrderItems() as $orderItem) {
$basket = [];
$basket[] = [
'id' => $orderItem->getProductId(),
'quantity' => $orderItem->getQuantity(),
];
$logger->info(sprintf('basket is %s', print_r($basket, true)));
$price = $orderItem->getAmount();
$entityManager->persist($orderItem);
$amount += $price * $orderItem->getQuantity();
if ($last_id < 10000) { // Кирилл просил сделать так...
$last_id = $this->getParameter('minTiberiumOrderId') + 1;
}
$logger->info(sprintf("make orderItem with tiberiumOrderId %s. ", $orderItem->getTiberiumOrderId()));
$entityManager->flush();
$response = $tiberium->getDeliveryVariants($basket, $orderItem->getTiberiumOrderId());
$logger->info("response to the getDeliveryVariants: " . print_r($response, true));
if ($response['Status'] == 2) {
$RecipientContact = $orderItem->getRecipientMsisdn() ?? $orderItem->getRecipientEmail();
$comment = 'Отправитель: Имя: ' . $orderItem->getSenderName() . ' Почта: ' . $orderItem->getSenderEmail() . ' Получатель: Имя: ' . $orderItem->getRecipientName() . ' Почта/SMS: ' . $RecipientContact;
$tiberium->makeOrder($basket, $orderItem->getTiberiumOrderId(), $orderItem->getTiberiumOrderId(), $orderItem->getSenderName(), $orderItem->getSenderEmail(), $orderItem->getRecipientMsisdn(), $comment);
} else {
return new Response('cannot make order', 500);
}
}
}
// now create payment
$response = $ykclient->createPayment([
'amount' => [
'value' => $amount,
'currency' => 'RUB',
],
'capture' => true,
'confirmation' => [
'type' => 'embedded',
],
'description' => 'Оплата заказа №' . $order->getId()->toString() . ' для ' . $order->getOrderItems()[0]->getSenderEmail(),
'metadata' => [
'order_id' => $order->getId(),
'http_host' => $request->getHttpHost(),
'host' => $request->getHost(),
],
],
$order->getId());
$confirmation_token = $response->getConfirmation()->getConfirmationToken();
$order->setPaymentStatus($response->getPaid());
$order->setPaymentData($response->toArray());
$order->setPaymentToken($confirmation_token);
$entityManager->persist($order);
$entityManager->flush();
return new JsonResponse([
'status' => 'ok',
'message' => 'success',
'confirmation_token' => $order->getPaymentToken(),
]);
}
/**
* @param Order $order
* @param Tiberium $tiberium
* @param LoggerInterface $logger
* @return JsonResponse
* @throws \Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface
*/
#[Route('/reorder/{id}', name: "reorder", methods: ['GET'])]
public function reOrder(
Order $order,
Tiberium $tiberium,
LoggerInterface $logger,
PaymentRemainderNotification $notification
)
{
try {
$tiberium->setDsn($order->getWidget()->getOrderServiceDsn());
foreach ($order->getOrderItems() as $item) {
$basket = [];
$basket[] = [
'id' => $item->getProductId(),
'quantity' => $item->getQuantity(),
];
$RecipientContact = $item->getRecipientMsisdn() ?? $item->getRecipientEmail();
$comment = 'Отправитель: Имя: ' . $item->getSenderName() . ' Почта: ' . $item->getSenderEmail() . ' Получатель: Имя: ' . $item->getRecipientName() . ' Почта/SMS: ' . $RecipientContact;
$response = $tiberium->makeOrder($basket, $item->getTiberiumOrderId(), $item->getTiberiumOrderId(), $item->getSenderName(), $item->getSenderEmail(), $item->getRecipientMsisdn(), $comment);
$logger->info("response from Tiberium for MANUAL makeOrder " . $item->getTiberiumOrderId() . ' is : ' . print_r($response));
if (isset($response['Error']) && !empty($response['Error'])) {
$notification->configure(
$order->getWidget(),
$order->getId(),
$item->getTiberiumOrderId(),
$response['Error']['ErrorMessage']
);
$notification->commit();
}
}
return new JsonResponse(['status' => 'ok']);
} catch (Exception $error) {
foreach ($order->getOrderItems() as $item) {
$notification->configure(
$order->getWidget(),
$order->getId(),
$item->getTiberiumOrderId(),
$error->getMessage()
);
$notification->commit();
}
return new JsonResponse(['status' => 'error', 'message' => $error->getMessage()]);
}
}
/**
* @param Request $request
* @param WidgetRepository $widgetRepository
* @param CacheManager $cacheManager
* @param Tiberium $tiberium
* @param LoggerInterface $logger
* @param WidgetRemainderNotification $notification
* @param string|null $term
* @return JsonResponse
*/
#[Route("/widget/{term}", name: "widget_entrypoint", methods: ["GET"])]
#[Route("/widget", name: "widget_by_hostname", methods: ["GET"])]
public function getWidget(
Request $request,
WidgetRepository $widgetRepository,
CacheManager $cacheManager,
Tiberium $tiberium,
LoggerInterface $logger,
WidgetRemainderNotification $notification,
WidgetInfoService $infoService,
string $term = null,
): JsonResponse
{
if(null === $term) {
$term = $request->headers->get('refferer');
}
$widget = $widgetRepository->findWidgetByDomainOrId($term);
if(null === $widget) {
throw new NotFoundHttpException();
}
$activeNominal = $request->query->get('active_nominal') ? $request->query->get('active_nominal') : null;
$productIdFilter = $request->query->get('product_id') ? $request->query->get('product_id') : null;
$logger->warning("DSN: " . $widget->getOrderServiceDsn());
$tiberium->setDsn($widget->getOrderServiceDsn());
$rules = str_replace("\r\n", "<br>", $widget->getRulesText());
$covers = [];
foreach ($widget->getCovers() as $cover) {
$parseUrl = parse_url($cacheManager->getBrowserPath(
basename($this->getParameter('app.user_files_dir')) . '/' .
hash('sha256', $widget->getId()) .'/cover/' . $cover['file'],
'thumb'));
$covers[] = [
'id' => $cover['sortOrder'],
'src' => '//'.$parseUrl['host'].$parseUrl['path']
];
uasort($covers, function ($a,$b) { return $a['id'] >= $b['id'] ? 1 : -1; } );
}
$amounts = [];
$limits = [];
if('Charity' === $widget->getDeliveryVariants()[0]) {
$info = $tiberium->getCardsList();
if($info['Status'] == 2) {
$limits['min'] = $info['Products']['Product']['minimumSum'];
$limits['max'] = $info['Products']['Product']['maximumSum'];
}
} else {
//если с фронта приходит productId, то возвращаем данные только по 1 товару
$productIds = $widget->getProductsAsArray();
if (null != $productIdFilter){
$productIds = array_intersect($productIds, array($productIdFilter));
}
$productTiberiumData = $tiberium->getProducts($productIds);
$productsData = TiberiumHelper::getProductFromTiberiumData($productTiberiumData);
$productsData = TiberiumHelper::prepareProductsDataAsArray($productsData);
foreach ($productsData as $productData) {
if (empty($productData)) {
continue;
}
if ($productData['InStock'] == "0") {
$notification->configure($widget, $productData['Id']);
$notification->commit();
continue;
}
$productNominal = TiberiumHelper::getProductNominalFromData($productData);
$nominal = $productNominal['nominal'];
$currency = $productNominal['currency'];
$amounts[] = [
'id' => $productData['Id'],
'amount' => $productData['Price'],
'nominal' => $nominal ?: $productData['Price'],
'currency' => $currency ?: 'руб.',
'saleImage' => null,
'saleColor' => null
];
}
$amounts = WidgetInfoService::sortNominalsByWidgetSettings($amounts, $widget);
}
$usageRules = WidgetHelper::convertUsageRulesToFrontend($widget);
$saleLabel = $infoService->getSaleLabel($widget, $request->getHttpHost());
$amounts = $infoService->addSaleLabelToAmounts($amounts, $saleLabel);
$data = [
'main' => [
'version' => 1.0,
'uuid' => $widget->getId(),
'name' => $widget->getName(),
'domain' => $widget->getDomain(),
'meta_title' => $widget->getMetaTitle(),
'meta_description' => $widget->getMetaDescription(),
'support_tel_number' => $widget->getSupportTelNumber(),
'support_email' => $widget->getSupportEmail(),
'delivery_variants' => $widget->getDeliveryVariants(),
'send_to_friend' => $widget->getSendToFriend(),
'offer_text' => $widget->getOffer(),
'faq' => $widget->getFaq(),
'rules_text' => $rules,
'hiw_create_title' => $widget->getHiwCreateTitle(),
'hiw_create_text' => $widget->getHiwCreateText(),
'hiw_receive_title' => $widget->getHiwReceiveTitle(),
'hiw_receive_text' => $widget->getHiwReceiveText(),
'hiw_glad_title' => $widget->getHiwGladTitle(),
'hiw_glad_text' => $widget->getHiwGladText(),
'template' => $widget->getMailTemplate()->getName(),
'id_metric_yandex' => $widget->getIdMetricYandex(),
'id_gtm' => $widget->getIdMetricGoogle(),
'custom_design' => (bool)$widget->getCustomDesign(),
'usage_rules' => $usageRules,
'icons_color' => $widget->getIconsColor(),
'active_nominal' => $activeNominal,
'can_wholesale' => $widget->getCanWholesale(),
'wholesale_example_phone' => $widget->getCanWholesale() ?
'https://' .
$request->getHttpHost() . $this->getParameter('wholesale.example_file_phone')
: null,
'wholesale_example_email' => $widget->getCanWholesale() ?
'https://' .
$request->getHttpHost() . $this->getParameter('wholesale.example_file_email')
: null,
'active_nominal' => $activeNominal,
'corporate_purchase' => $widget->getEnableBxCorporateScript(),
'script_from_admin' => $widget->getEnableBxCorporateScript() ? $widget->getBxCorporateScript() : null,
'ai_image_enable' => $widget->isAiImageEnable(),
'ai_text_enable' => $widget->isAiTextEnable(),
],
'style' => [
'primary_color' => $widget->getPrimaryColor(),
'primary_background_color' => $widget->getPrimaryBackgroundColor(),
'icons_color' => $widget->getIconsColor(),
'circles_color' => $widget->getCirclesColor(),
'stars_color' => $widget->getStarsColor(),
'logotype_image' => 'https://' .
$request->getHttpHost() . '/user_files/' .
hash('sha256', $widget->getId()) .'/logo/'.
$widget->getLogotypeImage(),
'logotype_link' => $widget->getLogotypeLink(),
'favicon_image' => 'https://' .
$request->getHttpHost() . '/user_files/' .
hash('sha256', $widget->getId()) .'/favicon/' .
$widget->getFaviconImage(),
'font' => $widget->getFont(),
'external_css_file' => $widget->getExternalCssFile() !== null ? 'https://' . $request->getHttpHost() . '/user_files/' .
hash('sha256', $widget->getId()) . '/css/' . $widget->getExternalCssFile() : false,
'products' => [
'covers' => $covers,
],
'amounts' => $amounts,
'limits' => $limits,
'backgroundImage' => $widget->getBackgroundImage() ?
'https://' .
$request->getHttpHost() . '/user_files/' . hash('sha256', $widget->getId()) . '/background/' .
$widget->getBackgroundImage()
: null,
],
];
return new JsonResponse($data);
}
/**
* @Route("/backend", name="backend_index", priority="0")
* @Security("is_granted('ROLE_CLIENT') or is_granted('ROLE_MERCHANT') or is_granted('ROLE_MANAGER') or is_granted('ROLE_SUPERADMINISTRATOR')")
*/
public function backend(): Response
{
return $this->redirect('backend/orders/statistics');
}
/**
* @Route("/widget/order/xls", name="parse_order_xls", methods={"POST"})
*/
public function parseFromXlsx(WidgetOrderXlsRequest $request, ValidatorInterface $validator, WholesaleServiceInterface $wholesaleService): JsonResponse
{
$response = [
'status' => 'ok',
'data' => null,
'message' => null
];
$errors = $validator->validate($request);
if (count($errors) > 0) {
$response['status'] = 'error';
$response['message'] = $errors[0]->getMessage();
return new JsonResponse($response);
}
$file = $request->file;
$recipientType = $request->recipientType;
try {
if (!$wholesaleService->importFromXls($file, $recipientType)) {
$response['status'] = 'error';
$response['message'] = 'В файле присутствуют ошибки';
$response['data'] = $wholesaleService->getErrorRows();
return new JsonResponse($response);
}
$response['data'] = $wholesaleService->getValidRows();
} catch (Exception $e) {
$response['message'] = $e->getMessage();
$response['status'] = 'error';
return new JsonResponse($response);
}
return new JsonResponse($response);
}
/**
* Загрузить кастомное изображение для сертификата
*
* @param Widget $widget
* @param WidgetUploadCoverRequest $request
* @param ValidatorInterface $validator
* @param FileServiceInterface $fileService
* @return JsonResponse
* @Route("/widget/{id}/upload-cover", name="upload_custom_cover", methods={"POST"})
*/
public function uploadCustomCover(Widget $widget, WidgetUploadCoverRequest $request, ValidatorInterface $validator, FileServiceInterface $fileService): JsonResponse
{
$response = [
'status' => 'ok',
'data' => null,
'message' => null
];
$errors = $validator->validate($request);
if (count($errors) > 0) {
$response['status'] = 'error';
$response['message'] = $errors[0]->getMessage();
return new JsonResponse($response);
}
try {
$fileName = $fileService->uploadCustomCover($request->file, $widget);
$fileFullPath = $request->schemeAndHttpHost . $fileService->getCustomCoverPathByWidget($widget) . $fileName;
$response['data']['fileName'] = $fileName;
$response['data']['fileUrl'] = $fileService->getPublicPathByFullPath($fileFullPath);
} catch (Exception $e) {
$response['message'] = 'Не удалось сохранить файл: ' . $e->getMessage();
$response['status'] = 'error';
return new JsonResponse($response);
}
return new JsonResponse($response);
}
}