From 002b6fa46873048678c5f2233429ca252760a8c7 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Thu, 30 Apr 2026 15:04:25 +0700 Subject: [PATCH] feat: restrict payroll index visibility to current user for Admin role --- .../Admin/Finance/PayrollController.php | 6 ++ tests/Feature/Admin/Finance/PayrollTest.php | 58 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/app/Http/Controllers/Admin/Finance/PayrollController.php b/app/Http/Controllers/Admin/Finance/PayrollController.php index e06bdd5..be5f6ed 100644 --- a/app/Http/Controllers/Admin/Finance/PayrollController.php +++ b/app/Http/Controllers/Admin/Finance/PayrollController.php @@ -24,10 +24,16 @@ public function index(): Response return Inertia::render('admin/finance/payroll/index', [ 'payrolls' => Payroll::with(['user.profile', 'adjustments']) ->where('period_month', '!=', $currentMonth) + ->when(auth()->user()->hasRole('Admin'), function ($query) { + $query->where('user_id', auth()->id()); + }) ->latest() ->get(), 'currentMonthPayrolls' => Payroll::with(['user.profile', 'adjustments']) ->where('period_month', $currentMonth) + ->when(auth()->user()->hasRole('Admin'), function ($query) { + $query->where('user_id', auth()->id()); + }) ->get(), ]); } diff --git a/tests/Feature/Admin/Finance/PayrollTest.php b/tests/Feature/Admin/Finance/PayrollTest.php index b8e2d7e..79f71cf 100644 --- a/tests/Feature/Admin/Finance/PayrollTest.php +++ b/tests/Feature/Admin/Finance/PayrollTest.php @@ -2,7 +2,9 @@ use App\Enums\SalaryAdjustmentType; use App\Models\Payroll; +use App\Models\User; use Illuminate\Support\Facades\Artisan; +use Spatie\Permission\Models\Role; use function Pest\Laravel\actingAs; use function Pest\Laravel\assertDatabaseHas; @@ -54,6 +56,62 @@ ); }); + it('filters payrolls for Admin role to only see their own records', function () { + Role::findOrCreate('Admin'); + $admin = createAuthorizedUser(['View:Payroll']); + $admin->assignRole('Admin'); + + $otherUser = User::factory()->create(); + $currentMonth = now()->format('Y-m'); + + // Payroll for admin + $adminPayroll = Payroll::factory()->create([ + 'user_id' => $admin->id, + 'period_month' => $currentMonth, + ]); + + // Payroll for other user + Payroll::factory()->create([ + 'user_id' => $otherUser->id, + 'period_month' => $currentMonth, + ]); + + actingAs($admin) + ->get(route('payroll.index')) + ->assertOk() + ->assertInertia(fn ($page) => $page + ->component('admin/finance/payroll/index') + ->has('currentMonthPayrolls', 1) + ->where('currentMonthPayrolls.0.id', $adminPayroll->id) + ); + }); + + it('shows all payrolls for users without Admin role', function () { + $user = createAuthorizedUser(['View:Payroll']); + // No Admin role assigned + + $otherUser = User::factory()->create(); + $currentMonth = now()->format('Y-m'); + + Payroll::factory()->create([ + 'user_id' => $user->id, + 'period_month' => $currentMonth, + ]); + + Payroll::factory()->create([ + 'user_id' => $otherUser->id, + 'period_month' => $currentMonth, + ]); + + actingAs($user) + ->get(route('payroll.index')) + ->assertOk() + ->assertInertia(fn ($page) => $page + ->component('admin/finance/payroll/index') + ->has('currentMonthPayrolls', 2) + ); + }); + it('can generate payroll', function () { // Mocking artisan call is tricky if we want to check side effects, // but here we check the response and session.