Commit 12e69c7d by Alfiro Pratama

sync noidentitas operator

parent 1b4808e5
<?php
namespace App\Http\Controllers\Operator;
use App\Http\Controllers\Controller;
use App\Models\Auth\Biodata;
use App\Models\User;
use App\Repositories\Auth\IsdmRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use RealRashid\SweetAlert\Facades\Alert;
class SyncNoidentitasController extends Controller
{
/** @var IsdmRepository */
private $isdmRepo;
public function __construct(IsdmRepository $isdmRepo)
{
$this->isdmRepo = $isdmRepo;
}
/**
* Daftar dosen yang noidentitas-nya masih null.
*/
public function index()
{
$data['title'] = 'Sync Noidentitas Dosen';
$data['users'] = User::with(['rBiodata', 'rolesCustom'])
->whereHas('rolesCustom', function ($q) {
return $q->where('name', 'dosen');
})
->whereHas('rBiodata', function ($q) {
return $q->whereNull('noidentitas');
})
->orderBy('name', 'asc')
->get();
return view('backend.operator.sync_noidentitas.index', $data);
}
/**
* Ambil NIDN/NUPTK dari API i-sdm berdasarkan email (untuk tombol Sync - isi ke kolom input).
*/
public function fetch(Request $request)
{
$biodataId = $request->input('biodata_id');
if (!$biodataId) {
return response()->json(['success' => false, 'message' => 'biodata_id wajib.']);
}
try {
$id = Crypt::decrypt($biodataId);
} catch (\Exception $e) {
return response()->json(['success' => false, 'message' => 'ID tidak valid.']);
}
$user = User::find($id);
if (!$user || !$user->email) {
return response()->json(['success' => false, 'message' => 'User/email tidak ditemukan.']);
}
$nidnOrNuptk = $this->isdmRepo->getNidnOrNuptkByEmail($user->email);
if ($nidnOrNuptk === null || $nidnOrNuptk === '') {
return response()->json(['success' => false, 'message' => 'Data tidak ditemukan di i-sdm untuk email ini.']);
}
return response()->json(['success' => true, 'nidn_or_nuptk' => $nidnOrNuptk]);
}
/**
* Update biodata: simpan noidentitas (NIDN ?? NUPTK) dari API i-sdm ke biodata simpmw.
*/
public function update(Request $request)
{
$request->validate([
'biodata_id' => 'required|string',
'identifier' => 'required|string|max:50',
], [
'identifier.required' => 'NIDN atau NUPTK wajib diisi.',
]);
$biodataId = Crypt::decrypt($request->biodata_id);
$biodata = Biodata::find($biodataId);
if (!$biodata) {
Alert::error('Biodata tidak ditemukan.');
return redirect()->route('operator.sync-noidentitas.index');
}
if ($biodata->noidentitas !== null) {
Alert::info('Noidentitas sudah terisi.');
return redirect()->route('operator.sync-noidentitas.index');
}
$isdm = $this->isdmRepo->getByNidnOrNip($request->identifier);
if (empty($isdm) || !isset($isdm[0])) {
Alert::error('Data tidak ditemukan di i-sdm. Pastikan NIDN atau NUPTK benar.');
return redirect()->route('operator.sync-noidentitas.index');
}
$row = $isdm[0];
$noidentitas = $row->nidn ?? $row->nuptk ?? $row->nip ?? null;
if ($noidentitas === null || $noidentitas === '') {
Alert::error('Data i-sdm tidak memiliki NIDN/NUPTK.');
return redirect()->route('operator.sync-noidentitas.index');
}
$biodata->noidentitas = $noidentitas;
$biodata->save();
Alert::success('Noidentitas berhasil diupdate: ' . $noidentitas);
return redirect()->route('operator.sync-noidentitas.index');
}
}
...@@ -59,7 +59,7 @@ class BiodataRepository ...@@ -59,7 +59,7 @@ class BiodataRepository
// $data['noid'] = $isdm[0]->nip; // $data['noid'] = $isdm[0]->nip;
$data['email'] = $auth[0]->email; $data['email'] = $auth[0]->email;
$data['name'] = $isdm[0]->nama; $data['name'] = $isdm[0]->nama;
$data['noid'] = $isdm[0]->nidn; $data['noid'] = $isdm[0]->nidn ?? $isdm[0]->nuptk;
if ($isdm[0]->isdosen == 0) { if ($isdm[0]->isdosen == 0) {
$data['role'] = 'tendik'; $data['role'] = 'tendik';
} else { } else {
......
...@@ -35,4 +35,83 @@ class IsdmRepository ...@@ -35,4 +35,83 @@ class IsdmRepository
return $isdm; return $isdm;
} }
/**
* Get data from i-sdm by NIDN or NIP (untuk NUPTK).
* Coba NIDN dulu, jika gagal coba NIP.
*
* @param string $value NIDN atau NUPTK/NIP
* @return object[]|null Data isdm atau null jika tidak ditemukan
*/
public function getByNidnOrNip($value)
{
$value = trim($value);
if ($value === '') {
return null;
}
try {
$isdm = $this->nidn($value);
if (!empty($isdm) && isset($isdm[0])) {
return $isdm;
}
} catch (\Exception $e) {
// coba dengan NIP (biodataumum by nip/nuptk)
}
try {
$isdm = $this->nip($value);
if (!empty($isdm) && isset($isdm[0])) {
return $isdm;
}
} catch (\Exception $e) {
return null;
}
return null;
}
/**
* Ambil NIDN atau NUPTK berdasarkan email: API SSO userid/{email} → userid → i-sdm biodataumum/{userid}.
* Sama seperti alur login (LoginController + BiodataRepository::isdm).
*
* @param string $email
* @return string|null NIDN atau NUPTK, null jika tidak ditemukan
*/
public function getNidnOrNuptkByEmail($email)
{
$email = trim($email);
if ($email === '') {
return null;
}
try {
$client = new GuzzleHttpClient();
$apiRequest = $client->request('GET', 'https://sso.unesa.ac.id/userid/' . $email);
$auth = json_decode($apiRequest->getBody()->getContents());
} catch (\Exception $e) {
return null;
}
if (!is_array($auth) || empty($auth) || !isset($auth[0]->userid)) {
return null;
}
$userid = trim($auth[0]->userid);
if ($userid === '') {
return null;
}
try {
$isdm = $this->nip($userid);
if (!empty($isdm) && isset($isdm[0])) {
$row = $isdm[0];
return $row->nidn ?? $row->nuptk ?? $row->nip ?? null;
}
} catch (\Exception $e) {
return null;
}
return null;
}
} }
...@@ -116,7 +116,7 @@ ...@@ -116,7 +116,7 @@
</tr> </tr>
<tr> <tr>
<td class="d-flex align-items-center mdi mdi-card-account-details-outline mdi-20px"> <td class="d-flex align-items-center mdi mdi-card-account-details-outline mdi-20px">
<span class="fw-medium mx-2 me-auto">NIP / NIDN</span> <span class="fw-medium mx-2 me-auto">NIP / NIDN / NUPTK</span>
<span class="text-end">:</span> <span class="text-end">:</span>
</td> </td>
<td>{{ $biodata->noidentitas }}</td> <td>{{ $biodata->noidentitas }}</td>
......
@extends('layouts.master')
@section('title')
Sync Noidentitas Dosen
@endsection
@section('header')
<div class="page-title">
<h3>Dashboard</h3>
</div>
@endsection
@section('contents')
<div class="page-title-box">
<div class="row align-items-center">
<div class="col-md-12">
<h6 class="page-title">{!! $title !!}</h6>
<ol class="breadcrumb m-0">
<li class="breadcrumb-item">Operator</li>
<li class="breadcrumb-item active">{!! $title !!}</li>
</ol>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<p class="text-muted mb-3">
Dosen di bawah ini belum memiliki noidentitas. Klik <strong>Sync</strong> untuk mengambil NIDN/NUPTK dari API i-sdm ke kolom input, periksa atau ubah bila perlu, lalu klik <strong>Update</strong> untuk menyimpan ke biodata simpmw.
</p>
@if($users->isEmpty())
<p class="text-success mb-0">Tidak ada dosen dengan noidentitas kosong.</p>
@else
<div class="table-responsive">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th width="50">No.</th>
<th>Nama</th>
<th>Email</th>
<th>NIDN / NUPTK</th>
</tr>
</thead>
<tbody>
@foreach ($users as $item)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $item->name }}</td>
<td>{{ $item->email }}</td>
<td>
<form action="{{ route('operator.sync-noidentitas.update') }}" method="POST" class="row-sync-form d-flex gap-1 align-items-center flex-wrap">
@csrf
<input type="hidden" name="biodata_id" value="{{ Crypt::encrypt($item->id) }}" class="row-biodata-id">
<input type="text" name="identifier" class="form-control form-control-sm row-identifier" placeholder="Klik Sync untuk ambil dari i-sdm" maxlength="50" required style="max-width: 180px;">
<button type="button" class="btn btn-sm btn-outline-primary btn-sync">Sync</button>
<button type="submit" class="btn btn-sm btn-primary">Update</button>
</form>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
</div>
</div>
</div>
</div>
@endsection
@section('js')
<script>
$(function() {
$('.btn-sync').on('click', function() {
var $row = $(this).closest('.row-sync-form');
var biodataId = $row.find('.row-biodata-id').val();
var $input = $row.find('.row-identifier');
var $btn = $(this);
if (!biodataId) return;
$btn.prop('disabled', true).text('...');
$.ajax({
url: '{{ route("operator.sync-noidentitas.fetch") }}',
type: 'GET',
data: { biodata_id: biodataId },
dataType: 'json',
success: function(res) {
if (res.success && res.nidn_or_nuptk) {
$input.val(res.nidn_or_nuptk);
} else {
alert(res.message || 'Data tidak ditemukan di i-sdm.');
}
},
error: function(xhr) {
var msg = (xhr.responseJSON && xhr.responseJSON.message) ? xhr.responseJSON.message : 'Gagal mengambil data.';
alert(msg);
},
complete: function() {
$btn.prop('disabled', false).text('Sync');
}
});
});
});
</script>
@endsection
...@@ -15,6 +15,7 @@ use App\Http\Controllers\Operator\ReviewerController; ...@@ -15,6 +15,7 @@ use App\Http\Controllers\Operator\ReviewerController;
use App\Http\Controllers\Authentication\LoginController; use App\Http\Controllers\Authentication\LoginController;
use App\Http\Controllers\Reviewer\DaftarMonevController; use App\Http\Controllers\Reviewer\DaftarMonevController;
use App\Http\Controllers\Operator\UserExternalController; use App\Http\Controllers\Operator\UserExternalController;
use App\Http\Controllers\Operator\SyncNoidentitasController;
use App\Http\Controllers\Operator\MonevProposalController; use App\Http\Controllers\Operator\MonevProposalController;
use App\Http\Controllers\Operator\ReviewerMonevController; use App\Http\Controllers\Operator\ReviewerMonevController;
use App\Http\Controllers\Operator\PengumumanController; use App\Http\Controllers\Operator\PengumumanController;
...@@ -219,6 +220,10 @@ Route::group(['middleware' => ['auth:sanctum', 'verified']], function () { ...@@ -219,6 +220,10 @@ Route::group(['middleware' => ['auth:sanctum', 'verified']], function () {
Route::resource('user-external', UserExternalController::class); Route::resource('user-external', UserExternalController::class);
Route::get('sync-noidentitas', [SyncNoidentitasController::class, 'index'])->name('sync-noidentitas.index');
Route::get('sync-noidentitas/fetch', [SyncNoidentitasController::class, 'fetch'])->name('sync-noidentitas.fetch');
Route::post('sync-noidentitas/update', [SyncNoidentitasController::class, 'update'])->name('sync-noidentitas.update');
Route::resource('pengumuman', PengumumanController::class); Route::resource('pengumuman', PengumumanController::class);
// cek email apakah sudah ada apa belum // cek email apakah sudah ada apa belum
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment