Skip to content

Commit

Permalink
[Event] add referrer code (#11533)
Browse files Browse the repository at this point in the history
* [Event] add referrer code

* Add unit tests

---------

Co-authored-by: Rémi <[email protected]>
  • Loading branch information
Remg and Rémi authored Feb 27, 2025
1 parent 5dbbb08 commit db5268b
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 1 deletion.
33 changes: 33 additions & 0 deletions migrations/2025/Version20250227133157.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Migrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20250227133157 extends AbstractMigration
{
public function up(Schema $schema): void
{
$this->addSql('ALTER TABLE
national_event_inscription
ADD
referrer_id INT UNSIGNED DEFAULT NULL,
ADD
referrer_code VARCHAR(7) DEFAULT NULL');
$this->addSql('ALTER TABLE
national_event_inscription
ADD
CONSTRAINT FK_C3325557798C22DB FOREIGN KEY (referrer_id) REFERENCES adherents (id) ON DELETE
SET
NULL');
$this->addSql('CREATE INDEX IDX_C3325557798C22DB ON national_event_inscription (referrer_id)');
}

public function down(Schema $schema): void
{
$this->addSql('ALTER TABLE national_event_inscription DROP FOREIGN KEY FK_C3325557798C22DB');
$this->addSql('DROP INDEX IDX_C3325557798C22DB ON national_event_inscription');
$this->addSql('ALTER TABLE national_event_inscription DROP referrer_id, DROP referrer_code');
}
}
17 changes: 17 additions & 0 deletions src/Adherent/Referral/ReferralParams.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace App\Adherent\Referral;

class ReferralParams
{
public const REFERRER_CODE = 'referrer';

public static function filterParameter(?string $parameter): ?string
{
if (!$parameter) {
return null;
}

return mb_substr($parameter, 0, 7);
}
}
1 change: 1 addition & 0 deletions src/Admin/NationalEvent/NationalEventInscriptionsAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ protected function configureListFields(ListMapper $list): void
->add('postalCode', null, ['label' => 'Code postal'])
->add('status', 'trans', ['label' => 'Statut'])
->add('adherent.tags', null, ['label' => 'Labels', 'template' => 'admin/national_event/list_adherent_tags.html.twig'])
->add('referrerCode', null, ['label' => 'Parrain', 'template' => 'admin/national_event/list_referrer_code.html.twig'])
->add(ListMapper::NAME_ACTIONS, null, ['actions' => ['edit' => []]])
;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Controller\Renaissance\NationalEvent;

use App\Adherent\Referral\ReferralParams;
use App\Entity\Adherent;
use App\Entity\NationalEvent\NationalEvent;
use App\Event\Request\EventInscriptionRequest;
Expand All @@ -18,6 +19,7 @@
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;

#[Route('/{slug}', name: 'app_national_event_by_slug', methods: ['GET', 'POST'])]
#[Route('/{slug}/{referrerCode}', name: 'app_national_event_by_slug_with_referrer', methods: ['GET', 'POST'])]
class EventInscriptionController extends AbstractController
{
private const SESSION_ID = 'nation_event:sess_id';
Expand All @@ -31,7 +33,7 @@ public function __construct(
) {
}

public function __invoke(Request $request, string $app_domain, ?NationalEvent $event = null): Response
public function __invoke(Request $request, string $app_domain, ?NationalEvent $event = null, ?string $referrerCode = null): Response
{
if (!$event && !$event = $this->nationalEventRepository->findOneForInscriptions()) {
return $this->redirectToRoute('renaissance_site');
Expand Down Expand Up @@ -64,6 +66,10 @@ public function __invoke(Request $request, string $app_domain, ?NationalEvent $e
$inscriptionRequest->utmCampaign = UtmParams::filterUtmParameter($request->query->get(UtmParams::UTM_CAMPAIGN));
}

if ($referrerCode) {
$inscriptionRequest->referrerCode = ReferralParams::filterParameter($referrerCode);
}

$isOpen = !$event->isComplete($inscriptionRequest->utmSource);

$form = $this
Expand Down
1 change: 1 addition & 0 deletions src/DataFixtures/ORM/LoadAdherentData.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ public function load(ObjectManager $manager): void
// Create adherent users list
$adherent1 = $this->adherentFactory->createFromArray([
'uuid' => self::ADHERENT_1_UUID,
'public_id' => '123-456',
'password' => self::DEFAULT_PASSWORD,
'email' => '[email protected]',
'gender' => 'female',
Expand Down
8 changes: 8 additions & 0 deletions src/Entity/NationalEvent/EventInscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,13 @@ class EventInscription
#[ORM\Column(nullable: true)]
public ?string $ticketQRCodeFile = null;

#[ORM\Column(length: 7, nullable: true)]
public ?string $referrerCode = null;

#[ORM\JoinColumn(onDelete: 'SET NULL')]
#[ORM\ManyToOne(targetEntity: Adherent::class)]
public ?Adherent $referrer = null;

public function __construct(NationalEvent $event, ?UuidInterface $uuid = null)
{
$this->uuid = $uuid ?? Uuid::uuid4();
Expand All @@ -138,6 +145,7 @@ public function updateFromRequest(EventInscriptionRequest $inscriptionRequest):
$this->birthdate = $inscriptionRequest->birthdate;
$this->utmSource = $inscriptionRequest->utmSource;
$this->utmCampaign = $inscriptionRequest->utmCampaign;
$this->referrerCode = $inscriptionRequest->referrerCode;
}

public function getFullName(): string
Expand Down
2 changes: 2 additions & 0 deletions src/Event/Request/EventInscriptionRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class EventInscriptionRequest implements RecaptchaChallengeInterface
public ?string $utmSource = null;
public ?string $utmCampaign = null;

public ?string $referrerCode = null;

public array $qualities = [];

#[Assert\Length(max: 255)]
Expand Down
7 changes: 7 additions & 0 deletions src/NationalEvent/EventInscriptionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ public function handle(NationalEvent $nationalEvent, EventInscriptionRequest $in
$eventInscription->adherent = $adherent;
}

if (
$eventInscription->referrerCode
&& $referrer = $this->adherentRepository->findOneBy(['publicId' => $eventInscription->referrerCode])
) {
$eventInscription->referrer = $referrer;
}

$this->entityManager->persist($eventInscription);

$this->entityManager->flush();
Expand Down
9 changes: 9 additions & 0 deletions templates/admin/national_event/list_referrer_code.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{% extends get_admin_template('base_list_field', admin.code) %}

{% block field %}
{% if object.referrer %}
{{ include(('admin/adherent/_summary.html.twig'), {adherent: object.referrer}) }}
{% elseif object.referrerCode %}
Code: <b>{{ object.referrerCode }}</b>
{% endif %}
{% endblock %}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace Tests\App\Controller\Renaissance\NationalEvent;

use App\Entity\NationalEvent\EventInscription;
use App\Repository\NationalEvent\EventInscriptionRepository;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Tests\App\AbstractWebTestCase;
use Tests\App\Controller\ControllerTestTrait;

#[Group('functional')]
class EventInscriptionControllerTest extends AbstractWebTestCase
{
use ControllerTestTrait;

private ?EventInscriptionRepository $eventInscriptionRepository = null;

#[DataProvider('provideReferrerCodes')]
public function testEventInscriptionWithReferral(string $referrerCode, ?string $referrerEmail): void
{
$crawler = $this->client->request(Request::METHOD_GET, "/grand-rassemblement/event-national-1/$referrerCode");
$this->assertStatusCode(Response::HTTP_OK, $this->client);

$buttonCrawlerNode = $crawler->selectButton('Je réserve ma place');

$form = $buttonCrawlerNode->form();

$form['event_inscription[acceptCgu]']->tick();
$form['event_inscription[acceptMedia]']->tick();

$this->client->submit($form, [
'event_inscription' => [
'email' => '[email protected]',
'civility' => 'male',
'firstName' => 'John',
'lastName' => 'Doe',
'birthPlace' => 'Paris',
'birthdate' => ['year' => '2000', 'month' => '10', 'day' => '2'],
'postalCode' => '75001',
],
]);
$this->assertClientIsRedirectedTo('/grand-rassemblement/event-national-1/confirmation', $this->client);

$this->client->followRedirect();
$this->assertStatusCode(Response::HTTP_OK, $this->client);

$eventInscription = $this->eventInscriptionRepository->findOneBy(['addressEmail' => '[email protected]']);
$this->assertInstanceOf(EventInscription::class, $eventInscription);
$this->assertEquals($referrerCode, $eventInscription->referrerCode);
$this->assertEquals($referrerEmail, $eventInscription->referrer?->getEmailAddress());
}

public static function provideReferrerCodes(): iterable
{
yield ['123-456', '[email protected]'];
yield ['invalid', null];
}

protected function setUp(): void
{
parent::setUp();

$this->eventInscriptionRepository = $this->getRepository(EventInscription::class);

$this->client->setServerParameter('HTTP_HOST', static::getContainer()->getParameter('user_vox_host'));
}

protected function tearDown(): void
{
parent::tearDown();

$this->eventInscriptionRepository = null;
}
}

0 comments on commit db5268b

Please sign in to comment.