PM_Console/backend/app/Http/Controllers/Api/TaskController.php

369 خطوط
13 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Requests\StoreTaskRequest;
use App\Http\Requests\UpdateTaskRequest;
use App\Http\Resources\TaskResource;
use App\Models\Task;
use App\Services\ActivityLogService;
use App\Services\NotificationService;
use App\Services\ProjectProgressService;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function __construct(
protected ActivityLogService $activityLogService,
protected NotificationService $notificationService,
protected ProjectProgressService $projectProgressService,
) {}
public function index(Request $request): JsonResponse
{
try {
$query = Task::with(['project', 'assignee', 'reporter'])->withCount(['comments', 'files']);
if ($request->filled('project_id')) {
$query->where('project_id', $request->project_id);
}
if ($request->filled('assignee_id')) {
$query->where('assignee_id', $request->assignee_id);
}
if ($request->filled('status')) {
$query->where('status', $request->status);
}
if ($request->filled('priority')) {
$query->where('priority', $request->priority);
}
if ($request->filled('search')) {
$search = $request->search;
$query->where('title', 'like', "%{$search}%");
}
$perPage = min((int) $request->input('per_page', 15), 100);
$sortBy = in_array($request->input('sort_by'), ['id', 'title', 'status', 'priority', 'created_at', 'updated_at', 'due_date', 'sort_order'], true)
? $request->input('sort_by')
: 'created_at';
$sortDir = $request->input('sort_dir') === 'asc' ? 'asc' : 'desc';
$tasks = $query->orderBy($sortBy, $sortDir)->paginate($perPage);
return response()->json([
'success' => true,
'data' => TaskResource::collection($tasks),
'meta' => [
'current_page' => $tasks->currentPage(),
'last_page' => $tasks->lastPage(),
'per_page' => $tasks->perPage(),
'total' => $tasks->total(),
],
'message' => 'لیست وظایف',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در دریافت لیست وظایف',
], 500);
}
}
public function show(Task $task): JsonResponse
{
try {
$task->load(['project', 'assignee', 'reporter', 'checklists', 'subtasks', 'comments.user', 'files']);
return response()->json([
'success' => true,
'data' => new TaskResource($task),
'message' => 'اطلاعات وظیفه',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در دریافت اطلاعات وظیفه',
], 500);
}
}
public function store(StoreTaskRequest $request): JsonResponse
{
try {
$data = $request->validated();
$data['reporter_id'] = $request->user()->id;
$data['created_by'] = $request->user()->id;
$task = Task::create($data);
$this->projectProgressService->calculateProgress($task->project_id);
$this->activityLogService->log(
$request->user()->id,
'create_task',
"وظیفه {$task->title} ایجاد شد",
'task',
$task->id,
$task->project_id,
$task->id,
['task_title' => $task->title]
);
if ($task->assignee_id) {
$this->notificationService->create(
$task->assignee_id,
'task_assigned',
[
'task_id' => $task->id,
'project_id' => $task->project_id,
'url' => '/kanban',
'notifiable_type' => 'App\\Models\\Task',
'notifiable_id' => $task->id,
],
"وظیفه جدید {$task->title} به شما اختصاص داده شد"
);
}
$task->load(['project', 'assignee', 'reporter']);
return response()->json([
'success' => true,
'data' => new TaskResource($task),
'message' => 'وظیفه با موفقیت ایجاد شد',
], 201);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در ایجاد وظیفه',
], 500);
}
}
public function update(UpdateTaskRequest $request, Task $task): JsonResponse
{
try {
$oldStatus = $task->status;
$task->update($request->validated());
if ($task->wasChanged('status')) {
$this->activityLogService->log(
$request->user()->id,
'update_task_status',
"وضعیت وظیفه {$task->title} از {$oldStatus} به {$task->status} تغییر یافت",
'task',
$task->id,
$task->project_id,
$task->id,
['old_status' => $oldStatus, 'new_status' => $task->status]
);
}
$this->projectProgressService->calculateProgress($task->project_id);
$task->load(['project', 'assignee', 'reporter']);
return response()->json([
'success' => true,
'data' => new TaskResource($task->fresh()),
'message' => 'وظیفه با موفقیت به‌روزرسانی شد',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در به‌روزرسانی وظیفه',
], 500);
}
}
public function destroy(Request $request, Task $task): JsonResponse
{
try {
$projectId = $task->project_id;
$taskId = $task->id;
$taskTitle = $task->title;
$this->activityLogService->log(
$request->user()->id,
'delete_task',
"وظیفه {$taskTitle} حذف شد",
'task',
$taskId,
$projectId,
null,
['task_title' => $taskTitle]
);
$task->delete();
$this->projectProgressService->calculateProgress($projectId);
return response()->json([
'success' => true,
'message' => 'وظیفه با موفقیت حذف شد',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در حذف وظیفه',
], 500);
}
}
public function updateStatus(Request $request, Task $task): JsonResponse
{
try {
$request->validate(['status' => 'required|string']);
$oldStatus = $task->status;
$task->update(['status' => $request->status]);
$this->projectProgressService->calculateProgress($task->project_id);
$this->activityLogService->log(
$request->user()->id,
'update_task_status',
"وضعیت وظیفه {$task->title} از {$oldStatus} به {$task->status} تغییر یافت",
'task',
$task->id,
$task->project_id,
$task->id,
['old_status' => $oldStatus, 'new_status' => $task->status]
);
if ($task->assignee_id) {
$this->notificationService->create(
$task->assignee_id,
'task_status_changed',
['task_id' => $task->id, 'status' => $task->status],
"وضعیت وظیفه {$task->title} به {$task->status} تغییر یافت"
);
}
return response()->json([
'success' => true,
'data' => new TaskResource($task->fresh()->load(['project', 'assignee'])),
'message' => 'وضعیت وظیفه به‌روزرسانی شد',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در به‌روزرسانی وضعیت',
], 500);
}
}
public function updateAssignee(Request $request, Task $task): JsonResponse
{
try {
$request->validate(['assignee_id' => 'nullable|exists:users,id']);
$oldAssigneeId = $task->assignee_id;
$task->update(['assignee_id' => $request->assignee_id]);
if ($request->assignee_id && $request->assignee_id != $oldAssigneeId) {
$this->notificationService->create(
$request->assignee_id,
'task_assigned',
[
'task_id' => $task->id,
'project_id' => $task->project_id,
'url' => '/kanban',
'notifiable_type' => 'App\\Models\\Task',
'notifiable_id' => $task->id,
],
"وظیفه {$task->title} به شما اختصاص داده شد"
);
}
$this->activityLogService->log(
$request->user()->id,
'update_task_assignee',
"مسئول وظیفه {$task->title} تغییر یافت",
'task',
$task->id,
$task->project_id,
$task->id,
['old_assignee' => $oldAssigneeId, 'new_assignee' => $request->assignee_id]
);
return response()->json([
'success' => true,
'data' => new TaskResource($task->fresh()->load(['project', 'assignee'])),
'message' => 'مسئول وظیفه به‌روزرسانی شد',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در به‌روزرسانی مسئول',
], 500);
}
}
public function reorder(Request $request): JsonResponse
{
try {
$request->validate([
'tasks' => 'required|array',
'tasks.*.id' => 'required|exists:tasks,id',
'tasks.*.sort_order' => 'required|integer',
]);
foreach ($request->tasks as $item) {
Task::where('id', $item['id'])->update(['sort_order' => $item['sort_order']]);
}
return response()->json([
'success' => true,
'message' => 'ترتیب وظایف به‌روزرسانی شد',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در مرتب‌سازی وظایف',
], 500);
}
}
public function myTasks(Request $request): JsonResponse
{
try {
$tasks = Task::with(['project', 'assignee'])
->where('assignee_id', $request->user()->id)
->where('status', '!=', 'done')
->orderBy('due_date')
->get();
return response()->json([
'success' => true,
'data' => TaskResource::collection($tasks),
'message' => 'وظایف من',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در دریافت وظایف من',
], 500);
}
}
public function delayedTasks(): JsonResponse
{
try {
$tasks = Task::with(['project', 'assignee'])
->where('due_date', '<', Carbon::now())
->where('status', '!=', 'done')
->orderBy('due_date')
->get();
return response()->json([
'success' => true,
'data' => TaskResource::collection($tasks),
'message' => 'وظایف عقب افتاده',
]);
} catch (\Exception $e) {
return response()->json([
'success' => false,
'message' => 'خطا در دریافت وظایف عقب افتاده',
], 500);
}
}
}