mivita/dev/payment-dashboard/app/Http/Controllers/PaymentDashboardController.php
2026-04-14 18:07:45 +02:00

152 lines
7 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\IncidentActivity;
use App\Models\PaymentIncident;
use Illuminate\Http\Request;
class PaymentDashboardController extends Controller
{
// ─── GF-Ansicht (Alois) ───────────────────────────────────────────────────
public function management()
{
$stats = $this->getStats();
$recentIncidents = PaymentIncident::orderBy('detected_at', 'desc')->take(5)->get();
$openIncidents = PaymentIncident::whereIn('status', ['open', 'in_progress', 'waiting_provider'])->get();
$providerStats = $this->getProviderStats();
return view('dashboard.management', compact('stats', 'recentIncidents', 'openIncidents', 'providerStats'));
}
// ─── Entwickler-Ansicht (Kevin) ───────────────────────────────────────────
public function developer()
{
$stats = $this->getStats();
$allIncidents = PaymentIncident::with('activities')->orderBy('detected_at', 'desc')->paginate(20);
$openIncidents = PaymentIncident::whereIn('status', ['open', 'in_progress', 'waiting_provider'])->with('activities')->get();
$providerStats = $this->getProviderStats();
$recentActivity = IncidentActivity::with('incident')->orderBy('created_at', 'desc')->take(10)->get();
return view('dashboard.developer', compact('stats', 'allIncidents', 'openIncidents', 'providerStats', 'recentActivity'));
}
// ─── Incident erstellen ───────────────────────────────────────────────────
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string',
'provider' => 'required|in:payone,stripe,paypal,mollie,other',
'type' => 'required|in:outage,ipn_error,payment_failure,slow_response,other',
'severity' => 'required|in:low,medium,high,critical',
'affected_orders' => 'nullable|integer|min:0',
'affected_revenue' => 'nullable|numeric|min:0',
'ticket_number' => 'nullable|string|max:100',
'detected_at' => 'required|date',
]);
$incident = PaymentIncident::create($validated);
// Erste Aktivität automatisch anlegen
IncidentActivity::create([
'incident_id' => $incident->id,
'type' => 'note',
'title' => 'Incident eröffnet',
'content' => $validated['description'] ?? null,
'author' => auth()->user()->name ?? 'Kevin',
]);
return redirect()->route('payment-dashboard.developer')
->with('success', 'Incident erfolgreich angelegt.');
}
// ─── Aktivität hinzufügen ─────────────────────────────────────────────────
public function addActivity(Request $request, PaymentIncident $incident)
{
$validated = $request->validate([
'type' => 'required|in:note,email,call,ticket,status_change,provider_response',
'title' => 'required|string|max:255',
'content' => 'nullable|string',
]);
IncidentActivity::create([
'incident_id' => $incident->id,
'type' => $validated['type'],
'title' => $validated['title'],
'content' => $validated['content'] ?? null,
'author' => auth()->user()->name ?? 'Kevin',
]);
// Status automatisch auf "in_progress" setzen wenn noch offen
if ($incident->status === 'open') {
$incident->update(['status' => 'in_progress']);
}
return back()->with('success', 'Aktivität hinzugefügt.');
}
// ─── Status ändern ────────────────────────────────────────────────────────
public function updateStatus(Request $request, PaymentIncident $incident)
{
$request->validate(['status' => 'required|in:open,in_progress,waiting_provider,resolved,closed']);
$oldStatus = $incident->status_label;
$incident->update([
'status' => $request->status,
'resolved_at' => in_array($request->status, ['resolved', 'closed']) ? now() : null,
]);
IncidentActivity::create([
'incident_id' => $incident->id,
'type' => 'status_change',
'title' => 'Status geändert: '.$oldStatus.' → '.$incident->fresh()->status_label,
'author' => auth()->user()->name ?? 'Kevin',
]);
return back()->with('success', 'Status aktualisiert.');
}
// ─── Incident Detail ──────────────────────────────────────────────────────
public function show(PaymentIncident $incident)
{
$incident->load('activities');
return view('dashboard.show', compact('incident'));
}
// ─── Helpers ──────────────────────────────────────────────────────────────
private function getStats(): array
{
return [
'open_incidents' => PaymentIncident::whereIn('status', ['open', 'waiting_provider'])->count(),
'in_progress' => PaymentIncident::where('status', 'in_progress')->count(),
'resolved_this_month' => PaymentIncident::where('status', 'resolved')
->whereMonth('resolved_at', now()->month)->count(),
'total_affected_revenue' => PaymentIncident::whereIn('status', ['open', 'in_progress', 'waiting_provider'])
->sum('affected_revenue'),
'payone_incidents_30d' => PaymentIncident::where('provider', 'payone')
->where('detected_at', '>=', now()->subDays(30))->count(),
];
}
private function getProviderStats(): array
{
$providers = ['payone', 'stripe', 'paypal', 'mollie'];
$stats = [];
foreach ($providers as $provider) {
$stats[$provider] = [
'label' => strtoupper($provider),
'open_incidents' => PaymentIncident::where('provider', $provider)
->whereIn('status', ['open', 'in_progress', 'waiting_provider'])->count(),
'total_30d' => PaymentIncident::where('provider', $provider)
->where('detected_at', '>=', now()->subDays(30))->count(),
'last_incident' => PaymentIncident::where('provider', $provider)
->orderBy('detected_at', 'desc')->first(),
];
}
return $stats;
}
}