diff --git a/app/Livewire/Customer/Dashboard.php b/app/Livewire/Customer/Dashboard.php index 9818a50f..e82e03a0 100644 --- a/app/Livewire/Customer/Dashboard.php +++ b/app/Livewire/Customer/Dashboard.php @@ -31,6 +31,12 @@ public function activeSubscription() return auth()->user()->subscription(); } + #[Computed] + public function isCompedSubscription(): bool + { + return auth()->user()->hasCompedSubscription(); + } + #[Computed] public function subscriptionName(): ?string { diff --git a/app/Livewire/MobilePricing.php b/app/Livewire/MobilePricing.php index 4c71ecb6..1fe14e33 100644 --- a/app/Livewire/MobilePricing.php +++ b/app/Livewire/MobilePricing.php @@ -69,6 +69,11 @@ public function createCheckoutSession(?string $plan, ?User $user = null) return; } + // Cancel any comped subscription before creating a new paid one + if ($user->hasCompedSubscription()) { + $user->subscription('default')->cancelNow(); + } + $user->createOrGetStripeCustomer(); $checkout = $user @@ -209,7 +214,7 @@ public function render() $subscription = $user->subscription('default'); - if ($subscription && $subscription->active()) { + if ($subscription && $subscription->active() && ! $user->hasCompedSubscription()) { $hasExistingSubscription = true; $isAlreadyUltra = $user->hasActiveUltraSubscription(); diff --git a/app/Models/User.php b/app/Models/User.php index 82da1024..0aee5dbc 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -215,6 +215,27 @@ public function hasMaxAccess(): bool return $this->hasActiveMaxLicense() || $this->hasActiveMaxSubLicense(); } + /** + * Check if the user's subscription is a comped (free) subscription. + * Covers both legacy comped (is_comped flag) and comped Ultra price. + */ + public function hasCompedSubscription(): bool + { + $subscription = $this->subscription(); + + if (! $subscription || ! $subscription->active()) { + return false; + } + + if ($subscription->is_comped) { + return true; + } + + $compedPriceId = config('subscriptions.plans.max.stripe_price_id_comped'); + + return $compedPriceId && $this->subscribedToPrice($compedPriceId); + } + public function hasActiveUltraSubscription(): bool { $subscription = $this->subscription(); diff --git a/tests/Feature/MobilePricingTest.php b/tests/Feature/MobilePricingTest.php index 47b4973f..5a919e53 100644 --- a/tests/Feature/MobilePricingTest.php +++ b/tests/Feature/MobilePricingTest.php @@ -137,7 +137,7 @@ public function ultra_subscriber_sees_already_on_ultra_message() } #[Test] - public function comped_max_subscriber_sees_upgrade_button() + public function comped_max_subscriber_sees_checkout_button() { $user = User::factory()->create(['stripe_id' => 'cus_'.uniqid()]); Auth::login($user); @@ -155,7 +155,37 @@ public function comped_max_subscriber_sees_upgrade_button() ->create(['stripe_price' => self::MAX_PRICE_ID]); Livewire::test(MobilePricing::class) - ->assertSee('Upgrade to Ultra') + ->assertSeeHtml('wire:click="createCheckoutSession(\'max\')"') + ->assertDontSee('Upgrade to Ultra') + ->assertDontSee('on Ultra', escape: false); + } + + #[Test] + public function comped_ultra_price_subscriber_sees_checkout_button() + { + $compedPriceId = 'price_test_comped_ultra'; + + config([ + 'subscriptions.plans.max.stripe_price_id_comped' => $compedPriceId, + ]); + + $user = User::factory()->create(['stripe_id' => 'cus_'.uniqid()]); + Auth::login($user); + + $subscription = Cashier::$subscriptionModel::factory() + ->for($user) + ->active() + ->create([ + 'stripe_price' => $compedPriceId, + ]); + + Cashier::$subscriptionItemModel::factory() + ->for($subscription, 'subscription') + ->create(['stripe_price' => $compedPriceId]); + + Livewire::test(MobilePricing::class) + ->assertSeeHtml('wire:click="createCheckoutSession(\'max\')"') + ->assertDontSee('Upgrade to Ultra') ->assertDontSee('on Ultra', escape: false); }