feat(auth): enforce strict branch scoping for overtime requests, attendance regularizations, and 13th month pay
- Restrict overtime applications query, submission, approval, and attendance details to assigned branch - Restrict attendance regularization listing, statistics, and dropdowns to assigned branch - Restrict 13th month pay batch generation, historical runs, entry updates, approvals, and CSV exports to assigned branch - Add feature tests in BranchScopedAccessTest for overtime and 13th month isolation
This commit is contained in:
@@ -31,11 +31,16 @@ class ThirteenthMonthController extends Controller
|
||||
$endYear = $request->input('end_year') ? (int) $request->input('end_year') : $currentYear;
|
||||
$endMonth = $request->input('end_month') ? (int) $request->input('end_month') : 12;
|
||||
|
||||
$selectedBranchId = $request->input('branch_id') ? (int) $request->input('branch_id') : null;
|
||||
$scopedBranchId = authBranchId();
|
||||
$selectedBranchId = $scopedBranchId ?: ($request->input('branch_id') ? (int) $request->input('branch_id') : null);
|
||||
|
||||
// Available years for back-year filtering (last 5 years up to next year)
|
||||
$availableYears = range($currentYear - 5, $currentYear + 1);
|
||||
$branches = Branch::all(['id', 'name']);
|
||||
$branchesQuery = Branch::query();
|
||||
if ($scopedBranchId) {
|
||||
$branchesQuery->where('id', $scopedBranchId);
|
||||
}
|
||||
$branches = $branchesQuery->get(['id', 'name']);
|
||||
|
||||
// Check if an existing run matches these range parameters
|
||||
$existingRun = ThirteenthMonthRun::where('start_year', $startYear)
|
||||
@@ -56,10 +61,15 @@ class ThirteenthMonthController extends Controller
|
||||
}
|
||||
|
||||
// Fetch historical runs list
|
||||
$pastRuns = ThirteenthMonthRun::with(['branch', 'creator'])
|
||||
$pastRunsQuery = ThirteenthMonthRun::with(['branch', 'creator'])
|
||||
->orderBy('year', 'desc')
|
||||
->orderBy('created_at', 'desc')
|
||||
->get();
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
if ($scopedBranchId) {
|
||||
$pastRunsQuery->where('branch_id', $scopedBranchId);
|
||||
}
|
||||
|
||||
$pastRuns = $pastRunsQuery->get();
|
||||
|
||||
return Inertia::render('hr/thirteenth-month/index', [
|
||||
'activeRun' => $existingRun,
|
||||
@@ -93,7 +103,9 @@ class ThirteenthMonthController extends Controller
|
||||
$startMonth = (int) $request->start_month;
|
||||
$endYear = (int) $request->end_year;
|
||||
$endMonth = (int) $request->end_month;
|
||||
$branchId = $request->branch_id ? (int) $request->branch_id : null;
|
||||
|
||||
$scopedBranchId = authBranchId();
|
||||
$branchId = $scopedBranchId ?: ($request->branch_id ? (int) $request->branch_id : null);
|
||||
|
||||
$run = $this->service->generateRun($startYear, $startMonth, $endYear, $endMonth, $branchId, null, Auth::id());
|
||||
|
||||
@@ -111,7 +123,14 @@ class ThirteenthMonthController extends Controller
|
||||
'notes' => 'nullable|string|max:255',
|
||||
]);
|
||||
|
||||
$entry = ThirteenthMonthEntry::findOrFail($id);
|
||||
$entry = ThirteenthMonthEntry::with(['employee', 'run'])->findOrFail($id);
|
||||
$scopedBranchId = authBranchId();
|
||||
if ($scopedBranchId) {
|
||||
$empBranchId = $entry->employee?->branch_id ?? $entry->run?->branch_id;
|
||||
if ($empBranchId && (int)$empBranchId !== (int)$scopedBranchId) {
|
||||
abort(403, 'Unauthorized to update 13th Month entry for an employee outside your assigned branch.');
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->has('adjustment_amount')) {
|
||||
$entry->adjustment_amount = (float) $request->adjustment_amount;
|
||||
@@ -152,6 +171,11 @@ class ThirteenthMonthController extends Controller
|
||||
public function approveRun(Request $request, $id)
|
||||
{
|
||||
$run = ThirteenthMonthRun::findOrFail($id);
|
||||
$scopedBranchId = authBranchId();
|
||||
if ($scopedBranchId && $run->branch_id && (int)$run->branch_id !== (int)$scopedBranchId) {
|
||||
abort(403, 'Unauthorized to approve 13th Month run for another branch.');
|
||||
}
|
||||
|
||||
$run->status = 'approved';
|
||||
$run->save();
|
||||
|
||||
@@ -164,6 +188,10 @@ class ThirteenthMonthController extends Controller
|
||||
public function exportCsv($id)
|
||||
{
|
||||
$run = ThirteenthMonthRun::with(['entries.employee.user', 'entries.employee.department', 'branch'])->findOrFail($id);
|
||||
$scopedBranchId = authBranchId();
|
||||
if ($scopedBranchId && $run->branch_id && (int)$run->branch_id !== (int)$scopedBranchId) {
|
||||
abort(403, 'Unauthorized to export 13th Month run for another branch.');
|
||||
}
|
||||
|
||||
$filename = "13th_Month_Pay_{$run->start_year}_{$run->start_month}_to_{$run->end_year}_{$run->end_month}_Export.csv";
|
||||
$headers = [
|
||||
|
||||
Reference in New Issue
Block a user