1+ <?php
2+
3+ namespace App \Modules \HR \Http \Controllers ;
4+
5+ use App \Http \Controllers \Controller ;
6+ use App \Modules \HR \Models \Employee ;
7+ use App \Modules \HR \Models \Timesheet ;
8+ use Carbon \Carbon ;
9+ use Illuminate \Http \RedirectResponse ;
10+ use Illuminate \Http \Request ;
11+ use Inertia \Inertia ;
12+ use Inertia \Response ;
13+
14+ class TimesheetController extends Controller
15+ {
16+ public function index (Request $ request ): Response
17+ {
18+ $ this ->authorize ('viewAny ' , Timesheet::class);
19+
20+ $ timesheets = Timesheet::with (['employee ' ])
21+ ->when ($ request ->employee_id , fn ($ q ) => $ q ->where ('employee_id ' , $ request ->employee_id ))
22+ ->when ($ request ->status , fn ($ q ) => $ q ->where ('status ' , $ request ->status ))
23+ ->orderBy ('week_start ' , 'desc ' )
24+ ->paginate (20 )
25+ ->withQueryString ();
26+
27+ $ employees = Employee::where ('status ' , 'active ' )
28+ ->orderBy ('last_name ' )
29+ ->get (['id ' , 'first_name ' , 'last_name ' ]);
30+
31+ return Inertia::render ('HR/Timesheets/Index ' , [
32+ 'timesheets ' => $ timesheets ,
33+ 'employees ' => $ employees ,
34+ 'filters ' => $ request ->only (['employee_id ' , 'status ' ]),
35+ ]);
36+ }
37+
38+ public function create (): Response
39+ {
40+ $ this ->authorize ('create ' , Timesheet::class);
41+
42+ $ employees = Employee::where ('status ' , 'active ' )
43+ ->orderBy ('last_name ' )
44+ ->get (['id ' , 'first_name ' , 'last_name ' ]);
45+
46+ return Inertia::render ('HR/Timesheets/Create ' , [
47+ 'employees ' => $ employees ,
48+ ]);
49+ }
50+
51+ public function store (Request $ request ): RedirectResponse
52+ {
53+ $ this ->authorize ('create ' , Timesheet::class);
54+
55+ $ validated = $ request ->validate ([
56+ 'week_start ' => 'required|date ' ,
57+ 'employee_id ' => 'required|exists:employees,id ' ,
58+ 'notes ' => 'nullable|string ' ,
59+ ]);
60+
61+ $ weekEnd = Carbon::parse ($ validated ['week_start ' ])->endOfWeek (Carbon::SUNDAY )->toDateString ();
62+
63+ Timesheet::create ([
64+ 'tenant_id ' => auth ()->user ()->tenant_id ,
65+ 'employee_id ' => $ validated ['employee_id ' ],
66+ 'week_start ' => $ validated ['week_start ' ],
67+ 'week_end ' => $ weekEnd ,
68+ 'notes ' => $ validated ['notes ' ] ?? null ,
69+ 'status ' => 'draft ' ,
70+ 'total_hours ' => 0 ,
71+ ]);
72+
73+ return redirect ()->back ();
74+ }
75+
76+ public function show (Timesheet $ timesheet ): Response
77+ {
78+ $ this ->authorize ('view ' , $ timesheet );
79+
80+ $ timesheet ->load (['employee ' , 'entries ' , 'approvedBy ' ]);
81+
82+ return Inertia::render ('HR/Timesheets/Show ' , [
83+ 'timesheet ' => $ timesheet ,
84+ ]);
85+ }
86+
87+ public function submit (Timesheet $ timesheet ): RedirectResponse
88+ {
89+ $ this ->authorize ('update ' , $ timesheet );
90+
91+ $ timesheet ->submit ();
92+
93+ return redirect ()->back ();
94+ }
95+
96+ public function approve (Timesheet $ timesheet ): RedirectResponse
97+ {
98+ $ this ->authorize ('update ' , $ timesheet );
99+
100+ $ timesheet ->approve (auth ()->id ());
101+
102+ return redirect ()->back ();
103+ }
104+
105+ public function reject (Timesheet $ timesheet ): RedirectResponse
106+ {
107+ $ this ->authorize ('update ' , $ timesheet );
108+
109+ $ timesheet ->reject ();
110+
111+ return redirect ()->back ();
112+ }
113+
114+ public function addEntry (Request $ request , Timesheet $ timesheet ): RedirectResponse
115+ {
116+ $ this ->authorize ('update ' , $ timesheet );
117+
118+ $ validated = $ request ->validate ([
119+ 'work_date ' => 'required|date ' ,
120+ 'hours ' => 'required|numeric|min:0.25|max:24 ' ,
121+ 'project ' => 'nullable|string|max:255 ' ,
122+ 'description ' => 'nullable|string ' ,
123+ ]);
124+
125+ $ timesheet ->entries ()->create ([
126+ 'tenant_id ' => auth ()->user ()->tenant_id ,
127+ 'timesheet_id ' => $ timesheet ->id ,
128+ 'work_date ' => $ validated ['work_date ' ],
129+ 'hours ' => $ validated ['hours ' ],
130+ 'project ' => $ validated ['project ' ] ?? null ,
131+ 'description ' => $ validated ['description ' ] ?? null ,
132+ ]);
133+
134+ $ timesheet ->recalculateHours ();
135+
136+ return redirect ()->back ();
137+ }
138+
139+ public function destroy (Timesheet $ timesheet ): RedirectResponse
140+ {
141+ $ this ->authorize ('delete ' , $ timesheet );
142+
143+ $ timesheet ->delete ();
144+
145+ return redirect ()->route ('hr.timesheets.index ' );
146+ }
147+
148+ }
0 commit comments