diff --git a/.changes/unreleased/Feature-20250808-120802.yaml b/.changes/unreleased/Feature-20250808-120802.yaml new file mode 100644 index 000000000..50d1eb8ba --- /dev/null +++ b/.changes/unreleased/Feature-20250808-120802.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: Create invitation list in user menu +time: 2025-08-08T12:08:02.446361367+02:00 +custom: + Issue: "385" + SchemaChange: No schema change diff --git a/.changes/unreleased/Feature-20251007-155945.yaml b/.changes/unreleased/Feature-20251007-155945.yaml new file mode 100644 index 000000000..9b59e7ea5 --- /dev/null +++ b/.changes/unreleased/Feature-20251007-155945.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: Admin interface for Motive entity +time: 2025-10-07T15:59:45.597029709+02:00 +custom: + Issue: "" + SchemaChange: No schema change diff --git a/.changes/unreleased/Feature-20251022-111552.yaml b/.changes/unreleased/Feature-20251022-111552.yaml new file mode 100644 index 000000000..058e40d82 --- /dev/null +++ b/.changes/unreleased/Feature-20251022-111552.yaml @@ -0,0 +1,6 @@ +kind: Feature +body: Add an admin interface for Motive entity +time: 2025-10-22T11:15:52.13937955+02:00 +custom: + Issue: "" + SchemaChange: Add columns or tables diff --git a/.changes/unreleased/Fixed-20251106-161605.yaml b/.changes/unreleased/Fixed-20251106-161605.yaml new file mode 100644 index 000000000..3962daf8a --- /dev/null +++ b/.changes/unreleased/Fixed-20251106-161605.yaml @@ -0,0 +1,6 @@ +kind: Fixed +body: Fix suggestion of referrer when creating notification for accompanyingPeriodWorkDocument +time: 2025-11-06T16:16:05.861813041+01:00 +custom: + Issue: "428" + SchemaChange: No schema change diff --git a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php index 94db03b1f..6705d7bb7 100644 --- a/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php +++ b/src/Bundle/ChillCalendarBundle/Controller/CalendarController.php @@ -13,6 +13,7 @@ namespace Chill\CalendarBundle\Controller; use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Form\CalendarType; +use Chill\CalendarBundle\Form\CancelType; use Chill\CalendarBundle\RemoteCalendar\Connector\RemoteCalendarConnectorInterface; use Chill\CalendarBundle\Repository\CalendarACLAwareRepositoryInterface; use Chill\CalendarBundle\Security\Voter\CalendarVoter; @@ -30,6 +31,7 @@ use Chill\PersonBundle\Repository\PersonRepository; use Chill\PersonBundle\Security\Authorization\AccompanyingPeriodVoter; use Chill\PersonBundle\Security\Authorization\PersonVoter; use Chill\ThirdPartyBundle\Entity\ThirdParty; +use Doctrine\ORM\EntityManagerInterface; use http\Exception\UnexpectedValueException; use Psr\Log\LoggerInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -60,6 +62,7 @@ class CalendarController extends AbstractController private readonly UserRepositoryInterface $userRepository, private readonly TranslatorInterface $translator, private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry, + private readonly EntityManagerInterface $em, ) {} /** @@ -111,6 +114,55 @@ class CalendarController extends AbstractController ]); } + #[Route(path: '/{_locale}/calendar/calendar/{id}/cancel', name: 'chill_calendar_calendar_cancel')] + public function cancelAction(Calendar $calendar, Request $request): Response + { + // Deal with sms being sent or not + // Communicate cancellation with the remote calendar. + + $this->denyAccessUnlessGranted(CalendarVoter::EDIT, $calendar); + + [$person, $accompanyingPeriod] = [$calendar->getPerson(), $calendar->getAccompanyingPeriod()]; + + $form = $this->createForm(CancelType::class, $calendar); + $form->add('submit', SubmitType::class); + + if ($accompanyingPeriod instanceof AccompanyingPeriod) { + $view = '@ChillCalendar/Calendar/cancelCalendarByAccompanyingCourse.html.twig'; + $redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_period', ['id' => $accompanyingPeriod->getId()]); + } elseif ($person instanceof Person) { + $view = '@ChillCalendar/Calendar/cancelCalendarByPerson.html.twig'; + $redirectRoute = $this->generateUrl('chill_calendar_calendar_list_by_person', ['id' => $person->getId()]); + } else { + throw new \RuntimeException('nor person or accompanying period'); + } + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + + $this->logger->notice('A calendar event has been cancelled', [ + 'by_user' => $this->getUser()->getUsername(), + 'calendar_id' => $calendar->getId(), + ]); + + $calendar->setStatus($calendar::STATUS_CANCELED); + $calendar->setSmsStatus($calendar::SMS_CANCEL_PENDING); + $this->em->flush(); + + $this->addFlash('success', $this->translator->trans('chill_calendar.calendar_canceled')); + + return new RedirectResponse($redirectRoute); + } + + return $this->render($view, [ + 'calendar' => $calendar, + 'form' => $form->createView(), + 'accompanyingCourse' => $accompanyingPeriod, + 'person' => $person, + ]); + } + /** * Edit a calendar item. */ @@ -266,7 +318,7 @@ class CalendarController extends AbstractController } if (!$this->getUser() instanceof User) { - throw new UnauthorizedHttpException('you are not an user'); + throw new UnauthorizedHttpException('you are not a user'); } $view = '@ChillCalendar/Calendar/listByUser.html.twig'; diff --git a/src/Bundle/ChillCalendarBundle/Controller/MyInvitationsController.php b/src/Bundle/ChillCalendarBundle/Controller/MyInvitationsController.php new file mode 100644 index 000000000..7af5ac18f --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Controller/MyInvitationsController.php @@ -0,0 +1,58 @@ +denyAccessUnlessGranted('ROLE_USER'); + + $user = $this->getUser(); + + if (!$user instanceof User) { + throw new UnauthorizedHttpException('you are not a user'); + } + + $total = count($this->inviteRepository->findBy(['user' => $user])); + $paginator = $this->paginator->create($total); + + $invitations = $this->inviteRepository->findBy( + ['user' => $user], + ['createdAt' => 'DESC'], + $paginator->getItemsPerPage(), + $paginator->getCurrentPageFirstItemNumber() + ); + + $view = '@ChillCalendar/Invitations/listByUser.html.twig'; + + return $this->render($view, [ + 'invitations' => $invitations, + 'paginator' => $paginator, + 'templates' => $this->docGeneratorTemplateRepository->findByEntity(Calendar::class), + ]); + } +} diff --git a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php index d7e552d5d..2a8e371e0 100644 --- a/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php +++ b/src/Bundle/ChillCalendarBundle/DataFixtures/ORM/LoadCancelReason.php @@ -35,7 +35,7 @@ class LoadCancelReason extends Fixture implements FixtureGroupInterface $arr = [ ['name' => CancelReason::CANCELEDBY_USER], ['name' => CancelReason::CANCELEDBY_PERSON], - ['name' => CancelReason::CANCELEDBY_DONOTCOUNT], + ['name' => CancelReason::CANCELEDBY_OTHER], ]; foreach ($arr as $a) { diff --git a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php index dad302193..c194c247e 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/Calendar.php +++ b/src/Bundle/ChillCalendarBundle/Entity/Calendar.php @@ -269,6 +269,11 @@ class Calendar implements TrackCreationInterface, TrackUpdateInterface, HasCente return $this->cancelReason; } + public function isCanceled(): bool + { + return null !== $this->cancelReason; + } + public function getCenters(): ?iterable { return match ($this->getContext()) { diff --git a/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php b/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php index d4a2ed9a9..04192133c 100644 --- a/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php +++ b/src/Bundle/ChillCalendarBundle/Entity/CancelReason.php @@ -18,14 +18,14 @@ use Doctrine\ORM\Mapping as ORM; #[ORM\Table(name: 'chill_calendar.cancel_reason')] class CancelReason { - final public const CANCELEDBY_DONOTCOUNT = 'CANCELEDBY_DONOTCOUNT'; + final public const CANCELEDBY_OTHER = 'CANCELEDBY_OTHER'; final public const CANCELEDBY_PERSON = 'CANCELEDBY_PERSON'; final public const CANCELEDBY_USER = 'CANCELEDBY_USER'; - #[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN)] - private ?bool $active = null; + #[ORM\Column(type: \Doctrine\DBAL\Types\Types::BOOLEAN, options: ['default' => true])] + private bool $active = true; #[ORM\Column(type: \Doctrine\DBAL\Types\Types::STRING, length: 255)] private ?string $canceledBy = null; diff --git a/src/Bundle/ChillCalendarBundle/Form/CancelReasonType.php b/src/Bundle/ChillCalendarBundle/Form/CancelReasonType.php index c0ac4ddb0..311d3ac02 100644 --- a/src/Bundle/ChillCalendarBundle/Form/CancelReasonType.php +++ b/src/Bundle/ChillCalendarBundle/Form/CancelReasonType.php @@ -15,7 +15,7 @@ use Chill\CalendarBundle\Entity\CancelReason; use Chill\MainBundle\Form\Type\TranslatableStringFormType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\TextType; +use Symfony\Component\Form\Extension\Core\Type\ChoiceType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -28,7 +28,14 @@ class CancelReasonType extends AbstractType ->add('active', CheckboxType::class, [ 'required' => false, ]) - ->add('canceledBy', TextType::class); + ->add('canceledBy', ChoiceType::class, [ + 'choices' => [ + 'chill_calendar.canceled_by.user' => CancelReason::CANCELEDBY_USER, + 'chill_calendar.canceled_by.person' => CancelReason::CANCELEDBY_PERSON, + 'chill_calendar.canceled_by.other' => CancelReason::CANCELEDBY_OTHER, + ], + 'required' => true, + ]); } public function configureOptions(OptionsResolver $resolver) diff --git a/src/Bundle/ChillCalendarBundle/Form/CancelType.php b/src/Bundle/ChillCalendarBundle/Form/CancelType.php new file mode 100644 index 000000000..ad41a6105 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Form/CancelType.php @@ -0,0 +1,42 @@ +add('cancelReason', EntityType::class, [ + 'class' => CancelReason::class, + 'required' => true, + 'choice_label' => fn (CancelReason $cancelReason) => $this->translatableStringHelper->localize($cancelReason->getName()), + ]); + } + + public function configureOptions(OptionsResolver $resolver) + { + $resolver->setDefaults([ + 'data_class' => Calendar::class, + + ]); + } +} diff --git a/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php b/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php index 3a062f7b8..672b53460 100644 --- a/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Menu/UserMenuBuilder.php @@ -25,6 +25,13 @@ class UserMenuBuilder implements LocalMenuBuilderInterface if ($this->security->isGranted('ROLE_USER')) { $menu->addChild('My calendar list', [ 'route' => 'chill_calendar_calendar_list_my', + ]) + ->setExtras([ + 'order' => 8, + 'icon' => 'tasks', + ]); + $menu->addChild('invite.list.title', [ + 'route' => 'chill_calendar_invitations_list_my', ]) ->setExtras([ 'order' => 9, diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php index 8f62fdcdb..2319fde99 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Doctrine/CalendarEntityListener.php @@ -21,6 +21,7 @@ namespace Chill\CalendarBundle\Messenger\Doctrine; use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Messenger\Message\CalendarMessage; use Chill\CalendarBundle\Messenger\Message\CalendarRemovedMessage; +use Chill\MainBundle\Entity\User; use Doctrine\ORM\Event\PostPersistEventArgs; use Doctrine\ORM\Event\PostRemoveEventArgs; use Doctrine\ORM\Event\PostUpdateEventArgs; @@ -31,6 +32,17 @@ class CalendarEntityListener { public function __construct(private readonly MessageBusInterface $messageBus, private readonly Security $security) {} + private function getAuthenticatedUser(): User + { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new \LogicException('Expected an instance of User.'); + } + + return $user; + } + public function postPersist(Calendar $calendar, PostPersistEventArgs $args): void { if (!$calendar->preventEnqueueChanges) { @@ -38,7 +50,7 @@ class CalendarEntityListener new CalendarMessage( $calendar, CalendarMessage::CALENDAR_PERSIST, - $this->security->getUser() + $this->getAuthenticatedUser() ) ); } @@ -50,7 +62,7 @@ class CalendarEntityListener $this->messageBus->dispatch( new CalendarRemovedMessage( $calendar, - $this->security->getUser() + $this->getAuthenticatedUser() ) ); } @@ -58,12 +70,19 @@ class CalendarEntityListener public function postUpdate(Calendar $calendar, PostUpdateEventArgs $args): void { - if (!$calendar->preventEnqueueChanges) { + if ($calendar->getStatus() === $calendar::STATUS_CANCELED) { + $this->messageBus->dispatch( + new CalendarRemovedMessage( + $calendar, + $this->getAuthenticatedUser() + ) + ); + } elseif (!$calendar->preventEnqueueChanges) { $this->messageBus->dispatch( new CalendarMessage( $calendar, CalendarMessage::CALENDAR_UPDATE, - $this->security->getUser() + $this->getAuthenticatedUser() ) ); } diff --git a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php index 53dcea28c..7d2e88fef 100644 --- a/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php +++ b/src/Bundle/ChillCalendarBundle/Messenger/Message/CalendarRemovedMessage.php @@ -70,6 +70,8 @@ class CalendarRemovedMessage public function getRemoteId(): string { + dump($this->remoteId); + return $this->remoteId; } } diff --git a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php index 3121854e5..e6f90f279 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/CalendarRepository.php @@ -191,6 +191,7 @@ class CalendarRepository implements ObjectRepository $qb->expr()->eq('c.mainUser', ':user'), $qb->expr()->gte('c.startDate', ':startDate'), $qb->expr()->lte('c.endDate', ':endDate'), + $qb->expr()->isNull('c.cancelReason'), ) ) ->setParameters([ diff --git a/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php b/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php index 8778330f8..6cb34738c 100644 --- a/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php +++ b/src/Bundle/ChillCalendarBundle/Repository/InviteRepository.php @@ -41,7 +41,7 @@ class InviteRepository implements ObjectRepository /** * @return array|Invite[] */ - public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null) + public function findBy(array $criteria, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array { return $this->entityRepository->findBy($criteria, $orderBy, $limit, $offset); } diff --git a/src/Bundle/ChillCalendarBundle/Resources/config/services/controller.yml b/src/Bundle/ChillCalendarBundle/Resources/config/services/controller.yml index a0457c5a8..cce562d7d 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/config/services/controller.yml +++ b/src/Bundle/ChillCalendarBundle/Resources/config/services/controller.yml @@ -1,5 +1,6 @@ services: Chill\CalendarBundle\Controller\: autowire: true + autoconfigure: true resource: '../../../Controller' tags: ['controller.service_arguments'] diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig index cff5c00cc..c827ca4f4 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/_list.html.twig @@ -1,17 +1,23 @@ -{# list used in context of person or accompanyingPeriod #} +{# list used in context of person, accompanyingPeriod or user #} -{% if calendarItems|length > 0 %} -
- - {% for calendar in calendarItems %} - -
-
-
-
+
+
+
+
+
+ {% if calendar.status == 'canceled' %} +
+ {{ 'chill_calendar.canceled'|trans }}: + {{ calendar.cancelReason.name|localize_translatable_string }} +
+ {% endif %} +

+ {% if calendar.status == 'canceled' %} + + {% endif %} {% if context == 'person' and calendar.context == 'accompanying_period' %} @@ -19,6 +25,9 @@ {% endif %} + {% if calendar.status == 'canceled' %} + + {% endif %} {% if calendar.endDate.diff(calendar.startDate).days >= 1 %} {{ calendar.startDate|format_datetime('short', 'short') }} - {{ calendar.endDate|format_datetime('short', 'short') }} @@ -26,44 +35,46 @@ {{ calendar.startDate|format_datetime('short', 'short') }} - {{ calendar.endDate|format_datetime('none', 'short') }} {% endif %} -

- -
- - {{ calendar.duration|date('%H:%I') }} - {% if false == calendar.sendSMS or null == calendar.sendSMS %} - - {% else %} - {% if calendar.smsStatus == 'sms_sent' %} - - - - - {% else %} - - - - - {% endif %} + {% if calendar.status == 'canceled' %} + {% endif %} -
-
-
-
- -
-
    - {% if calendar.mainUser is not empty %} - {{ calendar.mainUser|chill_entity_render_box({'at_date': calendar.startDate}) }} +
    + + {{ calendar.duration|date('%H:%I') }} + {% if false == calendar.sendSMS or null == calendar.sendSMS %} + + {% else %} + {% if calendar.smsStatus == 'sms_sent' %} + + + + + {% else %} + + + + {% endif %} -
+ {% endif %}
+
- {% if calendar.comment.comment is not empty +
+
    + {% if calendar.mainUser is not empty %} + {{ calendar.mainUser|chill_entity_render_box({'at_date': calendar.startDate}) }} + {% endif %} +
+
+ +
+
+ + {% if calendar.comment.comment is not empty or calendar.users|length > 0 or calendar.thirdParties|length > 0 or calendar.users|length > 0 %} @@ -76,131 +87,133 @@ } %}
-
- {% endif %} +
+ {% endif %} + + {% if calendar.comment.comment is not empty %} +
+
+ {{ calendar.comment|chill_entity_render_box( { 'limit_lines': 3, 'metadata': false } ) }} +
+
+ {% endif %} + + {% if calendar.location is not empty %} +
+
+ {% if calendar.location.address is not same as(null) and calendar.location.name is not empty %} + {% endif %} + {% if calendar.location.name is not empty %}{{ calendar.location.name }}{% endif %} + {% if calendar.location.address is not same as(null) %}{{ calendar.location.address|chill_entity_render_box({'multiline': false, 'with_picto': (calendar.location.name is empty)}) }}{% else %} + {% endif %} + {% if calendar.location.phonenumber1 is not empty %} {{ calendar.location.phonenumber1|chill_format_phonenumber }}{% endif %} + {% if calendar.location.phonenumber2 is not empty %} {{ calendar.location.phonenumber2|chill_format_phonenumber }}{% endif %} +
+
+ {% endif %} + + {% if calendar.documents is not empty %} +
+
+ {{ include('@ChillCalendar/Calendar/_documents.twig.html') }} +
+
+ {% endif %} + + {% if calendar.activity is not null %} +
+
+
+
+

{{ 'Activity'|trans }}

+
+

+ + + {{ calendar.activity.type.name | localize_translatable_string }} + + {% if calendar.activity.emergency %} + {{ 'Emergency'|trans|upper }} + {% endif %} + +

+ +
    +
  • + + {{ 'Created by'|trans }} + {{ calendar.activity.createdBy|chill_entity_render_string({'at_date': calendar.activity.createdAt}) }}, {{ 'on'|trans }} {{ calendar.activity.createdAt|format_datetime('short', 'short') }} + +
  • + {% if is_granted('CHILL_ACTIVITY_SEE', calendar.activity) %} +
  • + +
  • + {% endif %} +
- {% if calendar.comment.comment is not empty %} -
-
- {{ calendar.comment|chill_entity_render_box( { 'limit_lines': 3, 'metadata': false } ) }}
- {% endif %} - - {% if calendar.location is not empty %} -
-
- {% if calendar.location.address is not same as(null) and calendar.location.name is not empty %} - {% endif %} - {% if calendar.location.name is not empty %}{{ calendar.location.name }}{% endif %} - {% if calendar.location.address is not same as(null) %}{{ calendar.location.address|chill_entity_render_box({'multiline': false, 'with_picto': (calendar.location.name is empty)}) }}{% else %} - {% endif %} - {% if calendar.location.phonenumber1 is not empty %} {{ calendar.location.phonenumber1|chill_format_phonenumber }}{% endif %} - {% if calendar.location.phonenumber2 is not empty %} {{ calendar.location.phonenumber2|chill_format_phonenumber }}{% endif %} -
-
- {% endif %} - -
-
- - {{ include('@ChillCalendar/Calendar/_documents.twig.html') }} -
+
+
+ {% endif %} - {% if calendar.activity is not null %} -
-
-
-
-

{{ 'Activity'|trans }}

-
-

- - - {{ calendar.activity.type.name | localize_translatable_string }} - - {% if calendar.activity.emergency %} - {{ 'Emergency'|trans|upper }} - {% endif %} - -

- -
    -
  • - - {{ 'Created by'|trans }} - {{ calendar.activity.createdBy|chill_entity_render_string({'at_date': calendar.activity.createdAt}) }}, {{ 'on'|trans }} {{ calendar.activity.createdAt|format_datetime('short', 'short') }} - -
  • - {% if is_granted('CHILL_ACTIVITY_SEE', calendar.activity) %} -
  • - -
  • - {% endif %} -
- -
-
+
+
-
+ + {% endif %} {% endif %} + {% if calendar.activity is null and ( + (calendar.context == 'accompanying_period' and is_granted('CHILL_ACTIVITY_CREATE', calendar.accompanyingPeriod)) + or + (calendar.context == 'person' and is_granted('CHILL_ACTIVITY_CREATE', calendar.person)) + ) + and calendar.status is not constant('STATUS_CANCELED', calendar) + %} +
  • + + {{ 'Transform to activity'|trans }} + +
  • + {% endif %} -
    -
      - {% if is_granted('CHILL_CALENDAR_DOC_EDIT', calendar) %} - {% if templates|length == 0 %} -
    • - - {{ 'chill_calendar.Add a document'|trans }} - -
    • - {% else %} -
    • - -
    • - {% endif %} - {% endif %} - {% if calendar.activity is null and ( - (calendar.context == 'accompanying_period' and is_granted('CHILL_ACTIVITY_CREATE', calendar.accompanyingPeriod)) - or - (calendar.context == 'person' and is_granted('CHILL_ACTIVITY_CREATE', calendar.person)) - ) - %} -
    • - - {{ 'Transform to activity'|trans }} - -
    • - {% endif %} - - {% if (calendar.isInvited(app.user)) %} + {% if calendar.isInvited(app.user) and not calendar.isCanceled %} {% set invite = calendar.inviteForUser(app.user) %}
    • {% endif %} - {% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', calendar) %} + + {% if is_granted('CHILL_CALENDAR_CALENDAR_EDIT', calendar) and calendar.status is not constant('STATUS_CANCELED', calendar) %}
    • +
    • + {{ 'Cancel'|trans }} +
    • {% endif %} + {% if is_granted('CHILL_CALENDAR_CALENDAR_DELETE', calendar) %}
    • -
    - -
    - {% endfor %} - - {% if calendarItems|length < paginator.getTotalItems %} - {{ chill_pagination(paginator) }} - {% endif %} -
    -{% endif %} + +
    + + diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/cancelCalendarByAccompanyingCourse.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/cancelCalendarByAccompanyingCourse.html.twig new file mode 100644 index 000000000..2f6759725 --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/cancelCalendarByAccompanyingCourse.html.twig @@ -0,0 +1,29 @@ +{% extends "@ChillPerson/AccompanyingCourse/layout.html.twig" %} + +{% set activeRouteKey = 'chill_calendar_calendar_list' %} + +{% block title 'chill_calendar.cancel_calendar_item'|trans %} + +{% block content %} + + {{ form_start(form) }} + + {{ form_row(form.cancelReason) }} + + + + {{ form_end(form) }} + +{% endblock %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/cancelCalendarByPerson.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/cancelCalendarByPerson.html.twig new file mode 100644 index 000000000..76196b23e --- /dev/null +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/cancelCalendarByPerson.html.twig @@ -0,0 +1,29 @@ +{% extends "@ChillPerson/Person/layout.html.twig" %} + +{% set activeRouteKey = 'chill_calendar_calendar_list' %} + +{% block title 'chill_calendar.cancel_calendar_item'|trans %} + +{% block content %} + + {{ form_start(form) }} + + {{ form_row(form.cancelReason) }} + + + + {{ form_end(form) }} + +{% endblock %} diff --git a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByAccompanyingCourse.html.twig b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByAccompanyingCourse.html.twig index 7ce1003bc..96ddb3388 100644 --- a/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByAccompanyingCourse.html.twig +++ b/src/Bundle/ChillCalendarBundle/Resources/views/Calendar/listByAccompanyingCourse.html.twig @@ -34,7 +34,18 @@ {% endif %}

    {% else %} - {{ include('@ChillCalendar/Calendar/_list.html.twig', {context: 'accompanying_course'}) }} + {% if calendarItems|length > 0 %} +
    + {% for calendar in calendarItems %} + {{ include('@ChillCalendar/Calendar/_list.html.twig', {context: 'accompanying_course'}) }} + {% endfor %} +
    + + {% if calendarItems|length < paginator.getTotalItems %} + {{ chill_pagination(paginator) }} + {% endif %} + + {% endif %} {% endif %}