Feature: [calendar] allow to create and generate calendar by person

This commit is contained in:
2022-10-21 13:24:02 +02:00
parent 43dcb46d38
commit bc1a7c1d7b
15 changed files with 677 additions and 245 deletions

View File

@@ -18,15 +18,19 @@ use Chill\CalendarBundle\Repository\CalendarACLAwareRepositoryInterface;
use Chill\DocGeneratorBundle\Repository\DocGeneratorTemplateRepository;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Pagination\PaginatorFactory;
use Chill\MainBundle\Repository\UserRepository;
use Chill\MainBundle\Templating\Listing\FilterOrderHelper;
use Chill\MainBundle\Templating\Listing\FilterOrderHelperFactoryInterface;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\AccompanyingPeriodRepository;
use Chill\PersonBundle\Repository\PersonRepository;
use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter;
use Chill\PersonBundle\Security\Authorization\PersonVoter;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use DateTimeImmutable;
use Exception;
use Psr\Log\LoggerInterface;
use RuntimeException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Form;
@@ -40,6 +44,8 @@ use Symfony\Component\Serializer\SerializerInterface;
class CalendarController extends AbstractController
{
private AccompanyingPeriodRepository $accompanyingPeriodRepository;
private CalendarACLAwareRepositoryInterface $calendarACLAwareRepository;
private DocGeneratorTemplateRepository $docGeneratorTemplateRepository;
@@ -50,12 +56,12 @@ class CalendarController extends AbstractController
private PaginatorFactory $paginator;
private PersonRepository $personRepository;
private RemoteCalendarConnectorInterface $remoteCalendarConnector;
private SerializerInterface $serializer;
private UserRepository $userRepository;
public function __construct(
CalendarACLAwareRepositoryInterface $calendarACLAwareRepository,
DocGeneratorTemplateRepository $docGeneratorTemplateRepository,
@@ -64,7 +70,8 @@ class CalendarController extends AbstractController
PaginatorFactory $paginator,
RemoteCalendarConnectorInterface $remoteCalendarConnector,
SerializerInterface $serializer,
UserRepository $userRepository
PersonRepository $personRepository,
AccompanyingPeriodRepository $accompanyingPeriodRepository
) {
$this->calendarACLAwareRepository = $calendarACLAwareRepository;
$this->docGeneratorTemplateRepository = $docGeneratorTemplateRepository;
@@ -73,7 +80,8 @@ class CalendarController extends AbstractController
$this->paginator = $paginator;
$this->remoteCalendarConnector = $remoteCalendarConnector;
$this->serializer = $serializer;
$this->userRepository = $userRepository;
$this->personRepository = $personRepository;
$this->accompanyingPeriodRepository = $accompanyingPeriodRepository;
}
/**
@@ -83,19 +91,21 @@ class CalendarController extends AbstractController
*/
public function deleteAction(Request $request, Calendar $entity)
{
$view = null;
$em = $this->getDoctrine()->getManager();
$accompanyingPeriod = $entity->getAccompanyingPeriod();
$user = null; // TODO legacy code ? remove it ?
[$person, $accompanyingPeriod] = [$entity->getPerson(), $entity->getAccompanyingPeriod()];
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = '@ChillCalendar/Calendar/confirm_deleteByAccompanyingCourse.html.twig';
} elseif ($user instanceof User) {
$view = '@ChillCalendar/Calendar/confirm_deleteByUser.html.twig';
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_period', ['id' => $accompanyingPeriod->getId()]);
} elseif ($person instanceof Person) {
$view = '@ChillCalendar/Calendar/confirm_deleteByPerson.html.twig';
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]);
} else {
throw new RuntimeException('nor person or accompanying period');
}
$form = $this->createDeleteForm($entity->getId(), $user, $accompanyingPeriod);
$form = $this->createDeleteForm($entity);
if ($request->getMethod() === Request::METHOD_DELETE) {
$form->handleRequest($request);
@@ -112,20 +122,15 @@ class CalendarController extends AbstractController
$this->addFlash('success', $this->get('translator')
->trans('The calendar item has been successfully removed.'));
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
return $this->redirectToRoute('chill_calendar_calendar_list_by_period', $params);
return new RedirectResponse($redirectRoute);
}
}
if (null === $view) {
throw $this->createNotFoundException('Template not found');
}
return $this->render($view, [
'calendar' => $entity,
'delete_form' => $form->createView(),
'accompanyingCourse' => $accompanyingPeriod,
'person' => $person,
]);
}
@@ -143,13 +148,16 @@ class CalendarController extends AbstractController
$view = null;
$em = $this->getDoctrine()->getManager();
[$user, $accompanyingPeriod] = $this->getEntity($request);
[$person, $accompanyingPeriod] = [$entity->getPerson(), $entity->getAccompanyingPeriod()];
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = '@ChillCalendar/Calendar/editByAccompanyingCourse.html.twig';
} elseif ($user instanceof User) {
throw new Exception('to analyze');
$view = '@ChillCalendar/Calendar/editByUser.html.twig';
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_period', ['id' => $accompanyingPeriod->getId()]);
} elseif ($person instanceof Person) {
$view = '@ChillCalendar/Calendar/editByPerson.html.twig';
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]);
} else {
throw new RuntimeException('no person nor accompanying period');
}
$form = $this->createForm(CalendarType::class, $entity)
@@ -163,33 +171,24 @@ class CalendarController extends AbstractController
$this->addFlash('success', $this->get('translator')->trans('Success : calendar item updated!'));
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
if ($form->get('save_and_create_doc')->isClicked()) {
return $this->redirectToRoute('chill_calendar_calendardoc_pick_template', ['id' => $entity->getId()]);
}
return $this->redirectToRoute('chill_calendar_calendar_list_by_period', $params);
return new RedirectResponse($redirectRoute);
}
if ($form->isSubmitted() && !$form->isValid()) {
$this->addFlash('error', $this->get('translator')->trans('This form contains errors'));
}
$deleteForm = $this->createDeleteForm($entity->getId(), $user, $accompanyingPeriod);
if (null === $view) {
throw $this->createNotFoundException('Template not found');
}
$entity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
return $this->render($view, [
'entity' => $entity,
'form' => $form->createView(),
'delete_form' => $deleteForm->createView(),
'accompanyingCourse' => $accompanyingPeriod,
// 'user' => $user,
'accompanyingCourse' => $entity->getAccompanyingPeriod(),
'person' => $entity->getPerson(),
'entity_json' => $entity_array,
]);
}
@@ -225,6 +224,37 @@ class CalendarController extends AbstractController
]);
}
/**
* Lists all Calendar entities on a person.
*
* @Route("/{_locale}/calendar/calendar/by-person/{id}", name="chill_calendar_calendar_list_by_person")
*/
public function listActionByPerson(Person $person): Response
{
$filterOrder = $this->buildListFilterOrder();
['from' => $from, 'to' => $to] = $filterOrder->getDateRangeData('startDate');
$total = $this->calendarACLAwareRepository
->countByPerson($person, $from, $to);
$paginator = $this->paginator->create($total);
$calendarItems = $this->calendarACLAwareRepository->findByPerson(
$person,
$from,
$to,
['startDate' => 'DESC'],
$paginator->getCurrentPageFirstItemNumber(),
$paginator->getItemsPerPage()
);
return $this->render('@ChillCalendar/Calendar/listByPerson.html.twig', [
'calendarItems' => $calendarItems,
'person' => $person,
'paginator' => $paginator,
'filterOrder' => $filterOrder,
'hasDocs' => 0 < $this->docGeneratorTemplateRepository->countByEntity(Calendar::class),
]);
}
/**
* @Route("/{_locale}/calendar/calendar/my", name="chill_calendar_calendar_list_my")
*/
@@ -261,27 +291,22 @@ class CalendarController extends AbstractController
$view = null;
$em = $this->getDoctrine()->getManager();
[$user, $accompanyingPeriod] = $this->getEntity($request);
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = '@ChillCalendar/Calendar/newByAccompanyingCourse.html.twig';
}
// elseif ($user instanceof User) {
// $view = '@ChillCalendar/Calendar/newUser.html.twig';
// }
[$person, $accompanyingPeriod] = $this->getEntity($request);
$entity = new Calendar();
if ($request->query->has('mainUser')) {
$entity->setMainUser($this->userRepository->find($request->query->getInt('mainUser')));
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$view = '@ChillCalendar/Calendar/newByAccompanyingCourse.html.twig';
$entity->setAccompanyingPeriod($accompanyingPeriod);
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_period', ['id' => $accompanyingPeriod->getId()]);
} elseif ($person) {
$view = '@ChillCalendar/Calendar/newByPerson.html.twig';
$entity->setPerson($person)->addPerson($person);
$redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]);
}
// if ($user instanceof User) {
// $entity->setPerson($user);
// }
if ($accompanyingPeriod instanceof AccompanyingPeriod) {
$entity->setAccompanyingPeriod($accompanyingPeriod);
if ($request->query->has('mainUser')) {
$entity->setMainUser($this->userRepository->find($request->query->getInt('mainUser')));
}
$form = $this->createForm(CalendarType::class, $entity)
@@ -296,13 +321,11 @@ class CalendarController extends AbstractController
$this->addFlash('success', $this->get('translator')->trans('Success : calendar item created!'));
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
if ($form->get('save_and_create_doc')->isClicked()) {
return $this->redirectToRoute('chill_calendar_calendardoc_pick_template', ['id' => $entity->getId()]);
}
return $this->redirectToRoute('chill_calendar_calendar_list_by_period', $params);
return new RedirectResponse($redirectRoute);
}
if ($form->isSubmitted() && !$form->isValid()) {
@@ -316,7 +339,8 @@ class CalendarController extends AbstractController
$entity_array = $this->serializer->normalize($entity, 'json', ['groups' => 'read']);
return $this->render($view, [
'user' => $user,
'context' => $entity->getContext(),
'person' => $person,
'accompanyingCourse' => $accompanyingPeriod,
'entity' => $entity,
'form' => $form->createView(),
@@ -331,6 +355,7 @@ class CalendarController extends AbstractController
*/
public function showAction(Request $request, int $id): Response
{
throw new Exception('not implemented');
$view = null;
$em = $this->getDoctrine()->getManager();
@@ -465,49 +490,45 @@ class CalendarController extends AbstractController
/**
* Creates a form to delete a Calendar entity by id.
*/
private function createDeleteForm(int $id, ?User $user, ?AccompanyingPeriod $accompanyingPeriod): FormInterface
private function createDeleteForm(Calendar $calendar): FormInterface
{
$params = $this->buildParamsToUrl($user, $accompanyingPeriod);
$params['id'] = $id;
return $this->createFormBuilder()
->setAction($this->generateUrl('chill_calendar_calendar_delete', $params))
->setAction($this->generateUrl('chill_calendar_calendar_delete', ['id' => $calendar->getId()]))
->setMethod('DELETE')
->add('submit', SubmitType::class, ['label' => 'Delete'])
->getForm();
}
/**
* @return array{0: ?Person, 1: ?AccompanyingPeriod}
*/
private function getEntity(Request $request): array
{
$em = $this->getDoctrine()->getManager();
$user = $accompanyingPeriod = null;
$person = $accompanyingPeriod = null;
if ($request->query->has('user_id')) {
$user_id = $request->get('user_id');
$user = $em->getRepository(User::class)->find($user_id);
if ($request->query->has('person_id')) {
$person = $this->personRepository->find($request->query->getInt('person_id'));
if (null === $user) {
throw $this->createNotFoundException('User not found');
if (null === $person) {
throw $this->createNotFoundException('Person not found');
}
// TODO Add permission
// $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $user);
$this->denyAccessUnlessGranted(PersonVoter::SEE, $person);
} elseif ($request->query->has('accompanying_period_id')) {
$accompanying_period_id = $request->get('accompanying_period_id');
$accompanyingPeriod = $em->getRepository(AccompanyingPeriod::class)->find($accompanying_period_id);
$accompanyingPeriod = $this->accompanyingPeriodRepository->find($request->query->getInt('accompanying_period_id'));
if (null === $accompanyingPeriod) {
throw $this->createNotFoundException('Accompanying Period not found');
}
// TODO Add permission
// $this->denyAccessUnlessGranted('CHILL_PERSON_SEE', $person);
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $accompanyingPeriod);
} else {
throw $this->createNotFoundException('Person or Accompanying Period not found');
}
return [
$user, $accompanyingPeriod,
$person, $accompanyingPeriod,
];
}
}