SubscriptionPlan::count(), 'active_plans' => SubscriptionPlan::where('is_active', true)->count(), 'active_subscriptions' => UserSubscription::where('status', 'active')->count(), 'total_revenue' => Invoice::where('status', 'paid')->sum('amount'), 'pending_invoices' => Invoice::where('status', 'pending')->count(), 'expiring_soon' => UserSubscription::where('status', 'active') ->where('end_date', '<=', now()->addDays(7)) ->count(), ]; $plans = SubscriptionPlan::withCount('userSubscriptions')->get(); $subscriptions = UserSubscription::with(['user', 'plan']) ->orderByDesc('created_at') ->paginate(20); return view('superadmin.billing.index', compact('stats', 'plans', 'subscriptions')); } public function storePlan(Request $request): RedirectResponse { $validated = $request->validate([ 'name' => ['required', 'string', 'max:255'], 'description' => ['nullable', 'string'], 'price' => ['required', 'numeric', 'min:0'], 'currency' => ['required', 'string', 'size:3'], 'duration_days' => ['required', 'integer', 'min:1'], 'token_limit' => ['nullable', 'integer', 'min:0'], ]); SubscriptionPlan::create($validated + ['is_active' => true]); return back()->with('success', __('Plan created successfully.')); } public function updatePlan(Request $request, SubscriptionPlan $plan): RedirectResponse { $validated = $request->validate([ 'name' => ['required', 'string', 'max:255'], 'description' => ['nullable', 'string'], 'price' => ['required', 'numeric', 'min:0'], 'currency' => ['required', 'string', 'size:3'], 'duration_days' => ['required', 'integer', 'min:1'], 'token_limit' => ['nullable', 'integer', 'min:0'], 'is_active' => ['boolean'], ]); $plan->update($validated); return back()->with('success', __('Plan updated successfully.')); } public function approvePayment(UserSubscription $subscription): RedirectResponse { $subscription->update(['payment_approved' => true, 'status' => 'active']); // Create invoice $lastInvoice = Invoice::orderByDesc('id')->first(); $nextNumber = $lastInvoice ? (int)filter_var($lastInvoice->invoice_number, FILTER_SANITIZE_NUMBER_INT) + 1 : 1001; $invoice = Invoice::create([ 'user_id' => $subscription->user_id, 'user_subscription_id' => $subscription->id, 'invoice_number' => 'INV-' . $nextNumber . '/' . now()->year, 'amount' => $subscription->plan->price, 'currency' => $subscription->plan->currency, 'status' => 'paid', 'payment_method' => 'manual', 'paid_at' => now(), ]); // Generate PDF $this->generateInvoicePdf($invoice); // Notify user UserNotification::create([ 'user_id' => $subscription->user_id, 'type' => 'payment_received', 'title' => __('Payment Approved'), 'message' => __('Your payment of :amount has been approved. Your subscription is active until :date.', [ 'amount' => 'R$ ' . number_format($subscription->plan->price, 2, ',', '.'), 'date' => $subscription->end_date->format('d/m/Y'), ]), ]); return back()->with('success', __('Payment approved. Invoice generated and user notified.')); } public function cancelSubscription(UserSubscription $subscription): RedirectResponse { $subscription->update(['status' => 'cancelled', 'cancelled_at' => now()]); UserNotification::create([ 'user_id' => $subscription->user_id, 'type' => 'admin_message', 'title' => __('Subscription Cancelled'), 'message' => __('Your subscription has been cancelled by the administrator.'), ]); return back()->with('success', __('Subscription cancelled.')); } public function invoices(): View { $invoices = Invoice::with(['user', 'subscription.plan']) ->orderByDesc('created_at') ->paginate(20); return view('superadmin.billing.invoices', compact('invoices')); } public function downloadInvoice(Invoice $invoice) { if ($invoice->pdf_path && Storage::exists($invoice->pdf_path)) { return Storage::download($invoice->pdf_path, "invoice-{$invoice->invoice_number}.pdf"); } // Generate on the fly $this->generateInvoicePdf($invoice); return Storage::download($invoice->pdf_path, "invoice-{$invoice->invoice_number}.pdf"); } private function generateInvoicePdf(Invoice $invoice): void { $pdf = Pdf::loadView('pdf.invoice', compact('invoice')); $path = "invoices/invoice-{$invoice->invoice_number}.pdf"; Storage::put($path, $pdf->output()); $invoice->update(['pdf_path' => $path]); } }