<?php
namespace App\Controller\Front;
use App\Entity\Educational\Discipline;
use App\Entity\Event\RegisterEvent;
use App\Entity\Event\Training\Pack;
use App\Entity\Management\Subscription\Discount;
use App\Entity\Management\Subscription\Mission;
use App\Entity\Management\Subscription\Purchase\MissionExam;
use App\Entity\Management\Subscription\Subscription;
use App\Entity\Management\Subscription\TransactionMission;
use App\Entity\Management\Subscription\TypeOffer;
use App\Entity\Users\Child;
use App\Entity\Users\Parents;
use App\Entity\Users\StudentsParents;
use App\Entity\Users\User;
use App\Form\ParentsRegistrationSecondStepType;
use App\Manager\Purchase\PurchaseTunnelManager;
use App\Service\Mailer\SubscriptionMailer;
use App\Service\StripeService;
use App\Service\JWTService;
use Doctrine\ORM\EntityManagerInterface;
use Stripe\Exception\ApiErrorException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class MissionPurchaseController extends AbstractController
{
/**
* @Route("/mission-exam/choix-des-annales",name="choice-mission")
*/
public function choiceOffer(Request $request,EntityManagerInterface $entityManager){
$getMission = $request->get('mission');
$getPrice = $request->get('price');
$popinChoiceMission = false;
$missionsPrice = $packs = [];
$productFb = 'bac-francais';
$title = 'Bac français';
$typeOffer = null;
$user = $this->getUser();
$listMissionCustomer = [];
if($user instanceof Child){
$last = $entityManager->getRepository(Subscription::class)->getLastSubscriptionByStudent($user);
if($last){
$guardiant = $last->getGuardiant();
if(!is_null($guardiant)){
$paramerters = array_merge($request->query->all(),['_switch_user'=>$guardiant->getEmail()]);
return $this->redirectToRoute('choice-mission',$paramerters );
}
return $this->redirectToRoute('dashboard');
}
}
if(in_array($getMission,['bac','brevet','bac-francais','bac-francais-techno'])){
$popinChoiceMission = true;
$slug = 'bac-francais';
$productFb = 'bac-francais';
if($getMission == 'bac'){
$slug = 'mission-bac';
$title = 'Bac';
$productFb = 'bac';
}
if($getMission == 'brevet'){
$title = 'Brevet';
$slug = 'mission-brevet';
$productFb = 'brevet';
}
if($getMission == 'bac-francais-techno'){
$title = 'Bac Français technologie';
$slug = 'bac-francais-techno';
$productFb = 'bac-francais-techno';
}
$missionsPrice = $entityManager->getRepository(Mission::class)->getMissionsPrice($slug);
$typeOffer = $entityManager->getRepository(TypeOffer::class)->findOneBySlug($slug);
if($typeOffer && $typeOffer->isDisplayPack()){
$packs = $typeOffer->getPacks();
}
}
if($user instanceof Parents){
$listMissionCustomer = $entityManager->getRepository(MissionExam::class)->getAllListMissionByParent($user);
if(($getMission == 'brevet' || $getMission == 'bac-francais' || $getMission == 'bac-francais-techno') && $typeOffer){
$checkIf = $entityManager->getRepository(MissionExam::class)->checkIfPurchase($user->getId(),$typeOffer->getId());
if(!empty($checkIf)){
$this->addFlash('notice',"Vous avez déjà effectué cet achat");
return $this->redirectToRoute('dashboard');
}
}
}
$session = $request->getSession();
$disciplines = $entityManager->getRepository(Discipline::class)->findAll();
if($request->isMethod('post')){
$selectDis = $request->request->get('dis');
$price = $request->request->get('price');
$priceE = $entityManager->getRepository(Mission::class)->find($price);
if($priceE && (is_array($selectDis) && $priceE->getNbrDis()==count($selectDis) || $getMission != 'bac')){
$missionsBasket = $session->get('missionExam');
$missionsBasket['step_1'] = [
'getMission' =>$getMission,
'disciplines'=>$selectDis,
'price' =>$price,
'discount' =>$request->request->get('discount'),
'titleExam' =>$title,
'productFb' =>$productFb,
];
$session->set('missionExam',$missionsBasket);
return $this->redirectToRoute('register-mission',['mission'=>$getMission]);
}
}
return $this->render('front/purchase/mission/choice-offer.html.twig',[
'disciplines' =>$disciplines,
'getMission' =>$getMission,
'getPrice' =>$getPrice,
'popinChoiceMission' =>$popinChoiceMission,
'missionsPrice' =>$missionsPrice,
'titleExam' =>$title,
'typeOffer' =>$typeOffer,
'packs' =>$packs,
'listMissionCustomer'=>$listMissionCustomer
]);
}
/**
* @Route("/mission-exam/register",name="register-mission")
*/
public function register(Request $request,EntityManagerInterface $entityManager){
$session = $request->getSession();
$missionsBasket = $session->get('missionExam');
$isValid = true;
$parents = new Parents();
if(!$missionsBasket || !is_array($missionsBasket['step_1'])){
return $this->redirectToRoute('choice-mission');
}
$user = $this->getUser();
$listChild = [];
$getMission = $missionsBasket['step_1']['getMission'];
$title = $missionsBasket['step_1']['titleExam'];
$price = $missionsBasket['step_1']['price'];
$formOptions = [];
$formOptions['profil_parent'] = User::PROFIL_PARENT;
if($user){
if($user instanceof Parents){
$mission = $entityManager->getRepository(Mission::class)->find($price);
if($mission){
if(($getMission == 'brevet' || $getMission == 'bac-francais' || $getMission == 'bac-francais-techno') && $mission->getTypeOffer()) {
$checkIf = $entityManager->getRepository(MissionExam::class)->checkIfPurchase($user->getId(), $mission->getTypeOffer()->getId());
if (!empty($checkIf)) {
$this->addFlash('notice', "Vous avez déjà effectué cet achat");
return $this->redirectToRoute('dashboard');
}
}
}
$parents = $user;
$listChild = $entityManager->getRepository(StudentsParents::class)->getByParent($user);
$missionsBasket['step_2']['isCurrentUser'] = true;
$session->set('missionExam',$missionsBasket);
}else{
$last = $entityManager->getRepository(Subscription::class)->getLastSubscriptionByStudent($user);
if($last){
$guardiant = $last->getGuardiant();
$paramerters = array_merge($request->query->all(),['_switch_user'=>$guardiant->getEmail()]);
return $this->redirectToRoute('register-mission',$paramerters);
}
return $this->redirectToRoute('dashboard');
}
}
$form = $this->createForm(ParentsRegistrationSecondStepType::class, $parents, $formOptions);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$data = $request->request->all();
$missionsBasket['step_2']['infos'] = $data;
$session->set('missionExam',$missionsBasket);
return $this->redirectToRoute('paiement-mission',['mission'=>$getMission]);
}else{
$isValid = false;
}
}
$priceE = $entityManager->getRepository(Mission::class)->find($price);
return $this->render("front/purchase/mission/register.html.twig",[
'getMission' => $getMission,
'form' => $form->createView(),
'profilEleveParent' => "parent",
'isValid' => $isValid,
'titleExam' => $title,
'listChild' => $listChild,
'priceE' => $priceE
]);
}
/**
*
* @Route("/mission-exam/paiement",name="paiement-mission")
*/
public function paiement(Request $request,EntityManagerInterface $entityManager,StripeService $stripeService)
{
$session = $request->getSession();
$missionsBasket = $session->get('missionExam');
if(!$missionsBasket || !is_array($missionsBasket['step_2'])){
return $this->redirectToRoute('register-mission');
}
$getMission = $missionsBasket['step_1']['getMission'];
$title = $missionsBasket['step_1']['titleExam'];
$productFb = $missionsBasket['step_1']['productFb'];
$mission = $entityManager->getRepository(Mission::class)->find($missionsBasket['step_1']['price']);
$discount = $entityManager->getRepository(Discount::class)->findOneByCodePromo($missionsBasket['step_1']['discount']);
if($mission){
$som = $mission->getPrice();
if($discount){
$som = $mission->getPrice() - $mission->getPrice()*$discount->getPercent()/100;
}
$titleDis = [];
if($missionsBasket['step_1']['disciplines']){
foreach ($missionsBasket['step_1']['disciplines'] as $disc){
//$discipline = $entityManager->getRepository(Discipline::class)->find($disc);
$discipline = $entityManager->getRepository(Pack::class)->find($disc);
$titleDis[] = $discipline->getTitle();
}
}
$missionsBasket['step_1']['som'] = $som;
$session->set('missionExam',$missionsBasket);
return $this->render("front/purchase/mission/paiement.html.twig",[
'SPK' =>$stripeService->getPublishableKey(),
'getMission' =>$getMission,
'titleExam' =>$title,
'discount' =>$discount,
'mission' =>$mission,
'som' =>$som,
'titleDis' =>$titleDis,
'productFb'=> $productFb
]);
}
return $this->redirectToRoute('choice-mission');
}
public function processPaiement(){
}
/**
* @return JsonResponse
* @Route("/setup/charge/paiement",name="setup-mission-paiement")
*/
public function chargeIntentPayment(Request $request, StripeService $stripeService,EntityManagerInterface $entityManager)
{
$session = $request->getSession();
$discountParameters = [];
$user = $this->getUser();
if($request->isXmlHttpRequest()){
$paymentMethod = $request->request->get('pid');
if (!empty($paymentMethod)) {
$missionsBasket = $session->get('missionExam');
if(is_array($missionsBasket['step_1'])){
$priceId = $missionsBasket['step_1']['price'];
$mission = $entityManager->getRepository(Mission::class)->find($priceId);
$findDiscount = null;
if($mission){
$som = $mission->getPrice();
if($missionsBasket['step_1']['discount']){
$findDiscount = $entityManager->getRepository(Discount::class)->findOneByCodePromo($missionsBasket['step_1']['discount']);
if($findDiscount){
$som = $mission->getPrice() - $mission->getPrice()*$findDiscount->getPercent()/100;
}
}
$user = $this->getUser();
if(!$user){
$email = $missionsBasket['step_2']['infos']['parents_registration_second_step']['email']['first'];
$cus = $stripeService->getStripeClient()->customers->create([
"email" => $email,
]);
$cusId = $cus->id;
}else{
$email = $user->getEmail();
$cusId = $user->getStripeId();
if(is_null($cusId)){
$cus = $stripeService->getStripeClient()->customers->create([
"email" => $email,
]);
$cusId = $cus->id;
}
}
$invoice = $stripeService->getStripeClient()->invoices->create([
"description"=>"Facture {$mission->getTypeOffer()->getTitle()} - {$email}",
"customer" =>$cusId
]);
$data = [
"amount"=>round(100*$mission->getPrice(),0),
"description"=>"{$mission->getTypeOffer()->getTitle()} : {$mission->getTitle()}",
'currency' => 'eur',
'invoice'=>$invoice->id,
'customer'=>$cusId
];
if($findDiscount){
$data['discounts']= [['coupon'=>strtoupper($findDiscount->getStripeId())]];
}
$stripeService->getStripeClient()->invoiceItems->create($data);
$returnInvoice = $stripeService->getStripeClient()->invoices->finalizeInvoice($invoice->id);
$parameters = ['cus'=>$cusId,'invoice'=>$invoice->id,'paymentMethod'=>$paymentMethod];
if($returnInvoice->amount_due!=0){
$paymentIntent = $stripeService->getStripeClient()->paymentIntents->retrieve($returnInvoice->payment_intent);
$parameters = array_merge($parameters,['free'=>false,'clientsecret'=>$paymentIntent->client_secret,'pId'=>$paymentIntent->id,]);
}else{
$parameters['free'] = true;
}
$missionsBasket['step_3']['paiement'] = ['pi'=>$returnInvoice->id];
$session->set('missionExam',$missionsBasket);
$infos = [
"disciplines" => !empty($missionsBasket['step_1']['disciplines']) ?$missionsBasket['step_1']['disciplines']:null,
];
$new = new TransactionMission();
$new->setOffer($mission);
$new->setEmailParents($email);
$new->setDiscount($findDiscount);
$new->setInvoice($invoice->id);
$new->setCustomer($user);
$new->setIsfinish(false);
$new->setInfosMissions($infos);
$new->setInfosChild(!empty($missionsBasket['step_2']['infos']['parents_registration_second_step']['childrenForm'])?$missionsBasket['step_2']['infos']['parents_registration_second_step']['childrenForm']:[]);
$entityManager->persist($new);
$entityManager->flush();
$parameters['tm'] = $new->getId();
return new JsonResponse(array_merge(['success'=>true],$parameters));
}
}
}
return new JsonResponse(['success' => false,]);
}
return $this->redirectToRoute('');
}
/**
* @return JsonResponse
* @Route("/proccess/paiement/mission-exam",name="process-mission-paiement")
*/
public function proccess(Request $request, SubscriptionMailer $subscriptionMailer,StripeService $stripeService,EntityManagerInterface $entityManager,PurchaseTunnelManager $purchaseTunnelManager)
{
if($request->isMethod('post')){
$user = $this->getUser();
$session = $request->getSession();
$missionsBasket = $session->get('missionExam');
$childTab = [];
$newParent = false;
$priceId = $missionsBasket['step_1']['price'];
$getMission = $missionsBasket['step_1']['getMission'];
$mission = $entityManager->getRepository(Mission::class)->find($priceId);
if($mission){
$som = $mission->getPrice();
$findDiscount = null;
if($missionsBasket['step_1']['discount']){
$findDiscount = $entityManager->getRepository(Discount::class)->findOneByCodePromo($missionsBasket['step_1']['discount']);
if($findDiscount){
$som = $mission->getPrice() - $mission->getPrice()*$findDiscount->getPercent()/100;
}
}
if(!$user){
$parent = $purchaseTunnelManager->createParentTunnel($missionsBasket['step_2']['infos']['parents_registration_second_step']);
$parent->setStripeId($request->request->get('customer'));
$entityManager->persist($parent);
$entityManager->flush();
$newParent = true;
$token = new UsernamePasswordToken($parent, $parent->getPassword(), "main", $parent->getRoles());
$this->get("security.token_storage")->setToken($token);
$this->get('session')->set('_security_main', serialize($token));
$event = new InteractiveLoginEvent($request, $token);
$dispatcher = new EventDispatcher();
$dispatcher->dispatch($event, "security.interactive_login");
}else{
$parent = $user;
$list = $entityManager->getRepository(Parents::class)->findChildrenEntityByParent($parent);
foreach ($list as $row){
$row->addRoles("ROLE_EXAM");
$entityManager->flush();
$childTab[] = $row;
}
}
if(!empty($missionsBasket['step_2']['infos']['parents_registration_second_step']['childrenForm'])){
$now = new \DateTime('now');
foreach ($missionsBasket['step_2']['infos']['parents_registration_second_step']['childrenForm'] as $childinfos){
$child = $purchaseTunnelManager->registrationStudent($childinfos);
$child->addRoles("ROLE_EXAM");
$entityManager->persist($child);
$entityManager->flush();
$stP = new StudentsParents();
$stP->setStudent($child);
$stP->setParents($parent);
$stP->setEnabled(true);
$entityManager->persist($stP);
$entityManager->flush();
$sub = new Subscription();
$sub->setOffer($mission);
$sub->setStudent($child);
$sub->setGuardiant($parent);
$sub->setPrice($som);
$sub->setSubscripted($now);
$sub->setDiscount($findDiscount);
$sub->setUnSubscripted((clone $now)->modify('+2 second'));
$entityManager->persist($sub);
$entityManager->flush();
$childTab[] = $child;
}
}
$new = new MissionExam();
$new->setMission($mission);
$new->setPrice($som);
$new->setCustomer($parent);
$new->setDiscount($findDiscount);
$new->setTitle($mission->getTitle());
$new->setNbrDis($mission->getNbrDis());
$new->setPaymentIntent($request->request->get('invoice'));
$entityManager->persist($new);
$entityManager->flush();
if($missionsBasket['step_3']){
$listPack = empty($missionsBasket['step_1']['disciplines'])?$mission->getTypeOffer()->getPacks():$missionsBasket['step_1']['disciplines'];
foreach ($listPack as $disc){
//$discipline = $entityManager->getRepository(Discipline::class)->find($disc);
$discipline = $entityManager->getRepository(Pack::class)->find($disc);
if($discipline){
//$new->addDisciplines($discipline);
$new->addPacks($discipline);
$entityManager->flush();
foreach ($childTab as $child){
$register = new RegisterEvent($discipline,$child);
$entityManager->persist($register);
$entityManager->flush();
}
}
}
}
$title = $missionsBasket['step_1']['titleExam'];
$subscriptionMailer->missionExam($parent, $title,$this->getUser(),$newParent);
$text="Nous vous remercions d’avoir choisi Les Bons Profs pour vos révisions du {$title}.<br/>Afin d'accéder à <b>{$mission->getTypeOffer()->getTitle()}</b> vérifiez que le profil de votre enfant est bien configuré au niveau de la classe";
if(!$this->getUser()){
$text .= "<br/>Connectez-vous à l’aide de vos identifiants";
}
$this->addFlash('notice',$text);
$session->remove('missionExam');
$stripeService->getStripeClient()->invoices->update($request->request->get('invoice'),[
['metadata' => ['purchase_id' => $new->getId()]]
]);
$tmId = $request->request->get('tm');
$tm = $entityManager->getRepository(TransactionMission::class)->find($tmId);
if($tm){
$tm->setIsfinish(true);
$tm->setCustomer($user);
$entityManager->flush();
}
return $this->redirectToRoute('dashboard-mission-success',['mission'=>$getMission]);
}
}
}
/**
* @return JsonResponse
* @Route("/validation/paiement/mission",name="validation-mission-paiement")
*/
public function validation()
{
}
}