verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('view', [$person, $event]); $availabilities = VolunteerAvailability::where('person_id', $person->id) ->with('timeSlot') ->get() ->map(fn (VolunteerAvailability $a) => [ 'id' => $a->id, 'time_slot_id' => $a->time_slot_id, 'preference_level' => $a->preference_level, 'submitted_at' => $a->submitted_at?->toIso8601String(), 'time_slot' => $a->timeSlot ? [ 'id' => $a->timeSlot->id, 'name' => $a->timeSlot->name, 'date' => $a->timeSlot->date?->toDateString(), 'start_time' => $a->timeSlot->start_time, 'end_time' => $a->timeSlot->end_time, ] : null, ]); return response()->json(['data' => $availabilities]); } /** * @throws ValidationException */ public function sync(SyncVolunteerAvailabilityRequest $request, Organisation $organisation, Event $event, Person $person): JsonResponse { $this->verifyEventBelongsToOrganisation($organisation, $event); Gate::authorize('update', [$person, $event]); $availabilities = $request->validated('availabilities'); // Validate all time_slot_ids belong to the event (or parent festival) $validTimeSlotIds = $event->getAllRelevantTimeSlots()->pluck('id')->toArray(); $invalidSlots = collect($availabilities) ->pluck('time_slot_id') ->diff($validTimeSlotIds); if ($invalidSlots->isNotEmpty()) { throw ValidationException::withMessages([ 'availabilities' => ['Een of meer tijdsloten behoren niet tot dit evenement.'], ]); } // Validate time slots have person_type matching the person's crowd_type system_type $personSystemType = $person->crowdType?->system_type; if ($personSystemType !== null) { $requestedSlotIds = collect($availabilities)->pluck('time_slot_id')->toArray(); $mismatchedSlots = TimeSlot::whereIn('id', $requestedSlotIds) ->where('person_type', '!=', $personSystemType) ->exists(); if ($mismatchedSlots) { throw ValidationException::withMessages([ 'availabilities' => ['Een of meer tijdsloten komen niet overeen met het type van deze persoon.'], ]); } } // Delete existing availabilities for this person VolunteerAvailability::where('person_id', $person->id)->delete(); // Create new availabilities $now = now(); foreach ($availabilities as $item) { VolunteerAvailability::create([ 'person_id' => $person->id, 'time_slot_id' => $item['time_slot_id'], 'preference_level' => $item['preference_level'] ?? 3, 'submitted_at' => $now, ]); } activity('volunteer_availability') ->causedBy($request->user()) ->performedOn($person) ->withProperties([ 'count' => count($availabilities), 'time_slot_ids' => collect($availabilities)->pluck('time_slot_id')->toArray(), ]) ->log('volunteer_availability.synced'); return $this->success(null, 'Beschikbaarheid opgeslagen.'); } }