src/Controller/GroupSessionController/UserGroupSessionController.php line 166

Open in your IDE?
  1. <?php
  2. namespace App\Controller\GroupSessionController;
  3. use App\Entity\Child;
  4. use App\Entity\Gender;
  5. use App\Entity\Session;
  6. use App\Entity\SessionOrder;
  7. use App\Entity\StripePlanForGroup;
  8. use App\Entity\Subject;
  9. use App\Entity\User;
  10. use App\Notification\EmailNotification;
  11. use App\Notification\SlackClient;
  12. use App\Order\OrderHelper;
  13. use App\Repository\DiscountRepository;
  14. use App\Repository\HolidayRepository;
  15. use App\Repository\LevelTestRepository;
  16. use App\Repository\SessionRegistrationDateRepository;
  17. use App\Repository\SessionRepository;
  18. use App\Repository\StripePlanForGroupRepository;
  19. use App\Repository\SubjectRepository;
  20. use App\Service\ActiveCampaignHelper;
  21. use App\Service\Currency\CurrencyChangeService;
  22. use App\StripeClient;
  23. use Doctrine\ORM\EntityManagerInterface;
  24. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  25. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  26. use Stripe\Invoice;
  27. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  28. use Symfony\Component\HttpFoundation\RedirectResponse;
  29. use Symfony\Component\HttpFoundation\Request;
  30. use Symfony\Component\HttpFoundation\Response;
  31. use Symfony\Component\HttpFoundation\Session\Session as SessionSymfo;
  32. use Symfony\Component\Routing\Annotation\Route;
  33. /**
  34.  * @Route("/session")
  35.  */
  36. class UserGroupSessionController extends AbstractController
  37. {
  38.     private $em;
  39.     private $stripeClient;
  40.     private $emailNotification;
  41.     private $slackClient;
  42.     private $activeCampaignHelper;
  43.     public function __construct(EntityManagerInterface $emStripeClient $stripeClientEmailNotification $emailNotificationSlackClient $slackClient,
  44.                                 ActiveCampaignHelper   $activeCampaignHelper
  45.     ) {
  46.         $this->em                   $em;
  47.         $this->stripeClient         $stripeClient;
  48.         $this->emailNotification    $emailNotification;
  49.         $this->slackClient          $slackClient;
  50.         $this->activeCampaignHelper $activeCampaignHelper;
  51.     }
  52.     //Voir
  53.     /**
  54.      * @Route("/{gender}/{tag}", name="session_index", defaults={"tag": "alKaamil"}, methods={"GET"})
  55.      * @ParamConverter("gender", options={"mapping": {"gender" : "name"}})
  56.      * @param Gender $gender
  57.      * @param $tag
  58.      * @param SubjectRepository $subjectRepository
  59.      * @param SessionRepository $sessionRepository
  60.      * @param HolidayRepository $holidayRepository
  61.      * @param SessionRegistrationDateRepository $sessionRegistrationDateRepository
  62.      * @param LevelTestRepository $levelTestRepository
  63.      *
  64.      * @return Response
  65.      */
  66.     public function index(Gender                            $gender$tagSubjectRepository $subjectRepositorySessionRepository $sessionRepositoryHolidayRepository $holidayRepository,
  67.                           SessionRegistrationDateRepository $sessionRegistrationDateRepositoryLevelTestRepository $levelTestRepositoryRequest $request,
  68.                           DiscountRepository                $discountRepository
  69.     ): Response {
  70.         $parameter $request->query->get('d');
  71.         $discount $discountRepository->findOneBy([
  72.                                                        'urlParameter' => $parameter,
  73.                                                    ]);
  74.         $subject $subjectRepository->findOneBy([
  75.                                                      'tagName' => $tag,
  76.                                                  ]);
  77.         if ($discount) {
  78.             if ($discount->getSubject() == $subject) {
  79.                 $isDiscount     true;
  80.                 $discountAmount $discount->getAmount();
  81.                 $discountType   $discount->getType();
  82.             } else {
  83.                 $isDiscount     false;
  84.                 $discountAmount 0;
  85.                 $discountType   null;
  86.             }
  87.         } else {
  88.             $isDiscount     false;
  89.             $discountAmount 0;
  90.             $discountType   null;
  91.         }
  92.         if ( ! $subject) {
  93.             $this->addFlash('error'"Le programme demandé n'existe pas");
  94.             return $this->redirectToRoute('session_index', [
  95.                 'gender'  => $gender,
  96.                 '_locale' => $request->getLocale(),
  97.             ]);
  98.         }
  99.         $sessions $sessionRepository->openSessionByOrderSubjectGender(
  100.             $subject->getTagName(),
  101.             $gender->getName()
  102.         );
  103.         $holidays $holidayRepository->findAll();
  104.         $registrationDate $sessionRegistrationDateRepository->findOneBy([
  105.                                                                               'subject' => $subject,
  106.                                                                           ]);
  107.         $levelTestInfo $levelTestRepository->findOneBy([
  108.                                                              'type'    => "info",
  109.                                                              'subject' => $subject,
  110.                                                          ]);
  111.         return $this->render('session/index.html.twig', [
  112.             'sessions'         => $sessions,
  113.             'gender'           => $gender,
  114.             'local'            => $this->getParameter('locale'),
  115.             'holidays'         => $holidays,
  116.             'subject'          => $subject,
  117.             'registrationDate' => $registrationDate,
  118.             'levelTest'        => $levelTestInfo,
  119.             'isDiscount'       => $isDiscount,
  120.             'discountAmount'   => $discountAmount,
  121.             'discountType'     => $discountType,
  122.             'parameter'        => $parameter,
  123.         ]);
  124.     }
  125.     //Acheter
  126.     /**
  127.      * @Route("/order/purchase/{id}", name="session_purchase", requirements={"id":"\d+"}), methods={"GET","POST"})
  128.      * @ParamConverter("session", options={"id" : "id"})
  129.      * @Security("is_granted('ROLE_USER')")
  130.      * @param Session $session
  131.      * @param Request $request
  132.      * @param OrderHelper $orderHelper
  133.      * @param SessionSymfo $sessionSymfo
  134.      * @param StripePlanForGroupRepository $stripePlanForGroupRepository
  135.      *
  136.      * @return Response
  137.      */
  138.     public function purchase(Session            $sessionRequest $requestOrderHelper $orderHelperSessionSymfo $sessionSymfoStripePlanForGroupRepository $stripePlanForGroupRepository,
  139.                              DiscountRepository $discountRepositoryCurrencyChangeService $currencyChangeService
  140.     ): Response {
  141.         $isDiscount   false;
  142.         $sessionPrice $session->getPrice();
  143.         $parameter $request->query->get('d');
  144.         $discount $discountRepository->findOneBy([
  145.                                                        'urlParameter' => $parameter,
  146.                                                    ]);
  147.         if ($discount) {
  148.             /** @var StripePlanForGroup $plan */
  149.             $plan $stripePlanForGroupRepository->findOneBy([
  150.                                                                  'subject'    => $session->getLevel()->getSubject(),
  151.                                                                  'isDiscount' => true,
  152.                                                                  'discount'   => $discount,
  153.                                                              ]);
  154.             if ($plan) {
  155.                 $isDiscount true;
  156.                 $discountAmount $discount->getAmount();
  157.                 $discountType   $discount->getType();
  158.                 if ($discountType == 'fixe') {
  159.                     $sessionPrice $sessionPrice $discountAmount;
  160.                 } else {
  161.                     $deduction    = ($sessionPrice $discountAmount) / 100;
  162.                     $sessionPrice $sessionPrice $deduction;
  163.                 }
  164.             } else {
  165.                 /** @var StripePlanForGroup $plan */
  166.                 $plan $stripePlanForGroupRepository->findOneBy([
  167.                                                                      'subject'    => $session->getLevel()->getSubject(),
  168.                                                                      'isDiscount' => false,
  169.                                                                  ]);
  170.             }
  171.         } else {
  172.             /** @var StripePlanForGroup $plan */
  173.             $plan $stripePlanForGroupRepository->findOneBy([
  174.                                                                  'subject'    => $session->getLevel()->getSubject(),
  175.                                                                  'isDiscount' => false,
  176.                                                              ]);
  177.         }
  178.         $planId $plan->getStripeId();
  179.         $user $this->getUser();
  180.         $gender $session->getTeacher()->getUserId()->getGender();
  181.         if ($sessionSymfo->get('code-group')) {
  182.             $stripeCoupon $sessionSymfo->get('code-group');
  183.             $code         $stripeCoupon->amount_off 100;
  184.         } else {
  185.             $stripeCoupon false;
  186.             $code         0;
  187.         }
  188.         $currency $currencyChangeService->getCurrencyChangeForView($request);
  189.         $sessionPrice round($sessionPrice $currency['currencyRate']);
  190.         $error    false;
  191.         if ($request->isMethod('POST')) {
  192.             $token       $request->request->get('stripeToken');
  193.             $participant $request->request->get('child-select');
  194.             $paymentType $request->request->get('paymentType');
  195.             if ($session->getSeat() > 0) {
  196.                 try {
  197.                     if ($paymentType == "twoTime") {
  198.                         //paiement en deux fois
  199.                         $invoice $orderHelper->chargeCustomerForInstallement($token$user$planId);
  200.                     } else {
  201.                         if ($session->getPrice() == 0) {
  202.                             $sessionOrder $this->addSessionOrderToBdd($session$user"gratuit"0nullnullnullnullfalse$participant);
  203.                             $this->addFlash('success''Inscription completée ! Un mail vous a été envoyé, vérifiez vos courriers indésirables (SPAM) si vous ne l\'avez pas reçu.');
  204.                             return $this->redirectToRoute(
  205.                                 'confirmation_purchase',
  206.                                 [
  207.                                     'userId'    => $user->getId(),
  208.                                     'orderType' => 'group',
  209.                                     'orderId'   => $sessionOrder->getId(),
  210.                                     '_locale'   => $request->getLocale(),
  211.                                 ]
  212.                             );
  213.                         } else {
  214.                             $invoice $orderHelper->chargeCustomerSession($token$user$session$stripeCoupon$sessionPrice);
  215.                         }
  216.                     }
  217.                 } catch (\Stripe\Exception\CardException $e) {
  218.                     //error_log("A payment error occurred: {$e->getError()->message}");
  219.                     $error 'Il y a un problème pour charger votre carte: '.$e->getError()->message;
  220.                 } catch (\Stripe\Exception\InvalidRequestException $e) {
  221.                     $error 'Il y a un problème pour charger votre carte: '.$e->getError()->message;
  222.                 } catch (\Exception $e) {
  223.                     //error_log("Another problem occurred, maybe unrelated to Stripe.");
  224.                     $error 'Il y a un problème pour charger votre carte: '.$e;
  225.                 }
  226.                 if ( ! $error and $invoice->paid == true) {
  227.                     $sessionOrder $this->prepareCreationSessionOrderWithInvoice($invoice$user$session$participant$paymentType);
  228.                     $this->addFlash('success''Inscription completée ! Un mail vous a été envoyé, vérifiez vos courriers indésirables (SPAM) si vous ne l\'avez pas reçu.');
  229.                     $this->activeCampaignHelper->addOrder($sessionOrder);
  230.                     $this->activeCampaignHelper->updateCustomFieldLastLevelTestForContact($sessionOrder->getStudents()->getEmail(), $session);
  231.                     return $this->redirectToRoute(
  232.                         'confirmation_purchase',
  233.                         [
  234.                             'userId'    => $user->getId(),
  235.                             'orderType' => 'group',
  236.                             'orderId'   => $sessionOrder->getId(),
  237.                             '_locale'   => $request->getLocale(),
  238.                         ]
  239.                     );
  240.                 } else {
  241.                     $this->addFlash('error'$error);
  242.                     return $this->redirectToRoute('session_purchase', [
  243.                         'id'      => $session->getId(),
  244.                         '_locale' => $request->getLocale(),
  245.                     ]);
  246.                 }
  247.             } else {
  248.                 $this->addFlash('error'"Le groupe est complet, merci d'en choisir un autre");
  249.                 return $this->redirectToRoute('session_index', [
  250.                     'gender'  => $gender,
  251.                     '_locale' => $request->getLocale(),
  252.                 ]);
  253.             }
  254.         }
  255.         return $this->render('session/purchase.html.twig', [
  256.             'stripe_public_key' => $this->getParameter('stripe_public_key'),
  257.             'session'           => $session,
  258.             'currentUser'       => $user,
  259.             'errorCard'         => $error,
  260.             'code'              => $code,
  261.             'plan'              => $plan,
  262.             'price'             => $sessionPrice,
  263.             'isDiscount'        => $isDiscount,
  264.             'currency'          => $currency,
  265.         ]);
  266.     }
  267.     /**
  268.      * @Route("/order/success/takallam", name="session_success_takallam", methods={"GET","POST"})
  269.      */
  270.     public function successTakallam(Request $request)
  271.     {
  272.         dd($request);
  273.         return $this->render('session/registration-takallam-success.twig');
  274.     }
  275.     /**
  276.      * @Route("/coupon", name="session_coupon_add", methods={"POST"})
  277.      * @Security("is_granted('ROLE_USER')")
  278.      * @param Request $request
  279.      * @param StripeClient $stripeClient
  280.      * @param SessionSymfo $sessionSymfo
  281.      *
  282.      * @return RedirectResponse
  283.      */
  284.     public function addCouponAction(Request $requestStripeClient $stripeClientSessionSymfo $sessionSymfo): RedirectResponse
  285.     {
  286.         $referer $request->headers->get('referer');
  287.         $code $request->request->get('code');
  288.         if ( ! $code) {
  289.             $this->addFlash('error''Vous n\'avez entré aucun coupon');
  290.             return $this->redirect($referer);
  291.         }
  292.         try {
  293.             $stripeCoupon $stripeClient->findCoupon($code);
  294.         } catch (\Stripe\Exception\InvalidRequestException $e) {
  295.             $this->addFlash('error''Coupon Invalide');
  296.             return $this->redirect($referer);
  297.         }
  298.         if ($stripeCoupon->percent_off != null) {
  299.             $this->addFlash('error''Coupon invalide pour ces cours');
  300.             return $this->redirect($referer);
  301.         }
  302.         if ( ! $stripeCoupon->valid) {
  303.             $this->addFlash('error''Coupon expiré');
  304.             return $this->redirect($referer);
  305.         }
  306.         $sessionSymfo->set('code-group'$stripeCoupon);
  307.         return $this->redirect($referer);
  308.     }
  309.     /**
  310.      * @param Invoice $invoice
  311.      * @param User $user
  312.      * @param Session $session
  313.      * @param $participant
  314.      * @param $paymentType
  315.      */
  316.     private function prepareCreationSessionOrderWithInvoice(Invoice $invoiceUser $userSession $session$participant$paymentType)
  317.     {
  318.         $stripeCustomerId $invoice->customer;
  319.         $stripeCustomer = \Stripe\Customer::retrieve($stripeCustomerId);
  320.         if ($paymentType == "twoTime") {
  321.             $stripeSubscriptionId $invoice->subscription;
  322.             $stripeSubscription   = \Stripe\Subscription::retrieve($stripeSubscriptionId);
  323.             $subscriptionStatus $stripeSubscription->status;
  324.             if ($subscriptionStatus == 'active') {
  325.                 $paidAmount           = ($invoice->amount_paid 100) * 2;
  326.                 $nextPaymentTimeStamp $stripeSubscription->current_period_end;
  327.             } else {
  328.                 $this->addFlash('error'"Votre paiement n'a pas abouti");
  329.                 return $this->redirectToRoute('session_purchase', [
  330.                     'id'      => $session->getId(),
  331.                     '_locale' => $user->getLanguage()->getPole(),
  332.                 ]);
  333.             }
  334.         } else {
  335.             $paidAmount           $invoice->amount_paid 100;
  336.             $stripeSubscription   null;
  337.             $nextPaymentTimeStamp null;
  338.             $stripeSubscriptionId null;
  339.         }
  340.         $cardDetails $this->stripeClient->retrieveSource($stripeCustomerId$stripeCustomer->default_source);
  341.         $isTwoTime      $paymentType == "twoTime";
  342.         $cardBrand      $cardDetails->brand;
  343.         $cardLastDigits $cardDetails->last4;
  344.         $order $this->addSessionOrderToBdd(
  345.             $session,
  346.             $user,
  347.             $stripeCustomerId,
  348.             $paidAmount,
  349.             $cardBrand,
  350.             $cardLastDigits,
  351.             $nextPaymentTimeStamp,
  352.             $stripeSubscriptionId,
  353.             $isTwoTime,
  354.             $participant
  355.         );
  356.         return $order;
  357.     }
  358.     private function addSessionOrderToBdd(Session $sessionUser $user$stripeCustomerId$paidAmount$cardBrand$cardLastDigit$nextPaymentTimeStamp$stripeSubscriptionId,
  359.                                           bool    $isTwoTime$participant
  360.     ) {
  361.         $childRepo $this->em->getRepository(Child::class);
  362.         if ($participant) {
  363.             $participant $childRepo->findOneBy(['id' => $participant]);
  364.         } else {
  365.             $participant null;
  366.         }
  367.         $order = new SessionOrder();
  368.         $order->setSession($session)
  369.               ->setStripeCustomerId($stripeCustomerId)
  370.               ->setAmountPaid($paidAmount)
  371.               ->setIsActif(true)
  372.               ->setCanceledByStudent(false)
  373.               ->setCanceledByUs(false)
  374.               ->setCardBrand($cardBrand)
  375.               ->setCardLast4($cardLastDigit)
  376.               ->setIsTwoTime($isTwoTime)
  377.               ->setNextPaymentTimeStamp($nextPaymentTimeStamp)
  378.               ->setStripeSubscriptionId($stripeSubscriptionId)
  379.               ->setParticipant($participant)
  380.               ->setStudents($user)
  381.               ->setPaymentNb(1);
  382.         $session->decrementSeat();
  383.         $this->em->persist($session);
  384.         $this->em->persist($order);
  385.         $this->em->flush();
  386.         $program $order->getSession()->getLevel()->getProgramUrls();
  387.         $this->emailNotification->notifyStudentSessionOrder($order$user$program);
  388.         //$this->slackClient->notifySecretariatGroupSessionInscription($order, $user);
  389.         return $order;
  390.     }
  391. }