validated(); $query = Task::with(['assignee:id,name,avatar', 'assigner:id,name', 'creator:id,name', 'taskable', 'parent:id,subject']); AccessControl::scopeTasks($query, $request->user()); foreach (['status', 'priority', 'assigned_to', 'created_by'] as $filter) { if (array_key_exists($filter, $validated)) { $query->where($filter, $validated[$filter]); } } if (! empty($validated['due_from'])) { $query->where('due_at', '>=', $validated['due_from']); } if (! empty($validated['due_to'])) { $query->where('due_at', '<=', $validated['due_to']); } if ($request->boolean('overdue')) { $query->active()->whereNotNull('due_at')->where('due_at', '<', now()); } if (! empty($validated['taskable_type'])) { $query->where('taskable_type', EntityResolver::classFor($validated['taskable_type'])); } if (! empty($validated['taskable_id'])) { $query->where('taskable_id', $validated['taskable_id']); } if (! empty($validated['search'])) { $search = trim($validated['search']); $query->where(fn ($searchQuery) => $searchQuery ->where('subject', 'like', "%{$search}%") ->orWhere('description', 'like', "%{$search}%")); } [$sortColumn, $sortDirection] = $this->sort($validated['sort'] ?? '-created_at'); $paginator = $query->orderBy($sortColumn, $sortDirection)->paginate((int) ($validated['per_page'] ?? 20)); return ApiResponse::paginated($paginator, fn (Task $task) => $this->resource($task)); } public function store(StoreTaskRequest $request): JsonResponse { Gate::authorize('create', Task::class); $task = $this->service->create($request->validated(), $request->user()); return ApiResponse::success($this->resource($task), 201, 'کار ایجاد شد.'); } public function show(Task $task): JsonResponse { Gate::authorize('view', $task); return ApiResponse::success($this->resource($task->load(['assignee:id,name,avatar', 'assigner:id,name', 'creator:id,name', 'taskable', 'parent:id,subject']))); } public function update(UpdateTaskRequest $request, Task $task): JsonResponse { Gate::authorize('update', $task); $updated = $this->service->update($task, $request->validated(), $request->user()); return ApiResponse::success($this->resource($updated), message: 'کار ویرایش شد.'); } public function destroy(Task $task): JsonResponse { Gate::authorize('delete', $task); $this->service->delete($task); return ApiResponse::success(null, message: 'کار حذف شد.'); } public function assign(AssignTaskRequest $request, Task $task): JsonResponse { Gate::authorize('assign', [$task, (int) $request->validated('assigned_to')]); $updated = $this->service->assign($task, (int) $request->validated('assigned_to'), (int) $request->validated('version'), $request->user()); return ApiResponse::success($this->resource($updated), message: 'مسئول کار تغییر کرد.'); } public function start(Request $request, Task $task): JsonResponse { $validated = $request->validate(['version' => 'required|integer|min:1']); $updated = $this->service->transition($task, TaskStatus::InProgress, (int) $validated['version'], $request->user()); return ApiResponse::success($this->resource($updated), message: 'کار شروع شد.'); } public function complete(Request $request, Task $task): JsonResponse { $validated = $request->validate(['version' => 'required|integer|min:1']); $updated = $this->service->transition($task, TaskStatus::Done, (int) $validated['version'], $request->user()); return ApiResponse::success($this->resource($updated), message: 'کار تکمیل شد.'); } public function reopen(Request $request, Task $task): JsonResponse { $validated = $request->validate(['version' => 'required|integer|min:1']); $updated = $this->service->transition($task, TaskStatus::Open, (int) $validated['version'], $request->user()); return ApiResponse::success($this->resource($updated), message: 'کار بازگشایی شد.'); } public function cancel(Request $request, Task $task): JsonResponse { $validated = $request->validate(['version' => 'required|integer|min:1']); $updated = $this->service->transition($task, TaskStatus::Cancelled, (int) $validated['version'], $request->user()); return ApiResponse::success($this->resource($updated), message: 'کار لغو شد.'); } public function bulkAssign(Request $request): JsonResponse { $validated = $request->validate([ 'task_ids' => 'required|array|min:1|max:100', 'task_ids.*' => 'required|integer|distinct', 'assigned_to' => 'required|integer|exists:users,id', ]); $tasks = $this->service->bulkAssign($validated['task_ids'], (int) $validated['assigned_to'], $request->user()); return ApiResponse::success(array_map(fn (Task $task) => $this->resource($task), $tasks), message: 'کارها تخصیص داده شدند.'); } public function bulkComplete(Request $request): JsonResponse { $validated = $request->validate([ 'task_ids' => 'required|array|min:1|max:100', 'task_ids.*' => 'required|integer|distinct', ]); $tasks = $this->service->bulkComplete($validated['task_ids'], $request->user()); return ApiResponse::success(array_map(fn (Task $task) => $this->resource($task), $tasks), message: 'کارها تکمیل شدند.'); } private function resource(Task $task): array { return (new TaskResource($task))->resolve(request()); } private function sort(string $sort): array { return str_starts_with($sort, '-') ? [substr($sort, 1), 'desc'] : [$sort, 'asc']; } }