123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- <?php
- namespace App\Services\Project;
- use App\Http\Resources\API\ProjectGanttResource;
- use App\Http\Resources\API\ProjectGroupViewTaskResource;
- use App\Models\Enums\ProjectStatus;
- use App\Models\Project;
- use App\Models\Requirement;
- use App\Models\Task;
- use App\Models\User;
- use Carbon\Carbon;
- use Illuminate\Support\Collection;
- class ProjectGanttService
- {
- public function gantt(Project $project, string $group): array
- {
- $groupTasks = $this->getGroupTask($project, $group);
- $groups = $groupTasks->keys()->filter();
- $groupNamesKeyBy = $this->getGroupNamesKeyBy($groups, $group);
- $items = [];
- foreach(["", ...$groups] as $groupKey) {
- if (! isset($groupTasks[$groupKey])) {
- continue;
- }
- $treeTasks = make_tree($groupTasks[$groupKey]->toArray());
- $groupUniqueKey = uniqid();
- $items[] = $this->topGroupFormat(
- $groupUniqueKey,
- isset($groupNamesKeyBy[$groupKey]) ? $groupNamesKeyBy[$groupKey]['name'] : "Empty"
- );
- $tasks = $this->flattenTasks($treeTasks);
- foreach ($tasks as $task) {
- $items[] = $this->taskFormat($task, $groupUniqueKey);
- }
- }
- return $items;
- }
- protected function topGroupFormat(string $id, string $name)
- {
- return [
- 'id' => $id,
- 'text' => $name,
- 'parent' => 0,
- 'start_date' => null,
- 'end_date' => null,
- 'duration' => null,
- 'progress' => 0,
- 'assign_to' => null,
- 'open' => true,
- ];
- }
- protected function taskFormat(array $task, string $topId)
- {
- $progress = 0;
- $begin = $task['begin'] ? Carbon::parse($task['begin']) : Carbon::parse($task['created_at']);
- $end = $task['end'] ? Carbon::parse($task['end']) : $begin->copy()->addYears(2);
- $now = Carbon::now();
- if ($now->gt($end)) {
- $progress = 1;
- }
- if ($now->gt($begin) && $end->gt($now)) {
- $totalDay = $end->diffInDays($begin);
- $day = $now->diffInDays($begin);
- $progress = (float)number_format($day / $totalDay, 4);
- }
- return [
- 'id' => $task['id'],
- 'text' => $task['name'],
- 'parent' => $task['parent_id'] > 0 ? $task['parent_id'] : $topId ,
- 'start_date' => $task['begin'],
- 'end_date' => $task['end'],
- 'duration' => $end->diffInDays($begin),
- 'progress' => $progress,
- 'assign_to' =>$task['assign']?User::query()->where('id',$task['assign'])->first()->name:null,
- 'open' => true,
- ];
- }
- protected function flattenTasks($tasks) {
- $items = [];
- foreach ($tasks as $task) {
- $items[] = $task;
- if (!empty($task['children'])) {
- $items = array_merge($items, $this->flattenTasks($task['children']));
- }
- unset($task['children']);
- }
- return $items;
- }
- protected function getGroupNamesKeyBy(Collection $groups, string $group): array
- {
- $groupsFormat = $groups->map(fn($group) => ['id' => $group, 'name' => $group]);
- $groupNames = match ($group) {
- "requirement_id" => Requirement::query()->whereIn("id", $groups)->selectRaw("id,title as name")->get(),
- "task_type" => $groupsFormat,
- "assign" => User::query()->whereIn("id", $groups)->get(['id', 'name']),
- };
- return $groupNames->keyBy("id")->toArray();
- }
- protected function getGroupTask(
- Project $project,
- string $group,
- ): \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|array
- {
- return Task::query()
- ->with(['assignTo', 'finishedBy'])
- ->where("project_id", $project->id)
- ->get()
- ->groupBy($group);
- }
- }
|