src/Controller/ActivationFormController.php line 86

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Api\ProthelisApi;
  4. use App\Api\WeclappApi;
  5. use App\Entity\Coupon;
  6. use App\Entity\Device;
  7. use App\Entity\DeviceGroup;
  8. use App\Entity\Order;
  9. use App\Entity\Payment;
  10. use App\Entity\PaymentMethod;
  11. use App\Entity\Servicepack;
  12. use App\Entity\SubscriptionDevice;
  13. use App\Entity\User;
  14. use App\Entity\UserMandate;
  15. use App\Form\OrderFormStep1;
  16. use App\Form\OrderFormStep2;
  17. use App\Form\OrderFormStep3;
  18. use App\Form\OrderFormStep4;
  19. use App\Service\CouponService;
  20. use App\Service\DBLogService;
  21. use App\Service\DeviceService;
  22. use App\Service\MollieService;
  23. use App\Service\SubscriptionService;
  24. use Doctrine\ORM\EntityManagerInterface;
  25. use Mollie\Api\Resources\Mandate;
  26. use Symfony\Component\HttpFoundation\RedirectResponse;
  27. use Symfony\Component\HttpFoundation\RequestStack;
  28. use Symfony\Component\Routing\Annotation\Route;
  29. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  30. use Symfony\Component\Form\FormError;
  31. use Symfony\Component\Form\FormInterface;
  32. use Symfony\Component\HttpFoundation\Request;
  33. use Symfony\Component\HttpFoundation\Response;
  34. use Symfony\Contracts\Translation\TranslatorInterface;
  35. class ActivationFormController extends AbstractController implements RequireFullUserdataController
  36. {
  37.     /** @var DBLogService $dbLogService */
  38.     private DBLogService $dbLogService;
  39.     private TranslatorInterface $translator;
  40.     private RequestStack $requestStack;
  41.     private DeviceService $deviceService;
  42.     private EntityManagerInterface $entityManager;
  43.     private MollieService $mollieService;
  44.     private SubscriptionService $subscriptionService;
  45.     /**
  46.      * AccountController constructor.
  47.      */
  48.     public function __construct(EntityManagerInterface $entityManagerDBLogService $dbLogServiceTranslatorInterface $translatorRequestStack $requestStackDeviceService $deviceServiceMollieService $mollieServiceSubscriptionService $subscriptionService)
  49.     {
  50.         $this->dbLogService $dbLogService;
  51.         $this->translator $translator;
  52.         $this->requestStack $requestStack;
  53.         $this->deviceService $deviceService;
  54.         $this->entityManager $entityManager;
  55.         $this->mollieService $mollieService;
  56.         $this->subscriptionService $subscriptionService;
  57.     }
  58.     /**
  59.      * @Route("/signup/overview", name="user_signup_overview")
  60.      * @return Response
  61.      */
  62.     public function signupOverviewAction(Request $request)
  63.     {
  64.         return $this->render('activation/overview.html.twig', []);
  65.     }
  66.     
  67.     /**
  68.      * @Route("/activate/servicepack", name="activate_servicepack")
  69.      * @return Response
  70.      */
  71.     public function selectPackageAction(Request $requestCouponService $couponService)
  72.     {
  73.         return $this->redirectToRoute('activate_servicepack_step1', ['sn' => $request->get('sn')]);
  74.     }
  75.     /**
  76.      * @Route("/activate/servicepack/1", name="activate_servicepack_step1")
  77.      * @param Request       $request
  78.      * @param CouponService $couponService
  79.      * @return Response
  80.      */
  81.     public function selectPackageStep1Action(Request $requestCouponService $couponService)
  82.     {
  83.         $form $this->createForm(OrderFormStep1::class);
  84.         $sn $request->get('sn');
  85.         if (!empty($sn) && !$form->isSubmitted()) {
  86.             $form->get('deviceCode')->setData($sn);
  87.         }
  88.         $form->handleRequest($request);
  89.         $order null;
  90.         if ($form->isSubmitted() && $form->isValid()) {
  91.             /** @var Order $order */
  92.             $order $form->getData();
  93.             $order->setUser($this->getUser());
  94.             $order->setIsProcessed(false);
  95.             $order->setIsCanceled(false);
  96.             $order->setIsExtended(false);
  97.             $order->setMandateId(null);
  98.             $this->checkDeviceSN($form);
  99.             $this->setOrderDeviceData($order$form->get('deviceCode')->getData());
  100.             $this->processCoupon($couponService$order$form);
  101.             $order->setTotalPrice();
  102.             if ($form->isValid()) {
  103.                 $order->setDeviceCode(strtoupper($order->getDeviceCode()));
  104.                 // update user mandates
  105.                 $this->mollieService->updateUserMandates($this->getUser());
  106.                 $this->requestStack->getSession()->set('orderData'$order);
  107.                 // compare with subscription devices
  108.                 $subscriptionDevice $this->entityManager->getRepository(SubscriptionDevice::class)->findByDeviceCode($order->getDeviceCode());
  109.                 // todo: binding should become an option for coupons. For now, we take the servicepack id
  110. //                $bindingServicepack = $order->getCoupon() && $order->getCoupon()->getValidServicepack() && in_array($order->getCoupon()->getValidServicepack()->getId(), [37,38]);
  111.                 if ($subscriptionDevice) {
  112.                     //todo: only check for valid previous orders
  113.                     $alreadyActivated $this->entityManager->getRepository(Order::class)->findByDeviceCodeAndUser($order->getDeviceCode(), $this->getUser(), true);
  114.                     if (!$alreadyActivated) {
  115.                         $order->setCoupon(null);  // coupons currently don't support subscriptions
  116.                         $paymentMethod $this->entityManager->getRepository(PaymentMethod::class)->findOneBy(['provider' => 'subscription']);
  117.                         $order->setPaymentMethod($paymentMethod);
  118.                         $order->setServicepack($subscriptionDevice->getServicepack());
  119.                         $this->deviceService->calculateRenewalDate($order$subscriptionDevice->getDateAdded());
  120.                         //dump($order);
  121.                         return $this->redirectToRoute('activate_overview', ['formData' => $order]);
  122.                     }
  123.                 }
  124.                 if ($order->getTotalPrice() === 0.0) {
  125.                     $this->deviceService->calculateRenewalDate($order);
  126.                     return $this->redirectToRoute('activate_overview', ['formData' => $order]);
  127.                 }
  128.                 // if servicepack is set in coupon, don't let user change it
  129.                 if ($order->getCoupon() && $order->getCoupon()->getValidServicepack()) {
  130.                     $order->setServicepack($order->getCoupon()->getValidServicepack());
  131.                     $this->deviceService->calculateRenewalDate($order);
  132.                     //dump($order);
  133.                     return $this->redirectToRoute('activate_servicepack_step3', ['formData' => $order]);
  134.                 }
  135.                 return $this->redirectToRoute('activate_servicepack_step2', ['formData' => $order]);
  136.             } else {
  137. //                dump($form);
  138.             }
  139.         }
  140.         return $this->render('activation/select.packet.step1.html.twig', ['orderForm' => $form->createView()]);
  141.     }
  142.     /**
  143.      * Set order data for alternative service packs
  144.      * @Route("/activate/extra", name="activate_extra_step1")
  145.      * @return Response
  146.      */
  147.     public function selectExtraStep1Action()
  148.     {
  149.         $order = new Order();
  150.         $order->setUser($this->getUser());
  151.         $order->setDeviceCode(Device::NO_DEVICE_SN);
  152.         $order->setDeviceType('extra');
  153.         $order->setTotalPrice($order->getProductPrice());
  154.         $order->setIsProcessed(false);
  155.         $this->requestStack->getSession()->set('orderData'$order);
  156.         return $this->redirectToRoute('activate_servicepack_step2', ['formData' => $order]);
  157.     }
  158.     /**
  159.      * @Route("/activate/servicepack/2", name="activate_servicepack_step2")
  160.      * @param Request $request
  161.      * @return Response
  162.      */
  163.     public function selectPackageStep2Action(Request $request)
  164.     {
  165.         $order null;
  166.         if ($this->requestStack->getSession()->has('orderData') && $this->requestStack->getSession()->get('orderData') !== null) {
  167.             /** @var Order $orderData */
  168.             $orderData $this->requestStack->getSession()->get('orderData');
  169.             $orderData->setId(null);
  170.             $order $orderData//$em->merge($orderData);
  171.         } else {
  172.             $this->addFlash('error'$this->translator->trans('account.order.failed'));
  173.             $this->dbLogService->info('order''order_step2_error', ['message' => 'session does not exist'], $order$this->getUser());
  174.             return $this->redirectToRoute('user_account');
  175.         }
  176.         $tags $this->getUser()->getTags();
  177.         $today = new \DateTime();
  178.         $newPricesStart = new \DateTime('2023-10-01');
  179.         /** @var Servicepack[] $packs */
  180.         if (in_array(User::TAG_OLDCUSTOMER$tags) && $today $newPricesStart) {
  181.             $packsDefault $this->entityManager->getRepository(Servicepack::class)->findAllDefaultOldOrdered();
  182.         } else {
  183.             $packsDefault $this->entityManager->getRepository(Servicepack::class)->findAllDefaultOrdered();
  184.         }
  185.         $packsSubscription $this->entityManager->getRepository(Servicepack::class)->findAllAboOrdered();
  186.         $packsExtra $this->entityManager->getRepository(Servicepack::class)->findAllExtraOrdered();
  187.         $subscription_sets = [
  188.             'monthly' => [],
  189.             'total' => [],
  190.         ];
  191.         /** @var Servicepack $pack */
  192.         foreach ($packsSubscription as $pack) {
  193.             if ($pack->getType() === Servicepack::TYPE_ABO_MONTHLY) {
  194.                 $subscription_sets['monthly'][] = $pack;
  195.             } else {
  196.                 $subscription_sets['total'][] = $pack;
  197.             }
  198.         }
  199.         try {
  200.             $order->setServicepack($order->getServicepack());
  201.             $order->setServicepack($this->entityManager->merge($order->getServicepack()));
  202.         } catch (\Exception $exception) {}
  203.         $form $this->createForm(OrderFormStep2::class, $order);
  204.         $form->handleRequest($request);
  205.         if ($form->isSubmitted() && $form->isValid()) {
  206.             /** @var Order $order */
  207.             $order $form->getData();
  208.             $this->deviceService->calculateRenewalDate($order);
  209.             $order->setTotalPrice();
  210.             $order->setCallbackIdentifier();
  211.             $order->setIsRecurring($order->getServicepack()->getIsRecurring());
  212.             if ($form->isValid()) {
  213.                 $order->setPaymentMethod(null);
  214.                 $this->requestStack->getSession()->set('orderData'$order);
  215.                 return $this->redirectToRoute('activate_servicepack_step3', ['formData' => $order]);
  216.             }
  217.         }
  218.         $orderForm $form->createView();
  219.         $isDefault $order->getDeviceCode() !== Device::NO_DEVICE_SN;
  220.         $mandates $this->entityManager->getRepository(UserMandate::class)->findValidByUser($this->getUser());
  221.         $tags $this->getUser()->getTags();
  222.         $today = new \DateTime();
  223.         $newPricesStart = new \DateTime('2023-10-01');
  224.         $oldCutomer false;
  225.         if (in_array(User::TAG_OLDCUSTOMER$tags) && $today $newPricesStart) {
  226.             $oldCutomer true;
  227.         }
  228.         $enable_subscription in_array(User::TAG_ENABLE_ABO$tags);
  229. //        dump($subscription_sets);
  230.         return $this->render('activation/select.packet.step2.html.twig', [
  231.             'packs' => $isDefault $packsDefault $packsExtra,
  232.             'packs_subscription' => $subscription_sets,
  233.             'enable_subscription' => $enable_subscription,
  234.             'showDefaultPackets' => $isDefault,
  235.             'mandates' => $mandates,
  236.             'order' => $order,
  237.             'orderForm' => $orderForm,
  238.             'oldCustomer' => $oldCutomer]);
  239.     }
  240.     /**
  241.      * @Route("/activate/servicepack/3", name="activate_servicepack_step3")
  242.      * @param Request $request
  243.      * @return Response
  244.      */
  245.     public function selectPackageStep3Action(Request $request)
  246.     {
  247.         $order null;
  248.         $selectedPayment null;
  249.         if ($this->requestStack->getSession()->has('orderData') && $this->requestStack->getSession()->get('orderData') !== null) {
  250.             /** @var Order $orderData */
  251.             $orderData $this->requestStack->getSession()->get('orderData');
  252.             $orderData->setId(null);
  253.             $order $orderData//$em->merge($orderData);
  254.         } else {
  255.             $this->addFlash('error'$this->translator->trans('account.order.failed'));
  256.             $this->dbLogService->info('order''order_step2_error', ['message' => 'session does not exist'], $order$this->getUser());
  257.             return $this->redirectToRoute('user_account');
  258.         }
  259.         $user $this->getUser();
  260.         if ($user instanceof User) {
  261.             $country $user->getAddressCountry();
  262.         } else {
  263.             $country '1';
  264.         }
  265.         /** @var PaymentMethod[] $paymentMethod */
  266.         if ($order->getServicepack()->getIsRecurring()) {
  267.             $paymentMethod $this->entityManager->getRepository(PaymentMethod::class)->findRecurringForCountryOrdered($country);
  268.         } else {
  269.             $paymentMethod $this->entityManager->getRepository(PaymentMethod::class)->findNonRecurringForCountryOrdered($country);
  270.         }
  271.         try {
  272.             $order->setPaymentMethod($order->getPaymentMethod());
  273.             $order->setPaymentMethod($this->entityManager->merge($order->getPaymentMethod()));
  274.         } catch (\Exception $exception) {}
  275.         $form $this->createForm(OrderFormStep3::class, $order);
  276.         $form->handleRequest($request);
  277.         if ($form->isSubmitted() && $form->isValid()) {
  278.             /** @var Order $order */
  279.             $order $form->getData();
  280.             $selectedPayment $this->entityManager->getRepository(PaymentMethod::class)->find($orderData->getPaymentMethod());
  281.             if ($selectedPayment) {
  282.                 $order->setPaymentMethod($selectedPayment);
  283.             } else {
  284.                 $form->get('paymentMethod')->addError(
  285.                     new FormError(
  286.                         $this->translator->trans('account.export.msg_error_check_input')
  287.                     )
  288.                 );
  289.             }
  290. //            $formData = $form->getData();
  291.             // set payment method or assign mandate
  292. //            dump($formData);
  293. //            if (is_int($formData->getPaymentMethod())) {
  294. //                $payment = $this->entityManager->getRepository(PaymentMethod::class)->find($formData->getPaymentMethod());
  295. //                if ($payment) {
  296. //                    $order->setPaymentMethod($payment);
  297. //                }
  298. //            } else {
  299. //                // find mandate
  300. //                /** @var UserMandate $mandate */
  301. //                $mandate = $this->entityManager->getRepository(UserMandate::class)->find('mdt_'.$formData->getPaymentMethod());
  302. //                if ($mandate) {
  303. //                    if (!$mandate->getUser()->getId() === $order->getUser()->getId()) {
  304. //                        $form->get('paymentMethod')->addError(
  305. //                            new FormError(
  306. //                                $this->translator->trans('error')
  307. //                            )
  308. //                        );
  309. //                        }
  310. //                }
  311. //            }
  312.             if ($form->isValid()) {
  313.                 // find payment method
  314.                 $this->requestStack->getSession()->set('orderData'$order);
  315.                 return $this->redirectToRoute('activate_overview', ['formData' => $order]);
  316.             }
  317.         } else {
  318. //            exit;
  319.         }
  320.         if (!$order) {
  321.             foreach ($paymentMethod as $pk => $pv) {
  322.                 if ($pv->getProvider() === 'coupon') {
  323.                     unset($paymentMethod[$pk]);
  324.                 }
  325.             }
  326.         }
  327.         $orderForm $form->createView();
  328.         $isDefault $order->getDeviceCode() !== Device::NO_DEVICE_SN;
  329.         $mandates $this->entityManager->getRepository(UserMandate::class)->findValidByUser($this->getUser());
  330.         return $this->render('activation/select.packet.step3.html.twig', [
  331.             'showDefaultPackets' => $isDefault,
  332.             'paymentMethods' => $paymentMethod,
  333.             'mandates' => $mandates,
  334.             'order' => $order,
  335.             'orderForm' => $orderForm]);
  336.     }
  337.     /**
  338.      * @Route("/activate/overview", name="activate_overview")
  339.      * @param Request $request
  340.      * @return RedirectResponse|Response|null
  341.      */
  342.     public function overviewAction(Request $request)
  343.     {
  344.         $order null;
  345.         if ($this->requestStack->getSession()->has('orderData') && $this->requestStack->getSession()->get('orderData') !== null) {
  346.             $order $this->requestStack->getSession()->get('orderData');
  347.         } else {
  348.             $this->addFlash('error'$this->translator->trans('account.order.failed'));
  349.             $this->dbLogService->info('order''order_step3_error', ['message' => 'session does not exist'], $order$this->getUser());
  350.             return $this->redirectToRoute('user_account');
  351.         }
  352.         $form $this->createForm(OrderFormStep4::class, $order);
  353.         $form->handleRequest($request);
  354.         if ($form->isSubmitted() && $form->isValid()) {
  355.             /** @var Order $order */
  356.             $order $form->getData();
  357.             $this->requestStack->getSession()->set('orderData'$order);
  358.             return $this->redirectToRoute('activate_place', ['formData' => $order]);
  359.         }
  360.         $orderForm $form->createView();
  361.         return $this->render('activation/overview_table.html.twig', [
  362.             'user' => $this->getUser(),
  363.             'orderData' => $order,
  364.             'orderForm' => $orderForm,
  365.             'show_info_deactivated' => $this->deviceService->isDeactivatedForInactivity($order),
  366.         ]);
  367.     }
  368.     
  369.     /**
  370.      * @Route("/activate/place", name="activate_place")
  371.      * @return RedirectResponse
  372.      */
  373.     public function placeOrderAction(Request $request) {
  374.         try {
  375.             /** @var Order $order */
  376.             $order $this->requestStack->getSession()->get('orderData');
  377.             if (!$order) {
  378.                 // session not found
  379.                 $this->addFlash('error'$this->translator->trans('account.order.failed'));
  380.                 return $this->redirectToRoute('user_account');
  381.             }
  382.         } catch (\Exception $exception) {
  383.             // session not found
  384.             $this->addFlash('error'$this->translator->trans('account.order.failed'));
  385.             return $this->redirectToRoute('user_account');
  386.         }
  387.         switch ($order->getPaymentMethod()->getProvider()) {
  388.             case 'coupon':
  389.             case 'subscription':
  390.                 $order->setCurrentStatus('activating');
  391.                 $order->setPaymentStatus(PaymentMethod::STATUS_PAYMENT_COMPLETED);
  392.                 $this->addFlash('success'$this->translator->trans('account.order.success'));
  393.                 break;
  394.             case 'paypal':
  395.             case 'payever':
  396.             case 'mollie':
  397.             default:
  398.                 $order->setCurrentStatus('complete_payment');
  399.                 $order->setPaymentStatus(PaymentMethod::STATUS_COMPLETE_PAYMENT);
  400.         }
  401.         $order->setUserData($request->getClientIp());
  402.         $order->setIsRecurring($order->getServicepack()->getIsRecurring());
  403.         $order->setIsExtended(false);
  404.         $order->setIsCanceled(false);
  405.         /** @var User $user */
  406.         $user $this->getUser();
  407.         if ($user->getSalutation()) {
  408.             $order->setUser($this->getUser());
  409.         }
  410.         $order->setServicepack($this->entityManager->merge($order->getServicepack()));
  411.         $order->setPaymentMethod($this->entityManager->merge($order->getPaymentMethod()));
  412.         if ($order->getCoupon()) {
  413.             /** @var Coupon $coupon */
  414.             $coupon $order->getCoupon();
  415.             /** @var User $cuser */
  416.             if ($cuser $coupon->getValidUser()) {
  417.                 if ($cuser->getId() == $user->getId()) {
  418.                     $coupon->setValidUser($this->getUser());
  419.                     $order->setCoupon($coupon);
  420.                 }
  421.             }
  422.             $order->setCoupon($this->entityManager->merge($order->getCoupon()));
  423.         }
  424.         if (!$order->getId()) {
  425.             $this->entityManager->persist($order);
  426.             $this->entityManager->flush();
  427.             $this->requestStack->getSession()->set('orderData'$order);
  428.         }
  429.         // skip if order already processed (browser back button, etc.) or if no cost
  430.         if (!$order->getWcOrderNumber() && $order->getTotalPrice() > && $_ENV['APP_ENV'] !== 'dev') {
  431.             try {
  432.                 // Connect with weclapp
  433.                 $weclappApi = new WeclappApi($this->entityManager);
  434.                 // get/create wc user and set wc_user_id
  435.                 $wcCustomer $weclappApi->connectUser($user);
  436.                 // create order in wc
  437.                 $wcOrder $weclappApi->salesOrderManager->createAndBook($weclappApi$order$wcCustomer);
  438.                 // get wc order_id (for payment)
  439.                 $wcOrderNumber $wcOrder->orderNumber;
  440.                 $wcOrderId $wcOrder->id;
  441.                 $order->setWcOrderNumber($wcOrderNumber);
  442.                 $order->setWcOrderId($wcOrderId);
  443.                 $this->entityManager->flush();
  444.                 $this->dbLogService->debug('order''weclapp'$wcOrder$order$this->getUser());
  445.             } catch (\Exception $exception) {
  446.                 $this->dbLogService->error('order''weclapp'$exception$order$this->getUser());
  447.             }
  448.         }
  449. //        $this->dbLogService->info('order', 'place', $order, $order, $this->getUser());
  450. //        $this->dbLogService->info('order', 'place', null, $order, $this->getUser());
  451.         return $this->redirectToRoute('payment_prepare');
  452.     }
  453.     
  454.     /**
  455.      * @Route("/activate/completeOrder/{id}", requirements={"id" = "\d+"}, name="activate_completeorder")
  456.      * @return RedirectResponse
  457.      */
  458.     public function completeOrderAction($idRequest $request) {
  459.         /** @var Order $order */
  460.         $order $this->entityManager->getRepository(Order::class)->findOneFromUser($this->getUser(), $id);
  461.         if ($order->getPaymentStatus() !== PaymentMethod::STATUS_COMPLETE_PAYMENT) {
  462.             $this->addFlash('error'$this->translator->trans('account.order.failed'));
  463.             return $this->redirectToRoute('user_account');
  464.         }
  465.         $this->requestStack->getSession()->set('orderData'$order);
  466.         
  467.         return $this->redirectToRoute('payment_prepare');
  468.     }
  469.     /**
  470.      * @Route("/activate/cancelOrder/{id}", requirements={"id" = "\d+"}, name="activate_cancelorder")
  471.      * @return RedirectResponse
  472.      */
  473.     public function cancelOrderAction($idRequest $request) {
  474.         /** @var Order $order */
  475.         $order $this->entityManager->getRepository(Order::class)->findOneFromUser($this->getUser(), $id);
  476.         if ($order->getPaymentStatus() !== PaymentMethod::STATUS_COMPLETE_PAYMENT) {
  477.             $this->addFlash('error'$this->translator->trans('account.order.failed'));
  478.             return $this->redirectToRoute('user_account');
  479.         }
  480.         //$this->requestStack->getSession()->set('orderData', $order);
  481.         $order->setOrderComment('('.date('Y-m-d H:i:s').") Abgebrochen durch Kunden\n".$order->getOrderComment());
  482.         $order->setCurrentStatus('cancelled');
  483.         $order->setPaymentStatus(PaymentMethod::STATUS_PAYMENT_ABORTED);
  484.         $this->entityManager->flush();
  485.         return $this->redirect($request->headers->get('referer'));
  486.     }
  487.     /**
  488.      * @Route("/activate/completePayment/{id}", requirements={"id" = "\d+"}, name="activate_completepayment")
  489.      * @return RedirectResponse
  490.      */
  491.     public function completePaymentAction($idRequest $request) {
  492.         /** @var Payment $payment */
  493.         $payment $this->entityManager->getRepository(Payment::class)->findByUserAndId($this->getUser(), $id);
  494.         if ($payment->getStatus() !== Payment::STATUS_FAILED) {
  495.             $this->addFlash('error'$this->translator->trans('account.order.failed'));
  496.             return $this->redirectToRoute('user_account');
  497.         }
  498.         $order $payment->getOrder();
  499.         $pack_description $order->getDeviceType().' Service ' $order->getServicepack()
  500.                 ->getRuntime() . 'M: ' $order->getDeviceCode() . ' (' $order->getId() . ')';
  501.         $molliePayment $this->mollieService->retryOrderPayment($payment$pack_description);
  502.         return $this->redirect($molliePayment->getCheckoutUrl());
  503.     }
  504.     /**
  505.      * @param CouponService $couponService
  506.      * @param Order $order
  507.      * @param FormInterface $form
  508.      * @return void
  509.      */
  510.     protected function processCoupon(CouponService $couponServiceOrder $orderFormInterface $form)
  511.     {
  512.         // evaluate if device qualifies for bundled activation. If bundle is available, overwrite coupon field, otherwise keep it
  513.         $couponCode $this->getBundleCode($order$form->get('couponCode')->getData());
  514.         if (!empty($couponCode)) {
  515.             /** @var Coupon $coupon */
  516.             $coupon $order->getCouponByCode($couponCode$couponService);
  517.             if ($coupon->getError()) {
  518.                 $form->get('couponCode')
  519.                     ->addError(new FormError($coupon->getError()));
  520.             } else {
  521.                 if ($coupon->getId() !== null) {
  522.                     $order->setCoupon($coupon);
  523.                 }
  524.             }
  525.         } else {
  526. //            $order->setCoupon(null);
  527.         }
  528.         
  529.     }
  530.     protected function getBundleCode(Order $order$default null) {
  531.         // find bundle groups
  532.         $bundle_groups = [];
  533.         foreach (['6''12''24'] as $month) {
  534.             // check for free month first
  535.             $tmp $this->entityManager->getRepository(DeviceGroup::class)->getByTitle('Bundle '.$month.'+1 Monate');
  536.             if ($tmp instanceof DeviceGroup) {
  537.                 $bundle_groups[$tmp->getId()] = 'BUNDLE'.$month;
  538.             } else {
  539.                 $tmp $this->entityManager->getRepository(DeviceGroup::class)->getByTitle('Bundle '.$month.' Monate');
  540.                 if ($tmp instanceof DeviceGroup) {
  541.                     $bundle_groups[$tmp->getId()] = 'BUNDLE'.$month;
  542.                 }
  543.             }
  544.         }
  545.         $device_sn $order->getDeviceCode();
  546.         // find orders
  547.         $orders $this->entityManager->getRepository(Order::class)->findByDeviceCode($order->getDeviceCode());
  548.         if (count($orders) > 0) {
  549.             // device has been used before
  550.             return $default;
  551.         }
  552.         foreach ($bundle_groups as $group_id => $coupon_code) {
  553.             /** @var DeviceGroup $device_group */
  554.             $device_group $this->entityManager->getRepository(DeviceGroup::class)->find($group_id);
  555.             if ($device_group->containsDeviceCode($device_sn)) {
  556.                 return $coupon_code;
  557.             }
  558.         }
  559.         return $default;
  560.     }
  561.     protected function checkDeviceSN(FormInterface $form)
  562.     {
  563.         $device_sn $form->get('deviceCode')->getData();
  564.         /** @var User $user */
  565.         $user $this->getUser();
  566.         $device ProthelisApi::getDevice($device_sn);
  567.         /**
  568.          * check for different owner
  569.          */
  570.         if ($device && count($device->owners) > 0) {
  571.             $is_owner false;
  572.             foreach ($device->owners as $owner) {
  573.                 if ($owner->user_id === $user->getIdApi()) {
  574.                     $is_owner true;
  575.                 }
  576.             }
  577.             if (!$is_owner) {
  578.                 $form->get('deviceCode')->addError(
  579.                     new FormError(
  580.                         $this->translator->trans('account.order.error_device_taken')
  581.                     )
  582.                 );
  583.             }
  584.         }
  585.         /**
  586.          * check for deactivated
  587.          */
  588.         if ($device && $device->sim_provider==='freeeway' && $device->properties->sim_state == 120) {
  589.             $form->get('deviceCode')->addError(
  590.                 new FormError(
  591.                     $this->translator->trans('account.order.error_device_deactivated')
  592.                 )
  593.             );
  594.         }
  595.         /**
  596.          * check for incomplete orders
  597.          */
  598.         $incomplete_order $this->entityManager->getRepository(Order::class)->findUnfinishedBySnAndUser(
  599.             $device_sn,
  600.             $user
  601.         );
  602.         if (!empty($incomplete_order)) {
  603.             $form->get('deviceCode')->addError(
  604.                 new FormError(
  605.                     $this->translator->trans('account.order.error_open_order')
  606.                 )
  607.             );
  608.         }
  609.         /**
  610.          * check for active subscription
  611.          */
  612.         $hasSubscription $this->subscriptionService->hasActiveSubscription($device_sn);
  613.         if ($hasSubscription) {
  614.             $form->get('deviceCode')->addError(
  615.                 new FormError(
  616.                     $this->translator->trans('account.order.error_active_subscription')
  617.                 )
  618.             );
  619.         }
  620.     }
  621.     protected function setOrderDeviceData(Order $order$device_sn) {
  622.         $device ProthelisApi::getDevice($device_sn);
  623.         $device_name 'undefined';
  624.         if ($device) {
  625.             //TODO: define a better mapping process
  626.             $needle strtoupper(substr($device->hw_version03));
  627.             switch ($needle) {
  628.                 case 'G09':
  629.                     //GRETA
  630.                     $device_name 'GRETA';
  631.                     break;
  632.                 case 'GT0':
  633.                 case 'G02':
  634.                     //meintal
  635.                     $device_name 'meintal';
  636.                     break;
  637.                 case 'GU0':
  638.                 case 'G05':
  639.                     //area
  640.                     $device_name 'area';
  641.                     break;
  642.                 default:
  643.                     //undefined, probably GRETA
  644.                     $device_name 'GRETA';
  645.             }
  646.         }
  647.         $order->setDeviceType($device_name);
  648.     }
  649. }