<?php
declare(strict_types=1);
namespace Harmonizely\Controller;
use Harmonizely\Availability\FirstAvailableDateProvider;
use Harmonizely\EventTypes\LocationTypeProvider;
use Harmonizely\Model\EventTypeInterface;
use Harmonizely\Model\User;
use Harmonizely\Service\CancellationPolicy\Contract\IGetCancellationPolicyService;
use Harmonizely\Service\Common\Contract\IGetTimezoneListService;
use Harmonizely\Service\CustomTranslation\Event\SetCustomTranslationEvent;
use Harmonizely\Service\Locale\Event\SetLocaleEvent;
use Harmonizely\Service\Subscription\Voter\SubscriptionVoter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Harmonizely\Service\Panel\Api\UserEventTypeTag\Contract\IUserEventTypeTagListService;
class UserBookingController extends AbstractBookingController
{
/**
* @Entity("user", expr="repository.findOneEnabledBySlug(slug)")
* @param Request $request
* @param User $user
* @param IUserEventTypeTagListService $userEventTypeTagListService
* @return Response
*/
public function index(Request $request, User $user, IUserEventTypeTagListService $userEventTypeTagListService): Response
{
if ($this->reverseRedirectResolver->shouldRedirect($request, $user)) {
return $this->reverseRedirectResolver->resolve($request, $user);
}
$this->eventDispatcher->dispatch(new SetLocaleEvent(null, $user), SetLocaleEvent::NAME);
$this->eventDispatcher->dispatch(new SetCustomTranslationEvent($user->getId()), SetCustomTranslationEvent::NAME);
$selectedUserEventTypeTag = $request->get('userEventTypeTag');
/** @var EventTypeInterface[] $eventTypes */
$eventTypes = $this->eventTypeRepository->findByUserSlug($user->getSlug(), $selectedUserEventTypeTag);
$isAllowGroupBooking = SubscriptionVoter::staticVoteOnAttribute(SubscriptionVoter::GROUP_BOOKING, $user);
$eventTypeList = [];
foreach ($eventTypes as $eventType) {
if ($eventType->getGroupMeetingLimit() > 1 && !$isAllowGroupBooking) {
continue;
}
$eventTypeList[] = $eventType;
}
$userEventTypeTags = $userEventTypeTagListService->perform($user);
$userEventTypeTagsList = [];
foreach ($userEventTypeTags as $tag) {
$userEventTypeTagsList[] = [
'id' => $tag->getId(),
'name' => $tag->getName(),
'color' => $tag->getColor(),
];
}
return $this->render('booking/index.html.twig', [
'eventTypes' => $eventTypeList,
'user' => $user,
'userEventTypeTags' => $selectedUserEventTypeTag ? null : $userEventTypeTagsList,
'selectedUserEventTypeTags' => $request->get('userEventTypeTag'),
]);
}
/**
* @Entity("user", expr="repository.findOneEnabledBySlug(slug)")
*/
public function eventType(
Request $request,
User $user,
LocationTypeProvider $locationTypeProvider,
FirstAvailableDateProvider $firstAvailableDateProvider,
IGetCancellationPolicyService $getCancellationPolicyService,
IGetTimezoneListService $getTimezoneListService,
string $eventTypeSlug,
string $singleUseLinkCode = ''
): Response
{
$eventType = $this->eventTypeRepository->findOneBySlugAndUser($eventTypeSlug, $user);
if (false === $eventType instanceof EventTypeInterface) {
return $this->redirect(
$this->generateUrl(
'hrm_booking_index',
['slug' => $user->getSlug()],
UrlGeneratorInterface::ABSOLUTE_URL
)
);
}
if ($eventType->getType() === EventTypeInterface::TYPE_REGULAR && $user->getCalendarAccounts()->isEmpty()) {
return $this->renderCalendarNotConnected($user);
}
if ($singleUseLinkCode === '' && $this->reverseRedirectResolver->shouldRedirect($request, $user)) {
return $this->reverseRedirectResolver->resolve($request, $user);
}
if ($eventType->getGroupMeetingLimit() > 1 && !SubscriptionVoter::staticVoteOnAttribute(SubscriptionVoter::GROUP_BOOKING, $user)) {
throw $this->createNotFoundException();
}
$this->eventDispatcher->dispatch(new SetLocaleEvent($eventType), SetLocaleEvent::NAME);
$this->eventDispatcher->dispatch(new SetCustomTranslationEvent($user->getId()), SetCustomTranslationEvent::NAME);
if (SubscriptionVoter::staticVoteOnAttribute(SubscriptionVoter::QUESTION, $user)) {
$questions = $this->getQuestions($eventType);
} else {
$questions = [];
}
$locationType = $locationTypeProvider->provideFor($eventType, $user);
$startDate = $firstAvailableDateProvider->provideFor($eventType, (string) $eventType->getTimezone());
$duration = $eventType->getRealDuration($request->query->get('duration_id'));
return $this->render('booking/event_type.html.twig', [
'user' => $user,
'eventType' => $eventType,
'timezones' => json_encode($getTimezoneListService->perform()),
'questions' => json_encode($questions),
'simplypayPaymentSystems' => json_encode($this->getAllowedPaymentSystems($user)),
'integration' => $this->findIntegration($user, $locationType),
'singleUseLinkCode' => $singleUseLinkCode,
'calendarLayout' => $this->getCalendarLayoutService->perform($eventType),
'isHideUnavailableDates' => $this->isHideUnavailableDatesService->perform($eventType),
'isSundayIsFirstDayService' => $this->isSundayIsFirstDayService->perform($eventType),
'startDate' => $startDate->format('Y-m-d'),
'eventTypeDuration' => $duration,
'cancellationPolicy' => $getCancellationPolicyService->perform($eventType, $user),
]);
}
}