119 lines
4.8 KiB
PHP
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'
|
|
));
|
|
}
|
|
}
|