Skip to content

Commit 6af4ac5

Browse files
committed
Refonte - Événements > Inscriptions - Créer/Modifier/Supprimer
1 parent 026b13a commit 6af4ac5

20 files changed

Lines changed: 660 additions & 27 deletions

app/config/packages/backoffice_menu.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ parameters:
131131
url: '/admin/event/tickets'
132132
extra_routes:
133133
- admin_event_ticket_list
134+
- admin_event_ticket_add
135+
- admin_event_ticket_edit
134136
forum_pending_bankwires:
135137
nom: 'Virements en attente'
136138
niveau: 'ROLE_ADMIN'

app/config/routing/admin_event.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,5 @@ admin_event_sessions_delete:
137137
requirements:
138138
id: \d+
139139

140-
admin_event_ticket_list:
141-
path: /tickets
142-
defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\IndexAction }
140+
admin_event_ticket:
141+
resource: "admin_event_ticket.yml"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
admin_event_ticket_list:
2+
path: /tickets
3+
defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\IndexAction }
4+
5+
admin_event_ticket_edit:
6+
path: /tickets/{id}
7+
requirements:
8+
id: \d+
9+
defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\EditAction }
10+
11+
admin_event_ticket_add:
12+
path: /tickets/add
13+
defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\AddAction }
14+
15+
admin_event_ticket_delete:
16+
path: /tickets/delete/{id}
17+
requirements:
18+
id: \d+
19+
defaults: { _controller: AppBundle\Controller\Admin\Event\Ticket\DeleteAction }
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AppBundle\Controller\Admin\Event\Ticket;
6+
7+
use Afup\Site\Forum\Facturation;
8+
use AppBundle\AuditLog\Audit;
9+
use AppBundle\Event\Form\TicketAdminWithInvoiceType;
10+
use AppBundle\Event\Model\Event;
11+
use AppBundle\Event\Model\Invoice;
12+
use AppBundle\Event\Model\Repository\EventRepository;
13+
use AppBundle\Event\Model\Repository\InvoiceRepository;
14+
use AppBundle\Event\Model\Repository\TicketRepository;
15+
use AppBundle\Event\Model\Ticket;
16+
use AppBundle\Event\Model\TicketOffer;
17+
use AppBundle\Event\Ticket\TicketOffers;
18+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
19+
use Symfony\Component\HttpFoundation\Request;
20+
use Symfony\Component\HttpFoundation\Response;
21+
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
22+
23+
final class AddAction extends AbstractController
24+
{
25+
public function __construct(
26+
private readonly TicketOffers $ticketOffers,
27+
private readonly TicketRepository $ticketRepository,
28+
private readonly EventRepository $eventRepository,
29+
private readonly InvoiceRepository $invoiceRepository,
30+
private readonly Audit $audit,
31+
private readonly Facturation $facturation,
32+
) {}
33+
34+
public function __invoke(Request $request): Response
35+
{
36+
$eventId = $request->query->getInt('eventId');
37+
$event = $this->eventRepository->get($eventId);
38+
if (!$event instanceof Event) {
39+
throw $this->createNotFoundException(sprintf('Event not found with id "%s"', $eventId));
40+
}
41+
42+
$offers = $this->ticketOffers->getAllOffersForEvent($event);
43+
44+
$form = $this->createForm(TicketAdminWithInvoiceType::class, [], [
45+
'event' => $event,
46+
'offers' => $offers,
47+
]);
48+
49+
$form->handleRequest($request);
50+
if ($form->isSubmitted() && $form->isValid()) {
51+
/** @var Ticket $ticket */
52+
/** @var Invoice $invoice */
53+
['ticket' => $ticket, 'invoice' => $invoice] = $form->getData();
54+
55+
$ticketTypeId = $ticket->getTicketTypeId();
56+
$offer = array_find($offers, fn(TicketOffer $offer): bool => $offer->ticketTypeId === $ticketTypeId);
57+
if (!$offer instanceof TicketOffer) {
58+
throw new NotFoundHttpException(sprintf('Offer not found with ticketTypeId "%s"', $ticketTypeId));
59+
}
60+
61+
if ($offer->ticketEventType) {
62+
$ticket->setTicketEventType($offer->ticketEventType);
63+
}
64+
$ticket->setAmount($offer->price);
65+
$ticket->setDate(new \DateTime());
66+
$reference = $this->facturation->creerReference($event->getId(), $ticket->getLabel());
67+
$ticket->setReference($reference);
68+
$invoice->setReference($reference);
69+
70+
$this->ticketRepository->save($ticket);
71+
$this->invoiceRepository->saveWithTickets($invoice);
72+
73+
$this->audit->log(sprintf("Modification de l'inscription de %s (%d)", $ticket->getLabel(), $ticket->getId()));
74+
$this->addFlash('notice', "L'inscription a été modifiée.");
75+
76+
return $this->redirectToRoute('admin_event_ticket_list');
77+
}
78+
79+
return $this->render('admin/event/ticket/edit.html.twig', [
80+
'event' => $event,
81+
'form' => $form->createView(),
82+
]);
83+
}
84+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AppBundle\Controller\Admin\Event\Ticket;
6+
7+
use AppBundle\AuditLog\Audit;
8+
use AppBundle\Event\Model\Repository\InvoiceRepository;
9+
use AppBundle\Event\Model\Repository\TicketRepository;
10+
use AppBundle\Event\Model\Ticket;
11+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
12+
use Symfony\Component\HttpFoundation\Request;
13+
use Symfony\Component\HttpFoundation\Response;
14+
15+
final class DeleteAction extends AbstractController
16+
{
17+
public function __construct(
18+
private readonly TicketRepository $ticketRepository,
19+
private readonly InvoiceRepository $invoiceRepository,
20+
private readonly Audit $audit,
21+
) {}
22+
23+
public function __invoke(int $id, Request $request): Response
24+
{
25+
$ticket = $this->ticketRepository->get($id);
26+
if (!$ticket instanceof Ticket) {
27+
throw $this->createNotFoundException(sprintf('Ticket not found with id "%s"', $id));
28+
}
29+
30+
$invoice = $this->invoiceRepository->getByReference($id);
31+
if ($invoice) {
32+
$this->invoiceRepository->delete($invoice);
33+
}
34+
$this->ticketRepository->delete($ticket);
35+
36+
$this->audit->log("Suppression de l'inscription " . $id);
37+
$this->addFlash('notice', "L'inscription a été supprimée");
38+
39+
return $this->redirectToRoute('admin_event_ticket_list');
40+
}
41+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AppBundle\Controller\Admin\Event\Ticket;
6+
7+
use AppBundle\AuditLog\Audit;
8+
use AppBundle\Event\Form\TicketAdminWithInvoiceType;
9+
use AppBundle\Event\Model\Event;
10+
use AppBundle\Event\Model\Invoice;
11+
use AppBundle\Event\Model\Repository\EventRepository;
12+
use AppBundle\Event\Model\Repository\InvoiceRepository;
13+
use AppBundle\Event\Model\Repository\TicketRepository;
14+
use AppBundle\Event\Model\Ticket;
15+
use AppBundle\Event\Ticket\TicketOffers;
16+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
17+
use Symfony\Component\HttpFoundation\Request;
18+
use Symfony\Component\HttpFoundation\Response;
19+
20+
final class EditAction extends AbstractController
21+
{
22+
public function __construct(
23+
private readonly TicketOffers $ticketOffers,
24+
private readonly TicketRepository $ticketRepository,
25+
private readonly EventRepository $eventRepository,
26+
private readonly InvoiceRepository $invoiceRepository,
27+
private readonly Audit $audit,
28+
) {}
29+
30+
public function __invoke(int $id, Request $request): Response
31+
{
32+
$ticket = $this->ticketRepository->get($id);
33+
if (!$ticket instanceof Ticket) {
34+
throw $this->createNotFoundException(sprintf('Ticket not found with id "%s"', $id));
35+
}
36+
$event = $this->eventRepository->get($ticket->getForumId());
37+
if (!$event instanceof Event) {
38+
throw $this->createNotFoundException(sprintf('Event not found with id "%s"', $ticket->getForumId()));
39+
}
40+
$invoice = $this->invoiceRepository->getByReference($ticket->getReference());
41+
if (!$invoice instanceof Invoice) {
42+
throw $this->createNotFoundException(sprintf('Invoice not found with id "%s"', $ticket->getReference()));
43+
}
44+
45+
$offers = $this->ticketOffers->getAllOffersForEvent($event);
46+
47+
$form = $this->createForm(TicketAdminWithInvoiceType::class, [
48+
'ticket' => $ticket,
49+
'invoice' => $invoice,
50+
], [
51+
'event' => $event,
52+
'offers' => $offers,
53+
]);
54+
55+
$form->handleRequest($request);
56+
if ($form->isSubmitted() && $form->isValid()) {
57+
$data = $form->getData();
58+
$this->ticketRepository->save($data['ticket']);
59+
$this->invoiceRepository->save($data['invoice']);
60+
61+
$this->audit->log(sprintf("Modification de l'inscription de %s (%d)", $ticket->getLabel(), $ticket->getId()));
62+
$this->addFlash('notice', "L'inscription a été modifiée.");
63+
64+
return $this->redirectToRoute('admin_event_ticket_list');
65+
}
66+
67+
return $this->render('admin/event/ticket/edit.html.twig', [
68+
'event' => $event,
69+
'ticket' => $ticket,
70+
'invoice' => $invoice,
71+
'form' => $form->createView(),
72+
]);
73+
}
74+
}

sources/AppBundle/Controller/Admin/HomeAction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function __invoke(): Response
7373
}
7474

7575
$info['statistics']['montant total'] = number_format($montantTotal, 0, ',', "\u{a0}") . "\u{a0}";
76-
$info['url'] = '/pages/administration/index.php?page=forum_inscriptions&id_forum=' . $event->getId();
76+
$info['url'] = $this->generateUrl('admin_event_ticket_list', ['id' => $event->getId()]);
7777

7878
$cards[] = $info;
7979

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace AppBundle\Event\Form;
6+
7+
use AppBundle\Event\Model\Event;
8+
use AppBundle\Event\Model\Ticket;
9+
use AppBundle\Event\Model\TicketOffer;
10+
use AppBundle\Form\BooleanType;
11+
use Symfony\Component\Form\AbstractType;
12+
use Symfony\Component\Form\CallbackTransformer;
13+
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
14+
use Symfony\Component\Form\Extension\Core\Type\EmailType;
15+
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
16+
use Symfony\Component\Form\Extension\Core\Type\TextType;
17+
use Symfony\Component\Form\FormBuilderInterface;
18+
use Symfony\Component\OptionsResolver\OptionsResolver;
19+
20+
class TicketAdminType extends AbstractType
21+
{
22+
public function buildForm(FormBuilderInterface $builder, array $options): void
23+
{
24+
$event = $options['event'];
25+
$ticketOffers = $options['offers'];
26+
usort($ticketOffers, static fn(TicketOffer $a, TicketOffer $b) => $a->name > $b->name ? 1 : -1);
27+
28+
$builder
29+
->add('civility', ChoiceType::class, [
30+
'label' => 'Civilité',
31+
'choices' => [
32+
'M.' => 'M.',
33+
'Mme' => 'Mme',
34+
],
35+
])
36+
->add('firstname', TextType::class, [
37+
'label' => 'Prénom',
38+
])
39+
->add('lastname', TextType::class, [
40+
'label' => 'Nom',
41+
])
42+
->add('email', EmailType::class, [
43+
'label' => 'Email',
44+
])
45+
->add('phoneNumber', TextType::class, [
46+
'label' => 'Téléphone',
47+
'required' => false,
48+
])
49+
->add('comments', TextareaType::class, [
50+
'label' => 'Commentaires',
51+
'required' => false,
52+
])
53+
->add('companyCitation', BooleanType::class, [
54+
'label' => "J'accepte que ma compagnie soit citée comme participant à la conférence",
55+
])
56+
->add('newsletter', BooleanType::class, [
57+
'label' => "Je souhaite être tenu au courant des rencontres de l'AFUP sur des sujets afférents à PHP",
58+
])
59+
->add('optin', BooleanType::class, [
60+
'label' => "Je souhaite recevoir des informations de la part de vos partenaires presse/media",
61+
])
62+
->add('ticketTypeId', ChoiceType::class, [
63+
'label' => 'Formule',
64+
'choices' => $ticketOffers,
65+
'choice_label' => fn(TicketOffer $offer) => sprintf('%s - [%d €]', $offer->name, $offer->price),
66+
'choice_value' => fn(?TicketOffer $offer) => $offer->ticketTypeId ?? null,
67+
'group_by' => fn(TicketOffer $choice) => $choice->event ? 'Offre de l\'évènement' : 'Offre global',
68+
]);
69+
70+
if ($event->getTransportInformationEnabled()) {
71+
$transportMode = Ticket::TRANSPORT_MODES;
72+
asort($transportMode);
73+
74+
$builder->add('transportMode', ChoiceType::class, [
75+
'label' => 'Quel est votre mode de transport ?',
76+
'required' => true,
77+
'choices' => ['' => null] + array_flip($transportMode),
78+
]);
79+
80+
$builder->add('transportDistance', ChoiceType::class, [
81+
'label' => 'Quelle sera la distance parcourue ?',
82+
'required' => true,
83+
'choices' => ['' => null] + array_flip(Ticket::TRANSPORT_DISTANCES),
84+
]);
85+
}
86+
87+
$builder->get('ticketTypeId')
88+
->addModelTransformer(new CallbackTransformer(
89+
function ($id) use ($ticketOffers): TicketOffer|null {
90+
foreach ($ticketOffers as $ticketOffer) {
91+
if ($ticketOffer->ticketTypeId === $id) {
92+
return $ticketOffer;
93+
}
94+
}
95+
return null;
96+
},
97+
fn($ticketOffer): int => $ticketOffer->ticketTypeId,
98+
))
99+
;
100+
}
101+
102+
public function configureOptions(OptionsResolver $resolver): void
103+
{
104+
$resolver->setDefaults([
105+
'data_class' => Ticket::class,
106+
'event' => Event::class,
107+
'offers' => TicketOffer::class . '[]',
108+
]);
109+
}
110+
}

0 commit comments

Comments
 (0)