From e5cb2e916c328ba7abf0c38d94786df9d5ec2c0a Mon Sep 17 00:00:00 2001 From: jouel88 Date: Thu, 19 Mar 2026 21:58:48 +0700 Subject: [PATCH] seeder --- README.md | 71 ++++++++++++++ database/seeders/DatabaseSeeder.php | 65 +++++-------- database/seeders/JenisIzinSeeder.php | 15 ++- database/seeders/MasterDataSeeder.php | 106 ++++++++++++--------- database/seeders/PengajuanIzinSeeder.php | 6 +- database/seeders/PresensiSeeder.php | 7 +- database/seeders/PresensiStatusSeeder.php | 20 ++-- database/seeders/StatusPengajuanSeeder.php | 15 ++- 8 files changed, 192 insertions(+), 113 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..37ca69f6 --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# MPG HRIS - Web Management System + +Sistem Manajemen Sumber Daya Manusia (HRIS) terintegrasi untuk pengelolaan data pegawai, presensi, lembur, dan perizinan. Dibuat menggunakan framework Laravel dengan fokus pada performa dan kemudahan penggunaan. + +## 🚀 Tech Stack + +- **Backend**: Laravel 12.x (PHP 8.2+) +- **Frontend**: Blade Templates + Tailwind CSS (v3.x) +- **Database**: MySQL 8.x +- **Icons**: Heroicons (SVG inline) +- **Komponen UI**: Custom Blade Components (Table, Modal, Input, Button, dll.) + +## 🛠 Panduan Instalasi + +Ikuti langkah-langkah berikut untuk menjalankan proyek di lingkungan lokal: + +1. **Clone & Setup Environment** + ```bash + cp .env.example .env + # Sesuaikan DB_DATABASE, DB_USERNAME, DB_PASSWORD di .env + ``` + +2. **Instal Dependensi Backend** + ```bash + composer install + ``` + +3. **Instal Dependensi Frontend** + ```bash + npm install + npm run build # atau npm run dev untuk development + ``` + +4. **Generate App Key & Database** + ```bash + php artisan key:generate + php artisan migrate --seed + ``` + +5. **Akses Aplikasi** + Jalankan `php artisan serve` dan buka `http://localhost:8000`. + +## 📂 Struktur Proyek & Arsitektur + +Proyek ini mengikuti standar **Clean Code** Laravel dengan pemisahan tanggung jawab yang jelas: + +- **Form Requests**: Semua validasi input diletakkan di `app/Http/Requests`. +- **Controllers**: Fokus pada pengaturan trafik. Logika query berat dipisahkan ke Eloquent Scopes atau Service. +- **Models**: Menggunakan relasi Eloquent yang jelas dan penamaan kolom `snake_case` Bahasa Indonesia. +- **Resources**: UI dibangun menggunakan komponen Blade di `resources/views/components`. + +## 📜 Aturan Pengembangan (Project Rules) + +1. **Bahasa**: Gunakan Bahasa Indonesia untuk penjelasan, komentar, dan dokumentasi. +2. **Naming Convention**: + - Primary Key: `id_nama_tabel` (contoh: `id_divisi`, `id_jabatan`). + - Tabel Master: `snake_case`. +3. **UI Components**: Gunakan komponen yang sudah ada untuk konsistensi: + - ``: Wrapper tabel standar. + - `` & ``: Input form standar. + - `` & ``: Tombol aksi. + - ``: Untuk CRUD Data Master sederhana. + +## 🔑 Akun Default (Seeder) + +- **Super Admin**: `superadmin@mpg.co.id` / `password` +- **Admin**: `admin@mpg.co.id` / `admin123` +- **Pegawai**: `budi@mpg.co.id` / `Mpg123!` + +--- +Developed by MPG Team. diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php index fcafb48e..8864ba61 100644 --- a/database/seeders/DatabaseSeeder.php +++ b/database/seeders/DatabaseSeeder.php @@ -10,55 +10,38 @@ class DatabaseSeeder extends Seeder { public function run(): void { - - DB::table('lokasi_kantor')->insert([ - [ - 'nama_kantor' => 'Notis Digital', - 'alamat' => 'Jln. Kalimantan No. 1, Jember', - 'latitude' => -8.172110, - 'longitude' => 113.700550, - 'radius_meter' => 200, - 'created_at' => now(), - 'updated_at' => now(), - ], - [ - 'nama_kantor' => 'Curah Manis Studio', - 'alamat' => 'Jln. Mastrip, Jember', - 'latitude' => -8.172110, - 'longitude' => 113.700550, - 'radius_meter' => 200, - 'created_at' => now(), - 'updated_at' => now(), - ] - ]); - - User::factory(10)->create([ - 'id_kantor' => 1, - ]); - - User::factory(15)->create([ - 'id_kantor' => 2, - ]); - - User::factory()->create([ - 'nama_lengkap' => 'Julian (Super Admin)', - 'email' => 'julian@admin.com', - 'password' => bcrypt('password'), - 'divisi' => 'IT', - 'jabatan' => 'Manager', - 'id_kantor' => 1, - ]); - + // Panggil MasterDataSeeder terlebih dahulu untuk data dasar (Divisi, Jabatan, Kantor, Role, User Admin) $this->call([ MasterDataSeeder::class, + ]); + + // Tambahan data demo jika diperlukan (Opsional) + $kantor = \App\Models\Kantor::first(); + $divisi = \App\Models\Divisi::first(); + $jabatan = \App\Models\Jabatan::where('nama_jabatan', 'Staff')->first() ?? \App\Models\Jabatan::first(); + + $users = User::factory(5)->create([ + 'id_kantor' => $kantor->id_kantor, + 'id_divisi' => $divisi->id_divisi, + 'id_jabatan' => $jabatan->id_jabatan, + ]); + + $rolePegawai = \App\Models\Role::where('nama_role', 'pegawai')->first(); + if ($rolePegawai) { + foreach ($users as $user) { + $user->roles()->attach($rolePegawai->id_role); + } + } + + // Panggil seeder fitur lainnya + $this->call([ PermissionSeeder::class, PresensiStatusSeeder::class, PresensiSeeder::class, - JenisIzinSeeder::class, StatusPengajuanSeeder::class, - PengajuanIzinSeeder::class, + SuperAdminSeeder::class, // Menambah super administrator dengan role admin ]); } } diff --git a/database/seeders/JenisIzinSeeder.php b/database/seeders/JenisIzinSeeder.php index 0068cf58..1bd27cf2 100644 --- a/database/seeders/JenisIzinSeeder.php +++ b/database/seeders/JenisIzinSeeder.php @@ -9,13 +9,12 @@ class JenisIzinSeeder extends Seeder { public function run(): void { - DB::table('jenis_izin')->delete(); - - DB::table('jenis_izin')->insert([ - - ['id_jenis_izin' => 1, 'nama_izin' => 'Sakit'], - ['id_jenis_izin' => 2, 'nama_izin' => 'Cuti'], - ['id_jenis_izin' => 3, 'nama_izin' => 'Izin'], - ]); + $types = ['Sakit', 'Cuti', 'Izin']; + foreach ($types as $type) { + DB::table('jenis_izin')->updateOrInsert( + ['nama_izin' => $type], + ['updated_at' => now(), 'created_at' => now()] + ); + } } } diff --git a/database/seeders/MasterDataSeeder.php b/database/seeders/MasterDataSeeder.php index c7ea422b..03fc6a6e 100644 --- a/database/seeders/MasterDataSeeder.php +++ b/database/seeders/MasterDataSeeder.php @@ -13,54 +13,74 @@ class MasterDataSeeder extends Seeder { public function run() { + $divIT = Divisi::firstOrCreate(['nama_divisi' => 'Information Technology']); + $divHR = Divisi::firstOrCreate(['nama_divisi' => 'Human Resources']); + Divisi::firstOrCreate(['nama_divisi' => 'Finance & Accounting']); + Divisi::firstOrCreate(['nama_divisi' => 'Marketing']); - $divIT = Divisi::create(['nama_divisi' => 'Information Technology']); - $divHR = Divisi::create(['nama_divisi' => 'Human Resources']); - Divisi::create(['nama_divisi' => 'Finance & Accounting']); - Divisi::create(['nama_divisi' => 'Marketing']); + $jabMgr = Jabatan::firstOrCreate(['nama_jabatan' => 'Manager']); + $jabSpv = Jabatan::firstOrCreate(['nama_jabatan' => 'Supervisor']); + $jabStf = Jabatan::firstOrCreate(['nama_jabatan' => 'Staff']); + Jabatan::firstOrCreate(['nama_jabatan' => 'Internship']); - $jabMgr = Jabatan::create(['nama_jabatan' => 'Manager']); - $jabSpv = Jabatan::create(['nama_jabatan' => 'Supervisor']); - $jabStf = Jabatan::create(['nama_jabatan' => 'Staff']); - Jabatan::create(['nama_jabatan' => 'Internship']); + $kPusat = Kantor::firstOrCreate( + ['nama_kantor' => 'Kantor Pusat'], + [ + 'alamat' => 'Jl. Jendral Sudirman No. 1, Jakarta', + 'latitude' => -6.2088, + 'longitude' => 106.8456, + 'radius' => 200 + ] + ); - $kPusat = Kantor::create([ - 'nama_kantor' => 'Kantor Pusat', - 'alamat' => 'Jl. Jendral Sudirman No. 1, Jakarta', - 'tipe' => 'Pusat' - ]); + $kCabang = Kantor::firstOrCreate( + ['nama_kantor' => 'Curah Manis Studio'], + [ + 'alamat' => 'Jl. Curah Manis, Malang', + 'latitude' => -7.9839, + 'longitude' => 112.6214, + 'radius' => 200 + ] + ); - $kCabang = Kantor::create([ - 'nama_kantor' => 'Curah Manis Studio', - 'alamat' => 'Jl. Curah Manis, Malang', - 'tipe' => 'Cabang' - ]); + // Roles + $roleAdmin = \App\Models\Role::firstOrCreate(['nama_role' => 'admin']); + $roleHrd = \App\Models\Role::firstOrCreate(['nama_role' => 'hrd']); + $roleManager = \App\Models\Role::firstOrCreate(['nama_role' => 'manager']); + $rolePegawai = \App\Models\Role::firstOrCreate(['nama_role' => 'pegawai']); - User::create([ - 'nama_lengkap' => 'Super Administrator', - 'email' => 'admin@mpg.co.id', - 'password' => Hash::make('admin123'), - 'role' => 'admin', - 'nik' => '999999999', - 'status_aktif' => 1, + $admin = User::updateOrCreate( + ['email' => 'admin@mpg.co.id'], + [ + 'nama_lengkap' => 'Super Administrator', + 'password' => Hash::make('admin123'), + 'nik' => '999999999', + 'status_aktif' => 1, + 'id_divisi' => $divIT->id_divisi, + 'id_jabatan' => $jabMgr->id_jabatan, + 'id_kantor' => $kPusat->id_kantor, + 'tgl_bergabung' => now(), + ] + ); + if (!$admin->roles()->where('nama_role', 'admin')->exists()) { + $admin->roles()->attach($roleAdmin->id_role); + } - 'id_divisi' => $divIT->id_divisi, - 'id_jabatan' => $jabMgr->id_jabatan, - 'id_kantor' => $kPusat->id_kantor, - 'tgl_bergabung' => now(), - ]); - - User::create([ - 'nama_lengkap' => 'Budi Santoso', - 'email' => 'budi@mpg.co.id', - 'password' => Hash::make('Mpg123!'), - 'role' => 'pegawai', - 'nik' => '350712345678', - 'status_aktif' => 1, - 'id_divisi' => $divHR->id_divisi, - 'id_jabatan' => $jabStf->id_jabatan, - 'id_kantor' => $kCabang->id_kantor, - 'tgl_bergabung' => now(), - ]); + $pegawai = User::updateOrCreate( + ['email' => 'budi@mpg.co.id'], + [ + 'nama_lengkap' => 'Budi Santoso', + 'password' => Hash::make('Mpg123!'), + 'nik' => '350712345678', + 'status_aktif' => 1, + 'id_divisi' => $divHR->id_divisi, + 'id_jabatan' => $jabStf->id_jabatan, + 'id_kantor' => $kCabang->id_kantor, + 'tgl_bergabung' => now(), + ] + ); + if (!$pegawai->roles()->where('nama_role', 'pegawai')->exists()) { + $pegawai->roles()->attach($rolePegawai->id_role); + } } } diff --git a/database/seeders/PengajuanIzinSeeder.php b/database/seeders/PengajuanIzinSeeder.php index a3e960e4..adf271bd 100644 --- a/database/seeders/PengajuanIzinSeeder.php +++ b/database/seeders/PengajuanIzinSeeder.php @@ -21,10 +21,8 @@ public function run(): void foreach ($users as $user) { try { - - $idJenis = rand(1, 3); - - $idStatus = rand(1, 3); + $idJenis = DB::table('jenis_izin')->inRandomOrder()->first()->id_jenis_izin; + $idStatus = DB::table('status_pengajuan')->inRandomOrder()->first()->id_status; $tglMulai = now()->addDays(rand(-10, 10)); $tglSelesai = (clone $tglMulai)->addDays(rand(1, 3)); diff --git a/database/seeders/PresensiSeeder.php b/database/seeders/PresensiSeeder.php index cc54dd92..969f246b 100644 --- a/database/seeders/PresensiSeeder.php +++ b/database/seeders/PresensiSeeder.php @@ -40,12 +40,15 @@ public function run(): void $randomMinutes = rand(-10, 30); $jamMasuk = $shiftStart->copy()->addMinutes($randomMinutes); - $status = 1; + $idTepat = DB::table('status_presensi')->where('nama_status', 'Tepat Waktu')->value('id_status') ?? 1; + $idTelat = DB::table('status_presensi')->where('nama_status', 'Terlambat')->value('id_status') ?? 2; + + $status = $idTepat; $alasan = null; $toleransi = 10; if ($randomMinutes > $toleransi) { - $status = 2; + $status = $idTelat; $alasan = 'Terlambat ' . ($randomMinutes) . ' menit (Dummy Data)'; } diff --git a/database/seeders/PresensiStatusSeeder.php b/database/seeders/PresensiStatusSeeder.php index bfa90ce5..2a4d4a5f 100644 --- a/database/seeders/PresensiStatusSeeder.php +++ b/database/seeders/PresensiStatusSeeder.php @@ -10,14 +10,20 @@ class PresensiStatusSeeder extends Seeder public function run(): void { + $statuses = [ + 'Tepat Waktu', + 'Terlambat', + 'Izin', + 'Sakit', + 'Alpha', + ]; - DB::table('status_presensi')->insertOrIgnore([ - ['id_status' => 1, 'nama_status' => 'Tepat Waktu', 'created_at' => now(), 'updated_at' => now()], - ['id_status' => 2, 'nama_status' => 'Terlambat', 'created_at' => now(), 'updated_at' => now()], - ['id_status' => 3, 'nama_status' => 'Izin', 'created_at' => now(), 'updated_at' => now()], - ['id_status' => 4, 'nama_status' => 'Sakit', 'created_at' => now(), 'updated_at' => now()], - ['id_status' => 5, 'nama_status' => 'Alpha', 'created_at' => now(), 'updated_at' => now()], - ]); + foreach ($statuses as $status) { + DB::table('status_presensi')->updateOrInsert( + ['nama_status' => $status], + ['created_at' => now(), 'updated_at' => now()] + ); + } $this->command->info('Tabel status_presensi berhasil diisi!'); } diff --git a/database/seeders/StatusPengajuanSeeder.php b/database/seeders/StatusPengajuanSeeder.php index 576b6027..ea25e546 100644 --- a/database/seeders/StatusPengajuanSeeder.php +++ b/database/seeders/StatusPengajuanSeeder.php @@ -9,13 +9,12 @@ class StatusPengajuanSeeder extends Seeder { public function run(): void { - DB::table('status_pengajuan')->delete(); - - DB::table('status_pengajuan')->insert([ - - ['id_status' => 1, 'nama_status' => 'Disetujui'], - ['id_status' => 2, 'nama_status' => 'Pending'], - ['id_status' => 3, 'nama_status' => 'Ditolak'], - ]); + $statuses = ['Disetujui', 'Pending', 'Ditolak']; + foreach ($statuses as $status) { + DB::table('status_pengajuan')->updateOrInsert( + ['nama_status' => $status], + ['updated_at' => now(), 'created_at' => now()] + ); + } } }