diff --git a/app/Http/Controllers/AttendancePolicyController.php b/app/Http/Controllers/AttendancePolicyController.php deleted file mode 100644 index 8698c979b..000000000 --- a/app/Http/Controllers/AttendancePolicyController.php +++ /dev/null @@ -1,190 +0,0 @@ -can('manage-attendance-policies')) { - $query = AttendancePolicy::with(['creator'])->where(function ($q) { - if (Auth::user()->can('manage-any-attendance-policies')) { - $q->whereIn('created_by', getCompanyAndUsersId()); - } elseif (Auth::user()->can('manage-own-attendance-policies')) { - $q->where('created_by', Auth::id()); - } else { - $q->whereRaw('1 = 0'); - } - }); - - // Handle search - if ($request->has('search') && !empty($request->search)) { - $query->where(function ($q) use ($request) { - $q->where('name', 'like', '%' . $request->search . '%') - ->orWhere('description', 'like', '%' . $request->search . '%'); - }); - } - - // Handle status filter - if ($request->has('status') && !empty($request->status) && $request->status !== 'all') { - $query->where('status', $request->status); - } - - // Handle overtime calculation filter - if ($request->has('overtime_calculation') && !empty($request->overtime_calculation) && $request->overtime_calculation !== 'all') { - $query->where('overtime_calculation', $request->overtime_calculation); - } - - // Handle sorting - if ($request->has('sort_field') && !empty($request->sort_field)) { - $sortField = $request->sort_field; - $sortDirection = $request->sort_direction ?? 'asc'; - - if ($sortField === 'name') { - $query->orderBy('name', $sortDirection); - } else { - $query->orderBy('created_at', 'desc'); - } - } else { - $query->orderBy('created_at', 'desc'); - } - - $attendancePolicies = $query->paginate($request->per_page ?? 9); - - // Stats always calculated from ALL records — never affected by filters or pagination - $allPolicies = AttendancePolicy::where(function ($q) { - if (Auth::user()->can('manage-any-attendance-policies')) { - $q->whereIn('created_by', getCompanyAndUsersId()); - } elseif (Auth::user()->can('manage-own-attendance-policies')) { - $q->where('created_by', Auth::id()); - } else { - $q->whereRaw('1 = 0'); - } - }); - - $stats = [ - 'total' => (clone $allPolicies)->count(), - 'active' => (clone $allPolicies)->where('status', 'active')->count(), - 'avg_late_grace' => (int) round((clone $allPolicies)->avg('late_arrival_grace') ?? 0), - 'avg_overtime_rate'=> (float) ((clone $allPolicies)->avg('overtime_rate_per_hour') ?? 0), - ]; - - return Inertia::render('hr/attendance-policies/index', [ - 'attendancePolicies' => $attendancePolicies, - 'stats' => $stats, - 'filters' => $request->all(['search', 'status', 'overtime_calculation', 'sort_field', 'sort_direction', 'per_page']), - ]); - } else { - return redirect()->back()->with('error', __('Permission Denied.')); - } - } - - public function store(Request $request) - { - $validated = $request->validate([ - 'name' => 'required|string|max:255', - 'description' => 'nullable|string', - 'late_arrival_grace' => 'required|integer|min:0', - 'early_departure_grace' => 'required|integer|min:0', - 'overtime_rate_per_hour' => 'required|numeric|min:0', - 'status' => 'nullable|in:active,inactive', - ]); - - $validated['created_by'] = creatorId(); - $validated['status'] = $validated['status'] ?? 'active'; - - // Check if policy with same name already exists - $exists = AttendancePolicy::where('name', $validated['name']) - ->whereIn('created_by', getCompanyAndUsersId()) - ->exists(); - - if ($exists) { - return redirect()->back()->with('error', __('Attendance policy with this name already exists.')); - } - - AttendancePolicy::create($validated); - - return redirect()->back()->with('success', __('Attendance policy created successfully.')); - } - - public function update(Request $request, $attendancePolicyId) - { - $attendancePolicy = AttendancePolicy::where('id', $attendancePolicyId) - ->whereIn('created_by', getCompanyAndUsersId()) - ->first(); - - if ($attendancePolicy) { - try { - $validated = $request->validate([ - 'name' => 'required|string|max:255', - 'description' => 'nullable|string', - 'late_arrival_grace' => 'required|integer|min:0', - 'early_departure_grace' => 'required|integer|min:0', - 'overtime_rate_per_hour' => 'required|numeric|min:0', - 'status' => 'nullable|in:active,inactive', - ]); - - // Check if policy with same name already exists (excluding current) - $exists = AttendancePolicy::where('name', $validated['name']) - ->whereIn('created_by', getCompanyAndUsersId()) - ->where('id', '!=', $attendancePolicyId) - ->exists(); - - if ($exists) { - return redirect()->back()->with('error', __('Attendance policy with this name already exists.')); - } - - $attendancePolicy->update($validated); - - return redirect()->back()->with('success', __('Attendance policy updated successfully')); - } catch (\Exception $e) { - return redirect()->back()->with('error', $e->getMessage() ?: __('Failed to update attendance policy')); - } - } else { - return redirect()->back()->with('error', __('Attendance policy Not Found.')); - } - } - - public function destroy($attendancePolicyId) - { - $attendancePolicy = AttendancePolicy::where('id', $attendancePolicyId) - ->whereIn('created_by', getCompanyAndUsersId()) - ->first(); - - if ($attendancePolicy) { - try { - $attendancePolicy->delete(); - return redirect()->back()->with('success', __('Attendance policy deleted successfully')); - } catch (\Exception $e) { - return redirect()->back()->with('error', $e->getMessage() ?: __('Failed to delete attendance policy')); - } - } else { - return redirect()->back()->with('error', __('Attendance policy Not Found.')); - } - } - - public function toggleStatus($attendancePolicyId) - { - $attendancePolicy = AttendancePolicy::where('id', $attendancePolicyId) - ->whereIn('created_by', getCompanyAndUsersId()) - ->first(); - - if ($attendancePolicy) { - try { - $attendancePolicy->status = $attendancePolicy->status === 'active' ? 'inactive' : 'active'; - $attendancePolicy->save(); - - return redirect()->back()->with('success', __('Attendance policy status updated successfully')); - } catch (\Exception $e) { - return redirect()->back()->with('error', $e->getMessage() ?: __('Failed to update attendance policy status')); - } - } else { - return redirect()->back()->with('error', __('Attendance policy Not Found.')); - } - } -} diff --git a/app/Http/Controllers/AttendanceRecordController.php b/app/Http/Controllers/AttendanceRecordController.php index a9e6cf466..7849538d2 100644 --- a/app/Http/Controllers/AttendanceRecordController.php +++ b/app/Http/Controllers/AttendanceRecordController.php @@ -310,12 +310,11 @@ class AttendanceRecordController extends Controller Shift::find($employee->shift_id) : Shift::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); - $policy = $employee && $employee->attendance_policy_id ? - AttendancePolicy::find($employee->attendance_policy_id) : - AttendancePolicy::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); + if (! $shift) { + return redirect()->back()->with('error', __('Active shift not found for employee. Please configure this in employee settings.')); + } - $validated['shift_id'] = $shift?->id; - $validated['attendance_policy_id'] = $policy?->id; + $validated['shift_id'] = $shift->id; $validated['created_by'] = creatorId(); $validated['is_holiday'] = $validated['is_holiday'] ?? ($validated['status'] === 'holiday'); $validated['is_rest_day'] = $validated['is_rest_day'] ?? ($validated['status'] === 'rest_day'); @@ -383,27 +382,24 @@ class AttendanceRecordController extends Controller } } - // Get employee with shift and policy + // Get employee with shift $employee = \App\Models\Employee::where('user_id', $validated['employee_id'])->first(); if (!$employee || (!$employee->shift_id && !$attendanceRecord->shift_id)) { return redirect()->back()->with('error', __('Cannot process attendance: Employee has no shift assigned.')); } - $companyUserIds = getCompanyAndUsersId(); - - // Use employee's assigned shift and policy + // Use employee's assigned shift // PRESERVE the existing record shift_id (e.g. synced from legacy) — only fallback to employee default $shift = $attendanceRecord->shift_id ? Shift::find($attendanceRecord->shift_id) : Shift::find($employee->shift_id); - $policy = $employee && $employee->attendance_policy_id ? - AttendancePolicy::find($employee->attendance_policy_id) : - AttendancePolicy::whereIn('created_by', $companyUserIds)->where('status', 'active')->first(); + if (! $shift) { + return redirect()->back()->with('error', __('Active shift not found for employee. Please configure this in employee settings.')); + } - $validated['shift_id'] = $shift?->id; - $validated['attendance_policy_id'] = $policy?->id; + $validated['shift_id'] = $shift->id; // Handle balance deduction/restoration if status changed if ($validated['status'] === 'on_leave' && ($attendanceRecord->status !== 'on_leave' || $attendanceRecord->leave_type_id != $validated['leave_type_id'])) { @@ -590,19 +586,14 @@ class AttendanceRecordController extends Controller Shift::find($employee->shift_id) : Shift::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); - $policy = $employee->attendance_policy_id ? - AttendancePolicy::find($employee->attendance_policy_id) : - AttendancePolicy::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); - - if (! $shift || ! $policy) { - return redirect()->back()->with('error', __('No active shift or attendance policy found. Please contact HR.')); + if (! $shift) { + return redirect()->back()->with('error', __('No active shift found. Please contact HR.')); } if ($existingRecord) { $existingRecord->update([ 'clock_in' => $now->format('H:i:s'), 'shift_id' => $shift->id, - 'attendance_policy_id' => $policy->id, 'status' => 'present', 'clock_in_latitude' => $validated['latitude'] ?? null, 'clock_in_longitude' => $validated['longitude'] ?? null, @@ -615,7 +606,6 @@ class AttendanceRecordController extends Controller 'date' => $today, 'clock_in' => $now->format('H:i:s'), 'shift_id' => $shift->id, - 'attendance_policy_id' => $policy->id, 'is_weekend' => $today->isWeekend(), 'status' => 'present', 'created_by' => creatorId(), @@ -916,11 +906,7 @@ class AttendanceRecordController extends Controller Shift::find($employeeModel->shift_id) : Shift::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); - $policy = $employeeModel && $employeeModel->attendance_policy_id ? - AttendancePolicy::find($employeeModel->attendance_policy_id) : - AttendancePolicy::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); - - if (! $shift || ! $policy) { + if (! $shift) { $skipped++; continue; } @@ -929,7 +915,6 @@ class AttendanceRecordController extends Controller 'employee_id' => $employee->id, 'date' => $row['date'], 'shift_id' => $shift->id, - 'attendance_policy_id' => $policy->id, 'clock_in' => $row['clock_in'] ?? null, 'clock_out' => $row['clock_out'] ?? null, 'created_by' => creatorId(), diff --git a/app/Http/Controllers/EmployeeController.php b/app/Http/Controllers/EmployeeController.php index 35e696ad7..8f9503c19 100644 --- a/app/Http/Controllers/EmployeeController.php +++ b/app/Http/Controllers/EmployeeController.php @@ -245,7 +245,6 @@ class EmployeeController extends Controller 'shift_id' => 'nullable|exists:shifts,id', 'rest_days' => 'nullable|array', 'rest_days.*' => 'string|in:monday,tuesday,wednesday,thursday,friday,saturday,sunday', - 'attendance_policy_id' => 'nullable|exists:attendance_policies,id', 'salary' => 'required|numeric|min:0', // Employment details @@ -379,13 +378,6 @@ class EmployeeController extends Controller } $employee->shift_id = $shiftId; - $policyId = $request->attendance_policy_id; - if (empty($policyId)) { - $defaultPolicy = \App\Models\AttendancePolicy::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); - $policyId = $defaultPolicy ? $defaultPolicy->id : null; - } - $employee->attendance_policy_id = $policyId; - $employee->rest_days = $request->rest_days; $employee->date_of_joining = $request->date_of_joining; $employee->employment_type = $request->employment_type; @@ -595,7 +587,6 @@ class EmployeeController extends Controller 'shift_id' => 'nullable|exists:shifts,id', 'rest_days' => 'nullable|array', 'rest_days.*' => 'string|in:monday,tuesday,wednesday,thursday,friday,saturday,sunday', - 'attendance_policy_id' => 'nullable|exists:attendance_policies,id', 'salary' => 'required|numeric|min:0', // Employment details @@ -685,13 +676,6 @@ class EmployeeController extends Controller } $employee->shift_id = $shiftId; - $policyId = $request->attendance_policy_id; - if (empty($policyId)) { - $defaultPolicy = \App\Models\AttendancePolicy::whereIn('created_by', getCompanyAndUsersId())->where('status', 'active')->first(); - $policyId = $defaultPolicy ? $defaultPolicy->id : null; - } - $employee->attendance_policy_id = $policyId; - $employee->rest_days = $request->rest_days; $employee->phone = $request->phone; $employee->date_of_birth = $request->date_of_birth; @@ -1448,9 +1432,8 @@ class EmployeeController extends Controller 'branch_id' => $branchId, 'department_id' => $departmentId, 'designation_id' => $designationId, - 'base_salary' => $row['base_salary'], 'shift_id' => $shiftId, - 'attendance_policy_id' => $attendancePolicyId, + 'base_salary' => $row['base_salary'], 'date_of_joining' => !empty($row['date_of_joining']) ? $row['date_of_joining'] : now(), 'employment_type' => $row['employment_type'] ?? 'full-time', 'employee_status' => $row['employee_status'] ?? 'active', diff --git a/app/Models/AttendancePolicy.php b/app/Models/AttendancePolicy.php deleted file mode 100644 index ce404ee94..000000000 --- a/app/Models/AttendancePolicy.php +++ /dev/null @@ -1,65 +0,0 @@ - 'decimal:2', - ]; - - /** - * Get the user who created the policy. - */ - public function creator() - { - return $this->belongsTo(User::class, 'created_by'); - } - - /** - * Check if arrival time is late. - */ - public function isLateArrival($actualTime, $expectedTime) - { - $actual = \Carbon\Carbon::parse($actualTime); - $expected = \Carbon\Carbon::parse($expectedTime); - $graceMinutes = $this->late_arrival_grace; - - return $actual->gt($expected->addMinutes($graceMinutes)); - } - - /** - * Check if departure time is early. - */ - public function isEarlyDeparture($actualTime, $expectedTime) - { - $actual = \Carbon\Carbon::parse($actualTime); - $expected = \Carbon\Carbon::parse($expectedTime); - $graceMinutes = $this->early_departure_grace; - - return $actual->lt($expected->subMinutes($graceMinutes)); - } - - /** - * Calculate overtime amount. - */ - public function calculateOvertimeAmount($overtimeHours) - { - return $overtimeHours * $this->overtime_rate_per_hour; - } -} \ No newline at end of file diff --git a/app/Models/AttendanceRecord.php b/app/Models/AttendanceRecord.php index 550e22b75..4dce03768 100644 --- a/app/Models/AttendanceRecord.php +++ b/app/Models/AttendanceRecord.php @@ -13,7 +13,6 @@ class AttendanceRecord extends BaseModel 'employee_id', 'branch_id', 'shift_id', - 'attendance_policy_id', 'date', 'clock_in', 'clock_out', @@ -72,15 +71,7 @@ class AttendanceRecord extends BaseModel */ public function shift() { - return $this->belongsTo(Shift::class); - } - - /** - * Get the attendance policy. - */ - public function attendancePolicy() - { - return $this->belongsTo(AttendancePolicy::class); + return $this->belongsTo(Shift::class, 'shift_id'); } /** @@ -182,7 +173,7 @@ class AttendanceRecord extends BaseModel $expectedTime = \Carbon\Carbon::parse($this->date->format('Y-m-d') . ' ' . $this->shift->start_time); $actualTime = \Carbon\Carbon::parse($this->date->format('Y-m-d') . ' ' . $this->clock_in); - $graceMinutes = $this->attendancePolicy->late_arrival_grace ?? $this->shift->grace_period ?? 0; + $graceMinutes = 15; if ($actualTime->gt($expectedTime->copy()->addMinutes($graceMinutes))) { $this->is_late = true; @@ -216,7 +207,7 @@ class AttendanceRecord extends BaseModel $actualTime->addDay(); } - $graceMinutes = $this->attendancePolicy->early_departure_grace ?? 0; + $graceMinutes = 15; if ($actualTime->lt($expectedTime->copy()->subMinutes($graceMinutes))) { $this->is_early_departure = true; @@ -337,8 +328,9 @@ class AttendanceRecord extends BaseModel $this->overtime_hours = max(0, round($this->total_hours - $standardHours, 2)); // Step 3: Calculate overtime amount using policy - if ($this->overtime_hours > 0 && $this->attendancePolicy) { - $this->overtime_amount = round($this->overtime_hours * $this->attendancePolicy->overtime_rate_per_hour, 2); + if ($this->overtime_hours > 0) { + // Overtime amount is calculated during payroll generation. + $this->overtime_amount = 0; } else { $this->overtime_amount = 0; } diff --git a/database/migrations/2026_07_16_021748_remove_attendance_policies.php b/database/migrations/2026_07_16_021748_remove_attendance_policies.php new file mode 100644 index 000000000..7190d94db --- /dev/null +++ b/database/migrations/2026_07_16_021748_remove_attendance_policies.php @@ -0,0 +1,38 @@ +dropForeign(['attendance_policy_id']); + $table->dropColumn('attendance_policy_id'); + } + }); + + Schema::table('attendance_records', function (Blueprint $table) { + if (Schema::hasColumn('attendance_records', 'attendance_policy_id')) { + $table->dropForeign(['attendance_policy_id']); + $table->dropColumn('attendance_policy_id'); + } + }); + + Schema::dropIfExists('attendance_policies'); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + } +}; diff --git a/docs/PLAN-remove-attendance-policies.md b/docs/PLAN-remove-attendance-policies.md new file mode 100644 index 000000000..7f3109f1b --- /dev/null +++ b/docs/PLAN-remove-attendance-policies.md @@ -0,0 +1,49 @@ +# Project Plan: Remove Attendance Policies + +## 1. Context & Objective +The user wants to remove the entire `attendance_policies` feature from the HR system. Currently, the system relies on attendance policies to determine grace periods (late arrival, early departure) and an explicit overtime rate. + +We have verified that: +1. Overtime rate calculation is already safely hardcoded in `PayrollService.php` (`$hourlyRate * 1.25` or `1.30`). +2. Therefore, the dynamic `overtime_rate_per_hour` in the policy is redundant. +3. The late arrival and early departure grace periods should be hardcoded to exactly `15` minutes instead. + +The goal is to safely remove all frontend and backend references to attendance policies, making the system simpler and preventing clock-in errors. + +## 2. Task Breakdown + +### A. Backend Cleanup +- **Controllers:** + - `AttendanceRecordController.php`: Remove all queries and dependency checks for `$policy`. + - `EmployeeController.php`: Remove `attendance_policy_id` validation and auto-assignment logic we just added. Remove from `store` and `update`. + - `AttendancePolicyController.php`: Delete this controller entirely. +- **Models:** + - `AttendanceRecord.php`: In `checkLateArrival()` and `checkEarlyDeparture()`, hardcode the grace periods to `15` minutes instead of fetching from `$this->attendancePolicy->late_arrival_grace`. + - `Employee.php`: Remove the `attendancePolicy` relationship. + - `AttendancePolicy.php`: Delete this model entirely. +- **Database / Migrations:** + - Create a migration to drop the `attendance_policies` table. + - Create a migration to drop `attendance_policy_id` from `employees` and `attendance_records` tables. + +### B. Frontend Cleanup +- **Pages & Components:** + - Delete `resources/js/pages/hr/attendance-policies/` directory. + - Remove the Attendance Policies tab/link from `resources/js/layouts/hr-layout.tsx` or `sidebar.tsx` components. + - `resources/js/pages/hr/employees/create.tsx` & `edit.tsx`: Completely remove the "Attendance Policy" dropdown field. + - Remove from any employee view tables if displayed. +- **Routes:** + - In `routes/web.php` or `routes/hr.php`: Remove all routes related to `AttendancePolicyController`. + +## 3. Verification Checklist +- [ ] Employees can still clock in and out without errors. +- [ ] Late arrivals are correctly flagged only after 15 minutes past shift start time. +- [ ] Early departures are flagged if clocked out more than 15 minutes before shift end time. +- [ ] Employee create/edit works flawlessly without the Attendance Policy dropdown. +- [ ] The HR dashboard navigation does not show "Attendance Policies". +- [ ] Payroll generation still correctly calculates Overtime via `PayrollService.php`. + +## 4. Agent Assignments +- **`backend-specialist`**: Handles PHP controllers, models, and migrations. +- **`frontend-specialist`**: Removes React components, form fields, and navigation links. + +*Run `/create` to begin execution of this plan.* diff --git a/included_files.json b/included_files.json index ca006c1c7..652db201d 100644 --- a/included_files.json +++ b/included_files.json @@ -1086,74 +1086,21 @@ "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Matching\/HostValidator.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/RouteParameterBinder.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Events\/RouteMatched.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/barryvdh\/laravel-debugbar\/src\/Controllers\/OpenHandlerController.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/barryvdh\/laravel-debugbar\/src\/Controllers\/BaseController.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/ControllerDispatcher.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Contracts\/ControllerDispatcher.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/ControllerMiddlewareOptions.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/MiddlewareNameResolver.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/SortedMiddleware.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/CallableDispatcher.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Contracts\/CallableDispatcher.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Filesystem\/ServeFile.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/Facades\/URL.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/UrlGenerator.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Contracts\/Routing\/UrlGenerator.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/http-kernel\/Exception\/HttpException.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/http-kernel\/Exception\/HttpExceptionInterface.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Exceptions\/Handler.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Contracts\/Debug\/ExceptionHandler.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Configuration\/Exceptions.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Exceptions\/RegisterErrorViewPaths.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/Facades\/View.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/ResponseFactory.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Contracts\/Routing\/ResponseFactory.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Redirector.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/SessionManager.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/FileSessionHandler.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Session\/Store.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Contracts\/Session\/Session.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/ViewErrorBag.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/View\/ViewName.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/livewire\/livewire\/src\/Mechanisms\/ExtendBlade\/ExtendedCompilerEngine.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/View\/Engines\/CompilerEngine.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/View\/Engines\/PhpEngine.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Contracts\/View\/Engine.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/barryvdh\/laravel-debugbar\/src\/Middleware\/DebugbarEnabled.php", + "\/Users\/dvapp\/Documents\/HRM\/vendor\/php-debugbar\/php-debugbar\/src\/DebugBar\/OpenHandler.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Http\/Response.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/http-foundation\/Response.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/http-foundation\/ResponseHeaderBag.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Http\/ResponseTrait.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/inertiajs\/inertia-laravel\/src\/Inertia.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/livewire\/livewire\/src\/Mechanisms\/ExtendBlade\/DeterministicBladeKeys.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/livewire\/livewire\/src\/Drawer\/Regexes.php", - "\/Users\/dvapp\/Documents\/HRM\/storage\/framework\/views\/4d31dcd2ecd6ab7e954e110d3b7932af.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Translation\/TranslationServiceProvider.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Translation\/FileLoader.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Contracts\/Translation\/Loader.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Translation\/Translator.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/NamespacedItemResolver.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Contracts\/Translation\/Translator.php", - "\/Users\/dvapp\/Documents\/HRM\/storage\/framework\/views\/3e9b12a2bc10e51ca51a3d588b953ed2.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Events\/PreparingResponse.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/Events\/ResponsePrepared.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/barryvdh\/laravel-debugbar\/src\/SymfonyHttpDriver.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/php-debugbar\/php-debugbar\/src\/DebugBar\/HttpDriverInterface.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/uid\/Ulid.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/uid\/AbstractUid.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/uid\/HashableInterface.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/php-ds\/php-ds\/src\/Hashable.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/uid\/TimeBasedUidInterface.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/barryvdh\/laravel-debugbar\/src\/DataCollector\/RequestCollector.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/php-debugbar\/php-debugbar\/src\/DebugBar\/DataFormatter\/DebugBarVarDumper.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Cloner\/Data.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Cloner\/Stub.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/php-debugbar\/php-debugbar\/src\/DebugBar\/DataFormatter\/VarDumper\/DebugBarHtmlDumper.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Cloner\/Cursor.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/Caster.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/ClassStub.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/ConstStub.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/CutStub.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/EnumStub.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/LinkStub.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/UninitializedStub.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/symfony\/var-dumper\/Caster\/StubCaster.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/Optional.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Routing\/RouteUrlGenerator.php", - "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/Facades\/Config.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Http\/Events\/RequestHandled.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Foundation\/Events\/Terminating.php", "\/Users\/dvapp\/Documents\/HRM\/vendor\/laravel\/framework\/src\/Illuminate\/Support\/Defer\/DeferredCallbackCollection.php", diff --git a/resources/js/components/app-sidebar.tsx b/resources/js/components/app-sidebar.tsx index 577151aa4..f0da6cc60 100755 --- a/resources/js/components/app-sidebar.tsx +++ b/resources/js/components/app-sidebar.tsx @@ -770,12 +770,6 @@ export function AppSidebar() { }); } - if (hasPermission(permissions, 'manage-attendance-policies')) { - attendanceChildren.push({ - title: t('Attendance Policies'), - href: route('hr.attendance-policies.index') - }); - } if (hasPermission(permissions, 'manage-attendance-records')) { attendanceChildren.push({ diff --git a/resources/js/pages/hr/attendance-policies/index.tsx b/resources/js/pages/hr/attendance-policies/index.tsx deleted file mode 100755 index c0c605ced..000000000 --- a/resources/js/pages/hr/attendance-policies/index.tsx +++ /dev/null @@ -1,610 +0,0 @@ -// pages/hr/attendance-policies/index.tsx -import { useState } from 'react'; -import { PageTemplate } from '@/components/page-template'; -import { usePage, router } from '@inertiajs/react'; -import { Plus, Clock, DollarSign, Shield, Users, Eye, Edit, Trash2, Lock, CheckCircle } from 'lucide-react'; -import { hasPermission } from '@/utils/authorization'; -import { CrudTable } from '@/components/CrudTable'; -import { CrudFormModal } from '@/components/CrudFormModal'; -import { CrudDeleteModal } from '@/components/CrudDeleteModal'; -import { toast } from '@/components/custom-toast'; -import { useTranslation } from 'react-i18next'; -import { Pagination } from '@/components/ui/pagination'; -import { SearchAndFilterBar } from '@/components/ui/search-and-filter-bar'; -import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Badge } from '@/components/ui/badge'; -import { Dialog } from '@/components/ui/dialog'; -import View from './view'; - -export default function AttendancePolicies() { - const { t } = useTranslation(); - const { auth, attendancePolicies, stats, filters: pageFilters = {} } = usePage().props as any; - const permissions = auth?.permissions || []; - - // State - const [searchTerm, setSearchTerm] = useState(pageFilters.search || ''); - const [selectedStatus, setSelectedStatus] = useState(pageFilters.status || 'all'); - const [showFilters, setShowFilters] = useState(false); - const [isFormModalOpen, setIsFormModalOpen] = useState(false); - const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); - const [currentItem, setCurrentItem] = useState(null); - const [formMode, setFormMode] = useState<'create' | 'edit'>('create'); - const [viewingItem, setViewingItem] = useState(null); - - // Check if any filters are active - const hasActiveFilters = () => { - return searchTerm !== '' || selectedStatus !== 'all'; - }; - - // Count active filters - const activeFilterCount = () => { - return (searchTerm ? 1 : 0) + (selectedStatus !== 'all' ? 1 : 0); - }; - - const handleSearch = (e: React.FormEvent) => { - e.preventDefault(); - applyFilters(); - }; - - const applyFilters = () => { - router.get(route('hr.attendance-policies.index'), { - page: 1, - search: searchTerm || undefined, - status: selectedStatus !== 'all' ? selectedStatus : undefined, - per_page: pageFilters.per_page - }, { preserveState: true, preserveScroll: true }); - }; - - const handleSort = (field: string) => { - const direction = pageFilters.sort_field === field && pageFilters.sort_direction === 'asc' ? 'desc' : 'asc'; - - router.get(route('hr.attendance-policies.index'), { - sort_field: field, - sort_direction: direction, - page: 1, - search: searchTerm || undefined, - status: selectedStatus !== 'all' ? selectedStatus : undefined, - per_page: pageFilters.per_page - }, { preserveState: true, preserveScroll: true }); - }; - - const handleAction = (action: string, item: any) => { - setCurrentItem(item); - - switch (action) { - case 'view': - setViewingItem(item); - break; - case 'edit': - setFormMode('edit'); - setIsFormModalOpen(true); - break; - case 'delete': - setIsDeleteModalOpen(true); - break; - case 'toggle-status': - handleToggleStatus(item); - break; - } - }; - - const handleAddNew = () => { - setCurrentItem(null); - setFormMode('create'); - setIsFormModalOpen(true); - }; - - const handleFormSubmit = (formData: any) => { - if (formMode === 'create') { - toast.loading(t('Creating attendance policy...')); - - router.post(route('hr.attendance-policies.store'), formData, { - onSuccess: (page) => { - setIsFormModalOpen(false); - toast.dismiss(); - if (page.props.flash.success) { - toast.success(t(page.props.flash.success)); - } else if (page.props.flash.error) { - toast.error(t(page.props.flash.error)); - } - }, - onError: (errors) => { - toast.dismiss(); - if (typeof errors === 'string') { - toast.error(errors); - } else { - toast.error(`Failed to create attendance policy: ${Object.values(errors).join(', ')}`); - } - } - }); - } else if (formMode === 'edit') { - toast.loading(t('Updating attendance policy...')); - - router.put(route('hr.attendance-policies.update', currentItem.id), formData, { - onSuccess: (page) => { - setIsFormModalOpen(false); - toast.dismiss(); - if (page.props.flash.success) { - toast.success(t(page.props.flash.success)); - } else if (page.props.flash.error) { - toast.error(t(page.props.flash.error)); - } - }, - onError: (errors) => { - toast.dismiss(); - if (typeof errors === 'string') { - toast.error(errors); - } else { - toast.error(`Failed to update attendance policy: ${Object.values(errors).join(', ')}`); - } - } - }); - } - }; - - const handleDeleteConfirm = () => { - toast.loading(t('Deleting attendance policy...')); - - router.delete(route('hr.attendance-policies.destroy', currentItem.id), { - onSuccess: (page) => { - setIsDeleteModalOpen(false); - toast.dismiss(); - if (page.props.flash.success) { - toast.success(t(page.props.flash.success)); - } else if (page.props.flash.error) { - toast.error(t(page.props.flash.error)); - } - }, - onError: (errors) => { - toast.dismiss(); - if (typeof errors === 'string') { - toast.error(errors); - } else { - toast.error(`Failed to delete attendance policy: ${Object.values(errors).join(', ')}`); - } - } - }); - }; - - const handleToggleStatus = (policy: any) => { - const newStatus = policy.status === 'active' ? 'inactive' : 'active'; - toast.loading(`${newStatus === 'active' ? t('Activating') : t('Deactivating')} attendance policy...`); - - router.put(route('hr.attendance-policies.toggle-status', policy.id), {}, { - onSuccess: (page) => { - toast.dismiss(); - if (page.props.flash.success) { - toast.success(t(page.props.flash.success)); - } else if (page.props.flash.error) { - toast.error(t(page.props.flash.error)); - } - }, - onError: (errors) => { - toast.dismiss(); - if (typeof errors === 'string') { - toast.error(errors); - } else { - toast.error(`Failed to update attendance policy status: ${Object.values(errors).join(', ')}`); - } - } - }); - }; - - const handleResetFilters = () => { - setSearchTerm(''); - setSelectedStatus('all'); - setShowFilters(false); - - router.get(route('hr.attendance-policies.index'), { - page: 1, - per_page: pageFilters.per_page - }, { preserveState: true, preserveScroll: true }); - }; - - // Define page actions - const pageActions = []; - - // Add the "Add New Attendance Policy" button if user has permission - if (hasPermission(permissions, 'create-attendance-policies')) { - pageActions.push({ - label: t('Add Attendance Policy'), - icon: , - variant: 'default', - onClick: () => handleAddNew() - }); - } - - const breadcrumbs = [ - { title: t('Dashboard'), href: route('dashboard') }, - { title: t('Shift Management'), href: route('hr.attendance-policies.index') }, - { title: t('Attendance Policies') } - ]; - - // Define table columns - const columns = [ - { - key: 'name', - label: t('Policy Name'), - sortable: true - }, - { - key: 'late_arrival_grace', - label: t('Late Grace (mins)'), - render: (value: number) => ( - {value} - ) - }, - { - key: 'early_departure_grace', - label: t('Early Grace (mins)'), - render: (value: number) => ( - {value} - ) - }, - { - key: 'overtime_rate_per_hour', - label: t('Overtime Rate'), - render: (value: number) => ( - {window.appSettings?.formatCurrency(value)}/hr - ) - }, - { - key: 'status', - label: t('Status'), - render: (value: string) => { - return ( - - {value === 'active' ? t('Active') : t('Inactive')} - - ); - } - } - ]; - - // Define table actions - const actions = [ - { - label: t('View'), - icon: 'Eye', - action: 'view', - className: 'text-blue-500', - requiredPermission: 'view-attendance-policies' - }, - { - label: t('Edit'), - icon: 'Edit', - action: 'edit', - className: 'text-amber-500', - requiredPermission: 'edit-attendance-policies' - }, - { - label: t('Toggle Status'), - icon: 'Lock', - action: 'toggle-status', - className: 'text-amber-500', - requiredPermission: 'edit-attendance-policies' - }, - { - label: t('Delete'), - icon: 'Trash2', - action: 'delete', - className: 'text-red-500', - requiredPermission: 'delete-attendance-policies' - } - ]; - - // Prepare options for filters - const statusOptions = [ - { value: 'all', label: t('All Statuses') , disabled : true}, - { value: 'active', label: t('Active') }, - { value: 'inactive', label: t('Inactive') } - ]; - - - - // Render policy card - const renderPolicyCard = (policy: any) => { - return ( - - -
-
-
- -
-
- - {policy.name} - -
- - {policy.status === 'active' ? t('Active') : t('Inactive')} - -
-
-
- {/* Action Buttons */} -
- {hasPermission(permissions, 'view-attendance-policies') && ( - - )} - {hasPermission(permissions, 'edit-attendance-policies') && ( - - )} - {hasPermission(permissions, 'edit-attendance-policies') && ( - - )} - {hasPermission(permissions, 'delete-attendance-policies') && ( - - )} -
-
-
- -
-
-
- -
-

- {policy.late_arrival_grace} {t('minutes')} -

-

{t('Late Arrival Grace')}

-
-
-
- -
-

- {policy.early_departure_grace} {t('minutes')} -

-

{t('Early Departure Grace')}

-
-
-
-
-
- -
-

- {window.appSettings?.formatCurrency(policy.overtime_rate_per_hour)}/hr -

-

{t('Overtime Rate')}

-
-
-
-
- {policy.description && ( -
-

{policy.description}

-
- )} -
-
- ); - }; - - return ( - - {/* Search and filters section */} -
- { - router.get(route('hr.attendance-policies.index'), { - page: 1, - per_page: parseInt(value), - search: searchTerm || undefined, - status: selectedStatus !== 'all' ? selectedStatus : undefined - }, { preserveState: true, preserveScroll: true }); - }} - perPageOptions={[9, 27, 45, 90]} - /> -
- - {/* Content section */} -
- {/* Summary Cards */} -
- - -
-
-

{t('Total Policies')}

-

{stats?.total || 0}

-
-
- -
-
-
-
- - -
-
-

{t('Active Policies')}

-

- {stats?.active || 0} -

-
-
- -
-
-
-
- - -
-
-

{t('Avg Late Grace')}

-

- {stats?.avg_late_grace || 0} {t('min')} -

-
-
- -
-
-
-
- - -
-
-

{t('Avg Overtime Rate')}

-

- {window.appSettings?.formatCurrency(stats?.avg_overtime_rate || 0)} -

-
-
- -
-
-
-
-
- - {/* Policies Grid */} -
- {attendancePolicies?.data?.map((policy: any) => renderPolicyCard(policy))} -
- - {/* Pagination */} -
- { - const page = new URL(url).searchParams.get('page') || '1'; - router.get(route('hr.attendance-policies.index'), { - page, - search: searchTerm || undefined, - status: selectedStatus !== 'all' ? selectedStatus : undefined, - sort_field: pageFilters.sort_field || undefined, - sort_direction: pageFilters.sort_direction || undefined, - per_page: pageFilters.per_page, - }, { preserveState: true, preserveScroll: true }); - }} - /> -
-
- - {/* Form Modal */} - setIsFormModalOpen(false)} - onSubmit={handleFormSubmit} - formConfig={{ - fields: [ - { name: 'name', label: t('Policy Name'), type: 'text', required: true }, - { name: 'description', label: t('Description'), type: 'textarea' }, - { name: 'late_arrival_grace', label: t('Late Arrival Grace (minutes)'), type: 'number', required: true, min: 0, defaultValue: 15 }, - { name: 'early_departure_grace', label: t('Early Departure Grace (minutes)'), type: 'number', required: true, min: 0, defaultValue: 15 }, - { name: 'overtime_rate_per_hour', label: t('Overtime Rate Per Hour'), type: 'number', required: true, min: 0, step: 0.01, defaultValue: 150 }, - { - name: 'status', - label: t('Status'), - type: 'select', - options: [ - { value: 'active', label: 'Active' }, - { value: 'inactive', label: 'Inactive' } - ], - defaultValue: 'active' - } - ], - modalSize: 'lg' - }} - initialData={currentItem} - title={ - formMode === 'create' - ? t('Add New Attendance Policy') - : t('Edit Attendance Policy') - } - mode={formMode} - /> - - {/* Delete Modal */} - setIsDeleteModalOpen(false)} - onConfirm={handleDeleteConfirm} - itemName={currentItem?.name || ''} - entityName="attendance policy" - /> - {/* View Modal */} - setViewingItem(null)}> - {viewingItem && } - -
- ); -} \ No newline at end of file diff --git a/resources/js/pages/hr/attendance-policies/view.tsx b/resources/js/pages/hr/attendance-policies/view.tsx deleted file mode 100644 index c990ef408..000000000 --- a/resources/js/pages/hr/attendance-policies/view.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; -import { useTranslation } from 'react-i18next'; -import { Shield, Clock, DollarSign, Lock, FileText } from 'lucide-react'; -interface ViewAttendancePolicyProps { - policy: any; -} -export default function View({ policy }: ViewAttendancePolicyProps) { - const { t } = useTranslation(); - return ( - e.preventDefault()}> - -
-
- -
- {t('Attendance Policy Details')} -
-
-
-
-
- -

{policy.name || '-'}

-
-
- -

- - {policy.status === 'active' ? t('Active') : t('Inactive')} - -

-
-
-
-
- -

{policy.late_arrival_grace} {t('minutes')}

-
-
- -

{policy.early_departure_grace} {t('minutes')}

-
-
-
-
- -

- {policy.overtime_rate_per_hour ? `${window.appSettings?.formatCurrency(policy.overtime_rate_per_hour)}/hr` : '-'} -

-
-
- {policy.description && ( -
- -

{policy.description}

-
- )} -
-
- ); -} diff --git a/resources/js/pages/hr/employees/create.tsx b/resources/js/pages/hr/employees/create.tsx index 2155845ba..2bd8d0a5f 100755 --- a/resources/js/pages/hr/employees/create.tsx +++ b/resources/js/pages/hr/employees/create.tsx @@ -46,7 +46,6 @@ export default function EmployeeCreate() { designation_id: '', shift_id: '', rest_days: [] as string[], - attendance_policy_id: '', date_of_joining: '', employment_type: 'Full-time', @@ -610,26 +609,6 @@ export default function EmployeeCreate() { {errors.shift_id &&

{errors.shift_id}

} -
- - - {errors.attendance_policy_id &&

{errors.attendance_policy_id}

} -
-
diff --git a/resources/js/pages/hr/employees/edit.tsx b/resources/js/pages/hr/employees/edit.tsx index c79b864ff..c32385bb9 100755 --- a/resources/js/pages/hr/employees/edit.tsx +++ b/resources/js/pages/hr/employees/edit.tsx @@ -37,7 +37,6 @@ export default function EmployeeEdit() { designation_id: employee.employee?.designation_id ? employee.employee.designation_id.toString() : '', shift_id: employee.employee?.shift_id ? employee.employee.shift_id.toString() : '', rest_days: employee.employee?.rest_days || [], - attendance_policy_id: employee.employee?.attendance_policy_id ? employee.employee.attendance_policy_id.toString() : '', date_of_joining: employee.employee?.date_of_joining || '', employment_type: employee.employee?.employment_type || 'Full-time', @@ -641,26 +640,6 @@ export default function EmployeeEdit() { {errors.shift_id &&

{errors.shift_id}

}
-
- - - {errors.attendance_policy_id &&

{errors.attendance_policy_id}

} -
-
diff --git a/routes/web.php b/routes/web.php index 7b236175e..ad39e538d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -5,7 +5,6 @@ use App\Http\Controllers\ActionItemController; use App\Http\Controllers\AnnouncementController; use App\Http\Controllers\AssetController; use App\Http\Controllers\AssetTypeController; -use App\Http\Controllers\AttendancePolicyController; use App\Http\Controllers\AttendanceRecordController; use App\Http\Controllers\AttendanceRegularizationController; use App\Http\Controllers\AuthorizeNetPaymentController; @@ -1081,15 +1080,6 @@ Route::middleware(['auth', 'verified', 'setting'])->group(function () { Route::put('hr/shifts/{shift}/toggle-status', [ShiftController::class, 'toggleStatus'])->middleware('permission:edit-shifts')->name('hr.shifts.toggle-status'); }); - // Attendance Policies routes - Route::middleware('permission:manage-attendance-policies')->group(function () { - Route::get('hr/attendance-policies', [AttendancePolicyController::class, 'index'])->name('hr.attendance-policies.index'); - Route::post('hr/attendance-policies', [AttendancePolicyController::class, 'store'])->middleware('permission:create-attendance-policies')->name('hr.attendance-policies.store'); - Route::put('hr/attendance-policies/{attendancePolicy}', [AttendancePolicyController::class, 'update'])->middleware('permission:edit-attendance-policies')->name('hr.attendance-policies.update'); - Route::delete('hr/attendance-policies/{attendancePolicy}', [AttendancePolicyController::class, 'destroy'])->middleware('permission:delete-attendance-policies')->name('hr.attendance-policies.destroy'); - Route::put('hr/attendance-policies/{attendancePolicy}/toggle-status', [AttendancePolicyController::class, 'toggleStatus'])->middleware('permission:edit-attendance-policies')->name('hr.attendance-policies.toggle-status'); - }); - // Attendance Records routes Route::get('hr/attendance-records/calendar', [AttendanceRecordController::class, 'calendar'])->name('hr.attendance-records.calendar'); Route::get('hr/attendance-records', [AttendanceRecordController::class, 'index'])->name('hr.attendance-records.index');