# PRD — Sistem Pembayaran SMK GLOBIN

**Product Requirements Document** (Dokumen Kebutuhan Produk)

| Item | Keterangan |
|---|---|
| **Nama Produk** | Sistem Informasi Pembayaran Sekolah (SPP dan Biaya Lainnya) |
| **Sekolah** | SMK GLOBIN |
| **Jenis Dokumen** | Product Requirements Document (PRD) |
| **Versi** | 1.0 |
| **Tanggal** | Agustus 2026 |
| **Status** | Final — sebagai dasar pengembangan |
| **Platform** | Aplikasi Web (Browser) |

---

## Daftar Isi

<!-- TOC -->
1. [Ringkasan Eksekutif](#1-ringkasan-eksekutif)
2. [Latar Belakang dan Permasalahan](#2-latar-belakang-dan-permasalahan)
3. [Tujuan dan Manfaat](#3-tujuan-dan-manfaat)
4. [Lingkup Produk](#4-lingkup-produk)
5. [Pengguna dan Peran (Role)](#5-pengguna-dan-peran-role)
6. [Kebutuhan Fungsional](#6-kebutuhan-fungsional)
7. [Kebutuhan Non-Fungsional](#7-kebutuhan-non-fungsional)
8. [Model Data / Database](#8-model-data--database)
9. [Aturan Bisnis](#9-aturan-bisnis)
10. [Alur Kerja (Workflow)](#10-alur-kerja-workflow)
11. [Diagram ERD](#11-diagram-erd)
12. [Navigasi dan Menu per Role](#12-navigasi-dan-menu-per-role)
13. [API / Endpoint](#13-api--endpoint)
14. [Validasi dan Pesan Error](#14-validasi-dan-pesan-error)
15. [Teknologi dan Arsitektur](#15-teknologi-dan-arsitektur)
16. [Migrasi Data / Import Excel](#16-migrasi-data--import-excel)
17. [Pelaporan dan Cetak](#17-pelaporan-dan-cetak)
18. [Keamanan](#18-keamanan)
19. [Metrik Keberhasilan](#19-metrik-keberhasilan)
20. [Batasan dan Asumsi](#20-batasan-dan-asumsi)
21. [Roadmap / Tahapan Implementasi](#21-roadmap--tahapan-implementasi)
22. [Kriteria Penerimaan (Acceptance Criteria)](#22-kriteria-penerimaan-acceptance-criteria)
23. [Data Demo dan Akun Uji](#23-data-demo-dan-akun-uji)
24. [Risiko dan Mitigasi](#24-risiko-dan-mitigasi)
25. [Lampiran](#25-lampiran)

---

## 1. Ringkasan Eksekutif

Sistem Pembayaran SMK GLOBIN adalah aplikasi web terpadu untuk mencatat, mengelola, dan
melaporkan seluruh pembayaran siswa di lingkungan sekolah — meliputi **SPP bulanan** dan
**biaya lainnya** (jas almamater, baju batik, kunjungan industri, PKL, ASTS/ASAS/ASAT, daftar
ulang, akhir tahun, dan lain sebagainya).

Sistem menggantikan pencatatan manual dengan menyediakan:

- Manajemen **data master** (siswa, kelas, jurusan, tingkat, tahun ajaran, jenis pembayaran,
  skema diskon, akun pengguna).
- **Generate tagihan** otomatis (SPP bulanan dengan diskon skema, serta biaya sekali pakai).
- **Pembayaran dengan dukungan cicilan**, perhitungan sisa otomatis, dan **kwitansi PDF**.
- **Laporan rekap** (PDF/Excel), **daftar tunggakan**, dan **dashboard** per peran.
- **Import Excel** untuk data siswa dan riwayat pembayaran lama (migrasi data manual).

Produk ditujukan bagi **admin/operator**, **bendahara**, **kepala sekolah**, **wali kelas**,
dan **siswa/orang tua**.

---

## 2. Latar Belakang dan Permasalahan

Saat ini pencatatan pembayaran SPP dan biaya lainnya di SMK GLOBIN dilakukan secara manual
(buku/kertas). Proses ini menimbulkan kendala:

1. **Data tercecer** — catatan pembayaran siswa mudah hilang, rusak, atau sulit ditelusuri.
2. **Laporan lambat** — pembuatan rekap dan daftar tunggakan memakan waktu lama dan rawan
   kesalahan hitung.
3. **Kwitansi tidak rapi** — tidak ada format standar dan file arsip yang terdokumentasi.
4. **Kurang transparan** — orang tua/wali sulit memantau status pembayaran secara cepat.
5. **Risiko salah hitung** — banyaknya jenis pembayaran, skema diskon, dan cicilan membuat
   perhitungan manual rentan salah.

### Tujuan

Menyediakan satu sistem digital yang:
- memusatkan pencatatan seluruh pembayaran secara akuntabel dan dapat ditelusuri;
- mempercepat pembuatan laporan rekap per kelas/bulan/tingkat/tahun;
- mencetak kwitansi dan laporan (PDF) secara otomatis;
- menampilkan daftar siswa menunggak secara otomatis;
- mendukung manajemen naik kelas dengan penanganan tunggakan otomatis;
- memudahkan pemantauan oleh bendahara, wali kelas, kepala sekolah, dan orang tua.

---

## 3. Tujuan dan Manfaat

### 3.1. Tujuan Fungsional
- Menyediakan pendataan siswa dan kelas yang terpusat.
- Mengotomatiskan pembuatan tagihan SPP bulanan dan biaya kegiatan.
- Mencatat setiap transaksi pembayaran termasuk cicilan.
- Menghasilkan kwitansi, laporan rekap, dan daftar tunggakan.
- Mendukung impor data lama dari Excel.

### 3.2. Manfaat
| Manfaat | Penjelasan |
|---|---|
| **Akuntabel & rapi** | Seluruh transaksi tercatat lengkap, berstempel waktu, dan dapat ditelusuri. |
| **Hemat waktu** | Rekap dan laporan tersusun otomatis, dapat diekspor PDF/Excel. |
| **Cepat** | Kwitansi tercetak dalam hitungan detik setelah pembayaran. |
| **Transparan** | Wali kelas, kepala sekolah, dan siswa/orang tua dapat memantau status pembayaran. |
| **Otomatis** | Penanganan diskon skema, cicilan, dan tunggakan tanpa hitung manual. |
| **Mudah migrasi** | Data manual dapat diimpor dari Excel tanpa mengetik ulang. |

---

## 4. Lingkup Produk

### 4.1. Dalam Lingkup (In-Scope)
- Manajemen data master: skema SPP, tingkat, jurusan, kelas, siswa, tahun ajaran,
  jenis pembayaran.
- Generate tagihan SPP bulanan dan biaya sekali pakai.
- Pengelolaan pembayaran (termasuk cicilan) dan penerbitan kwitansi.
- Fitur naik kelas di akhir tahun ajaran.
- Laporan rekap dan daftar tunggakan (PDF/Excel).
- Import/ekspor Excel dan template unduhan.
- Otentikasi dan otorisasi berbasis peran.

### 4.2. Di Luar Lingkup (Out-of-Scope)
- Pembayaran online / payment gateway (belum disediakan pada versi ini).
- Integrasi dengan sistem akademik lain.
- Manajemen keuangan umum sekolah di luar pembayaran siswa.
- Aplikasi mobile native (versi ini berbasis web responsif).
- Fitur reminder otomatis via WhatsApp/SMS (rencana pengembangan lanjut).

---

## 5. Pengguna dan Peran (Role)

Sistem memiliki 5 peran dengan kontrol akses berbeda. Aturan umum: **perbaikan data
(tambah/ubah/hapus) hanya oleh admin & bendahara**; peran lain bersifat pemantauan.

### 5.1. Admin / Operator
| Izin | Detail |
|---|---|
| Kelola data master | skema SPP, tingkat, jurusan, kelas, siswa, tahun ajaran, jenis pembayaran |
| Generate tagihan | SPP bulanan & biaya sekali pakai |
| Kelola akun pengguna | membuat akun (termasuk otomatis saat input/import siswa) |
| Import data | import data siswa dari Excel |
| Naik kelas | menjalankan proses naik kelas akhir tahun |
| Pembayaran & laporan | akses penuh ke semua modul pembayaran dan laporan |

### 5.2. Bendahara
| Izin | Detail |
|---|---|
| Menerima pembayaran | input pembayaran, kelola cicilan |
| Cetak kwitansi | kwitansi PDF per transaksi |
| Import riwayat | import riwayat pembayaran lama dari Excel |
| Laporan | rekap pembayaran per bulan/kelas, daftar tunggakan |

### 5.3. Kepala Sekolah (Kepsek)
| Izin | Detail |
|---|---|
| Pemantauan | melihat seluruh laporan, rekap, dan daftar tunggakan (hanya baca) |
| Dashboard | ringkasan penerimaan dan tunggakan |

### 5.4. Wali Kelas
| Izin | Detail |
|---|---|
| Pemantauan kelas | melihat status pembayaran & tunggakan siswa di kelasnya (hanya baca) |
| Dashboard | ringkasan kelas walinya |

### 5.5. Siswa / Orang Tua
| Izin | Detail |
|---|---|
| Melihat sendiri | tagihan, riwayat pembayaran, dan status tunggakan miliknya (hanya baca) |

---

## 6. Kebutuhan Fungsional

### 6.1. Otentikasi dan Otorisasi (AUTH)
| ID | Kebutuhan | Penerapan |
|---|---|---|
| AUTH-01 | Login berbasis email & password | Breeze authentication; pengalihan ke dashboard |
| AUTH-02 | Logout | Laravel session logout |
| AUTH-03 | Reset kata sandi | Breeze password reset (email) |
| AUTH-04 | Verifikasi email | Breeze email verification |
| AUTH-05 | Kontrol akses berbasis peran | `RoleMiddleware` dengan alias `role`; model `User` punya helper `isAdmin()`, `isBendahara()`, `isKepsek()`, `isWalikelas()`, `isSiswa()` |
| AUTH-06 | Profil pengguna | edit profil, email, password |

### 6.2. Manajemen Data Master (ADMIN)

#### 6.2.1. Skema SPP (diskon)
| ID | Kebutuhan |
|---|---|
| SKEMA-01 | CRUD skema: `nama`, `persen` (0–100), `status_aktif` |
| SKEMA-02 | Skema aktif digunakan dalam perhitungan nominal SPP otomatis |
| SKEMA-03 | Contoh default: Normal (100%), Yatim (75%), Yatim Piatu (50%) |

#### 6.2.2. Tingkat (X/XI/XII)
| ID | Kebutuhan |
|---|---|
| TING-01 | CRUD tingkat: `nama`, `urutan` (menentukan urutan naik kelas) |

#### 6.2.3. Jurusan
| ID | Kebutuhan |
|---|---|
| JUR-01 | CRUD jurusan: `nama` (contoh: TKR, TKJ, TSM) |

#### 6.2.4. Kelas
| ID | Kebutuhan |
|---|---|
| KLS-01 | CRUD kelas: `nama`, `tingkat`, `jurusan`, `walikelas_user_id` |
| KLS-02 | Pencarian/filter kelas berdasarkan tingkat |

#### 6.2.5. Tahun Ajaran
| ID | Kebutuhan |
|---|---|
| TA-01 | CRUD tahun ajaran: `nama`, `tanggal_mulai`, `tanggal_selesai`, `status_aktif` |
| TA-02 | Hanya satu tahun ajaran aktif pada satu waktu (penggunanya admin yang mengatur `status_aktif`) |

#### 6.2.6. Jenis Pembayaran
| ID | Kebutuhan |
|---|---|
| JENIS-01 | CRUD jenis pembayaran: `nama`, `tingkat_id` (nullable), `kategori` (`bulanan`/`sekali`), `nominal`, `status_aktif` |
| JENIS-02 | SPP bulanan didefinisikan dengan `kategori=bulanan` dan `tingkat_id=null` (berlaku semua tingkat) |
| JENIS-03 | Biaya lain (sekali) dapat terikat pada tingkat tertentu atau umum |
| JENIS-04 | Contoh per tingkat: lihat [Bab 9 – Skema Biaya](#9-aturan-bisnis) |

#### 6.2.7. Siswa
| ID | Kebutuhan |
|---|---|
| SISWA-01 | CRUD siswa: `nis` (unik), `nama`, `kelas`, `user` (opsional), `skema_spp`, `telp`, `nama_orangtua`, `status_aktif` |
| SISWA-02 | Opsi membuat akun otomatis saat tambah siswa (email + password) |
| SISWA-03 | Filter siswa per kelas dan pencarian nama/NIS |
| SISWA-04 | Nonaktifkan siswa (soft) bila memiliki tagihan; hapus permanen hanya jika tidak ada tagihan |
| SISWA-05 | Tampilkan jumlah tagihan belum lunas per siswa |
| SISWA-06 | **Import Excel** data siswa → auto-buat akun; terdapat **template unduhan** |

### 6.3. Modul Tagihan (ADMIN)
| ID | Kebutuhan |
|---|---|
| TAG-01 | Generate **SPP bulanan** untuk semua siswa aktif pada bulan & tahun tertentu |
| TAG-02 | Penerapan skema diskon per siswa saat generate SPP (nominal = nominal_jenis × persen/100) |
| TAG-03 | Generate **biaya sekali pakai** per-batch untuk semua/target tingkat siswa aktif |
| TAG-04 | Pencegahan duplikasi: tidak membuat tagihan yang sudah ada (skipped otomatis) |
| TAG-05 | Daftar tagihan: filter per kelas, jenis, status (`belum`/`cicil`/`lunas`); pagination |
| TAG-06 | Menampilkan total pembayaran terbayar per tagihan (`withSum`) |
| TAG-07 | Hapus tagihan hanya jika belum memiliki pembayaran |
| TAG-08 | Import riwayat pembayaran lama (untuk kelengkapan data) |

### 6.4. Modul Pembayaran (BENDAHARA & ADMIN)
| ID | Kebutuhan |
|---|---|
| BYR-01 | Pilih siswa → daftar tagihan belum lunas (sisa > 0), urut tagihan terlama |
| BYR-02 | Input pembayaran: `tagihan_id`, `jumlah`, `tanggal`, `metode` |
| BYR-03 | **Cicilan**: jumlah boleh kurang dari sisa; sisa & status ter-update otomatis |
| BYR-04 | Validasi: jumlah > 0; tidak melebihi sisa; tagihan lunas ditolak |
| BYR-05 | Auto-`no_kwitansi` format `KW-{tagihan_id 5 digit}` (contoh `KW-00001`) |
| BYR-06 | Riwayat/pembayaran: filter rentang tanggal dan pencarian nama/NIS; pagination |
| BYR-07 | **Kwitansi PDF** per transaksi (streaming) |
| BYR-08 | **Import riwayat** pembayaran lama dari Excel |

### 6.5. Fitur Naik Kelas (ADMIN)
| ID | Kebutuhan |
|---|---|
| NK-01 | Menampilkan ringkasan jumlah siswa per tingkat |
| NK-02 | Proses naik kelas: siswa di tingkat bukan terakhir dipindah ke tingkat berikutnya (kelas dengan jurusan sama) |
| NK-03 | Siswa di tingkat terakhir (XII) ditandai **lulus** (`status_aktif=false`) |
| NK-04 | Tagihan lama yang belum lunas tetap tercatat dan menjadi **tunggakan** |

### 6.6. Dashboard per Role
| ID | Pembeda |
|---|---|
| DASH-01 | **Admin**: ringkasan jumlah siswa/kelas, tagihan, penerimaan, tunggakan |
| DASH-02 | **Bendahara**: ringkasan penerimaan, pembayaran hari ini, tunggakan |
| DASH-03 | **Kepsek**: ringkasan penerimaan & tunggakan (baca) |
| DASH-04 | **Wali Kelas**: statistik pembayaran siswa di kelasnya |
| DASH-05 | **Siswa**: total tagihan, tunggakan, riwayat milik sendiri |

### 6.7. Modul Laporan (ADMIN, BENDAHARA, KEPSEK)
| ID | Kebutuhan |
|---|---|
| LAP-01 | **Rekap pembayaran**: filter bulan & tahun (wajib), opsional per kelas |
| LAP-02 | Menampilkan rincian transaksi + total |
| LAP-03 | Ekspor rekap ke **PDF** (via dompdf, A4 landscape) |
| LAP-04 | Ekspor rekap ke **Excel** (via maatwebsite) |
| LAP-05 | **Daftar tunggakan**: siswa aktif yang memiliki tagihan `belum`/`cicil` dengan sisa > 0 |
| LAP-06 | Tampilkan jumlah item belum lunas & total tunggakan per siswa + grand total |
| LAP-07 | Ekspor daftar tunggakan ke **PDF** |

---

## 7. Kebutuhan Non-Fungsional

| Kategori | Kebutuhan |
|---|---|
| **Performa** | Waktu muat halaman < 3 detik (jaringan lokal); pagination untuk daftar besar |
| **Ketersediaan** | Dapat diakses dari browser; berjalan pada infrastruktur lokal sekolah |
| **Keamanan** | Otentikasi & otorisasi peran; validasi input server-side; proteksi CSRF; hash password |
| **Portabilitas** | Data tersimpan di MySQL/DBMS relasional; impor/ekspor Excel & PDF standar |
| **Usability** | UI responsif (Tailwind) untuk komputer & ponsel; menu menyesuaikan peran |
| **Maintainability** | Arsitektur MVC Laravel; kode terstruktur per controller/model/view |
| **Audit** | Setiap pembayaran mencatat `user_id` (petugas) dan stempel waktu |

---

## 8. Model Data / Database

### 8.1. `users`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| name | string | nama pengguna |
| email | string unik | digunakan untuk login |
| role | enum | `admin`, `bendahara`, `kepsek`, `walikelas`, `siswa` (default `siswa`) |
| email_verified_at | timestamp nullable | verifikasi |
| password | string | hash |
| remember_token | string nullable | |
| timestamps | | |

Tabel terkait: `password_reset_tokens`, `sessions`, `cache`, `jobs` (default framework).

### 8.2. `skema_spps`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| nama | string | contoh: Normal, Yatim, Yatim Piatu |
| persen | int unsigned | 100 = full; 75 = diskon 25%; 50 = diskon 50% |
| status_aktif | boolean | default true |
| timestamps | | |

### 8.3. `tingkats`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| nama | string | X, XI, XII |
| urutan | int unsigned | 1, 2, 3 — urutan naik kelas |
| timestamps | | |

### 8.4. `jurusans`
| Kolom | Tipe |
|---|---|
| id | bigint PK |
| nama | string |
| timestamps | |

### 8.5. `kelas`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| nama | string | contoh: "X TKR 1" |
| tingkat_id | FK → tingkats (cascade) | |
| jurusan_id | FK → jurusans (cascade) | |
| walikelas_user_id | FK → users, nullable (set null) | wali kelas yang ditugaskan |
| timestamps | | |

### 8.6. `siswas`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| nis | string unik | nomor induk siswa |
| nama | string | |
| kelas_id | FK → kelas (restrict) | |
| user_id | FK → users, nullable (set null) | akun login siswa |
| skema_spp_id | FK → skema_spps | menentukan diskon SPP |
| telp | string nullable | |
| nama_orangtua | string nullable | |
| status_aktif | boolean | default true; false = lulus/nonaktif |
| timestamps | | |

### 8.7. `tahun_ajarans`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| nama | string | contoh: "2025/2026" |
| tanggal_mulai | date | contoh: 2025-07-10 |
| tanggal_selesai | date | contoh: 2026-06-25 |
| status_aktif | boolean | default false; satu aktif |
| timestamps | | |

### 8.8. `jenis_pembayarans`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| nama | string | SPP, Jas Almamater, PKL, dsb. |
| tingkat_id | FK → tingkats, nullable (set null) | null = berlaku semua tingkat (mis. SPP) |
| kategori | enum | `bulanan`, `sekali` |
| nominal | decimal(12,2) | |
| status_aktif | boolean | default true |
| timestamps | | |

### 8.9. `tagihans`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| siswa_id | FK → siswas (cascade) | |
| jenis_pembayaran_id | FK → jenis_pembayarans (cascade) | |
| tahun_ajaran_id | FK → tahun_ajarans (cascade) | |
| periode_bulan | int unsigned nullable | khusus SPP (1–12) |
| periode_tahun | int unsigned nullable | khusus SPP |
| nominal | decimal(12,2) | besaran setelah diskon skema (untuk SPP) |
| sisa | decimal(12,2) | sisa yang belum dibayar |
| status | enum | `belum`, `cicil`, `lunas` |
| timestamps | | |

Indeks: `(tahun_ajaran_id, siswa_id)`, `(status, sisa)`.

### 8.10. `pembayarans`
| Kolom | Tipe | Keterangan |
|---|---|---|
| id | bigint PK | |
| tagihan_id | FK → tagihans (cascade) | |
| user_id | FK → users, nullable (set null) | petugas pencatat; null saat import |
| tanggal | date | |
| jumlah | decimal(12,2) | |
| metode | string | default `tunai`; `import` untuk impor lama |
| no_kwitansi | string nullable | format `KW-00001` / `IMP-...` |
| timestamps | | |

Indeks: `tanggal`.

---

## 9. Aturan Bisnis

### 9.1. Skema Biaya per Tingkat (contoh/ilustrasi — dapat diubah admin)

**Kelas X**
SPP (bulanan) · Jas Almamater · Baju Batik · Kunjungan Industri · ASTS 1 · ASAS 1 · ASTS 2 · ASAT

**Kelas XI**
SPP (bulanan) · Daftar Ulang · PKL · ASTS 1 · ASAS 1 · ASTS 2 · ASAT

**Kelas XII**
SPP (bulanan) · Daftar Ulang · Akhir Tahun

> Nama jenis, nominal, dan tingkat bersifat **konfigurabel** melalui menu "Jenis Pembayaran".

### 9.2. SPP dan Skema Diskon
- Nominal SPP **sama untuk semua tingkat** (kategori `bulanan`, `tingkat_id=null`).
- Saat generate SPP, nominal per siswa = `nominal_jenis × persen_skema / 100`.
- Contoh (SPP Rp100.000/bulan):
  - **Normal** → Rp100.000
  - **Yatim** → Rp75.000 (diskon 25%)
  - **Yatim Piatu** → Rp50.000 (diskon 50%)

### 9.3. Tahun Ajaran & Periode
- Tahun ajaran berjalan kira-kira **10 Juli s.d. 25 Juni** tahun berikutnya.
- Periode SPP disimpan per bulan-tahun (`periode_bulan`, `periode_tahun`).
- Generate SPP: jika bulan ≥ 7, periode tahun mengikuti tahun perjalanan pertama tahun ajaran.

### 9.4. Cicilan dan Status Tagihan
- Pembayaran dapat **sebagian** (cicilan); `sisa` dikurangi otomatis.
- Status berubah: `belum` → `cicil` (jika sisa > 0) → `lunas` (jika sisa = 0).
- Jumlah pembayaran tidak boleh **melebihi sisa**; tidak bisa membayar tagihan yang sudah lunas.

### 9.5. Nomor Kwitansi
- Transaksi baru: `KW-{id_tagihan:5}` (contoh `KW-00001`).
- Data import: `IMP-{id_tagihan}`.

### 9.6. Naik Kelas
- Siswa pada tingkat bukan terakhir dipindah ke **kelas di tingkat berikutnya dengan jurusan sama**.
- Siswa pada tingkat terakhir (XII) → **lulus** (`status_aktif=false`).
- Tagihan belum lunas tetap ada → otomatis menjadi **tunggakan**.

### 9.7. Tunggakan
- Definisi: tagihan ber-status `belum` atau `cicil` **dan** `sisa > 0` pada siswa aktif.

### 9.8. Penghapusan yang Dilindungi
- Siswa yang memiliki tagihan **tidak dapat dihapus** permanen (gunakan nonaktifkan).
- Tagihan yang memiliki pembayaran **tidak dapat dihapus**.

---

## 10. Alur Kerja (Workflow)

### 10.1. Alur Pembayaran
1. Admin menetapkan daftar & nominal **jenis pembayaran** per tingkat.
2. Admin **generate tagihan** (SPP bulanan / biaya kegiatan).
3. Bendahara menerima pembayaran dari siswa/orang tua & memilih tagihan.
4. Sistem menghitung **sisa** otomatis (mendukung cicilan).
5. **Kwitansi PDF** dicetak dan diserahkan ke pembayar.
6. Data tercatat sebagai riwayat dan masuk ke laporan.

### 10.2. Alur Naik Kelas
1. Admin menjalankan proses **naik kelas** di akhir tahun ajaran.
2. Siswa naik ke tingkat berikutnya (X→XI→XII; XII→lulus).
3. Tagihan belum lunas dipindahkan sebagai **tunggakan**.
4. Daftar jenis pembayaran mengikuti tingkat baru.
5. Siswa baru kelas X didaftarkan (data + akun otomatis).

### 10.3. Alur Import Data Lama
1. Admin mengunduh **template** (untuk siswa) atau menyiapkan Excel riwayat.
2. Upload file (`.xlsx`, `.xls`, `.csv`).
3. Sistem memproses baris per baris; membuat tagihan & pembayaran/akun otomatis.
4. Data hasil import masuk ke riwayat & laporan.

---

## 11. Diagram ERD

```
users (1) ────< (0..1) siswas >---- (1) kelas >---- (1) tingkat
                                   |   ^              
                        (1) skema_spps              |
                                                    |
siswas (1) ──< tagihans >---- (1) jenis_pembayarans ┘
                |  ^                    |
                |  (1) tahun_ajarans    (0..1) tingkat
                |                       
pembayarans >---(1) tagihans
   |
   (0..1) users
```

**Ringkasan relasi:**
- `kelas` → `tingkat` (1:N), `jurusan` (N:1), `users.walikelas` (N:1)
- `siswas` → `kelas`, `skema_spps`, `users` (N:1)
- `tagihans` → `siswas`, `jenis_pembayarans`, `tahun_ajarans` (N:1)
- `pembayarans` → `tagihans`, `users` (N:1)

---

## 12. Navigasi dan Menu per Role

| Menu | Admin | Bendahara | Kepsek | Wali Kelas | Siswa |
|---|---|---|---|---|---|
| Dashboard | ✔ | ✔ | ✔ | ✔ | ✔ |
| Skema SPP | ✔ CRUD | – | – | – | – |
| Tingkat | ✔ CRUD | – | – | – | – |
| Jurusan | ✔ CRUD | – | – | – | – |
| Kelas | ✔ CRUD | – | – | – | – |
| Tahun Ajaran | ✔ CRUD | – | – | – | – |
| Jenis Pembayaran | ✔ CRUD | – | – | – | – |
| Siswa | ✔ CRUD+Import | – | – | – | – |
| Tagihan | ✔ (generate/daftar/import) | – | – | – | – |
| Naik Kelas | ✔ | – | – | – | – |
| Pembayaran | ✔ | ✔ | – | – | – |
| Laporan Rekap | ✔ | ✔ | ✔ | – | – |
| Laporan Tunggakan | ✔ | ✔ | ✔ | – | – |

---

## 13. API / Endpoint

### 13.1. Otentikasi
| Method | URI | Nama | Keterangan |
|---|---|---|---|
| GET | `/login` | login | halaman login |
| POST | `/login` | login | proses login |
| POST | `/logout` | logout | logout |
| GET/POST | `/forgot-password` | password.email/request | reset password |

### 13.2. Umum
| Method | URI | Nama |
|---|---|---|
| GET | `/` | redirect ke dashboard |
| GET | `/dashboard` | dashboard (auth+verified) |
| GET/PATCH/DELETE | `/profile` | profil |

### 13.3. Admin — Master Data (prefix `admin.`, role admin)
| Method | URI | Nama |
|---|---|---|
| resource | `/admin/tingkat` | admin.tingkat.* |
| resource | `/admin/jurusan` | admin.jurusan.* |
| resource | `/admin/kelas` | admin.kelas.* |
| resource | `/admin/siswa` | admin.siswa.* |
| POST | `/admin/siswa/import` | admin.siswa.import |
| GET | `/admin/siswa/import/template` | admin.siswa.import.template |
| resource | `/admin/tahun-ajaran` | admin.tahun-ajaran.* |
| resource | `/admin/jenis-pembayaran` | admin.jenis-pembayaran.* |
| resource | `/admin/skema-spp` | admin.skema-spp.* |

### 13.4. Tagihan (role admin)
| Method | URI | Nama |
|---|---|---|
| GET | `/tagihan` | tagihan.index |
| GET | `/tagihan/generate` | tagihan.create |
| POST | `/tagihan/generate` | tagihan.store |
| GET | `/tagihan/generate-riwayat` | tagihan.create.riwayat |
| POST | `/tagihan/generate-riwayat` | tagihan.store.riwayat |
| DELETE | `/tagihan/{tagihan}` | tagihan.destroy |

### 13.5. Naik Kelas (role admin)
| Method | URI | Nama |
|---|---|---|
| GET | `/naik-kelas` | naik-kelas.index |
| POST | `/naik-kelas` | naik-kelas.store |

### 13.6. Pembayaran (role admin, bendahara)
| Method | URI | Nama |
|---|---|---|
| GET | `/pembayaran` | pembayaran.index |
| GET | `/pembayaran/siswa/{siswa}` | pembayaran.create |
| POST | `/pembayaran/siswa/{siswa}` | pembayaran.store |
| GET | `/pembayaran/riwayat` | pembayaran.riwayat |
| GET | `/pembayaran/kwitansi/{pembayaran}` | pembayaran.kwitansi |
| GET | `/pembayaran/import` | pembayaran.import |
| POST | `/pembayaran/import` | pembayaran.import.store |

### 13.7. Laporan (role admin, bendahara, kepsek)
| Method | URI | Nama |
|---|---|---|
| GET | `/laporan` | laporan.index |
| GET | `/laporan/rekap/pdf` | laporan.rekap.pdf |
| GET | `/laporan/rekap/excel` | laporan.rekap.excel |
| GET | `/laporan/tunggakan` | laporan.tunggakan |
| GET | `/laporan/tunggakan/pdf` | laporan.tunggakan.pdf |

---

## 14. Validasi dan Pesan Error

### 14.1. Aturan Validasi Utama
| Area | Aturan |
|---|---|
| Login | email valid, password |
| Siswa | `nis` required & unique; `nama` required; `kelas_id` & `skema_spp_id` exist; `email_akun` valid; password min 4 |
| Generate SPP | `bulan` required int 1–12 |
| Generate sekali | `jenis_pembayaran_id` required & exists |
| Pembayaran | `tagihan_id` required & exists; `jumlah` required numeric min 0.01 |
| Import file | required, `.xlsx/.xls/.csv` |

### 14.2. Pesan Kesalahan Fungsional
| Kondisi | Pesan |
|---|---|
| Belum ada tahun ajaran aktif | "Aktifkan tahun ajaran terlebih dahulu." |
| SPP belum diatur | "Jenis SPP belum diatur. Tambahkan jenis SPP bulanan tanpa tingkat." |
| Tagihan sudah lunas | "Tagihan ini sudah lunas." |
| Jumlah melebihi sisa | "Jumlah melebihi sisa tagihan (sisa: Rp ...)." |
| Hapus tagihan berbayar | "Tidak dapat menghapus tagihan yang sudah memiliki pembayaran." |
| Hapus siswa bertagihan | "Tidak dapat menghapus siswa yang memiliki tagihan. Nonaktifkan saja." |
| Generate berhasil | "Tagihan SPP dibuat untuk N siswa..." / "Tagihan {jenis} dibuat untuk N siswa..." |
| Naik kelas selesai | "Naik kelas selesai: X siswa naik jenjang, Y siswa lulus." |

---

## 15. Teknologi dan Arsitektur

| Komponen | Teknologi |
|---|---|
| Bahasa | PHP 8.2 |
| Framework | Laravel 12 (MVC) |
| Database | MySQL / MariaDB |
| UI/Tampilan | Blade + Tailwind CSS (via Vite) |
| Otentikasi | Laravel Breeze (Blade) |
| Cetak PDF | barryvdh/laravel-dompdf |
| Ekspor/Impor Excel | maatwebsite/excel |
| Tampilan uang | helper `terbilang()` (autoload `files`) + format `number_format` |

**Arsitektur:** Monolitik MVC Laravel — Controller memproses permintaan, Model memetakan
tabel, View Blade merender halaman. Middleware `role` membatasi akses. Server dapat
dijalankan dengan `php artisan serve`.

---

## 16. Migrasi Data / Import Excel

### 16.1. Import Data Siswa (`SiswaImport`)
- Format kolom: `nis`, `nama`, `kelas`, `nama_orangtua`, `telp`, `skema`, `email` (opsional).
- Baris dengan `nis`/`nama` kosong dilewati.
- `nis` duplikat dilewati.
- Kelas dicocokkan berdasarkan nama; skema fallback ke "Normal".
- **Akun user siswa dibuat otomatis** (email default `siswa_{nis}@sppglobin.test`, password default `password`).

### 16.2. Import Riwayat Pembayaran (`RiwayatPembayaranImport`)
- Format kolom: `nis`, `jenis`, `jumlah`, `tanggal`, `bulan` (opsional).
- `nis` tidak ditemukan → dilewati.
- Jenis dicocokkan; jika tidak ditemukan, fallback ke jenis SPP bulanan.
- Tahun ajaran diselesaikan dari tanggal pembayaran.
- Jika tagihan belum ada → dibuat otomatis (nominal = max(jumlah, nominal_jenis)).
- `sisa` dan `status` di-update; catatan pembayaran `metode=import`, `no_kwitansi=IMP-{id}`.

### 16.3. Ekspor
- **Template siswa**: `SiswaTemplateExport` — satu baris contoh per kelas, skema default "Normal".
- **Rekap pembayaran**: `RekapPembayaranExport` — rincian + total periode.

---

## 17. Pelaporan dan Cetak

| Modul | Format | Isi | Konfigurasi Halaman |
|---|---|---|---|
| Kwitansi | PDF (stream) | data pembayaran, siswa, jenis tagihan, terbilang | portrait |
| Rekap Pembayaran | PDF (download) | rincian transaksi + total, periode | A4 landscape |
| Rekap Pembayaran | Excel (download) | rincian + ringkasan total | spreadsheet |
| Daftar Tunggakan | PDF (download) | per siswa: item & total tunggakan + grand total | A4 landscape |

---

## 18. Keamanan

- Otentikasi session Laravel + Breeze (hash password via `Hash::make`).
- Otorisasi berbasis peran (`role` middleware + helper model).
- Proteksi CSRF pada semua form POST.
- Validasi input server-side (Laravel Validation).
- Pembatasan akses menu berdasarkan peran di sidebar.
- Rollback/hapus terlindungi untuk data yang memiliki dependensi pembayaran.

---

## 19. Metrik Keberhasilan

| Metrik | Target |
|---|---|
| Waktu membuat kwitansi | < 10 detik |
| Waktu generate tagihan SPP | semua siswa aktif dalam sekali proses |
| Waktu membuat laporan rekap | < 1 menit (PDF/Excel) |
| Akurasi status tunggakan | 100% otomatis, tanpa hitung manual |
| Migrasi data lama | melalui import Excel tanpa ketik ulang |
| Akses peran | setiap role hanya melihat menu sesuai izinnya |

---

## 20. Batasan dan Asumsi

### Asumsi
- Nominal SPP sama untuk semua tingkat.
- Periode tahun ajaran ± 10 Juli s.d. 25 Juni.
- Satu tahun ajaran aktif pada satu waktu.
- Data pembayaran dapat berupa cicilan.
- Login dilakukan dengan email (bukan NIS langsung) pada versi ini.

### Batasan
- Tidak ada payment gateway / pembayaran online pada versi ini.
- Reset password memerlukan konfigurasi email (pada lingkungan tanpa email, gunakan kontrol admin).
- Import tidak melakukan rollback transaksi parsial jika baris gagal (baris valid tetap diproses).

---

## 21. Roadmap / Tahapan Implementasi

| Fase | Kegiatan |
|---|---|
| **Fase 1 (selesai)** | Setup proyek, database, otentikasi, master data, tagihan, pembayaran, naik kelas, dashboard, laporan, import/export |
| **Fase 2** | Uji coba data riil & finalisasi tampilan; deployment ke lingkungan sekolah |
| **Fase 3 (pengembangan lanjut)** | Pembayaran online/payment gateway; reminder WhatsApp/SMS; laporan tahunan & grafik lanjutan; login via NIS |

---

## 22. Kriteria Penerimaan (Acceptance Criteria)

| No | Kriteria |
|---|---|
| AC-1 | Login berhasil untuk ke-5 peran dengan dashboard yang sesuai peran. |
| AC-2 | Admin dapat menambah/mengubah/menghapus seluruh data master. |
| AC-3 | Generate SPP menerapkan skema diskon (Normal/Yatim/Yatim Piatu) dengan benar. |
| AC-4 | Pembayaran cicilan menurunkan sisa dan mengubah status (`belum`→`cicil`→`lunas`). |
| AC-5 | Kwitansi PDF tercetak otomatis untuk setiap pembayaran. |
| AC-6 | Laporan rekap dapat diekspor PDF & Excel; daftar tunggakan dapat diekspor PDF. |
| AC-7 | Fitur naik kelas memindahkan siswa & menandai kelas XII lulus. |
| AC-8 | Import Excel siswa membuat akun otomatis; import riwayat menghasilkan tagihan & pembayaran. |
| AC-9 | Pengguna non-izin tidak dapat mengakses modul yang dibatasi. |
| AC-10 | Data dengan dependensi pembayaran tidak dapat dihapus permanen. |

---

## 23. Data Demo dan Akun Uji

Semua akun password **`password`**:

| Peran | Email | Nama (skema) |
|---|---|---|
| Admin | admin@sppglobin.test | Admin |
| Bendahara | bendahara@sppglobin.test | Bendahara |
| Kepala Sekolah | kepsek@sppglobin.test | Kepala Sekolah |
| Wali Kelas | walikelas@sppglobin.test | Wali Kelas TKR 1 |
| Siswa | siswa@sppglobin.test | Siswa Demo (NIS 24001, Normal) |

Data demo tambahan:
- Skema SPP: Normal (100%), Yatim (75%), Yatim Piatu (50%).
- Tingkat: X(1), XI(2), XII(3).
- Jurusan: TKR, TKJ, TSM (contoh).
- Kelas: X TKR 1, XI TKR 1, XII TKR 1.
- Tahun ajaran aktif: 2025/2026 (10-07-2025 s.d. 25-06-2026).
- Jenis pembayaran: SPP (bulanan, Rp100.000) + biaya sekali per tingkat (lihat [9.1](#91-skema-biaya-per-tingkat-contohillustrasi--dapat-diubah-admin)).

---

## 24. Risiko dan Mitigasi

| Risiko | Dampak | Mitigasi |
|---|---|---|
| Kesalahan skema periode tahun (Juli–Desember) saat generate SPP | tanggal periode salah | verifikasi & uji; periode tahun default `now()->year` |
| Import baris tidak valid | data sebagian masuk | dokumentasikan format; validasi per baris; audit hasil |
| Konflik akun email duplikat saat import | akun gagal | gunakan email default unik berbasis NIS |
| Kehilangan data | data rusak | backup database berkala |
| Lupa periode tahun ajaran | tagihan salah tahun | pastikan tahun ajaran aktif dikelola admin |

---

## 25. Lampiran

- **Dokumen Rancangan:** `docs/Rancangan-Aplikasi-Pembayaran-SMK-GLOBIN.pdf`
- **Kode Sumber:** proyek Laravel di `C:\Users\Lenovo\spp-globin`
- **Skema Database:** migration di `database/migrations/`
- **Seeder & Data Demo:** `database/seeders/DatabaseSeeder.php`

---

*Dokumen ini merupakan kelanjutan dari rancangan usulan dan dapat disesuaikan dengan
kebutuhan nyata operasional SMK GLOBIN.*
