Skip to content

Commit

Permalink
added endpoint to join an event as a guest
Browse files Browse the repository at this point in the history
  • Loading branch information
Felix Ruf committed Feb 1, 2024
1 parent 41d7f76 commit 58a1d02
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 45 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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
9 changes: 1 addition & 8 deletions src/Mealz/MealBundle/Controller/EventController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
51 changes: 49 additions & 2 deletions src/Mealz/MealBundle/Controller/MealGuestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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
*/
Expand Down
5 changes: 5 additions & 0 deletions src/Mealz/MealBundle/Resources/config/routing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
53 changes: 51 additions & 2 deletions src/Mealz/MealBundle/Service/EventParticipationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,32 @@
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
{
private Doorman $doorman;
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;
}

/**
Expand Down Expand Up @@ -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();
Expand All @@ -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()
);
}
Expand Down Expand Up @@ -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();
}
}
}
44 changes: 22 additions & 22 deletions src/Mealz/MealBundle/Service/GuestParticipationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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]);
Expand Down
21 changes: 21 additions & 0 deletions src/Resources/src/api/postJoinEventGuest.ts
Original file line number Diff line number Diff line change
@@ -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<IMessage | null>(
'POST',
`/api/event/invitation/${invitationHash}`,
'application/json',
JSON.stringify(guestData)
);

await request();

return { error, response };
}
4 changes: 4 additions & 0 deletions src/Resources/src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
},
Expand Down Expand Up @@ -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!"
}
Expand Down
Loading

0 comments on commit 58a1d02

Please sign in to comment.