feat: Implement user-specific payroll filtering and enforce authorization for payroll access and export.

This commit is contained in:
Yoga Pangestu 2025-12-18 09:54:11 +07:00
parent b66474ed3e
commit 078a541686
3 changed files with 25 additions and 6 deletions

View File

@ -105,6 +105,7 @@ public function builder(): Builder
'payrolls.created_at'
)
->paid()
->forCurrentUser()
->with(['user', 'user.employee']);
}
}

View File

@ -18,6 +18,7 @@
use App\Traits\Utilities\WithUpdatedData;
use Barryvdh\DomPDF\Facade\Pdf;
use Flux\Flux;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\DB;
use Livewire\Attributes\On;
use Livewire\Attributes\Title;
@ -38,7 +39,7 @@ class Payroll extends Component
public array $users = [];
public function mount()
public function mount(): void
{
$this->loadPayrolls();
@ -51,10 +52,11 @@ public function mount()
->toArray();
}
private function loadPayrolls()
private function loadPayrolls(): void
{
$this->payrolls = PayrollModel::with(['user', 'user.employee'])
->notPaid()
->forCurrentUser()
->where('period_month', now()->format('Y-m'))
->whereHas('user', function ($query) {
$query->active()
@ -64,7 +66,7 @@ private function loadPayrolls()
}
#[On('modal:open')]
public function openModal(string $method, string $modalTitle, ?string $id = null)
public function openModal(string $method, string $modalTitle, ?string $id = null): void
{
$this->resetValidation();
$this->resetErrorBag();
@ -73,7 +75,7 @@ public function openModal(string $method, string $modalTitle, ?string $id = null
$this->modalTitle = $modalTitle;
}
public function create()
public function create(): void
{
$this->canOrAbort('manage adjustment');
@ -97,7 +99,7 @@ public function create()
Flux::modals()->close();
}
public function delete(PayrollAdjustment $adjustment)
public function delete(PayrollAdjustment $adjustment): void
{
$this->canOrAbort('manage adjustment');
@ -129,6 +131,12 @@ public function exportPdf(PayrollModel $payroll)
{
$this->canOrAbort('view payroll');
// Validasi: user hanya bisa export payroll milik sendiri (kecuali Owner/Developer)
$user = auth()->user();
if (! $user->hasRole(['Owner', 'Developer']) && $payroll->user_id !== $user->id) {
abort(403, 'Anda tidak memiliki akses untuk melihat payroll ini.');
}
$payroll->load(['user.employee', 'adjustments']);
$pdf = Pdf::loadView('pdf.payroll-slip', [
@ -147,7 +155,7 @@ public function exportPdf(PayrollModel $payroll)
}, $fileName);
}
public function render()
public function render(): View
{
return view('livewire.studio.finance.payrolls', [
'pageTitle' => 'Penggajian',

View File

@ -44,6 +44,16 @@ public function notPaid(Builder $query): void
$query->where('is_paid', IsPaid::NOT_PAID->value);
}
#[Scope]
public function forCurrentUser(Builder $query): void
{
$user = auth()->user();
if ($user && ! $user->hasRole(['Owner', 'Developer'])) {
$query->where('user_id', $user->id);
}
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class);