<?php
namespace App\Controller;
use App\Entity\CouponCode;
use App\Entity\Invoice;
use App\Entity\Order;
use App\Entity\Template;
use App\Form\OrderFormType;
use App\Repository\CouponCodeRepository;
use App\Security\MailerController;
use BarionClient;
use Currency;
use Doctrine\Persistence\ManagerRegistry as PersistenceManagerRegistry;
use Dompdf\Dompdf;
use Dompdf\Options;
use FundingSourceType;
use ItemModel;
use PaymentTransactionModel;
use PaymentType;
use PreparePaymentRequestModel;
use PreparePaymentResponseModel;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use UILocale;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
class OrderController extends AbstractController
{
private MailerController $mailerController;
private CouponCodeRepository $couponCodeRepository;
public function __construct(
MailerController $emailVerifier,
CouponCodeRepository $couponCodeRepository,
) {
$this->mailerController = $emailVerifier;
$this->couponCodeRepository = $couponCodeRepository;
}
#[Route('/order', name: 'app_order')]
public function index(Security $security, PersistenceManagerRegistry $doctrine, Request $request): Response
{
$order = new Order();
$form = $this->createForm(OrderFormType::class, $order, [
'action' => $this->generateUrl('app_order_process'),
'method' => 'POST',
]);
$entityManager = $doctrine->getManager();
$templates = $entityManager->getRepository(Template::class)->findAll();
$array = [
'form' => $form->createView(),
'templates' => $templates,
];
// Check if the user has accepted or declined cookies
$cookiesAccepted = $request->cookies->get('cookies_accepted');
if ($cookiesAccepted === 'true') {
// User accepted cookies
$array['loggedUser'] = $security->getUser();
} else {
// User declined cookies
$array['loggedUser'] = null;
}
return $this->render('order/index.html.twig', $array);
}
#[Route('/order/process', name: 'app_order_process')]
public function processOrder(Request $request, PersistenceManagerRegistry $doctrine): Response
{
$entityManager = $doctrine->getManager();
$user = $this->getUser();
$data = $request->request->all('order_form');
$lastVariableSymbol = $doctrine->getRepository(Order::class)->findLastVariableSymbol();
if ($lastVariableSymbol) {
$lastVariableSymbol = $lastVariableSymbol[0]->getVariableSymbol();
$lastVariableSymbol++;
} else {
$lastVariableSymbol = date("Y") . 100;
}
$template = $doctrine->getRepository(Template::class)->findOneBy([
'path' => $data['template']
]);
$order = $this->prepareOrder($data, $user);
$order->setVariableSymbol($lastVariableSymbol);
$order->setTemplate($template);
$entityManager->persist($order);
$entityManager->flush();
$path = $_SERVER['DOCUMENT_ROOT'] . $this->getParameter('order') . $lastVariableSymbol;
if (!file_exists($path)) {
mkdir($path, 0777, true);
}
$pdfOptions = new Options();
$pdfOptions->set('defaultFont', 'Arial');
$pdfOptions->set('isRemoteEnabled', true);
$code = $doctrine->getRepository(CouponCode::class)->findOneByCode($order->getCode());
$html = $this->renderView('invoice/index.html.twig', [
'order' => $order,
'code' => $code,
]);
// Instantiate Dompdf with our options
$dompdf = new Dompdf($pdfOptions);
$dompdf->loadHtml($html);
$dompdf->setPaper('A4');
$dompdf->render();
file_put_contents($path . '/' . $order->getVariableSymbol() . '.pdf', $dompdf->output());
$paymentRequest = $this->makePayment($order->getFinalPrice(), $order->getBillingEmail(), $order->getVariableSymbol());
$order->setPaymentId($paymentRequest->PaymentId);
$invoice = new Invoice();
$invoice->setName($order->getVariableSymbol() . '.pdf');
$invoice->setPath($path);
$invoice->setAssociatedOrder($order);
$order->setInvoice($invoice);
$entityManager->persist($order);
$entityManager->persist($invoice);
$entityManager->flush();
$this->mailerController->sendNewOrderEmail($request, $order, $path . '/' . $order->getVariableSymbol() . '.pdf', $paymentRequest->PaymentRedirectUrl);
return $this->redirect($paymentRequest->PaymentRedirectUrl);
}
public function makePayment($price, $email, $variableSymbol): PreparePaymentResponseModel
{
$barionClient = new BarionClient($this->getParameter('app.barionKey'), 2, $this->getParameter('app.barionEnv'));
$item = new ItemModel();
$item->Name = "MojeZpráva.cz - dopis";
$item->Description = "Objednávka zprávy s vlastním textem na přibližné datum.";
$item->Quantity = 1;
$item->Unit = "zpráva";
$item->UnitPrice = $price;
$item->ItemTotal = $price;
$item->SKU = "Zpráva s vlastním textem";
$trans = new PaymentTransactionModel();
$trans->POSTransactionId = "Platba za zprávu";
$trans->Payee = $this->getParameter('app.barionUser');
$trans->Total = $price;
$trans->AddItem($item);
$ppr = new PreparePaymentRequestModel();
$ppr->GuestCheckout = true;
$ppr->PaymentType = PaymentType::Immediate;
$ppr->FundingSources = array(FundingSourceType::All);
$ppr->PaymentRequestId = "PAYMENT-01 - dopsat co to vlastne je";
$ppr->PayerHint = $email;
$ppr->Locale = UILocale::CZ;
$ppr->OrderNumber = $variableSymbol;
$ppr->Currency = Currency::CZK;
$ppr->RedirectUrl = $this->getParameter('app.url') . "order/accepted";
$ppr->CallbackUrl = $this->getParameter('app.url') . "order";
$ppr->AddTransaction($trans);
return $barionClient->PreparePayment($ppr);
}
public function prepareOrder($data, $user): Order
{
$order = new Order();
if (strlen($data['deliveryCity']) > 0) {
$order->setDeliveryCity($data['deliveryCity']);
$order->setDeliveryFirstname($data['deliveryFirstname']);
$order->setDeliveryLastname($data['deliveryLastname']);
$order->setDeliveryState($data['deliveryCountry']);
$order->setDeliveryStreet1($data['deliveryStreet']);
$order->setDeliveryStreet2($data['deliveryStreet2']);
$order->setDeliveryZipCode($data['deliveryZipcode']);
$order->setDeliveryEmail($data['deliveryEmail']);
$order->setDeliveryPhone($data['deliveryPhone']);
}
$order->setBillingCity($data['billingCity']);
$order->setBillingFirstname($data['billingFirstname']);
$order->setBillingLastname($data['billingLastname']);
$order->setBillingState($data['billingCountry']);
$order->setBillingStreet($data['billingStreet']);
$order->setBillingStreet2($data['billingStreet2']);
$order->setBillingZipCode($data['billingZipcode']);
$order->setBillingEmail($data['billingEmail']);
$order->setBillingPhone($data['billingPhone']);
$order->setPrice($this->getParameter('messagePrice'));
$order->setFinalPrice($data['price']);
$order->setCode($data['code'] ?? '0');
$order->setText($data['text']);
$order->setDeliveryDate(new \DateTime($data['deliveryDate']));
$order->setUser($user);
$order->setIssuedAt(new \DateTime());
return $order;
}
#[Route('/order/accepted', name: 'app_order_accepted')]
public function orderAccepted(Request $request, PersistenceManagerRegistry $doctrine): Response
{
$order = $doctrine->getRepository(Order::class)->findOneByPaymentId($request->get('paymentId'));
$order->setPaid(true);
$entityManager = $doctrine->getManager();
$entityManager->persist($order);
$entityManager->flush();
return $this->render('order/accepted.html.twig');
}
#[Route('/couponCode', name: 'app_get_couponCode')]
public function getCouponCode(Request $request, PersistenceManagerRegistry $doctrine): Response
{
$code = $doctrine->getRepository(CouponCode::class)->findOneByCode($request->get('code'));
$serializer = new Serializer(array(new GetSetMethodNormalizer()), array('json' => new JsonEncoder()));
$json = $serializer->serialize($code, 'json');
if ($code) {
return new Response($json, 200);
} else {
return new Response(null, 404);
}
}
}