Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/#260047 event participation #417

Merged
merged 64 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
6e164c3
initialized branch
Jan 11, 2023
5b2c89a
Delete yarn.lock
hacksch Jan 26, 2023
75a5fb4
added a component to show that there are no meals for the day
May 15, 2023
2f6171d
added an api endpoint for creating a slot and continued the work on t…
May 17, 2023
dba6bab
fixed code smells
May 31, 2023
78b4339
feat: implement finance page and api Endpoint
Aug 22, 2023
6cddae1
feat: implement finance page and api Endpoint
Aug 22, 2023
f11c559
potetial fix for login
Oct 26, 2023
b5ec5a3
next try to inject env variables into docker compose
Oct 31, 2023
16ab225
test workflow
Nov 1, 2023
fa511e9
fixed rebase errors
Dec 6, 2023
975cf18
removed unused imports
Dec 6, 2023
63548df
added endpoints to create, update, delete and list all events
Dec 6, 2023
29a21c3
fixed code smells
Dec 7, 2023
f16f106
added a basic view for the events
Dec 7, 2023
5066194
added some more ui elements
Dec 7, 2023
4f00a7e
added fetching of events and basic rendering of them
Dec 7, 2023
47a8235
added functionality to create, edit and delete events
Dec 12, 2023
5204a6e
added frontend-unit-tests, e2e-tests and backend-unit-tests
Dec 13, 2023
3714419
updated mealAdminController towork with events
Dec 14, 2023
504b2f4
changed interface definition to reflect the backend change
Dec 14, 2023
7eae5c6
fixed tests
Dec 19, 2023
81cf6dc
added an input for events in the menu creation view
Dec 19, 2023
944ea68
changed tests to include events during the menu creation process
Dec 19, 2023
4eac789
changed the dashboard api to include events
Dec 19, 2023
4e24639
fixed null event on dashboard
Dec 20, 2023
0158249
added Events to the DashBoard View and added updates for the EventPar…
Dec 20, 2023
41415ea
added explanation for running a single jest testfile
Jan 9, 2024
edfe4dd
fixed typo
Jan 9, 2024
f0a6245
added icon to events to better distinguish them from meals
Jan 9, 2024
ea0f913
fixed some code smells and failing tests
Jan 9, 2024
34cd69d
added tests for the dashboard
Jan 9, 2024
19d3e7b
added a cypress test for the dashboard
Jan 10, 2024
77bffd9
added endpoints to join and leave events
Jan 10, 2024
e52a19c
fixed several code smells
Jan 10, 2024
1144da9
added joining and leaving an event and emitting an event via mercure,…
Jan 16, 2024
a412db9
added tests
Jan 17, 2024
930d635
fixed code smells
Jan 17, 2024
3c748b9
added indicators to events in the dashboard
Jan 17, 2024
4f451e6
fixed color on event days
Jan 18, 2024
e4bed32
fixed cypress test
Jan 18, 2024
0ebb911
added events and participants of these events to the /print/participa…
Jan 18, 2024
cdc3b73
fixed code smell
Jan 18, 2024
ff916f1
added print functionality to PrintList
Jan 18, 2024
73de49c
fixed cutted off list on download
Jan 23, 2024
5eda9e5
removed unused icon
Jan 23, 2024
95441c2
added modal that shows the participants for an event on that day
Jan 23, 2024
b8b8d57
added description for combi meals that contain variations
Jan 24, 2024
5fa6dbd
fixed code smell
Jan 24, 2024
196874e
added tests for printable list and the event participants list
Jan 24, 2024
fb713ed
added endpoint to generate invite link and view to display the invite
Jan 25, 2024
f9761bd
added dates to text on guest event view
Jan 30, 2024
bae0764
fixed code smells
Jan 30, 2024
41d7f76
adjusted cypress tests to still work with eventinvitations
Jan 30, 2024
58a1d02
added endpoint to join an event as a guest
Jan 30, 2024
f634c59
fixed code smells
Jan 30, 2024
b015daa
added tests for new event invitation functionality
Jan 31, 2024
b6e69eb
fixed broken files after rebase
Feb 1, 2024
dced694
further work to fix problems caused by rebasing
Feb 6, 2024
de74f50
fixes for updated linters / tests
Feb 6, 2024
ea06bf4
removed chown
Feb 6, 2024
d137069
potential fix for missing permissions
Feb 6, 2024
11afdaf
readded executable bit to scripts
Feb 6, 2024
e4d2c50
requested changes from code review
Feb 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ tests/e2e/cypress/videos/
tests/e2e/cypress/screenshots/
test_ci_cypress.sh
tests/e2e/cypress/e2e/FillDBWithStuff.cy.ts
tests/e2e/cypress/downloads/result.pdf
src/Resources/style/output.css.map
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ RUN \
&& find public -type f -not -name "*.php" -exec chmod 644 '{}' \+

RUN echo "* * * * * /var/www/meals/bin/console meals:keep-alive-connection > /dev/stdout" >> /etc/crontabs/www-data
RUN chmod +x "/container/entrypoint"
RUN chmod +x "/container/scripts/wait-for"

ENTRYPOINT ["/container/entrypoint"]

Expand Down
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,21 @@ Point your web browser to https://meals.test :tada:

:memo: Don't forget to add `127.0.0.1 meals.test` to your local hosts file if not done automatically via ddev.

To run End-to-End testing via cypress run te following command:
To run End-to-End testing via cypress run the following command:
```
make run-cypress
```
You need to start the devbox before running any tests with cypress.

## Component testing

To run specific component tests with JEST in isolation:
```
ddev exec yarn --cwd=src/Resources test -- -t "<test-filename> <testname>"
```
`<test-filename>` for a file with the name `xyz.spec.ts` would be `xyz`
`<testname>` is optional, if no testname is specified the whole file is run

## Troubleshooting

### SQLSTATE[42S22]: Column not found: 1054 Unknown column
Expand Down Expand Up @@ -186,3 +195,13 @@ IDP_CLIENT_SECRET=client-secret
* 505: The settlement request was already processed or the request is invalid
*CashController 6xx*
* 601: The amount of cash that will be added, has to be more than zero
*EventController 7xx*
* 701: Event creation parameters are missing
*EventParticipationController 8xx*
* 801: User has no permission to enter or leave
* 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
* 902: Parameters were not provided (eg. firstname and lastname)
* 903: An unknown error occured on joining the event as a guest
1 change: 1 addition & 0 deletions config/packages/mercure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ mercure:
- participation-updates
- meal-offer-updates
- slot-allocation-updates
- event-participation-updates
- keep-alive-connection
2 changes: 1 addition & 1 deletion config/packages/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ security:
- { path: ^/api/guest-invitation, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/api/environmentals, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/api/user, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/api/event/invitation/\S*, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: '^/participation/slots-status/\d{4}-\d{2}-\d{2}$', roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: '^/participation/count-status/\d{4}-\d{2}-\d{2}$', roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/language-switch, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/css, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/js, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
- { path: ^/images, roles: [IS_AUTHENTICATED_ANONYMOUSLY] }
Expand Down
7 changes: 3 additions & 4 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ parameters:
app.secret: '%env(APP_SECRET)%'

mealz.lock_toggle_participation_at: '-1 day 16:00'
mealz.meal.price: 3.60
mealz.meal.price: 4.13
mealz.meal.search_timestamp: '2000-01-01'
mealz.meal.new_flag_counter: 2
mealz.meal.combined.price: 5.60

mealz.meal.combined.price: 6.13
# PDO Session Handler options
# Define table and column names to store session data
app.session.handler.pdo.options:
Expand Down Expand Up @@ -294,4 +293,4 @@ services:

# Interface implementations
App\Mealz\UserBundle\Repository\ProfileRepositoryInterface: '@App\Mealz\UserBundle\Repository\ProfileRepository'
App\Mealz\UserBundle\Repository\RoleRepositoryInterface: '@App\Mealz\UserBundle\Repository\RoleRepository'
App\Mealz\UserBundle\Repository\RoleRepositoryInterface: '@App\Mealz\UserBundle\Repository\RoleRepository'
3 changes: 1 addition & 2 deletions psalm.baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,7 @@
</UndefinedClass>
</file>
<file src="src/Mealz/MealBundle/Service/Doorman.php">
<UndefinedInterfaceMethod occurrences="2">
<code>getProfile</code>
<UndefinedInterfaceMethod occurrences="3">
<code>getProfile</code>
</UndefinedInterfaceMethod>
</file>
Expand Down
5 changes: 4 additions & 1 deletion src/Mealz/MealBundle/Controller/ApiController.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public function getDashboardData(ParticipationCountService $partCountSrv): JsonR
'days' => [],
'isEnabled' => $week->isEnabled(),
];
/* @var Day $day */
/** @var Day $day */
foreach ($week->getDays() as $day) {
$participationsPerDay = $partCountSrv->getParticipationByDay($day);

Expand All @@ -102,6 +102,7 @@ public function getDashboardData(ParticipationCountService $partCountSrv): JsonR
'slots' => [],
'meals' => [],
'isEnabled' => $day->isEnabled(),
'event' => $this->apiSrv->getEventParticipationData($day, $profile),
];

$this->addSlots($response[$week->getId()]['days'][$day->getId()]['slots'], $slots, $day, $activeParticipations);
Expand Down Expand Up @@ -168,6 +169,8 @@ public function list(): JSONResponse
$list['meals'] = $list['meals'] + $this->getDishData($meal);
}

$list['event'] = $this->apiSrv->getEventParticipationInfo($day);

$list['day'] = $day->getDateTime();

return new JsonResponse($list, 200);
Expand Down
163 changes: 163 additions & 0 deletions src/Mealz/MealBundle/Controller/EventController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
<?php

declare(strict_types=1);

namespace App\Mealz\MealBundle\Controller;

use App\Mealz\MealBundle\Entity\Event;
use App\Mealz\MealBundle\Event\EventParticipationUpdateEvent;
use App\Mealz\MealBundle\Repository\DayRepositoryInterface;
use App\Mealz\MealBundle\Repository\EventRepositoryInterface;
use App\Mealz\MealBundle\Service\EventParticipationService;
use DateTime;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;

/**
* @Security("is_granted('ROLE_USER')")
*/
class EventController extends BaseListController
{
private DayRepositoryInterface $dayRepo;
private EntityManagerInterface $em;
private EventRepositoryInterface $eventRepo;
private EventDispatcherInterface $eventDispatcher;
private EventParticipationService $eventPartSrv;

public function __construct(
DayRepositoryInterface $dayRepoInterface,
EntityManagerInterface $entityManager,
EventRepositoryInterface $eventRepository,
EventDispatcherInterface $eventDispatcher,
EventParticipationService $eventPartSrv
) {
$this->dayRepo = $dayRepoInterface;
$this->em = $entityManager;
$this->eventRepo = $eventRepository;
$this->eventDispatcher = $eventDispatcher;
$this->eventPartSrv = $eventPartSrv;
}

public function getEventList(): JsonResponse
{
$events = $this->eventRepo->findBy(['deleted' => 0]);

return new JsonResponse($events, 200);
}

/**
* @Security("is_granted('ROLE_KITCHEN_STAFF')")
*/
public function new(Request $request): JsonResponse
{
$parameters = json_decode($request->getContent(), true);
if (false === isset($parameters['title']) || false === isset($parameters['public'])) {
return new JsonResponse(['message' => '701: Event creation parameters are not set'], 500);
}

$event = new Event($parameters['title'], $parameters['public']);
$this->em->persist($event);
$this->em->flush();

return new JsonResponse(null, 200);
}

/**
* @Security("is_granted('ROLE_KITCHEN_STAFF')")
*/
public function update(Request $request, Event $event): JsonResponse
{
try {
$parameters = json_decode($request->getContent(), true);

if (true === isset($parameters['title'])) {
$event->setTitle($parameters['title']);
}

if (true === isset($parameters['public'])) {
$event->setPublic($parameters['public']);
}

$this->em->persist($event);
$this->em->flush();

return new JsonResponse($event, 200);
} catch (Exception $e) {
$this->logException($e);

return new JsonResponse(['message' => $e->getMessage(), 500]);
}
}

/**
* @Security("is_granted('ROLE_KITCHEN_STAFF')")
*/
public function delete(Event $event): JsonResponse
{
try {
$event->setDeleted(true);

$this->em->persist($event);
$this->em->flush();

return new JsonResponse(null, 200);
} catch (Exception $e) {
$this->logException($e);

return new JsonResponse(['message' => $e->getMessage(), 500]);
}
}

public function join(DateTime $date): JsonResponse
{
$profile = $this->getProfile();
if (null === $profile) {
return new JsonResponse(['message' => '801: User is not allowed to join'], 403);
}

$day = $this->dayRepo->getDayByDate($date);

$eventParticipation = $this->eventPartSrv->join($profile, $day);
if (null === $eventParticipation) {
return new JsonResponse(['message' => '802: User could not join the event'], 500);
}

$this->eventDispatcher->dispatch(new EventParticipationUpdateEvent($eventParticipation));

return new JsonResponse($this->eventPartSrv->getEventParticipationData($day, $profile), 200);
}

public function leave(DateTime $date): JsonResponse
{
$profile = $this->getProfile();
if (null === $profile) {
return new JsonResponse(['message' => '801: User is not allowed to leave'], 403);
}

$day = $this->dayRepo->getDayByDate($date);

$eventParticipation = $this->eventPartSrv->leave($profile, $day);
if (null === $eventParticipation) {
return new JsonResponse(['message' => '802: User could not leave the event'], 500);
}

$this->eventDispatcher->dispatch(new EventParticipationUpdateEvent($eventParticipation));

return new JsonResponse($this->eventPartSrv->getEventParticipationData($day, $profile), 200);
}

public function getEventParticipants(DateTime $date): JsonResponse
{
$day = $this->dayRepo->getDayByDate($date);

if (null === $day) {
return new JsonResponse(['message' => 'Could not find day'], 404);
}

return new JsonResponse($this->eventPartSrv->getParticipants($day), 200);
}
}
26 changes: 0 additions & 26 deletions src/Mealz/MealBundle/Controller/LanguageController.php

This file was deleted.

8 changes: 7 additions & 1 deletion src/Mealz/MealBundle/Controller/MealAdminController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use App\Mealz\MealBundle\Repository\WeekRepositoryInterface;
use App\Mealz\MealBundle\Service\DayService;
use App\Mealz\MealBundle\Service\DishService;
use App\Mealz\MealBundle\Service\EventParticipationService;
use App\Mealz\MealBundle\Service\WeekService;
use DateTime;
use DateTimeZone;
Expand All @@ -35,6 +36,7 @@ class MealAdminController extends BaseController
private DayRepositoryInterface $dayRepository;
private DayService $dayService;
private DishService $dishService;
private EventParticipationService $eventService;
private EntityManagerInterface $em;

public function __construct(
Expand All @@ -45,6 +47,7 @@ public function __construct(
DayRepositoryInterface $dayRepository,
DayService $dayService,
DishService $dishService,
EventParticipationService $eventService,
EntityManagerInterface $em
) {
$this->eventDispatcher = $eventDispatcher;
Expand All @@ -54,6 +57,7 @@ public function __construct(
$this->dayRepository = $dayRepository;
$this->dayService = $dayService;
$this->dishService = $dishService;
$this->eventService = $eventService;
$this->em = $em;
}

Expand Down Expand Up @@ -113,7 +117,7 @@ public function new(DateTime $date, Request $request): JsonResponse
$this->handleNewDay($dayData, $weekDays[$dayIndex++]);
}
} catch (Exception $e) {
return new JsonResponse(['message' => $e->getMessage()], 500);
return new JsonResponse(['message' => 'NoErrorNumber: ' . $e->getMessage()], 500);
}

$this->em->persist($week);
Expand Down Expand Up @@ -213,6 +217,7 @@ private function handleDay(array $day)
}

$this->setLockParticipationForDay($dayEntity, $day);
$this->eventService->handleEventParticipation($dayEntity, $day['event']);

$mealCollection = $day['meals'];
/*
Expand Down Expand Up @@ -244,6 +249,7 @@ private function handleNewDay($dayData, Day $day)
}

$this->setLockParticipationForDay($day, $dayData);
$this->eventService->handleEventParticipation($day, $dayData['event']);

$mealCollection = $dayData['meals'];
// max 2 main meals allowed
Expand Down
Loading
Loading