diff --git a/app/config/packages/backoffice_menu.yaml b/app/config/packages/backoffice_menu.yaml index 86a668798..169a34b8f 100644 --- a/app/config/packages/backoffice_menu.yaml +++ b/app/config/packages/backoffice_menu.yaml @@ -131,6 +131,8 @@ parameters: url: '/admin/event/tickets' extra_routes: - admin_event_ticket_list + - admin_event_ticket_add + - admin_event_ticket_edit forum_pending_bankwires: nom: 'Virements en attente' niveau: 'ROLE_ADMIN' diff --git a/app/config/routing/admin_event.yml b/app/config/routing/admin_event.yml index ef268bfb0..6c9d756b3 100644 --- a/app/config/routing/admin_event.yml +++ b/app/config/routing/admin_event.yml @@ -137,6 +137,5 @@ admin_event_sessions_delete: requirements: id: \d+ -admin_event_ticket_list: - path: /tickets - defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\IndexAction } \ No newline at end of file +admin_event_ticket: + resource: "admin_event_ticket.yml" diff --git a/app/config/routing/admin_event_ticket.yml b/app/config/routing/admin_event_ticket.yml new file mode 100644 index 000000000..77a98ecea --- /dev/null +++ b/app/config/routing/admin_event_ticket.yml @@ -0,0 +1,19 @@ +admin_event_ticket_list: + path: /tickets + defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\IndexAction } + +admin_event_ticket_edit: + path: /tickets/{id} + requirements: + id: \d+ + defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\EditAction } + +admin_event_ticket_add: + path: /tickets/add + defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\AddAction } + +admin_event_ticket_delete: + path: /tickets/delete/{id} + requirements: + id: \d+ + defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\DeleteAction } \ No newline at end of file diff --git a/sources/AppBundle/Controller/Admin/Event/Ticket/AddAction.php b/sources/AppBundle/Controller/Admin/Event/Ticket/AddAction.php new file mode 100644 index 000000000..54f4d9a2c --- /dev/null +++ b/sources/AppBundle/Controller/Admin/Event/Ticket/AddAction.php @@ -0,0 +1,97 @@ +query->getInt('eventId'); + $event = $this->eventRepository->get($eventId); + if (!$event instanceof Event) { + throw $this->createNotFoundException(sprintf('Event not found with id "%s"', $eventId)); + } + + $offers = $this->ticketOffers->getAllOffersForEvent($event); + + $ticket = new Ticket(); + $invoice = new Invoice(); + $invoice->setPaymentType(Ticket::PAYMENT_NONE); + $invoice->setPaymentDate(new \DateTime()); + + $form = $this->createForm(TicketAdminWithInvoiceType::class, [ + 'ticket' => $ticket, + 'invoice' => $invoice, + ], [ + 'event' => $event, + 'offers' => $offers, + ]); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + ['ticket' => $ticket, 'invoice' => $invoice] = $form->getData(); + + $ticketTypeId = $ticket->getTicketTypeId(); + $offer = array_find($offers, fn(TicketOffer $offer): bool => $offer->ticketTypeId === $ticketTypeId); + if (!$offer instanceof TicketOffer) { + throw $this->createNotFoundException(sprintf('Offer not found with ticketTypeId "%s"', $ticketTypeId)); + } + + $reference = $this->facturation->creerReference($event->getId(), $ticket->getLabel()); + if ($offer->ticketEventType) { + $ticket->setTicketEventType($offer->ticketEventType); + } + $ticket->setForumId($event->getId()); + $ticket->setAmount($offer->price); + $ticket->setDate(new \DateTime()); + $ticket->setReference($reference); + + $invoice->setReference($reference); + $invoice->setAmount($ticket->getAmount()); + $invoice->setForumId($ticket->getForumId()); + $invoice->setStatus($ticket->getInvoiceStatus()); + $invoice->setStatus($ticket->getStatus()); + $invoice->setInvoice(true); + $invoice->setInvoiceDate($invoice->getPaymentDate()); + + $this->ticketRepository->save($ticket); + $this->invoiceRepository->save($invoice); + + $this->audit->log(sprintf("Ajout de l'inscription de %s (%d)", $ticket->getLabel(), $ticket->getId())); + $this->addFlash('notice', "L'inscription a été ajoutée."); + + return $this->redirectToRoute('admin_event_ticket_list'); + } + + return $this->render('admin/event/ticket/add.html.twig', [ + 'event' => $event, + 'form' => $form->createView(), + ]); + } +} diff --git a/sources/AppBundle/Controller/Admin/Event/Ticket/DeleteAction.php b/sources/AppBundle/Controller/Admin/Event/Ticket/DeleteAction.php new file mode 100644 index 000000000..5b60f430e --- /dev/null +++ b/sources/AppBundle/Controller/Admin/Event/Ticket/DeleteAction.php @@ -0,0 +1,41 @@ +ticketRepository->get($id); + if (!$ticket instanceof Ticket) { + throw $this->createNotFoundException(sprintf('Ticket not found with id "%s"', $id)); + } + + $invoice = $this->invoiceRepository->getByReference($id); + if ($invoice) { + $this->invoiceRepository->delete($invoice); + } + $this->ticketRepository->delete($ticket); + + $this->audit->log("Suppression de l'inscription " . $id); + $this->addFlash('notice', "L'inscription a été supprimée"); + + return $this->redirectToRoute('admin_event_ticket_list'); + } +} diff --git a/sources/AppBundle/Controller/Admin/Event/Ticket/EditAction.php b/sources/AppBundle/Controller/Admin/Event/Ticket/EditAction.php new file mode 100644 index 000000000..576054e46 --- /dev/null +++ b/sources/AppBundle/Controller/Admin/Event/Ticket/EditAction.php @@ -0,0 +1,78 @@ +ticketRepository->get($id); + if (!$ticket instanceof Ticket) { + throw $this->createNotFoundException(sprintf('Ticket not found with id "%s"', $id)); + } + $event = $this->eventRepository->get($ticket->getForumId()); + if (!$event instanceof Event) { + throw $this->createNotFoundException(sprintf('Event not found with id "%s"', $ticket->getForumId())); + } + $invoice = $this->invoiceRepository->getByReference($ticket->getReference()); + if (!$invoice instanceof Invoice) { + throw $this->createNotFoundException(sprintf('Invoice not found with id "%s"', $ticket->getReference())); + } + + $offers = $this->ticketOffers->getAllOffersForEvent($event); + + $form = $this->createForm(TicketAdminWithInvoiceType::class, [ + 'ticket' => $ticket, + 'invoice' => $invoice, + ], [ + 'event' => $event, + 'offers' => $offers, + ]); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + ['ticket' => $ticket, 'invoice' => $invoice] = $form->getData(); + + $invoice->setStatus($ticket->getInvoiceStatus()); + $invoice->setStatus($ticket->getStatus()); + + $this->ticketRepository->save($ticket); + $this->invoiceRepository->save($invoice); + + $this->audit->log(sprintf("Modification de l'inscription de %s (%d)", $ticket->getLabel(), $ticket->getId())); + $this->addFlash('notice', "L'inscription a été modifiée."); + + return $this->redirectToRoute('admin_event_ticket_list'); + } + + return $this->render('admin/event/ticket/edit.html.twig', [ + 'event' => $event, + 'ticket' => $ticket, + 'invoice' => $invoice, + 'form' => $form->createView(), + ]); + } +} diff --git a/sources/AppBundle/Controller/Admin/HomeAction.php b/sources/AppBundle/Controller/Admin/HomeAction.php index 69a43197d..7270580cc 100644 --- a/sources/AppBundle/Controller/Admin/HomeAction.php +++ b/sources/AppBundle/Controller/Admin/HomeAction.php @@ -73,7 +73,7 @@ public function __invoke(): Response } $info['statistics']['montant total'] = number_format($montantTotal, 0, ',', "\u{a0}") . "\u{a0}€"; - $info['url'] = '/pages/administration/index.php?page=forum_inscriptions&id_forum=' . $event->getId(); + $info['url'] = $this->generateUrl('admin_event_ticket_list', ['id' => $event->getId()]); $cards[] = $info; diff --git a/sources/AppBundle/Event/Form/TicketAdminType.php b/sources/AppBundle/Event/Form/TicketAdminType.php new file mode 100644 index 000000000..afd1eab83 --- /dev/null +++ b/sources/AppBundle/Event/Form/TicketAdminType.php @@ -0,0 +1,140 @@ + Ticket::STATUS_CREATED, + 'Inscription annulée' => Ticket::STATUS_CANCELLED, + 'Paiement CB erreur' => Ticket::STATUS_ERROR, + 'Paiement CB refusé' => Ticket::STATUS_DECLINED, + 'Inscription réglée' => Ticket::STATUS_PAID, + 'Invitation' => Ticket::STATUS_GUEST, + 'Attente règlement' => Ticket::STATUS_WAITING, + 'Inscription confirmée' => Ticket::STATUS_CONFIRMED, + 'Inscription à posteriori' => Ticket::STATUS_PAID_AFTER, + ]; + + $invoiceStatuses = [ + 'Facture à envoyer' => Ticket::INVOICE_TODO, + 'Facture envoyée' => Ticket::INVOICE_SENT, + 'Facture reçue' => Ticket::INVOICE_RECEIVED, + ]; + + $event = $options['event']; + $ticketOffers = $options['offers']; + usort($ticketOffers, static fn(TicketOffer $a, TicketOffer $b) => $a->name > $b->name ? 1 : -1); + + $builder + ->add('civility', ChoiceType::class, [ + 'label' => 'Civilité', + 'choices' => [ + 'M.' => 'M.', + 'Mme' => 'Mme', + ], + ]) + ->add('firstname', TextType::class, [ + 'label' => 'Prénom', + ]) + ->add('lastname', TextType::class, [ + 'label' => 'Nom', + ]) + ->add('email', EmailType::class, [ + 'label' => 'Email', + ]) + ->add('phoneNumber', TextType::class, [ + 'label' => 'Téléphone', + 'required' => false, + ]) + ->add('comments', TextareaType::class, [ + 'label' => 'Commentaires', + 'required' => false, + ]) + ->add('companyCitation', BooleanType::class, [ + 'label' => "J'accepte que ma compagnie soit citée comme participant à la conférence", + ]) + ->add('newsletter', BooleanType::class, [ + 'label' => "Je souhaite être tenu au courant des rencontres de l'AFUP sur des sujets afférents à PHP", + 'required' => true, + ]) + ->add('optin', BooleanType::class, [ + 'label' => "Je souhaite recevoir des informations de la part de vos partenaires presse/media", + 'required' => true, + ]) + ->add('ticketTypeId', ChoiceType::class, [ + 'label' => 'Formule', + 'choices' => $ticketOffers, + 'choice_label' => fn(TicketOffer $offer) => sprintf('%s - [%d €]', $offer->name, $offer->price), + 'choice_value' => fn(?TicketOffer $offer) => $offer->ticketTypeId ?? null, + 'group_by' => fn(TicketOffer $choice) => $choice->event ? 'Offre de l\'évènement' : 'Offre global', + ]) + ->add('status', ChoiceType::class, [ + 'label' => "État de l'inscription", + 'choices' => $ticketStatuses, + 'required' => true, + ]) + ->add('invoiceStatus', ChoiceType::class, [ + 'label' => 'État de la facturation', + 'choices' => $invoiceStatuses, + 'required' => true, + ]); + + if ($event->getTransportInformationEnabled()) { + $transportMode = Ticket::TRANSPORT_MODES; + asort($transportMode); + + $builder->add('transportMode', ChoiceType::class, [ + 'label' => 'Quel est votre mode de transport ?', + 'required' => true, + 'choices' => ['' => null] + array_flip($transportMode), + ]); + + $builder->add('transportDistance', ChoiceType::class, [ + 'label' => 'Quelle sera la distance parcourue ?', + 'required' => true, + 'choices' => ['' => null] + array_flip(Ticket::TRANSPORT_DISTANCES), + ]); + } + + $builder->get('ticketTypeId') + ->addModelTransformer(new CallbackTransformer( + function ($id) use ($ticketOffers): TicketOffer|null { + foreach ($ticketOffers as $ticketOffer) { + if ($ticketOffer->ticketTypeId === $id) { + return $ticketOffer; + } + } + return null; + }, + fn($ticketOffer): int => $ticketOffer->ticketTypeId, + )) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Ticket::class, + 'event' => Event::class, + 'offers' => TicketOffer::class . '[]', + ]); + } +} diff --git a/sources/AppBundle/Event/Form/TicketAdminWithInvoiceType.php b/sources/AppBundle/Event/Form/TicketAdminWithInvoiceType.php new file mode 100644 index 000000000..35ad57a13 --- /dev/null +++ b/sources/AppBundle/Event/Form/TicketAdminWithInvoiceType.php @@ -0,0 +1,37 @@ +add('ticket', TicketAdminType::class, [ + 'label' => 'Ticket', + 'event' => $options['event'], + 'offers' => $options['offers'], + 'data' => $options['data']['ticket'] ?? null, + ]) + ->add('invoice', TicketInvoiceType::class, [ + 'label' => 'Facture', + 'data' => $options['data']['invoice'] ?? null, + ]); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'event' => Event::class, + 'offers' => TicketOffer::class . '[]', + ]); + } +} diff --git a/sources/AppBundle/Event/Form/TicketInvoiceType.php b/sources/AppBundle/Event/Form/TicketInvoiceType.php new file mode 100644 index 000000000..45cbced8f --- /dev/null +++ b/sources/AppBundle/Event/Form/TicketInvoiceType.php @@ -0,0 +1,90 @@ + Ticket::PAYMENT_CREDIT_CARD, + 'Chèque' => Ticket::PAYMENT_CHEQUE, + 'Virement' => Ticket::PAYMENT_BANKWIRE, + 'Aucun' => Ticket::PAYMENT_NONE, + ]; + + $builder + ->add('reference', TextType::class, [ + 'label' => 'Référence', + 'disabled' => !$options['data'], + 'required' => false, + ]) + ->add('authorization', TextType::class, [ + 'label' => 'Autorisation', + 'required' => false, + ]) + ->add('transaction', TextType::class, [ + 'label' => 'Transaction', + 'required' => false, + ]) + + ->add('paymentType', ChoiceType::class, [ + 'label' => 'Règlement', + 'expanded' => true, + 'row_attr' => ['class' => 'fields inline'], + 'choices' => $paymentTypes, + ]) + ->add('paymentInfos', TextareaType::class, [ + 'label' => 'Informations règlement', + 'required' => false, + ]) + ->add('paymentDate', DateType::class, [ + 'label' => 'Date', + 'required' => false, + ]) + + ->add('company', TextType::class, [ + 'label' => 'Société', + 'required' => false, + ]) + ->add('firstname', TextType::class, [ + 'label' => 'Prénom', + ]) + ->add('lastname', TextType::class, [ + 'label' => 'Nom', + ]) + ->add('address', TextareaType::class, [ + 'label' => 'Adresse', + ]) + ->add('zipcode', TextType::class, [ + 'label' => 'Code postal', + ]) + ->add('city', TextType::class, [ + 'label' => 'Ville', + ]) + ->add('email', EmailType::class, [ + 'label' => 'Email', + ]) + ; + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => Invoice::class, + ]); + } +} diff --git a/sources/AppBundle/Event/Model/Repository/TicketRepository.php b/sources/AppBundle/Event/Model/Repository/TicketRepository.php index ce3bc4a14..9d5af7645 100644 --- a/sources/AppBundle/Event/Model/Repository/TicketRepository.php +++ b/sources/AppBundle/Event/Model/Repository/TicketRepository.php @@ -420,6 +420,7 @@ public static function initMetadata(SerializerFactoryInterface $serializerFactor 'columnName' => 'mail_partenaire', 'fieldName' => 'optin', 'type' => 'bool', + 'default' => false, 'serializer' => Boolean::class, ]) ->addField([ diff --git a/sources/AppBundle/Event/Model/TicketOffer.php b/sources/AppBundle/Event/Model/TicketOffer.php index 3c6303750..ac97198bf 100644 --- a/sources/AppBundle/Event/Model/TicketOffer.php +++ b/sources/AppBundle/Event/Model/TicketOffer.php @@ -7,10 +7,11 @@ final readonly class TicketOffer { public function __construct( - public int $id, + public int $ticketTypeId, public string $name, public float $price, public int $availableTickets, - public Event $event, + public ?Event $event = null, + public ?TicketEventType $ticketEventType = null, ) {} } diff --git a/sources/AppBundle/Event/Ticket/TicketOffers.php b/sources/AppBundle/Event/Ticket/TicketOffers.php index b0da8aba3..18aadd85c 100644 --- a/sources/AppBundle/Event/Ticket/TicketOffers.php +++ b/sources/AppBundle/Event/Ticket/TicketOffers.php @@ -6,13 +6,16 @@ use AppBundle\Event\Model\Event; use AppBundle\Event\Model\Repository\TicketEventTypeRepository; +use AppBundle\Event\Model\Repository\TicketTypeRepository; use AppBundle\Event\Model\TicketOffer; +use AppBundle\Event\Model\TicketType; readonly class TicketOffers { public function __construct( private TicketEventTypeRepository $ticketEventTypeRepository, private TicketTypeAvailability $ticketTypeAvailability, + private TicketTypeRepository $ticketTypeRepository, ) {} /** @@ -20,28 +23,30 @@ public function __construct( */ public function getAllOffersForEvent(Event $event): array { - global $AFUP_Tarifs_Forum, $AFUP_Tarifs_Forum_Lib; - - $ticketTypes = $this->ticketEventTypeRepository->getTicketsByEvent($event, false); - $offers = []; - foreach ($AFUP_Tarifs_Forum as $ticketType => $ticketPrice) { - $offers[$ticketType] = new TicketOffer( - (int) $ticketType, - $AFUP_Tarifs_Forum_Lib[$ticketType], - $ticketPrice, + + /** @var TicketType[] $ticketTypes */ + $ticketTypes = $this->ticketTypeRepository->getAll(); + foreach ($ticketTypes as $ticketType) { + $ticketTypeId = $ticketType->getId(); + $offers[$ticketTypeId] = new TicketOffer( + $ticketTypeId, + $ticketType->getPrettyName(), + $ticketType->getDefaultPrice(), $event->getSeats(), - $event, ); } - foreach ($ticketTypes as $ticketType) { - $offers[$ticketType->getTicketTypeId()] = new TicketOffer( - $ticketType->getTicketTypeId(), - $ticketType->getTicketType()->getPrettyName(), - $ticketType->getPrice(), - $this->ticketTypeAvailability->getStock($ticketType, $event), + $ticketTypes = $this->ticketEventTypeRepository->getTicketsByEvent($event, false); + foreach ($ticketTypes as $ticketEventType) { + $ticketTypeId = $ticketEventType->getTicketTypeId(); + $offers[$ticketTypeId] = new TicketOffer( + $ticketTypeId, + $ticketEventType->getTicketType()->getPrettyName(), + $ticketEventType->getPrice(), + $this->ticketTypeAvailability->getStock($ticketEventType, $event), $event, + $ticketEventType, ); } diff --git a/sources/AppBundle/Form/BooleanType.php b/sources/AppBundle/Form/BooleanType.php new file mode 100644 index 000000000..1aca9409d --- /dev/null +++ b/sources/AppBundle/Form/BooleanType.php @@ -0,0 +1,29 @@ +setDefaults([ + 'expanded' => true, + 'row_attr' => ['class' => 'fields inline'], + 'choices' => [ + 'Oui' => true, + 'Non' => false, + ], + ]); + } + + public function getParent(): string + { + return ChoiceType::class; + } +} diff --git a/sources/AppBundle/Slack/MessageFactory.php b/sources/AppBundle/Slack/MessageFactory.php index 44676dd84..67a081660 100644 --- a/sources/AppBundle/Slack/MessageFactory.php +++ b/sources/AppBundle/Slack/MessageFactory.php @@ -208,7 +208,7 @@ public function createMessageForTicketStats(Event $event, EventStatsRepository $ $attachment = new Attachment(); $attachment ->setTitle('Total des inscriptions') - ->setTitleLink('https://afup.org/pages/administration/index.php?page=forum_inscriptions&id_forum=' . $event->getId()) + ->setTitleLink($this->urlGenerator->generate('admin_event_ticket_list', ['id' => $event->getId()],UrlGeneratorInterface::ABSOLUTE_URL)) ; if ($event->lastsOneDay()) { diff --git a/templates/admin/accounting/search.html.twig b/templates/admin/accounting/search.html.twig index a4a3a2bbf..246b8e57d 100644 --- a/templates/admin/accounting/search.html.twig +++ b/templates/admin/accounting/search.html.twig @@ -157,7 +157,7 @@ {{ inscription.forum_titre }} - Voir diff --git a/templates/admin/event/ticket/add.html.twig b/templates/admin/event/ticket/add.html.twig new file mode 100644 index 000000000..0e0f6b9ba --- /dev/null +++ b/templates/admin/event/ticket/add.html.twig @@ -0,0 +1,6 @@ +{% extends 'admin/base_with_header.html.twig' %} + +{% block content %} +

Ajouter une inscription pour le {{ event.title }}

+ {% include 'admin/event/ticket/form.html.twig' %} +{% endblock %} diff --git a/templates/admin/event/ticket/edit.html.twig b/templates/admin/event/ticket/edit.html.twig new file mode 100644 index 000000000..ee6719b9f --- /dev/null +++ b/templates/admin/event/ticket/edit.html.twig @@ -0,0 +1,6 @@ +{% extends 'admin/base_with_header.html.twig' %} + +{% block content %} +

Modifier une inscription pour le {{ event.title }}

+ {% include 'admin/event/ticket/form.html.twig' %} +{% endblock %} diff --git a/templates/admin/event/ticket/form.html.twig b/templates/admin/event/ticket/form.html.twig new file mode 100644 index 000000000..30ceaed13 --- /dev/null +++ b/templates/admin/event/ticket/form.html.twig @@ -0,0 +1,89 @@ + +{% form_theme form 'form_theme_admin.html.twig' %} + {{ form_start(form) }} +
+
+

Informations

+ {{ form_row(form.ticket.ticketTypeId) }} + {{ form_row(form.ticket.civility) }} + {{ form_row(form.ticket.lastname) }} + {{ form_row(form.ticket.firstname) }} + {{ form_row(form.ticket.email) }} + {{ form_row(form.ticket.phoneNumber) }} +
+ +
+

Réservé à l'administration

+

+ La référence est utilisée comme numéro de facture. Elle peut être commune à plusieurs inscriptions. +

+ {% if invoice is defined %} +

+ Rechercher la facture +

+ {% endif %} + {{ form_row(form.invoice.reference) }} + {{ form_row(form.invoice.authorization) }} + {{ form_row(form.invoice.transaction) }} + {{ form_row(form.ticket.status) }} + {{ form_row(form.ticket.invoiceStatus) }} +
+ +
+

Règlement

+ {{ form_row(form.invoice.paymentType) }} + {{ form_row(form.invoice.paymentInfos) }} + {{ form_row(form.invoice.paymentDate) }} +
+ +
+

Facturation

+

+ Ces informations concernent la personne ou la société qui sera facturée +

+ {{ form_row(form.invoice.company) }} + {{ form_row(form.invoice.lastname) }} + {{ form_row(form.invoice.firstname) }} + {{ form_row(form.invoice.address) }} + {{ form_row(form.invoice.zipcode) }} + {{ form_row(form.invoice.city) }} + {{ form_row(form.invoice.email) }} +
+ +
+

Divers

+ {{ form_row(form.ticket.comments) }} + {{ form_row(form.ticket.companyCitation) }} + {{ form_row(form.ticket.newsletter) }} + {{ form_row(form.ticket.optin) }} +
+ +
+

Transports

+ {% if form.ticket.transportMode %} + {{ form_row(form.ticket.transportMode) }} + {{ form_row(form.ticket.transportDistance) }} + {% else %} +

+ Les informations sur le transport ne sont pas demandées pour cet évènement. +

+ {% endif %} +
+ +
+
+ +
+ +
+
+
+ +
+

* indique un champ obligatoire

+
+ + {{ form_rest(form) }} +
+{{ form_end(form) }} \ No newline at end of file diff --git a/templates/admin/event/ticket/index.html.twig b/templates/admin/event/ticket/index.html.twig index 77f2bcf1b..d38c566e5 100644 --- a/templates/admin/event/ticket/index.html.twig +++ b/templates/admin/event/ticket/index.html.twig @@ -5,7 +5,7 @@ {% include 'admin/event/change_event.html.twig' with {form: event_select_form} only %}