Skip to content

Commit

Permalink
Console command - grant membership
Browse files Browse the repository at this point in the history
  • Loading branch information
JanMikes committed Jan 5, 2025
1 parent b7ca542 commit 01148a5
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 3 deletions.
50 changes: 50 additions & 0 deletions src/ConsoleCommands/GrantMembershipToPlayerConsoleCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace SpeedPuzzling\Web\ConsoleCommands;

use DateTimeImmutable;
use SpeedPuzzling\Web\Message\GrantMembership;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Messenger\MessageBusInterface;

#[AsCommand('myspeedpuzzling:membership:grant')]
final class GrantMembershipToPlayerConsoleCommands extends Command
{
public function __construct(
readonly private MessageBusInterface $messageBus,
) {
parent::__construct();
}

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

$this->addArgument('playerId', InputArgument::REQUIRED);
$this->addArgument('endsAt', InputArgument::REQUIRED);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
/** @var string $playerId */
$playerId = $input->getArgument('playerId');

/** @var string $endsAt */
$endsAt = $input->getArgument('endsAt');

$this->messageBus->dispatch(
new GrantMembership(
playerId: $playerId,
endsAt: new DateTimeImmutable($endsAt),
),
);

return self::SUCCESS;
}
}
6 changes: 3 additions & 3 deletions src/Entity/Membership.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ class Membership implements EntityWithEvents
{
use HasEvents;

#[Column(nullable: true)]
public null|DateTimeImmutable $endsAt = null;

public function __construct(
#[Id]
#[Immutable]
Expand All @@ -44,6 +41,9 @@ public function __construct(

#[Column(nullable: true)]
public null|DateTimeImmutable $billingPeriodEndsAt = null,

#[Column(nullable: true)]
public null|DateTimeImmutable $endsAt = null,
) {
$this->recordThat(new MembershipStarted($this->id));
}
Expand Down
9 changes: 9 additions & 0 deletions src/Exceptions/PlayerAlreadyHaveMembership.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace SpeedPuzzling\Web\Exceptions;

final class PlayerAlreadyHaveMembership extends \Exception
{
}
16 changes: 16 additions & 0 deletions src/Message/GrantMembership.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace SpeedPuzzling\Web\Message;

use DateTimeImmutable;

readonly final class GrantMembership
{
public function __construct(
public string $playerId,
public DateTimeImmutable $endsAt,
) {
}
}
51 changes: 51 additions & 0 deletions src/MessageHandler/GrantMembershipHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

namespace SpeedPuzzling\Web\MessageHandler;

use Psr\Clock\ClockInterface;
use Ramsey\Uuid\Uuid;
use SpeedPuzzling\Web\Entity\Membership;
use SpeedPuzzling\Web\Exceptions\MembershipNotFound;
use SpeedPuzzling\Web\Exceptions\PlayerAlreadyHaveMembership;
use SpeedPuzzling\Web\Exceptions\PlayerNotFound;
use SpeedPuzzling\Web\Message\GrantMembership;
use SpeedPuzzling\Web\Repository\MembershipRepository;
use SpeedPuzzling\Web\Repository\PlayerRepository;

readonly final class GrantMembershipHandler
{
public function __construct(
private PlayerRepository $playerRepository,
private MembershipRepository $membershipRepository,
private ClockInterface $clock,
) {
}

/**
* @throws PlayerAlreadyHaveMembership
* @throws PlayerNotFound
*/
public function __invoke(GrantMembership $message): void
{

$player = $this->playerRepository->get($message->playerId);

try {
$this->membershipRepository->getByPlayerId($message->playerId);

throw new PlayerAlreadyHaveMembership();
} catch (MembershipNotFound) {
// We want to create new membership - ofc it is not found :-)
$membership = new Membership(
Uuid::uuid7(),
$player,
$this->clock->now(),
endsAt: $message->endsAt,
);

$this->membershipRepository->save($membership);
}
}
}

0 comments on commit 01148a5

Please sign in to comment.