diff --git a/README.md b/README.md index b2c925f59..f3f8fe769 100755 --- a/README.md +++ b/README.md @@ -202,4 +202,6 @@ IDP_CLIENT_SECRET=client-secret * 802: User could not join the event * 803: User could not leave the event *MealGuestController 9xx* - * 901: Could not find the Invitation for the given hash \ No newline at end of file + * 901: Could not find the Invitation for the given hash + * 902: Parameters were not provided (eg. firstname and lastname) + * 903: An unknown error occured on joining the event as a guest \ No newline at end of file diff --git a/src/Mealz/MealBundle/Controller/EventController.php b/src/Mealz/MealBundle/Controller/EventController.php index 3462bcd4e..fdba2e1f2 100644 --- a/src/Mealz/MealBundle/Controller/EventController.php +++ b/src/Mealz/MealBundle/Controller/EventController.php @@ -159,13 +159,6 @@ public function getEventParticipants(DateTime $date): JsonResponse return new JsonResponse(['message' => 'Could not find day'], 404); } - $participants = $day->getEvent()->getParticipants(); - - $participantsNames = array_map( - fn (Participant $participant) => $participant->getProfile()->getFullName(), - $participants->toArray() - ); - - return new JsonResponse($participantsNames, 200); + return new JsonResponse($this->eventPartSrv->getParticipants($day), 200); } } diff --git a/src/Mealz/MealBundle/Controller/MealGuestController.php b/src/Mealz/MealBundle/Controller/MealGuestController.php index d90de9b77..0a3a22df3 100644 --- a/src/Mealz/MealBundle/Controller/MealGuestController.php +++ b/src/Mealz/MealBundle/Controller/MealGuestController.php @@ -7,9 +7,11 @@ use App\Mealz\MealBundle\Entity\Day; use App\Mealz\MealBundle\Entity\GuestInvitation; use App\Mealz\MealBundle\Entity\Participant; +use App\Mealz\MealBundle\Event\EventParticipationUpdateEvent; use App\Mealz\MealBundle\Event\ParticipationUpdateEvent; use App\Mealz\MealBundle\Event\SlotAllocationUpdateEvent; use App\Mealz\MealBundle\Repository\GuestInvitationRepositoryInterface; +use App\Mealz\MealBundle\Service\EventParticipationService; use App\Mealz\MealBundle\Service\GuestParticipationService; use Exception; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; @@ -21,11 +23,16 @@ class MealGuestController extends BaseController { + private EventParticipationService $eventParticipationService; private GuestParticipationService $gps; private EventDispatcherInterface $eventDispatcher; - public function __construct(GuestParticipationService $gps, EventDispatcherInterface $eventDispatcher) - { + public function __construct( + EventParticipationService $eventParticipationService, + GuestParticipationService $gps, + EventDispatcherInterface $eventDispatcher + ) { + $this->eventParticipationService = $eventParticipationService; $this->gps = $gps; $this->eventDispatcher = $eventDispatcher; } @@ -97,6 +104,46 @@ public function getEventInvitationData( return new JsonResponse($guestData, 200); } + // TODO: check for existing guest + public function joinEventAsGuest( + string $invitationId, + Request $request, + GuestInvitationRepositoryInterface $guestInvitationRepo + ): JsonResponse { + $parameters = json_decode($request->getContent(), true); + + /** @var GuestInvitation $invitation */ + $invitation = $guestInvitationRepo->find($invitationId); + if (null === $invitation) { + return new JsonResponse(['message' => '901: Could not find invitation for the given hash', 403]); + } elseif (false === isset($parameters['firstName']) || false === isset($parameters['lastName'])) { + return new JsonResponse(['message' => '902: Parameters were not provided'], 404); + } + + if (false === isset($parameters['company'])) { + $parameters['company'] = ''; + } + + try { + $eventParticipation = $this->eventParticipationService->joinAsGuest( + $parameters['firstName'], + $parameters['lastName'], + $parameters['company'], + $invitation->getDay() + ); + + if (null === $eventParticipation) { + return new JsonResponse(['message' => '903: Unknown error occured while joining the event'], 500); + } + + $this->eventDispatcher->dispatch(new EventParticipationUpdateEvent($eventParticipation)); + + return new JsonResponse(null, 200); + } catch (Exception $e) { + return new JsonResponse(['message' => '903: ' . $e->getMessage()], 500); + } + } + /** * @param Participant[] $participants */ diff --git a/src/Mealz/MealBundle/Resources/config/routing.yml b/src/Mealz/MealBundle/Resources/config/routing.yml index 242ca65ee..ef961b8c9 100644 --- a/src/Mealz/MealBundle/Resources/config/routing.yml +++ b/src/Mealz/MealBundle/Resources/config/routing.yml @@ -173,6 +173,11 @@ MealzMealBundle_api_event_invitation_data: defaults: { _controller: App\Mealz\MealBundle\Controller\MealGuestController::getEventInvitationData } methods: [ GET ] +MealzMealBundle_api_event_invitation_join: + path: /api/event/invitation/{invitationId} + defaults: { _controller: App\Mealz\MealBundle\Controller\MealGuestController::joinEventAsGuest } + methods: [ POST ] + MealzMealBundle_api_events: path: /api/events defaults: { _controller: App\Mealz\MealBundle\Controller\EventController::getEventList } diff --git a/src/Mealz/MealBundle/Service/EventParticipationService.php b/src/Mealz/MealBundle/Service/EventParticipationService.php index 2491faa25..1c2a5cee8 100644 --- a/src/Mealz/MealBundle/Service/EventParticipationService.php +++ b/src/Mealz/MealBundle/Service/EventParticipationService.php @@ -8,8 +8,11 @@ use App\Mealz\MealBundle\Entity\Participant; use App\Mealz\MealBundle\Repository\EventParticipationRepositoryInterface; use App\Mealz\MealBundle\Repository\EventRepositoryInterface; +use App\Mealz\MealBundle\Service\GuestParticipationService; use App\Mealz\UserBundle\Entity\Profile; +use DateTime; use Doctrine\ORM\EntityManagerInterface; +use Exception; class EventParticipationService { @@ -17,17 +20,20 @@ class EventParticipationService private EntityManagerInterface $em; private EventParticipationRepositoryInterface $eventPartRepo; private EventRepositoryInterface $eventRepo; + private GuestParticipationService $guestParticipationService; public function __construct( Doorman $doorman, EntityManagerInterface $em, EventRepositoryInterface $eventRepo, - EventParticipationRepositoryInterface $eventPartRepo + EventParticipationRepositoryInterface $eventPartRepo, + GuestParticipationService $guestParticipationService ) { $this->doorman = $doorman; $this->em = $em; $this->eventPartRepo = $eventPartRepo; $this->eventRepo = $eventRepo; + $this->guestParticipationService = $guestParticipationService; } /** @@ -82,6 +88,37 @@ public function join(Profile $profile, Day $day): ?EventParticipation return null; } + public function joinAsGuest( + string $firstName, + string $lastName, + string $company, + Day $eventDay + ): ?EventParticipation { + $guestProfile = $this->guestParticipationService->getCreateGuestProfile( + $firstName, + $lastName, + $company, + $eventDay->getDateTime() + ); + + $this->em->beginTransaction(); + + try { + $this->em->persist($guestProfile); + $eventParticiation = $eventDay->getEvent(); + $participation = $this->createEventParticipation($guestProfile, $eventParticiation); + + $this->em->persist($participation); + + $this->em->flush(); + $this->em->commit(); + return $eventParticiation; + } catch (Exception $e) { + $this->em->rollback(); + throw $e; + } + } + public function leave(Profile $profile, Day $day): ?EventParticipation { $eventParticipation = $day->getEvent(); @@ -101,7 +138,7 @@ public function getParticipants(Day $day): array } return array_map( - fn (Participant $participant) => $participant->getProfile()->getFullName(), + fn (Participant $participant) => $this->getParticipantName($participant), $day->getEvent()->getParticipants()->toArray() ); } @@ -130,4 +167,16 @@ private function createEventParticipation(Profile $profile, EventParticipation $ { return new Participant($profile, null, $eventParticiation); } + + private function getParticipantName(Participant $participant): string + { + if ($participant->isGuest()) { + $company = strlen($participant->getProfile()->getCompany()) > 0 ? + ' (' . $participant->getProfile()->getCompany() . ')' : + ' (Gast)'; + return $participant->getProfile()->getFullName() . $company; + } else { + return $participant->getProfile()->getFullName(); + } + } } diff --git a/src/Mealz/MealBundle/Service/GuestParticipationService.php b/src/Mealz/MealBundle/Service/GuestParticipationService.php index 1f10a17a6..28a35ee35 100644 --- a/src/Mealz/MealBundle/Service/GuestParticipationService.php +++ b/src/Mealz/MealBundle/Service/GuestParticipationService.php @@ -78,6 +78,28 @@ public function join(Profile $profile, Collection $meals, ?Slot $slot = null, ar return $this->register($guestProfile, $meals, $slot, $dishSlugs); } + public function getCreateGuestProfile( + string $firstName, + string $lastName, + string $company, + DateTime $mealDate + ): Profile { + $guestProfileID = sprintf('%s.%s_%s', $firstName, $lastName, $mealDate->format('Y-m-d')); + $guestProfile = $this->profileRepo->find($guestProfileID); + if (true === ($guestProfile instanceof Profile) && true === $guestProfile->isGuest()) { + return $guestProfile; + } + + $profile = new Profile(); + $profile->setUsername($guestProfileID); + $profile->setFirstName($firstName); + $profile->setName($lastName); + $profile->setCompany($company); + $profile->addRole($this->getGuestRole()); + + return $profile; + } + /** * Registers user with $profile to given meals and slot. * @@ -179,28 +201,6 @@ private function create(Profile $profile, Collection $meals, ?Slot $slot = null, return $participants; } - private function getCreateGuestProfile( - string $firstName, - string $lastName, - string $company, - DateTime $mealDate - ): Profile { - $guestProfileID = sprintf('%s.%s_%s', $firstName, $lastName, $mealDate->format('Y-m-d')); - $guestProfile = $this->profileRepo->find($guestProfileID); - if (true === ($guestProfile instanceof Profile) && true === $guestProfile->isGuest()) { - return $guestProfile; - } - - $profile = new Profile(); - $profile->setUsername($guestProfileID); - $profile->setFirstName($firstName); - $profile->setName($lastName); - $profile->setCompany($company); - $profile->addRole($this->getGuestRole()); - - return $profile; - } - private function getGuestRole(): Role { $guestRole = $this->roleRepo->findOneBy(['sid' => Role::ROLE_GUEST]); diff --git a/src/Resources/src/api/postJoinEventGuest.ts b/src/Resources/src/api/postJoinEventGuest.ts new file mode 100644 index 000000000..13ada1ade --- /dev/null +++ b/src/Resources/src/api/postJoinEventGuest.ts @@ -0,0 +1,21 @@ +import { IMessage } from "@/interfaces/IMessage"; +import useApi from "./api"; + +export interface GuestEventData { + firstName: string, + lastName: string, + company: string +} + +export default async function postJoinEventGuest(invitationHash: string, guestData: GuestEventData) { + const { error, request, response } = useApi( + 'POST', + `/api/event/invitation/${invitationHash}`, + 'application/json', + JSON.stringify(guestData) + ); + + await request(); + + return { error, response }; +} \ No newline at end of file diff --git a/src/Resources/src/locales/de.json b/src/Resources/src/locales/de.json index 327d2c785..2fc8a5f8d 100644 --- a/src/Resources/src/locales/de.json +++ b/src/Resources/src/locales/de.json @@ -203,6 +203,9 @@ "created": "Der Zeitslot wurde erfolgreich erstellt.", "deleted": "Der Zeitslot wurde erfolgreich gelöscht.", "updated": "Der Zeitslot wurde erfolgreich bearbeitet." + }, + "guest": { + "joined": "Sie nehmen an der Veranstaltung teil. Wir freuen uns Sie dabei zu haben." } } }, @@ -232,6 +235,7 @@ "description": "Als Gast in unserem Haus laden wir Sie gerne zu einem Mittagessen in der AOE Eatery ein. Für Ihre Bestellung tragen Sie sich bitte bis spätestens einen Tag vorher mit Ihren Daten ein und wählen das gewünschte Gericht aus, das dann an unsere Köche weitergeleitet wird.\n\nGuten Appetit wünscht Ihnen,\nAOE", "event": { "submit": "An Event teilnehmen", + "joined": "Sie nehmen am %eventDate% an \"%EventTitle%\" teil. Wir freuen uns Sie dabei zu haben.", "title": "Veranstaltung bei AOE", "description": "Hiermit laden wir Sie zu der Veranstaltung \"%EventTitle%\" bei uns ein. Damit wir rechtzeitig mit Ihnen planen können tragen Sie sich bitte bis spätestens %lockDate% Uhr für das Event ein.\n\nWir freuen uns auf Sie!" } diff --git a/src/Resources/src/views/GuestEvent.vue b/src/Resources/src/views/GuestEvent.vue index 8efc5389b..c5cd1af60 100644 --- a/src/Resources/src/views/GuestEvent.vue +++ b/src/Resources/src/views/GuestEvent.vue @@ -1,6 +1,6 @@