siakad-itm/database/seeders/UserSeeder.php

257 lines
8.6 KiB
PHP

<?php
namespace Database\Seeders;
use App\Enums\Semester;
use App\Enums\StudentStatus;
use App\Models\AcademicTerm;
use App\Models\Department;
use App\Models\Lecturer;
use App\Models\Student;
use App\Models\User;
use App\Models\UserProfile;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class UserSeeder extends Seeder
{
public function run(): void
{
$users = [
[
'username' => 'pangestu',
'email' => 'pangestu@student.itmpwk.ac.id',
'roles' => ['mahasiswa', 'developer'],
'profile' => [
'full_name' => 'Yoga Pangestu',
'phone_number' => '082121495806',
'address' => 'Jl. Merdeka No. 1, Purwakarta',
'gender' => 'male',
'birth_place' => 'Subang',
'birth_date' => '2005-03-13',
],
'student' => [
'student_number' => '23010001',
'department_id' => 1,
'enrollment_year' => 2023,
'current_semester' => 5,
'academic_advisor_id' => null,
'status' => StudentStatus::Active,
],
],
[
'username' => 'doni',
'email' => 'doni@student.itmpwk.ac.id',
'roles' => ['mahasiswa'],
'profile' => [
'full_name' => 'Doni Setiawan Ramadhan',
'phone_number' => '085793462823',
'address' => 'Jl. Merdeka No. 1, Purwakarta',
'gender' => 'male',
'birth_place' => 'Purwakarta',
'birth_date' => '2004-10-30',
],
'student' => [
'student_number' => '23020002',
'department_id' => 1,
'enrollment_year' => 2023,
'current_semester' => 5,
'academic_advisor_id' => null,
'status' => StudentStatus::Active,
],
],
[
'username' => 'asep',
'email' => 'asep@student.itmpwk.ac.id',
'roles' => ['mahasiswa'],
'profile' => [
'full_name' => 'Asep Saepudin',
'phone_number' => '081546505033',
'address' => 'Jl. Merdeka No. 1, Purwakarta',
'gender' => 'male',
'birth_place' => 'Purwakarta',
'birth_date' => '2005-09-24',
],
'student' => [
'student_number' => '24010003',
'department_id' => 1,
'enrollment_year' => 2024,
'current_semester' => 3,
'academic_advisor_id' => null,
'status' => StudentStatus::Active,
],
],
[
'username' => 'komala',
'email' => 'komala@student.itmpwk.ac.id',
'roles' => ['mahasiswa'],
'profile' => [
'full_name' => 'Komala Dewi',
'phone_number' => '085819894938',
'address' => 'Jl. Merdeka No. 1, Purwakarta',
'gender' => 'female',
'birth_place' => 'Purwakarta',
'birth_date' => '2005-05-04',
],
'student' => [
'student_number' => '24020004',
'department_id' => 1,
'enrollment_year' => 2024,
'current_semester' => 3,
'academic_advisor_id' => null,
'status' => StudentStatus::Active,
],
],
];
foreach ($users as $userData) {
$roles = $userData['roles'];
$profile = $userData['profile'];
unset($userData['profile'], $userData['roles']);
$student = $userData['student'] ?? null;
$lecturer = $userData['lecturer'] ?? null;
unset($userData['profile'], $userData['student'], $userData['lecturer']);
$userData['password'] = Hash::make(config('app.default_password'));
$user = User::create($userData);
$user->profile()->create($profile);
$user->assignRole($roles);
if ($lecturer) {
$departmentId = $lecturer['department_id'];
unset($lecturer['department_id']);
$createdLecturer = $user->lecturer()->create($lecturer);
$createdLecturer->departments()->attach($departmentId);
}
if ($student) {
$user->student()->create($student);
}
}
$this->seedRandomLecturers();
$this->seedRandomStudents();
$this->seedOtherStaff();
}
/**
* 5-8 dosen acak per jurusan. Sebagian dosen diafiliasikan ke lebih dari
* satu jurusan lewat pivot lecturer_department, sebagian cukup 1 jurusan.
*/
private function seedRandomLecturers(): void
{
$departments = Department::all();
foreach ($departments as $department) {
$count = fake()->numberBetween(5, 8);
$lecturers = collect();
for ($i = 0; $i < $count; $i++) {
$lecturer = $this->createLecturer($department);
$lecturers->push($lecturer);
if (fake()->boolean(35)) {
$otherDepartmentIds = Department::query()
->where('id', '!=', $department->id)
->inRandomOrder()
->limit(fake()->numberBetween(1, 2))
->pluck('id');
$lecturer->departments()->attach($otherDepartmentIds);
}
}
$lecturers->random()->user->assignRole('kaprodi');
}
}
private function createLecturer(Department $department): Lecturer
{
$user = User::factory()->create();
$user->profile()->save(UserProfile::factory()->make());
$user->assignRole('dosen');
$lecturer = $user->lecturer()->save(Lecturer::factory()->makeOne());
$lecturer->departments()->attach($department->id);
return $lecturer;
}
/**
* 8-10 mahasiswa acak per jurusan untuk setiap periode akademik, supaya
* enrollment_year-nya mengikuti tahun ajaran yang benar-benar ada.
*/
private function seedRandomStudents(): void
{
$departments = Department::all();
foreach (AcademicTerm::all() as $term) {
[$startYear, $endYear] = explode('/', $term->name);
$enrollmentYear = $term->semester === Semester::even ? (int) $endYear : (int) $startYear;
foreach ($departments as $department) {
$count = fake()->numberBetween(8, 10);
for ($i = 0; $i < $count; $i++) {
$this->createStudent($department, $enrollmentYear);
}
}
}
}
private function createStudent(Department $department, int $enrollmentYear): Student
{
$user = User::factory()->create();
$user->profile()->save(UserProfile::factory()->make());
$user->assignRole('mahasiswa');
$advisorId = Lecturer::query()
->whereRelation('departments', 'departments.id', $department->id)
->inRandomOrder()
->value('id');
$status = fake()->randomElement([
StudentStatus::Active,
StudentStatus::Active,
StudentStatus::Active,
StudentStatus::OnLeave,
StudentStatus::Graduated,
StudentStatus::DroppedOut,
]);
return $user->student()->save(Student::factory()->makeOne([
'department_id' => $department->id,
'enrollment_year' => $enrollmentYear,
'academic_advisor_id' => $advisorId,
'status' => $status,
]));
}
/**
* Sejumlah kecil akun staf lain supaya tiap role punya data acak juga.
*/
private function seedOtherStaff(): void
{
$roleCounts = [
'staff-admin' => 2,
'staff-keuangan' => 2,
'developer' => 2,
];
foreach ($roleCounts as $role => $count) {
for ($i = 0; $i < $count; $i++) {
$user = User::factory()->create();
$user->profile()->save(UserProfile::factory()->make());
$user->assignRole($role);
}
}
}
}