Roles Kantor
This commit is contained in:
parent
e5cb2e916c
commit
bffdb4bef3
|
|
@ -0,0 +1,70 @@
|
|||
# 🛡️ QA & System Testing Guide - MPG HRIS
|
||||
|
||||
Dokumen ini disusun untuk membantu tim Quality Assurance (QA) memahami alur bisnis, aturan validasi, dan skenario pengujian untuk ekosistem MPG HRIS (Web & Mobile).
|
||||
|
||||
---
|
||||
|
||||
## 👥 1. Matriks Peran & Izin (RBAC)
|
||||
|
||||
Sistem ini menggunakan Role-Based Access Control yang ketat. Berikut adalah daftar akun uji coba default:
|
||||
|
||||
| Role | Email | Password | Cakupan Akses |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **Super Admin** | `superadmin@mpg.co.id` | `password` | Seluruh data & seluruh kantor (Global). |
|
||||
| **Admin** | `admin@mpg.co.id` | `admin123` | Manajemen data master & operasional (Global). |
|
||||
| **Manajer** | (Sesuai User) | `Mpg123!` | Approval Izin & Koreksi Presensi (**Hanya Kantor Sendiri**). |
|
||||
| **Supervisor** | (Sesuai User) | `Mpg123!` | Management Jadwal Pegawai (**Hanya Kantor Sendiri**). |
|
||||
| **Pegawai** | `budi@mpg.co.id` | `Mpg123!` | Presensi & Pengajuan Izin via Mobile. |
|
||||
|
||||
---
|
||||
|
||||
## 🏢 2. Isolasi Data Per Kantor (Feature Highlight)
|
||||
|
||||
Fitur ini memastikan Manajer dan Supervisor **tidak bisa** melihat atau memproses data dari kantor lain.
|
||||
|
||||
**Skenario Test QA:**
|
||||
1. Login sebagai Manajer Kantor A.
|
||||
2. Pastikan di Dashboard/Laporan tidak muncul nama pegawai dari Kantor B.
|
||||
3. Coba akses ID Izin/Presensi dari Kantor B via URL langsung (ID di URL).
|
||||
4. **Expected Result**: Muncul error 403 (Forbidden) atau redirect kembali dengan pesan error.
|
||||
|
||||
---
|
||||
|
||||
## 📱 3. Skenario Pengujian Mobile (Pegawai)
|
||||
|
||||
### A. Presensi Real-time
|
||||
1. **Validasi Radius**: Gunakan Mock Location. Coba absen di luar radius (misal > 100m dari titik kantor).
|
||||
- **Expected**: Status presensi menjadi "Pending" (menunggu validasi admin) dan muncul peringatan "Di Luar Radius".
|
||||
2. **Face Recognition**:
|
||||
- Absen dengan wajah yang sudah terdaftar -> **Lolos**.
|
||||
- Absen dengan wajah orang lain/foto -> **Gagal/Pending verifikasi**.
|
||||
3. **Shift Kerja**: Absen sesuai jam shift. Jika lewat toleransi 15 menit, status otomatis "Terlambat".
|
||||
|
||||
### B. Pengajuan Izin/Cuti
|
||||
1. **Aturan Cuti**: Coba ajukan cuti kurang dari 7 hari dari tanggal mulai (H-7).
|
||||
- **Expected**: Muncul error "Pengajuan Cuti minimal H-7".
|
||||
2. **Signature**: Pastikan tanda tangan tersimpan dengan jelas dan muncul di PDF/Web Panel.
|
||||
|
||||
---
|
||||
|
||||
## 💻 4. Skenario Pengujian Web (Manajer/Admin)
|
||||
|
||||
### A. Alur Persetujuan Izin (Workflow)
|
||||
1. **Flow**: Pegawai (Mobile) -> Manajer (Approve) -> HRD/Admin (Approve).
|
||||
2. **Dampak Data**: Setelah disetujui HRD (Final), cek tabel Presensi pegawai tersebut.
|
||||
- **Expected**: Data presensi otomatis terisi sesuai jenis izin (Cuti/Sakit) pada rentang tanggal tersebut.
|
||||
|
||||
### B. Penjadwalan (Scheduling)
|
||||
1. **Bulk Create**: Buat jadwal untuk 10 pegawai sekaligus untuk 1 bulan.
|
||||
2. **Conflict Detect**: Buat jadwal pada tanggal di mana pegawai sudah mengajukan Cuti.
|
||||
- **Expected**: Muncul peringatan konflik penggunaan poin/cuti.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 5. Prasyarat Teknis QA
|
||||
- **Web**: Laravel 12, MySQL 8, npm installed.
|
||||
- **Mobile**: Flutter SDK, Dio, Google ML Kit (Face Detection).
|
||||
- **Environment**: Pastikan `BASE_URL` di mobile `.env` sudah mengarah ke IP/Domain server Laravel.
|
||||
|
||||
---
|
||||
*Dibuat oleh Tim Development MPG*
|
||||
|
|
@ -61,6 +61,11 @@ ## 📜 Aturan Pengembangan (Project Rules)
|
|||
- `<x-button>` & `<x-back-button>`: Tombol aksi.
|
||||
- `<x-modal>`: Untuk CRUD Data Master sederhana.
|
||||
|
||||
## 🛡️ Quality Assurance (QA) & Testing
|
||||
|
||||
Untuk tim QA, silakan merujuk ke dokumen panduan pengujian komprehensif di:
|
||||
👉 **[QA_GUIDE.md](file:///c:/xampp/htdocs/mpg-hris/QA_GUIDE.md)**
|
||||
|
||||
## 🔑 Akun Default (Seeder)
|
||||
|
||||
- **Super Admin**: `superadmin@mpg.co.id` / `password`
|
||||
|
|
|
|||
|
|
@ -17,14 +17,21 @@ class JadwalController extends Controller
|
|||
{
|
||||
public function index()
|
||||
{
|
||||
$kantor = Kantor::all();
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
$kantor = $isGlobalAdmin ? Kantor::all() : Kantor::where('id_kantor', $user->id_kantor)->get();
|
||||
$divisi = Divisi::all();
|
||||
$shifts = ShiftKerja::all()->map(function ($s) {
|
||||
$s->color = $this->getShiftColor($s->nama_shift);
|
||||
return $s;
|
||||
});
|
||||
|
||||
$pegawai = User::where('status_aktif', 1)->orderBy('nama_lengkap', 'asc')->get();
|
||||
$pegawaiQuery = User::where('status_aktif', 1);
|
||||
if (!$isGlobalAdmin) {
|
||||
$pegawaiQuery->where('id_kantor', $user->id_kantor);
|
||||
}
|
||||
$pegawai = $pegawaiQuery->orderBy('nama_lengkap', 'asc')->get();
|
||||
|
||||
return view('jadwal.index', compact('kantor', 'divisi', 'shifts', 'pegawai'));
|
||||
}
|
||||
|
|
@ -34,16 +41,32 @@ public function getEvents(Request $request)
|
|||
$start = Carbon::parse($request->start)->format('Y-m-d');
|
||||
$end = Carbon::parse($request->end)->format('Y-m-d');
|
||||
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
$query = JadwalKerja::with(['user.kantor', 'user.jabatan', 'shift'])
|
||||
->whereDate('tanggal', '>=', $start)
|
||||
->whereDate('tanggal', '<=', $end);
|
||||
|
||||
if ($request->filled('filter_kantor') && $request->filter_kantor != "") {
|
||||
$query->whereHas('user', function ($q) use ($request) {
|
||||
$q->where('id_kantor', $request->filter_kantor);
|
||||
if (!$isGlobalAdmin) {
|
||||
$query->whereHas('user', function ($q) use ($user) {
|
||||
$q->where('id_kantor', $user->id_kantor);
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->filled('filter_kantor') && $request->filter_kantor != "") {
|
||||
// Jika bukan admin, pastikan filter_kantor sesuai dengan kantornya
|
||||
if (!$isGlobalAdmin && $request->filter_kantor != $user->id_kantor) {
|
||||
$query->whereHas('user', function ($q) use ($user) {
|
||||
$q->where('id_kantor', $user->id_kantor);
|
||||
});
|
||||
} else {
|
||||
$query->whereHas('user', function ($q) use ($request) {
|
||||
$q->where('id_kantor', $request->filter_kantor);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('filter_divisi') && $request->filter_divisi != "") {
|
||||
$query->whereHas('user', function ($q) use ($request) {
|
||||
$q->where('id_divisi', $request->filter_divisi);
|
||||
|
|
@ -129,12 +152,12 @@ public function getEvents(Request $request)
|
|||
|
||||
$hariLibursQuery = \App\Models\HariLibur::whereBetween('tanggal', [$start, $end]);
|
||||
if ($request->filled('filter_kantor') && $request->filter_kantor != "") {
|
||||
$hariLibursQuery->where(function($q) use ($request) {
|
||||
$hariLibursQuery->where(function ($q) use ($request) {
|
||||
$q->whereNull('id_kantor')->orWhere('id_kantor', $request->filter_kantor);
|
||||
});
|
||||
}
|
||||
$hariLiburs = $hariLibursQuery->get();
|
||||
|
||||
|
||||
foreach ($hariLiburs as $hl) {
|
||||
$events[] = [
|
||||
'id' => 'libur-' . $hl->id,
|
||||
|
|
@ -173,14 +196,18 @@ private function getShiftColor($namaShift)
|
|||
|
||||
public function create()
|
||||
{
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
$shifts = ShiftKerja::all();
|
||||
$kantor = Kantor::all();
|
||||
$kantor = $isGlobalAdmin ? Kantor::all() : Kantor::where('id_kantor', $user->id_kantor)->get();
|
||||
$divisi = Divisi::all();
|
||||
|
||||
$pegawai = User::where('status_aktif', 1)
|
||||
->with(['kantor', 'jabatan'])
|
||||
->orderBy('nama_lengkap', 'asc')
|
||||
->get();
|
||||
$pegawaiQuery = User::where('status_aktif', 1)->with(['kantor', 'jabatan']);
|
||||
if (!$isGlobalAdmin) {
|
||||
$pegawaiQuery->where('id_kantor', $user->id_kantor);
|
||||
}
|
||||
$pegawai = $pegawaiQuery->orderBy('nama_lengkap', 'asc')->get();
|
||||
|
||||
return view('jadwal.create', compact('shifts', 'pegawai', 'kantor', 'divisi'));
|
||||
}
|
||||
|
|
@ -195,6 +222,20 @@ public function store(Request $request)
|
|||
'user_ids.*' => 'exists:users,id',
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
// Validasi Kantor (Security Check)
|
||||
if (!$isGlobalAdmin) {
|
||||
$invalidUsers = User::whereIn('id', $request->user_ids)
|
||||
->where('id_kantor', '!=', $user->id_kantor)
|
||||
->exists();
|
||||
|
||||
if ($invalidUsers) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan membuat jadwal untuk karyawan di luar kantor Anda.');
|
||||
}
|
||||
}
|
||||
|
||||
$startDate = Carbon::parse($request->tanggal_mulai);
|
||||
$endDate = Carbon::parse($request->tanggal_selesai);
|
||||
$period = \Carbon\CarbonPeriod::create($startDate, $endDate);
|
||||
|
|
@ -216,10 +257,10 @@ public function store(Request $request)
|
|||
|
||||
foreach ($userIds as $userId) {
|
||||
$user = $usersData->get($userId);
|
||||
$isLibur = $libursDate->contains(function($libur) use ($user) {
|
||||
return is_null($libur->id_kantor) || ($user && $libur->id_kantor == $user->id_kantor);
|
||||
$isLibur = $libursDate->contains(function ($libur) use ($user) {
|
||||
return is_null($libur->id_kantor) || ($user && $libur->id_kantor == $user->id_kantor);
|
||||
});
|
||||
|
||||
|
||||
if ($isLibur) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -249,7 +290,6 @@ public function store(Request $request)
|
|||
}
|
||||
|
||||
return redirect()->route('jadwal.index')->with('success', $message);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return redirect()->back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
|
||||
}
|
||||
|
|
@ -262,6 +302,13 @@ public function update(Request $request, $id)
|
|||
]);
|
||||
|
||||
$jadwal = JadwalKerja::findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
// Security Check
|
||||
if (!$user->isGlobalAdmin() && $jadwal->user->id_kantor != $user->id_kantor) {
|
||||
return response()->json(['success' => false, 'message' => 'Anda tidak diizinkan mengubah jadwal karyawan di luar kantor Anda.'], 403);
|
||||
}
|
||||
|
||||
$warningMsg = null;
|
||||
|
||||
try {
|
||||
|
|
@ -284,7 +331,6 @@ public function update(Request $request, $id)
|
|||
'success' => true,
|
||||
'message' => $warningMsg ?? 'Jadwal berhasil diperbarui'
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json(['success' => false, 'message' => $e->getMessage()], 500);
|
||||
}
|
||||
|
|
@ -293,6 +339,13 @@ public function update(Request $request, $id)
|
|||
public function destroy($id)
|
||||
{
|
||||
$jadwal = JadwalKerja::findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
// Security Check
|
||||
if (!$user->isGlobalAdmin() && $jadwal->user->id_kantor != $user->id_kantor) {
|
||||
return response()->json(['success' => false, 'message' => 'Anda tidak diizinkan menghapus jadwal karyawan di luar kantor Anda.'], 403);
|
||||
}
|
||||
|
||||
$jadwal->delete();
|
||||
|
||||
return response()->json(['success' => true, 'message' => 'Jadwal berhasil dihapus']);
|
||||
|
|
@ -307,6 +360,19 @@ public function bulkDestroy(Request $request)
|
|||
'user_ids.*' => 'exists:users,id',
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
if (!$isGlobalAdmin) {
|
||||
$invalidUsers = User::whereIn('id', $request->user_ids)
|
||||
->where('id_kantor', '!=', $user->id_kantor)
|
||||
->exists();
|
||||
|
||||
if ($invalidUsers) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan menghapus jadwal karyawan di luar kantor Anda.');
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
DB::transaction(function () use ($request) {
|
||||
JadwalKerja::whereIn('id_user', $request->user_ids)
|
||||
|
|
|
|||
|
|
@ -19,9 +19,17 @@ class PengajuanIzinController extends Controller
|
|||
public function index(Request $request)
|
||||
{
|
||||
$statusId = $request->get('status');
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
$query = PengajuanIzin::with(['user', 'jenisIzin', 'statusPengajuan', 'suratIzin']);
|
||||
|
||||
if (!$isGlobalAdmin) {
|
||||
$query->whereHas('user', function ($q) use ($user) {
|
||||
$q->where('id_kantor', $user->id_kantor);
|
||||
});
|
||||
}
|
||||
|
||||
if ($statusId) {
|
||||
$query->where('id_status', $statusId);
|
||||
}
|
||||
|
|
@ -121,7 +129,13 @@ public function approve($id)
|
|||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$izin = PengajuanIzin::with('jenisIzin')->findOrFail($id);
|
||||
$izin = PengajuanIzin::with(['jenisIzin', 'user'])->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
// Security Check
|
||||
if (!$user->isGlobalAdmin() && $izin->user->id_kantor != $user->id_kantor) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan menyetujui pengajuan dari kantor lain.');
|
||||
}
|
||||
|
||||
if ($izin->id_status !== 1) {
|
||||
return redirect()->back()->with('error', 'Pengajuan ini sudah diproses sebelumnya.');
|
||||
|
|
@ -178,7 +192,13 @@ public function approve($id)
|
|||
|
||||
public function reject(Request $request, $id)
|
||||
{
|
||||
$izin = PengajuanIzin::findOrFail($id);
|
||||
$izin = PengajuanIzin::with('user')->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
// Security Check
|
||||
if (!$user->isGlobalAdmin() && $izin->user->id_kantor != $user->id_kantor) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan menolak pengajuan dari kantor lain.');
|
||||
}
|
||||
|
||||
if ($izin->id_status !== 1) {
|
||||
return redirect()->back()->with('error', 'Pengajuan ini sudah diproses sebelumnya.');
|
||||
|
|
|
|||
|
|
@ -17,11 +17,20 @@ class PresensiController extends Controller
|
|||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
$tanggal = $request->get('tanggal', Carbon::today()->format('Y-m-d'));
|
||||
$divisiId = $request->get('divisi_id');
|
||||
|
||||
$pendingDates = Presensi::where('id_validasi', 2)
|
||||
->selectRaw('DATE(tanggal) as tgl, COUNT(*) as jumlah')
|
||||
$pendingQuery = Presensi::where('id_validasi', 2);
|
||||
if (!$isGlobalAdmin) {
|
||||
$pendingQuery->whereHas('user', function ($q) use ($user) {
|
||||
$q->where('id_kantor', $user->id_kantor);
|
||||
});
|
||||
}
|
||||
|
||||
$pendingDates = $pendingQuery->selectRaw('DATE(tanggal) as tgl, COUNT(*) as jumlah')
|
||||
->groupBy('tgl')
|
||||
->orderBy('tgl', 'desc')
|
||||
->get();
|
||||
|
|
@ -29,6 +38,12 @@ public function index(Request $request)
|
|||
$query = Presensi::with(['user.jabatan', 'user.kantor'])
|
||||
->whereDate('tanggal', $tanggal);
|
||||
|
||||
if (!$isGlobalAdmin) {
|
||||
$query->whereHas('user', function ($q) use ($user) {
|
||||
$q->where('id_kantor', $user->id_kantor);
|
||||
});
|
||||
}
|
||||
|
||||
if ($divisiId) {
|
||||
$query->whereHas('user', function ($q) use ($divisiId) {
|
||||
$q->where('id_divisi', $divisiId);
|
||||
|
|
@ -109,7 +124,7 @@ public function index(Request $request)
|
|||
|
||||
$item->jarak_masuk = null;
|
||||
if ($item->user && $item->user->kantor && $item->lat_masuk && $item->lon_masuk) {
|
||||
$item->jarak_masuk = app(self::class)->calculateDistance(
|
||||
$item->jarak_masuk = $this->calculateDistance(
|
||||
$item->lat_masuk,
|
||||
$item->lon_masuk,
|
||||
$item->user->kantor->latitude,
|
||||
|
|
@ -131,7 +146,13 @@ public function index(Request $request)
|
|||
|
||||
public function approve($id)
|
||||
{
|
||||
$presensi = Presensi::findOrFail($id);
|
||||
$presensi = Presensi::with('user')->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
if (!$user->isGlobalAdmin() && $presensi->user->id_kantor != $user->id_kantor) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan menyetujui presensi dari kantor lain.');
|
||||
}
|
||||
|
||||
$presensi->update(['id_validasi' => 1]);
|
||||
|
||||
return redirect()->back()->with('success', 'Presensi berhasil disetujui.');
|
||||
|
|
@ -139,7 +160,13 @@ public function approve($id)
|
|||
|
||||
public function reject($id)
|
||||
{
|
||||
$presensi = Presensi::findOrFail($id);
|
||||
$presensi = Presensi::with('user')->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
if (!$user->isGlobalAdmin() && $presensi->user->id_kantor != $user->id_kantor) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan menolak presensi dari kantor lain.');
|
||||
}
|
||||
|
||||
$presensi->update(['id_validasi' => 3]);
|
||||
|
||||
return redirect()->back()->with('success', 'Presensi berhasil ditolak.');
|
||||
|
|
@ -152,6 +179,19 @@ public function bulkAction(Request $request)
|
|||
'action' => 'required|in:approve,reject'
|
||||
]);
|
||||
|
||||
$user = Auth::user();
|
||||
if (!$user->isGlobalAdmin()) {
|
||||
$invalidCount = Presensi::whereIn('id_presensi', $request->presensi_ids)
|
||||
->whereHas('user', function ($q) use ($user) {
|
||||
$q->where('id_kantor', '!=', $user->id_kantor);
|
||||
})
|
||||
->count();
|
||||
|
||||
if ($invalidCount > 0) {
|
||||
return redirect()->back()->with('error', 'Terdapat data dari kantor lain dalam pilihan Anda.');
|
||||
}
|
||||
}
|
||||
|
||||
$statusValidasi = $request->action == 'approve' ? 1 : 3;
|
||||
|
||||
Presensi::whereIn('id_presensi', $request->presensi_ids)
|
||||
|
|
@ -164,9 +204,17 @@ public function bulkAction(Request $request)
|
|||
|
||||
public function create()
|
||||
{
|
||||
$pegawai = \App\Models\User::with('divisi')
|
||||
->orderBy('nama_lengkap', 'asc')
|
||||
->get();
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
$pegawaiQuery = \App\Models\User::with('divisi')
|
||||
->orderBy('nama_lengkap', 'asc');
|
||||
|
||||
if (!$isGlobalAdmin) {
|
||||
$pegawaiQuery->where('id_kantor', $user->id_kantor);
|
||||
}
|
||||
|
||||
$pegawai = $pegawaiQuery->get();
|
||||
|
||||
$statuses = \Illuminate\Support\Facades\DB::table('status_presensi')->get();
|
||||
|
||||
|
|
@ -213,6 +261,12 @@ public function storeManual(StoreManualPresensiRequest $request)
|
|||
public function edit($id)
|
||||
{
|
||||
$presensi = Presensi::with('user.divisi')->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
if (!$user->isGlobalAdmin() && $presensi->user->id_kantor != $user->id_kantor) {
|
||||
abort(403, 'Anda tidak diizinkan mengedit presensi dari kantor lain.');
|
||||
}
|
||||
|
||||
$statuses = \Illuminate\Support\Facades\DB::table('status_presensi')->get();
|
||||
|
||||
return view('presensi.edit', compact('presensi', 'statuses'));
|
||||
|
|
@ -220,6 +274,13 @@ public function edit($id)
|
|||
|
||||
public function updateManual(Request $request, $id)
|
||||
{
|
||||
$presensi = Presensi::with('user')->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
|
||||
if (!$user->isGlobalAdmin() && $presensi->user->id_kantor != $user->id_kantor) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan mengoreksi presensi dari kantor lain.');
|
||||
}
|
||||
|
||||
$request->validate([
|
||||
'id_status' => 'required|exists:status_presensi,id_status',
|
||||
'jam_masuk' => [
|
||||
|
|
|
|||
|
|
@ -15,8 +15,17 @@ class SuratIzinController extends Controller
|
|||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
$query = SuratIzin::with(['user', 'pengajuanIzin.jenisIzin', 'approvals.approver']);
|
||||
|
||||
if (!$isGlobalAdmin) {
|
||||
$query->whereHas('user', function ($q) use ($user) {
|
||||
$q->where('id_kantor', $user->id_kantor);
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->filled('status')) {
|
||||
$query->where('status_surat', $request->status);
|
||||
}
|
||||
|
|
@ -44,17 +53,19 @@ public function show($id)
|
|||
])->findOrFail($id);
|
||||
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
// Security Check: Office Isolation
|
||||
if (!$isGlobalAdmin && $surat->user->id_kantor != $user->id_kantor) {
|
||||
abort(403, 'Anda tidak diizinkan mengakses data dari kantor lain.');
|
||||
}
|
||||
|
||||
$canApprove = false;
|
||||
$tahapApproval = null;
|
||||
|
||||
$isSuperAdmin = $user->roles->contains(function ($role) {
|
||||
return in_array(strtolower($role->nama_role), ['admin', 'super admin', 'super_admin']);
|
||||
});
|
||||
|
||||
if ($surat->status_surat === 'menunggu_manajer' && ($user->roles->contains('nama_role', 'manajer') || $isSuperAdmin)) {
|
||||
if ($surat->status_surat === 'menunggu_manajer' && ($user->roles->contains('nama_role', 'manajer') || $isGlobalAdmin)) {
|
||||
$canApprove = true;
|
||||
$tahapApproval = 1;
|
||||
} elseif ($surat->status_surat === 'menunggu_hrd' && ($user->roles->contains('nama_role', 'hrd') || $isSuperAdmin)) {
|
||||
} elseif ($surat->status_surat === 'menunggu_hrd' && ($user->roles->contains('nama_role', 'hrd') || $isGlobalAdmin)) {
|
||||
$canApprove = true;
|
||||
$tahapApproval = 2;
|
||||
}
|
||||
|
|
@ -67,21 +78,24 @@ public function show($id)
|
|||
public function approve(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$surat = SuratIzin::findOrFail($id);
|
||||
$surat = SuratIzin::with('user')->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
// Security Check
|
||||
if (!$isGlobalAdmin && $surat->user->id_kantor != $user->id_kantor) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan menyetujui surat dari karyawan kantor lain.');
|
||||
}
|
||||
|
||||
if (in_array($surat->status_surat, ['disetujui', 'ditolak'])) {
|
||||
return redirect()->back()->with('error', 'Surat ini sudah diproses sebelumnya.');
|
||||
}
|
||||
|
||||
$tahap = null;
|
||||
$isSuperAdmin = $user->roles->contains(function ($role) {
|
||||
return in_array(strtolower($role->nama_role), ['admin', 'super admin', 'super_admin']);
|
||||
});
|
||||
|
||||
if ($surat->status_surat === 'menunggu_manajer' && ($user->roles->contains('nama_role', 'manajer') || $isSuperAdmin)) {
|
||||
if ($surat->status_surat === 'menunggu_manajer' && ($user->roles->contains('nama_role', 'manajer') || $isGlobalAdmin)) {
|
||||
$tahap = 1;
|
||||
} elseif ($surat->status_surat === 'menunggu_hrd' && ($user->roles->contains('nama_role', 'hrd') || $isSuperAdmin)) {
|
||||
} elseif ($surat->status_surat === 'menunggu_hrd' && ($user->roles->contains('nama_role', 'hrd') || $isGlobalAdmin)) {
|
||||
$tahap = 2;
|
||||
}
|
||||
|
||||
|
|
@ -126,21 +140,24 @@ public function approve(Request $request, $id)
|
|||
public function reject(Request $request, $id)
|
||||
{
|
||||
try {
|
||||
$surat = SuratIzin::findOrFail($id);
|
||||
$surat = SuratIzin::with('user')->findOrFail($id);
|
||||
$user = Auth::user();
|
||||
$isGlobalAdmin = $user->isGlobalAdmin();
|
||||
|
||||
// Security Check
|
||||
if (!$isGlobalAdmin && $surat->user->id_kantor != $user->id_kantor) {
|
||||
return redirect()->back()->with('error', 'Anda tidak diizinkan menolak surat dari karyawan kantor lain.');
|
||||
}
|
||||
|
||||
if (in_array($surat->status_surat, ['disetujui', 'ditolak'])) {
|
||||
return redirect()->back()->with('error', 'Surat ini sudah diproses sebelumnya.');
|
||||
}
|
||||
|
||||
$tahap = null;
|
||||
$isSuperAdmin = $user->roles->contains(function ($role) {
|
||||
return in_array(strtolower($role->nama_role), ['admin', 'super admin', 'super_admin']);
|
||||
});
|
||||
|
||||
if ($surat->status_surat === 'menunggu_manajer' && ($user->roles->contains('nama_role', 'manajer') || $isSuperAdmin)) {
|
||||
if ($surat->status_surat === 'menunggu_manajer' && ($user->roles->contains('nama_role', 'manajer') || $isGlobalAdmin)) {
|
||||
$tahap = 1;
|
||||
} elseif ($surat->status_surat === 'menunggu_hrd' && ($user->roles->contains('nama_role', 'hrd') || $isSuperAdmin)) {
|
||||
} elseif ($surat->status_surat === 'menunggu_hrd' && ($user->roles->contains('nama_role', 'hrd') || $isGlobalAdmin)) {
|
||||
$tahap = 2;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue