<?php
namespace App\Controller;
use App\Client\StripeClient;
use App\Dto\Slot;
use App\Entity\Account;
use App\Entity\CustomerProfile;
use App\Entity\GroupSession;
use App\Entity\Need;
use App\Entity\Partner;
use App\Entity\PartnerNote;
use App\Entity\PartnerSecondaryLocation;
use App\Entity\PartnerSubscription;
use App\Entity\Reservation;
use App\Entity\ReservationPayment;
use App\Entity\ReservationPaymentLog;
use App\Entity\ServiceDelivery;
use App\Entity\ServiceDeliveryPlace;
use App\Entity\Speciality;
use App\Entity\User;
use App\Entity\VillesFrance;
use App\Form\PartnerNoteType;
use App\Form\UserLoginType;
use App\Form\UserRegisterType;
use App\Security\PasswordEncoder;
use App\Service\GoogleCalendarService;
use App\Service\ICalService;
use App\Service\MailjetEmailService;
use App\Utils\AgendaUtils;
use Doctrine\ORM\EntityManagerInterface;
use Stripe\Exception\ApiErrorException;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Validator\Constraints\NotBlank;
use ICal\ICal;
/**
* Class Defaultcontroller
* @package App\Controller
*
* @Route("/", name="default_")
*/
class DefaultController extends AbstractController
{
private $em;
private $agendaUtils;
private $passwordEncoder;
private $session;
private $tokenStorage;
private $eventDispatcher;
private $stripeClient;
private $mailjetEmailService;
private $icalService;
private $googleCalendarService;
public function __construct(EntityManagerInterface $em, AgendaUtils $agendaUtils, PasswordEncoder $passwordEncoder, SessionInterface $session, TokenStorageInterface $tokenStorage, EventDispatcherInterface $eventDispatcher, StripeClient $stripeClient, MailjetEmailService $mailjetEmailService, ICalService $icalService, GoogleCalendarService $googleCalendarService)
{
$this->em = $em;
$this->agendaUtils = $agendaUtils;
$this->passwordEncoder = $passwordEncoder;
$this->session = $session;
$this->tokenStorage = $tokenStorage;
$this->eventDispatcher = $eventDispatcher;
$this->stripeClient = $stripeClient;
$this->mailjetEmailService = $mailjetEmailService;
$this->icalService = $icalService;
$this->googleCalendarService = $googleCalendarService;
}
/**
* @Route(
* path="/",
* name="home",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function homeAction(Request $request, EntityManagerInterface $em)
{
$needs = $em->getRepository(Need::class)->findBy([], ["label" => "ASC"]);
$specialities = $em->getRepository(Speciality::class)->findBy([], ["label" => "ASC"]);
return $this->render('index.html.twig', [
"needs" => $needs,
"specialities" => $specialities,
]);
}
/**
* @Route(
* path="/login",
* name="login",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function loginAction(Request $request, EntityManagerInterface $em)
{
$user = new User();
$formRegister = $this->createForm(UserRegisterType::class, $user);
$registerError = null;
$registerSuccess = null;
$account = new Account();
$formLogin = $this->createForm(UserLoginType::class, $account);
$loginError = null;
$handleRegister = $this->handleRegister($formRegister, $user, $request);
if ($handleRegister) {
if ($handleRegister['success']) {
$registerSuccess = "Bienvenue sur ZenDez-Vous ! Votre compte a été créé avec succès. Vous pouvez dès maintenant vous connecter.";
} else {
$registerError = $handleRegister['message'];
}
}
$handleLogin = $this->handleLogin($formLogin, $request);
if ($handleLogin) {
if ($handleLogin['success']) {
return $this->redirectToRoute('default_home');
} else {
$loginError = $handleLogin['message'];
}
}
return $this->render('login.html.twig', [
"formRegister" => $formRegister->createView(),
"registerError" => $registerError,
"registerSuccess" => $registerSuccess,
"formLogin" => $formLogin->createView(),
"loginError" => $loginError,
]);
}
/**
* @Route(
* path="/login-pro",
* name="login_pro",
* )
*
* @return Response
*/
public function loginProAction(Request $request, EntityManagerInterface $em)
{
return $this->render('login-pro.html.twig', [
]);
}
private function handleRegister(FormInterface $form, User $user, Request $request)
{
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$account = $this->em->getRepository(Account::class)->findOneBy(['email' => $form->get('email')->getData()]);
if (!$account) {
if ($form->get('password')->getData() == $form->get('password2')->getData()) {
$this->em->persist($user);
$this->em->flush();
$account = new Account();
$account->setEmail($form->get('email')->getData());
$account->setRegistrationDate(new \DateTime('now'));
$salt = md5(uniqid());
$account->setSalt($salt);
$enc_pwd = $this->passwordEncoder->encodePassword($form->get('password')->getData(), $salt);
$account->setPassword($enc_pwd);
$account->setEnabled(true);
$account->setUser($user);
$account->setRoles(["ROLE_USER"]);
$this->em->persist($account);
$this->em->flush();
$stripeCustomer = $this->stripeClient->createCustomer($account, $account->getEmail(), $user->getFirstName(), $user->getLastName());
if ($stripeCustomer && $stripeCustomer->id) {
$account->setStripeCustomerId($stripeCustomer->id);
$this->em->flush();
}
$this->mailjetEmailService->send(
"Bienvenue sur ZenDez-Vous",
$account->getEmail(),
4686131,
[
"title" => "Bienvenue !",
"content" => "Bonjour " . $user->getFirstName() . "<br/><br/>L'équipe ZenDez-Vous vous remercie pour votre inscription.<br/>Accèdez dès maintenant à des milliers de créneaux disponibles avec nos praticiens.<br/><br/>Vous ne savez pas par où commencer ? Prenez rendez-vous avec un de nos coachs pour faire le point sur vos besoins et obtenir un parcours de bien-être approprié.",
"email" => $account->getEmail(),
]);
return [
'success' => true,
];
} else {
return [
'success' => false,
'message' => 'Les mots de passes ne correspondent pas.',
];
}
} else {
return [
'success' => false,
'message' => 'Cet adresse email est déjà utilisé.',
];
}
}
return null;
}
private function handleLogin(FormInterface $form, Request $request)
{
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$account = $this->em->getRepository(Account::class)->findOneBy(['email' => $form->get('email')->getData()]);
if ($account) {
$isValid = $this->passwordEncoder->isPasswordValid($account->getPassword(), $form->get('password')->getData(), $account->getSalt());
if ($isValid) {
if ($account->getEnabled()) {
$firewall = 'main';
$token = new UsernamePasswordToken($account, $firewall, $account->getRoles());
$this->tokenStorage->setToken($token);
$this->session->set('_security_' . $firewall, serialize($token));
$event = new InteractiveLoginEvent($request, $token);
$this->eventDispatcher->dispatch($event, SecurityEvents::INTERACTIVE_LOGIN);
$account->setLastLogin(new \DateTime('now'));
$this->em->flush();
return [
'success' => true,
];
} else {
return [
'success' => false,
'message' => 'Votre compte n\'est pas actif.',
];
}
} else {
return [
'success' => false,
'message' => 'Identifiant et/ou mot de passe incorrect.',
];
}
} else {
return [
'success' => false,
'message' => 'Identifiant et/ou mot de passe incorrect.',
];
}
}
return null;
}
/**
* @Route(
* path="/logout",
* name="logout"
* )
*
* @return Response
*/
public function logoutAction(Request $request, EntityManagerInterface $em)
{
$this->tokenStorage->setToken(null);
$this->session->invalidate();
return $this->redirectToRoute("default_home");
}
/**
* @Route(
* path="/forgot",
* name="forgot_password"
* )
*
* @return Response
*/
public function forgotPasswordAction(Request $request, EntityManagerInterface $em, MailjetEmailService $mailjetEmailService)
{
$form = $this->createFormBuilder()
->add('email', EmailType::class, array(
'attr' => array(
'placeholder' => 'Adresse mail',
),
'required' => true,
))
->getForm();
$form->handleRequest($request);
$success = null;
$error = null;
if ($form->isSubmitted()) {
if ($form->isValid()) {
$data = $form->getData();
$account = $em->getRepository(Account::class)->findOneBy(["email" => $data["email"]]);
if ($account) {
if ($account->getEnabled()) {
$now = new \DateTime('now');
if (!$account->getPasswordRequestDate() || $now->getTimestamp() - $account->getPasswordRequestDate()->getTimestamp() >= 86400) {
$token = hash("sha256", uniqid());
$account->setPasswordRequest($token);
$account->setPasswordRequestDate(new \DateTime('now'));
$em->flush();
$url = $this->generateUrl("default_reset_password", ["email" => $account->getEmail(), "token" => $token], UrlGeneratorInterface::ABSOLUTE_URL);
$content = <<<EOD
<br/>
Vous avez effectué une demande de réinitialisation de mot de passe pour votre compte ZenDez-Vous<br/>
<br/>
Pour définir un nouveau mot de passe, rendez-vous sur le lien suivant:<br/>
<a href="$url">$url</a>
EOD;
$mailjetEmailService->send(
"ZenDez-Vous: réinitialisation de votre mot de passe",
$account->getEmail(),
4686131,
[
"title" => "Réinitialisation de votre mot de passe",
"content" => $content,
"email" => $account->getEmail(),
]);
$success = "Si un compte existe à cette adresse email, un mail contenant un lien de réinitialisation a été envoyé à l'adresse indiquée. Ce lien est valide pendant 24h.";
} else {
$error = "Une demande de réinitialisation est déjà en cours. Veuillez vérifier votre boite mail.";
}
} else {
$error = "Votre compte n'est pas actif";
}
} else {
$success = "Si un compte existe à cette adresse email, un mail contenant un lien de réinitialisation a été envoyé à l'adresse indiquée. Ce lien est valide pendant 24h.";
}
} else {
$error = "Merci de saisir une adresse mail valide";
}
}
return $this->render('forgot.html.twig', [
"form" => $form->createView(),
"success" => $success,
"error" => $error,
]);
}
/**
* @Route(
* path="/reset-password/{email}/{token}",
* name="reset_password"
* )
*
* @return Response
*/
public function resetPasswordAction(Request $request, EntityManagerInterface $em, PasswordEncoder $passwordEncoder)
{
$account = $em->getRepository(Account::class)->findOneBy(["email" => $request->get("email")]);
if ($account) {
if ($account->getPasswordRequest() && $account->getPasswordRequestDate()) {
if ($account->getPasswordRequest() == $request->get("token")) {
$now = new \DateTime('now');
if ($now->getTimestamp() - $account->getPasswordRequestDate()->getTimestamp() < 86400) {
$form = $this->createFormBuilder()
->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'invalid_message' => 'Les mot de passe ne sont pas identiques',
'first_options' => array(
"label" => 'Nouveau mot de passe',
'attr' => array(
'placeholder' => ''
),
),
'second_options' => array("label" => 'Confirmation mot de passe', 'attr' => array('placeholder' => '')),
))->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$salt = md5(uniqid());
$pwd = $form['password']->getData();
$account->setSalt($salt);
$enc_pwd = $passwordEncoder->encodePassword($pwd, $salt);
$account->setPassword($enc_pwd);
$account->setPasswordRequest(null);
$account->setPasswordRequestDate(null);
$em->flush();
return $this->redirectToRoute("default_login");
}
return $this->render('reset_pwd.html.twig', [
"form" => $form->createView(),
]);
} else {
throw new NotFoundHttpException("Cette URL n'est plus valide");
}
} else {
throw new NotFoundHttpException("Cette URL n'est pas valide");
}
}
}
throw new NotFoundHttpException();
}
/**
* @Route(
* path="/join-us",
* name="join-us",
* )
*
* @return Response
*/
public function joinUsAction(Request $request, EntityManagerInterface $em)
{
return $this->redirectToRoute('default_nous-rejoindre', [], 301);
}
/**
* @Route(
* path="/nous-rejoindre",
* name="nous-rejoindre",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function nousRejoindreAction(Request $request, EntityManagerInterface $em)
{
return $this->render('join-us.html.twig', []);
}
/**
* @Route(
* path="/formations",
* name="formations",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function formationsAction(Request $request, EntityManagerInterface $em)
{
return $this->render('formations.html.twig', [
]);
}
/**
* @Route(
* path="/formations-partenaires",
* name="formations-partenaires",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function formationsPartenairesAction(Request $request, EntityManagerInterface $em)
{
return $this->render('formations-partenaires.html.twig', [
]);
}
/**
* @Route(
* path="/are-you-practitioner",
* name="are-you-practitioner",
* )
*
* @return Response
*/
public function areYouPractitionerAction(Request $request, EntityManagerInterface $em)
{
return $this->redirectToRoute('default_professionnels-du-bien-etre', [], 301);
}
/**
* @Route(
* path="/professionnels-du-bien-etre",
* name="professionnels-du-bien-etre",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function professionnelsDuBienEtreAction(Request $request, EntityManagerInterface $em)
{
return $this->render('are-you-practitioner.html.twig', []);
}
/**
* @Route(
* path="/offre-entreprise",
* name="offre-entreprise",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function offreEntrepriseAction(Request $request, EntityManagerInterface $em)
{
return $this->render('offre-entreprise.html.twig', [
]);
}
/**
* @Route(
* path="/conseils",
* name="conseils",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function conseilsAction(Request $request, EntityManagerInterface $em)
{
return $this->render('conseils.html.twig', [
]);
}
/**
* @Route(
* path="/besoins",
* name="besoins",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function besoinsAction(Request $request, EntityManagerInterface $em)
{
$needs = $em->getRepository(Need::class)->findBy([], ["label" => "ASC"]);
return $this->render('besoins.html.twig', [
"needs" => $needs,
]);
}
/**
* @Route(
* path="/mentions-legales",
* name="mentions_legales",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function mentionsLegalesAction(Request $request, EntityManagerInterface $em)
{
return $this->render('mentions-legales.html.twig', [
]);
}
/**
* @Route(
* path="/besoins/{slug}",
* name="besoins_fiche"
* )
*
* @return Response
*/
public function besoinsFicheAction(Need $need, Request $request, EntityManagerInterface $em)
{
return $this->render('besoins/fiche.html.twig', [
"need" => $need,
]);
}
/**
* @Route(
* path="/pratiques",
* name="pratiques",
* )
*
* @return Response
*/
public function pratiquesAction(Request $request, EntityManagerInterface $em)
{
return $this->redirectToRoute('praticiens_list', [], 301);
}
/**
* @Route(
* path="/pratiques/{slug}",
* name="pratiques_fiche"
* )
*
* @return Response
*/
public function pratiquesFicheAction(Speciality $speciality, Request $request, EntityManagerInterface $em)
{
return $this->redirectToRoute('praticiens_description', ["slugJob" => $speciality->getSlugJob()], 301);
}
/**
* @Route(
* path="/search",
* name="search",
* options={"sitemap" = true}
* )
*
* @return Response
*/
public function searchAction(Request $request, EntityManagerInterface $em)
{
$type = "practitionner";
$terms = $request->get('search');
$keywords= null;
if ($terms) {
$termsExplode = explode(" ", $terms);
if (count($termsExplode)) {
$keywords = $termsExplode;
}
}
$location = $request->get('location');
$lat = $request->get('lat');
if ($lat && $location) { $lat = floatval($lat); } else { $lat = null; }
$lon = $request->get('lon');
if ($lon && $location) { $lon = floatval($lon); } else { $lon = null; }
$radius = $request->get('rad');
if (!$radius || intval($radius) < 5 || intval($radius) > 50) {
$radius = 50;
} else {
$radius = intval($radius);
}
if ($location && (!$lat || !$lon)) {
$locationKeywords = null;
$locationExplode = explode(" ", $location);
if (count($locationExplode)) {
$locationKeywords = $locationExplode;
}
$cities = $this->em->getRepository(VillesFrance::class)->findByTerms($locationKeywords);
if ($cities) {
$city = $cities[0];
if ($city) {
$location = $city->getVilleNomReel();
$lat = $city->getVilleLatitudeDeg();
$lon = $city->getVilleLongitudeDeg();
}
}
}
$partners = $em->getRepository(Partner::class)->search($type, $keywords, $lat, $lon, $radius);
$partnersAllowed = $this::checkPartnerAllowed($partners);
// Autres en téléconsultation
$othersOnVisio = false;
if (count($partnersAllowed) == 0 && $lat && $lon) {
$partners = $em->getRepository(Partner::class)->search($type, $keywords, null, null, null, null, true);
$partnersAllowed = $this::checkPartnerAllowed($partners);
if (count($partnersAllowed) > 0) {
$othersOnVisio = true;
}
}
$specialitiesJobString = null;
$specialitiesJobsString = null;
if ($terms) {
$specialities = $this->em->getRepository(Speciality::class)->findByTerms($keywords);
$specialitiesJob = [];
$specialitiesJobs = [];
if ($specialities) {
foreach ($specialities as $speciality) {
$specialitiesJob[] = $speciality->getJob();
$specialitiesJobs[] = $speciality->getJobs();
}
$specialitiesJobString = implode(', ', $specialitiesJob);
$specialitiesJobsString = implode(', ', $specialitiesJobs);
}
}
return $this->render('search.html.twig', [
"type" => $type,
"partners" => $partnersAllowed,
"terms" => $terms,
"location" => $location,
"lat" => $request->get('lat'),
"lon" => $request->get('lon'),
"rad" => $radius,
"othersOnVisio" => $othersOnVisio,
"specialitiesJobString" => $specialitiesJobString,
"specialitiesJobsString" => $specialitiesJobsString,
]);
}
private function checkPartnerAllowed($partners)
{
return $this::checkPartnersAlloweds($partners);
}
public static function checkPartnersAlloweds($partners)
{
$partnersAllowed = [];
foreach ($partners as $p) {
$partner = $p[0];
if ($partner->getIsActivePractitioner()) {
$partnersAllowed[] = $partner;
}
}
return $partnersAllowed;
}
/**
* @Route(
* path="/praticien/{slug}",
* name="praticien_fiche"
* )
*
* @return Response
*/
public function praticienFicheAction(Partner $partner, Request $request, EntityManagerInterface $em)
{
if (!$partner->getIspractitioner()) {
throw new NotFoundHttpException();
}
if (!$partner->isSubscriptionActive() || !$partner->isValidatedPractitioner()) {
return $this->redirectToRoute("default_home");
}
$form = null;
$partnerNote = null;
if ($this->getUser() && $this->getUser()->getUser()) {
$partnerNote = $em->getRepository(PartnerNote::class)->findOneBy(["partner" => $partner, "user" => $this->getUser()->getUser()]);
if (!$partnerNote) {
$partnerNote = new PartnerNote();
$partnerNote->setUser($this->getUser()->getUser());
$partnerNote->setPartner($partner);
}
$form = $this->createForm(PartnerNoteType::class, $partnerNote);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em->persist($partnerNote);
$em->flush();
}
}
$groupSessions = $em->getRepository(GroupSession::class)->findAvailablesByPartner($partner);
return $this->render('praticien/fiche.html.twig', [
"practitioner" => $partner,
"form" => $form ? $form->createView() : null,
"partnerNote" => $partnerNote,
"groupSessions" => $groupSessions
]);
}
/**
* @Route(
* path="/checkout/identification",
* name="checkout_identification"
* )
*
* @return Response
*/
public function checkoutIdentificationAction(Request $request, EntityManagerInterface $em)
{
$coaching = $request->get("coaching");
$partner = null;
if (!$coaching) {
$partnerId = $request->get('partner');
if (!$partnerId) {
return $this->redirectToRoute('default_home');
}
$partner = $em->getRepository(Partner::class)->find($partnerId);
if (!$partner) {
return $this->redirectToRoute('default_home');
}
if ($partner->getIspractitioner() && !$partner->isSubscriptionActive()) {
return $this->redirectToRoute('default_home');
}
}
$user = new User();
$formRegister = $this->createForm(UserRegisterType::class, $user);
$registerError = null;
$registerSuccess = null;
$account = new Account();
$formLogin = $this->createForm(UserLoginType::class, $account);
$loginError = null;
$handleRegister = $this->handleRegister($formRegister, $user, $request);
if ($handleRegister) {
if ($handleRegister['success']) {
$registerSuccess = "Bienvenue sur ZenDez-Vous ! Votre compte a été créé avec succès. Vous pouvez dès maintenant vous connecter.";
} else {
$registerError = $handleRegister['message'];
}
}
$handleLogin = $this->handleLogin($formLogin, $request);
if ($handleLogin) {
if (!$handleLogin['success']) {
$loginError = $handleLogin['message'];
}
}
if ($_POST && isset($_POST["profile"])) {
$profileId = $_POST["profile"];
if (!$profileId) {
$profileId = "self";
}
if ($coaching) {
$lat = null;
if (isset($_POST['lat'])) { $lat = $_POST['lat']; }
$lon = null;
if (isset($_POST['lon'])) { $on = $_POST['lon']; }
$partners = $em->getRepository(Partner::class)->searchCoachsForUser($this->getUser()->getUser(), $lat, $lon);
$availablesSlots = [];
foreach ($partners as $p) {
$slots = $this->agendaUtils->getAvailableSlots($p[0], null, null, null, true);
foreach ($slots as $slot) {
$availablesSlots[] = [
"start" => $slot->getStartDate(),
"partner" => $p[0],
];
}
}
usort($availablesSlots, function ($item1, $item2) {
return $item1['start'] <=> $item2['start'];
});
$partner = $availablesSlots[0]["partner"];
}
$sessionParam = $request->get('session');
if ($sessionParam) {
return $this->redirectToRoute("default_checkout_payment", [
"partner" => $partner->getId(),
"profile" => $profileId,
"session" => $sessionParam
]);
}
return $this->redirectToRoute("default_checkout_choice", [
"partner" => $partner->getId(),
"profile" => $profileId,
"coaching" => $coaching
]);
}
$criticalError = null;
$slot = null;
return $this->render('checkout/step1.html.twig', [
"partner" => $partner,
"slot" => $slot,
"criticalError" => $criticalError,
"formRegister" => $formRegister->createView(),
"registerError" => $registerError,
"registerSuccess" => $registerSuccess,
"formLogin" => $formLogin->createView(),
"loginError" => $loginError,
"coaching" => $coaching
]);
}
/**
* @Route(
* path="/checkout/choice",
* name="checkout_choice"
* )
*
* @return Response
*/
public function checkoutChoiceAction(Request $request, EntityManagerInterface $em)
{
$isCoaching = (bool)$request->get("coaching");
$partnerId = $request->get('partner');
if (!$partnerId) {
return $this->redirectToRoute('default_home');
}
if (!$this->getUser()) {
return $this->redirectToRoute('default_checkout_identification', ["partner" => $partnerId]);
}
$partner = $em->getRepository(Partner::class)->find($partnerId);
if (!$partner) {
return $this->redirectToRoute('default_home');
}
if (!$isCoaching && $partner->getIspractitioner() && !$partner->getIsActivePractitioner()) {
return $this->redirectToRoute('default_home');
}
$profileParam = $request->get('profile');
$profile = null;
if ($profileParam != "self") {
$profileObj = $this->em->getRepository(CustomerProfile::class)->find($profileParam);
if ($profileObj && $this->getUser()->getUser()->getCustomerProfile()->contains($profileObj)) {
$profile = $profileObj;
}
}
$removeOnlyFirst = false;
$removeOnlySecond = false;
if ($isCoaching) {
if ($this->getUser() && $this->getUser()->getUser()->isFirstCoaching($em)) {
$removeOnlySecond = true;
} else {
$removeOnlyFirst = true;
}
} else {
if ($profile) {
if ($profile->isFirstReservation($partner, $em)) {
$removeOnlySecond = true;
} else {
$removeOnlyFirst = true;
}
} else {
if ($this->getUser() && $this->getUser()->getUser()->isFirstReservation($partner, $em)) {
$removeOnlySecond = true;
} else {
$removeOnlyFirst = true;
}
}
}
// Sélectioner de la prestation
$form = $this->createFormBuilder()
->add('service', EntityType::class, [
'class' => ServiceDelivery::class,
'label' => "Sélectionnez la prestation",
'choices' => $partner->getAvailablesServicesDeliveries($isCoaching, !$isCoaching, $removeOnlyFirst, $removeOnlySecond),
'choice_label' => function (?ServiceDelivery $serviceDelivery) {
$duration = $serviceDelivery->getDuration();
if ($duration == 60) { $duration = "1h"; }
elseif ($duration == 90) { $duration = "1h30"; }
else { $duration = $duration.' mn'; }
return $serviceDelivery->getLabel().' ('.$duration.')';
},
"required" => true,
'constraints' => array(
new NotBlank(["message" => "Veuillez indiquer une prestation"])
)
])
->add('canal', EntityType::class, [
'class' => ServiceDeliveryPlace::class,
'label' => "Sélectionnez le lieu",
'choice_label' => 'label',
"required" => true,
"attr" => ["autocomplete" => "off"],
'constraints' => array(
new NotBlank(["message" => "Veuillez indiquer un lieu"])
)
])
->getForm();
if ($partner->getSecondaryLocations() && count($partner->getSecondaryLocations()) > 0) {
$locationOptions = [];
$locationOptions[($partner->getAddressName() ?? "Cabinet principal")." (".$partner->getAddress().", ".$partner->getCity().")"] = 0;
foreach ($partner->getSecondaryLocations() as $secondaryLocation) {
if ($secondaryLocation->getActive()) {
$locationOptions[$secondaryLocation->getName()." (".$secondaryLocation->getAddress().", ".$secondaryLocation->getCity().")"] = $secondaryLocation->getId();
}
}
$form->add('location', ChoiceType::class, [
"label" => "Sélectionnez le cabinet",
"choices" => $locationOptions,
"data" => 0,
"placeholder" => false,
"required" => false,
]);
}
$form->handleRequest($request);
$service = null;
$canal = null;
$slot = null;
$location = null;
if ($form->isSubmitted() && $form->isValid()) {
$service = $form->get('service')->getData();
$canal = $form->get('canal')->getData();
if ($form->has('location')) {
$locationId = $form->get('location')->getData();
if ($locationId > 0) {
$secondarionLocation = $em->getRepository(PartnerSecondaryLocation::class)->find($locationId);
if ($secondarionLocation && $secondarionLocation->getPartner()->getId() == $partner->getId()) {
$location = $secondarionLocation;
}
}
}
}
$groupSessions = [];
if (!$service) {
$groupSessions = $em->getRepository(GroupSession::class)->findAvailablesByPartner($partner);
}
return $this->render('checkout/step2.html.twig', [
"partner" => $partner,
"slot" => $slot,
"form" => $form->createView(),
"sessions" => $groupSessions,
"service" => $service,
"canal" => $canal,
"location" => $location,
"profile" => $profileParam,
"coaching" => $request->get("coaching"),
]);
}
/**
* @Route(
* path="/checkout/payment",
* name="checkout_payment"
* )
*
* @return Response
*/
public function checkoutPaymentAction(Request $request, EntityManagerInterface $em)
{
$partnerId = $request->get('partner');
if (!$partnerId) {
return $this->redirectToRoute('default_home');
}
if (!$this->getUser()) {
return $this->redirectToRoute('default_checkout_identification', ["partner" => $partnerId]);
}
$partner = $em->getRepository(Partner::class)->find($partnerId);
if (!$partner) {
return $this->redirectToRoute('default_home');
}
if ($partner->getIspractitioner() && !$partner->isSubscriptionActive()) {
return $this->redirectToRoute('default_home');
}
if (!$this->getUser()) {
return $this->redirectToRoute('default_home');
}
$criticalError = null;
$serviceParam = $request->get('service');
$service = null;
if ($serviceParam) {
$service = $this->em->getRepository(ServiceDelivery::class)->find($serviceParam);
if (!$service || $service->getPartner()->getId() != $partner->getId() || !$service->getEnabled() || $service->getHistoryService()) {
$criticalError = "La prestation sélectionnée n'est plus disponible.";
}
}
$canalParam = $request->get('canal');
$canal = null;
if ($canalParam) {
$canal = $this->em->getRepository(ServiceDeliveryPlace::class)->find($canalParam);
if (!$canal || ($service && !$service->getServiceDeliveryPlace()->contains($canal))) {
$criticalError = "Le lieu sélectionné est invalide.";
}
}
$locationParam = $request->get('location');
$secondaryLocation = null;
if ($locationParam) {
$secondaryLocation = $this->em->getRepository(PartnerSecondaryLocation::class)->find($locationParam);
if (!$secondaryLocation || $secondaryLocation->getPartner()->getId() != $partner->getId()) {
$criticalError = "Le cabinet sélectionné est invalide.";
}
}
$sessionParam = $request->get('session');
$session = null;
if ($sessionParam) {
$session = $this->em->getRepository(GroupSession::class)->find($sessionParam);
if (!$session || $session->getPartner()->getId() != $partner->getId() || !$session->isReservable()) {
$criticalError = "La session de groupe n'est plus disponible";
}
}
$slotParam = $request->get('slot');
$slot = null;
if ($slotParam) {
$slot = $this->checkSlot($slotParam, $partner, $service, $canal, $secondaryLocation);
if (!$slot) {
$criticalError = "Le créneau sélectionné n'est plus disponible.";
}
}
$profileParam = $request->get('profile');
$profile = null;
if ($profileParam != "self") {
$profile = $this->em->getRepository(CustomerProfile::class)->find($profileParam);
if (!$profile || !$this->getUser()->getUser()->getCustomerProfile()->contains($profile)) {
$criticalError = "Le profil sélectionné est invalide.";
}
}
if (!$service && !$canal && !$session) {
return $this->redirectToRoute('default_checkout_identification', ["partner" => $partnerId]);
}
if (!$slot && !$session) {
return $this->redirectToRoute('default_checkout_choice', ["partner" => $partnerId, "profile" => $profileParam]);
}
if ($session) {
$paymentStrategy = DefaultController::getPaymentStrategyForSession($partner, $session);
} else {
$paymentStrategy = DefaultController::getPaymentStrategy($partner, $service, $canal);
}
if (isset($_POST['pay'])) {
$reservation = new Reservation();
$reservation->setPartner($partner);
$reservation->setUser($this->getUser()->getUser());
if ($profile) {
$reservation->setCustomerProfile($profile);
}
$reservation->setCreationDate(new \DateTime('now'));
if ($session) {
$reservation->setGroupSession($session);
$reservation->setStartDate($session->getStartDate());
$reservation->setEffectiveStartDate($session->getStartDate());
$reservation->setEndDate($session->getEndDate());
$reservation->setEffectiveEndDate($session->getEndDate());
} else {
$reservation->setServiceDelivery($service);
$reservation->setServiceDeliveryPlace($canal);
$reservation->setStartDate($slot->getStartDate());
$reservation->setEffectiveStartDate($this->agendaUtils->calcEffectiveStartDate($slot, $partner, $service, $canal));
$reservation->setEndDate($slot->getEndDate());
$reservation->setEffectiveEndDate($this->agendaUtils->calcEffectiveEndDate($slot, $partner, $service, $canal));
}
if ($secondaryLocation) {
$reservation->setPartnerSecondaryLocation($secondaryLocation);
}
$this->em->persist($reservation);
$this->em->flush();
AgendaUtils::handlePostReservation($reservation, $this->em, $this->googleCalendarService);
if ($paymentStrategy["total"] == 0) {
$reservation->setPaid(true);
$this->em->flush();
$this->sendReservationEmails($reservation);
return $this->redirectToRoute("default_checkout_success", ['reservation' => $reservation->getId()]);
} else {
$success_url = $this->generateUrl("default_checkout_success", ['reservation' => $reservation->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
$cancel_url = $this->generateUrl("default_checkout_error", ['reservation' => $reservation->getId()], UrlGeneratorInterface::ABSOLUTE_URL);
try {
$checkout = $this->stripeClient->checkout($reservation, $paymentStrategy, $cancel_url, $success_url);
if ($checkout && $checkout->url) {
return $this->redirect($checkout->url);
}
} catch (ApiErrorException $e) {
$criticalError = "Une erreur est survenue lors de l'ouverture du paiement.";
}
}
}
return $this->render('checkout/step3.html.twig', [
"partner" => $partner,
"slot" => $slot,
"service" => $service,
"session" => $session,
"canal" => $canal,
"location" => $secondaryLocation,
"criticalError" => $criticalError,
"paymentStrategy" => $paymentStrategy,
]);
}
public static function getPaymentStrategy(Partner $partner, ServiceDelivery $service, ServiceDeliveryPlace $canal)
{
/*
* STRATEGIE
* ---------
*
* COACHING:
* Emprunte du total vers ZV
* -> ok: Capture du montant total
* -> annulation > 48h: Annulation du PaymentIntent
* -> annulation < 48h: Capture de 20€
*
* PRATICIEN:
* Emprunte de 20€ vers le praticien
* -> ok: Annulation du PaymentIntent
* -> annulation > 48h: Annulation du PaymentIntent
* -> annulation < 48h: Capture des 20€ avec 10€ de frais
*
*/
$price = $service->getRealPrice();
$charge = $price < 20 ? $price : 20;
$fee = $price < 20 ? $price-10 : 10;
if ($fee < 0) { $fee = 0; }
if ($price == 0) {
return [
"strategy-html" => "Cette consultation est gratuite.<br/>Vous n'avez rien à régler. Vous aurez la possibilité d'annuler sans frais votre rendez-vous, bien que vous vous engagiez à honorer ce rendez-vous.",
"charge" => 0,
"pay" => 0,
"total" => $price,
"behalf_of" => null,
"cancelation" => [
"sup48" => [
"capture" => 0,
"fee" => 0,
"refund" => true,
],
"inf48" => [
"capture" => 0,
"fee" => 0,
"refund" => true,
],
],
];
}
if ($service->getIsCoaching()) {
return [
"strategy-html" => "Vous payez votre consultation directement auprès de ZenDez-Vous.<br/>Pour réserver votre créneau, vous devez régler la somme de ".$price."€. Vous aurez la possibilité d'annuler sans frais votre rendez-vous au moins 48H avant, au-delà, vous serez tout de même débité de ".$charge."€.",
"charge" => $price,
"pay" => 0,
"total" => $price,
"behalf_of" => null,
"cancelation" => [
"sup48" => [
"capture" => 0,
"fee" => 0,
"refund" => true,
],
"inf48" => [
"capture" => $charge,
"fee" => 0,
"refund" => false,
],
],
];
} else {
return [
"strategy-html" => "Vous payez votre consultation directement auprès du praticien.<br/>Pour réserver votre créneau, vous devez régler une empreinte bancaire de ".$charge."€. Vous ne serez débité que si vous annulez votre rendez-vous moins de 48 heures avant votre rendez-vous ou si vous ne vous présentez pas auprès du praticien, conformément aux <a href='/assets/docs/zendez-vous_cgv.pdf' target='_blank' rel='noreferrer'>conditions générales de vente.</a>",
"charge" => $charge,
"pay" => 0,
"total" => $charge,
"behalf_of" => $partner->getStripeAccountId(),
"cancelation" => [
"sup48" => [
"capture" => 0,
"fee" => 0,
"refund" => true,
],
"inf48" => [
"capture" => $charge,
"fee" => $fee,
"refund" => false,
],
],
];
}
}
public static function getPaymentStrategyForSession(Partner $partner, GroupSession $session)
{
$price = $session->getPrice();
$charge = $price < 20 ? $price : 20;
$fee = $price < 20 ? $price-10 : 10;
if ($fee < 0) { $fee = 0; }
if ($price == 0) {
return [
"strategy-html" => "Cette session est gratuite.<br/>Vous n'avez rien à régler. Vous aurez la possibilité d'annuler sans frais, bien que vous vous engagiez à honorer votre présence.",
"charge" => 0,
"pay" => 0,
"total" => $price,
"behalf_of" => null,
"cancelation" => [
"sup48" => [
"capture" => 0,
"fee" => 0,
"refund" => true,
],
"inf48" => [
"capture" => 0,
"fee" => 0,
"refund" => true,
],
],
];
}
return [
"strategy-html" => "Vous payez votre session directement auprès du praticien.<br/>Pour valider votre inscription, vous devez régler une empreinte bancaire de ".$charge."€. Vous ne serez débité que si vous annulez votre rendez-vous moins de 48 heures avant votre rendez-vous ou si vous ne vous présentez pas à la session, conformément aux <a href='/assets/docs/zendez-vous_cgv.pdf' target='_blank' rel='noreferrer'>conditions générales de vente.</a>",
"charge" => $charge,
"pay" => 0,
"total" => $charge,
"behalf_of" => $partner->getStripeAccountId(),
"cancelation" => [
"sup48" => [
"capture" => 0,
"fee" => 0,
"refund" => true,
],
"inf48" => [
"capture" => $charge,
"fee" => $fee,
"refund" => false,
],
],
];
}
/**
* @Route(
* path="/checkout/success",
* name="checkout_success"
* )
*
* @return Response
*/
public function checkoutSuccessAction(Request $request, EntityManagerInterface $em)
{
$reservationId = $request->get('reservation');
if (!$reservationId) {
throw new BadRequestException();
}
$reservation = $this->em->getRepository(Reservation::class)->find($reservationId);
if (!$reservation) {
throw new BadRequestException();
}
if (!$this->getUser()) {
throw new BadRequestException();
}
if (!$reservation->getUser() || ($reservation->getUser()->getId() != $this->getUser()->getUser()->getId() && $reservation->getStartDate() < new \DateTime('now'))) {
throw new BadRequestException();
}
return $this->render('checkout/step4.html.twig', [
"reservation" => $reservation,
"partner" => $reservation->getPartner(),
"error" => false,
]);
}
/**
* @Route(
* path="/checkout/error",
* name="checkout_error"
* )
*
* @return Response
*/
public function checkoutErrorAction(Request $request, EntityManagerInterface $em)
{
$reservationId = $request->get('reservation');
if (!$reservationId) {
throw new BadRequestException();
}
$reservation = $this->em->getRepository(Reservation::class)->find($reservationId);
if (!$reservation) {
throw new BadRequestException();
}
if ($reservation->getUser()->getId() != $this->getUser()->getUser()->getId() && $reservation->getStartDate() < new \DateTime('now')) {
throw new BadRequestException();
}
return $this->render('checkout/step4.html.twig', [
"reservation" => $reservation,
"partner" => $reservation->getPartner(),
"error" => true,
]);
}
private function checkSlot($slotParam, Partner $practitioner, ServiceDelivery $service, ServiceDeliveryPlace $canal, ?PartnerSecondaryLocation $secondaryLocation): ?Slot
{
$slot = null;
if ($slotParam) {
// On vérifie la validité du créneau
$startDateTime = \DateTime::createFromFormat('d/m/Y H:i:s', $slotParam);
$slotAvailable = null;
$availableSlots = $this->agendaUtils->getAvailableSlots($practitioner, $service, $canal, $secondaryLocation, null);
foreach ($availableSlots as $availableSlot) {
if ($availableSlot->getStartDate() == $startDateTime) {
$slotAvailable = $availableSlot;
break;
}
}
if ($slotAvailable) {
$slot = $slotAvailable;
}
}
return $slot;
}
/**
* @Route(
* path="/stripevents",
* name="stripevents"
* )
*
* @param Request $request
* @return Response
*/
public function stripeventsAction(Request $request)
{
$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$endpoint_secret = $this->getParameter('stripe_event_secret');
$response = new Response();
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
return $response;
} catch(\Exception $e) {
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
return $response;
}
if ($event) {
$event_type = $event->type;
$data = $event->data->object;
switch ($event_type) {
case 'checkout.session.completed':
$event_key = substr($data->client_reference_id, 0, 5);
switch ($event_key) {
case "resv_":
// Réservation
$reservation = $this->em->getRepository(Reservation::class)->find(substr($data->client_reference_id, 5));
if ($reservation) {
$reservation->setPaid(true);
$reservation->setStripePaymentId($data->payment_intent);
$this->em->flush();
$reservationPayment = new ReservationPayment();
$reservationPayment->setCreationDate(new \DateTime('now'));
$reservationPayment->setTotalAmount($data->amount_total);
$reservationPayment->setStripePi($data->payment_intent);
try {
$pi = $this->stripeClient->getPaymentIntent($data->payment_intent);
$reservationPayment->setChargedAmount($pi->amount_capturable);
$reservationPayment->setPaidAmount($pi->amount_received);
} catch (ApiErrorException $e) {
}
$this->em->persist($reservationPayment);
$this->em->flush();
$reservation->setReservationPayment($reservationPayment);
$this->em->flush();
$paymentLog = new ReservationPaymentLog();
$paymentLog->setCreationDate(new \DateTime('now'));
$paymentLog->setReservationPayment($reservationPayment);
$paymentLog->setLog("Reception du paiement - Montant:".$data->amount_total);
$paymentLog->setStripeId($event->id);
$this->em->persist($paymentLog);
$this->em->flush();
$this->sendReservationEmails($reservation);
$response->setStatusCode(Response::HTTP_OK);
return $response;
}
case "sub1_":
case "sub2_":
// Abonnement praticien
// 1 = montly ; 2 = yearly
$partner = $this->em->getRepository(Partner::class)->find(substr($data->client_reference_id, 5));
if ($partner) {
$subscription = new PartnerSubscription();
$subscription->setPartner($partner);
$subscription->setPrice((($data->amount_total)/100)/1.2);
$subscription->setStartDate(new \DateTime('now'));
$subscription->setStripeSubId($data->subscription);
$subscription->setDuration($event_key == "sub1_" ? 1 : 12);
$subscription->setPaymentType("stripe");
$this->em->persist($subscription);
$this->em->flush();
$partner->setSubscriptionDiscount(null);
$partner->setSubscriptionDiscountType(null);
$partner->setSubscriptionDiscountDuration(null);
$this->em->flush();
// Notification praticien
$this->mailjetEmailService->send(
"ZenDez-Vous: votre abonnement est maintenant actif !",
$partner->getAccount()->getEmail(),
4686131,
[
"title" => "Vous êtes abonné à ZenDez-Vous",
"content" => "Bonjour ".$partner->getFirstName(). " " . $partner->getLastName() .",<br/><br/>Vous venez de souscrire à ZenDez-Vous.<br/>La mise en ligne de votre profil sera effective après configuration de votre compte auprès de notre prestataire Stripe pour recevoir les indemnités. N'oubliez pas de réaliser cette configuration sur votre <a href='https://zendez-vous.fr/manager/login'>intranet</a> si ce n'est pas encore fait.<br/><br/>Merci pour votre confiance !",
"email" => $partner->getAccount()->getEmail(),
]);
// Notification admin
$this->mailjetEmailService->send(
"ZenDez-Vous: ".$partner->getFirstName(). " " . $partner->getLastName()." s'est abonné !",
"inscription-praticien@zendez-vous.fr",
4686131,
[
"title" => "Un nouvel abonné sur ZenDez-Vous",
"content" => "Bonjour, <br/><br/>Le praticien ".$partner->getFirstName(). " " . $partner->getLastName() ." a souscrit à ZenDez-Vous.<br/>",
"email" => "inscription-praticien@zendez-vous.fr",
]);
$response->setStatusCode(Response::HTTP_OK);
return $response;
}
break;
default:
break;
}
break;
case 'subscription_schedule.canceled':
case 'customer.subscription.deleted':
$subscription = $this->em->getRepository(PartnerSubscription::class)->findOneBy(["stripeSubId" => $data->id]);
if ($subscription) {
$subscription->setCanceled(true);
$endDate = new \DateTime();
$endDate->setTimestamp($data->cancel_at);
$subscription->setEndDate($endDate);
$this->em->flush();
// Notification praticien
$partner = $subscription->getPartner();
$this->mailjetEmailService->send(
"ZenDez-Vous: votre abonnement a été résilié !",
$partner->getAccount()->getEmail(),
4686131,
[
"title" => "Vous avez résilié votre abonnement",
"content" => "Bonjour ".$partner->getFirstName()."<br/><br/>Votre abonnement à ZenDez-Vous a été résilié.<br/>A l'échéance, vous ne pourrez plus profiter des fonctionnalités de la plateforme et votre profil ne sera plus visible sur notre site.",
"email" => $partner->getAccount()->getEmail(),
]);
// Notification admin
$this->mailjetEmailService->send(
"ZenDez-Vous: ".$partner->getFirstName(). " " . $partner->getLastName()." a résilié son abonnement...",
"inscription-praticien@zendez-vous.fr",
4686131,
[
"title" => "Un praticien a résilié son abonnement",
"content" => "Bonjour, <br/><br/>Le praticien ".$partner->getFirstName(). " " . $partner->getLastName() ." a résilié son abonnement à ZenDez-Vous.<br/>",
"email" => "inscription-praticien@zendez-vous.fr",
]);
$response->setStatusCode(Response::HTTP_OK);
return $response;
}
$response->setStatusCode(Response::HTTP_OK);
return $response;
break;
default:
break;
}
}
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
return $response;
}
private function sendReservationEmails(Reservation $reservation)
{
$user = $reservation->getUser();
$partner = $reservation->getPartner();
$motif = $reservation->getMotif();
if ($user && $partner) {
// Mail client
$pour = "";
if ($reservation->getCustomerProfile()) {
$pour = " pour ".$reservation->getCustomerProfile()->getFirstName()." ".$reservation->getCustomerProfile()->getLastName();
}
$this->mailjetEmailService->send(
"ZenDez-Vous: Votre réservation est confirmée",
$user->getAccount()->getEmail(),
4686131,
[
"title" => "Votre réservation est confirmée",
"content" => "Bonjour " . $user->getFirstName() . "<br/><br/>Vous avez rendez-vous avec ".$partner->getFirstName()." ".$partner->getLastName()." le ".$reservation->getStartDate()->format("d/m/Y à H:i").$pour.".<br/>Motif de la consultation: ".$motif.".",
"email" => $user->getAccount()->getEmail(),
],
[
[
'ContentType' => "text/calendar",
'Filename' => "cal.ics",
'Base64Content' => base64_encode($this->icalService->reservationToIcalUser($reservation))
]
]);
// Mail partner
$this->mailjetEmailService->send(
"ZenDez-Vous: Nouvelle réservation",
$partner->getAccount()->getEmail(),
4686131,
[
"title" => "Vous avez une nouvelle réservation",
"content" => "Bonjour " . $partner->getFirstName() . "<br/><br/>Vous avez rendez-vous avec ".$user->getFirstName()." ".$user->getLastName()." le ".$reservation->getStartDate()->format("d/m/Y à H:i").".<br/>Motif de la consultation: ".$motif.".",
"email" => $partner->getAccount()->getEmail(),
],
[
[
'ContentType' => "text/calendar",
'Filename' => "cal.ics",
'Base64Content' => base64_encode($this->icalService->reservationToIcalPartner($reservation))
]
]);
}
}
/**
* @Route(
* path="/stripeventsconnect",
* name="stripeventsconnect"
* )
*
* @param Request $request
* @return Response
*/
public function stripeventsconnectAction(Request $request)
{
$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$endpoint_secret = $this->getParameter('stripe_event_secret_connect');
$response = new Response();
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
return $response;
} catch(\Exception $e) {
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
return $response;
}
if ($event) {
$event_type = $event->type;
$data = $event->data->object;
switch ($event_type) {
case "account.updated":
$partner = $this->em->getRepository(Partner::class)->findOneBy(['stripeAccountId' => $data->id]);
if ($partner) {
$partner->setStripeAccountVerified($data->details_submitted);
$partner->setStripeChargesEnabled($data->charges_enabled);
$partner->setStripePayoutsEnabled($data->payouts_enabled);
$this->em->flush();
$response->setStatusCode(Response::HTTP_OK);
return $response;
}
break;
default:
break;
}
}
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
return $response;
}
/**
* @Route(
* path="/test-gc",
* name="test_google_calendar"
* )
*
* @return Response
*/
public function testGoogleCalendar(Request $request, EntityManagerInterface $em, GoogleCalendarService $googleCalendarService)
{
throw new NotFoundHttpException();
$partner = $em->getRepository(Partner::class)->find(76);
$checkSynchro = $googleCalendarService->check_synchro($partner);
if ($checkSynchro["success"] == true) {
$events = $googleCalendarService->getEvents($partner);
foreach ($events as $event) {
var_dump($event);
echo "</br>";
$transparency = $event->getTransparency();
if ($transparency == "transparent") {
echo "L'utilisateur a indiqué être libre pendant cet événement.\n";
} else {
echo "L'utilisateur est occupé pendant cet événement.\n";
}
echo "</br>";
echo $event['summary'];
echo "</br>";
echo $event['status'];
echo "</br>";
var_dump($event['updated']);
echo "</br>";
var_dump($event['start']);
echo "</br>";
var_dump($event['end']);
echo "</br>";
echo $event['description'];
echo "</br>";
echo $event['id'];
echo "</br>";
echo "</br>";
}
return new Response("Connected.");
} else {
return new Response("<a href='".$checkSynchro["url"]."'>Connexion</a>");
}
}
/**
* @Route(
* path="/test-gc-callback",
* name="test_google_calendar_callback"
* )
*
* @return Response
*/
public function testGoogleCalendarCallback(Request $request, EntityManagerInterface $em, GoogleCalendarService $googleCalendarService)
{
throw new NotFoundHttpException();
$partner = $em->getRepository(Partner::class)->find(1);
$code = $request->get("code");
if ($code) {
$googleCalendarService->callback($partner, $code);
}
return $this->redirectToRoute('default_test_google_calendar');
}
/**
* @Route(
* path="/test-ics",
* name="test_ics"
* )
*
* @return Response
*/
public function testIcs(Request $request, EntityManagerInterface $em)
{
throw new NotFoundHttpException();
$url = "https://calendar.google.com/calendar/ical/dcrbernard.pro%40gmail.com/private-bed1dbf12461e28136808d40a5ffc0ad/basic.ics";
$ical = new ICal($url);
var_dump($ical);
echo "</br>";
echo "</br>";
echo $ical->eventCount;
echo "</br>";
echo "</br>";
$events = $ical->eventsFromInterval('1 month');
foreach ($events as $event) {
var_dump($event);
echo "</br>";
echo $event->summary;
echo "</br>";
echo $event->status;
echo "</br>";
echo $event->uid;
echo "</br>";
echo $event->dtstart_tz;
echo "</br>";
echo $event->printData();
}
echo "</br>";
echo "</br>";
return new Response("OK");
}
/**
* @Route(
* path="/migration/coaching",
* name="migration_coaching"
* )
*
* @return Response
*/
public function migrationCoaching(Request $request, EntityManagerInterface $em)
{
throw new NotFoundHttpException();
$coachings = $em->getRepository(ServiceDelivery::class)->findBy(["isCoaching" => true]);
foreach ($coachings as $coaching) {
if ($coaching->getLabel() == "Conseil ZenDez-Vous 1ère consultation" || $coaching->getLabel() == "Coaching ZenDez-Vous 1ère consultation") {
$newServiceDelivery = clone $coaching;
$newServiceDelivery->setLabel("Coaching ZenDez-Vous 1ère consultation");
$newServiceDelivery->setDuration(30);
$newServiceDelivery->setPrice(34);
$this->em->persist($newServiceDelivery);
$this->em->flush();
$coaching->setHistoryService($newServiceDelivery);
$this->em->flush();
}
if ($coaching->getLabel() == "Conseil ZenDez-Vous suivi" || $coaching->getLabel() == "Coaching ZenDez-Vous suivi") {
$newServiceDelivery = clone $coaching;
$newServiceDelivery->setLabel("Coaching ZenDez-Vous suivi");
$newServiceDelivery->setDuration(30);
$newServiceDelivery->setPrice(34);
$this->em->persist($newServiceDelivery);
$this->em->flush();
$coaching->setHistoryService($newServiceDelivery);
$this->em->flush();
}
}
return new Response("OK");
}
}