Compute change of global subscribed subscribers
[MAILPOET-4828]
This commit is contained in:
committed by
Aschepikov
parent
6e99d5ec9d
commit
04307ca2a6
@@ -161,10 +161,24 @@ class HomepageDataController {
|
||||
$listData[$list['id']]['unsubscribed'] = $list['count'];
|
||||
}
|
||||
|
||||
$subscribedCount = $this->subscribersRepository->getCountOfCreatedAfterWithStatues($thirtyDaysAgo, [SubscriberEntity::STATUS_SUBSCRIBED]);
|
||||
$unsubscribedCount = $this->subscribersRepository->getCountOfUnsubscribedAfter($thirtyDaysAgo);
|
||||
$subscribedSubscribersCount = $this->subscribersRepository->getCountOfSubscribersForStates([SubscriberEntity::STATUS_SUBSCRIBED]);
|
||||
$subscribedSubscribers30DaysAgo = $subscribedSubscribersCount - $subscribedCount + $unsubscribedCount;
|
||||
if ($subscribedSubscribers30DaysAgo > 0) {
|
||||
$globalChangePercent = (($subscribedSubscribersCount - $subscribedSubscribers30DaysAgo) / $subscribedSubscribers30DaysAgo) * 100;
|
||||
if (floor($globalChangePercent) !== (float)$globalChangePercent) {
|
||||
$globalChangePercent = round($globalChangePercent, 1);
|
||||
}
|
||||
} else {
|
||||
$globalChangePercent = $subscribedSubscribersCount * 100;
|
||||
}
|
||||
|
||||
return [
|
||||
'global' => [
|
||||
'subscribed' => $this->subscribersRepository->getCountOfCreatedAfterWithStatues($thirtyDaysAgo, [SubscriberEntity::STATUS_SUBSCRIBED]),
|
||||
'unsubscribed' => $this->subscribersRepository->getCountOfUnsubscribedAfter($thirtyDaysAgo),
|
||||
'subscribed' => $subscribedCount,
|
||||
'unsubscribed' => $unsubscribedCount,
|
||||
'change' => $globalChangePercent,
|
||||
],
|
||||
'lists' => array_values($listData),
|
||||
];
|
||||
|
@@ -51,18 +51,22 @@ class SubscribersRepository extends Repository {
|
||||
}
|
||||
|
||||
public function getTotalSubscribers(): int {
|
||||
return $this->getCountOfSubscribersForStates([
|
||||
SubscriberEntity::STATUS_SUBSCRIBED,
|
||||
SubscriberEntity::STATUS_UNCONFIRMED,
|
||||
SubscriberEntity::STATUS_INACTIVE,
|
||||
]);
|
||||
}
|
||||
|
||||
public function getCountOfSubscribersForStates(array $states): int {
|
||||
$query = $this->entityManager
|
||||
->createQueryBuilder()
|
||||
->select('count(n.id)')
|
||||
->from(SubscriberEntity::class, 'n')
|
||||
->where('n.deletedAt IS NULL AND n.status IN (:statuses)')
|
||||
->setParameter('statuses', [
|
||||
SubscriberEntity::STATUS_SUBSCRIBED,
|
||||
SubscriberEntity::STATUS_UNCONFIRMED,
|
||||
SubscriberEntity::STATUS_INACTIVE,
|
||||
])
|
||||
->setParameter('statuses', $states)
|
||||
->getQuery();
|
||||
return (int)$query->getSingleScalarResult();
|
||||
return intval($query->getSingleScalarResult());
|
||||
}
|
||||
|
||||
public function invalidateTotalSubscribersCache(): void {
|
||||
@@ -390,7 +394,8 @@ class SubscribersRepository extends Repository {
|
||||
->select('COUNT(s.id)')
|
||||
->from(StatisticsUnsubscribeEntity::class, 'su')
|
||||
->join('su.subscriber', 's')
|
||||
->where('s.createdAt > :unsubscribedAfter')
|
||||
->where('s.createdAt <= :unsubscribedAfter')
|
||||
->andWhere('su.createdAt > :unsubscribedAfter')
|
||||
->andWhere('s.status = :status')
|
||||
->andWhere('s.deletedAt IS NULL')
|
||||
->setParameter('unsubscribedAfter', $unsubscribedAfter)
|
||||
|
@@ -815,11 +815,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||
|
||||
-
|
||||
message: "#^Cannot cast mixed to int\\.$#"
|
||||
count: 1
|
||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||
|
||||
-
|
||||
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
||||
count: 1
|
||||
|
@@ -815,11 +815,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||
|
||||
-
|
||||
message: "#^Cannot cast mixed to int\\.$#"
|
||||
count: 1
|
||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||
|
||||
-
|
||||
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
||||
count: 1
|
||||
|
@@ -814,11 +814,6 @@ parameters:
|
||||
count: 1
|
||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||
|
||||
-
|
||||
message: "#^Cannot cast mixed to int\\.$#"
|
||||
count: 1
|
||||
path: ../../lib/Subscribers/SubscribersRepository.php
|
||||
|
||||
-
|
||||
message: "#^Method MailPoet\\\\Subscribers\\\\SubscribersRepository\\:\\:findIdsOfDeletedByEmails\\(\\) should return array\\<int\\> but returns array\\<array\\<string, int\\>\\>\\.$#"
|
||||
count: 1
|
||||
|
@@ -195,8 +195,8 @@ class HomepageDataControllerTest extends \MailPoetTest {
|
||||
$oldUnsubscribedStats->setCreatedAt($thirtyOneDaysAgo);
|
||||
$this->entityManager->persist($oldUnsubscribedStats);
|
||||
$this->entityManager->flush();
|
||||
// Freshly unsubscribed
|
||||
$newUnsubscribed = (new Subscriber())->withCreatedAt($twentyNineDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||
// Freshly unsubscribed (but created before the period)
|
||||
$newUnsubscribed = (new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||
$newUnsubscribedStats = new StatisticsUnsubscribeEntity(null, null, $newUnsubscribed);
|
||||
$newUnsubscribedStats->setCreatedAt($twentyNineDaysAgo);
|
||||
$this->entityManager->persist($newUnsubscribedStats);
|
||||
@@ -207,6 +207,46 @@ class HomepageDataControllerTest extends \MailPoetTest {
|
||||
expect($subscribersStats['global']['unsubscribed'])->equals(1);
|
||||
}
|
||||
|
||||
public function testItFetchesCorrectGlobalSubscriberChange(): void {
|
||||
$thirtyOneDaysAgo = Carbon::now()->subDays(31);
|
||||
$twentyNineDaysAgo = Carbon::now()->subDays(29);
|
||||
|
||||
// 10 New Subscribers
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
(new Subscriber())->withCreatedAt($twentyNineDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||
}
|
||||
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||
expect($subscribersStats['global']['change'])->equals(1000);
|
||||
|
||||
// 10 New Subscribers + 5 Old Subscribers
|
||||
for ($i = 0; $i < 5; $i++) {
|
||||
(new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||
}
|
||||
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||
expect($subscribersStats['global']['change'])->equals(200);
|
||||
|
||||
// 10 New Subscribers + 6 Old Subscribers
|
||||
(new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_SUBSCRIBED)->create();
|
||||
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||
expect($subscribersStats['global']['change'])->equals( 166.7);
|
||||
|
||||
// 10 New Subscribers + 6 Old Subscribers + 10 New Unsubscribed
|
||||
for ($i = 0; $i < 10; $i++) {
|
||||
$unsubscribed = (new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||
$this->entityManager->persist(new StatisticsUnsubscribeEntity(null, null, $unsubscribed));
|
||||
$this->entityManager->flush();
|
||||
}
|
||||
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||
expect($subscribersStats['global']['change'])->equals( 0);
|
||||
|
||||
// 10 New Subscribers + 6 Old Subscribers + 11 New Unsubscribed
|
||||
$unsubscribed = (new Subscriber())->withCreatedAt($thirtyOneDaysAgo)->withStatus(SubscriberEntity::STATUS_UNSUBSCRIBED)->create();
|
||||
$this->entityManager->persist(new StatisticsUnsubscribeEntity(null, null, $unsubscribed));
|
||||
$this->entityManager->flush();
|
||||
$subscribersStats = $this->homepageDataController->getPageData()['subscribersStats'];
|
||||
expect($subscribersStats['global']['change'])->equals( -5.9);
|
||||
}
|
||||
|
||||
public function testItFetchesCorrectListLevelSubscribedStats(): void {
|
||||
$thirtyOneDaysAgo = Carbon::now()->subDays(31);
|
||||
$twentyNineDaysAgo = Carbon::now()->subDays(29);
|
||||
|
Reference in New Issue
Block a user