最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

laravel - Currently, i'm working on attendance part which user can clock in and clock out - Stack Overflow

programmeradmin1浏览0评论

So supposedly, when user open the system only the clock in button enable, while clock out button disable. when user clicks on the clock in button, the button will be disabled and clock out button enable. So at the end of the day, both button will be disabled as user had clockedin/out. But, the problem is, the clock out button not working. Also, the clock in button is working but it don't enable back after 10 p.m as i set before.

Here my AttendanceController

public function store(Request $request)
{
    $user = auth()->user();
    $currentDate = Carbon::today(); // Ensure this is the current date

    $request->validate([
        'employee_id' => 'required',
        'att_in' => 'required|date_format:H:i:s',
        'attendance_status_id' => 'required|integer',
        'att_out' => 'required|date_format:H:i:s',
    ]);

    // Check the time for attendance status
    $status = $this->attendanceStatus($request->att_in);

    // Fetch the user's attendance record for today
    $attendance = Attendance::where('employee_id', $user->id)
                             ->whereDate('date', $currentDate)
                             ->first();

    // Handle clock-in scenario
    if ($request->has('clockIn')) {  // Check if 'clockIn' was sent in the request
        if ($attendance && $attendance->att_in) {
            return response()->json(['message' => 'You have already clocked in today.'], 400);
        }

        if (!$attendance) {
            // If no attendance record exists for today, create one
            $attendance = new Attendance();
            $attendance->employee_id = $user->id;
            $attendance->date = $currentDate;
        }

        $attendance->att_in = Carbon::now()->format('H:i:s'); // Set the clock-in time
        $attendance->attendance_status_id = $status; // Set the attendance status
        $attendance->save();

        return response()->json(['message' => 'Clock-in recorded successfully.']);
    }

    // Handle clock-out scenario
    if ($request->has('clockOut')) {  // Check if 'clockOut' was sent in the request
        if (!$attendance) {
            return response()->json(['message' => 'You need to clock in first.'], 400);
        }

        if ($attendance->att_out) {
            return response()->json(['message' => 'You have already clocked out today.'], 400);
        }

        $attendance->att_out = Carbon::now()->format('H:i:s'); // Set the clock-out time
        $attendance->save();

        return response()->json(['message' => 'Clock-out recorded successfully.']);
    }

    return response()->json(['message' => 'Invalid action.'], 400);
}

public function clockIn(Request $request)
{
    $request->validate([
        'att_in' => 'required|date_format:H:i:s',
        'date' => 'required|date_format:Y-m-d',
    ]);

    // Store clock-in data in the session
    $request->session()->put('clockInData', [
        'employee_id' => $request->employee_id,
        'att_in' => $request->att_in,
        'date' => $request->date,
    ]);

    // Check if the user has already clocked in for the day
    $checkDuplication = Attendance::where('employee_id', auth()->user()->employee->id)
        ->where('date', $request->date)
        ->whereNull('att_out') // Ensure the user has not clocked out already
        ->exists();

    if ($checkDuplication) {
        return response()->json(['status' => 'error', 'message' => 'You have already clocked in for the day']);
    }

    // Check the clock-in time and set the status
    $clockInTime = Carbon::parse($request->att_in)->format('H:i:s');
    $status = $this->attendanceStatus($clockInTime);

    // Save clock-in data to the database with the calculated status
    $attendance = new Attendance([
        'employee_id' => auth()->user()->employee->id,
        'att_in' => $request->att_in,
        'date' => $request->date,
        'attendance_status_id' => $status,
    ]);

    $attendance->save();

    // Return the attendance ID and status in the response
    return response()->json([
        'status' => 'success',
        'message' => 'Clock-in successful',
        'attendance_id' => $attendance->id,
        'attendance_status_id' => $status,
    ]);
    
}

public function clockOut(Request $request)
{
    $request->validate([
        'att_out' => 'required|date_format:H:i:s',
        'attendance_id' => 'required|integer',
    ]);

    // Get the authenticated user's ID
    $attendance = Attendance::find($request->attendance_id);

    // Check if the attendance record belongs to the authenticated user
    if ($attendance && $attendance->employee_id === auth()->user()->employee->id) {

        // Check if user has clocked in
        if ($attendance->att_in === null) {
            return response()->json([
                'status' => 'failed',
                'message' => 'You must clock in before clocking out.'
            ], 400);
        }


        if ($attendance->att_out === null) {
            return response()->json([
                'status' => 'success',
                'message' => 'Good bye!.'
            ]);
        }

        // Check if the user has already clocked out
        if ($attendance->att_out !== null) {
            return response()->json([
                'status' => 'error',
                'message' => 'You have already clocked out for the day.'
            ]);
        }

        // Calculate hours between clock-in and clock-out
        $clockInTime = Carbon::parse($attendance->att_in);
        $clockOutTime = Carbon::parse($request->att_out);
        $hoursWorked = $clockOutTime->diff($clockInTime)->format('%H:%I:%S');

        // Update the existing attendance record with clock-out data and hours worked
        $attendance->update([
            'att_out' => $request->att_out,
            'hours_worked' => $hoursWorked,
            'response' => 'Total Hours: ' . $hoursWorked,
        ]);

        return response()->json([
            'status' => 'success',
            'message' => 'Clock-out successful',
            'attendance_id' => $attendance->id,
            'hours_worked' => $hoursWorked,
        ]);
    } else {
        return response()->json(['status' => 'error', 'message' => 'Clock-in record not found']);
    }
}

// Helper function to determine the attendance status
protected function attendanceStatus($clockInTime)
{
    if ($clockInTime > '09:01:00') {
        return 4; // Late
    } elseif ($clockInTime < '09:01:00') {
        return 5; // Early
    }
    return 2; // On-time
}

Here my index(button)

<div class="button-container">
                                <button class="btn btn-clock" id="clockIn" clockIn()>Clock In</button>
                                <button class="btn btn-clock" id="clockOut" clockOut()>Clock Out</button>
                            </div>

my Ajax in the index

<script>
    document.addEventListener('DOMContentLoaded', function() {
        const clockIn = document.getElementById('clockIn');
        const clockOut = document.getElementById('clockOut');

        // Check if the user already clocked in/out today
        attendanceStatus();

        if (sessionStorage.getItem('clockedIn') === 'true') {
        clockIn.disabled = true;
        clockOut.disabled = false;
        } 
        else {
            clockIn.disabled = false;
            clockOut.disabled = true;
        }

        clockIn.addEventListener('click', function() {
            if (!clockIn.disabled) {
                clockIn.classList.add('clicked');
                clockInAction();
            }
        });

        clockOut.addEventListener('click', function() {
            if (!clockOut.disabled) {
                clockOut.classList.add('clicked');
                clockOutAction();
            }
        });

        function attendanceStatus() {
            const currentTime = new Date();
            const hour = currentTime.getHours();

            // Check if the time is after 6 pm and before 10 pm to disable clock-in and clock-out buttons
            if (hour >= 18 && hour < 22) {
                clockIn.disabled = true;
                clockOut.disabled = true;
            } else if (hour >= 22) {
                clockIn.disabled = false;
                clockOut.disabled = true;
            }
        }

        // Call attendanceStatus periodically to re-evaluate time conditions
        setInterval(attendanceStatus, 60000);  // Run every minute

        function clockInAction() {  // Renamed function
            var currentDate = new Date().toISOString().split('T')[0];
            var currentTime = new Date().toLocaleTimeString('en-US', { hour12: false }).split(' ')[0];
            var employeeId = {{ auth()->user()->id }};

            $.ajax({
                type: "POST",
                url: "{{ route('clock-in') }}",
                data: {
                    att_in: currentTime,
                    date: currentDate,
                    employee_id: employeeId,
                    _token: '{{ csrf_token() }}'
                },
                success: function (response) {
                    if (response.status === 'success') {
                        sessionStorage.setItem('attendance_id', response.attendance_id);
                        sessionStorage.setItem('clockedIn', true);
                        alert('Clocked In Successfully. Fighting! Status: ' + response.message);

                        // Update button text and disable clock-in button
                        clockIn.innerHTML = "Clocked In";
                        clockOut.innerHTML = "Clock Out";
                        clockOut.disabled = false;
                        clockIn.disabled = true;
                    } else {
                        alert('Clock-in failed: ' + response.message);
                        clockIn.disabled = false;  // Re-enable if clock-in fails
                    }
                },
                error: function (error) {
                    alert('Error clocking in: ' + error.responseJSON.message);
                    clockIn.disabled = false;  // Re-enable if error occurs
                }
            });
        }

        function clockOutAction() {  // Renamed function
            var currentDate = new Date().toISOString().split('T')[0];
            var currentTime = new Date().toLocaleTimeString('en-US', { hour12: false }).split(' ')[0];
            var employeeId = {{ auth()->user()->id }};
            const attendanceId = sessionStorage.getItem('attendance_id');


            $.ajax({
                type: "POST",
                url: "{{ route('clock-out') }}",
                data: {
                    att_out: currentTime,  // Updated to att_out for clock-out action
                    att_in: att_in,
                    date: currentDate,
                    employee_id: employeeId,
                    attendance_id: attendanceId,
                    _token: '{{ csrf_token() }}'
                },
                success: function (response) {
                    if (response.status === 'success') {
                        sessionStorage.setItem('att_in');
                        sessionStorage.setItem('clockedOut', true);
                        alert('Clocked Out Successfully. See You Later! Status: ' + response.message);

                        clockOut.disabled = true;
                        clockIn.disabled = true;
                    } 
                },
                error: function (error) {
                    alert('Error clocking out: ' + error.responseJSON.message);
                    clockOut.disabled = false;  
                }
            });
        }
    });
</script>

DB (attendances table)

In my table, i have: id - employee_id - shift_id(not in used) - date - att_in - att_break - att_resume - att_out - attendance_status_id - response(total hours worked) - (timestamp)

I've already searched on google, youTube, followed ChatGPT, but the results are still the same.

So supposedly, when user open the system only the clock in button enable, while clock out button disable. when user clicks on the clock in button, the button will be disabled and clock out button enable. So at the end of the day, both button will be disabled as user had clockedin/out. But, the problem is, the clock out button not working. Also, the clock in button is working but it don't enable back after 10 p.m as i set before.

Here my AttendanceController

public function store(Request $request)
{
    $user = auth()->user();
    $currentDate = Carbon::today(); // Ensure this is the current date

    $request->validate([
        'employee_id' => 'required',
        'att_in' => 'required|date_format:H:i:s',
        'attendance_status_id' => 'required|integer',
        'att_out' => 'required|date_format:H:i:s',
    ]);

    // Check the time for attendance status
    $status = $this->attendanceStatus($request->att_in);

    // Fetch the user's attendance record for today
    $attendance = Attendance::where('employee_id', $user->id)
                             ->whereDate('date', $currentDate)
                             ->first();

    // Handle clock-in scenario
    if ($request->has('clockIn')) {  // Check if 'clockIn' was sent in the request
        if ($attendance && $attendance->att_in) {
            return response()->json(['message' => 'You have already clocked in today.'], 400);
        }

        if (!$attendance) {
            // If no attendance record exists for today, create one
            $attendance = new Attendance();
            $attendance->employee_id = $user->id;
            $attendance->date = $currentDate;
        }

        $attendance->att_in = Carbon::now()->format('H:i:s'); // Set the clock-in time
        $attendance->attendance_status_id = $status; // Set the attendance status
        $attendance->save();

        return response()->json(['message' => 'Clock-in recorded successfully.']);
    }

    // Handle clock-out scenario
    if ($request->has('clockOut')) {  // Check if 'clockOut' was sent in the request
        if (!$attendance) {
            return response()->json(['message' => 'You need to clock in first.'], 400);
        }

        if ($attendance->att_out) {
            return response()->json(['message' => 'You have already clocked out today.'], 400);
        }

        $attendance->att_out = Carbon::now()->format('H:i:s'); // Set the clock-out time
        $attendance->save();

        return response()->json(['message' => 'Clock-out recorded successfully.']);
    }

    return response()->json(['message' => 'Invalid action.'], 400);
}

public function clockIn(Request $request)
{
    $request->validate([
        'att_in' => 'required|date_format:H:i:s',
        'date' => 'required|date_format:Y-m-d',
    ]);

    // Store clock-in data in the session
    $request->session()->put('clockInData', [
        'employee_id' => $request->employee_id,
        'att_in' => $request->att_in,
        'date' => $request->date,
    ]);

    // Check if the user has already clocked in for the day
    $checkDuplication = Attendance::where('employee_id', auth()->user()->employee->id)
        ->where('date', $request->date)
        ->whereNull('att_out') // Ensure the user has not clocked out already
        ->exists();

    if ($checkDuplication) {
        return response()->json(['status' => 'error', 'message' => 'You have already clocked in for the day']);
    }

    // Check the clock-in time and set the status
    $clockInTime = Carbon::parse($request->att_in)->format('H:i:s');
    $status = $this->attendanceStatus($clockInTime);

    // Save clock-in data to the database with the calculated status
    $attendance = new Attendance([
        'employee_id' => auth()->user()->employee->id,
        'att_in' => $request->att_in,
        'date' => $request->date,
        'attendance_status_id' => $status,
    ]);

    $attendance->save();

    // Return the attendance ID and status in the response
    return response()->json([
        'status' => 'success',
        'message' => 'Clock-in successful',
        'attendance_id' => $attendance->id,
        'attendance_status_id' => $status,
    ]);
    
}

public function clockOut(Request $request)
{
    $request->validate([
        'att_out' => 'required|date_format:H:i:s',
        'attendance_id' => 'required|integer',
    ]);

    // Get the authenticated user's ID
    $attendance = Attendance::find($request->attendance_id);

    // Check if the attendance record belongs to the authenticated user
    if ($attendance && $attendance->employee_id === auth()->user()->employee->id) {

        // Check if user has clocked in
        if ($attendance->att_in === null) {
            return response()->json([
                'status' => 'failed',
                'message' => 'You must clock in before clocking out.'
            ], 400);
        }


        if ($attendance->att_out === null) {
            return response()->json([
                'status' => 'success',
                'message' => 'Good bye!.'
            ]);
        }

        // Check if the user has already clocked out
        if ($attendance->att_out !== null) {
            return response()->json([
                'status' => 'error',
                'message' => 'You have already clocked out for the day.'
            ]);
        }

        // Calculate hours between clock-in and clock-out
        $clockInTime = Carbon::parse($attendance->att_in);
        $clockOutTime = Carbon::parse($request->att_out);
        $hoursWorked = $clockOutTime->diff($clockInTime)->format('%H:%I:%S');

        // Update the existing attendance record with clock-out data and hours worked
        $attendance->update([
            'att_out' => $request->att_out,
            'hours_worked' => $hoursWorked,
            'response' => 'Total Hours: ' . $hoursWorked,
        ]);

        return response()->json([
            'status' => 'success',
            'message' => 'Clock-out successful',
            'attendance_id' => $attendance->id,
            'hours_worked' => $hoursWorked,
        ]);
    } else {
        return response()->json(['status' => 'error', 'message' => 'Clock-in record not found']);
    }
}

// Helper function to determine the attendance status
protected function attendanceStatus($clockInTime)
{
    if ($clockInTime > '09:01:00') {
        return 4; // Late
    } elseif ($clockInTime < '09:01:00') {
        return 5; // Early
    }
    return 2; // On-time
}

Here my index(button)

<div class="button-container">
                                <button class="btn btn-clock" id="clockIn" clockIn()>Clock In</button>
                                <button class="btn btn-clock" id="clockOut" clockOut()>Clock Out</button>
                            </div>

my Ajax in the index

<script>
    document.addEventListener('DOMContentLoaded', function() {
        const clockIn = document.getElementById('clockIn');
        const clockOut = document.getElementById('clockOut');

        // Check if the user already clocked in/out today
        attendanceStatus();

        if (sessionStorage.getItem('clockedIn') === 'true') {
        clockIn.disabled = true;
        clockOut.disabled = false;
        } 
        else {
            clockIn.disabled = false;
            clockOut.disabled = true;
        }

        clockIn.addEventListener('click', function() {
            if (!clockIn.disabled) {
                clockIn.classList.add('clicked');
                clockInAction();
            }
        });

        clockOut.addEventListener('click', function() {
            if (!clockOut.disabled) {
                clockOut.classList.add('clicked');
                clockOutAction();
            }
        });

        function attendanceStatus() {
            const currentTime = new Date();
            const hour = currentTime.getHours();

            // Check if the time is after 6 pm and before 10 pm to disable clock-in and clock-out buttons
            if (hour >= 18 && hour < 22) {
                clockIn.disabled = true;
                clockOut.disabled = true;
            } else if (hour >= 22) {
                clockIn.disabled = false;
                clockOut.disabled = true;
            }
        }

        // Call attendanceStatus periodically to re-evaluate time conditions
        setInterval(attendanceStatus, 60000);  // Run every minute

        function clockInAction() {  // Renamed function
            var currentDate = new Date().toISOString().split('T')[0];
            var currentTime = new Date().toLocaleTimeString('en-US', { hour12: false }).split(' ')[0];
            var employeeId = {{ auth()->user()->id }};

            $.ajax({
                type: "POST",
                url: "{{ route('clock-in') }}",
                data: {
                    att_in: currentTime,
                    date: currentDate,
                    employee_id: employeeId,
                    _token: '{{ csrf_token() }}'
                },
                success: function (response) {
                    if (response.status === 'success') {
                        sessionStorage.setItem('attendance_id', response.attendance_id);
                        sessionStorage.setItem('clockedIn', true);
                        alert('Clocked In Successfully. Fighting! Status: ' + response.message);

                        // Update button text and disable clock-in button
                        clockIn.innerHTML = "Clocked In";
                        clockOut.innerHTML = "Clock Out";
                        clockOut.disabled = false;
                        clockIn.disabled = true;
                    } else {
                        alert('Clock-in failed: ' + response.message);
                        clockIn.disabled = false;  // Re-enable if clock-in fails
                    }
                },
                error: function (error) {
                    alert('Error clocking in: ' + error.responseJSON.message);
                    clockIn.disabled = false;  // Re-enable if error occurs
                }
            });
        }

        function clockOutAction() {  // Renamed function
            var currentDate = new Date().toISOString().split('T')[0];
            var currentTime = new Date().toLocaleTimeString('en-US', { hour12: false }).split(' ')[0];
            var employeeId = {{ auth()->user()->id }};
            const attendanceId = sessionStorage.getItem('attendance_id');


            $.ajax({
                type: "POST",
                url: "{{ route('clock-out') }}",
                data: {
                    att_out: currentTime,  // Updated to att_out for clock-out action
                    att_in: att_in,
                    date: currentDate,
                    employee_id: employeeId,
                    attendance_id: attendanceId,
                    _token: '{{ csrf_token() }}'
                },
                success: function (response) {
                    if (response.status === 'success') {
                        sessionStorage.setItem('att_in');
                        sessionStorage.setItem('clockedOut', true);
                        alert('Clocked Out Successfully. See You Later! Status: ' + response.message);

                        clockOut.disabled = true;
                        clockIn.disabled = true;
                    } 
                },
                error: function (error) {
                    alert('Error clocking out: ' + error.responseJSON.message);
                    clockOut.disabled = false;  
                }
            });
        }
    });
</script>

DB (attendances table)

In my table, i have: id - employee_id - shift_id(not in used) - date - att_in - att_break - att_resume - att_out - attendance_status_id - response(total hours worked) - (timestamp)

I've already searched on google, youTube, followed ChatGPT, but the results are still the same.

Share Improve this question asked Nov 19, 2024 at 3:02 The A.IThe A.I 11 bronze badge 2
  • are there any errors – oelimoe Commented Nov 19, 2024 at 13:57
  • Welcome to StackOverflow, @The A.I. When debugging I advise you to focus on either the backend or the frontend and not both at once. For example, are the controller functions returning the JSON you expect? (check your browser's web inspector). And when debugging the frontend you could hardcode some JSON in the controller (so you know the problem is not with the DB or other code). – JorisJ1 Commented Nov 20, 2024 at 20:07
Add a comment  | 

1 Answer 1

Reset to default 0

When the Javascript starts you first do a attendanceStatus(); to enable/disable based on the hour of the day, and this seems to work alright.

But right below that you immediately override the previous action by enabling/disabling the buttons based on whatever is in sessionStorage.getItem('clockedIn').

You would have to combine the timebased and session checks somehow to get the result you desire.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论