gps_system/app/Livewire/SubscriptionManagement.php
sackey 6b878bb0a0
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
Initial commit
2025-09-12 16:19:56 +00:00

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();
}
}