69 lines
2.2 KiB
PHP
69 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace Modules\TimelineScheduling\Services;
|
|
|
|
use Illuminate\Support\Collection;
|
|
use Modules\ProjectManagement\Models\Task;
|
|
use Modules\TimelineScheduling\Models\TaskDependency;
|
|
|
|
class GanttDataTransformer
|
|
{
|
|
/**
|
|
* Transform project tasks + dependencies into Gantt-chart-ready JSON.
|
|
* Compatible with Frappe Gantt / similar chart libraries.
|
|
*/
|
|
public function transform(int $projectId): array
|
|
{
|
|
$tasks = Task::where('project_id', $projectId)
|
|
->select('id', 'ulid', 'name', 'status', 'start_date', 'end_date', 'priority')
|
|
->orderBy('start_date')
|
|
->get();
|
|
|
|
$dependencies = TaskDependency::whereIn('task_id', $tasks->pluck('id'))
|
|
->get()
|
|
->groupBy('task_id');
|
|
|
|
$ganttTasks = $tasks->map(function (Task $task) use ($dependencies) {
|
|
$deps = $dependencies->get($task->id, collect());
|
|
$depStrings = $deps->map(fn($d) => "task-{$d->predecessor_id}")->implode(', ');
|
|
|
|
return [
|
|
'id' => "task-{$task->id}",
|
|
'name' => $task->name,
|
|
'start' => $task->start_date?->format('Y-m-d') ?? now()->format('Y-m-d'),
|
|
'end' => $task->end_date?->format('Y-m-d') ?? now()->addDays(7)->format('Y-m-d'),
|
|
'progress' => $this->statusToProgress($task->status),
|
|
'dependencies' => $depStrings ?: null,
|
|
'custom_class' => $this->statusToClass($task->status),
|
|
'meta' => [
|
|
'task_id' => $task->id,
|
|
'status' => $task->status,
|
|
'priority' => $task->priority,
|
|
],
|
|
];
|
|
});
|
|
|
|
return $ganttTasks->values()->toArray();
|
|
}
|
|
|
|
private function statusToProgress(string $status): int
|
|
{
|
|
return match ($status) {
|
|
'completed' => 100,
|
|
'in_progress' => 50,
|
|
'on_hold' => 25,
|
|
default => 0,
|
|
};
|
|
}
|
|
|
|
private function statusToClass(string $status): string
|
|
{
|
|
return match ($status) {
|
|
'completed' => 'bar-completed',
|
|
'in_progress' => 'bar-in-progress',
|
|
'on_hold' => 'bar-on-hold',
|
|
default => 'bar-pending',
|
|
};
|
|
}
|
|
}
|