Update open registrations management

This commit is contained in:
DariusIII
2026-03-11 11:51:59 +01:00
parent 4bca02f103
commit e9414a61e6
8 changed files with 384 additions and 81 deletions
@@ -0,0 +1,60 @@
<?php
declare(strict_types=1);
namespace App\Console\Commands;
use App\Services\RegistrationStatusService;
use Illuminate\Console\Command;
class DisableExpiredRegistrationPeriods extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'nntmux:disable-expired-registration-periods';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Disable completed registration periods and mark them as done';
public function __construct(
private readonly RegistrationStatusService $registrationStatusService
) {
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle(): int
{
$expiredPeriods = $this->registrationStatusService->disableExpiredPeriods();
if ($expiredPeriods->isEmpty()) {
$this->info('No expired registration periods found.');
return Command::SUCCESS;
}
foreach ($expiredPeriods as $period) {
$this->line(sprintf(
'Marked registration period as done: %s (ended: %s)',
$period->name,
$period->ends_at->format('Y-m-d H:i')
));
}
$this->info(sprintf(
'Successfully completed %d expired registration period(s).',
$expiredPeriods->count()
));
return Command::SUCCESS;
}
}
@@ -29,7 +29,10 @@ class AdminRegistrationController extends BasePageController
public function index(Request $request): View|RedirectResponse
{
$now = now();
$this->setAdminPrefs();
$this->registrationStatusService->disableExpiredPeriods($now);
$editingPeriod = null;
if ($request->filled('edit_period')) {
@@ -44,11 +47,21 @@ class AdminRegistrationController extends BasePageController
}
}
$status = $this->registrationStatusService->resolve();
$status = $this->registrationStatusService->resolve($now);
$periods = RegistrationPeriod::query()
->with(['createdByUser', 'updatedByUser'])
->orderByDesc('starts_at')
->get();
[$pastPeriods, $currentPeriods] = $periods->partition(
fn (RegistrationPeriod $period): bool => $period->hasEndedAt($now)
);
$currentPeriods = $currentPeriods
->sortBy(fn (RegistrationPeriod $period): int => $period->starts_at?->getTimestamp() ?? PHP_INT_MAX)
->values();
$pastPeriods = $pastPeriods
->sortByDesc(fn (RegistrationPeriod $period): int => $period->ends_at?->getTimestamp() ?? 0)
->values();
$history = RegistrationStatusHistory::query()
->with(['changedByUser', 'registrationPeriod'])
->orderByDesc('created_at')
@@ -87,7 +100,8 @@ class AdminRegistrationController extends BasePageController
'meta_description' => 'Manage registration status, scheduled open periods, and registration activity.',
'registrationStatus' => $status,
'statusOptions' => $this->registrationStatusService->statusOptions(),
'periods' => $periods,
'currentPeriods' => $currentPeriods,
'pastPeriods' => $pastPeriods,
'editingPeriod' => $editingPeriod,
'history' => $history,
'recentSuccessfulRegistrations' => $recentSuccessfulRegistrations,
@@ -158,6 +172,14 @@ class AdminRegistrationController extends BasePageController
/** @var User|null $admin */
$admin = Auth::user();
if ($period->hasEndedAt()) {
$this->registrationStatusService->disableExpiredPeriods();
return redirect()
->route('admin.registrations.index')
->with('success', 'That scheduled open-registration period has already passed and is now marked as done.');
}
$this->registrationStatusService->togglePeriod(
$period,
$admin,
+7
View File
@@ -83,4 +83,11 @@ class RegistrationPeriod extends Model
&& $this->starts_at->lte($at)
&& $this->ends_at->gte($at);
}
public function hasEndedAt(?CarbonInterface $at = null): bool
{
$at ??= now();
return $this->ends_at !== null && $this->ends_at->lt($at);
}
}
+2
View File
@@ -17,6 +17,8 @@ class RegistrationStatusHistory extends Model
public const ACTION_PERIOD_TOGGLED = 'period_toggled';
public const ACTION_PERIOD_COMPLETED = 'period_completed';
public const ACTION_PERIOD_DELETED = 'period_deleted';
protected $table = 'registration_status_history';
@@ -9,6 +9,7 @@ use App\Models\RegistrationStatusHistory;
use App\Models\Settings;
use App\Models\User;
use Carbon\CarbonInterface;
use Illuminate\Support\Collection;
class RegistrationStatusService
{
@@ -220,6 +221,41 @@ class RegistrationStatusService
return $period;
}
/**
* @return Collection<int, RegistrationPeriod>
*/
public function disableExpiredPeriods(?CarbonInterface $at = null): Collection
{
$at ??= now();
$expiredPeriods = RegistrationPeriod::query()
->where('is_enabled', true)
->where('ends_at', '<', $at)
->get();
foreach ($expiredPeriods as $period) {
$period->forceFill([
'is_enabled' => false,
'updated_by' => null,
])->save();
RegistrationStatusHistory::record(
RegistrationStatusHistory::ACTION_PERIOD_COMPLETED,
sprintf('Scheduled open period "%s" completed after reaching its end time.', $period->name),
null,
null,
null,
$period->id,
[
'completed_at' => $at->toDateTimeString(),
'period' => $this->serializePeriod($period),
]
);
}
return $expiredPeriods;
}
public function deletePeriod(RegistrationPeriod $period, ?User $changedBy = null, ?string $note = null): void
{
$snapshot = $this->serializePeriod($period);