feat: implement comprehensive dashboard controller and modular administrative and project management interfaces
Some checks failed
Tests / PHP 8.3 (push) Has been cancelled
Tests / PHP 8.4 (push) Has been cancelled
Tests / PHP 8.5 (push) Has been cancelled

This commit is contained in:
Ajjj
2026-08-03 18:28:52 +08:00
parent 42ba980f7a
commit 936ae1c6b2
48 changed files with 1832 additions and 385 deletions

View File

@@ -52,6 +52,10 @@ class DashboardController extends Controller
// Fetch Resources
$resources = $this->getResourcesData($selectedProject);
// Fetch Role-Tailored DB Analytics
$user = Auth::user();
$roleAnalytics = $this->getRoleAnalyticsData($user, $selectedProject);
return Inertia::render('Dashboard', [
'projects' => $projects,
'selectedProject' => $selectedProject ? [
@@ -66,6 +70,7 @@ class DashboardController extends Controller
'activities' => $activities,
'blockers' => $blockers,
'resources' => $resources,
'roleAnalytics' => $roleAnalytics,
]);
}
@@ -355,4 +360,89 @@ class DashboardController extends Controller
]
];
}
/**
* Compute role-tailored analytics metrics from database tables.
*/
private function getRoleAnalyticsData(?\App\Models\User $user, ?Project $project): array
{
$roleName = $user ? ($user->roles->first()?->name ?? 'User') : 'User';
$userType = $user->user_type ?? 'employee';
$pQuery = function ($query) use ($project) {
if ($project) {
$query->where('project_id', $project->id);
}
};
// 1. Executive / Super Admin / Admin Analytics
$invoicesQuery = \Modules\FinancialManagement\Models\FinancialInvoice::query();
if ($project) {
$invoicesQuery->where('project_id', $project->id);
}
$totalBilled = (float) $invoicesQuery->sum('subtotal');
$totalPaid = (float) $invoicesQuery->sum('paid_amount');
$totalRetention = (float) $invoicesQuery->sum('retention_amount');
$pendingApprovalsCount = \Modules\ApprovalWorkflow\Models\ApprovalChain::where('status', 'in_review')->count();
$totalProjectsCount = Project::count();
$activeProjectsCount = Project::where('status', 'active')->count();
// 2. PM Milestone & Progress Analytics
$milestonesQuery = \Modules\TimelineScheduling\Models\Milestone::query();
if ($project) {
$milestonesQuery->where('project_id', $project->id);
}
$totalMilestones = $milestonesQuery->count();
$completedMilestones = (clone $milestonesQuery)->where('status', 'completed')->count();
$inProgressMilestones = (clone $milestonesQuery)->where('status', 'in_progress')->count();
// 3. Subcontractor / Bidding Analytics
$bidsQuery = \Modules\BiddingManagement\Models\BidPackage::query();
if ($project) {
$bidsQuery->where('project_id', $project->id);
}
$activeBids = $bidsQuery->count();
$openInvitations = \Modules\BiddingManagement\Models\BidInvitation::where('status', 'sent')->count();
// 4. Warehouse & Technical Inventory
$totalItems = \Modules\MasterData\Models\Material::count();
$totalWarehouses = \Modules\MaterialLogistics\Models\Warehouse::count();
$totalDocuments = \Modules\DocumentManagement\Models\Document::count();
$pendingCashAdvances = \Modules\FinancialManagement\Models\CashAdvance::where('status', 'pending')->count();
return [
'role' => $roleName,
'user_type' => $userType,
'financials' => [
'total_billed' => $totalBilled,
'total_paid' => $totalPaid,
'total_retention' => $totalRetention,
'outstanding_balance' => max(0, $totalBilled - $totalPaid),
],
'projects' => [
'total' => $totalProjectsCount,
'active' => $activeProjectsCount,
],
'approvals' => [
'pending' => $pendingApprovalsCount,
],
'milestones' => [
'total' => $totalMilestones,
'completed' => $completedMilestones,
'in_progress' => $inProgressMilestones,
'completion_rate' => $totalMilestones > 0 ? round(($completedMilestones / $totalMilestones) * 100, 1) : 0,
],
'bidding' => [
'active_packages' => $activeBids,
'open_invitations' => $openInvitations,
],
'logistics' => [
'catalog_items' => $totalItems,
'warehouses' => $totalWarehouses,
'documents' => $totalDocuments,
'pending_cash_advances' => $pendingCashAdvances,
],
];
}
}