diff --git a/phpstan-baseline.php b/phpstan-baseline.php index f85ead6d8..8383677f5 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -655,18 +655,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$email of method AppBundle\\\\Association\\\\Model\\\\SubscriptionReminderLog\\:\\:setEmail\\(\\) expects string, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$userId of method AppBundle\\\\Association\\\\Model\\\\SubscriptionReminderLog\\:\\:setUserId\\(\\) expects int, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php', -]; $ignoreErrors[] = [ 'message' => '#^Method AppBundle\\\\Association\\\\CompanyMembership\\\\CompanyReminderFactory\\:\\:getReminder\\(\\) has parameter \\$class with no type specified\\.$#', 'identifier' => 'missingType.parameter', @@ -1189,60 +1177,6 @@ 'count' => 5, 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/CompanyMemberRepository.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Binary operation "\\*" between int and mixed results in an error\\.$#', - 'identifier' => 'binaryOp.invalid', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Binary operation "\\+" between mixed and 1 results in an error\\.$#', - 'identifier' => 'binaryOp.invalid', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Cannot cast mixed to int\\.$#', - 'identifier' => 'cast.int', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Association\\\\Model\\\\Repository\\\\SubscriptionReminderLogRepository\\:\\:getPaginatedLogs\\(\\) has no return type specified\\.$#', - 'identifier' => 'missingType.return', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Association\\\\Model\\\\Repository\\\\SubscriptionReminderLogRepository\\:\\:getPaginatedLogs\\(\\) has parameter \\$limit with no type specified\\.$#', - 'identifier' => 'missingType.parameter', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Association\\\\Model\\\\Repository\\\\SubscriptionReminderLogRepository\\:\\:getPaginatedLogs\\(\\) has parameter \\$page with no type specified\\.$#', - 'identifier' => 'missingType.parameter', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Association\\\\Model\\\\Repository\\\\SubscriptionReminderLogRepository\\:\\:initMetadata\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#', - 'identifier' => 'missingType.iterableValue', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Method AppBundle\\\\Association\\\\Model\\\\Repository\\\\SubscriptionReminderLogRepository\\:\\:initMetadata\\(\\) should return M of CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata but returns CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\\\.$#', - 'identifier' => 'return.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$databaseName of method CCMBenchmark\\\\Ting\\\\Repository\\\\Metadata\\\\:\\:setDatabase\\(\\) expects string, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/Model/Repository/SubscriptionReminderLogRepository.php', -]; $ignoreErrors[] = [ 'message' => '#^Method AppBundle\\\\Association\\\\Model\\\\Repository\\\\SubscriptionRepository\\:\\:initMetadata\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#', 'identifier' => 'missingType.iterableValue', @@ -1681,18 +1615,6 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php', ]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$email of method AppBundle\\\\Association\\\\Model\\\\SubscriptionReminderLog\\:\\:setEmail\\(\\) expects string, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php', -]; -$ignoreErrors[] = [ - 'message' => '#^Parameter \\#1 \\$userId of method AppBundle\\\\Association\\\\Model\\\\SubscriptionReminderLog\\:\\:setUserId\\(\\) expects int, mixed given\\.$#', - 'identifier' => 'argument.type', - 'count' => 1, - 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php', -]; $ignoreErrors[] = [ 'message' => '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#', 'identifier' => 'foreach.nonIterable', @@ -9931,5 +9853,29 @@ 'count' => 1, 'path' => __DIR__ . '/sources/AppBundle/VideoNotifier/StatusGenerator.php', ]; +$ignoreErrors[] = [ + 'message' => '#^Cannot cast mixed to string\\.$#', + 'identifier' => 'cast.string', + 'count' => 1, + 'path' => __DIR__ . '/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Cannot cast mixed to int\\.$#', + 'identifier' => 'cast.int', + 'count' => 1, + 'path' => __DIR__ . '/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Cannot cast mixed to string\\.$#', + 'identifier' => 'cast.string', + 'count' => 1, + 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php', +]; +$ignoreErrors[] = [ + 'message' => '#^Cannot cast mixed to int\\.$#', + 'identifier' => 'cast.int', + 'count' => 1, + 'path' => __DIR__ . '/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php', +]; return ['parameters' => ['ignoreErrors' => $ignoreErrors]]; diff --git a/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php b/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php index 560343b97..f8ab85f1d 100644 --- a/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php +++ b/sources/AppBundle/Association/CompanyMembership/AbstractCompanyReminder.php @@ -6,8 +6,8 @@ use AppBundle\Association\MembershipReminderInterface; use AppBundle\Association\MemberType; -use AppBundle\Association\Model\Repository\SubscriptionReminderLogRepository; -use AppBundle\Association\Model\SubscriptionReminderLog; +use AppBundle\Association\Entity\Repository\SubscriptionReminderLogRepository; +use AppBundle\Association\Entity\SubscriptionReminderLog; use AppBundle\Association\NotifiableInterface; use AppBundle\Email\Mailer\Attachment; use AppBundle\Email\Mailer\Mailer; @@ -31,13 +31,11 @@ abstract protected function getKey(): string; public function sendReminder(NotifiableInterface $user): void { $log = new SubscriptionReminderLog(); - $log - ->setEmail($user->getEmail()) - ->setUserId($user->getId()) - ->setReminderDate(new \DateTime()) - ->setReminderKey($this->getKey()) - ->setUserType(MemberType::MemberCompany->value) - ; + $log->email = (string) $user->getEmail(); + $log->userId = (int) $user->getId(); + $log->reminderDate = new \DateTimeImmutable(); + $log->reminderKey = $this->getKey(); + $log->userType = MemberType::MemberCompany; $message = new Message($this->getSubject(), MailUserFactory::sponsors(), new MailUser($user->getEmail())); @@ -49,7 +47,7 @@ public function sendReminder(NotifiableInterface $user): void )); $status = $this->mailer->sendTransactional($message, $this->getText()); - $log->setMailSent($status); + $log->mailSent = $status; $this->subscriptionReminderLogRepository->save($log); } } diff --git a/sources/AppBundle/Association/CompanyMembership/CompanyReminderFactory.php b/sources/AppBundle/Association/CompanyMembership/CompanyReminderFactory.php index 242e26551..a469316d6 100644 --- a/sources/AppBundle/Association/CompanyMembership/CompanyReminderFactory.php +++ b/sources/AppBundle/Association/CompanyMembership/CompanyReminderFactory.php @@ -5,7 +5,7 @@ namespace AppBundle\Association\CompanyMembership; use AppBundle\Association\MembershipReminderInterface; -use AppBundle\Association\Model\Repository\SubscriptionReminderLogRepository; +use AppBundle\Association\Entity\Repository\SubscriptionReminderLogRepository; use AppBundle\Email\Mailer\Mailer; class CompanyReminderFactory diff --git a/sources/AppBundle/Association/Entity/Repository/SubscriptionReminderLogRepository.php b/sources/AppBundle/Association/Entity/Repository/SubscriptionReminderLogRepository.php new file mode 100644 index 000000000..9fa962c93 --- /dev/null +++ b/sources/AppBundle/Association/Entity/Repository/SubscriptionReminderLogRepository.php @@ -0,0 +1,79 @@ + + */ +class SubscriptionReminderLogRepository extends EntityRepository +{ + private const int DEFAULT_LIMIT = 50; + + public function __construct( + ManagerRegistry $registry, + private readonly MapperBuilder $mapperBuilder, + ) { + parent::__construct($registry, SubscriptionReminderLog::class); + } + + /** + * @param int $limit Nombre d'éléments de la page ; un élément supplémentaire + * est remonté pour savoir s'il existe une page suivante + * @return list + */ + public function getPaginatedLogs(int $page = 1, int $limit = self::DEFAULT_LIMIT): array + { + $rows = $this->connection() + ->createQueryBuilder() + ->select( + 'asrl.id', + 'asrl.reminder_key', + 'asrl.reminder_date', + 'asrl.mail_sent', + 'app.id AS app_id', + 'app.nom', + 'app.prenom', + 'apm.id AS apm_id', + 'apm.raison_sociale', + ) + ->from('afup_subscription_reminder_log', 'asrl') + ->leftJoin('asrl', 'afup_personnes_physiques', 'app', 'app.id = asrl.user_id') + ->leftJoin('app', 'afup_personnes_morales', 'apm', 'apm.id = app.id_personne_morale') + ->orderBy('asrl.reminder_date', 'DESC') + ->setFirstResult(($page - 1) * $limit) + ->setMaxResults($limit + 1) + ->executeQuery() + ->fetchAllAssociative() + ; + + $entries = []; + foreach ($rows as $row) { + $entries[] = $this->mapperBuilder + // mail_sent est un tinyint en base : Valinor exige + // l'autorisation de cast pour mapper un int vers un bool. + ->allowScalarValueCasting() + ->supportDateFormats('Y-m-d H:i:s') + ->configureWith(new ConvertKeysToCamelCase()) + ->mapper() + ->map(SubscriptionReminderLogEntry::class, Source::array($row)); + } + + return $entries; + } + + private function connection(): Connection + { + return $this->getEntityManager()->getConnection(); + } +} diff --git a/sources/AppBundle/Association/Entity/SubscriptionReminderLog.php b/sources/AppBundle/Association/Entity/SubscriptionReminderLog.php new file mode 100644 index 000000000..e030c1510 --- /dev/null +++ b/sources/AppBundle/Association/Entity/SubscriptionReminderLog.php @@ -0,0 +1,37 @@ + - */ -class SubscriptionReminderLogRepository extends Repository implements MetadataInitializer -{ - public function getPaginatedLogs($page = 1, $limit = 50) - { - return $this->getQuery(' - SELECT asrl.id, asrl.user_id, asrl.user_type, asrl.email, asrl.reminder_key, asrl.reminder_date, asrl.mail_sent, - app.id, apm.id, app.nom, apm.nom, app.prenom, apm.prenom, apm.raison_sociale - FROM `afup_subscription_reminder_log` asrl - LEFT JOIN afup_personnes_physiques app ON app.id = asrl.user_id - LEFT JOIN afup_personnes_morales apm ON apm.id = app.id_personne_morale - ORDER BY asrl.reminder_date DESC - LIMIT ' . (((int) $page - 1) * $limit) . ', ' . (int) ($limit + 1), - )->query(); - } - - /** - * @inheritDoc - */ - public static function initMetadata(SerializerFactoryInterface $serializerFactory, array $options = []) - { - $metadata = new Metadata($serializerFactory); - - $metadata->setEntity(SubscriptionReminderLog::class); - $metadata->setConnectionName('main'); - $metadata->setDatabase($options['database']); - $metadata->setTable('afup_subscription_reminder_log'); - - $metadata - ->addField([ - 'columnName' => 'id', - 'fieldName' => 'id', - 'primary' => true, - 'autoincrement' => true, - 'type' => 'int', - ]) - ->addField([ - 'columnName' => 'user_id', - 'fieldName' => 'userId', - 'type' => 'int', - ]) - ->addField([ - 'columnName' => 'user_type', - 'fieldName' => 'userType', - 'type' => 'int', - ]) - ->addField([ - 'columnName' => 'email', - 'fieldName' => 'email', - 'type' => 'string', - ]) - ->addField([ - 'columnName' => 'reminder_key', - 'fieldName' => 'reminderKey', - 'type' => 'string', - ]) - ->addField([ - 'columnName' => 'reminder_date', - 'fieldName' => 'reminderDate', - 'type' => 'datetime', - ]) - ->addField([ - 'columnName' => 'mail_sent', - 'fieldName' => 'mailSent', - 'type' => 'int', - ]) - ; - - return $metadata; - } -} diff --git a/sources/AppBundle/Association/Model/SubscriptionReminderLog.php b/sources/AppBundle/Association/Model/SubscriptionReminderLog.php deleted file mode 100644 index df33a0fb2..000000000 --- a/sources/AppBundle/Association/Model/SubscriptionReminderLog.php +++ /dev/null @@ -1,163 +0,0 @@ -id; - } - - /** - * @param int $id - */ - public function setId($id): self - { - $this->propertyChanged('id', $this->id, $id); - $this->id = $id; - return $this; - } - - /** - * @return int - */ - public function getUserId(): ?int - { - return $this->userId; - } - - /** - * @param int $userId - */ - public function setUserId($userId): self - { - $userId = (int) $userId; - $this->propertyChanged('userId', $this->userId, $userId); - $this->userId = $userId; - return $this; - } - - /** - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * @param string $email - */ - public function setEmail($email): self - { - $this->propertyChanged('email', $this->email, $email); - $this->email = $email; - return $this; - } - - /** - * @return int - */ - public function getUserType() - { - return $this->userType; - } - - /** - * @param int $userType - */ - public function setUserType($userType): self - { - $this->propertyChanged('userType', $this->userType, $userType); - $this->userType = $userType; - return $this; - } - - /** - * @return string - */ - public function getReminderKey() - { - return $this->reminderKey; - } - - /** - * @param string $reminderKey - */ - public function setReminderKey($reminderKey): self - { - $this->propertyChanged('reminderKey', $this->reminderKey, $reminderKey); - $this->reminderKey = $reminderKey; - return $this; - } - - /** - * @return \DateTime - */ - public function getReminderDate(): ?\DateTime - { - return $this->reminderDate; - } - - public function setReminderDate(\DateTime $reminderDate): self - { - $this->propertyChanged('reminderDate', $this->reminderDate, $reminderDate); - $this->reminderDate = $reminderDate; - return $this; - } - - /** - * @return bool - */ - public function getMailSent(): ?bool - { - return $this->mailSent; - } - - /** - * @param bool $mailSent - */ - public function setMailSent($mailSent): self - { - $this->propertyChanged('mailSent', $this->mailSent, (bool) $mailSent); - $this->mailSent = (bool) $mailSent; - return $this; - } -} diff --git a/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php b/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php index 1da3c9a0c..8d3d2d92f 100644 --- a/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php +++ b/sources/AppBundle/Association/UserMembership/AbstractUserReminder.php @@ -6,8 +6,8 @@ use AppBundle\Association\MembershipReminderInterface; use AppBundle\Association\MemberType; -use AppBundle\Association\Model\Repository\SubscriptionReminderLogRepository; -use AppBundle\Association\Model\SubscriptionReminderLog; +use AppBundle\Association\Entity\Repository\SubscriptionReminderLogRepository; +use AppBundle\Association\Entity\SubscriptionReminderLog; use AppBundle\Association\NotifiableInterface; use AppBundle\Email\Mailer\Attachment; use AppBundle\Email\Mailer\Mailer; @@ -30,13 +30,11 @@ abstract protected function getKey(): string; public function sendReminder(NotifiableInterface $user): void { $log = new SubscriptionReminderLog(); - $log - ->setEmail($user->getEmail()) - ->setUserId($user->getId()) - ->setReminderDate(new \DateTime()) - ->setReminderKey($this->getKey()) - ->setUserType(MemberType::MemberPhysical->value) - ; + $log->email = (string) $user->getEmail(); + $log->userId = (int) $user->getId(); + $log->reminderDate = new \DateTimeImmutable(); + $log->reminderKey = $this->getKey(); + $log->userType = MemberType::MemberPhysical; $message = new Message( $this->getSubject(), @@ -52,7 +50,7 @@ public function sendReminder(NotifiableInterface $user): void )); $status = $this->mailer->sendTransactional($message, $this->getText(), MailUserFactory::bureau()->getEmail()); - $log->setMailSent($status); + $log->mailSent = $status; $this->subscriptionReminderLogRepository->save($log); } } diff --git a/sources/AppBundle/Association/UserMembership/UserReminderFactory.php b/sources/AppBundle/Association/UserMembership/UserReminderFactory.php index 93156cdb4..eb6a6b34f 100644 --- a/sources/AppBundle/Association/UserMembership/UserReminderFactory.php +++ b/sources/AppBundle/Association/UserMembership/UserReminderFactory.php @@ -6,7 +6,7 @@ use AppBundle\Association\CompanyMembership\SubscriptionManagement; use AppBundle\Association\MembershipReminderInterface; -use AppBundle\Association\Model\Repository\SubscriptionReminderLogRepository; +use AppBundle\Association\Entity\Repository\SubscriptionReminderLogRepository; use AppBundle\Email\Mailer\Mailer; class UserReminderFactory diff --git a/sources/AppBundle/Command/SubscriptionReminderCommand.php b/sources/AppBundle/Command/SubscriptionReminderCommand.php index 561536205..3de2fb081 100644 --- a/sources/AppBundle/Command/SubscriptionReminderCommand.php +++ b/sources/AppBundle/Command/SubscriptionReminderCommand.php @@ -8,7 +8,7 @@ use AppBundle\Association\CompanyMembership\CompanyReminderFactory; use AppBundle\Association\MembershipReminderInterface; use AppBundle\Association\MemberType; -use AppBundle\Association\Model\Repository\SubscriptionReminderLogRepository; +use AppBundle\Association\Entity\Repository\SubscriptionReminderLogRepository; use AppBundle\Association\Model\Repository\UserRepository; use AppBundle\Association\UserMembership\Reminder15DaysAfterEnd; use AppBundle\Association\UserMembership\Reminder15DaysBeforeEnd; diff --git a/sources/AppBundle/Controller/Admin/Membership/ReminderLogAction.php b/sources/AppBundle/Controller/Admin/Membership/ReminderLogAction.php index 8723b707d..4206a5b88 100644 --- a/sources/AppBundle/Controller/Admin/Membership/ReminderLogAction.php +++ b/sources/AppBundle/Controller/Admin/Membership/ReminderLogAction.php @@ -4,7 +4,7 @@ namespace AppBundle\Controller\Admin\Membership; -use AppBundle\Association\Model\Repository\SubscriptionReminderLogRepository; +use AppBundle\Association\Entity\Repository\SubscriptionReminderLogRepository; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Twig\Environment; diff --git a/templates/admin/relances/liste.html.twig b/templates/admin/relances/liste.html.twig index 4e2dfa808..60278d798 100644 --- a/templates/admin/relances/liste.html.twig +++ b/templates/admin/relances/liste.html.twig @@ -16,27 +16,27 @@ {% for log in logs %} - {{ log.app.firstname }} {{ log.app.lastname }} - {% if log.apm is not null %}{{ log.apm.companyName }}{% else %}¤{% endif %} + {{ log.prenom }} {{ log.nom }} + {% if log.apmId is not null %}{{ log.raisonSociale }}{% else %}¤{% endif %} - {% if log.asrl.mailSent %} + {% if log.mailSent %} Ok {% else %} Erreur {% endif %} - {{ log.asrl.reminderKey }} - {{ log.asrl.reminderDate|date('d/m/Y') }} + {{ log.reminderKey }} + {{ log.reminderDate|date('d/m/Y') }} @@ -47,7 +47,7 @@
- {% if logs.count > limit %} + {% if logs|length > limit %}
diff --git a/tests/integration/AppBundle/Association/Entity/Repository/SubscriptionReminderLogRepositoryTest.php b/tests/integration/AppBundle/Association/Entity/Repository/SubscriptionReminderLogRepositoryTest.php new file mode 100644 index 000000000..40a48ad0d --- /dev/null +++ b/tests/integration/AppBundle/Association/Entity/Repository/SubscriptionReminderLogRepositoryTest.php @@ -0,0 +1,151 @@ +get(SubscriptionReminderLogRepository::class); + $this->connection = self::getContainer()->get(Connection::class); + + // Données de base reproductibles pour chaque test : deux personnes + // physiques dont une rattachée à une personne morale. + $this->connection->insert('afup_personnes_physiques', [ + 'id' => 1, + 'roles' => '[]', + 'adresse' => '1 rue du Test', + 'nom' => 'Paul', + 'prenom' => 'Personne', + 'email' => 'paul@example.com', + ]); + $this->connection->insert('afup_personnes_physiques', [ + 'id' => 2, + 'roles' => '[]', + 'adresse' => '2 rue du Test', + 'nom' => 'Dupont', + 'prenom' => 'Edmond', + 'email' => 'edmond@example.com', + 'id_personne_morale' => 10, + ]); + $this->connection->insert('afup_personnes_morales', [ + 'id' => 10, + 'raison_sociale' => 'MyCorp', + 'nom' => 'Dupont', + 'prenom' => 'Edmond', + 'email' => 'mycorp@example.com', + 'siret' => '4445451', + 'adresse' => '1 rue du Test', + 'code_postal' => '69001', + 'ville' => 'LYON', + 'id_pays' => 'FR', + ]); + + $this->insertReminderLog(userId: 1, date: '2022-04-01', sent: true); + $this->insertReminderLog(userId: 2, date: '2022-03-01', sent: false); + $this->insertReminderLog(userId: 2, date: '2022-02-01', sent: true); + } + + private function insertReminderLog(int $userId, string $date, bool $sent, ?int $id = null): void + { + $this->connection->insert('afup_subscription_reminder_log', [ + 'user_id' => $userId, + 'user_type' => 0, + 'email' => 'relance@example.com', + 'reminder_date' => $date, + 'reminder_key' => '15DaysAfter', + 'mail_sent' => (int) $sent, + ] + (is_int($id) ? ['id' => $id] : [])); + } + + public function testGetPaginatedLogsSortsByDateAndMapsScalarValues(): void + { + $repository = self::getContainer()->get(SubscriptionReminderLogRepository::class); + + $logs = $repository->getPaginatedLogs(); + + self::assertCount(3, $logs); + + $first = $logs[0]; + self::assertSame('Personne', $first->prenom); + self::assertSame('Paul', $first->nom); + self::assertSame(1, $first->appId); + self::assertTrue($first->mailSent); + self::assertSame('15DaysAfter', $first->reminderKey); + self::assertSame('2022-04-01', $first->reminderDate->format('Y-m-d')); + + $second = $logs[1]; + self::assertSame('Edmond', $second->prenom); + self::assertSame('Dupont', $second->nom); + self::assertSame('2022-03-01', $second->reminderDate->format('Y-m-d')); + } + + public function testGetPaginatedLogsHidesCompanyWhenMemberIsPhysical(): void + { + $repository = self::getContainer()->get(SubscriptionReminderLogRepository::class); + + $logs = $repository->getPaginatedLogs(); + + self::assertNull($logs[0]->apmId); + self::assertNull($logs[0]->raisonSociale); + } + + public function testGetPaginatedLogsReturnsCompanyInformation(): void + { + $repository = self::getContainer()->get(SubscriptionReminderLogRepository::class); + + $logs = $repository->getPaginatedLogs(); + + self::assertSame(10, $logs[1]->apmId); + self::assertSame('MyCorp', $logs[1]->raisonSociale); + self::assertFalse($logs[1]->mailSent); + } + + public function testGetPaginatedLogsIsPaginated(): void + { + $repository = self::getContainer()->get(SubscriptionReminderLogRepository::class); + + $pageOne = $repository->getPaginatedLogs(page: 1, limit: 2); + $pageTwo = $repository->getPaginatedLogs(page: 2, limit: 2); + + // Une remontée de plus que la limite indique qu'une page suivante existe. + self::assertCount(3, $pageOne); + self::assertCount(1, $pageTwo); + self::assertSame('2022-02-01', $pageTwo[0]->reminderDate->format('Y-m-d')); + } + + public function testGetPaginatedLogsWithDeletedUserReturnsNullMemberInformation(): void + { + // Un log orphelin (utilisateur supprimé depuis) doit apparaître + // sans information de membre au lieu de lever une exception. + $this->connection->insert('afup_subscription_reminder_log', [ + 'user_id' => 9999, + 'user_type' => 0, + 'email' => 'supprime@example.com', + 'reminder_date' => '2022-05-01', + 'reminder_key' => '15DaysAfter', + 'mail_sent' => 0, + ]); + + $repository = self::getContainer()->get(SubscriptionReminderLogRepository::class); + + $logs = $repository->getPaginatedLogs(); + + self::assertCount(4, $logs); + self::assertSame('2022-05-01', $logs[0]->reminderDate->format('Y-m-d')); + self::assertNull($logs[0]->nom); + self::assertNull($logs[0]->prenom); + self::assertNull($logs[0]->appId); + self::assertFalse($logs[0]->mailSent); + } +}