257 lines
9.7 KiB
PHP
257 lines
9.7 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire;
|
|
|
|
use App\Models\Subscription;
|
|
use App\Models\User;
|
|
use Livewire\Component;
|
|
use Livewire\WithPagination;
|
|
|
|
class SubscriptionManagement extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
public $filters = [
|
|
'search' => '',
|
|
'status' => '',
|
|
'plan' => '',
|
|
'billing_cycle' => '',
|
|
'payment_status' => '',
|
|
];
|
|
|
|
public $showCreateSubscriptionModal = false;
|
|
public $showEditSubscriptionModal = false;
|
|
public $showBillingModal = false;
|
|
public $editingSubscription = null;
|
|
public $selectedSubscription = null;
|
|
public $billingHistory = [];
|
|
|
|
public $subscriptionForm = [
|
|
'user_id' => '',
|
|
'plan' => '',
|
|
'billing_cycle' => '',
|
|
'amount' => '',
|
|
'device_limit' => '',
|
|
'status' => 'active',
|
|
'starts_at' => '',
|
|
'ends_at' => '',
|
|
'next_billing_date' => '',
|
|
'stripe_id' => '',
|
|
'notes' => '',
|
|
];
|
|
|
|
protected $layout = 'layouts.app';
|
|
|
|
public function mount()
|
|
{
|
|
// Initialize component without parameters
|
|
}
|
|
|
|
public function getStatsProperty()
|
|
{
|
|
$activeSubscriptions = Subscription::where('status', 'active')->count();
|
|
$monthlyRevenue = Subscription::where('status', 'active')
|
|
->where('billing_cycle', 'monthly')
|
|
->sum('amount') +
|
|
(Subscription::where('status', 'active')
|
|
->where('billing_cycle', 'yearly')
|
|
->sum('amount') / 12);
|
|
|
|
$expiringSubscriptions = Subscription::where('status', 'active')
|
|
->where('ends_at', '<=', now()->addDays(30))
|
|
->count();
|
|
|
|
$newSubscriptions = Subscription::where('created_at', '>=', now()->startOfMonth())->count();
|
|
|
|
$avgSubscriptionValue = Subscription::where('status', 'active')->avg('amount');
|
|
|
|
return [
|
|
'monthly_revenue' => $monthlyRevenue,
|
|
'revenue_change' => 12.5, // Mock percentage change
|
|
'active_subscriptions' => $activeSubscriptions,
|
|
'new_subscriptions' => $newSubscriptions,
|
|
'expiring_soon' => $expiringSubscriptions,
|
|
'avg_subscription_value' => $avgSubscriptionValue,
|
|
];
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$subscriptions = Subscription::query()
|
|
->with(['user'])
|
|
->when($this->filters['search'], function ($query) {
|
|
$query->whereHas('user', function ($q) {
|
|
$q->where('name', 'like', '%' . $this->filters['search'] . '%')
|
|
->orWhere('email', 'like', '%' . $this->filters['search'] . '%');
|
|
});
|
|
})
|
|
->when($this->filters['status'], function ($query) {
|
|
$query->where('status', $this->filters['status']);
|
|
})
|
|
->when($this->filters['plan'], function ($query) {
|
|
$query->where('plan', $this->filters['plan']);
|
|
})
|
|
->when($this->filters['billing_cycle'], function ($query) {
|
|
$query->where('billing_cycle', $this->filters['billing_cycle']);
|
|
})
|
|
->when($this->filters['payment_status'], function ($query) {
|
|
$query->where('payment_status', $this->filters['payment_status']);
|
|
})
|
|
->orderBy('created_at', 'desc')
|
|
->paginate(15);
|
|
|
|
$users = User::whereDoesntHave('activeSubscription')->get();
|
|
|
|
return view('livewire.subscription-management', [
|
|
'subscriptions' => $subscriptions,
|
|
'users' => $users,
|
|
]);
|
|
}
|
|
|
|
public function editSubscription($subscriptionId)
|
|
{
|
|
$this->editingSubscription = Subscription::with('user')->find($subscriptionId);
|
|
$this->subscriptionForm = [
|
|
'user_id' => $this->editingSubscription->user_id,
|
|
'plan' => $this->editingSubscription->plan,
|
|
'billing_cycle' => $this->editingSubscription->billing_cycle,
|
|
'amount' => $this->editingSubscription->amount,
|
|
'device_limit' => $this->editingSubscription->device_limit,
|
|
'status' => $this->editingSubscription->status,
|
|
'starts_at' => $this->editingSubscription->starts_at?->format('Y-m-d'),
|
|
'ends_at' => $this->editingSubscription->ends_at?->format('Y-m-d'),
|
|
'next_billing_date' => $this->editingSubscription->next_billing_date?->format('Y-m-d'),
|
|
'stripe_id' => $this->editingSubscription->stripe_id,
|
|
'notes' => $this->editingSubscription->notes,
|
|
];
|
|
$this->showEditSubscriptionModal = true;
|
|
}
|
|
|
|
public function createSubscription()
|
|
{
|
|
$this->validate([
|
|
'subscriptionForm.user_id' => 'required|exists:users,id',
|
|
'subscriptionForm.plan' => 'required|string',
|
|
'subscriptionForm.billing_cycle' => 'required|string',
|
|
'subscriptionForm.amount' => 'required|numeric|min:0',
|
|
'subscriptionForm.device_limit' => 'required|integer|min:1',
|
|
]);
|
|
|
|
Subscription::create([
|
|
'user_id' => $this->subscriptionForm['user_id'],
|
|
'plan' => $this->subscriptionForm['plan'],
|
|
'billing_cycle' => $this->subscriptionForm['billing_cycle'],
|
|
'amount' => $this->subscriptionForm['amount'],
|
|
'device_limit' => $this->subscriptionForm['device_limit'],
|
|
'status' => $this->subscriptionForm['status'],
|
|
'starts_at' => $this->subscriptionForm['starts_at'] ? \Carbon\Carbon::parse($this->subscriptionForm['starts_at']) : now(),
|
|
'ends_at' => $this->subscriptionForm['ends_at'] ? \Carbon\Carbon::parse($this->subscriptionForm['ends_at']) : null,
|
|
'next_billing_date' => $this->subscriptionForm['next_billing_date'] ? \Carbon\Carbon::parse($this->subscriptionForm['next_billing_date']) : null,
|
|
'stripe_id' => $this->subscriptionForm['stripe_id'],
|
|
'notes' => $this->subscriptionForm['notes'],
|
|
]);
|
|
|
|
$this->closeSubscriptionModal();
|
|
$this->reset('subscriptionForm');
|
|
session()->flash('message', 'Subscription created successfully.');
|
|
}
|
|
|
|
public function updateSubscription()
|
|
{
|
|
$this->validate([
|
|
'subscriptionForm.plan' => 'required|string',
|
|
'subscriptionForm.billing_cycle' => 'required|string',
|
|
'subscriptionForm.amount' => 'required|numeric|min:0',
|
|
'subscriptionForm.device_limit' => 'required|integer|min:1',
|
|
]);
|
|
|
|
$this->editingSubscription->update([
|
|
'plan' => $this->subscriptionForm['plan'],
|
|
'billing_cycle' => $this->subscriptionForm['billing_cycle'],
|
|
'amount' => $this->subscriptionForm['amount'],
|
|
'device_limit' => $this->subscriptionForm['device_limit'],
|
|
'status' => $this->subscriptionForm['status'],
|
|
'starts_at' => $this->subscriptionForm['starts_at'] ? \Carbon\Carbon::parse($this->subscriptionForm['starts_at']) : $this->editingSubscription->starts_at,
|
|
'ends_at' => $this->subscriptionForm['ends_at'] ? \Carbon\Carbon::parse($this->subscriptionForm['ends_at']) : null,
|
|
'next_billing_date' => $this->subscriptionForm['next_billing_date'] ? \Carbon\Carbon::parse($this->subscriptionForm['next_billing_date']) : null,
|
|
'stripe_id' => $this->subscriptionForm['stripe_id'],
|
|
'notes' => $this->subscriptionForm['notes'],
|
|
]);
|
|
|
|
$this->closeSubscriptionModal();
|
|
$this->reset('subscriptionForm');
|
|
session()->flash('message', 'Subscription updated successfully.');
|
|
}
|
|
|
|
public function cancelSubscription($subscriptionId)
|
|
{
|
|
Subscription::find($subscriptionId)->update(['status' => 'cancelled']);
|
|
session()->flash('message', 'Subscription cancelled successfully.');
|
|
}
|
|
|
|
public function renewSubscription($subscriptionId)
|
|
{
|
|
Subscription::find($subscriptionId)->update(['status' => 'active']);
|
|
session()->flash('message', 'Subscription renewed successfully.');
|
|
}
|
|
|
|
public function viewBilling($subscriptionId)
|
|
{
|
|
$this->selectedSubscription = Subscription::with('user')->find($subscriptionId);
|
|
// Mock billing history - in real app, this would come from payment provider
|
|
$this->billingHistory = collect([
|
|
(object) [
|
|
'created_at' => now()->subMonth(),
|
|
'amount' => $this->selectedSubscription->amount,
|
|
'status' => 'paid',
|
|
'invoice_url' => null,
|
|
],
|
|
(object) [
|
|
'created_at' => now()->subMonths(2),
|
|
'amount' => $this->selectedSubscription->amount,
|
|
'status' => 'paid',
|
|
'invoice_url' => null,
|
|
],
|
|
]);
|
|
$this->showBillingModal = true;
|
|
}
|
|
|
|
public function closeSubscriptionModal()
|
|
{
|
|
$this->showCreateSubscriptionModal = false;
|
|
$this->showEditSubscriptionModal = false;
|
|
$this->editingSubscription = null;
|
|
$this->reset('subscriptionForm');
|
|
}
|
|
|
|
public function closeBillingModal()
|
|
{
|
|
$this->showBillingModal = false;
|
|
$this->selectedSubscription = null;
|
|
$this->billingHistory = [];
|
|
}
|
|
|
|
// Handle legacy method name (backward compatibility)
|
|
public function showSubscriptionformModal($subscriptionId = null)
|
|
{
|
|
if ($subscriptionId) {
|
|
$this->editSubscription($subscriptionId);
|
|
} else {
|
|
$this->showCreateModal = true;
|
|
}
|
|
}
|
|
|
|
// Handle legacy method name (backward compatibility)
|
|
public function showBillinghistoryModal($subscriptionId = null)
|
|
{
|
|
if ($subscriptionId) {
|
|
$this->viewBilling($subscriptionId);
|
|
}
|
|
}
|
|
|
|
public function updatingFilters()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
}
|