feat(payroll,leaves): enforce branch scoping for payroll/payslips/salaries, restrict employee role to own leaves, and set payslip header to SCX Software
This commit is contained in:
@@ -16,32 +16,34 @@ class LeaveBalanceController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
if (Auth::user()->can('manage-leave-balances') || Auth::user()->can('view-leave-balances')) {
|
||||
$user = Auth::user();
|
||||
$isEmployee = ($user->type === 'employee' || $user->hasRole('employee'));
|
||||
|
||||
if ($user->can('manage-leave-balances') || $user->can('view-leave-balances') || $user->can('manage-own-leave-balances') || $isEmployee) {
|
||||
$scopedBranchId = authBranchId();
|
||||
$query = LeaveBalance::with(['employee', 'leaveType', 'leavePolicy', 'creator'])
|
||||
->where(function ($q) use ($scopedBranchId) {
|
||||
if ($scopedBranchId) {
|
||||
$q->whereIn('created_by', getCompanyAndUsersId())
|
||||
->whereHas('employee.employee', function ($eq) use ($scopedBranchId) {
|
||||
$eq->where('branch_id', $scopedBranchId);
|
||||
});
|
||||
} elseif (Auth::user()->can('manage-any-leave-balances')) {
|
||||
$q->whereIn('created_by', getCompanyAndUsersId());
|
||||
} elseif (Auth::user()->can('manage-leave-balances')) {
|
||||
$branchId = Auth::user()->branch_id ?? Auth::user()->employee->branch_id ?? null;
|
||||
if ($branchId) {
|
||||
$q->whereHas('employee.employee', function ($eq) use ($branchId) {
|
||||
$eq->where('branch_id', $branchId);
|
||||
});
|
||||
} else {
|
||||
$q->where('created_by', Auth::id())->orWhere('employee_id', Auth::id());
|
||||
}
|
||||
} elseif (Auth::user()->can('manage-own-leave-balances') || Auth::user()->can('view-leave-balances') || Auth::user()->type === 'employee') {
|
||||
$q->where('created_by', Auth::id())->orWhere('employee_id', Auth::id());
|
||||
} else {
|
||||
$q->whereRaw('1 = 0');
|
||||
}
|
||||
});
|
||||
$query = LeaveBalance::with(['employee', 'leaveType', 'leavePolicy', 'creator']);
|
||||
|
||||
if ($isEmployee) {
|
||||
$query->where('employee_id', $user->id);
|
||||
} elseif ($scopedBranchId) {
|
||||
$query->whereIn('created_by', getCompanyAndUsersId())
|
||||
->whereHas('employee.employee', function ($eq) use ($scopedBranchId) {
|
||||
$eq->where('branch_id', $scopedBranchId);
|
||||
});
|
||||
} elseif ($user->can('manage-any-leave-balances')) {
|
||||
$query->whereIn('created_by', getCompanyAndUsersId());
|
||||
} elseif ($user->can('manage-leave-balances')) {
|
||||
$branchId = $user->branch_id ?? $user->employee->branch_id ?? null;
|
||||
if ($branchId) {
|
||||
$query->whereHas('employee.employee', function ($eq) use ($branchId) {
|
||||
$eq->where('branch_id', $branchId);
|
||||
});
|
||||
} else {
|
||||
$query->where('employee_id', $user->id);
|
||||
}
|
||||
} else {
|
||||
$query->where('employee_id', $user->id);
|
||||
}
|
||||
|
||||
// Handle search
|
||||
if ($request->has('search') && !empty($request->search)) {
|
||||
@@ -56,7 +58,7 @@ class LeaveBalanceController extends Controller
|
||||
}
|
||||
|
||||
// Handle employee filter
|
||||
if ($request->has('employee_id') && !empty($request->employee_id) && $request->employee_id !== 'all') {
|
||||
if (!$isEmployee && $request->has('employee_id') && !empty($request->employee_id) && $request->employee_id !== 'all') {
|
||||
$query->where('employee_id', $request->employee_id);
|
||||
}
|
||||
|
||||
@@ -97,9 +99,7 @@ class LeaveBalanceController extends Controller
|
||||
});
|
||||
|
||||
// Get employees for filter dropdown
|
||||
$employees = User::where('type', 'employee')
|
||||
->whereIn('created_by', getCompanyAndUsersId())
|
||||
->get(['id', 'name']);
|
||||
$employees = $isEmployee ? [] : $this->getFilteredEmployees();
|
||||
|
||||
// Get leave types for filter dropdown
|
||||
$leaveTypes = LeaveType::whereIn('created_by', getCompanyAndUsersId())
|
||||
@@ -107,15 +107,20 @@ class LeaveBalanceController extends Controller
|
||||
->get(['id', 'name', 'color']);
|
||||
|
||||
// Get years for filter
|
||||
$years = LeaveBalance::whereIn('created_by', getCompanyAndUsersId())
|
||||
->distinct()
|
||||
$yearsQuery = LeaveBalance::whereIn('created_by', getCompanyAndUsersId());
|
||||
if ($isEmployee) {
|
||||
$yearsQuery->where('employee_id', $user->id);
|
||||
} elseif ($scopedBranchId) {
|
||||
$yearsQuery->whereHas('employee.employee', fn($eq) => $eq->where('branch_id', $scopedBranchId));
|
||||
}
|
||||
$years = $yearsQuery->distinct()
|
||||
->pluck('year')
|
||||
->sort()
|
||||
->values();
|
||||
|
||||
return Inertia::render('hr/leave-balances/index', [
|
||||
'leaveBalances' => $leaveBalances,
|
||||
'employees' => $this->getFilteredEmployees(),
|
||||
'employees' => $employees,
|
||||
'leaveTypes' => $leaveTypes,
|
||||
'years' => $years,
|
||||
'filters' => $request->all(['search', 'employee_id', 'leave_type_id', 'year', 'sort_field', 'sort_direction', 'per_page']),
|
||||
@@ -167,6 +172,12 @@ class LeaveBalanceController extends Controller
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$isEmployee = ($user->type === 'employee' || $user->hasRole('employee'));
|
||||
if ($isEmployee) {
|
||||
return redirect()->back()->with('error', __('Permission Denied.'));
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'employee_id' => 'required|exists:users,id',
|
||||
'leave_type_id' => 'required|exists:leave_types,id',
|
||||
@@ -177,6 +188,14 @@ class LeaveBalanceController extends Controller
|
||||
'adjustment_reason' => 'nullable|string',
|
||||
]);
|
||||
|
||||
$scopedBranchId = authBranchId();
|
||||
if ($scopedBranchId) {
|
||||
$emp = Employee::where('user_id', $validated['employee_id'])->first();
|
||||
if ($emp && (int)$emp->branch_id !== (int)$scopedBranchId) {
|
||||
return redirect()->back()->with('error', __('Permission Denied. Employee is not in your branch.'));
|
||||
}
|
||||
}
|
||||
|
||||
$validated['created_by'] = creatorId();
|
||||
$validated['carried_forward'] = $validated['carried_forward'] ?? 0;
|
||||
$validated['manual_adjustment'] = $validated['manual_adjustment'] ?? 0;
|
||||
@@ -215,11 +234,25 @@ class LeaveBalanceController extends Controller
|
||||
|
||||
public function update(Request $request, $leaveBalanceId)
|
||||
{
|
||||
$leaveBalance = LeaveBalance::where('id', $leaveBalanceId)
|
||||
$user = Auth::user();
|
||||
$isEmployee = ($user->type === 'employee' || $user->hasRole('employee'));
|
||||
if ($isEmployee) {
|
||||
return redirect()->back()->with('error', __('Permission Denied.'));
|
||||
}
|
||||
|
||||
$leaveBalance = LeaveBalance::with('employee.employee')->where('id', $leaveBalanceId)
|
||||
->whereIn('created_by', getCompanyAndUsersId())
|
||||
->first();
|
||||
|
||||
if ($leaveBalance) {
|
||||
$scopedBranchId = authBranchId();
|
||||
if ($scopedBranchId) {
|
||||
$balanceBranchId = $leaveBalance->employee?->employee?->branch_id;
|
||||
if ($balanceBranchId && (int)$balanceBranchId !== (int)$scopedBranchId) {
|
||||
return redirect()->back()->with('error', __('Permission Denied.'));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$validated = $request->validate([
|
||||
'employee_id' => 'required|exists:users,id',
|
||||
@@ -262,11 +295,25 @@ class LeaveBalanceController extends Controller
|
||||
|
||||
public function destroy($leaveBalanceId)
|
||||
{
|
||||
$leaveBalance = LeaveBalance::where('id', $leaveBalanceId)
|
||||
$user = Auth::user();
|
||||
$isEmployee = ($user->type === 'employee' || $user->hasRole('employee'));
|
||||
if ($isEmployee) {
|
||||
return redirect()->back()->with('error', __('Permission Denied.'));
|
||||
}
|
||||
|
||||
$leaveBalance = LeaveBalance::with('employee.employee')->where('id', $leaveBalanceId)
|
||||
->whereIn('created_by', getCompanyAndUsersId())
|
||||
->first();
|
||||
|
||||
if ($leaveBalance) {
|
||||
$scopedBranchId = authBranchId();
|
||||
if ($scopedBranchId) {
|
||||
$balanceBranchId = $leaveBalance->employee?->employee?->branch_id;
|
||||
if ($balanceBranchId && (int)$balanceBranchId !== (int)$scopedBranchId) {
|
||||
return redirect()->back()->with('error', __('Permission Denied.'));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$leaveBalance->delete();
|
||||
return redirect()->back()->with('success', __('Leave balance deleted successfully'));
|
||||
@@ -280,16 +327,30 @@ class LeaveBalanceController extends Controller
|
||||
|
||||
public function adjust(Request $request, $leaveBalanceId)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$isEmployee = ($user->type === 'employee' || $user->hasRole('employee'));
|
||||
if ($isEmployee) {
|
||||
return redirect()->back()->with('error', __('Permission Denied.'));
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'manual_adjustment' => 'required|numeric',
|
||||
'adjustment_reason' => 'required|string',
|
||||
]);
|
||||
|
||||
$leaveBalance = LeaveBalance::where('id', $leaveBalanceId)
|
||||
$leaveBalance = LeaveBalance::with('employee.employee')->where('id', $leaveBalanceId)
|
||||
->whereIn('created_by', getCompanyAndUsersId())
|
||||
->first();
|
||||
|
||||
if ($leaveBalance) {
|
||||
$scopedBranchId = authBranchId();
|
||||
if ($scopedBranchId) {
|
||||
$balanceBranchId = $leaveBalance->employee?->employee?->branch_id;
|
||||
if ($balanceBranchId && (int)$balanceBranchId !== (int)$scopedBranchId) {
|
||||
return redirect()->back()->with('error', __('Permission Denied.'));
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$leaveBalance->update([
|
||||
'manual_adjustment' => $validated['manual_adjustment'],
|
||||
|
||||
Reference in New Issue
Block a user