user(); $businessId = (int) $user->business_id; $isSelf = $viewer && (int) $viewer->id === (int) $user->id; $isAdmin = $viewer ? $this->moduleUtil->is_admin($viewer, $businessId) : false; $essentialsEnabled = $this->essentialsEnabled($businessId); $user->loadMissing(['media', 'contactAccess', 'assignments.entity', 'assignments.orgUnit', 'roles']); $department = $user->essentials_department_id ? Category::find($user->essentials_department_id) : null; $designation = $user->essentials_designation_id ? Category::find($user->essentials_designation_id) : null; $workLocation = $user->location_id ? BusinessLocation::find($user->location_id) : null; $primaryAssignment = EmploymentAssignment::where('business_id', $businessId) ->where('user_id', $user->id) ->where('is_primary', true) ->with(['entity', 'orgUnit']) ->first(); $holdingContext = $this->holdingHrmSyncService->getUserFormContext($businessId, $user); $monthStart = Carbon::now()->startOfMonth()->format('Y-m-d'); $monthEnd = Carbon::now()->endOfMonth()->format('Y-m-d'); $yearStart = Carbon::now()->startOfYear()->format('Y-m-d'); $yearEnd = Carbon::now()->endOfYear()->format('Y-m-d'); $stats = [ 'logged_hours' => 0, 'open_tasks' => 0, 'approved_leaves' => 0, 'payroll_count' => 0, 'support_tickets' => 0, 'open_support_tickets' => 0, ]; $sidebar = [ 'leaves_taken' => 0, 'late_attendance' => 0, 'open_tasks' => [], 'recent_tickets' => [], ]; $attendanceRows = collect(); $leaveRows = collect(); $taskRows = collect(); $payrollRows = collect(); $ticketRows = collect(); if ($essentialsEnabled && $this->canViewEssentialsData($viewer, $user, $isSelf, $isAdmin)) { $essentialsUtil = app(\Modules\Essentials\Utils\EssentialsUtil::class); $stats['logged_hours'] = (float) str_replace(',', '', $essentialsUtil->getTotalWorkDuration( 'hour', $user->id, $businessId, $monthStart, $monthEnd )); $stats['open_tasks'] = $this->countOpenTasks($user->id); $stats['approved_leaves'] = $this->countApprovedLeaves($businessId, $user->id, $yearStart, $yearEnd); $stats['payroll_count'] = $essentialsUtil->getPayrollQuery($businessId) ->where('transactions.expense_for', $user->id) ->count(); $sidebar['leaves_taken'] = $stats['approved_leaves']; $sidebar['late_attendance'] = $this->countLateAttendance($businessId, $user->id, $yearStart, $yearEnd); $sidebar['open_tasks'] = $this->getOpenTasks($user->id, 5); $attendanceRows = $this->getRecentAttendance($businessId, $user->id, 10); $leaveRows = $this->getRecentLeaves($businessId, $user->id, 10); $taskRows = $this->getOpenTasks($user->id, 20); $payrollRows = $essentialsUtil->getPayrollQuery($businessId) ->where('transactions.expense_for', $user->id) ->orderBy('transaction_date', 'desc') ->limit(10) ->get(); } $ticketsEnabled = $this->ticketsEnabled($businessId); if ($ticketsEnabled && $this->canViewTickets($viewer, $user, $isSelf, $isAdmin)) { $ticketStats = $this->getTicketStats($businessId, $user->id); $stats['support_tickets'] = $ticketStats['total']; $stats['open_support_tickets'] = $ticketStats['open']; $sidebar['recent_tickets'] = $this->getRecentTickets($businessId, $user->id, 5); $ticketRows = $this->getRecentTickets($businessId, $user->id, 20); } $lastActivity = Activity::forSubject($user)->latest()->first(); $lastActivityAt = $lastActivity?->created_at ?? $user->updated_at; $tabs = $this->resolveTabs($essentialsEnabled, $viewer, $user, $isSelf, $isAdmin, $options); $mt_skills = collect(); $mt_scores = collect(); $mt_total_score_points = 0; if ($this->managementToolsEnabled($businessId)) { $mtUtil = app(\Modules\ManagementTools\Utils\ManagementToolsUtil::class); $mt_skills = $mtUtil->getUserSkillsList($businessId, $user->id); $mt_scores = $mtUtil->getUserRecentScores($businessId, $user->id, 6); $mt_total_score_points = $mtUtil->getUserTotalScorePoints($businessId, $user->id); } return [ 'user' => $user, 'employee_id' => 'EMP-'.str_pad((string) $user->id, 3, '0', STR_PAD_LEFT), 'avatar_url' => $this->avatarUrl($user), 'department' => $department, 'designation' => $designation, 'work_location' => $workLocation, 'primary_assignment' => $primaryAssignment ?: $holdingContext['primaryAssignment'], 'holding_url' => $holdingContext['holdingUrl'], 'last_activity_at' => $lastActivityAt, 'stats' => $stats, 'sidebar' => $sidebar, 'attendance_rows' => $attendanceRows, 'leave_rows' => $leaveRows, 'task_rows' => $taskRows, 'payroll_rows' => $payrollRows, 'ticket_rows' => $ticketRows, 'tickets_enabled' => $ticketsEnabled ?? false, 'tickets_url' => ($ticketsEnabled ?? false) ? action([\Modules\ManagementTools\Http\Controllers\TicketController::class, 'index']) : null, 'tabs' => $tabs, 'is_self' => $isSelf, 'can_edit' => $viewer && ($isSelf || $viewer->can('user.update')), 'essentials_enabled' => $essentialsEnabled, 'attendance_url' => $essentialsEnabled ? action([\Modules\Essentials\Http\Controllers\AttendanceController::class, 'index']).'?employee_id='.$user->id : null, 'leaves_url' => $essentialsEnabled ? action([\Modules\Essentials\Http\Controllers\EssentialsLeaveController::class, 'index']).'?user_id='.$user->id : null, 'mt_skills' => $mt_skills, 'mt_scores' => $mt_scores, 'mt_total_score_points' => $mt_total_score_points, 'mt_my_scores_url' => $this->managementToolsEnabled($businessId) ? action([\Modules\ManagementTools\Http\Controllers\ScoreController::class, 'myScores']) : null, 'management_tools_enabled' => $this->managementToolsEnabled($businessId), ]; } private function essentialsEnabled(int $businessId): bool { return $this->moduleUtil->isModuleInstalled('Essentials') && $this->moduleUtil->hasThePermissionInSubscription($businessId, 'essentials_module'); } private function canViewEssentialsData($viewer, User $user, bool $isSelf, bool $isAdmin): bool { if (! $viewer) { return false; } if ($isSelf) { return true; } if ($isAdmin || $viewer->can('essentials.crud_all_attendance')) { return true; } return $viewer->can('user.view'); } private function resolveTabs( bool $essentialsEnabled, $viewer, User $user, bool $isSelf, bool $isAdmin, array $options ): array { $tabs = [ 'profile' => [ 'id' => 'profile_tab', 'label' => __('lang_v1.profile_tab_profile'), 'icon' => 'fa-user', 'enabled' => true, ], ]; if ($essentialsEnabled && $this->canViewEssentialsData($viewer, $user, $isSelf, $isAdmin)) { $tabs['attendance'] = [ 'id' => 'attendance_tab', 'label' => __('lang_v1.profile_tab_attendance'), 'icon' => 'fa-clock', 'enabled' => true, ]; $tabs['leaves'] = [ 'id' => 'leaves_tab', 'label' => __('lang_v1.profile_tab_leaves'), 'icon' => 'fa-plane', 'enabled' => true, ]; $tabs['tasks'] = [ 'id' => 'tasks_tab', 'label' => __('lang_v1.profile_tab_tasks'), 'icon' => 'fa-tasks', 'enabled' => true, ]; if ($isSelf || $isAdmin || ($viewer && $viewer->can('essentials.view_all_payroll'))) { $tabs['payroll'] = [ 'id' => 'payroll_tab', 'label' => __('lang_v1.profile_tab_payroll'), 'icon' => 'fa-money-bill', 'enabled' => true, ]; } } $tabs['documents'] = [ 'id' => 'documents_tab', 'label' => __('lang_v1.profile_tab_documents'), 'icon' => 'fa-paperclip', 'enabled' => true, ]; if ($this->ticketsEnabled((int) $user->business_id) && $this->canViewTickets($viewer, $user, $isSelf, $isAdmin)) { $tabs['tickets'] = [ 'id' => 'tickets_tab', 'label' => __('lang_v1.profile_tab_tickets'), 'icon' => 'fa-life-ring', 'enabled' => true, ]; } if (empty($options['hide_activities'])) { $tabs['activities'] = [ 'id' => 'activities_tab', 'label' => __('lang_v1.profile_tab_activities'), 'icon' => 'fa-history', 'enabled' => true, ]; } if (! empty($options['show_edit_tab'])) { $tabs['edit'] = [ 'id' => 'edit_tab', 'label' => __('lang_v1.profile_tab_edit'), 'icon' => 'fa-edit', 'enabled' => true, ]; $tabs['password'] = [ 'id' => 'password_tab', 'label' => __('user.change_password'), 'icon' => 'fa-lock', 'enabled' => true, ]; } return $tabs; } private function avatarUrl(User $user): string { if (! empty($user->media->display_url)) { return $user->media->display_url; } $palette = ['0074ba', '16cdc7', '36c76c', '7c3aed', 'f97316', 'ff6692', '46caeb', 'e6a800']; $background = $palette[$user->id % count($palette)]; return 'https://ui-avatars.com/api/?name='.urlencode($user->user_full_name).'&background='.$background.'&color=fff&size=200&bold=true'; } private function countOpenTasks(int $userId): int { if (! class_exists(\Modules\Essentials\Entities\ToDo::class)) { return 0; } return \Modules\Essentials\Entities\ToDo::whereHas('users', function ($q) use ($userId) { $q->where('user_id', $userId); })->where('status', '!=', 'completed')->count(); } private function getOpenTasks(int $userId, int $limit) { if (! class_exists(\Modules\Essentials\Entities\ToDo::class)) { return collect(); } return \Modules\Essentials\Entities\ToDo::whereHas('users', function ($q) use ($userId) { $q->where('user_id', $userId); }) ->where('status', '!=', 'completed') ->orderBy('created_at', 'desc') ->limit($limit) ->get(); } private function countApprovedLeaves(int $businessId, int $userId, string $start, string $end): int { if (! class_exists(\Modules\Essentials\Entities\EssentialsLeave::class)) { return 0; } return \Modules\Essentials\Entities\EssentialsLeave::where('business_id', $businessId) ->where('user_id', $userId) ->where('status', 'approved') ->whereDate('start_date', '>=', $start) ->whereDate('start_date', '<=', $end) ->count(); } private function getRecentLeaves(int $businessId, int $userId, int $limit) { if (! class_exists(\Modules\Essentials\Entities\EssentialsLeave::class)) { return collect(); } return \Modules\Essentials\Entities\EssentialsLeave::where('business_id', $businessId) ->where('user_id', $userId) ->with('leave_type') ->orderBy('start_date', 'desc') ->limit($limit) ->get(); } private function getRecentAttendance(int $businessId, int $userId, int $limit) { if (! class_exists(\Modules\Essentials\Entities\EssentialsAttendance::class)) { return collect(); } return \Modules\Essentials\Entities\EssentialsAttendance::where('business_id', $businessId) ->where('user_id', $userId) ->orderBy('clock_in_time', 'desc') ->limit($limit) ->get(); } private function countLateAttendance(int $businessId, int $userId, string $start, string $end): int { if (! class_exists(\Modules\Essentials\Entities\EssentialsAttendance::class)) { return 0; } try { return \Modules\Essentials\Entities\EssentialsAttendance::query() ->from('essentials_attendances as ea') ->join('essentials_shifts as es', 'es.id', '=', 'ea.essentials_shift_id') ->where('ea.business_id', $businessId) ->where('ea.user_id', $userId) ->whereNotNull('ea.clock_in_time') ->whereNotNull('es.start_time') ->whereDate('ea.clock_in_time', '>=', $start) ->whereDate('ea.clock_in_time', '<=', $end) ->whereRaw('TIME(ea.clock_in_time) > ADDTIME(es.start_time, "00:15:00")') ->count(); } catch (\Throwable $e) { return 0; } } private function ticketsEnabled(int $businessId): bool { return $this->managementToolsEnabled($businessId) && class_exists(\Modules\ManagementTools\Entities\MtUserTicket::class); } private function managementToolsEnabled(int $businessId): bool { return $this->moduleUtil->isModuleInstalled('ManagementTools') && $this->moduleUtil->hasThePermissionInSubscription($businessId, 'managementtools_module'); } private function canViewTickets($viewer, User $user, bool $isSelf, bool $isAdmin): bool { if (! $viewer) { return false; } if ($isSelf) { return $viewer->can('managementtools.ticket_own') || $viewer->can('managementtools.ticket_manage'); } if ($isAdmin || $viewer->can('managementtools.ticket_manage')) { return true; } return $viewer->can('user.view'); } private function getTicketStats(int $businessId, int $userId): array { $base = \Modules\ManagementTools\Entities\MtUserTicket::forBusiness($businessId) ->where('user_id', $userId); return [ 'total' => (clone $base)->count(), 'open' => (clone $base)->open()->count(), ]; } private function getRecentTickets(int $businessId, int $userId, int $limit) { return \Modules\ManagementTools\Entities\MtUserTicket::forBusiness($businessId) ->where('user_id', $userId) ->with('assignee') ->orderByDesc('updated_at') ->limit($limit) ->get(); } }