mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-28 22:01:33 +00:00
172 lines
4.6 KiB
PHP
172 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Models;
|
|
|
|
use Carbon\Carbon;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Spatie\Permission\Models\Role;
|
|
|
|
/**
|
|
* App\Models\RolePromotionStat
|
|
*
|
|
* @property int $id
|
|
* @property int $user_id
|
|
* @property int $role_promotion_id
|
|
* @property int $role_id
|
|
* @property int $days_added
|
|
* @property Carbon|null $previous_expiry_date
|
|
* @property Carbon|null $new_expiry_date
|
|
* @property Carbon $applied_at
|
|
* @property Carbon|null $created_at
|
|
* @property Carbon|null $updated_at
|
|
* @property-read User $user
|
|
* @property-read RolePromotion $promotion
|
|
* @property-read Role $role
|
|
*/
|
|
class RolePromotionStat extends Model
|
|
{
|
|
protected $fillable = [
|
|
'user_id',
|
|
'role_promotion_id',
|
|
'role_id',
|
|
'days_added',
|
|
'previous_expiry_date',
|
|
'new_expiry_date',
|
|
'applied_at',
|
|
];
|
|
|
|
protected $casts = [
|
|
'days_added' => 'integer',
|
|
'previous_expiry_date' => 'datetime',
|
|
'new_expiry_date' => 'datetime',
|
|
'applied_at' => 'datetime',
|
|
];
|
|
|
|
/**
|
|
* Get the user that received the promotion
|
|
*
|
|
* @return BelongsTo<User, $this>
|
|
*/
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
/**
|
|
* Get the promotion that was applied
|
|
*
|
|
* @return BelongsTo<RolePromotion, $this>
|
|
*/
|
|
public function promotion(): BelongsTo
|
|
{
|
|
return $this->belongsTo(RolePromotion::class, 'role_promotion_id');
|
|
}
|
|
|
|
/**
|
|
* Get the role that was upgraded
|
|
*/
|
|
public function role(): BelongsTo // @phpstan-ignore missingType.generics
|
|
{
|
|
return $this->belongsTo(Role::class);
|
|
}
|
|
|
|
/**
|
|
* Scope to get stats for a specific promotion
|
|
*/
|
|
public function scopeForPromotion(mixed $query, int $promotionId): mixed
|
|
{
|
|
return $query->where('role_promotion_id', $promotionId);
|
|
}
|
|
|
|
/**
|
|
* Scope to get stats for a specific user
|
|
*/
|
|
public function scopeForUser(mixed $query, int $userId): mixed
|
|
{
|
|
return $query->where('user_id', $userId);
|
|
}
|
|
|
|
/**
|
|
* Scope to get stats for a specific role
|
|
*/
|
|
public function scopeForRole(mixed $query, int $roleId): mixed
|
|
{
|
|
return $query->where('role_id', $roleId);
|
|
}
|
|
|
|
/**
|
|
* Scope to get stats within a date range
|
|
*/
|
|
public function scopeAppliedBetween(mixed $query, mixed $startDate, mixed $endDate): mixed
|
|
{
|
|
return $query->whereBetween('applied_at', [$startDate, $endDate]);
|
|
}
|
|
|
|
/**
|
|
* Get statistics summary for a promotion
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public static function getPromotionSummary(int $promotionId): array
|
|
{
|
|
$stats = static::forPromotion($promotionId)->get();
|
|
|
|
return [
|
|
'total_upgrades' => $stats->count(),
|
|
'total_days_added' => $stats->sum('days_added'),
|
|
'unique_users' => $stats->unique('user_id')->count(),
|
|
'roles_affected' => $stats->unique('role_id')->count(),
|
|
'latest_application' => $stats->max('applied_at'),
|
|
'earliest_application' => $stats->min('applied_at'),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Get statistics summary for a user
|
|
*
|
|
* @return array<string, mixed>
|
|
*/
|
|
public static function getUserSummary(int $userId): array
|
|
{
|
|
$stats = static::forUser($userId)->get();
|
|
|
|
return [
|
|
'total_promotions_received' => $stats->count(),
|
|
'total_days_added' => $stats->sum('days_added'),
|
|
'promotions' => $stats->groupBy('role_promotion_id')->map(function ($group) {
|
|
return [
|
|
'promotion_id' => $group->first()->role_promotion_id,
|
|
'promotion_name' => $group->first()->promotion->name,
|
|
'times_applied' => $group->count(),
|
|
'total_days' => $group->sum('days_added'),
|
|
];
|
|
})->values()->all(),
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Record a promotion application
|
|
*/
|
|
public static function recordPromotion(
|
|
int $userId,
|
|
int $promotionId,
|
|
int $roleId,
|
|
int $daysAdded,
|
|
?Carbon $previousExpiryDate = null,
|
|
?Carbon $newExpiryDate = null
|
|
): self {
|
|
return static::create([
|
|
'user_id' => $userId,
|
|
'role_promotion_id' => $promotionId,
|
|
'role_id' => $roleId,
|
|
'days_added' => $daysAdded,
|
|
'previous_expiry_date' => $previousExpiryDate,
|
|
'new_expiry_date' => $newExpiryDate,
|
|
'applied_at' => now(),
|
|
]);
|
|
}
|
|
}
|