vernova/app/Http/Controllers/DashboardController.php
2026-07-26 19:58:27 +03:30

119 lines
4.8 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Helpers\CurrencyHelper;
use App\Helpers\CalendarHelper;
use App\Helpers\NumberHelper;
use App\Models\Project;
use App\Models\Task;
use App\Models\Employee;
use App\Models\Expense;
use App\Models\AuditLog;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
class DashboardController extends Controller
{
/**
* Display the dashboard with KPIs, recent activities, and project progress.
* All data is tenant-scoped via global scope.
*/
public function index()
{
$user = Auth::user();
$tenantId = $this->getTenantId();
$baseCurrency = CurrencyHelper::getBaseCurrency();
$currencyCode = $baseCurrency?->code ?? config('projectra.defaults.currency', 'IRR');
// --- KPIs ---
$activeProjectsCount = Project::whereIn('status', ['planning', 'active'])->count();
$totalBudget = Project::whereIn('status', ['planning', 'active'])
->sum('budget');
$pendingTasksCount = Task::where('status', 'pending')->count();
$activeEmployeesCount = Employee::where('status', 'active')->count();
// Budget in base currency
$totalBudgetFormatted = CurrencyHelper::formatWithSymbol((float) $totalBudget, $currencyCode);
// --- Trends (compare with previous month) ---
$lastMonthStart = now()->subMonth()->startOfMonth();
$lastMonthEnd = now()->subMonth()->endOfMonth();
$lastMonthProjects = Project::whereBetween('created_at', [$lastMonthStart, $lastMonthEnd])->count();
$thisMonthProjects = Project::whereBetween('created_at', [now()->startOfMonth(), now()->endOfMonth()])->count();
$projectTrend = $lastMonthProjects > 0
? round((($thisMonthProjects - $lastMonthProjects) / $lastMonthProjects) * 100, 1)
: ($thisMonthProjects > 0 ? 100 : 0);
$lastMonthTasks = Task::whereBetween('created_at', [$lastMonthStart, $lastMonthEnd])->count();
$thisMonthTasks = Task::whereBetween('created_at', [now()->startOfMonth(), now()->endOfMonth()])->count();
$taskTrend = $lastMonthTasks > 0
? round((($thisMonthTasks - $lastMonthTasks) / $lastMonthTasks) * 100, 1)
: ($thisMonthTasks > 0 ? 100 : 0);
$lastMonthExpenses = Expense::whereBetween('expense_date', [$lastMonthStart, $lastMonthEnd])
->where('status', 'approved')->sum('amount');
$thisMonthExpenses = Expense::whereBetween('expense_date', [now()->startOfMonth(), now()->endOfMonth()])
->where('status', 'approved')->sum('amount');
$expenseTrend = $lastMonthExpenses > 0
? round((($thisMonthExpenses - $lastMonthExpenses) / $lastMonthExpenses) * 100, 1)
: ($thisMonthExpenses > 0 ? 100 : 0);
$lastMonthEmployees = Employee::whereBetween('hire_date', [$lastMonthStart, $lastMonthEnd])->count();
$thisMonthEmployees = Employee::whereBetween('hire_date', [now()->startOfMonth(), now()->endOfMonth()])->count();
$employeeTrend = $lastMonthEmployees > 0
? round((($thisMonthEmployees - $lastMonthEmployees) / $lastMonthEmployees) * 100, 1)
: ($thisMonthEmployees > 0 ? 100 : 0);
// --- Project Progress ---
$projectsInProgress = Project::whereIn('status', ['active', 'planning'])
->with(['manager', 'tasks'])
->orderBy('progress', 'desc')
->limit(5)
->get();
// --- Recent Activities ---
$recentActivities = AuditLog::where('tenant_id', $tenantId)
->with('user')
->orderBy('created_at', 'desc')
->limit(8)
->get();
// --- Tasks by status for current user ---
$myTasks = Task::where('assignee_id', $user->id)
->whereNotIn('status', ['done', 'cancelled'])
->with('project')
->orderBy('due_date', 'asc')
->limit(5)
->get();
// --- Calendar & i18n info ---
$currentCalendar = session('calendar', config('projectra.default_calendar', 'jalali'));
$currentLocale = app()->getLocale();
$todayDisplay = CalendarHelper::getCurrentDate($currentCalendar);
if ($currentLocale === 'fa') {
$todayDisplay = persian_num($todayDisplay);
}
return view('dashboard.index', compact(
'activeProjectsCount',
'totalBudget',
'totalBudgetFormatted',
'pendingTasksCount',
'activeEmployeesCount',
'projectTrend',
'taskTrend',
'expenseTrend',
'employeeTrend',
'projectsInProgress',
'recentActivities',
'myTasks',
'currentCalendar',
'currentLocale',
'todayDisplay',
'currencyCode'
));
}
}