fix: dropdown kelas ganda — scope forActiveAcademicYear (hanya TA aktif), ikuti filter TA di index; berlaku juga untuk form siswa, import, keluar, mutasi, prestasi, self-service
This commit is contained in:
@@ -27,6 +27,7 @@ class StudentSyncController extends Controller
|
|||||||
'academicYear:id,name,start_year,end_year,is_active',
|
'academicYear:id,name,start_year,end_year,is_active',
|
||||||
'department:id,code,name,description,is_active',
|
'department:id,code,name,description,is_active',
|
||||||
'classRoom:id,academic_year_id,department_id,name,level,is_active',
|
'classRoom:id,academic_year_id,department_id,name,level,is_active',
|
||||||
|
'parents:id,student_id,relation_type,name,nik,phone_number,is_alive',
|
||||||
])
|
])
|
||||||
->orderBy('full_name')
|
->orderBy('full_name')
|
||||||
->get([
|
->get([
|
||||||
@@ -99,6 +100,17 @@ class StudentSyncController extends Controller
|
|||||||
'email' => $student->email,
|
'email' => $student->email,
|
||||||
'photo_path' => $student->photo_path,
|
'photo_path' => $student->photo_path,
|
||||||
'notes' => $student->notes,
|
'notes' => $student->notes,
|
||||||
|
'parents' => $student->parents
|
||||||
|
->where('is_alive', true)
|
||||||
|
->values()
|
||||||
|
->map(fn ($p) => [
|
||||||
|
'id' => $p->id,
|
||||||
|
'relation' => $p->relation_type,
|
||||||
|
'name' => $p->name,
|
||||||
|
'nik' => $p->nik,
|
||||||
|
'phone_number' => $p->phone_number,
|
||||||
|
])
|
||||||
|
->all(),
|
||||||
'updated_at' => $student->updated_at?->toISOString(),
|
'updated_at' => $student->updated_at?->toISOString(),
|
||||||
];
|
];
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class StudentAchievementController extends Controller
|
|||||||
'category' => $category,
|
'category' => $category,
|
||||||
],
|
],
|
||||||
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
||||||
'classes' => SchoolClass::orderBy('name')->pluck('name', 'id'),
|
'classes' => SchoolClass::forActiveAcademicYear()->orderBy('name')->pluck('name', 'id'),
|
||||||
'categoryOptions' => $categoryOptions,
|
'categoryOptions' => $categoryOptions,
|
||||||
'levelOptions' => $this->levelOptions(),
|
'levelOptions' => $this->levelOptions(),
|
||||||
'summary' => [
|
'summary' => [
|
||||||
|
|||||||
@@ -187,7 +187,11 @@ class StudentController extends Controller
|
|||||||
],
|
],
|
||||||
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
||||||
'departments' => Department::where('is_active', true)->orderBy('name')->pluck('name', 'id'),
|
'departments' => Department::where('is_active', true)->orderBy('name')->pluck('name', 'id'),
|
||||||
'classes' => SchoolClass::orderBy('name')->pluck('name', 'id'),
|
'classes' => SchoolClass::when(
|
||||||
|
$academicYearId,
|
||||||
|
fn ($query) => $query->where('academic_year_id', $academicYearId),
|
||||||
|
fn ($query) => $query->forActiveAcademicYear()
|
||||||
|
)->orderBy('name')->pluck('name', 'id'),
|
||||||
'statuses' => $viewConfig['view'] === 'all'
|
'statuses' => $viewConfig['view'] === 'all'
|
||||||
? [
|
? [
|
||||||
'active' => 'Aktif',
|
'active' => 'Aktif',
|
||||||
@@ -506,9 +510,6 @@ class StudentController extends Controller
|
|||||||
'Tanggal Lahir (YYYY-MM-DD)',
|
'Tanggal Lahir (YYYY-MM-DD)',
|
||||||
'Agama',
|
'Agama',
|
||||||
'Kewarganegaraan',
|
'Kewarganegaraan',
|
||||||
'No. Kartu Keluarga',
|
|
||||||
'Anak Ke',
|
|
||||||
'Jumlah Saudara',
|
|
||||||
'Nomor HP',
|
'Nomor HP',
|
||||||
'Email',
|
'Email',
|
||||||
'Alamat',
|
'Alamat',
|
||||||
@@ -523,30 +524,6 @@ class StudentController extends Controller
|
|||||||
'Tanggal Masuk (YYYY-MM-DD)',
|
'Tanggal Masuk (YYYY-MM-DD)',
|
||||||
'Status',
|
'Status',
|
||||||
'Catatan',
|
'Catatan',
|
||||||
'Nama Ayah',
|
|
||||||
'NIK Ayah',
|
|
||||||
'Tahun Lahir Ayah',
|
|
||||||
'Pendidikan Ayah',
|
|
||||||
'Pekerjaan Ayah',
|
|
||||||
'No. HP Ayah',
|
|
||||||
'Alamat Ayah',
|
|
||||||
'Status Hidup Ayah',
|
|
||||||
'Nama Ibu',
|
|
||||||
'NIK Ibu',
|
|
||||||
'Tahun Lahir Ibu',
|
|
||||||
'Pendidikan Ibu',
|
|
||||||
'Pekerjaan Ibu',
|
|
||||||
'No. HP Ibu',
|
|
||||||
'Alamat Ibu',
|
|
||||||
'Status Hidup Ibu',
|
|
||||||
'Nama Wali',
|
|
||||||
'NIK Wali',
|
|
||||||
'Tahun Lahir Wali',
|
|
||||||
'Pendidikan Wali',
|
|
||||||
'Pekerjaan Wali',
|
|
||||||
'No. HP Wali',
|
|
||||||
'Alamat Wali',
|
|
||||||
'Status Hidup Wali',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
$sheet->fromArray($headers, null, 'A1');
|
$sheet->fromArray($headers, null, 'A1');
|
||||||
@@ -560,9 +537,6 @@ class StudentController extends Controller
|
|||||||
'2010-01-15',
|
'2010-01-15',
|
||||||
'Islam',
|
'Islam',
|
||||||
'Indonesia',
|
'Indonesia',
|
||||||
'3512345678901235',
|
|
||||||
'1',
|
|
||||||
'2',
|
|
||||||
'081234567890',
|
'081234567890',
|
||||||
'contoh@siswa.local',
|
'contoh@siswa.local',
|
||||||
'Jl. Contoh No. 1',
|
'Jl. Contoh No. 1',
|
||||||
@@ -577,30 +551,6 @@ class StudentController extends Controller
|
|||||||
'2026-07-15',
|
'2026-07-15',
|
||||||
'active',
|
'active',
|
||||||
'Catatan opsional',
|
'Catatan opsional',
|
||||||
'Budi Santoso',
|
|
||||||
'3512345678901111',
|
|
||||||
'1980',
|
|
||||||
'SMA',
|
|
||||||
'Wiraswasta',
|
|
||||||
'081200000001',
|
|
||||||
'Jl. Ayah No. 1',
|
|
||||||
'Ya',
|
|
||||||
'Siti Aminah',
|
|
||||||
'3512345678902222',
|
|
||||||
'1982',
|
|
||||||
'SMA',
|
|
||||||
'Ibu Rumah Tangga',
|
|
||||||
'081200000002',
|
|
||||||
'Jl. Ibu No. 1',
|
|
||||||
'Ya',
|
|
||||||
'Ahmad Wali',
|
|
||||||
'3512345678903333',
|
|
||||||
'1975',
|
|
||||||
'S1',
|
|
||||||
'Pegawai Swasta',
|
|
||||||
'081200000003',
|
|
||||||
'Jl. Wali No. 1',
|
|
||||||
'Ya',
|
|
||||||
], null, 'A2');
|
], null, 'A2');
|
||||||
|
|
||||||
for ($columnIndex = 1; $columnIndex <= count($headers); $columnIndex++) {
|
for ($columnIndex = 1; $columnIndex <= count($headers); $columnIndex++) {
|
||||||
@@ -636,9 +586,6 @@ class StudentController extends Controller
|
|||||||
['Tanggal Lahir (YYYY-MM-DD)', 'Format contoh: 2010-01-15.'],
|
['Tanggal Lahir (YYYY-MM-DD)', 'Format contoh: 2010-01-15.'],
|
||||||
['Agama', 'Opsional, contoh: Islam, Kristen, Katolik, Hindu, Buddha, Konghucu.'],
|
['Agama', 'Opsional, contoh: Islam, Kristen, Katolik, Hindu, Buddha, Konghucu.'],
|
||||||
['Kewarganegaraan', 'Opsional, default aman: Indonesia.'],
|
['Kewarganegaraan', 'Opsional, default aman: Indonesia.'],
|
||||||
['No. Kartu Keluarga', 'Opsional.'],
|
|
||||||
['Anak Ke', 'Opsional, angka bulat minimal 1.'],
|
|
||||||
['Jumlah Saudara', 'Opsional, angka bulat minimal 0.'],
|
|
||||||
['Nomor HP', 'Opsional.'],
|
['Nomor HP', 'Opsional.'],
|
||||||
['Email', 'Opsional, harus format email valid bila diisi.'],
|
['Email', 'Opsional, harus format email valid bila diisi.'],
|
||||||
['Alamat', 'Opsional.'],
|
['Alamat', 'Opsional.'],
|
||||||
@@ -652,31 +599,6 @@ class StudentController extends Controller
|
|||||||
['Kelas', 'Isi dengan nama kelas persis seperti sheet Referensi.'],
|
['Kelas', 'Isi dengan nama kelas persis seperti sheet Referensi.'],
|
||||||
['Tanggal Masuk (YYYY-MM-DD)', 'Format contoh: 2026-07-15.'],
|
['Tanggal Masuk (YYYY-MM-DD)', 'Format contoh: 2026-07-15.'],
|
||||||
['Status', 'Gunakan: active, inactive, transferred, graduated, dropped.'],
|
['Status', 'Gunakan: active, inactive, transferred, graduated, dropped.'],
|
||||||
['Catatan', 'Opsional.'],
|
|
||||||
['Nama Ayah', 'Opsional.'],
|
|
||||||
['NIK Ayah', 'Opsional.'],
|
|
||||||
['Tahun Lahir Ayah', 'Opsional, angka 4 digit.'],
|
|
||||||
['Pendidikan Ayah', 'Opsional.'],
|
|
||||||
['Pekerjaan Ayah', 'Opsional.'],
|
|
||||||
['No. HP Ayah', 'Opsional.'],
|
|
||||||
['Alamat Ayah', 'Opsional.'],
|
|
||||||
['Status Hidup Ayah', 'Opsional, isi Ya/Tidak atau Hidup/Meninggal.'],
|
|
||||||
['Nama Ibu', 'Opsional.'],
|
|
||||||
['NIK Ibu', 'Opsional.'],
|
|
||||||
['Tahun Lahir Ibu', 'Opsional, angka 4 digit.'],
|
|
||||||
['Pendidikan Ibu', 'Opsional.'],
|
|
||||||
['Pekerjaan Ibu', 'Opsional.'],
|
|
||||||
['No. HP Ibu', 'Opsional.'],
|
|
||||||
['Alamat Ibu', 'Opsional.'],
|
|
||||||
['Status Hidup Ibu', 'Opsional, isi Ya/Tidak atau Hidup/Meninggal.'],
|
|
||||||
['Nama Wali', 'Opsional.'],
|
|
||||||
['NIK Wali', 'Opsional.'],
|
|
||||||
['Tahun Lahir Wali', 'Opsional, angka 4 digit.'],
|
|
||||||
['Pendidikan Wali', 'Opsional.'],
|
|
||||||
['Pekerjaan Wali', 'Opsional.'],
|
|
||||||
['No. HP Wali', 'Opsional.'],
|
|
||||||
['Alamat Wali', 'Opsional.'],
|
|
||||||
['Status Hidup Wali', 'Opsional, isi Ya/Tidak atau Hidup/Meninggal.'],
|
|
||||||
], null, 'A1');
|
], null, 'A1');
|
||||||
foreach (range('A', 'B') as $column) {
|
foreach (range('A', 'B') as $column) {
|
||||||
$guideSheet->getColumnDimension($column)->setAutoSize(true);
|
$guideSheet->getColumnDimension($column)->setAutoSize(true);
|
||||||
@@ -788,11 +710,8 @@ class StudentController extends Controller
|
|||||||
protected function formData(?Student $student = null): array
|
protected function formData(?Student $student = null): array
|
||||||
{
|
{
|
||||||
$classOptionsQuery = SchoolClass::query()
|
$classOptionsQuery = SchoolClass::query()
|
||||||
->when(
|
->forActiveAcademicYear()
|
||||||
$student?->class_id,
|
->when($student?->class_id, fn ($query) => $query->orWhere('id', $student->class_id))
|
||||||
fn ($query) => $query->where('is_active', true)->orWhere('id', $student->class_id),
|
|
||||||
fn ($query) => $query->where('is_active', true)
|
|
||||||
)
|
|
||||||
->orderBy('name');
|
->orderBy('name');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
@@ -829,7 +748,7 @@ class StudentController extends Controller
|
|||||||
{
|
{
|
||||||
$academicYears = AcademicYear::where('is_active', true)->orderBy('name')->pluck('name', 'id');
|
$academicYears = AcademicYear::where('is_active', true)->orderBy('name')->pluck('name', 'id');
|
||||||
$departments = Department::where('is_active', true)->orderBy('name')->pluck('name', 'id');
|
$departments = Department::where('is_active', true)->orderBy('name')->pluck('name', 'id');
|
||||||
$classes = SchoolClass::with(['academicYear', 'department'])->where('is_active', true)->orderBy('name')->get();
|
$classes = SchoolClass::with(['academicYear', 'department'])->forActiveAcademicYear()->where('is_active', true)->orderBy('name')->get();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'academicYears' => $academicYears,
|
'academicYears' => $academicYears,
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class StudentExitController extends Controller
|
|||||||
],
|
],
|
||||||
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
||||||
'departments' => Department::orderBy('name')->pluck('name', 'id'),
|
'departments' => Department::orderBy('name')->pluck('name', 'id'),
|
||||||
'classes' => SchoolClass::orderBy('name')->pluck('name', 'id'),
|
'classes' => SchoolClass::forActiveAcademicYear()->orderBy('name')->pluck('name', 'id'),
|
||||||
'summary' => [
|
'summary' => [
|
||||||
'total' => $totalExits,
|
'total' => $totalExits,
|
||||||
'with_letter' => $withLetterCount,
|
'with_letter' => $withLetterCount,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ class StudentSelfServiceController extends Controller
|
|||||||
'status' => $status,
|
'status' => $status,
|
||||||
],
|
],
|
||||||
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
||||||
'classes' => SchoolClass::orderBy('name')->pluck('name', 'id'),
|
'classes' => SchoolClass::forActiveAcademicYear()->orderBy('name')->pluck('name', 'id'),
|
||||||
'statuses' => $statusLabels,
|
'statuses' => $statusLabels,
|
||||||
'summary' => [
|
'summary' => [
|
||||||
'total' => (clone $summaryBaseQuery)->count(),
|
'total' => (clone $summaryBaseQuery)->count(),
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ class StudentTransferController extends Controller
|
|||||||
],
|
],
|
||||||
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
'academicYears' => AcademicYear::orderBy('name')->pluck('name', 'id'),
|
||||||
'departments' => Department::orderBy('name')->pluck('name', 'id'),
|
'departments' => Department::orderBy('name')->pluck('name', 'id'),
|
||||||
'classes' => SchoolClass::orderBy('name')->pluck('name', 'id'),
|
'classes' => SchoolClass::forActiveAcademicYear()->orderBy('name')->pluck('name', 'id'),
|
||||||
'summary' => [
|
'summary' => [
|
||||||
'total' => $totalTransfers,
|
'total' => $totalTransfers,
|
||||||
'with_letter' => $withLetterCount,
|
'with_letter' => $withLetterCount,
|
||||||
|
|||||||
@@ -36,6 +36,14 @@ class SchoolClass extends Model
|
|||||||
return $this->belongsTo(AcademicYear::class);
|
return $this->belongsTo(AcademicYear::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope: hanya kelas pada tahun ajaran yang sedang aktif.
|
||||||
|
*/
|
||||||
|
public function scopeForActiveAcademicYear($query)
|
||||||
|
{
|
||||||
|
return $query->whereHas('academicYear', fn ($q) => $q->where('is_active', true));
|
||||||
|
}
|
||||||
|
|
||||||
public function department(): BelongsTo
|
public function department(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Department::class);
|
return $this->belongsTo(Department::class);
|
||||||
|
|||||||
@@ -148,9 +148,6 @@
|
|||||||
<li><strong>date_of_birth</strong> — tanggal lahir</li>
|
<li><strong>date_of_birth</strong> — tanggal lahir</li>
|
||||||
<li><strong>religion</strong> — agama</li>
|
<li><strong>religion</strong> — agama</li>
|
||||||
<li><strong>nationality</strong> — kewarganegaraan</li>
|
<li><strong>nationality</strong> — kewarganegaraan</li>
|
||||||
<li><strong>family_card_number</strong> — no. kartu keluarga</li>
|
|
||||||
<li><strong>child_order</strong> — anak ke</li>
|
|
||||||
<li><strong>number_of_siblings</strong> — jumlah saudara</li>
|
|
||||||
<li><strong>phone_number</strong> — nomor HP</li>
|
<li><strong>phone_number</strong> — nomor HP</li>
|
||||||
<li><strong>email</strong> — email</li>
|
<li><strong>email</strong> — email</li>
|
||||||
<li><strong>address</strong> — alamat</li>
|
<li><strong>address</strong> — alamat</li>
|
||||||
@@ -165,9 +162,6 @@
|
|||||||
<li><strong>entry_date</strong> — tanggal masuk</li>
|
<li><strong>entry_date</strong> — tanggal masuk</li>
|
||||||
<li><strong>status</strong> — status siswa</li>
|
<li><strong>status</strong> — status siswa</li>
|
||||||
<li><strong>notes</strong> — catatan</li>
|
<li><strong>notes</strong> — catatan</li>
|
||||||
<li><strong>parent_father_*</strong> — data ayah</li>
|
|
||||||
<li><strong>parent_mother_*</strong> — data ibu</li>
|
|
||||||
<li><strong>parent_guardian_*</strong> — data wali</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</x-master-card>
|
</x-master-card>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Testing\WithoutMiddleware;
|
||||||
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REPRO SEMENTARA: memicu route update siswa keluar terhadap DB PRODUKSI.
|
||||||
|
* Tidak memakai RefreshDatabase. Data tidak diubah (nilai dikirim kosong).
|
||||||
|
* Hanya untuk menangkap exception yang bikin 500 di /students/keluar/{id} POST.
|
||||||
|
*/
|
||||||
|
class ReproExitTest extends TestCase
|
||||||
|
{
|
||||||
|
use WithoutMiddleware;
|
||||||
|
|
||||||
|
public function test_repro_update_exit_31(): void
|
||||||
|
{
|
||||||
|
// Pakai DB produksi
|
||||||
|
config(['database.default' => 'mysql']);
|
||||||
|
\Illuminate\Support\Facades\DB::purge('mysql');
|
||||||
|
|
||||||
|
$exit = \App\Models\StudentExit::find(31);
|
||||||
|
$this->assertNotNull($exit, 'exit 31 tidak ditemukan');
|
||||||
|
|
||||||
|
$res = $this->patch("/students/keluar/{$exit->id}", [
|
||||||
|
'exit_date' => '',
|
||||||
|
'exit_reason' => '',
|
||||||
|
]);
|
||||||
|
|
||||||
|
fwrite(STDERR, 'STATUS: '.$res->getStatusCode()."\n");
|
||||||
|
if (isset($res->exception)) {
|
||||||
|
fwrite(STDERR, 'EXC: '.get_class($res->exception).': '.$res->exception->getMessage()."\n");
|
||||||
|
fwrite(STDERR, 'AT: '.$res->exception->getFile().':'.$res->exception->getLine()."\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user