fix: shift fill_rate percentage and seeder status consistency

fill_rate accessor returned decimal (0.33) instead of percentage (33),
causing progress bars to display at ~1% width. DevSeeder hard-coded
status='full' on EHBO za_dag despite only 1/4 slots filled, and factory
assignments now respect slots_open_for_claiming. Added post-assignment
status auto-correction based on actual fill counts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-10 20:11:35 +02:00
parent c21bc085e9
commit c220446920
2 changed files with 18 additions and 7 deletions

View File

@@ -111,7 +111,7 @@ final class Shift extends Model
return 0; return 0;
} }
return round($this->filled_slots / $this->slots_total, 2); return (int) round(($this->filled_slots / $this->slots_total) * 100);
}); });
} }

View File

@@ -328,14 +328,13 @@ class DevSeeder extends Seeder
// EHBO: 6 shifts across volunteer time slots // EHBO: 6 shifts across volunteer time slots
foreach (['vr_early', 'vr_avond', 'za_dag', 'za_avond', 'zo_dag', 'zo_avond'] as $key) { foreach (['vr_early', 'vr_avond', 'za_dag', 'za_avond', 'zo_dag', 'zo_avond'] as $key) {
$isFull = $key === 'za_dag';
$shift = Shift::create([ $shift = Shift::create([
'festival_section_id' => $ehbo->id, 'festival_section_id' => $ehbo->id,
'time_slot_id' => $ts[$key]->id, 'time_slot_id' => $ts[$key]->id,
'title' => 'EHBO Post', 'title' => 'EHBO Post',
'slots_total' => $isFull ? 4 : 3, 'slots_total' => $key === 'za_dag' ? 4 : 3,
'slots_open_for_claiming' => $isFull ? 0 : 2, 'slots_open_for_claiming' => $key === 'za_dag' ? 0 : 2,
'status' => $isFull ? 'full' : 'open', 'status' => 'open',
]); ]);
$allShifts[] = $shift; $allShifts[] = $shift;
$s["ehbo_{$key}"] = $shift; $s["ehbo_{$key}"] = $shift;
@@ -669,7 +668,7 @@ class DevSeeder extends Seeder
->where('status', 'approved') ->where('status', 'approved')
->get(); ->get();
$openShifts = collect($allShifts)->filter(fn (Shift $shift) => $shift->status === 'open'); $openShifts = collect($allShifts)->filter(fn (Shift $shift) => $shift->status === 'open' && $shift->slots_open_for_claiming > 0);
$statusPool = array_merge( $statusPool = array_merge(
array_fill(0, 75, ShiftAssignmentStatus::APPROVED), array_fill(0, 75, ShiftAssignmentStatus::APPROVED),
@@ -724,6 +723,18 @@ class DevSeeder extends Seeder
$assignmentCount = ShiftAssignment::whereIn('shift_id', collect($allShifts)->pluck('id'))->count(); $assignmentCount = ShiftAssignment::whereIn('shift_id', collect($allShifts)->pluck('id'))->count();
$this->command->info(" {$assignmentCount} shift assignments created"); $this->command->info(" {$assignmentCount} shift assignments created");
// Auto-correct shift statuses based on actual fill
foreach ($allShifts as $shift) {
$filled = ShiftAssignment::where('shift_id', $shift->id)
->whereIn('status', [ShiftAssignmentStatus::APPROVED, ShiftAssignmentStatus::COMPLETED])
->count();
$correctStatus = $filled >= $shift->slots_total ? 'full' : 'open';
if ($shift->status !== $correctStatus) {
$shift->update(['status' => $correctStatus]);
}
}
// ── Volunteer availabilities (~70) ── // ── Volunteer availabilities (~70) ──
$volSlotKeys = ['vr_early', 'vr_avond', 'za_dag', 'za_avond', 'zo_dag', 'zo_avond']; $volSlotKeys = ['vr_early', 'vr_avond', 'za_dag', 'za_avond', 'zo_dag', 'zo_avond'];
@@ -978,7 +989,7 @@ class DevSeeder extends Seeder
// ── Shift assignments (~80) ── // ── Shift assignments (~80) ──
$openShifts = collect($allShifts)->filter(fn (Shift $shift) => $shift->status === 'open'); $openShifts = collect($allShifts)->filter(fn (Shift $shift) => $shift->status === 'open' && $shift->slots_open_for_claiming > 0);
$draftShifts = collect($allShifts)->filter(fn (Shift $shift) => $shift->status === 'draft'); $draftShifts = collect($allShifts)->filter(fn (Shift $shift) => $shift->status === 'draft');
$allApproved = $approvedVol->merge($approvedCrew); $allApproved = $approvedVol->merge($approvedCrew);