152 lines
7 KiB
PHP
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;
|
|
}
|
|
}
|