238 lines
7.8 KiB
PHP
238 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use Illuminate\Http\Request;
|
|
use App\Models\Presensi;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use App\Models\Cuti;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class PresensiController extends Controller
|
|
{
|
|
public function store(Request $request)
|
|
{
|
|
try {
|
|
$request->validate([
|
|
'status' => 'required',
|
|
'keterangan' => 'required',
|
|
'photo' => 'required_if:status,Hadir',
|
|
'latitude' => 'required_if:status,Hadir',
|
|
'longitude' => 'required_if:status,Hadir',
|
|
'clock_type' => 'required|in:in,out'
|
|
]);
|
|
|
|
$user = Auth::user();
|
|
$now = Carbon::now();
|
|
|
|
// Cek apakah sudah presensi hari ini untuk clock type yang sama
|
|
$existingPresensi = Presensi::where('user_id', $user->id)
|
|
->whereDate('created_at', $now->toDateString())
|
|
->where('clock_type', $request->clock_type)
|
|
->first();
|
|
|
|
if ($existingPresensi) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Anda sudah melakukan presensi ' .
|
|
($request->clock_type == 'in' ? 'masuk' : 'keluar') .
|
|
' hari ini'
|
|
], 400);
|
|
}
|
|
|
|
// Set status terlambat jika clock in setelah jam 8 pagi
|
|
$status = $request->status;
|
|
if ($request->clock_type == 'in' && $status == 'Hadir') {
|
|
$batasWaktu = Carbon::createFromTime(8, 0, 0); // 08:00:00
|
|
if ($now->greaterThan($batasWaktu)) {
|
|
$status = 'Terlambat';
|
|
}
|
|
}
|
|
|
|
$data = [
|
|
'user_id' => $user->id,
|
|
'status' => $status,
|
|
'keterangan' => $request->keterangan,
|
|
'clock_type' => $request->clock_type
|
|
];
|
|
|
|
// Jika status Hadir, simpan foto dan lokasi
|
|
if ($request->status == 'Hadir') {
|
|
if ($request->hasFile('photo')) {
|
|
$photo = $request->file('photo');
|
|
$filename = time() . '_' . $user->id . '.' . $photo->getClientOriginalExtension();
|
|
$path = $photo->storeAs('public/presensi', $filename);
|
|
$data['foto'] = $filename;
|
|
}
|
|
|
|
$data['latitude'] = $request->latitude;
|
|
$data['longitude'] = $request->longitude;
|
|
}
|
|
|
|
$presensi = Presensi::create($data);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Presensi berhasil disimpan',
|
|
'data' => $presensi
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Error: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function getPresensi(Request $request)
|
|
{
|
|
try {
|
|
$user = auth()->user();
|
|
if (!$user) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Unauthorized'
|
|
], 401);
|
|
}
|
|
|
|
$query = Presensi::where('user_id', $user->id);
|
|
|
|
// Filter by date
|
|
if ($request->has('date')) {
|
|
$query->whereDate('created_at', $request->date);
|
|
}
|
|
|
|
// Filter by status
|
|
if ($request->has('status')) {
|
|
$query->where('status', $request->status);
|
|
}
|
|
|
|
// Filter by clock_type
|
|
if ($request->has('clock_type')) {
|
|
$query->where('clock_type', $request->clock_type);
|
|
}
|
|
|
|
// Sort by latest first
|
|
$presensi = $query->orderBy('created_at', 'desc')->get();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Data presensi berhasil diambil',
|
|
'data' => $presensi
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Error: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function getDashboardStats()
|
|
{
|
|
try {
|
|
$user = Auth::user();
|
|
$currentMonth = Carbon::now()->month;
|
|
$currentYear = Carbon::now()->year;
|
|
|
|
// Hitung jumlah kehadiran bulan ini
|
|
$attendanceCount = Presensi::where('user_id', $user->id)
|
|
->whereMonth('created_at', $currentMonth)
|
|
->whereYear('created_at', $currentYear)
|
|
->where('status', 'Hadir')
|
|
->count();
|
|
|
|
// Hitung sisa cuti
|
|
$totalLeaveTaken = Cuti::where('user_id', $user->id)
|
|
->where('status', 'Disetujui')
|
|
->whereYear('tanggal_mulai', $currentYear)
|
|
->count();
|
|
|
|
// Asumsi total cuti per tahun adalah 12 hari
|
|
$remainingLeave = 12 - $totalLeaveTaken;
|
|
$remainingLeave = max(0, $remainingLeave); // Pastikan tidak negatif
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'attendance_count' => $attendanceCount,
|
|
'remaining_leave' => $remainingLeave
|
|
]
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Gagal mengambil data statistik: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function getMonthlyTotal()
|
|
{
|
|
try {
|
|
$total = Presensi::whereMonth('created_at', Carbon::now()->month)
|
|
->whereYear('created_at', Carbon::now()->year)
|
|
->where('status', 'Hadir')
|
|
->where('clock_type', 'in')
|
|
->count();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => [
|
|
'total' => $total
|
|
]
|
|
]);
|
|
} catch (\Exception $e) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Error: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function getStats()
|
|
{
|
|
try {
|
|
$user = auth()->user();
|
|
if (!$user) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Unauthorized'
|
|
], 401);
|
|
}
|
|
|
|
// Hitung total presensi bulan ini untuk user yang login
|
|
$totalPresensi = Presensi::where('user_id', $user->id)
|
|
->whereMonth('created_at', now()->month)
|
|
->whereYear('created_at', now()->year)
|
|
->where('clock_type', 'in') // Hanya hitung clock in
|
|
->count();
|
|
|
|
Log::info('Presensi stats for user ' . $user->id . ':', ['total' => $totalPresensi]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Data statistik presensi berhasil diambil',
|
|
'data' => [
|
|
'total_presensi' => $totalPresensi
|
|
]
|
|
], 200);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Error getting presensi stats: ' . $e->getMessage());
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Error: ' . $e->getMessage()
|
|
], 500);
|
|
}
|
|
}
|
|
}
|