penjadwalan-ga/app/Http/Controllers/Admin/SiswaController.php

574 lines
22 KiB
PHP

<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Guests\PesertaController;
use App\Models\DetailKelas;
use App\Models\HistoriSiswa;
use App\Models\Kelas;
use App\Models\Siswa;
use App\Models\Programs;
use App\Models\User;
use App\Models\Sekolah;
use Illuminate\Database\QueryException;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
class SiswaController extends Controller
{
public function index()
{
$data = Siswa::with('Programs')
->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');
}
}