163 خطوط
5.9 KiB
PHP
163 خطوط
5.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Project;
|
|
use App\Models\Task;
|
|
use App\Models\Meeting;
|
|
use App\Models\ActivityLog;
|
|
use App\Models\Sprint;
|
|
use Carbon\Carbon;
|
|
|
|
class DashboardService
|
|
{
|
|
public function getSummary($user = null)
|
|
{
|
|
$activeProjects = Project::where('status', '!=', 'done')->where('is_archived', false)->count();
|
|
$completedProjects = Project::where('status', 'done')->count();
|
|
$today = Carbon::today();
|
|
$delayedProjects = Project::whereDate('end_date', '<', $today)->where('status', '!=', 'done')->where('is_archived', false)->count();
|
|
|
|
$openTasks = Task::whereNotIn('status', ['done', 'canceled'])->count();
|
|
$completedTasks = Task::where('status', 'done')->count();
|
|
$delayedTasks = Task::whereDate('due_date', '<', $today)->where('status', '!=', 'done')->count();
|
|
|
|
$teamPerformance = [];
|
|
$workload = [];
|
|
|
|
$riskyProjects = Project::whereIn('risk_level', ['high', 'critical'])->where('is_archived', false)->limit(5)->get();
|
|
|
|
$upcomingDeadlines = Task::with('project')
|
|
->whereDate('due_date', '>=', $today)
|
|
->whereDate('due_date', '<=', $today->copy()->addDays(7))
|
|
->where('status', '!=', 'done')
|
|
->orderBy('due_date')
|
|
->limit(10)
|
|
->get()
|
|
->map(fn($t) => [
|
|
'id' => $t->id,
|
|
'title' => $t->title,
|
|
'project' => $t->project?->title,
|
|
'due_date' => $t->due_date?->format('Y-m-d'),
|
|
'days_left' => $today->diffInDays($t->due_date, false),
|
|
]);
|
|
|
|
$recentActivities = ActivityLog::with('user')
|
|
->orderBy('created_at', 'desc')
|
|
->limit(10)
|
|
->get()
|
|
->map(fn($log) => [
|
|
'id' => $log->id,
|
|
'description' => $log->description,
|
|
'user' => $log->user?->name ?? '?',
|
|
'created_at' => $log->created_at?->toDateTimeString(),
|
|
'time_ago' => $log->created_at?->diffForHumans(),
|
|
]);
|
|
|
|
$myTasks = collect();
|
|
if ($user) {
|
|
$myTasks = Task::where('assignee_id', $user->id)
|
|
->where('status', '!=', 'done')
|
|
->orderBy('due_date')
|
|
->limit(10)
|
|
->get();
|
|
}
|
|
|
|
$activeSprint = null;
|
|
if ($user) {
|
|
$sprint = Sprint::with(['project', 'tasks.assignee'])
|
|
->where('status', 'active')
|
|
->whereHas('members', fn($query) => $query->where('users.id', $user->id))
|
|
->orderBy('end_date')
|
|
->first();
|
|
|
|
if ($sprint) {
|
|
$totalTasks = $sprint->tasks->count();
|
|
$completedTasks = $sprint->tasks->where('status', 'done')->count();
|
|
$activeSprint = [
|
|
'id' => $sprint->id,
|
|
'title' => $sprint->title,
|
|
'project' => $sprint->project?->title,
|
|
'end_date' => $sprint->end_date?->format('Y-m-d'),
|
|
'remaining_days' => max(Carbon::today()->diffInDays($sprint->end_date, false), 0),
|
|
'progress' => $totalTasks > 0 ? round(($completedTasks / $totalTasks) * 100, 2) : 0,
|
|
'my_tasks' => $sprint->tasks
|
|
->where('assignee_id', $user->id)
|
|
->values()
|
|
->map(fn($task) => [
|
|
'id' => $task->id,
|
|
'title' => $task->title,
|
|
'status' => $task->status,
|
|
]),
|
|
];
|
|
}
|
|
}
|
|
|
|
$todayMeetings = Meeting::whereDate('date', Carbon::today())->count();
|
|
$teamMembers = \App\Models\User::count();
|
|
|
|
$projectProgresses = Project::where('is_archived', false)
|
|
->select(['id', 'title', 'progress', 'status'])
|
|
->limit(10)
|
|
->get();
|
|
|
|
return [
|
|
'activeProjects' => $activeProjects,
|
|
'completedProjects' => $completedProjects,
|
|
'delayedProjects' => $delayedProjects,
|
|
'openTasks' => $openTasks,
|
|
'completedTasks' => $completedTasks,
|
|
'delayedTasks' => $delayedTasks,
|
|
'teamPerformance' => $teamPerformance,
|
|
'workload' => $workload,
|
|
'riskyProjects' => $riskyProjects,
|
|
'upcomingDeadlines' => $upcomingDeadlines,
|
|
'recentActivities' => $recentActivities,
|
|
'myTasks' => $myTasks,
|
|
'todayMeetings' => $todayMeetings,
|
|
'teamMembers' => $teamMembers,
|
|
'projectProgresses' => $projectProgresses,
|
|
'activeSprint' => $activeSprint,
|
|
];
|
|
}
|
|
|
|
public function getChartData()
|
|
{
|
|
$months = collect();
|
|
$taskCreationData = [];
|
|
$taskCompletionData = [];
|
|
|
|
for ($i = 5; $i >= 0; $i--) {
|
|
$month = Carbon::now()->subMonths($i);
|
|
$monthName = $month->format('Y-m');
|
|
$months->push($monthName);
|
|
|
|
$taskCreationData[] = Task::whereYear('created_at', $month->year)
|
|
->whereMonth('created_at', $month->month)
|
|
->count();
|
|
|
|
$taskCompletionData[] = Task::where('status', 'done')
|
|
->whereYear('updated_at', $month->year)
|
|
->whereMonth('updated_at', $month->month)
|
|
->count();
|
|
}
|
|
|
|
$monthlyTasks = [];
|
|
foreach ($months as $i => $month) {
|
|
$monthlyTasks[] = [
|
|
'month' => $month,
|
|
'created' => $taskCreationData[$i],
|
|
'completed' => $taskCompletionData[$i],
|
|
];
|
|
}
|
|
|
|
return [
|
|
'labels' => $months->values(),
|
|
'taskCreation' => $taskCreationData,
|
|
'taskCompletion' => $taskCompletionData,
|
|
'monthlyTasks' => $monthlyTasks,
|
|
'monthly_tasks' => $monthlyTasks,
|
|
];
|
|
}
|
|
}
|