From c976c379b9e5e5855bc2d4d0e5d3e74ca08e944a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Jul 2022 20:14:25 +0000 Subject: [PATCH 1/8] Bump dependabot/fetch-metadata from 1.3.1 to 1.3.3 Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 1.3.1 to 1.3.3. - [Release notes](https://github.com/dependabot/fetch-metadata/releases) - [Commits](https://github.com/dependabot/fetch-metadata/compare/v1.3.1...v1.3.3) --- updated-dependencies: - dependency-name: dependabot/fetch-metadata dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/dependabot-auto-merge.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 70e017a..14da349 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -13,7 +13,7 @@ jobs: - name: Dependabot metadata id: metadata - uses: dependabot/fetch-metadata@v1.3.1 + uses: dependabot/fetch-metadata@v1.3.3 with: github-token: "${{ secrets.GITHUB_TOKEN }}" From e2756f715309f376f8d3a46fbdd76521bfa71a98 Mon Sep 17 00:00:00 2001 From: Ali Ragab Date: Tue, 12 Jul 2022 20:44:04 +0300 Subject: [PATCH 2/8] Update 2022_02_01_235539_create_subscriptions_table.php Fixing error: Illuminate\Database\QueryException SQLSTATE[42000]: Syntax error or access violation: 1067 Invalid default value for 'expired_at' (SQL: create table `subscriptions` (`id` bigint unsigned not null auto_increment primary key, `plan_id` bigint unsigned not null, `canceled_at` timestamp null, `expired_at` timestamp not null, `grace_days_ended_at` timestamp null, `started_at` date not null, `suppressed_at` timestamp null, `was_switched` tinyint(1) not null default '0', `deleted_at` timestamp null, `created_at` timestamp null, `updated_at` timestamp null, `subscriber_type` varchar(255) not null, `subscriber_id` bigint unsigned not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci') When trying to migrate --- .../migrations/2022_02_01_235539_create_subscriptions_table.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database/migrations/2022_02_01_235539_create_subscriptions_table.php b/database/migrations/2022_02_01_235539_create_subscriptions_table.php index 849f0db..5cf7c64 100644 --- a/database/migrations/2022_02_01_235539_create_subscriptions_table.php +++ b/database/migrations/2022_02_01_235539_create_subscriptions_table.php @@ -17,7 +17,7 @@ public function up() $table->id(); $table->foreignIdFor(\LucasDotVin\Soulbscription\Models\Plan::class); $table->timestamp('canceled_at')->nullable(); - $table->timestamp('expired_at'); + $table->timestamp('expired_at')->nullable(); $table->timestamp('grace_days_ended_at')->nullable(); $table->date('started_at'); $table->timestamp('suppressed_at')->nullable(); From 36f3d547fa97cabea96d0dd1a09350421542f7d0 Mon Sep 17 00:00:00 2001 From: 3AGLExyz <66855115+3AGLExyz@users.noreply.github.com> Date: Wed, 13 Jul 2022 14:57:19 +0200 Subject: [PATCH 3/8] - Added uses_uuid to config file - Added uses_uuid into config file because this config is requested in 2022_02_01_235539_create_subscriptions_table but was not yet declared because. - Using the "env()" function to add .env file functionality for developing --- config/soulbscription.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/soulbscription.php b/config/soulbscription.php index d92a221..ebdc860 100644 --- a/config/soulbscription.php +++ b/config/soulbscription.php @@ -1,7 +1,7 @@ false, + 'feature_tickets' => env('SOULBSCRIPTION_FEATURE_TICKETS', false), 'models' => [ @@ -14,6 +14,10 @@ 'feature_plan' => \LucasDotVin\Soulbscription\Models\FeaturePlan::class, 'plan' => \LucasDotVin\Soulbscription\Models\Plan::class, + + 'subscriber' => [ + 'uses_uuid' => env('SOULBSCRIPTION_SUBSCRIBER_USES_UUID', false), + ], 'subscription' => \LucasDotVin\Soulbscription\Models\Subscription::class, From 47826b7c879f083456fd56b641838835e567bca4 Mon Sep 17 00:00:00 2001 From: Ali Ragab Date: Wed, 13 Jul 2022 16:28:19 +0300 Subject: [PATCH 4/8] Update HasSubscriptions.php add a function to check if a user subscribed to a plan --- src/Models/Concerns/HasSubscriptions.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Models/Concerns/HasSubscriptions.php b/src/Models/Concerns/HasSubscriptions.php index e7c5540..1b2c6c4 100644 --- a/src/Models/Concerns/HasSubscriptions.php +++ b/src/Models/Concerns/HasSubscriptions.php @@ -121,6 +121,13 @@ public function subscribeTo(Plan $plan, $expiration = null, $startDate = null): ->start($startDate); } + public function hasSubscription(Plan $plan): bool + { + return $this->subscription() + ->where('plan_id', $plan->id) + ->exists(); + } + public function switchTo(Plan $plan, $expiration = null, $immediately = true): Subscription { if ($immediately) { From 53f627dd663b82a888db6ad3c162b3d67c69d004 Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 18 Jul 2022 20:46:06 -0300 Subject: [PATCH 5/8] Create test cases over hasSubscriptionTo method --- .../Models/Concerns/HasSubscriptionsTest.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/tests/Models/Concerns/HasSubscriptionsTest.php b/tests/Models/Concerns/HasSubscriptionsTest.php index 4f93a8f..ab926ca 100644 --- a/tests/Models/Concerns/HasSubscriptionsTest.php +++ b/tests/Models/Concerns/HasSubscriptionsTest.php @@ -809,4 +809,32 @@ public function testItRaisesAnExceptionWhenSettingConsumedQuotaForANotQuotaFeatu $subscriber->setConsumedQuota($feature->name, $consumption); } + + public function testItChecksIfTheUserHasSubscriptionToAPlan() + { + $plan = Plan::factory()->createOne(); + + $subscriber = User::factory()->createOne(); + $subscriber->subscribeTo($plan); + + $hasSubscription = $subscriber->hasSubscriptionTo($plan); + $isSubscribed = $subscriber->isSubscribedTo($plan); + + $this->assertTrue($hasSubscription); + $this->assertTrue($isSubscribed); + } + + public function testItChecksIfTheUserDoesNotHaveSubscriptionToAPlan() + { + $plan = Plan::factory()->createOne(); + + $subscriber = User::factory()->createOne(); + $subscriber->subscribeTo($plan); + + $hasSubscription = $subscriber->missingSubscriptionTo($plan); + $isSubscribed = $subscriber->isNotSubscribedTo($plan); + + $this->assertFalse($hasSubscription); + $this->assertFalse($isSubscribed); + } } From 2fd7c3dc7070f5647b9bf3d5c10e710576443a18 Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 18 Jul 2022 20:46:19 -0300 Subject: [PATCH 6/8] Create methods to check if a user is subscribed to a given plan --- src/Models/Concerns/HasSubscriptions.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/Models/Concerns/HasSubscriptions.php b/src/Models/Concerns/HasSubscriptions.php index 1b2c6c4..fd1ccc1 100644 --- a/src/Models/Concerns/HasSubscriptions.php +++ b/src/Models/Concerns/HasSubscriptions.php @@ -121,13 +121,28 @@ public function subscribeTo(Plan $plan, $expiration = null, $startDate = null): ->start($startDate); } - public function hasSubscription(Plan $plan): bool + public function hasSubscriptionTo(Plan $plan): bool { return $this->subscription() ->where('plan_id', $plan->id) ->exists(); } + public function isSubscribedTo(Plan $plan): bool + { + return $this->hasSubscriptionTo($plan); + } + + public function missingSubscriptionTo(Plan $plan): bool + { + return !$this->hasSubscriptionTo($plan); + } + + public function isNotSubscribedTo(Plan $plan): bool + { + return !$this->isSubscribedTo($plan); + } + public function switchTo(Plan $plan, $expiration = null, $immediately = true): Subscription { if ($immediately) { From 7be5d3da3c8f8b82f33fbcba15fbd3a7f15cabc1 Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 18 Jul 2022 21:01:47 -0300 Subject: [PATCH 7/8] Create test cases to ensure renew uses current date only if the subscription is overdue --- tests/Models/SubscriptionTest.php | 39 +++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/tests/Models/SubscriptionTest.php b/tests/Models/SubscriptionTest.php index a9f3404..a5d8cd4 100644 --- a/tests/Models/SubscriptionTest.php +++ b/tests/Models/SubscriptionTest.php @@ -22,12 +22,47 @@ class SubscriptionTest extends TestCase public function testModelRenews() { + Carbon::setTestNow(now()); + $plan = Plan::factory()->create(); $subscriber = User::factory()->create(); $subscription = Subscription::factory() ->for($plan) ->for($subscriber, 'subscriber') - ->create(); + ->create([ + 'expired_at' => now()->addDays(1), + ]); + + $expectedExpiredAt = $plan->calculateNextRecurrenceEnd($subscription->expired_at)->toDateTimeString(); + + Event::fake(); + + $subscription->renew(); + + Event::assertDispatched(SubscriptionRenewed::class); + + $this->assertDatabaseHas('subscriptions', [ + 'plan_id' => $plan->id, + 'subscriber_id' => $subscriber->id, + 'subscriber_type' => User::class, + 'expired_at' => $expectedExpiredAt, + ]); + } + + public function testModelRenewsBasedOnCurrentDateIfOverdue() + { + Carbon::setTestNow(now()); + + $plan = Plan::factory()->create(); + $subscriber = User::factory()->create(); + $subscription = Subscription::factory() + ->for($plan) + ->for($subscriber, 'subscriber') + ->create([ + 'expired_at' => now()->subDay(), + ]); + + $expectedExpiredAt = $plan->calculateNextRecurrenceEnd()->toDateTimeString(); Event::fake(); @@ -39,7 +74,7 @@ public function testModelRenews() 'plan_id' => $plan->id, 'subscriber_id' => $subscriber->id, 'subscriber_type' => User::class, - 'expired_at' => $plan->calculateNextRecurrenceEnd(), + 'expired_at' => $expectedExpiredAt, ]); } From 57ea335444609f88784017cd3640c18ae158d49d Mon Sep 17 00:00:00 2001 From: Lucas Vinicius Date: Mon, 18 Jul 2022 21:02:03 -0300 Subject: [PATCH 8/8] Calculate renewed expiration using current date if it is overdue --- src/Models/Subscription.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Models/Subscription.php b/src/Models/Subscription.php index 454149f..2a500bf 100644 --- a/src/Models/Subscription.php +++ b/src/Models/Subscription.php @@ -109,7 +109,7 @@ public function renew(?Carbon $expirationDate = null): self 'overdue' => $this->isOverdue, ]); - $expirationDate = $expirationDate ?: $this->plan->calculateNextRecurrenceEnd(); + $expirationDate = $this->getRenewedExpiration($expirationDate); $this->update([ 'expired_at' => $expirationDate, @@ -153,4 +153,17 @@ public function getIsOverdueAttribute(): bool return $this->expired_at->isPast(); } + + private function getRenewedExpiration(?Carbon $expirationDate = null) + { + if (!empty($expirationDate)) { + return $expirationDate; + } + + if ($this->isOverdue) { + return $this->plan->calculateNextRecurrenceEnd(); + } + + return $this->plan->calculateNextRecurrenceEnd($this->expired_at); + } }