PSF PAYROLL PSF

Gambaran Umum

Pengenalan Sistem Payroll Terpadu PT Putra Sinar Fisip.

Sistem Payroll Terpadu adalah aplikasi berbasis web untuk mengelola penggajian karyawan secara terstruktur, fleksibel, dan terintegrasi — dari pengaturan gaji, acuan gaji, hitung gaji, penyesuaian, hingga slip gaji.

Dibangun dengan Laravel 11, PHP 8.2+, Tailwind CSS, dan Alpine.js. Basis data menggunakan SQLite dengan Eloquent ORM.

Data Master

Karyawan, pengaturan gaji, BPJS, wilayah, status

Input Bulanan

Absensi, NKI, Kasbon per periode

Payroll Engine

Acuan → Hitung → Slip Gaji

Output

Slip PDF & Excel, laporan rekap

Instalasi & Setup

Persyaratan Sistem

  • PHP ^8.2
  • Composer
  • Node.js ^20
  • SQLite / MySQL / PostgreSQL
  • Laragon / XAMPP / Valet

Langkah Instalasi

  1. git clone https://github.com/HugoEdmoundo/payroll-app.ptpsf.git
  2. cd payroll-app.ptpsf
  3. composer install
  4. copy .env.example .env
  5. php artisan key:generate
  6. php artisan migrate
  7. npm install && npm run build
  8. php artisan serve

Pastikan database/database.sqlite sudah ada sebelum migrasi.

Autentikasi

Login

Masukkan email dan password yang telah didaftarkan administrator.

Session & Akses

Sesi aktif hingga logout. Dua tingkat akses: Superadmin (full) dan User (terbatas). Detail di Pengguna & Role.

Alur Data & Cascade

Sistem menggunakan pendekatan Source of Truth pada modul Pengaturan Gaji.

Karyawan (Harian/OJT/Kontrak)
  |
  v
Salary Templates + Pengaturan BpjsKoperasi
  |
  v
NKI + Absensi + Kasbon + Acuan Gaji
  |
  v
Hitung Gaji (kalkulasi final)
  |
  v
Slip Gaji (PDF/Excel)

Data Cascade: Perubahan pada NKI, Absensi, atau Acuan Gaji otomatis merambat ke Hitung Gaji via Observer Pattern.

Struktur Database

11 tabel utama dengan SQLite:

TabelPKDeskripsi
karyawanid_karyawanData master karyawan
salary_templatesidTemplate gaji (standard & status)
pengaturan_bpjs_koperasiidKonfigurasi BPJS & koperasi
master_wilayahidData wilayah
master_status_pegawaiidData status pegawai
acuan_gajiid_acuanAcuan gaji per periode
hitung_gajiidHasil hitung + penyesuaian
slip_gajiidSlip gaji final
absensiid_absensiAbsensi per periode
nkiid_nkiNilai Kinerja Individu
kasbonid_kasbonPinjaman karyawan

Unique constraint (karyawan_id, periode) di setiap tabel transaksi.

Relasi Antar Tabel

DariKeTipeFK
acuan_gajikaryawanN:1id_karyawan
hitung_gajiacuan_gajiN:1acuan_gaji_id
hitung_gajikaryawanN:1karyawan_id
slip_gajihitung_gajiN:1hitung_gaji_id
absensikaryawanN:1id_karyawan
kasbonkaryawanN:1id_karyawan
nkikaryawanN:1id_karyawan

Pola Observer

Data cascade otomatis via Eloquent Observer:

ObserverModelFungsi
NKIObserverNKIUpdate tunjangan_prestasi di Acuan Gaji & Hitung Gaji
AbsensiObserverAbsensiKalkulasi ulang potongan_absensi
AcuanGajiObserverAcuan GajiGenerate otomatis Hitung Gaji
HitungGajiObserverHitung GajiUpdate status cicilan Kasbon
PengaturanGaji::observe(PengaturanGajiObserver::class);
AcuanGaji::observe(AcuanGajiObserver::class);
HitungGaji::observe(HitungGajiObserver::class);
NKI::observe(NKIObserver::class);
Absensi::observe(AbsensiObserver::class);

Karyawan

Pusat data master karyawan dengan informasi personal, employment, dan kompensasi.

FieldTipeDeskripsi
id_karyawanPKPrimary key
nama_karyawanstringNama lengkap
emailstringEmail (nullable)
join_datedatetimeTanggal mulai bekerja
jabatanstringJabatan / posisi
lokasi_kerjastringWilayah kerja
jenis_karyawanstringKonsultan, Organik, Teknisi, Borongan
status_pegawaistringHarian/OJT/Kontrak (otomatis)
npwpstringNPWP (nullable)
bpjs_kesehatan_nostringNo BPJS Kesehatan
bpjs_tk_nostringNo BPJS Ketenagakerjaan
no_rekeningstringNomor rekening
bankstringNama bank
status_karyawanstringAktif / Nonaktif

Status Pegawai Otomatis

class Karyawan extends Model {
    public function calculateStatusPegawai() {
        $days = $this->join_date->diffInDays(now());
        if ($days < 14)  return 'Harian';
        if ($days < 104) return 'OJT';
        return 'Kontrak';
    }
}

CRUD & Fitur

  • Tambah, edit, lihat, hapus karyawan
  • Import/export Excel (dengan template)
  • Riwayat jabatan (Job Movement) tercatat otomatis

Penghapusan bersifat permanen (hard delete) — menghapus semua data terkait.

Pengaturan Gaji

Source of Truth untuk komponen gaji. Disimpan di salary_templates dengan dua tipe: Standard dan Status.

Standard Template

Untuk karyawan Kontrak, dikombinasikan dengan jenis_karyawan, jabatan, lokasi_kerja.

FieldDeskripsi
gaji_pokokGaji pokok bulanan
tunjangan_operasionalTunjangan operasional
tunjangan_prestasiDasar tunjangan prestasi (x persentase NKI)

Status Template

Untuk Harian dan OJT.

FieldDeskripsi
gaji_pokokGaji pokok (Rp90.000/hari untuk Harian)
lokasi_kerjaWilayah kerja
$model->gaji_nett = $model->gaji_pokok + ($model->tunjangan_prestasi ?? 0);
$model->total_gaji = $model->gaji_nett;

BPJS & Koperasi

Konfigurasi global untuk semua karyawan di tabel pengaturan_bpjs_koperasi.

FieldDeskripsi
bpjs_kesehatan_pendapatanBPJS Kesehatan (perusahaan)
bpjs_kecelakaan_kerja_pendapatanBPJS Kecelakaan Kerja
bpjs_kematian_pendapatanBPJS Kematian
bpjs_jht_pendapatanBPJS JHT
bpjs_jp_pendapatanBPJS JP
koperasiPotongan koperasi

Karyawan Harian & OJT tidak mendapat BPJS.

Master Wilayah & Status Pegawai

Master Wilayah

FieldDeskripsi
kodeKode wilayah (unique)
namaNama wilayah
is_activeStatus aktif

Master Status Pegawai

FieldDeskripsi
namaNama status
durasi_hariDurasi dalam hari
gunakan_nkiGunakan NKI
is_activeStatus aktif

Absensi

Mencatat kehadiran per periode untuk menghitung potongan absensi.

FieldDeskripsi
id_karyawanFK ke karyawan
periodeYYYY-MM
hadirJumlah hari hadir
absenceHari tidak hadir (izin)
tanpa_keteranganTanpa keterangan
potongan_absensiNominal potongan (otomatis)
potongan = (absence + tanpa_keterangan) / jumlah_hari_bulan
           x (gaji_pokok + tunjangan_prestasi + tunjangan_operasional)

NKI (Nilai Kinerja Individu)

Penilaian kinerja yang mempengaruhi Tunjangan Prestasi. Hanya untuk Kontrak.

KomponenBobotDeskripsi
kemampuan20%Kemampuan teknis
kontribusi_120%Kontribusi pertama
kontribusi_240%Kontribusi kedua
kedisiplinan20%Tingkat kedisiplinan
nilai_nki = (kemampuan x 0.20) + (kontribusi_1 x 0.20)
           + (kontribusi_2 x 0.40) + (kedisiplinan x 0.20)

if (nilai_nki >= 8.5) -> 100%  |  >= 8.0 -> 80%  |  < 8.0 -> 70%

Kasbon & Cicilan

Dua metode: Langsung (potong sekali) dan Cicilan (tiap bulan).

FieldDeskripsi
nominalJumlah pinjaman
metode_pembayaranLangsung / Cicilan
status_pembayaranPending / Lunas
jumlah_cicilanJumlah cicilan
cicilan_terbayarCicilan terbayar
sisa_cicilanSisa pinjaman

Cicilan disimpan di kasbon_cicilan dengan field: cicilan_ke, periode, nominal_cicilan, status.

Acuan Gaji

Base reference per karyawan per periode. Semua komponen dikumpulkan di sini sebelum Hitung Gaji.

Pendapatan (12)

  • gaji_pokok
  • bpjs_kesehatan
  • bpjs_kecelakaan_kerja
  • bpjs_kematian
  • bpjs_jht
  • bpjs_jp
  • tunjangan_prestasi
  • tunjangan_konjungtur
  • benefit_ibadah
  • benefit_komunikasi
  • benefit_operasional
  • reward

Pengeluaran (7)

  • koperasi
  • kasbon
  • umroh
  • kurban
  • mutabaah
  • potongan_absensi
  • potongan_kehadiran
$model->total_pendapatan = sum(semua pendapatan);
$model->total_pengeluaran = sum(semua pengeluaran);
$model->gaji_bersih = total_pendapatan - total_pengeluaran;

Unique constraint: unique(id_karyawan, periode).

Hitung Gaji

Inti sistem payroll — kalkulasi final dengan data Acuan Gaji + penyesuaian.

Alur

  1. Acuan Gaji dibuat → sistem generate Hitung Gaji (AcuanGajiObserver)
  2. Kalkulasi ulang NKI & Absensi
  3. Adjustment bisa ditambahkan via modal
  4. Status: DraftPreviewApproved

Adjustments (JSON)

{
    "gaji_pokok": { "type": "+", "nominal": 500000, "description": "Bonus" },
    "koperasi":   { "type": "-", "nominal": 100000, "description": "Koreksi" }
}
total_pendapatan = sum(12 pendapatan + adjustments pendapatan)
total_pengeluaran = sum(7 pengeluaran + adjustments pengeluaran)
gaji_bersih = total_pendapatan - total_pengeluaran

Penyesuaian

Adjustment memungkinkan modifikasi komponen gaji tanpa mengubah data Acuan Gaji asli. Berguna untuk:

  • Bonus — pembayaran satu kali
  • Denda — potongan tambahan
  • Koreksi — error data approved
  • Insentif — tambahan khusus

Slip Gaji

Output akhir payroll. Setiap karyawan approved memiliki slip PDF & Excel.

FieldDeskripsi
nomor_slipSG-YYYYMM-XXXX
take_home_payGaji bersih
detail_pendapatanJSON snapshot
detail_pengeluaranJSON snapshot

Pengguna & Role

Superadmin Full
  • ✓ Semua fitur payroll
  • ✓ Manajemen pengguna
  • ✓ Pengaturan sistem
User Terbatas
  • ✓ Input data payroll
  • ✓ Export slip gaji
  • ✗ Tidak manage pengguna

Hak Akses

Hierarki pengecekan permission:

public function hasPermission($key) {
    if ($this->isSuperadmin()) return true;
    if (!$this->is_active) return false;
    // Priority 1: User-specific permission
    // Priority 2: Role-based permission
    return false;
}

Module permissions: karyawan.view, karyawan.create, payroll.hitung-gaji, admin.users, dll.

Pengaturan Sistem

Menu Admin → Settings untuk:

  • Jabatan per Jenis Karyawan
  • Dynamic Fields custom
  • Konfigurasi umum aplikasi

Log Aktivitas

Semua aksi signifikan dicatat di activity_logs:

FieldDeskripsi
user_idPengguna
action_typecreate/update/delete/approve
entity_typeKaryawan, HitungGaji, dll
old_valueData sebelum (JSON)
new_valueData setelah (JSON)

Import & Export

ModulImportTemplateExport
Karyawan
Acuan Gaji
Absensi
NKI
Kasbon
Slip Gaji✓ (Excel+PDF)

FAQ

Data tidak muncul setelah generate Acuan Gaji

Pastikan: karyawan Aktif, Pengaturan Gaji sudah diisi, periode benar (YYYY-MM).

Duplicate entry error

Satu record per karyawan per periode. Gunakan periode berbeda atau edit yang sudah ada.

Gaji bersih 0 atau tidak sesuai

Pastikan komponen gaji terisi. Gunakan Adjustment untuk koreksi jika sudah approved.

Tidak bisa edit Hitung Gaji approved

Fitur keamanan. Gunakan Adjustment untuk koreksi.

Cara reset password?

Hubungi administrator sistem.

© 2026 PSF Payroll. All rights reserved. v1.0