diff --git a/app/Enums/Role.php b/app/Enums/Role.php index 23f05d1..9fb885b 100644 --- a/app/Enums/Role.php +++ b/app/Enums/Role.php @@ -261,12 +261,10 @@ public function permissions(): array self::ADMIN_BAHAN_BAKU => [ Permission::DASHBOARD_VIEW, - Permission::DASHBOARD_ATTENDANCE, Permission::ANALYSIS_VIEW, Permission::ANALYSIS_ATTENDANCE, Permission::ANALYSIS_RAW_MATERIALS, - Permission::ANALYSIS_TOP_SUPPLIERS, Permission::ATTENDANCES_VIEW, Permission::ATTENDANCES_CREATE, diff --git a/app/Http/Controllers/Admin/AnalysisController.php b/app/Http/Controllers/Admin/AnalysisController.php index 5d85fbc..4c076a5 100644 --- a/app/Http/Controllers/Admin/AnalysisController.php +++ b/app/Http/Controllers/Admin/AnalysisController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Admin; +use App\Enums\Role; use App\Http\Controllers\Controller; use App\Services\System\AnalysisService; use Carbon\Carbon; @@ -20,12 +21,17 @@ public function index(Request $request): Response $startDate = $request->query('start_date') ? Carbon::parse($request->query('start_date'))->startOfDay() : null; $endDate = $request->query('end_date') ? Carbon::parse($request->query('end_date'))->endOfDay() : null; + $user = $request->user(); + $isManager = $user?->hasAnyRole([Role::OWNER->value, Role::DEVELOPER->value, Role::DIREKTUR->value]) ?? false; + return Inertia::render('admin/Analysis', [ 'filters' => [ 'start_date' => $request->query('start_date', ''), 'end_date' => $request->query('end_date', ''), ], 'attendance' => $this->analysisService->getAttendance(), + 'myAttendance' => $user ? $this->analysisService->getMyAttendance($user, $startDate, $endDate) : null, + 'isManager' => $isManager, 'cashOverview' => $this->analysisService->getCashOverview(), 'rawMaterialStock' => $this->analysisService->getRawMaterialStock(), 'productStock' => $this->analysisService->getProductStock(), diff --git a/app/Http/Controllers/Admin/DashboardController.php b/app/Http/Controllers/Admin/DashboardController.php index f0901c8..ef22323 100644 --- a/app/Http/Controllers/Admin/DashboardController.php +++ b/app/Http/Controllers/Admin/DashboardController.php @@ -4,6 +4,7 @@ use App\Http\Controllers\Controller; use App\Services\System\DashboardService; +use Illuminate\Http\Request; use Inertia\Inertia; use Inertia\Response; @@ -13,8 +14,10 @@ public function __construct( private readonly DashboardService $dashboardService, ) {} - public function index(): Response + public function index(Request $request): Response { + $user = $request->user(); + return Inertia::render('admin/Dashboard', [ 'attendance' => $this->dashboardService->getAttendance(), 'cashOverview' => $this->dashboardService->getCashOverview(), @@ -22,6 +25,16 @@ public function index(): Response 'expenseSummary' => $this->dashboardService->getExpenseSummary(), 'orderStats' => $this->dashboardService->getOrderStats(), + + 'todayAttendance' => $user + ? $this->dashboardService->getTodayAttendanceForUser($user) + : null, + 'isOnLeave' => $user + ? $this->dashboardService->isOnLeaveTodayForUser($user) + : false, + 'canCheckIn' => $user + ? $this->dashboardService->canCheckInForUser($user) + : false, ]); } } diff --git a/app/Services/System/AnalysisService.php b/app/Services/System/AnalysisService.php index 4b00618..ea12293 100644 --- a/app/Services/System/AnalysisService.php +++ b/app/Services/System/AnalysisService.php @@ -15,6 +15,7 @@ use App\Models\ProductVariant; use App\Models\Purchase; use App\Models\RawMaterialPrice; +use App\Models\User; use Carbon\Carbon; class AnalysisService @@ -47,6 +48,69 @@ public function getAttendance(): array ]; } + public function getMyAttendance(User $user, ?Carbon $startDate = null, ?Carbon $endDate = null): array + { + $employee = $user->employee; + + if ($employee === null) { + return [ + 'total_days' => 0, + 'present_days' => 0, + 'absent_days' => 0, + 'leave_days' => 0, + 'percentage' => 0, + ]; + } + + $start = $startDate ?? Carbon::today()->startOfMonth(); + $end = $endDate ?? Carbon::today()->endOfMonth(); + + $totalDays = 0; + $presentDays = 0; + $current = $start->copy()->startOfDay(); + + while ($current->lte($end)) { + if ($current->isWeekday()) { + $totalDays++; + + $hasAttendance = Attendance::query() + ->where('employee_id', $employee->id) + ->whereDate('attendance_date', $current) + ->exists(); + + if ($hasAttendance) { + $presentDays++; + } + } + + $current->addDay(); + } + + $leaveDays = LeaveRequest::query() + ->approved() + ->where('employee_id', $employee->id) + ->where('start_date', '<=', $end->toDateString()) + ->where('end_date', '>=', $start->toDateString()) + ->get() + ->sum(fn ($leave) => max( + 0, + min($leave->end_date, $end->toDateString()) + - max($leave->start_date, $start->toDateString()) + ) / 86400 + 1); + + $leaveDays = (int) $leaveDays; + $absentDays = max(0, $totalDays - $presentDays - $leaveDays); + $percentage = $totalDays > 0 ? round(($presentDays / $totalDays) * 100) : 0; + + return [ + 'total_days' => $totalDays, + 'present_days' => $presentDays, + 'absent_days' => $absentDays, + 'leave_days' => $leaveDays, + 'percentage' => $percentage, + ]; + } + public function getCashOverview(): array { $totalBalance = CashAccount::query()->sum('balance'); diff --git a/app/Services/System/DashboardService.php b/app/Services/System/DashboardService.php index c0999c1..419600a 100644 --- a/app/Services/System/DashboardService.php +++ b/app/Services/System/DashboardService.php @@ -14,10 +14,52 @@ use App\Models\LeaveRequest; use App\Models\Order; use App\Models\Purchase; +use App\Models\User; use Carbon\Carbon; class DashboardService { + /** + * @return array|null + */ + public function getTodayAttendanceForUser(User $user): ?array + { + $employee = $user->employee; + + if ($employee === null) { + return null; + } + + $attendance = Attendance::query() + ->with('media') + ->where('employee_id', $employee->id) + ->whereDate('attendance_date', today()) + ->first(); + + return $attendance?->toArray(); + } + + public function isOnLeaveTodayForUser(User $user): bool + { + $employee = $user->employee; + + if ($employee === null) { + return false; + } + + return LeaveRequest::query() + ->approved() + ->where('employee_id', $employee->id) + ->whereDate('start_date', '<=', today()) + ->whereDate('end_date', '>=', today()) + ->exists(); + } + + public function canCheckInForUser(User $user): bool + { + return $user->can('attendances.create') && $user->employee !== null; + } + public function getAttendance(): array { $totalEmployees = Employee::query()->count(); diff --git a/resources/js/components/card/AttendanceCard.vue b/resources/js/components/card/AttendanceCard.vue new file mode 100644 index 0000000..68cfa39 --- /dev/null +++ b/resources/js/components/card/AttendanceCard.vue @@ -0,0 +1,108 @@ + + + diff --git a/resources/js/pages/admin/Analysis.vue b/resources/js/pages/admin/Analysis.vue index 42d44cc..1664330 100644 --- a/resources/js/pages/admin/Analysis.vue +++ b/resources/js/pages/admin/Analysis.vue @@ -35,6 +35,14 @@ const props = defineProps<{ absent: number; on_leave: number; }; + myAttendance: { + total_days: number; + present_days: number; + absent_days: number; + leave_days: number; + percentage: number; + } | null; + isManager: boolean; cashOverview: { total_balance: number; total_transactions: number; @@ -354,7 +362,7 @@ watch([startDate, endDate], () => {
- + + +
{
+ + diff --git a/resources/js/pages/admin/hr/attendances/Index.vue b/resources/js/pages/admin/hr/attendances/Index.vue index 699aac0..240a9cc 100644 --- a/resources/js/pages/admin/hr/attendances/Index.vue +++ b/resources/js/pages/admin/hr/attendances/Index.vue @@ -1,10 +1,8 @@