mivita/app/Models/PaymentIncident.php
2026-04-14 18:07:45 +02:00

156 lines
4 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class PaymentIncident extends Model
{
protected $fillable = [
'title',
'description',
'notes',
'provider',
'type',
'status',
'severity',
'affected_orders',
'affected_revenue',
'detected_at',
'resolved_at',
'ticket_number',
];
/** @var array<string, mixed> */
protected $attributes = [
'status' => 'open',
'severity' => 'medium',
'provider' => 'payone',
];
protected function casts(): array
{
return [
'detected_at' => 'datetime',
'resolved_at' => 'datetime',
'affected_revenue' => 'decimal:2',
];
}
public function activities(): HasMany
{
return $this->hasMany(IncidentActivity::class, 'incident_id')->orderBy('created_at');
}
public function scopeOpen(Builder $query): Builder
{
return $query->whereIn('status', ['open', 'in_progress', 'waiting_provider']);
}
public function scopePayone(Builder $query): Builder
{
return $query->where('provider', 'payone');
}
public function scopeLastDays(Builder $query, int $days): Builder
{
return $query->where('detected_at', '>=', now()->subDays($days));
}
public function getDurationAttribute(): string
{
$end = $this->resolved_at ?? now();
$diff = $this->detected_at->diff($end);
if ($diff->days > 0) {
return $diff->days.'d '.$diff->h.'h';
}
if ($diff->h > 0) {
return $diff->h.'h '.$diff->i.'min';
}
return $diff->i.' min';
}
public function getSeverityColorAttribute(): string
{
return match ($this->severity) {
'critical' => 'danger',
'high' => 'warning',
'medium' => 'info',
'low' => 'success',
default => 'secondary',
};
}
public function getSeverityLabelAttribute(): string
{
return match ($this->severity) {
'critical' => 'Kritisch',
'high' => 'Hoch',
'medium' => 'Mittel',
'low' => 'Niedrig',
default => $this->severity,
};
}
public function getStatusLabelAttribute(): string
{
return match ($this->status) {
'open' => 'Offen',
'in_progress' => 'In Bearbeitung',
'waiting_provider' => 'Wartet auf Anbieter',
'resolved' => 'Gelöst',
'closed' => 'Geschlossen',
default => $this->status,
};
}
public function getStatusColorAttribute(): string
{
return match ($this->status) {
'open' => 'danger',
'in_progress' => 'warning',
'waiting_provider' => 'info',
'resolved' => 'success',
'closed' => 'secondary',
default => 'secondary',
};
}
public function getTypeIconAttribute(): string
{
return match ($this->type) {
'outage' => 'ion-md-power',
'ipn_error' => 'ion-md-git-network',
'payment_failure' => 'ion-md-card',
'slow_response' => 'ion-md-timer',
default => 'ion-md-alert',
};
}
public function getTypeLabelAttribute(): string
{
return match ($this->type) {
'outage' => 'Ausfall',
'ipn_error' => 'IPN-Fehler',
'payment_failure' => 'Zahlungsfehler',
'slow_response' => 'Langsame Antwort',
default => 'Sonstiges',
};
}
public function getProviderLabelAttribute(): string
{
return match ($this->provider) {
'payone' => 'PAYONE',
// 'stripe' => 'Stripe', // aktuell nicht aktiv
'paypal' => 'PayPal',
// 'mollie' => 'Mollie', // aktuell nicht aktiv
default => 'Sonstige',
};
}
}