From 6e2cce95313433eeb878393d7d3da4f158f01f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 28 Nov 2023 17:39:38 +0100 Subject: [PATCH] Event: add more fields: documents, organizationCost, note, and location --- .../Controller/EventController.php | 15 +++- src/Bundle/ChillEventBundle/Entity/Event.php | 90 +++++++++++++++++++ .../ChillEventBundle/Entity/Participation.php | 15 ++-- .../ChillEventBundle/Form/EventType.php | 28 ++++++ .../Resources/views/Event/edit.html.twig | 7 +- .../Resources/views/Event/new.html.twig | 17 +++- .../Resources/views/Event/show.html.twig | 82 +++++++++++------ .../migrations/Version20231128114959.php | 7 ++ .../migrations/Version20231128122635.php | 51 +++++++++++ .../translations/messages.fr.yml | 9 ++ 10 files changed, 282 insertions(+), 39 deletions(-) create mode 100644 src/Bundle/ChillEventBundle/migrations/Version20231128122635.php diff --git a/src/Bundle/ChillEventBundle/Controller/EventController.php b/src/Bundle/ChillEventBundle/Controller/EventController.php index 367c6c334..02fbe44af 100644 --- a/src/Bundle/ChillEventBundle/Controller/EventController.php +++ b/src/Bundle/ChillEventBundle/Controller/EventController.php @@ -17,6 +17,7 @@ use Chill\EventBundle\Form\EventType; use Chill\EventBundle\Form\Type\PickEventType; use Chill\EventBundle\Security\Authorization\EventVoter; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Entity\User; use Chill\MainBundle\Pagination\PaginatorFactory; use Chill\MainBundle\Security\Authorization\AuthorizationHelperInterface; use Chill\PersonBundle\Entity\Person; @@ -37,6 +38,8 @@ use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\StreamedResponse; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\Security\Core\Security; use Symfony\Contracts\Translation\TranslatorInterface; /** @@ -52,7 +55,8 @@ final class EventController extends AbstractController private readonly AuthorizationHelperInterface $authorizationHelper, private readonly FormFactoryInterface $formFactoryInterface, private readonly TranslatorInterface $translator, - private readonly PaginatorFactory $paginator + private readonly PaginatorFactory $paginator, + private readonly Security $security, ) {} /** @@ -202,6 +206,12 @@ final class EventController extends AbstractController */ public function newAction(?Center $center, Request $request) { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException('not a regular user. Maybe an administrator ?'); + } + if (null === $center) { $center_id = $request->query->get('center_id'); $center = $this->getDoctrine()->getRepository(Center::class)->find($center_id); @@ -209,6 +219,7 @@ final class EventController extends AbstractController $entity = new Event(); $entity->setCenter($center); + $entity->setLocation($user->getCurrentLocation()); $form = $this->createCreateForm($entity); $form->handleRequest($request); @@ -336,7 +347,7 @@ final class EventController extends AbstractController $this->addFlash('success', $this->translator ->trans('The event was updated')); - return $this->redirectToRoute('chill_event__event_edit', ['event_id' => $event_id]); + return $this->redirectToRoute('chill_event__event_show', ['event_id' => $event_id]); } return $this->render('@ChillEvent/Event/edit.html.twig', [ diff --git a/src/Bundle/ChillEventBundle/Entity/Event.php b/src/Bundle/ChillEventBundle/Entity/Event.php index 980610092..44f716edf 100644 --- a/src/Bundle/ChillEventBundle/Entity/Event.php +++ b/src/Bundle/ChillEventBundle/Entity/Event.php @@ -11,13 +11,16 @@ declare(strict_types=1); namespace Chill\EventBundle\Entity; +use Chill\DocStoreBundle\Entity\StoredObject; use Chill\MainBundle\Doctrine\Model\TrackCreationInterface; use Chill\MainBundle\Doctrine\Model\TrackCreationTrait; use Chill\MainBundle\Doctrine\Model\TrackUpdateInterface; use Chill\MainBundle\Doctrine\Model\TrackUpdateTrait; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable; use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\HasScopeInterface; +use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\Scope; use Chill\MainBundle\Entity\User; use DateTime; @@ -42,6 +45,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter /** * @ORM\ManyToOne(targetEntity="Chill\MainBundle\Entity\Center")A + * * @Assert\NotNull() */ private ?Center $center = null; @@ -72,6 +76,7 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter /** * @ORM\Column(type="string", length=150) + * * @Assert\NotBlank() */ private ?string $name = null; @@ -87,16 +92,45 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter /** * @ORM\ManyToOne(targetEntity="Chill\EventBundle\Entity\EventType") + * * @Assert\NotNull() */ private ?EventType $type = null; + /** + * @ORM\Embedded(class=CommentEmbeddable::class, columnPrefix="comment_") + */ + private CommentEmbeddable $comment; + + /** + * @ORM\ManyToOne(targetEntity=Location::class) + * + * @ORM\JoinColumn(nullable=true) + */ + private ?Location $location = null; + + /** + * @var Collection + * + * @ORM\ManyToMany(targetEntity=StoredObject::class, cascade={"persist","refresh"}) + * + * @ORM\JoinTable("chill_event_event_documents") + */ + private Collection $documents; + + /** + * @ORM\Column(type="decimal", precision=10, scale=4, nullable=true, options={"default": null}) + */ + private string $organizationCost = '0.0'; + /** * Event constructor. */ public function __construct() { $this->participations = new ArrayCollection(); + $this->documents = new ArrayCollection(); + $this->comment = new CommentEmbeddable(); } /** @@ -111,6 +145,22 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter return $this; } + public function addDocument(StoredObject $storedObject): self + { + if ($this->documents->contains($storedObject)) { + $this->documents[] = $storedObject; + } + + return $this; + } + + public function removeDocument(StoredObject $storedObject): self + { + $this->documents->removeElement($storedObject); + + return $this; + } + /** * @return Center */ @@ -270,4 +320,44 @@ class Event implements HasCenterInterface, HasScopeInterface, TrackCreationInter return $this; } + + public function getComment(): CommentEmbeddable + { + return $this->comment; + } + + public function setComment(CommentEmbeddable $comment): void + { + $this->comment = $comment; + } + + public function getLocation(): ?Location + { + return $this->location; + } + + public function setLocation(?Location $location): void + { + $this->location = $location; + } + + public function getDocuments(): Collection + { + return $this->documents; + } + + public function setDocuments(Collection $documents): void + { + $this->documents = $documents; + } + + public function getOrganizationCost(): string + { + return $this->organizationCost; + } + + public function setOrganizationCost(string $organizationCost): void + { + $this->organizationCost = $organizationCost; + } } diff --git a/src/Bundle/ChillEventBundle/Entity/Participation.php b/src/Bundle/ChillEventBundle/Entity/Participation.php index e53ee4181..d5ab7deeb 100644 --- a/src/Bundle/ChillEventBundle/Entity/Participation.php +++ b/src/Bundle/ChillEventBundle/Entity/Participation.php @@ -20,7 +20,6 @@ use Chill\MainBundle\Entity\HasCenterInterface; use Chill\MainBundle\Entity\HasScopeInterface; use Chill\MainBundle\Entity\Scope; use Chill\PersonBundle\Entity\Person; -use DateTime; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Validator\Constraints as Assert; @@ -33,10 +32,12 @@ use Symfony\Component\Validator\Context\ExecutionContextInterface; * repositoryClass="Chill\EventBundle\Repository\ParticipationRepository") * * @ORM\Table(name="chill_event_participation", uniqueConstraints={ + * * @ORM\UniqueConstraint(name="chill_event_participation_event_person_unique_idx", columns={"event_id", "person_id"}) * }) * * @ORM\HasLifecycleCallbacks + * * @UniqueEntity({"event", "person"}, message="event.validation.person_already_participate_to_event") */ class Participation implements \ArrayAccess, HasCenterInterface, HasScopeInterface, TrackUpdateInterface, TrackCreationInterface @@ -62,6 +63,7 @@ class Participation implements \ArrayAccess, HasCenterInterface, HasScopeInterfa /** * @ORM\ManyToOne(targetEntity="Chill\PersonBundle\Entity\Person") + * * @Assert\NotNull() */ private ?Person $person = null; @@ -73,14 +75,12 @@ class Participation implements \ArrayAccess, HasCenterInterface, HasScopeInterfa /** * @ORM\ManyToOne(targetEntity="Chill\EventBundle\Entity\Status") + * * @Assert\NotNull() */ private ?Status $status = null; - /** - * @return Center - */ - public function getCenter(): null|Center + public function getCenter() { if (null === $this->getEvent()) { throw new \RuntimeException('The event is not linked with this instance. You should initialize the event with a valid center before.'); @@ -99,8 +99,6 @@ class Participation implements \ArrayAccess, HasCenterInterface, HasScopeInterfa /** * Get id. - * - * @return int */ public function getId(): int { @@ -110,7 +108,7 @@ class Participation implements \ArrayAccess, HasCenterInterface, HasScopeInterfa /** * Get lastUpdate. * - * @return \DateTime + * @return \DateTimeInterface|null */ public function getLastUpdate() { @@ -289,6 +287,7 @@ class Participation implements \ArrayAccess, HasCenterInterface, HasScopeInterfa * Set lastUpdate. * * @return Participation + * * @deprecated */ protected function update() diff --git a/src/Bundle/ChillEventBundle/Form/EventType.php b/src/Bundle/ChillEventBundle/Form/EventType.php index a06999d2b..d874fa95f 100644 --- a/src/Bundle/ChillEventBundle/Form/EventType.php +++ b/src/Bundle/ChillEventBundle/Form/EventType.php @@ -11,12 +11,18 @@ declare(strict_types=1); namespace Chill\EventBundle\Form; +use Chill\DocStoreBundle\Entity\StoredObject; +use Chill\DocStoreBundle\Form\StoredObjectType; use Chill\EventBundle\Form\Type\PickEventTypeType; use Chill\MainBundle\Entity\Center; +use Chill\MainBundle\Form\Type\ChillCollectionType; use Chill\MainBundle\Form\Type\ChillDateTimeType; +use Chill\MainBundle\Form\Type\CommentType; +use Chill\MainBundle\Form\Type\PickUserLocationType; use Chill\MainBundle\Form\Type\ScopePickerType; use Chill\MainBundle\Form\Type\UserPickerType; use Symfony\Component\Form\AbstractType; +use Symfony\Component\Form\Extension\Core\Type\MoneyType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -47,6 +53,28 @@ class EventType extends AbstractType 'class' => '', ], 'required' => false, + ]) + ->add('location', PickUserLocationType::class, [ + 'label' => 'event.fields.location', + ]) + ->add('comment', CommentType::class, [ + 'label' => 'Comment', + 'required' => false, + ]) + ->add('documents', ChillCollectionType::class, [ + 'entry_type' => StoredObjectType::class, + 'entry_options' => [ + 'has_title' => true, + ], + 'allow_add' => true, + 'allow_delete' => true, + 'delete_empty' => fn(StoredObject $storedObject): bool => '' === $storedObject->getFilename(), + 'button_remove_label' => 'event.form.remove_document', + 'button_add_label' => 'event.form.add_document', + ]) + ->add('organizationCost', MoneyType::class, [ + 'label' => 'event.fields.organizationCost', + 'help' => 'event.form.organisationCost_help', ]); } diff --git a/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig b/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig index af1e32cec..fc4001c63 100644 --- a/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig +++ b/src/Bundle/ChillEventBundle/Resources/views/Event/edit.html.twig @@ -14,10 +14,15 @@ {{ form_row(edit_form.type, { 'label': 'Event type' }) }} {{ form_row(edit_form.moderator) }} + {{ form_row(edit_form.location) }} + {{ form_row(edit_form.organizationCost) }} + + {{ form_row(edit_form.comment) }} + {{ form_row(edit_form.documents) }}