<?php
namespace App\Controller\Front\Order;
use App\Config\Coupon;
use App\Config\Currency;
use App\Config\InvoiceSchema;
use App\Config\Pages;
use App\Controller\Front\UserZone\SecurityUtilsController;
use App\Entity\Order\Orders;
use App\Entity\Page\Page;
use App\Message\OrderInvoice;
use App\Message\ThanksForOrderEmail;
use Exception;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class OrderController extends SecurityUtilsController
{
private const ORDER_TEMPLATE = 'front/order/order.twig';
private const ORDER_THANKS_TEMPLATE = 'front/order/thanks.twig';
private const ORDER_ERROR_TEMPLATE = 'front/order/error.twig';
private const SUMMARY_TABLE_PATH = 'front/order/include/table/table.twig';
private const FIND_ORDERS_SELECT = 'front/offer/modals/copy/modal_content.twig';
public function showThanks(Request $request, Page $page): Response
{
return $this->render(self::ORDER_THANKS_TEMPLATE, [
'afterCreatedUser' => false
]);
}
public function showError(Request $request, Page $page): Response
{
return $this->render(self::ORDER_ERROR_TEMPLATE);
}
public function showCreatedUser(Request $request, Page $page): Response
{
return $this->render(self::ORDER_THANKS_TEMPLATE, [
'afterCreatedUser' => true
]);
}
/**
* @Route("/{_locale}/render/summary", name="render-summary-table", methods={"POST"})
*/
public function renderSummaryTable(Request $request): Response
{
$data = $request->request->all();
$discountType = $data['discount']['type'] ?? '';
$discountId = $data['discount']['id'] ?? '';
return new JsonResponse($this->renderView(self::SUMMARY_TABLE_PATH, [
'discountType' => $discountType,
'discount' => $discountType === Coupon::DISCOUNT ?
$this->couponDiscountProvider->getOneById($discountId) :
$this->couponSingleUseProvider->getOneById($discountId),
'package' => $this->packageService
->createPackageView($this->packageProvider->getOneById($data['id'] ?? ''), $request)
]));
}
/**
* @Route("/{_locale}/check/discount", name="check-discount", methods={"POST"})
*/
public function checkDiscount(Request $request): Response
{
$data = $request->request->all();
$code = $data['code'] ?? '';
$user = $data['user'] ?? '';
$couponDiscount = $this->couponDiscountProvider->getOneByCode($code);
$couponOneUse = $this->couponSingleUseProvider->getOneByCodeAndUser($code, $user);
$response = [
'discount' => [],
'error' => true
];
if ($couponDiscount) {
if ($couponDiscount->checkActiveUntilIsBiggerThanToday()) {
$response = [
'discount' => [
'id' => $couponDiscount->getId(),
'type' => Coupon::DISCOUNT,
],
'error' => false
];
} else {
$this->couponDiscountService->changeActive(false, $couponDiscount);
}
}
if ($couponOneUse) {
if ($couponOneUse->checkActiveUntilIsBiggerThanToday()) {
$response = [
'discount' => [
'id' => $couponOneUse->getId(),
'type' => Coupon::DISCOUNT_SINGLE_USED,
],
'error' => false
];
} else {
$this->couponSingleUseService->changeActive(false, $couponOneUse);
}
}
return new JsonResponse($response);
}
/**
* @Route("refresh_order", name="refresh-order", methods={"GET"})
*/
public function refresh(Request $request): Response
{
$locale = $request->getLocale();
$dataQuery = $request->query->all();
$orderRedirectPage = $this->pageProvider->getOneByMigrationId(PAGES::ORDER_THANKS);
$url = $orderRedirectPage?->translate($locale, false)->getUrl();
$data = [
'redirect_url' => $this->generateUrl('front-page', [
'_locale' => $locale,
'url' => $url
])
];
if ($orderEntity = $this->orderProvider->getOneById($dataQuery['order'])) {
$orderEntity->generateUuid();
$this->manager->persist($orderEntity);
$this->manager->flush();
$p24Response = $this->p24Client->getTransaction($orderEntity, $data);
return new RedirectResponse($p24Response->redirectUrl());
}
return new RedirectResponse($url);
}
/**
* @Route("verify_order", name="verify-order", methods={"POST", "GET"})
*/
public function verify(Request $request): Response
{
$webHook = $this->p24Client->handleWebhook();
$orderUuid = $webHook->sessionId();
$orderEntity = $this->orderProvider->getOneByUuid($orderUuid);
$this->p24Client->verify($webHook, $orderEntity);
$this->orderService->updateByVerifyOrder([
'paymentStatus' => Orders::PAYMENT_TYPE[2]['value'],
'status' => Orders::STATUS[1]['value']
], $orderEntity);
$this->userPackageService->updateByVerifyOrder($orderEntity);
$iFirmaRequest = new Request();
$locale = $orderEntity->getCurrency() === Currency::PLN ? 'pl' : 'en';
$country = $orderEntity->getInvoice()['country'] ?? 'pl';
$iFirmaRequest->setLocale($locale);
$iFirmaRequest->request->set('order', $orderEntity->getId());
$iFirmaRequest->request->set('invoiceType', InvoiceSchema::INVOICE);
$iFirmaRequest->request->set('country', $country);
$this->IFirmaService->createInvoice($iFirmaRequest);
$invoiceEntity = $orderEntity->getInvoiceFile()->getInvoiceId() .'.pdf';
$filePath = $this->parameterBag->get('invoice') . $invoiceEntity;
$this->messageBus->dispatch(new OrderInvoice(
$orderEntity->getUser()->getEmail(),
$locale,
$filePath,
InvoiceSchema::INVOICE,
false
)
);
return new Response('ok');
}
/**
* @Route("find/by/params", name="find_orders_by_params", methods={"GET"})
*/
public function findOrders(Request $request): Response
{
$offerEntity = $this->offerProvider->getEntityById($request->get('offer', null));
$locale = $request->get('locale', 'pl');
$userPackage = $this->userPackageProvider->getOneByUserPackageOrderAndActive(
$this->getUser(),
$offerEntity?->getPackage(),
$offerEntity?->getOrder()
);
$parameters = [
'user' => $offerEntity?->getUser()?->getId(),
'isAdditionalUser' => $userPackage?->getAdditionalUser(),
'locale' => $locale,
'numberLocalization' => $offerEntity?->getOrder()?->getConfiguration()['number_location'] ?? 0,
'industry' => $offerEntity?->getCategoryId(),
'isRange' => (bool) $offerEntity?->getOrder()?->getIsRange(),
];
$orders = $this->orderProvider->findByPackageParameters($parameters);
return new JsonResponse(
[
'ordersView' => $this->renderView(self::FIND_ORDERS_SELECT, [
'orders' => $orders,
'message' => $this->translator
->trans('USER_ZONE.MY_OFFER.MODALS.COPY_NO_HAVE_ACTIVE_PACKAGE', [], null, $locale)
]),
'haveOrders' => empty($orders) === false
]
);
}
public function show(Request $request, Page $page): Response
{
$originalRequest = $request->attributes->get('originalRequest', null);
$step = $originalRequest->query->get('step', null);
$package = $originalRequest->query->get('package', null);
$isOffer = $originalRequest->query->get('isOffer', 0);
$orderOffer = $originalRequest->query->get('orderOffer', null);
$userQuery = $originalRequest->query->get('user', null);
$originalRequest->request->set('currency', $originalRequest->getLocale() === 'pl' ? Currency::PLN : Currency::EURO);
$user = null;
if ($redirect = $this->checkUserHaveBlockRole($request, $isOffer)) {
return $this->redirect($redirect);
}
if ($isOffer) {
$orderEntity = $this->orderProvider->getOneById($orderOffer);
if (is_null($orderEntity) === false) {
if ($redirect = $this->checkOrderExperience($request, $orderEntity)) {
return $this->redirect($redirect);
}
if ($redirect = $this->checkOrderNeedToAccepted($request, $orderEntity)) {
return $this->redirect($redirect);
}
}
if (is_null($orderOffer) === true && is_null($package) === true) {
return $this->createResponse(PAGES::ORDER, $originalRequest);
}
} else {
if (is_null($step) === false && is_null($package) === true) {
return $this->createResponse(PAGES::ORDER, $originalRequest);
}
}
if ($originalRequest->isMethod('POST')) {
$stepForm = (int) $originalRequest->request->get('step', null);
$paymentMethod = $originalRequest->request->get('payment', null);
$orderId = $request->request->get('order');
// 2 - Form from Summary
if ($stepForm === 2) {
$orderEntity = $this->orderProvider->getOneById($orderId);
if (is_null($orderEntity) === false) {
$locale = $orderEntity->getCurrency() === Currency::PLN ? 'pl' : 'en';
} else {
$locale = $originalRequest->getLocale();
}
try {
if ($originalRequest->get('createdUser', null)) {
try {
$user = $this->userService->createAccountByOrder($originalRequest);
$orderEntity->setUser($user);
$this->manager->persist($orderEntity);
$this->manager->flush();
} catch (Exception $e){}
} else {
$user = $this->getUser() ?
$this->getUser() : $this->userService->createAccountByOrder($originalRequest);
}
if ($isOffer) {
$user = $this->userProvider->getUserByUsername($userQuery ?? '');
}
if (is_null($user) === false) {
$originalRequest->request->set('customer', $user->getId());
if (!$isOffer && $locale === "en") {
$isOffer = 1;
$paymentMethod = '1';
if (is_null($orderEntity)) {
$orderEntity = $this->orderService->create($originalRequest);
}
}
if ($isOffer) {
if ($paymentMethod === '1') {
try {
$this->orderService->setNeedToAccepted($orderEntity, false);
$this->messageBus->dispatch(new ThanksForOrderEmail(
$locale,
$user?->getEmail()
)
);
$iFirmaRequest = new Request();
$locale = $orderEntity->getCurrency() === Currency::PLN ? 'pl' : 'en';
$orderUser = $orderEntity->getUser();
$iFirmaRequest->setLocale($locale);
$iFirmaRequest->request->set('country', $orderUser->getCompanyCountry());
$iFirmaRequest->request->set('order', $orderEntity->getId());
$iFirmaRequest->request->set('invoiceType', InvoiceSchema::PRO_FORM);
$this->IFirmaService->createInvoice($iFirmaRequest);
$invoiceEntity = $orderEntity->getInvoiceProFormFile()->getInvoiceId() .'.pdf';
$filePath = $this->parameterBag->get('invoice') . $invoiceEntity;
$this->messageBus->dispatch(new OrderInvoice(
$orderUser->getEmail(),
$locale,
$filePath,
InvoiceSchema::PRO_FORM,
false
)
);
return $this->createResponse(PAGES::ORDER_THANKS, $originalRequest);
} catch (Exception $e) {
$this->messageBus->dispatch(new ThanksForOrderEmail(
$locale,
$user?->getEmail()
));
return $this->createResponse(PAGES::ORDER_ERROR, $originalRequest);
}
} else {
return new RedirectResponse($this->p24Redirect($originalRequest, $orderEntity));
}
} else {
return new RedirectResponse($this->p24Redirect($originalRequest, null));
}
}
} catch (Exception $e) {
return $this->createResponse(PAGES::ORDER_ERROR, $originalRequest);
}
}
}
$viewParams = $this->orderFactory->createOrderViewParams($originalRequest, $package, $this->getUser());
if ((int)$viewParams['step'] === 2) {
$email = $originalRequest->request->all()['company']['invoice_data']['email'] ?? '';
$companyAddress = $originalRequest->request->all()['company']['address']['address'] ?? '';
$packageEntity = $viewParams['package'] ?? null;
$userFromDb = $this->userProvider->getOneByEmail($email);
if ($redirectToUrl = $this->checkUserExists($request, $userFromDb)) {
return $this->cookieService->set([
'cookieName' => 'after_link_login',
'cookieValue' => $originalRequest->getUri(),
'redirectToUrl' => $redirectToUrl
]);
}
if (is_null($this->getUser()) === false || $isOffer) {
$user = $isOffer ? $this->userProvider->getUserByUsername($userQuery) : $this->getUser()->getEmail();
if (is_null($user)) {
if ($isOffer) {
$email = $orderEntity->getConfiguration()['customerAfterAcceptOffer'] ?? '';
$companyAddress = $this->createCompanyParamsAfterAcceptedOffer($orderEntity->getInvoice());
$viewParams['myCompany'] = $companyAddress;
$viewParams['myData'] = $this->createMyDataParamsAfterAcceptedOffer($originalRequest);
if($createdUser = $originalRequest->get('createdUser')){
$viewParams['createdUser'] = $createdUser;
}
}
} else {
$email = $isOffer ? $user->getEmail() : $this->getUser()->getEmail();
$companyAddress = $isOffer ?
$user->getCompany()[0] ?? null : $this->getUser()->getCompany()[0] ?? null;
if (is_null($companyAddress) === false) {
$companyAddress = $companyAddress->getIsExtraInvoiceData() ?
$companyAddress->getExtraInvoiceData()->getAddress()->getAddress()
: $companyAddress->getInvoiceData()->getAddress()->getAddress();
}
}
}
if ($redirect = $this->checkEmailIsExists($request, $email)) {
return $this->redirect($redirect);
}
if ($redirect = $this->checkPackagePrice($request, $packageEntity)) {
return $this->redirect($redirect);
}
}
$viewParams['entity'] = $page;
return $this->render(self::ORDER_TEMPLATE, $viewParams);
}
private function createCompanyParamsAfterAcceptedOffer(array $params): array
{
return [
'name' => $params['company'] ?? '',
'nip' => $params['nip'] ?? '',
'address' => $params['street'] ?? '',
'postCode' => $params['zip_code'] ?? '',
'city' => $params['city'] ?? '',
'country' => $params['country'] ?? ''
];
}
private function createMyDataParamsAfterAcceptedOffer(Request $request): array
{
return [
'email' => $request->get('user'),
'phone' => ''
];
}
private function createResponse(int $key, Request $request): Response
{
$locale = $request->getLocale();
if ($key === PAGES::ORDER_THANKS) {
$page = $this->pageProvider->getOneByMigrationId(PAGES::ORDER_THANKS);
}
if ($key === PAGES::ORDER_ERROR) {
$page = $this->pageProvider->getOneByMigrationId(PAGES::ORDER_ERROR);
}
if ($key === PAGES::ORDER) {
$page = $this->pageProvider->getOneByMigrationId(PAGES::ORDER);
}
return $this->redirectToRoute('front-page', [
'_locale' => $locale,
'url' => $page->translate($locale, false)->getUrl(),
]);
}
}