validate([ 'status' => ['nullable', 'in:active,inactive'], 'area_id' => ['nullable', 'integer'], 'q' => ['nullable', 'string', 'max:100'], 'per_page' => ['nullable', 'integer', 'min:1', 'max:100'], ]); $perPage = (int) $request->input('per_page', 25); $teams = CollectionTeam::query() ->with(['area', 'driver', 'scanner', 'truck']) ->when($request->filled('status'), fn ($q) => $q->where('status', $request->string('status'))) ->when($request->filled('area_id'), fn ($q) => $q->where('area_id', $request->integer('area_id'))) ->when($request->filled('q'), fn ($q) => $q->where('name', 'like', '%'.$request->string('q').'%')) ->orderBy('name') ->paginate($perPage); return $this->ok( CollectionTeamResource::collection($teams), null, [ 'page' => $teams->currentPage(), 'per_page' => $teams->perPage(), 'total' => $teams->total(), 'last_page' => $teams->lastPage(), ], ); } public function store(StoreCollectionTeamRequest $request): JsonResponse { $data = $request->validated(); $helperIds = $data['helper_ids'] ?? []; $override = (bool) ($data['override_conflicts'] ?? false); unset($data['helper_ids'], $data['override_conflicts']); if (! $override) { $conflicts = $this->conflicts->check( $data['driver_id'] ?? null, $data['scanner_id'] ?? null, $data['truck_id'] ?? null, $helperIds, ); if (! empty($conflicts)) { return $this->fail('Team has assignment conflicts', ['conflicts' => $conflicts], 422); } } $team = DB::transaction(function () use ($data, $helperIds) { $team = CollectionTeam::create($data); $today = now()->toDateString(); foreach ($helperIds as $uid) { TeamMember::create([ 'team_id' => $team->id, 'user_id' => $uid, 'role_in_team' => TeamMember::ROLE_HELPER, 'assigned_from' => $today, ]); } return $team; }); return $this->created( new CollectionTeamResource( $team->fresh()->load(['area', 'driver', 'scanner', 'truck', 'helpers.user']), ), 'Team created', ); } public function show(CollectionTeam $team): JsonResponse { $team->load(['area', 'driver', 'scanner', 'truck', 'helpers.user']); return $this->ok(new CollectionTeamResource($team)); } public function update(StoreCollectionTeamRequest $request, CollectionTeam $team): JsonResponse { $data = $request->validated(); $helperIds = $data['helper_ids'] ?? null; $override = (bool) ($data['override_conflicts'] ?? false); unset($data['helper_ids'], $data['override_conflicts']); if (! $override) { $conflicts = $this->conflicts->check( $data['driver_id'] ?? $team->driver_id, $data['scanner_id'] ?? $team->scanner_id, $data['truck_id'] ?? $team->truck_id, $helperIds ?? [], $team->id, ); if (! empty($conflicts)) { return $this->fail('Team has assignment conflicts', ['conflicts' => $conflicts], 422); } } DB::transaction(function () use ($team, $data, $helperIds) { $team->update($data); if ($helperIds !== null) { $today = now()->toDateString(); $team->members()->where('role_in_team', TeamMember::ROLE_HELPER)->delete(); foreach ($helperIds as $uid) { TeamMember::create([ 'team_id' => $team->id, 'user_id' => $uid, 'role_in_team' => TeamMember::ROLE_HELPER, 'assigned_from' => $today, ]); } } }); return $this->ok( new CollectionTeamResource( $team->fresh()->load(['area', 'driver', 'scanner', 'truck', 'helpers.user']), ), 'Team updated', ); } public function destroy(CollectionTeam $team): JsonResponse { $team->delete(); return $this->ok(null, 'Team deleted'); } }