where('is_active', true) ->get() ->sortByDesc('created_at') ->map(function ($item) { $nama = trim($item->nama_anak); if ($item->double_data_checked) { $item->status_duplikat = 'clear'; return $item; } $sudahTerdaftar = Siswa::where('is_active', 1) ->where('nama_anak', 'LIKE', '%' . $nama . '%') ->where('id', '!=', $item->id) ->exists(); $item->status_duplikat = $sudahTerdaftar ? 'sudah_terdaftar' : 'clear'; return $item; }); $sekolah = Sekolah::where('id', '!=', 0) ->orderBy('nama_sekolah', 'asc')->get(); return view('admin.pages.siswa', compact('data', 'sekolah')); } public function getApprovedListCount(){ $count = Siswa::where('is_active', false)->count(); return response()->json([ 'success' => true, 'count' => $count ]); } public function aprovedList(){ $data = Siswa::with('Programs') ->where('is_active', 0) ->get() ->sortByDesc('created_at') ->map(function ($item) { $nama = trim($item->nama_anak); $sudahTerdaftar = Siswa::where('is_active', 1) ->where(function ($q) use ($nama) { $q->where('nama_anak', 'LIKE', '%' . $nama . '%') ->orWhereRaw('? LIKE CONCAT("%", nama_anak, "%")', [$nama]); }) ->exists(); $item->status_duplikat = $sudahTerdaftar ? 'sudah_terdaftar' : 'clear'; return $item; }); $sekolah = Sekolah::orderByDesc('id')->get(); return view('admin.pages.approval-list-siswa', compact('data', 'sekolah')); } public function compareSiswa(Request $request, $id) { $baru = Siswa::with('Programs', 'sekolah')->find($id); if (!$baru) { if ($request->ajax()) { return response()->json(['error' => 'Data siswa baru tidak ditemukan'], 404); } abort(404, 'Data siswa baru tidak ditemukan'); } $nama = trim($baru->nama_anak); // Cari data aktif yang mirip dua arah dengan nama baru $mirip = Siswa::where('id', '!=', $baru->id) ->where('is_active', 1) ->where(function ($q) use ($nama) { $q->where('nama_anak', 'LIKE', '%' . $nama . '%') ->orWhereRaw('? LIKE CONCAT("%", nama_anak, "%")', [$nama]); }) ->with('Programs', 'sekolah') ->get(); // helper untuk membangun history kelas $buildHistory = function ($peserta) { $dk = DetailKelas::where('siswa_id', $peserta->id)->get(); $kelasIds = $dk->pluck('kelas_id'); $kelasArr = Kelas::whereIn('id', $kelasIds)->get()->map(function ($kelas) use ($dk) { $k = $dk->where('kelas_id', $kelas->id)->first(); return [ 'nama_kelas' => $kelas->nama_kelas, 'jenis_kelas' => $kelas->jenis_kelas ?? '-', 'tanggal_bergabung' => Carbon::parse($k->created_at)->locale('id')->translatedFormat('d M Y'), 'status' => $k->status_siswa ?? '-', ]; }); return ['events' => collect([]), 'kelas' => $kelasArr]; }; // jika request ajax, kirim JSON seperti sebelumnya if ($request->ajax()) { $baruHist = $buildHistory($baru); return response()->json([ 'baru' => array_merge([ 'id' => $baru->id, 'nama_anak' => $baru->nama_anak ?? 'Belum diisi', 'nama_orangtua' => $baru->nama_orangtua ?? 'Belum diisi', 'no_hp_orangtua' => $baru->no_hp_orangtua ?? 'Belum diisi', 'asal_sekolah' => $baru->asal_sekolah ?? optional($baru->sekolah)->nama_sekolah ?? 'Belum diisi', 'kelas' => $baru->kelas ?? 'Belum diisi', 'tanggal_daftar' => optional($baru->created_at)->translatedFormat('d M Y - H:i') ?? 'Belum diisi', 'foto' => $baru->foto ? asset('storage/' . $baru->foto) : ($baru->jenis_kelamin == 'P' ? asset('img/kid-woman.png') : asset('img/kid-man.png')), ], $baruHist), 'mirip' => $mirip->map(function ($s) use ($buildHistory) { $hist = $buildHistory($s); return array_merge([ 'id' => $s->id, 'nama_anak' => $s->nama_anak ?? 'Belum diisi', 'nama_orangtua' => $s->nama_orangtua ?? 'Belum diisi', 'no_hp_orangtua' => $s->no_hp_orangtua ?? 'Belum diisi', 'asal_sekolah' => $s->asal_sekolah ?? optional($s->sekolah)->nama_sekolah ?? 'Belum diisi', 'kelas' => $s->kelas ?? 'Belum diisi', 'tanggal_daftar' => optional($s->created_at)->translatedFormat('d M Y - H:i') ?? 'Belum diisi', 'foto' => $s->foto ? asset('storage/' . $s->foto) : ($s->jenis_kelamin == 'P' ? asset('img/kid-woman.png') : asset('img/kid-man.png')), ], $hist); }), ]); } // tambahkan histori ke objek sebelum kirim ke view $baruHist = $buildHistory($baru); $baru->events = $baruHist['events']; $baru->kelasHistory = $baruHist['kelas']; $mirip->transform(function ($s) use ($buildHistory) { $h = $buildHistory($s); $s->events = $h['events']; $s->kelasHistory = $h['kelas']; return $s; }); // render halaman comparasion bila bukan ajax return view('admin.pages.compare-siswa', compact('baru', 'mirip')); } public function approveSiswa(Request $request) { $request->validate([ 'duplicate_id' => 'required|integer', 'siswa_baru_id' => 'required|integer', 'merge_fields' => 'sometimes|array', 'merge_fields.*' => 'string', ]); $duplicateId = $request->duplicate_id; // ID siswa lama/utama $siswaBaruId = $request->siswa_baru_id; // ID siswa baru (hasil input) $mergeFields = $request->input('merge_fields', []); try { DB::beginTransaction(); $siswaBaru = Siswa::findOrFail($siswaBaruId); if ($siswaBaruId == $duplicateId) { // treat as new student approval $sekolah_id = $siswaBaru->sekolah_id; if (empty($sekolah_id)) { $sekolah = Sekolah::create([ 'nama_sekolah' => $siswaBaru->asal_sekolah ]); $sekolah_id = $sekolah->id; } $siswaBaru->update([ 'is_active' => 1, 'sekolah_id' => $sekolah_id, 'asal_sekolah' => null, 'double_data_checked' => 1 ]); $msg = "Siswa berhasil disetujui"; } else { // update duplicate record with selected fields from new data before merging if (!empty($mergeFields)) { $allowed = [ 'nama_orangtua', 'no_hp_orangtua', 'asal_sekolah', 'kelas', 'tempat_lahir', 'tanggal_lahir', 'jenis_kelamin', 'email', 'program_id', 'status', 'sekolah_id' ]; $updateData = []; foreach ($mergeFields as $field) { if (in_array($field, $allowed) && isset($siswaBaru->$field)) { $updateData[$field] = $siswaBaru->$field; } } if (!empty($updateData)) { Siswa::where('id', $duplicateId)->update($updateData); } } $kelasBaru = DetailKelas::where('siswa_id', $siswaBaruId)->get(); foreach ($kelasBaru as $kelas) { $sudahAda = DetailKelas::where('kelas_id', $kelas->kelas_id) ->where('siswa_id', $duplicateId) ->exists(); if ($sudahAda) { $kelas->delete(); } else { $kelas->update(['siswa_id' => $duplicateId]); } } Siswa::where('id', $duplicateId)->update(['is_active' => 1]); $siswaBaru->delete(); $msg = "Data siswa berhasil digabungkan"; } DB::commit(); return response()->json([ 'status' => 'success', 'message' => $msg, ]); } catch (\Exception $e) { DB::rollBack(); return response()->json([ 'status' => 'error', 'message' => 'Terjadi kesalahan: ' . $e->getMessage(), ], 500); } } public function store(Request $request) { $validated = $request->validate( [ 'nama_anak' => 'required|string|max:255|unique:siswa', 'kelas' => 'required', 'nama_orangtua' => 'required', 'program_id'=> 'required', 'status' => 'required', 'jenis_kelamin' => 'required', 'sekolah_id' => 'nullable', 'asal_sekolah' => 'nullable', ], [ 'nama_anak.required' => 'Nama anak wajib diisi', 'nama_anak.max' => 'Nama anak terlalu panjang', 'nama_anak.unique' => 'Nama anak tersebut sudah ada', 'kelas.required' => 'Kelas wajib diisi', 'nama_orangtua.required' => 'Nama orangtua wajib diisi', 'program_id.required' => 'Program wajib dipilih', 'status.required' => 'Status wajib diisi', 'jenis_kelamin.required' => 'Jenis kelamin anak wajib diisi', ] ); if ($request->no_hp_orangtua !== null || $request->no_hp_orangtua !== ''){ $str = ltrim($request->no_hp_orangtua, '0'); $validated['no_hp_orangtua'] = $str; } if ($request->keterangan !== null || $request->keterangan !== ''){ $validated['keterangan'] = $request->keterangan; }else{ $validated['keterangan'] = null; } if ($request->tempat_lahir !== null || $request->tempat_lahir !== ''){ $validated['tempat_lahir'] = $request->tempat_lahir; } if (!empty($request->tanggal_lahir)) { $validated['tanggal_lahir'] = $request->tanggal_lahir; $validated['usia'] = Carbon::parse($request->tanggal_lahir)->age; } else { $validated['usia'] = $request->usia ?? null; } if ($request->hasFile('foto')) { $file = $request->file('foto'); $hashedName = md5(time() . $file->getClientOriginalName()) . '.' . $file->getClientOriginalExtension(); $file->storeAs('anak', $hashedName, 'public'); $validated['foto'] = 'anak/' . $hashedName; } $validated['register_by'] = 1; $validated['is_active'] = 1; try { $siswa = Siswa::create($validated); $namaProgram = Programs::select('level', 'kelas')->where('id', $request->program_id)->first(); $namaProgram = 'Level '. $namaProgram->level . ' ' . $namaProgram->kelas; // add data to histori siswa HistoriSiswa::create([ 'siswa_id' => $siswa->id, 'status' => $siswa->status, ]); return redirect('/admin/siswa')->with('success', 'Data Berhasil Disimpan'); }catch (QueryException $e){ return redirect('/admin/siswa')->with('error', 'Data anak telah ada'); } } public function getDataSiswa(string $id) { $data = Siswa::with('Programs')->where('id', $id)->first(); if (!$data) { return response()->json(['error' => 'Peserta tidak ditemukan'], 404); } $events = collect([]); $detailKelas = DetailKelas::where('siswa_id', $data->id)->get(); $kelasIds = $detailKelas->pluck('kelas_id'); $kelas = Kelas::whereIn('id', $kelasIds)->get()->map(function ($kelas) use ($detailKelas) { $detailKelasSingle = $detailKelas->where('kelas_id', $kelas->id)->first(); return [ 'nama_kelas' => $kelas->nama_kelas, 'jenis_kelas' => $kelas->jenis_kelas ?? '-', 'tanggal_bergabung' => Carbon::parse($detailKelasSingle->created_at)->locale('id')->translatedFormat('d M Y'), 'status' => $detailKelasSingle->status_siswa ?? '-', ]; }); $created_at = Carbon::parse($data->created_at)->locale('id')->translatedFormat('l, d F Y - H:i') . ' WIB'; $register_by = match ($data->register_by) { 1 => 'Admin', 0 => 'Self (Freetrial)', default => 'Undifined', }; $usia = 0; if ($data->tanggal_lahir == null || $data->tanggal_lahir === '' || $data->tanggal_lahir == '0000-00-00') { $usia = $data->usia ?? null; }else{ $usia = Carbon::parse($data->tanggal_lahir)->age; } return response()->json([ 'id' => $data->id, 'nama_anak' => $data->nama_anak, 'nama_orangtua' => $data->nama_orangtua, 'no_hp_orangtua' => $data->no_hp_orangtua, 'usia' => $usia ?? null, 'kelas' => $data->kelas, 'tempat_lahir' => $data->tempat_lahir ?? null, 'tanggal_lahir' => $data->tanggal_lahir ?? null, 'jenis_kelamin' => $data->jenis_kelamin ?? null, 'email' => $data->email ?? null, 'program_id'=> $data->program_id ?? null, 'program_kelas' => $data->Programs->kelas ?? null, 'level' => $data->Programs->level ?? null, 'program' => optional($data->Programs)->level ? 'Level ' . optional($data->Programs)->level . ' (' . optional($data->Programs)->kelas . ')' : null, 'status' => $data->status ?? null, 'sekolah_id' => $data->sekolah_id ?? null, 'asal_sekolah' => optional($data->sekolah)->nama_sekolah ?? $data->asal_sekolah ?? null, 'keterangan' => $data->keterangan ?? null, 'foto' => $data->foto ?? null, 'tanggal_daftar' => $created_at ?? null, 'register_by' => $register_by ?? null, 'events' => $events, 'histori' => $kelas ]); } public function show(string $id) { $data = Siswa::with(['Programs', 'sekolah'])->findOrFail($id); $detailKelas = DetailKelas::where('siswa_id', $data->id)->get(); $kelasIds = $detailKelas->pluck('kelas_id'); $kelasHistory = Kelas::whereIn('id', $kelasIds)->get()->map(function ($kelas) use ($detailKelas) { $detailKelasSingle = $detailKelas->where('kelas_id', $kelas->id)->first(); return [ 'nama_kelas' => $kelas->nama_kelas, 'jenis_kelas' => $kelas->jenis_kelas ?? '-', 'tanggal_bergabung' => ($detailKelasSingle && $detailKelasSingle->created_at) ? Carbon::parse($detailKelasSingle->created_at)->locale('id')->translatedFormat('d M Y') : '-', 'status' => $detailKelasSingle->status_siswa ?? '-', ]; }); $tanggal_daftar = Carbon::parse($data->created_at)->locale('id')->translatedFormat('d F Y - H:i') . ' WIB'; $register_by = match ($data->register_by) { 1 => 'Admin', 0 => 'Self (Freetrial)', default => 'Undefined', }; $usia = 0; if (empty($data->tanggal_lahir) || $data->tanggal_lahir == '0000-00-00') { $usia = $data->usia ?? null; } else { $usia = Carbon::parse($data->tanggal_lahir)->age; } $sekolah = Sekolah::where('id', '!=', 0) ->orderBy('nama_sekolah', 'asc')->get(); return view('admin.pages.siswa_detail', compact('data', 'kelasHistory', 'tanggal_daftar', 'register_by', 'usia', 'sekolah')); } function getSiswaCount() { $data = Siswa::get(); return response()->json([ 'Semua' => $data->count() ?? null, 'Contacted' => $data->where('status', 'Contacted')->count() ?? null, 'Freetrial' => $data->where('status', 'Freetrial')->count() ?? null, 'Booking' => $data->where('status', 'Booking')->count() ?? null, 'Terdaftar-24-Sesi' => $data->where('status', 'Terdaftar 24 Sesi')->count() ?? null, 'Terdaftar-12-Sesi' => $data->where('status', 'Terdaftar 12 Sesi')->count() ?? null, 'Aktif-24-Sesi' => $data->where('status', 'Aktif 24 Sesi')->count() ?? null, 'Aktif-12-Sesi' => $data->where('status', 'Aktif 12 Sesi')->count() ?? null, 'Aktif-Ekstra' => $data->where('status', 'Aktif Ekstra')->count() ?? null, 'Tidak-Aktif' => $data->where('status', 'Tidak Aktif')->count() ?? null, 'Berhenti' => $data->where('status', 'Berhenti')->count() ?? null, 'Tidak-Tertarik' => $data->where('status', 'Tidak Tertarik')->count() ?? null, ]); } public function update(Request $request, string $id) { $data = Siswa::with('Programs')->findOrFail($id); $validated = $request->validate( [ 'nama_anak' => 'required|string|max:255', 'kelas' => 'required', 'nama_orangtua' => 'required', 'program_id'=> 'required', 'status'=> 'required', 'jenis_kelamin' => 'required', 'sekolah_id' => 'nullable', 'asal_sekolah' => 'nullable', ], [ 'nama_anak.required' => 'Nama anak wajib diisi', 'nama_anak.max' => 'Nama Anak Terlalu Panjang', 'kelas.required' => 'Kelas wajib diisi', 'nama_orangtua.required' => 'Nama orangtua wajib diisi', 'program_id.required' => 'Program wajib dipilih', 'status.required' => 'Status wajib diisi', 'jenis_kelamin.required' => 'Jenis kelamin anak wajib diisi', ] ); if ($request->no_hp_orangtua !== null || $request->no_hp_orangtua !== ''){ $str = ltrim($request->no_hp_orangtua, '0'); $validated['no_hp_orangtua'] = $str; } if ($request->keterangan !== null || $request->keterangan !== ''){ $validated['keterangan'] = $request->keterangan; }else{ $validated['keterangan'] = null; } if ($request->tempat_lahir !== null || $request->tempat_lahir !== ''){ $validated['tempat_lahir'] = $request->tempat_lahir; } if (!empty($request->tanggal_lahir)) { $validated['tanggal_lahir'] = $request->tanggal_lahir; $validated['usia'] = Carbon::parse($request->tanggal_lahir)->age; } else { $validated['usia'] = $request->usia ?? null; } if ($request->hasFile('foto')) { if ($data->foto) { $imagePath = storage_path('app/public/' . $data->foto); if (file_exists($imagePath)) { unlink($imagePath); } } $file = $request->file('foto'); $hashedName = md5(time() . $file->getClientOriginalName()) . '.' . $file->getClientOriginalExtension(); $file->storeAs('anak', $hashedName, 'public'); $validated['foto'] = 'anak/' . $hashedName; } $data->update($validated); // histori siswa check $historiSiswa = HistoriSiswa::where('siswa_id', $id) ->whereMonth('created_at', Carbon::now()->month) ->whereYear('created_at', Carbon::now()->year) ->first(); if(!empty($historiSiswa)){ $historiSiswa->update([ 'status' => $data->status, ]); }else{ HistoriSiswa::create([ 'siswa_id' => $id, 'status' => $data->status, ]); } return redirect('/admin/siswa')->with('success', 'Data Berhasil Diubah'); } public function destroy(string $id) { $data = Siswa::with('Programs')->findOrFail($id); if ($data->foto) { $imagePath = storage_path('app/public/' . $data->foto); if (file_exists($imagePath)) { unlink($imagePath); } } $data->delete(); return redirect('/admin/siswa')->with('success', 'Data Berhasil Dihapus'); } }