From ed45f14a45538bba59deeabc810efd5b4ce73309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Tue, 23 Apr 2024 23:38:34 +0200 Subject: [PATCH] Add tracking of addressee history in ticket system The updates introduce tracking for the history of addressees in the ticket system, both when added and when removed. The user who removed an addressee is now recorded. The changes also ensure these updated aspects are correctly normalized and users can see them in the ticket history. A new database migration file was created for the changes. --- .../Handler/SetAddresseesCommandHandler.php | 6 +++ .../src/migrations/Version20240423212824.php | 40 +++++++++++++++++++ .../SetAddressesCommandHandlerTest.php | 6 ++- .../SetAddresseesControllerTest.php | 4 +- 4 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/Bundle/ChillTicketBundle/src/migrations/Version20240423212824.php diff --git a/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetAddresseesCommandHandler.php b/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetAddresseesCommandHandler.php index 25ac97e5d..b2805ed2f 100644 --- a/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetAddresseesCommandHandler.php +++ b/src/Bundle/ChillTicketBundle/src/Action/Ticket/Handler/SetAddresseesCommandHandler.php @@ -11,17 +11,20 @@ declare(strict_types=1); namespace Chill\TicketBundle\Action\Ticket\Handler; +use Chill\MainBundle\Entity\User; use Chill\TicketBundle\Action\Ticket\SetAddresseesCommand; use Chill\TicketBundle\Entity\AddresseeHistory; use Chill\TicketBundle\Entity\Ticket; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\Clock\ClockInterface; +use Symfony\Component\Security\Core\Security; final readonly class SetAddresseesCommandHandler { public function __construct( private ClockInterface $clock, private EntityManagerInterface $entityManager, + private Security $security, ) {} public function handle(Ticket $ticket, SetAddresseesCommand $command): void @@ -34,6 +37,9 @@ final readonly class SetAddresseesCommandHandler if (!in_array($addressHistory->getAddressee(), $command->addressees, true)) { $addressHistory->setEndDate($this->clock->now()); + if (($user = $this->security->getUser()) instanceof User) { + $addressHistory->setRemovedBy($user); + } } } diff --git a/src/Bundle/ChillTicketBundle/src/migrations/Version20240423212824.php b/src/Bundle/ChillTicketBundle/src/migrations/Version20240423212824.php new file mode 100644 index 000000000..3c025d763 --- /dev/null +++ b/src/Bundle/ChillTicketBundle/src/migrations/Version20240423212824.php @@ -0,0 +1,40 @@ +addSql('ALTER TABLE chill_ticket.addressee_history ADD endDate TIMESTAMP(0) WITHOUT TIME ZONE DEFAULT null'); + $this->addSql('ALTER TABLE chill_ticket.addressee_history ADD removedBy_id INT DEFAULT NULL'); + $this->addSql('COMMENT ON COLUMN chill_ticket.addressee_history.endDate IS \'(DC2Type:datetime_immutable)\''); + $this->addSql('ALTER TABLE chill_ticket.addressee_history ADD CONSTRAINT FK_434EBDBDB8346CCF FOREIGN KEY (removedBy_id) REFERENCES users (id) NOT DEFERRABLE INITIALLY IMMEDIATE'); + $this->addSql('CREATE INDEX IDX_434EBDBDB8346CCF ON chill_ticket.addressee_history (removedBy_id)'); + } + + public function down(Schema $schema): void + { + $this->addSql('ALTER TABLE chill_ticket.addressee_history DROP CONSTRAINT FK_434EBDBDB8346CCF'); + $this->addSql('DROP INDEX chill_ticket.IDX_434EBDBDB8346CCF'); + $this->addSql('ALTER TABLE chill_ticket.addressee_history DROP endDate'); + $this->addSql('ALTER TABLE chill_ticket.addressee_history DROP removedBy_id'); + } +} diff --git a/src/Bundle/ChillTicketBundle/tests/Action/Ticket/Handler/SetAddressesCommandHandlerTest.php b/src/Bundle/ChillTicketBundle/tests/Action/Ticket/Handler/SetAddressesCommandHandlerTest.php index efb545bac..cef1ae153 100644 --- a/src/Bundle/ChillTicketBundle/tests/Action/Ticket/Handler/SetAddressesCommandHandlerTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Action/Ticket/Handler/SetAddressesCommandHandlerTest.php @@ -22,6 +22,7 @@ use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Component\Clock\MockClock; +use Symfony\Component\Security\Core\Security; /** * @internal @@ -113,6 +114,9 @@ final class SetAddressesCommandHandlerTest extends TestCase private function buildHandler(EntityManagerInterface $entityManager): SetAddresseesCommandHandler { - return new SetAddresseesCommandHandler(new MockClock(), $entityManager); + $security = $this->prophesize(Security::class); + $security->getUser()->willReturn(new User()); + + return new SetAddresseesCommandHandler(new MockClock(), $entityManager, $security->reveal()); } } diff --git a/src/Bundle/ChillTicketBundle/tests/Controller/SetAddresseesControllerTest.php b/src/Bundle/ChillTicketBundle/tests/Controller/SetAddresseesControllerTest.php index a7ca214c1..af0d48e87 100644 --- a/src/Bundle/ChillTicketBundle/tests/Controller/SetAddresseesControllerTest.php +++ b/src/Bundle/ChillTicketBundle/tests/Controller/SetAddresseesControllerTest.php @@ -177,8 +177,10 @@ class SetAddresseesControllerTest extends KernelTestCase private function buildController(bool $willSave, bool $isValid): SetAddresseesController { + $user = new User(); $security = $this->prophesize(Security::class); $security->isGranted('ROLE_USER')->willReturn(true); + $security->getUser()->willReturn($user); $entityManager = $this->prophesize(EntityManagerInterface::class); @@ -203,7 +205,7 @@ class SetAddresseesControllerTest extends KernelTestCase $security->reveal(), $entityManager->reveal(), $this->serializer, - new SetAddresseesCommandHandler(new MockClock(), $entityManager->reveal()), + new SetAddresseesCommandHandler(new MockClock(), $entityManager->reveal(), $security->reveal()), $validator->reveal() ); }