diff --git a/db/seeds/Inscriptions.php b/db/seeds/Inscriptions.php index dd640d493..4e3462c27 100644 --- a/db/seeds/Inscriptions.php +++ b/db/seeds/Inscriptions.php @@ -68,7 +68,8 @@ public function run(): void 'date' => new \DateTime("2024-01-02")->getTimestamp(), 'reference' => 'REF-TEST-004', 'type_inscription' => Tarif::TYPE_2_DAYS_AFUP['id'], - 'montant' => Tarif::TYPE_2_DAYS_AFUP['default_price'], + // Prix vendeur de l'evenement de test (db/seeds/EventTarif.php : id_tarif = 3, price = 15) + 'montant' => 15.0, 'genre' => Genre::Femme->value, 'nom' => 'Sans', 'prenom' => 'Cotisation', @@ -85,7 +86,8 @@ public function run(): void 'date' => time(), 'reference' => 'REF-TEST-005', 'type_inscription' => Tarif::TYPE_2_DAYS_AFUP['id'], - 'montant' => Tarif::TYPE_2_DAYS_AFUP['default_price'], + // Prix vendeur de l'evenement de test (db/seeds/EventTarif.php : id_tarif = 3, price = 15) + 'montant' => 15.0, 'genre' => Genre::Homme->value, 'nom' => 'Personne', 'prenom' => 'Paul', @@ -103,7 +105,8 @@ public function run(): void 'date' => time(), 'reference' => 'REF-TEST-006', 'type_inscription' => Tarif::TYPE_2_DAYS_AFUP['id'], - 'montant' => Tarif::TYPE_2_DAYS_AFUP['default_price'], + // Prix vendeur de l'evenement de test (db/seeds/EventTarif.php : id_tarif = 3, price = 15) + 'montant' => 15.0, 'genre' => Genre::Homme->value, 'nom' => 'Maurice', 'prenom' => 'Jean', @@ -223,7 +226,7 @@ public function run(): void ], [ 'reference' => 'REF-TEST-004', - 'montant' => Tarif::TYPE_2_DAYS_AFUP['default_price'], + 'montant' => 15.0, 'date_reglement' => new \DateTime("2024-01-02")->getTimestamp(), 'type_reglement' => Ticket::PAYMENT_CREDIT_CARD, 'email' => 'sans@cotisation.fr', @@ -242,7 +245,7 @@ public function run(): void ], [ 'reference' => 'REF-TEST-005', - 'montant' => Tarif::TYPE_2_DAYS_AFUP['default_price'], + 'montant' => 15.0, 'date_reglement' => new \DateTime("2024-01-02")->getTimestamp(), 'type_reglement' => Ticket::PAYMENT_CREDIT_CARD, 'nom' => 'Personne', @@ -261,7 +264,7 @@ public function run(): void ], [ 'reference' => 'REF-TEST-006', - 'montant' => Tarif::TYPE_2_DAYS_AFUP['default_price'], + 'montant' => 15.0, 'date_reglement' => new \DateTime("2024-01-02")->getTimestamp(), 'type_reglement' => Ticket::PAYMENT_CREDIT_CARD, 'nom' => 'Maurice', diff --git a/phpstan-baseline.php b/phpstan-baseline.php index 5a36f5372..f85ead6d8 100644 --- a/phpstan-baseline.php +++ b/phpstan-baseline.php @@ -6328,7 +6328,7 @@ $ignoreErrors[] = [ 'message' => '#^Cannot cast mixed to int\\.$#', 'identifier' => 'cast.int', - 'count' => 3, + 'count' => 4, 'path' => __DIR__ . '/sources/AppBundle/Event/Model/Repository/EventStatsRepository.php', ]; $ignoreErrors[] = [ diff --git a/sources/AppBundle/Controller/Admin/Event/Ticket/IndexAction.php b/sources/AppBundle/Controller/Admin/Event/Ticket/IndexAction.php index e61dab893..1de4a7be8 100644 --- a/sources/AppBundle/Controller/Admin/Event/Ticket/IndexAction.php +++ b/sources/AppBundle/Controller/Admin/Event/Ticket/IndexAction.php @@ -75,7 +75,8 @@ private function computeStatistics(EventStats $statistics, Event $event): array $registered = $statistics->ticketType->registered[$ticketType] ?? 0; $confirmed = $statistics->ticketType->confirmed[$ticketType] ?? 0; $paying = $statistics->ticketType->paying[$ticketType] ?? 0; - $amount = $paying * $ticketOffer->price; + $realAmount = $statistics->ticketType->realAmounts[$ticketType] ?? 0.0; + $amount = $realAmount; if ($registered) { $computed[$ticketType] = [ @@ -83,7 +84,7 @@ private function computeStatistics(EventStats $statistics, Event $event): array 'registered' => $registered, 'confirmed' => $confirmed, 'paying' => $paying, - 'amount' => $ticketOffer->price, + 'amount' => $paying > 0 && $realAmount > 0 ? round($realAmount / $paying, 2) : $ticketOffer->price, 'payingAmount' => $amount, 'availableTickets' => $ticketOffer->availableTickets, ]; diff --git a/sources/AppBundle/Event/Model/EventStats/TicketTypeStats.php b/sources/AppBundle/Event/Model/EventStats/TicketTypeStats.php index 3d1da8766..7a165b534 100644 --- a/sources/AppBundle/Event/Model/EventStats/TicketTypeStats.php +++ b/sources/AppBundle/Event/Model/EventStats/TicketTypeStats.php @@ -15,5 +15,8 @@ public function __construct( /** @var list */ public array $paying, + + /** @var array Montant réel encaissé ou en attente par type de tarif */ + public array $realAmounts = [], ) {} } diff --git a/sources/AppBundle/Event/Model/Repository/EventStatsRepository.php b/sources/AppBundle/Event/Model/Repository/EventStatsRepository.php index 9d4f8897f..9ef3651db 100644 --- a/sources/AppBundle/Event/Model/Repository/EventStatsRepository.php +++ b/sources/AppBundle/Event/Model/Repository/EventStatsRepository.php @@ -75,6 +75,20 @@ public function getStatsForTicketTypes(int $eventId, ?Datetime $from): TicketTyp $paying[$row['type_inscription']] = $row['c']; } + $queryBuilder = clone $baseQueryBuilder; + $queryBuilder + ->select('type_inscription', 'SUM(montant) AS montant') + ->andWhere('etat IN(:states)') + ->setParameter('states', [Ticket::STATUS_PAID, Ticket::STATUS_WAITING], ArrayParameterType::INTEGER); + $statement = $queryBuilder->executeQuery(); + + $realAmounts = []; + foreach ($statement->fetchAllAssociative() as $row) { + if (is_numeric($row['montant'])) { + $realAmounts[(int) $row['type_inscription']] = (float) $row['montant']; + } + } + $queryBuilder = clone $baseQueryBuilder; $statement = $queryBuilder->andWhere('etat NOT IN(:states)') ->setParameter('states', [Ticket::STATUS_CANCELLED, Ticket::STATUS_ERROR, Ticket::STATUS_DECLINED], ArrayParameterType::INTEGER) @@ -85,7 +99,7 @@ public function getStatsForTicketTypes(int $eventId, ?Datetime $from): TicketTyp $registered[$row['type_inscription']] = $row['c']; } - return new TicketTypeStats($confirmed, $registered, $paying); + return new TicketTypeStats($confirmed, $registered, $paying, $realAmounts); } private function getStatsForDay(int $eventId, string $day, ?Datetime $from = null): DailyStats diff --git a/tests/integration/AppBundle/Event/Model/Repository/EventStatsRepositoryTest.php b/tests/integration/AppBundle/Event/Model/Repository/EventStatsRepositoryTest.php new file mode 100644 index 000000000..249c0352a --- /dev/null +++ b/tests/integration/AppBundle/Event/Model/Repository/EventStatsRepositoryTest.php @@ -0,0 +1,49 @@ +get(EventStatsRepository::class); + $connection = self::getContainer()->get(Connection::class); + + // Deux places via une billetterie privée : une réglée, une en attente de règlement + $this->insertInscription($connection, 'TOKEN-STATS-1', 'STATS-A', 42, Ticket::STATUS_PAID, 80.0); + $this->insertInscription($connection, 'TOKEN-STATS-1', 'STATS-B', 42, Ticket::STATUS_WAITING, 80.0); + // Une place annulée ne doit pas être comptée + $this->insertInscription($connection, 'TOKEN-STATS-1', 'STATS-C', 42, Ticket::STATUS_CANCELLED, 80.0); + + $stats = $eventStatsRepository->getStatsForTicketTypes(42, null); + + self::assertSame(2, $stats->paying[Ticket::TYPE_SPECIAL_PRICE] ?? 0); + self::assertSame(160.0, $stats->realAmounts[Ticket::TYPE_SPECIAL_PRICE] ?? 0.0); + } + + private function insertInscription( + Connection $connection, + string $token, + string $reference, + int $forumId, + int $etat, + float $montant, + ): void { + $connection->insert('afup_inscription_forum', [ + 'reference' => $reference, + 'special_price_token' => $token, + 'id_forum' => $forumId, + 'etat' => $etat, + 'type_inscription' => Ticket::TYPE_SPECIAL_PRICE, + 'montant' => $montant, + 'date' => time(), + ]); + } +}