done approval -> next testing
This commit is contained in:
parent
0ee7b75460
commit
798455de16
@ -17,6 +17,7 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use Mockery\Matcher\Not;
|
||||
use PhpOffice\PhpSpreadsheet\Spreadsheet;
|
||||
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
|
||||
use setasign\Fpdi\Fpdi;
|
||||
@ -1330,20 +1331,36 @@ class DashboardController extends Controller
|
||||
$isAtasan = MappingUnitKerjaPegawai::where('statusenabled', true)->where(function($q){
|
||||
$q->where('objectatasanlangsungfk', auth()->user()?->dataUser?->id)->orWhere('objectpejabatpenilaifk', auth()->user()->objectpegawaifk);
|
||||
})->exists();
|
||||
|
||||
$objectUnit = MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
|
||||
->pluck('objectunitkerjapegawaifk')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
$isKomiteMutu = in_array(51, $objectUnit);
|
||||
$isTurt = in_array(22, $objectUnit);
|
||||
foreach ($datas as $index => $data) {
|
||||
if(isset(explode('/', $data['id_unit_kerja'],2)[1])){
|
||||
list($id_unit_kerja, $nama_unit_kerja) = explode('/', $data['id_unit_kerja'],2);
|
||||
}else{
|
||||
$nama_unit_kerja = UnitKerja::where('id', $data['id_unit_kerja'])->first()->name;
|
||||
$id_unit_kerja = $data['id_unit_kerja'];
|
||||
}
|
||||
list($id_sub_unit_kerja, $nama_sub_unit_kerja) = explode('/', $data['id_sub_unit_kerja'],2);
|
||||
if($data['master_kategori_directory_id']){
|
||||
list($master_kategori_directory_id, $nama_kategori) = explode('/', $data['master_kategori_directory_id'],2);
|
||||
}
|
||||
if(isset($data['akre'])){
|
||||
$path = $data['akre'];
|
||||
}else{
|
||||
if(isset($data['master_kategori_directory_id'])){
|
||||
list($master_kategori_directory_id, $nama_kategori) = explode('/', $data['master_kategori_directory_id'],2);
|
||||
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}/{$nama_kategori}";
|
||||
}else{
|
||||
$path = "{$nama_unit_kerja}/{$nama_sub_unit_kerja}";
|
||||
}
|
||||
}
|
||||
|
||||
$uploadedFile = request()->file("data.$index.file");
|
||||
if(!$uploadedFile){
|
||||
throw new \RuntimeException('File wajib diunggah pada segment ke-' . ($index+1));
|
||||
@ -1351,8 +1368,14 @@ class DashboardController extends Controller
|
||||
if (!$uploadedFile->isValid()) {
|
||||
throw new \RuntimeException('Upload file gagal pada segment ke-' . ($index+1));
|
||||
}
|
||||
$status = $isAtasan ? 'approved' : null;
|
||||
dd($data);
|
||||
$requiresMutuApproval = isset($data['akre']);
|
||||
$requiresTurtApproval = !empty($master_kategori_directory_id);
|
||||
$mutuStatus = $isKomiteMutu && $requiresMutuApproval ? 'approved' : null;
|
||||
$turtStatus = $isTurt && $requiresTurtApproval ? 'approved' : null;
|
||||
$finalApproved = $isAtasan
|
||||
&& (!$requiresMutuApproval || $mutuStatus === 'approved')
|
||||
&& (!$requiresTurtApproval || $turtStatus === 'approved');
|
||||
$status = $finalApproved ? 'approved' : null;
|
||||
$payload = [
|
||||
'id_unit_kerja' => $id_unit_kerja,
|
||||
'id_sub_unit_kerja' => $id_sub_unit_kerja,
|
||||
@ -1368,28 +1391,34 @@ class DashboardController extends Controller
|
||||
'action_by' => $status && $status === "approved" ? auth()->user()->objectpegawaifk : null,
|
||||
'action_at' => $status && $status === "approved" ? now() : null,
|
||||
'is_akre' => isset($data['akre']),
|
||||
'kategori_hukum' => isset($data['kategori_hukum']) ? $data['kategori_hukum'] : null
|
||||
'kategori_hukum' => isset($data['kategori_hukum']) ? $data['kategori_hukum'] : null,
|
||||
'status_mutu' => $mutuStatus,
|
||||
'action_mutu_at' => $mutuStatus === 'approved' ? now() : null,
|
||||
'action_mutu_by' => $mutuStatus === 'approved' ? auth()->user()->objectpegawaifk : null,
|
||||
'status_turt' => $turtStatus,
|
||||
'action_turt_at' => $turtStatus === 'approved' ? now() : null,
|
||||
'action_turt_by' => $turtStatus === 'approved' ? auth()->user()->objectpegawaifk : null,
|
||||
];
|
||||
$fd = FileDirectory::create($payload);
|
||||
|
||||
$disk = Storage::disk('s3');
|
||||
// $disk = Storage::disk('s3');
|
||||
$imageName = $this->buildStoredFileName(
|
||||
$fd->nama_dokumen ?? null,
|
||||
$fd->file_directory_id,
|
||||
$uploadedFile->getClientOriginalExtension()
|
||||
);
|
||||
$disk->putFileAs(
|
||||
$path,
|
||||
$uploadedFile,
|
||||
$imageName,
|
||||
['visibility' => 'private']
|
||||
);
|
||||
// $disk->putFileAs(
|
||||
// $path,
|
||||
// $uploadedFile,
|
||||
// $imageName,
|
||||
// ['visibility' => 'private']
|
||||
// );
|
||||
$fd->update([
|
||||
'file' => $path . '/' . $imageName
|
||||
]);
|
||||
$docNumber = $fd->no_dokumen ? 'nomor '. $fd->no_dokumen : $data['nama_dokumen'];
|
||||
if(!$isAtasan){
|
||||
$uploaderName = auth()->user()?->dataUser?->namalengkap ?? 'Pengguna';
|
||||
$docNumber = $fd->no_dokumen ? 'nomor '. $fd->no_dokumen : $imageName;
|
||||
$payloadNotification = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh {$uploaderName}.",
|
||||
@ -1412,15 +1441,40 @@ class DashboardController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
if($isAtasan){
|
||||
if($fd->is_akre && $fd->status_mutu !== 'approved'){
|
||||
$payloadNotificationMutu = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh " . auth()->user()->dataUser->namalengkap,
|
||||
'url' => '/pengajuan-file',
|
||||
'is_read' => false,
|
||||
'unit_id' => 51,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotificationMutu);
|
||||
}
|
||||
if($fd->master_kategori_directory_id && $fd->status_turt !== 'approved'){
|
||||
$payloadNotificationTurt = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh " . auth()->user()->dataUser->namalengkap,
|
||||
'url' => '/pengajuan-file',
|
||||
'is_read' => false,
|
||||
'unit_id' => 22,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotificationTurt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'Data berhasil disimpan',
|
||||
'status_action' => $isAtasan ? 'approved' : null
|
||||
'status_action' => $status
|
||||
], 200);
|
||||
} catch (\Throwable $th) {
|
||||
// dd($th);
|
||||
dd($th);
|
||||
DB::connection('dbDirectory')->rollback();
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
@ -1822,7 +1876,19 @@ class DashboardController extends Controller
|
||||
}
|
||||
|
||||
public function pendingFile(){
|
||||
return view('pendingFile.index', ['title' => 'Data Persetujuan']);
|
||||
$objectUnit = MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
|
||||
->pluck('objectunitkerjapegawaifk')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
|
||||
return view('pendingFile.index', [
|
||||
'title' => 'Data Persetujuan',
|
||||
'isKomiteMutu' => in_array(51, $objectUnit),
|
||||
'isTurt' => in_array(22, $objectUnit),
|
||||
]);
|
||||
}
|
||||
|
||||
public function dataPendingFile(){
|
||||
@ -1840,18 +1906,80 @@ class DashboardController extends Controller
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
$objectUnit = MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
|
||||
->pluck('objectunitkerjapegawaifk')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
$keyword = request('keyword');
|
||||
$query = FileDirectory::where('statusenabled', true)
|
||||
->where(function($qsa){
|
||||
$qsa->where('status_action', '!=', 'approved')->orWhereNull('status_action');
|
||||
$isKomiteMutu = in_array(51, $objectUnit);
|
||||
$isTurt = in_array(22, $objectUnit);
|
||||
// 51 / Komite Mutu
|
||||
// 22 / turt
|
||||
$query = FileDirectory::where('statusenabled', true);
|
||||
|
||||
if ($isKomiteMutu || $isTurt) {
|
||||
$query->where('status_action', 'approved')
|
||||
->where(function ($q) use ($isKomiteMutu, $isTurt) {
|
||||
if ($isTurt) {
|
||||
$q->where(function ($sub) {
|
||||
$sub->whereNotNull('master_kategori_directory_id')
|
||||
->where(function ($pendingTurt) {
|
||||
$pendingTurt->whereNull('status_turt')
|
||||
->orWhere('status_turt', 'rejected');
|
||||
});
|
||||
});
|
||||
}
|
||||
if ($isKomiteMutu) {
|
||||
$method = $isTurt ? 'orWhere' : 'where';
|
||||
$q->{$method}(function ($sub) {
|
||||
$sub->where('is_akre', true)
|
||||
->where(function ($pendingMutu) {
|
||||
$pendingMutu->whereNull('status_mutu')
|
||||
->orWhere('status_mutu', 'rejected');
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$query->where(function ($qsa) {
|
||||
$qsa->where('status_action', '!=', 'approved')
|
||||
->orWhereNull('status_action')
|
||||
->orWhere(function ($approvedButPending) {
|
||||
$approvedButPending->where('status_action', 'approved')
|
||||
->where(function ($needFurtherApproval) {
|
||||
$needFurtherApproval
|
||||
->where(function ($needTurt) {
|
||||
$needTurt->whereNotNull('master_kategori_directory_id')
|
||||
->where(function ($pendingTurt) {
|
||||
$pendingTurt->whereNull('status_turt')
|
||||
->orWhere('status_turt', 'rejected');
|
||||
});
|
||||
})
|
||||
->whereIn('pegawai_id_entry', $objectpegawaifk)
|
||||
->when($keyword, function ($q) use ($keyword) {
|
||||
->orWhere(function ($needMutu) {
|
||||
$needMutu->where('is_akre', true)
|
||||
->where(function ($pendingMutu) {
|
||||
$pendingMutu->whereNull('status_mutu')
|
||||
->orWhere('status_mutu', 'rejected');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
$query->when($keyword, function ($q) use ($keyword) {
|
||||
$q->where(function ($sub) use ($keyword) {
|
||||
$sub->where('nama_dokumen', 'ILIKE', "%{$keyword}%")
|
||||
->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%");
|
||||
});
|
||||
});
|
||||
if(!empty($objectpegawaifk) && !$isKomiteMutu && !$isTurt){
|
||||
$query->whereIn('pegawai_id_entry', $objectpegawaifk);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if($start){
|
||||
$query->whereDate('entry_at','>=',$start);
|
||||
@ -1877,9 +2005,14 @@ class DashboardController extends Controller
|
||||
'tanggal_terbit' => $item->tanggal_terbit,
|
||||
'permission_file' => $item->permission_file,
|
||||
'status_action' => $item->status_action,
|
||||
'status_mutu' => $item->status_mutu,
|
||||
'status_turt' => $item->status_turt,
|
||||
'mutu_revision' => $item->mutu_revision,
|
||||
'turt_revision' => $item->turt_revision,
|
||||
'id_unit_kerja' => $item->id_unit_kerja,
|
||||
'id_sub_unit_kerja' => $item->id_sub_unit_kerja,
|
||||
'master_kategori_directory_id' => $item->master_kategori_directory_id
|
||||
'master_kategori_directory_id' => $item->master_kategori_directory_id,
|
||||
'is_akre' => $item->is_akre,
|
||||
];
|
||||
});
|
||||
return response()->json([
|
||||
@ -1942,6 +2075,29 @@ class DashboardController extends Controller
|
||||
'action_type' => 'Approved Dokumen',
|
||||
];
|
||||
LogActivity::create($payloadLog);
|
||||
if($data->is_akre){
|
||||
$payloadNotificationMutu = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh {$data->pegawai_nama_entry}.",
|
||||
'url' => '/pending-file',
|
||||
'is_read' => false,
|
||||
'unit_id' => 51,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotificationMutu);
|
||||
}
|
||||
if($data->master_kategori_directory_id){
|
||||
$payloadNotificationTurt = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh {$data->pegawai_nama_entry}.",
|
||||
'url' => '/pending-file',
|
||||
'is_read' => false,
|
||||
'unit_id' => 22,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotificationTurt);
|
||||
}
|
||||
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
@ -2224,7 +2380,16 @@ class DashboardController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
$pegawaiId = auth()->user()?->dataUser?->id;
|
||||
$pegawaiId = auth()->user()?->objectpegawaifk;
|
||||
$objectUnit = MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
|
||||
->pluck('objectunitkerjapegawaifk')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
$isKomiteMutu = in_array(51, $objectUnit);
|
||||
$isTurt = in_array(22, $objectUnit);
|
||||
if (!$pegawaiId) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
@ -2233,8 +2398,16 @@ class DashboardController extends Controller
|
||||
'unread' => 0
|
||||
], 404);
|
||||
}
|
||||
|
||||
$query = Notifkasi::where('pegawai_id', $pegawaiId);
|
||||
$query = Notifkasi::query();
|
||||
$query->where(function($q) use($pegawaiId, $objectUnit, $isKomiteMutu, $isTurt){
|
||||
if($isKomiteMutu || $isTurt){
|
||||
$q->orWhere(function($sub) use($objectUnit){
|
||||
$sub->whereNull('pegawai_id')->whereIn('unit_id', $objectUnit);
|
||||
});
|
||||
}else{
|
||||
$q->where('pegawai_id', $pegawaiId);
|
||||
}
|
||||
});
|
||||
$unread = (clone $query)->where('is_read', false)->count();
|
||||
$items = $query->orderBy('created_at', 'desc')
|
||||
->limit(20)
|
||||
@ -2266,6 +2439,15 @@ class DashboardController extends Controller
|
||||
}
|
||||
|
||||
$pegawaiId = auth()->user()?->dataUser?->id;
|
||||
$objectUnit = MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
|
||||
->pluck('objectunitkerjapegawaifk')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
$isKomiteMutu = in_array(51, $objectUnit);
|
||||
$isTurt = in_array(22, $objectUnit);
|
||||
if (!$pegawaiId) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
@ -2273,8 +2455,16 @@ class DashboardController extends Controller
|
||||
], 404);
|
||||
}
|
||||
|
||||
Notifkasi::where('pegawai_id', $pegawaiId)
|
||||
->where('is_read', false)
|
||||
$query = Notifkasi::query();
|
||||
$query->where(function($q) use($pegawaiId, $isKomiteMutu, $isTurt, $objectUnit){
|
||||
if($isKomiteMutu || $isTurt){
|
||||
$q->orWhere(function($sub) use($objectUnit){
|
||||
$sub->whereNull('pegawai_id')->whereIn('unit_id', $objectUnit);
|
||||
});
|
||||
}else{
|
||||
$q->where('pegawai_id', $pegawaiId);
|
||||
}
|
||||
})->where('is_read', false)
|
||||
->update(['is_read' => true]);
|
||||
|
||||
return response()->json([
|
||||
@ -2515,9 +2705,20 @@ class DashboardController extends Controller
|
||||
$katDok = MasterKategori::where('statusenabled', true)
|
||||
->select('master_kategori_directory_id', 'nama_kategori_directory')
|
||||
->get();
|
||||
$objectUnit = MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
|
||||
->pluck('objectunitkerjapegawaifk')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
$isKomiteMutu = in_array(51, $objectUnit);
|
||||
$isTurt = in_array(22, $objectUnit);
|
||||
return view('pengajuanFile.index', [
|
||||
'title' => 'Data Persetujuan',
|
||||
'katDok' => $katDok
|
||||
'katDok' => $katDok,
|
||||
'isKomiteMutu' => $isKomiteMutu,
|
||||
'isTurt' => $isTurt
|
||||
]);
|
||||
}
|
||||
|
||||
@ -2527,21 +2728,87 @@ class DashboardController extends Controller
|
||||
$start = request('start_date');
|
||||
$end = request('end_date');
|
||||
$isHistory = filter_var(request('history'), FILTER_VALIDATE_BOOLEAN);
|
||||
$query = FileDirectory::with('kategori')->where('statusenabled', true)
|
||||
->where('pegawai_id_entry', auth()->user()->objectpegawaifk)
|
||||
$mode = (string) request('mode', 'pengajuan');
|
||||
$pegawaiId = auth()->user()->objectpegawaifk;
|
||||
$objectUnit = MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', $pegawaiId)
|
||||
->pluck('objectunitkerjapegawaifk')
|
||||
->unique()
|
||||
->values()
|
||||
->all();
|
||||
$isKomiteMutu = in_array(51, $objectUnit);
|
||||
$isTurt = in_array(22, $objectUnit);
|
||||
|
||||
$query = FileDirectory::with('kategori')->where('statusenabled', true);
|
||||
|
||||
if ($mode === 'persetujuan' && ($isKomiteMutu || $isTurt)) {
|
||||
$query->where(function ($q) use ($isKomiteMutu, $isTurt) {
|
||||
if ($isTurt) {
|
||||
$q->whereNotNull('master_kategori_directory_id')
|
||||
->where(function ($pendingTurt) {
|
||||
$pendingTurt->whereNull('status_turt')
|
||||
->orWhere('status_turt', 'rejected');
|
||||
});
|
||||
}
|
||||
if ($isKomiteMutu) {
|
||||
$method = $isTurt ? 'orWhere' : 'where';
|
||||
$q->{$method}(function ($sub) {
|
||||
$sub->where('is_akre', true)
|
||||
->where(function ($pendingMutu) {
|
||||
$pendingMutu->whereNull('status_mutu')
|
||||
->orWhere('status_mutu', 'rejected');
|
||||
});
|
||||
});
|
||||
}
|
||||
})->where('status_action', 'approved');
|
||||
} else {
|
||||
$query->where('pegawai_id_entry', $pegawaiId)
|
||||
->when($isHistory, function($q){
|
||||
$q->where('status_action', 'approved');
|
||||
$q->where('status_action', 'approved')
|
||||
->where(function ($sub) {
|
||||
$sub->whereNull('master_kategori_directory_id')
|
||||
->orWhere('status_turt', 'approved');
|
||||
})
|
||||
->where(function ($sub) {
|
||||
$sub->where('is_akre', '!=', true)
|
||||
->orWhereNull('is_akre')
|
||||
->orWhere('status_mutu', 'approved');
|
||||
});
|
||||
}, function($q){
|
||||
$q->where(function($sub){
|
||||
$sub->where('status_action', '!=', 'approved')
|
||||
->orWhereNull('status_action');
|
||||
->orWhereNull('status_action')
|
||||
->orWhere(function ($approvedButPending) {
|
||||
$approvedButPending->where('status_action', 'approved')
|
||||
->where(function ($needFurtherApproval) {
|
||||
$needFurtherApproval
|
||||
->where(function ($needTurt) {
|
||||
$needTurt->whereNotNull('master_kategori_directory_id')
|
||||
->where(function ($pendingTurt) {
|
||||
$pendingTurt->whereNull('status_turt')
|
||||
->orWhere('status_turt', 'rejected');
|
||||
});
|
||||
})
|
||||
->orderBy('entry_at','desc');
|
||||
->orWhere(function ($needMutu) {
|
||||
$needMutu->where('is_akre', true)
|
||||
->where(function ($pendingMutu) {
|
||||
$pendingMutu->whereNull('status_mutu')
|
||||
->orWhere('status_mutu', 'rejected');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$query->orderBy('entry_at','desc');
|
||||
if($keyword){
|
||||
$query->where(function($q) use ($keyword){
|
||||
$q->where('file', 'ILIKE', "%{$keyword}%")
|
||||
->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%");
|
||||
->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%")
|
||||
->orWhere('nama_dokumen', 'ILIKE', "%{$keyword}%");
|
||||
});
|
||||
}
|
||||
if($start){
|
||||
@ -2568,6 +2835,10 @@ class DashboardController extends Controller
|
||||
'permission_file' => $item->permission_file,
|
||||
'status_action' => $item->status_action,
|
||||
'revision' => $item->revision,
|
||||
'status_mutu' => $item->status_mutu,
|
||||
'status_turt' => $item->status_turt,
|
||||
'mutu_revision' => $item->mutu_revision,
|
||||
'turt_revision' => $item->turt_revision,
|
||||
'id_unit_kerja' => $item->id_unit_kerja,
|
||||
'id_sub_unit_kerja' => $item->id_sub_unit_kerja,
|
||||
'master_kategori_directory_id' => $item->master_kategori_directory_id,
|
||||
@ -2727,39 +2998,70 @@ class DashboardController extends Controller
|
||||
}
|
||||
}
|
||||
}
|
||||
$targetRoleNotifications = [];
|
||||
$resetMutuApproval = $data->status_mutu === 'rejected';
|
||||
$resetTurtApproval = $data->status_turt === 'rejected';
|
||||
|
||||
if ($resetMutuApproval) {
|
||||
$payload['status_mutu'] = null;
|
||||
$payload['mutu_revision'] = null;
|
||||
$payload['action_mutu_at'] = null;
|
||||
$payload['action_mutu_by'] = null;
|
||||
$targetRoleNotifications[] = 51;
|
||||
}
|
||||
|
||||
if ($resetTurtApproval) {
|
||||
$payload['status_turt'] = null;
|
||||
$payload['turt_revision'] = null;
|
||||
$payload['action_turt_at'] = null;
|
||||
$payload['action_turt_by'] = null;
|
||||
$targetRoleNotifications[] = 22;
|
||||
}
|
||||
|
||||
$payload['revision'] = null;
|
||||
$payload['status_action'] = 'revised';
|
||||
$payload['action_at'] = null;
|
||||
$payload['action_by'] = null;
|
||||
|
||||
|
||||
if (!empty($payload)) {
|
||||
$data->update($payload);
|
||||
}
|
||||
$data->refresh();
|
||||
$mapping = MappingUnitKerjaPegawai::where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()?->dataUser?->id)
|
||||
->first();
|
||||
$parts = array_values(array_filter(explode('/', $data->file)));
|
||||
$uploaderName = auth()->user()?->dataUser?->namalengkap ?? 'Pengguna';
|
||||
$docNumber = $data->no_dokumen ? 'nomor '. $data->no_dokumen : end($parts);;
|
||||
$payloadNotification = [
|
||||
$notifText = "Dokumen {$docNumber} telah direvisi dan memerlukan persetujuan ulang. Direvisi oleh {$uploaderName}.";
|
||||
$targetRoleNotifications = array_values(array_unique($targetRoleNotifications));
|
||||
|
||||
if (!empty($targetRoleNotifications)) {
|
||||
foreach ($targetRoleNotifications as $unitId) {
|
||||
Notifkasi::create([
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} telah direvisi dan memerlukan persetujuan ulang. ". "Direvisi oleh {$uploaderName}.",
|
||||
'text_notifikasi' => $notifText,
|
||||
'url' => '/pengajuan-file',
|
||||
'is_read' => false,
|
||||
'unit_id' => $unitId,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
$pegawaiTargets = array_filter([
|
||||
$mapping?->objectatasanlangsungfk,
|
||||
$mapping?->objectpejabatpenilaifk,
|
||||
]);
|
||||
|
||||
foreach (array_unique($pegawaiTargets) as $pegawaiId) {
|
||||
Notifkasi::create([
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => $notifText,
|
||||
'url' => '/pending-file',
|
||||
'is_read' => false,
|
||||
'pegawai_id' => $mapping?->objectatasanlangsungfk,
|
||||
];
|
||||
|
||||
|
||||
Notifkasi::create($payloadNotification);
|
||||
|
||||
if($mapping->objectpejabatpenilaifk){
|
||||
$payloadNotification = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} telah direvisi dan memerlukan persetujuan ulang. ". "Direvisi oleh {$uploaderName}.",
|
||||
'url' => '/pending-file',
|
||||
'is_read' => false,
|
||||
'pegawai_id' => $mapping?->objectpejabatpenilaifk,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotification);
|
||||
'pegawai_id' => $pegawaiId,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$payloadLog = [
|
||||
@ -2771,7 +3073,7 @@ class DashboardController extends Controller
|
||||
'statusenabled' => true,
|
||||
'nama_dokumen' => $data->nama_dokumen ?? null,
|
||||
'no_dokumen' => $data->no_dokumen ?? null,
|
||||
'mod_change' => null,
|
||||
'mod_change' => 'Reset approval: ' . (!empty($targetRoleNotifications) ? implode(',', $targetRoleNotifications) : 'atasan'),
|
||||
'id_unit_kerja' => $data ? $data->id_unit_kerja : null,
|
||||
'id_sub_unit_kerja' => $data ? $data->id_sub_unit_kerja : null,
|
||||
'action_type' => 'Revisi Dokumen',
|
||||
@ -3230,4 +3532,340 @@ class DashboardController extends Controller
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function approvePendingFileMutu(string $id){
|
||||
try {
|
||||
DB::connection('dbDirectory')->beginTransaction();
|
||||
if (!$this->hasApprovalRole(51)) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Anda tidak memiliki akses approval Komite Mutu'
|
||||
], 403);
|
||||
}
|
||||
$data = FileDirectory::where('file_directory_id', $id)->first();
|
||||
if(!$data){
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Data tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
if ($data->status_action !== 'approved') {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Dokumen belum disetujui atasan.'
|
||||
], 422);
|
||||
}
|
||||
$data->update([
|
||||
'status_mutu' => 'approved',
|
||||
'action_mutu_at' => now(),
|
||||
'action_mutu_by' => auth()->user()->objectpegawaifk,
|
||||
]);
|
||||
$this->syncFinalApprovalStatus($data->fresh());
|
||||
|
||||
$parts = array_values(array_filter(explode('/', $data->file)));
|
||||
$actionName = auth()->user()?->dataUser?->namalengkap ?? 'Pengguna';
|
||||
$docNumber = $data->no_dokumen ? 'nomor '. $data->no_dokumen : end($parts);
|
||||
$payloadNotification = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} telah disetujui oleh {$actionName} Komite Mutu.",
|
||||
'url' => '/',
|
||||
'is_read' => false,
|
||||
'pegawai_id' => $data->pegawai_id_entry,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotification);
|
||||
|
||||
$payloadLog = [
|
||||
'file_directory_id' => $data->file_directory_id,
|
||||
'pegawai_id_entry' => $data->pegawai_id_entry,
|
||||
'pegawai_nama_entry' => $data->pegawai_nama_entry,
|
||||
'entry_at' => now(),
|
||||
'file' => $data->file,
|
||||
'statusenabled' => true,
|
||||
'nama_dokumen' => $data->nama_dokumen ?? null,
|
||||
'no_dokumen' => $data->no_dokumen ?? null,
|
||||
'mod_change' => null,
|
||||
'id_unit_kerja' => $data ? $data->id_unit_kerja : null,
|
||||
'id_sub_unit_kerja' => $data ? $data->id_sub_unit_kerja : null,
|
||||
'action_type' => 'Approved Dokumen Mutu',
|
||||
];
|
||||
LogActivity::create($payloadLog);
|
||||
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'File berhasil di-approve'
|
||||
], 200);
|
||||
} catch (\Throwable $th) {
|
||||
DB::connection('dbDirectory')->rollBack();
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => $th->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function approvePendingFileTurt(string $id){
|
||||
try {
|
||||
DB::connection('dbDirectory')->beginTransaction();
|
||||
if (!$this->hasApprovalRole(22)) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Anda tidak memiliki akses approval TURT'
|
||||
], 403);
|
||||
}
|
||||
$data = FileDirectory::where('file_directory_id', $id)->first();
|
||||
if(!$data){
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Data tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
if ($data->status_action !== 'approved') {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Dokumen belum disetujui atasan.'
|
||||
], 422);
|
||||
}
|
||||
$data->update([
|
||||
'status_turt' => 'approved',
|
||||
'action_turt_at' => now(),
|
||||
'action_turt_by' => auth()->user()->objectpegawaifk,
|
||||
]);
|
||||
$this->syncFinalApprovalStatus($data->fresh());
|
||||
|
||||
$parts = array_values(array_filter(explode('/', $data->file)));
|
||||
$actionName = auth()->user()?->dataUser?->namalengkap ?? 'Pengguna';
|
||||
$docNumber = $data->no_dokumen ? 'nomor '. $data->no_dokumen : end($parts);
|
||||
$payloadNotification = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} telah disetujui oleh {$actionName}, Tim Kerja Tata Usaha dan Rumah Tangga.",
|
||||
'url' => '/',
|
||||
'is_read' => false,
|
||||
'pegawai_id' => $data->pegawai_id_entry,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotification);
|
||||
|
||||
$payloadLog = [
|
||||
'file_directory_id' => $data->file_directory_id,
|
||||
'pegawai_id_entry' => $data->pegawai_id_entry,
|
||||
'pegawai_nama_entry' => $data->pegawai_nama_entry,
|
||||
'entry_at' => now(),
|
||||
'file' => $data->file,
|
||||
'statusenabled' => true,
|
||||
'nama_dokumen' => $data->nama_dokumen ?? null,
|
||||
'no_dokumen' => $data->no_dokumen ?? null,
|
||||
'mod_change' => null,
|
||||
'id_unit_kerja' => $data ? $data->id_unit_kerja : null,
|
||||
'id_sub_unit_kerja' => $data ? $data->id_sub_unit_kerja : null,
|
||||
'action_type' => 'Approved Dokumen Turt',
|
||||
];
|
||||
LogActivity::create($payloadLog);
|
||||
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'File berhasil di-approve'
|
||||
], 200);
|
||||
} catch (\Throwable $th) {
|
||||
DB::connection('dbDirectory')->rollBack();
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => $th->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function rejectPendingFileMutu(Request $request, string $id){
|
||||
try {
|
||||
DB::connection('dbDirectory')->beginTransaction();
|
||||
if (!$this->hasApprovalRole(51)) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Anda tidak memiliki akses approval Komite Mutu'
|
||||
], 403);
|
||||
}
|
||||
$data = FileDirectory::where('file_directory_id', $id)->first();
|
||||
if(!$data){
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Data tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
if ($data->status_action !== 'approved') {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Dokumen belum disetujui atasan.'
|
||||
], 422);
|
||||
}
|
||||
$revision = trim((string) $request->input('revision', ''));
|
||||
if ($revision === '') {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Catatan revisi wajib diisi'
|
||||
], 422);
|
||||
}
|
||||
$data->update([
|
||||
'status_mutu' => 'rejected',
|
||||
'action_mutu_at' => now(),
|
||||
'action_mutu_by' => auth()->user()->dataUser->id,
|
||||
'mutu_revision' => $revision,
|
||||
'revision' => 'Komite Mutu: ' . $revision,
|
||||
'status_action' => 'rejected',
|
||||
'action_at' => now(),
|
||||
'action_by' => auth()->user()->objectpegawaifk,
|
||||
]);
|
||||
|
||||
$parts = array_values(array_filter(explode('/', $data->file)));
|
||||
$actionName = auth()->user()?->dataUser?->namalengkap ?? 'Pengguna';
|
||||
$docNumber = $data->no_dokumen ? 'nomor '. $data->no_dokumen : end($parts);
|
||||
$payloadNotification = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} telah ditolak oleh {$actionName}, Komite Mutu. ". "Silakan periksa dokumen untuk melakukan perbaikan.",
|
||||
'url' => '/pengajuan-file',
|
||||
'is_read' => false,
|
||||
// 'pegawai_id' => $mapping?->objectatasanlangsungfk,
|
||||
'pegawai_id' => $data->pegawai_id_entry,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotification);
|
||||
$payloadLog = [
|
||||
'file_directory_id' => $data->file_directory_id,
|
||||
'pegawai_id_entry' => $data->pegawai_id_entry,
|
||||
'pegawai_nama_entry' => $data->pegawai_nama_entry,
|
||||
'entry_at' => now(),
|
||||
'file' => $data->file,
|
||||
'statusenabled' => true,
|
||||
'nama_dokumen' => $data->nama_dokumen ?? null,
|
||||
'no_dokumen' => $data->no_dokumen ?? null,
|
||||
'id_unit_kerja' => $data ? $data->id_unit_kerja : null,
|
||||
'id_sub_unit_kerja' => $data ? $data->id_sub_unit_kerja : null,
|
||||
'action_type' => 'Rejected Dokumen Mutu',
|
||||
];
|
||||
LogActivity::create($payloadLog);
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'File berhasil di-reject'
|
||||
], 200);
|
||||
} catch (\Throwable $th) {
|
||||
DB::connection('dbDirectory')->rollBack();
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => $th->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
public function rejectPendingFileTurt(Request $request, string $id){
|
||||
try {
|
||||
DB::connection('dbDirectory')->beginTransaction();
|
||||
if (!$this->hasApprovalRole(22)) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Anda tidak memiliki akses approval TURT'
|
||||
], 403);
|
||||
}
|
||||
$data = FileDirectory::where('file_directory_id', $id)->first();
|
||||
if(!$data){
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Data tidak ditemukan'
|
||||
], 404);
|
||||
}
|
||||
if ($data->status_action !== 'approved') {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Dokumen belum disetujui atasan.'
|
||||
], 422);
|
||||
}
|
||||
$revision = trim((string) $request->input('revision', ''));
|
||||
if ($revision === '') {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => 'Catatan revisi wajib diisi'
|
||||
], 422);
|
||||
}
|
||||
$data->update([
|
||||
'status_turt' => 'rejected',
|
||||
'action_turt_at' => now(),
|
||||
'action_turt_by' => auth()->user()->dataUser->id,
|
||||
'turt_revision' => $revision,
|
||||
'revision' => 'TURT: ' . $revision,
|
||||
'status_action' => 'rejected',
|
||||
'action_at' => now(),
|
||||
'action_by' => auth()->user()->objectpegawaifk,
|
||||
]);
|
||||
|
||||
$parts = array_values(array_filter(explode('/', $data->file)));
|
||||
$actionName = auth()->user()?->dataUser?->namalengkap ?? 'Pengguna';
|
||||
$docNumber = $data->no_dokumen ? 'nomor '. $data->no_dokumen : end($parts);
|
||||
$payloadNotification = [
|
||||
'created_at' => now(),
|
||||
'text_notifikasi' => "Dokumen {$docNumber} telah ditolak oleh {$actionName}, Tim Kerja Tata Usaha dan Rumah Tangga. ". "Silakan periksa dokumen untuk melakukan perbaikan.",
|
||||
'url' => '/pengajuan-file',
|
||||
'is_read' => false,
|
||||
// 'pegawai_id' => $mapping?->objectatasanlangsungfk,
|
||||
'pegawai_id' => $data->pegawai_id_entry,
|
||||
];
|
||||
|
||||
Notifkasi::create($payloadNotification);
|
||||
$payloadLog = [
|
||||
'file_directory_id' => $data->file_directory_id,
|
||||
'pegawai_id_entry' => $data->pegawai_id_entry,
|
||||
'pegawai_nama_entry' => $data->pegawai_nama_entry,
|
||||
'entry_at' => now(),
|
||||
'file' => $data->file,
|
||||
'statusenabled' => true,
|
||||
'nama_dokumen' => $data->nama_dokumen ?? null,
|
||||
'no_dokumen' => $data->no_dokumen ?? null,
|
||||
'mod_change' => $revision,
|
||||
'id_unit_kerja' => $data ? $data->id_unit_kerja : null,
|
||||
'id_sub_unit_kerja' => $data ? $data->id_sub_unit_kerja : null,
|
||||
'action_type' => 'Rejected Dokumen Turt',
|
||||
];
|
||||
LogActivity::create($payloadLog);
|
||||
DB::connection('dbDirectory')->commit();
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'message' => 'File berhasil di-reject'
|
||||
], 200);
|
||||
} catch (\Throwable $th) {
|
||||
DB::connection('dbDirectory')->rollBack();
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'message' => $th->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function syncFinalApprovalStatus(FileDirectory $data): void
|
||||
{
|
||||
$mustApproveMutu = (bool) $data->is_akre;
|
||||
$mustApproveTurt = !empty($data->master_kategori_directory_id);
|
||||
|
||||
if ($data->status_action !== 'approved') {
|
||||
return;
|
||||
}
|
||||
|
||||
$mutuApproved = !$mustApproveMutu || $data->status_mutu === 'approved';
|
||||
$turtApproved = !$mustApproveTurt || $data->status_turt === 'approved';
|
||||
|
||||
if ($mutuApproved && $turtApproved) {
|
||||
$data->update([
|
||||
'status_action' => 'approved',
|
||||
'action_at' => now(),
|
||||
'action_by' => auth()->user()->objectpegawaifk,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
private function hasApprovalRole(int $unitId): bool
|
||||
{
|
||||
return MappingUnitKerjaPegawai::query()
|
||||
->where('statusenabled', true)
|
||||
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
|
||||
->where('objectunitkerjapegawaifk', $unitId)
|
||||
->exists();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ class User extends Authenticatable
|
||||
'katasandi' => 'hashed',
|
||||
];
|
||||
}
|
||||
protected $with = ['dataUser', 'masterPersetujuan', 'akses'];
|
||||
protected $with = ['dataUser'];
|
||||
public function dataUser(){
|
||||
return $this->belongsTo(DataUser::class, 'objectpegawaifk', 'id')->select('id', 'namalengkap');
|
||||
}
|
||||
|
||||
8
public/assets/css/styles.min.css
vendored
8
public/assets/css/styles.min.css
vendored
@ -15904,14 +15904,14 @@ body {
|
||||
border-radius: 20px;
|
||||
}
|
||||
.body-wrapper .body-wrapper-inner {
|
||||
min-height: calc(100vh - 110px);
|
||||
min-height: calc(130vh - 180px);
|
||||
}
|
||||
.body-wrapper .container-fluid, .body-wrapper .container-sm, .body-wrapper .container-md, .body-wrapper .container-lg, .body-wrapper .container-xl, .body-wrapper .container-xxl {
|
||||
max-width: 1300px;
|
||||
max-width: 1600px;
|
||||
margin: 0 auto;
|
||||
padding: 24px;
|
||||
padding: 10px;
|
||||
transition: 0.2s ease-in;
|
||||
padding-top: 120px;
|
||||
padding-top: 90px;
|
||||
}
|
||||
@media (max-width: 991.98px) {
|
||||
.body-wrapper .container-fluid, .body-wrapper .container-sm, .body-wrapper .container-md, .body-wrapper .container-lg, .body-wrapper .container-xl, .body-wrapper .container-xxl {
|
||||
|
||||
@ -19,6 +19,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const titleEl = document.getElementById('pendingTitle');
|
||||
const tabPendingEl = document.getElementById('tabPengajuan');
|
||||
const tabHistoryEl = document.getElementById('tabHistory');
|
||||
const isKomiteMutu = !!window.isKomiteMutu;
|
||||
const isTurt = !!window.isTurt;
|
||||
|
||||
const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
|
||||
const selectedIds = new Set();
|
||||
@ -63,10 +65,35 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
function statusBadge(status){
|
||||
if (status === 'rejected') return '<span class="badge bg-danger">Rejected</span>';
|
||||
if (status === 'revised') return '<span class="badge bg-info">Revised</span>';
|
||||
return '<span class="badge bg-warning text-dark">Pending</span>';
|
||||
function approvalBadge(status, label){
|
||||
if (status === 'approved') return `<span class="badge bg-success">Approved ${label}</span>`;
|
||||
if (status === 'rejected') return `<span class="badge bg-danger">Rejected ${label}</span>`;
|
||||
return `<span class="badge bg-warning text-dark">Pending ${label}</span>`;
|
||||
}
|
||||
|
||||
function getWorkflowStatusBadges(item){
|
||||
if (item?.status_mutu === 'rejected') return [`<span class="badge bg-danger">Rejected Mutu</span>`];
|
||||
if (item?.status_turt === 'rejected') return [`<span class="badge bg-danger">Rejected TURT</span>`];
|
||||
if (item?.status_action === 'rejected') return [`<span class="badge bg-danger">Rejected Atasan</span>`];
|
||||
if (item?.status_action === 'revised') return [`<span class="badge bg-info">Revised</span>`];
|
||||
|
||||
if (item?.status_action !== 'approved') {
|
||||
return [`<span class="badge bg-warning text-dark">Pending Atasan</span>`];
|
||||
}
|
||||
|
||||
const statuses = [];
|
||||
if (item?.is_akre && item?.status_mutu !== 'approved') {
|
||||
statuses.push(`<span class="badge bg-warning text-dark">Pending Mutu</span>`);
|
||||
}
|
||||
if (item?.master_kategori_directory_id && item?.status_turt !== 'approved') {
|
||||
statuses.push(`<span class="badge bg-warning text-dark">Pending TURT</span>`);
|
||||
}
|
||||
|
||||
if (statuses.length) {
|
||||
return statuses;
|
||||
}
|
||||
|
||||
return [`<span class="badge bg-success">Approved</span>`];
|
||||
}
|
||||
|
||||
function aksesBadge(akses){
|
||||
@ -81,18 +108,22 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
}
|
||||
|
||||
function isRejected(item){
|
||||
return item?.status_action === 'rejected';
|
||||
return item?.status_action === 'rejected' || item?.status_mutu === 'rejected' || item?.status_turt === 'rejected';
|
||||
}
|
||||
|
||||
function isAtasanApproved(item){
|
||||
return item?.status_action === 'approved';
|
||||
}
|
||||
|
||||
function getSelectableIdsOnPage(){
|
||||
return (tableState.data || [])
|
||||
.filter((item) => !isRejected(item))
|
||||
.filter((item) => !isRejected(item) && !isAtasanApproved(item))
|
||||
.map((item) => String(item.file_directory_id));
|
||||
}
|
||||
|
||||
function updateSelectAllState(){
|
||||
if (!selectAllCheckbox) return;
|
||||
if (tableState.mode === 'history') {
|
||||
if (tableState.mode === 'history' || isKomiteMutu || isTurt) {
|
||||
selectAllCheckbox.checked = false;
|
||||
selectAllCheckbox.indeterminate = false;
|
||||
selectAllCheckbox.disabled = true;
|
||||
@ -115,8 +146,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
function updateSelectionUI(){
|
||||
const count = selectedIds.size;
|
||||
if (selectedCountEl) selectedCountEl.textContent = String(count);
|
||||
if (bulkApproveBtn) bulkApproveBtn.disabled = count === 0 || tableState.mode === 'history';
|
||||
if (clearSelectionBtn) clearSelectionBtn.disabled = count === 0 || tableState.mode === 'history';
|
||||
if (bulkApproveBtn) bulkApproveBtn.disabled = count === 0 || tableState.mode === 'history' || isKomiteMutu || isTurt;
|
||||
if (clearSelectionBtn) clearSelectionBtn.disabled = count === 0 || tableState.mode === 'history' || isKomiteMutu || isTurt;
|
||||
updateSelectAllState();
|
||||
}
|
||||
|
||||
@ -126,10 +157,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const tanggalTerbit = item.tanggal_terbit ? formatTanggal(item.tanggal_terbit) : '-';
|
||||
const id = String(item.file_directory_id);
|
||||
const rejected = isRejected(item);
|
||||
const atasanApproved = isAtasanApproved(item);
|
||||
const checked = selectedIds.has(id);
|
||||
const aksi = `
|
||||
<div class="d-flex gap-1">
|
||||
<button class="btn btn-sm btn-primary" onclick="infoDok(this)"
|
||||
const actions = [
|
||||
`<button class="btn btn-sm btn-primary" onclick="infoDok(this)"
|
||||
data-file="${item.file}"
|
||||
data-fileName="${item.nama_dokumen}"
|
||||
data-id="${item.file_directory_id}"
|
||||
@ -137,15 +168,34 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
data-tanggal_terbit="${item.tanggal_terbit || '-'}"
|
||||
data-permission_file="${item.permission_file || '-'}">
|
||||
<i class="fa-solid fa-eye"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-success" onclick="approvePending('${item.file_directory_id}', '${item.nama_dokumen || ''}')">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
<button class="btn btn-sm btn-danger" onclick="rejectPending('${item.file_directory_id}', '${item.nama_dokumen || ''}')">
|
||||
<i class="fa-solid fa-xmark"></i>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
</button>`
|
||||
];
|
||||
|
||||
if (isKomiteMutu || isTurt) {
|
||||
if (isKomiteMutu && item.is_akre && item.status_mutu !== 'approved') {
|
||||
actions.push(`<button class="btn btn-sm btn-success" onclick="approvePendingRole('mutu','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-check"></i></button>`);
|
||||
actions.push(`<button class="btn btn-sm btn-danger" onclick="rejectPendingRole('mutu','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-xmark"></i></button>`);
|
||||
}
|
||||
if (isTurt && item.status_turt !== 'approved') {
|
||||
actions.push(`<button class="btn btn-sm btn-success" onclick="approvePendingRole('turt','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-check-double"></i></button>`);
|
||||
actions.push(`<button class="btn btn-sm btn-danger" onclick="rejectPendingRole('turt','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-ban"></i></button>`);
|
||||
}
|
||||
if (item.status_mutu === 'rejected' && item.mutu_revision) {
|
||||
actions.push(`<button class="btn btn-sm btn-info" onclick="infoRejectRole('Komite Mutu', ${JSON.stringify('' + (item.mutu_revision || ''))})"><i class="fa-solid fa-circle-info"></i></button>`);
|
||||
}
|
||||
if (item.status_turt === 'rejected' && item.turt_revision) {
|
||||
actions.push(`<button class="btn btn-sm btn-info" onclick="infoRejectRole('TURT', ${JSON.stringify('' + (item.turt_revision || ''))})"><i class="fa-solid fa-circle-info"></i></button>`);
|
||||
}
|
||||
} else {
|
||||
if (!atasanApproved) {
|
||||
actions.push(`<button class="btn btn-sm btn-success" onclick="approvePending('${item.file_directory_id}', '${item.nama_dokumen || ''}')"><i class="fa-solid fa-check"></i></button>`);
|
||||
actions.push(`<button class="btn btn-sm btn-danger" onclick="rejectPending('${item.file_directory_id}', '${item.nama_dokumen || ''}')"><i class="fa-solid fa-xmark"></i></button>`);
|
||||
}
|
||||
}
|
||||
|
||||
const statusContent = (isKomiteMutu || isTurt)
|
||||
? getWorkflowStatusBadges(item).join(' ')
|
||||
: getWorkflowStatusBadges(item).join(' ');
|
||||
return `
|
||||
<tr class="${checked ? 'table-active' : ''}">
|
||||
<td class="text-center">
|
||||
@ -153,11 +203,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
class="form-check-input row-select"
|
||||
data-id="${id}"
|
||||
${checked ? 'checked' : ''}
|
||||
${rejected ? 'disabled' : ''}>
|
||||
${(rejected || atasanApproved || isKomiteMutu || isTurt) ? 'disabled' : ''}>
|
||||
</td>
|
||||
<td class="text-center">${rejected ? '' : aksi}</td>
|
||||
<td class="text-center text-nowrap">${rejected ? '' : `<div class="d-flex justify-content-center align-items-center gap-1 flex-nowrap">${actions.join('')}</div>`}</td>
|
||||
<td>${safeText(item.no_dokumen)}</td>
|
||||
<td>${statusBadge(item?.status_action)}</td>
|
||||
<td>${statusContent}</td>
|
||||
<td>${aksesBadge(item?.permission_file)}</td>
|
||||
<td><a href="#" class="file-link"
|
||||
data-file="${item.file}"
|
||||
@ -323,7 +373,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
tabHistoryEl.classList.toggle('d-none', tableState.mode !== 'history');
|
||||
}
|
||||
if (pendingBulkActionsEl) {
|
||||
pendingBulkActionsEl.classList.toggle('d-none', tableState.mode === 'history');
|
||||
pendingBulkActionsEl.classList.toggle('d-none', tableState.mode === 'history' || isKomiteMutu || isTurt);
|
||||
}
|
||||
updateSelectionUI();
|
||||
}
|
||||
@ -473,6 +523,117 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
|
||||
window.infoRejectRole = function(label, revision){
|
||||
Swal.fire({
|
||||
title: `Catatan ${label}`,
|
||||
text: revision || 'Tidak ada catatan revisi.',
|
||||
icon: 'info',
|
||||
confirmButtonText: 'Tutup'
|
||||
});
|
||||
}
|
||||
|
||||
window.approvePendingRole = function(type, id, fileName){
|
||||
const endpoint = type === 'mutu'
|
||||
? `/pending-file/${id}/approve-mutu`
|
||||
: `/pending-file/${id}/approve-turt`;
|
||||
const label = type === 'mutu' ? 'Komite Mutu' : 'TURT';
|
||||
|
||||
Swal.fire({
|
||||
title: `Approve ${label}?`,
|
||||
text: fileName || 'Dokumen akan disetujui.',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Approve',
|
||||
cancelButtonText: 'Batal',
|
||||
}).then((result) => {
|
||||
if (!result.isConfirmed) return;
|
||||
fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': csrfToken,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
}).then(async(res) => {
|
||||
const data = await res.json();
|
||||
if (!res.ok || !data?.status) {
|
||||
throw new Error(data?.message || 'Gagal approve.');
|
||||
}
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: data.message || 'Dokumen disetujui.',
|
||||
timer: 1500,
|
||||
showConfirmButton: false
|
||||
});
|
||||
fetchData();
|
||||
}).catch((err) => {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: err.message || 'Terjadi kesalahan.'
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.rejectPendingRole = function(type, id, fileName){
|
||||
const endpoint = type === 'mutu'
|
||||
? `/pending-file/${id}/reject-mutu`
|
||||
: `/pending-file/${id}/reject-turt`;
|
||||
const label = type === 'mutu' ? 'Komite Mutu' : 'TURT';
|
||||
|
||||
Swal.fire({
|
||||
title: `Reject ${label}?`,
|
||||
text: fileName || 'Dokumen akan ditolak.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Reject',
|
||||
cancelButtonText: 'Batal',
|
||||
input: 'textarea',
|
||||
inputLabel: 'Catatan',
|
||||
inputPlaceholder: 'Tulis alasan atau catatan revisi...',
|
||||
inputAttributes: {
|
||||
'aria-label': 'Catatan'
|
||||
},
|
||||
preConfirm: (value) => {
|
||||
const revision = (value || '').trim();
|
||||
if (!revision) {
|
||||
Swal.showValidationMessage('Catatan revisi wajib diisi.');
|
||||
}
|
||||
return revision;
|
||||
}
|
||||
}).then((result) => {
|
||||
if (!result.isConfirmed) return;
|
||||
fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': csrfToken,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ revision: result.value })
|
||||
}).then(async(res) => {
|
||||
const data = await res.json();
|
||||
if (!res.ok || !data?.status) {
|
||||
throw new Error(data?.message || 'Gagal reject.');
|
||||
}
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: data.message || 'Dokumen ditolak.',
|
||||
timer: 1500,
|
||||
showConfirmButton: false
|
||||
});
|
||||
fetchData();
|
||||
}).catch((err) => {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: err.message || 'Terjadi kesalahan.'
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.infoDok = function(e){
|
||||
let fileUrl =$(e).data('file');
|
||||
let noDokumen = $(e).data('no_dokumen');
|
||||
|
||||
@ -27,6 +27,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const editUnitSelect = $('#edit_id_unit_kerja');
|
||||
const editSubUnitSelect = $('#edit_id_sub_unit_kerja');
|
||||
const selectedIds = new Set();
|
||||
const isKomiteMutu = !!window.isKomiteMutu;
|
||||
const isTurt = !!window.isTurt;
|
||||
|
||||
if (pageSizeSelect) {
|
||||
const initialSize = parseInt(pageSizeSelect.value);
|
||||
@ -74,7 +76,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
function updateSelectAllState(){
|
||||
if (!selectAllCheckbox) return;
|
||||
if (tableState.mode === 'history') {
|
||||
if (tableState.mode === 'history' || tableState.mode === 'persetujuan') {
|
||||
selectAllCheckbox.checked = false;
|
||||
selectAllCheckbox.indeterminate = false;
|
||||
selectAllCheckbox.disabled = true;
|
||||
@ -98,18 +100,60 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
function updateSelectionUI(){
|
||||
const count = selectedIds.size;
|
||||
if (selectedCountEl) selectedCountEl.textContent = String(count);
|
||||
if (bulkDeleteBtn) bulkDeleteBtn.disabled = count === 0 || tableState.mode === 'history';
|
||||
if (clearSelectionBtn) clearSelectionBtn.disabled = count === 0 || tableState.mode === 'history';
|
||||
if (bulkDeleteBtn) bulkDeleteBtn.disabled = count === 0 || tableState.mode === 'history' || tableState.mode === 'persetujuan';
|
||||
if (clearSelectionBtn) clearSelectionBtn.disabled = count === 0 || tableState.mode === 'history' || tableState.mode === 'persetujuan';
|
||||
updateSelectAllState();
|
||||
}
|
||||
|
||||
function approvalBadge(status, label){
|
||||
if (status === 'approved') return `<span class="badge bg-success">Approved ${label}</span>`;
|
||||
if (status === 'rejected') return `<span class="badge bg-danger">Rejected ${label}</span>`;
|
||||
return `<span class="badge bg-warning text-dark">Pending ${label}</span>`;
|
||||
}
|
||||
|
||||
function getPengajuanStatusBadge(item){
|
||||
if (item?.status_mutu === 'rejected') {
|
||||
return `<span class="badge bg-danger">Rejected Mutu</span>`;
|
||||
}
|
||||
if (item?.status_turt === 'rejected') {
|
||||
return `<span class="badge bg-danger">Rejected TURT</span>`;
|
||||
}
|
||||
if (item?.status_action === 'rejected') {
|
||||
return `<span class="badge bg-danger">Rejected Atasan</span>`;
|
||||
}
|
||||
if (item?.status_action === 'revised') {
|
||||
return `<span class="badge bg-info">Revised</span>`;
|
||||
}
|
||||
|
||||
if (item?.status_action !== 'approved') {
|
||||
return `<span class="badge bg-warning text-dark">Pending Atasan</span>`;
|
||||
}
|
||||
|
||||
const pendingApprovals = [];
|
||||
if (item?.is_akre && item?.status_mutu !== 'approved') {
|
||||
pendingApprovals.push('Pending Mutu');
|
||||
}
|
||||
if (item?.master_kategori_directory_id && item?.status_turt !== 'approved') {
|
||||
pendingApprovals.push('Pending TURT');
|
||||
}
|
||||
|
||||
if (pendingApprovals.length) {
|
||||
return pendingApprovals.map((label) => `<span class="badge bg-warning text-dark">${label}</span>`).join(' ');
|
||||
}
|
||||
if (item?.status_action === 'approved') {
|
||||
return `<span class="badge bg-success">Approved</span>`;
|
||||
}
|
||||
|
||||
return `<span class="badge bg-warning text-dark">Pending Atasan</span>`;
|
||||
}
|
||||
|
||||
function buildRow(item){
|
||||
let tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-';
|
||||
let tanggalExp = item.tgl_expired ? formatTanggal(item.tgl_expired) : '-';
|
||||
let tanggalTerbit = item.tanggal_terbit ? formatTanggal(item.tanggal_terbit) : '-';
|
||||
const isApproved = item?.status_action === 'approved';
|
||||
const isRejected = item?.status_action === 'rejected';
|
||||
const showEdit = !isApproved;
|
||||
const isRejected = item?.status_action === 'rejected' || item?.status_mutu === 'rejected' || item?.status_turt === 'rejected';
|
||||
const showEdit = !isApproved || isRejected;
|
||||
const showInfo = isRejected;
|
||||
const id = String(item.file_directory_id);
|
||||
const checked = selectedIds.has(id);
|
||||
@ -146,18 +190,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
</td>
|
||||
<td>${aksi}</td>
|
||||
<td>${item.no_dokumen || '-'}</td>
|
||||
<td>
|
||||
<button class="btn btn-sm
|
||||
${item?.status_action === "approved" ? 'btn-success' :
|
||||
item?.status_action === "rejected" ? 'btn-danger' :
|
||||
item?.status_action === "revised" ? 'btn-info' :
|
||||
'btn-warning'}">
|
||||
${item?.status_action === "approved" ? 'Approved' :
|
||||
item?.status_action === "rejected" ? 'Rejected' :
|
||||
item?.status_action === "revised" ? 'Revised' :
|
||||
'Pending'}
|
||||
</button>
|
||||
</td>
|
||||
<td>${getPengajuanStatusBadge(item)}</td>
|
||||
<td>${aksesBadge(item?.permission_file)}</td>
|
||||
<td><a href="#" class="file-link"
|
||||
data-file="${item.file}"
|
||||
@ -180,6 +213,67 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
`;
|
||||
}
|
||||
|
||||
function buildRowPersetujuan(item){
|
||||
const tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-';
|
||||
const tanggalExp = item.tgl_expired ? formatTanggal(item.tgl_expired) : '-';
|
||||
const tanggalTerbit = item.tanggal_terbit ? formatTanggal(item.tanggal_terbit) : '-';
|
||||
const showMutu = isKomiteMutu && !!item.is_akre;
|
||||
const showTurt = isTurt;
|
||||
const actions = [
|
||||
`<button type="button" class="btn btn-sm btn-primary" onclick="infoDok(this)"
|
||||
data-file="${item.file}"
|
||||
data-fileName="${item.nama_dokumen}"
|
||||
data-id="${item.file_directory_id}"
|
||||
data-no_dokumen="${item.no_dokumen || '-'}"
|
||||
data-tanggal_terbit="${item.tanggal_terbit || '-'}"
|
||||
data-permission_file="${item.permission_file || '-'}"><i class="fa-solid fa-eye"></i></button>`
|
||||
];
|
||||
|
||||
if (showMutu && item.status_mutu !== 'approved') {
|
||||
actions.push(`<button class="btn btn-sm btn-success" onclick="approvePersetujuan('mutu','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-check"></i></button>`);
|
||||
actions.push(`<button class="btn btn-sm btn-danger" onclick="rejectPersetujuan('mutu','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-xmark"></i></button>`);
|
||||
}
|
||||
if (showTurt && item.status_turt !== 'approved') {
|
||||
actions.push(`<button class="btn btn-sm btn-success" onclick="approvePersetujuan('turt','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-check-double"></i></button>`);
|
||||
actions.push(`<button class="btn btn-sm btn-danger" onclick="rejectPersetujuan('turt','${item.file_directory_id}','${item.nama_dokumen || ''}')"><i class="fa-solid fa-ban"></i></button>`);
|
||||
}
|
||||
if (item.status_mutu === 'rejected' && item.mutu_revision) {
|
||||
actions.push(`<button class="btn btn-sm btn-info" onclick="infoRejectPersetujuan('Komite Mutu', ${JSON.stringify('' + (item.mutu_revision || ''))})"><i class="fa-solid fa-circle-info"></i></button>`);
|
||||
}
|
||||
if (item.status_turt === 'rejected' && item.turt_revision) {
|
||||
actions.push(`<button class="btn btn-sm btn-info" onclick="infoRejectPersetujuan('TURT', ${JSON.stringify('' + (item.turt_revision || ''))})"><i class="fa-solid fa-circle-info"></i></button>`);
|
||||
}
|
||||
|
||||
const statusParts = [];
|
||||
if (item.is_akre) {
|
||||
statusParts.push(approvalBadge(item.status_mutu, 'Mutu'));
|
||||
}
|
||||
if (item.master_kategori_directory_id) {
|
||||
statusParts.push(approvalBadge(item.status_turt, 'TURT'));
|
||||
}
|
||||
|
||||
return `
|
||||
<tr>
|
||||
<td class="text-center">-</td>
|
||||
<td><div class="d-flex gap-1 flex-wrap">${actions.join('')}</div></td>
|
||||
<td>${item.no_dokumen || '-'}</td>
|
||||
<td><div class="d-flex gap-1 flex-wrap">${statusParts.join('')}</div></td>
|
||||
<td>${aksesBadge(item?.permission_file)}</td>
|
||||
<td><a href="#" class="file-link"
|
||||
data-file="${item.file}"
|
||||
data-fileName="${item.nama_dokumen}"
|
||||
data-id="${item.file_directory_id}"
|
||||
data-no_dokumen="${item.no_dokumen || '-'}"
|
||||
data-tanggal_terbit="${item.tanggal_terbit || '-'}"
|
||||
data-permission_file="${item.permission_file || '-'}">${item.nama_dokumen}</a></td>
|
||||
${item.is_akre ? `<td colspan="2" class="text-center">Dokumen akreditasi</td>` : `<td>${item.name_kategori || '-'}</td><td>${item.name_unit || '-'}</td>`}
|
||||
<td class="text-nowrap">${tanggalTerbit}</td>
|
||||
<td class="text-nowrap">${tanggalExp}</td>
|
||||
<td class="text-nowrap">${tanggal}</td>
|
||||
</tr>
|
||||
`;
|
||||
}
|
||||
|
||||
function buildHistoryRow(item){
|
||||
const tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-';
|
||||
const tanggalExp = item.tgl_expired ? formatTanggal(item.tgl_expired) : '-';
|
||||
@ -300,11 +394,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
function renderTable(){
|
||||
const isHistoryMode = tableState.mode === 'history';
|
||||
const isPersetujuan = tableState.mode === 'persetujuan';
|
||||
|
||||
const activeState = isHistoryMode ? historyState : tableState;
|
||||
|
||||
const pageData = activeState.data || [];
|
||||
const targetBody = isHistoryMode ? tbodyHistory : tbodyPengajuan;
|
||||
const colSpan = isHistoryMode ? 9 : 11;
|
||||
const rowBuilder = isHistoryMode ? buildHistoryRow : buildRow;
|
||||
const rowBuilder = isHistoryMode ? buildHistoryRow : (isPersetujuan ? buildRowPersetujuan : buildRow);
|
||||
if (pageData.length === 0) {
|
||||
targetBody.innerHTML = `
|
||||
<tr>
|
||||
@ -363,17 +460,20 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
}
|
||||
if (titleEl) {
|
||||
titleEl.textContent = tableState.mode === 'history' ? 'Log History' : 'Data Pengajuan';
|
||||
titleEl.textContent = tableState.mode === 'history'
|
||||
? 'Log History'
|
||||
: (tableState.mode === 'persetujuan' ? 'Data Persetujuan' : 'Data Pengajuan');
|
||||
}
|
||||
document.body.dataset.pengajuanMode = tableState.mode;
|
||||
|
||||
if (tabPengajuanEl && tabHistoryEl) {
|
||||
tabPengajuanEl.classList.toggle('d-none', tableState.mode === 'history');
|
||||
tabHistoryEl.classList.toggle('d-none', tableState.mode !== 'history');
|
||||
}
|
||||
if (bulkActionsEl) {
|
||||
bulkActionsEl.classList.toggle('d-none', tableState.mode === 'history');
|
||||
bulkActionsEl.classList.toggle('d-none', tableState.mode === 'history' || tableState.mode === 'persetujuan');
|
||||
}
|
||||
if (deleteDataEl && tableState.mode === 'history') {
|
||||
if (deleteDataEl && (tableState.mode === 'history' || tableState.mode === 'persetujuan')) {
|
||||
deleteDataEl.classList.add('d-none');
|
||||
}
|
||||
updateSelectionUI();
|
||||
@ -457,7 +557,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
per_page: activeState.pageSize,
|
||||
keyword: activeState.search || '',
|
||||
start_date: activeState.startDate || '',
|
||||
end_date: activeState.endDate || ''
|
||||
end_date: activeState.endDate || '',
|
||||
mode: tableState.mode
|
||||
});
|
||||
const endpoint = tableState.mode === 'history'
|
||||
? `/data/log-dokumen?${params.toString()}`
|
||||
@ -478,7 +579,17 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
|
||||
window.infoReject = function(id){
|
||||
const item = getItemById(id);
|
||||
const revision = item?.revision ? String(item.revision) : 'Tidak ada catatan revisi.';
|
||||
const notes = [];
|
||||
if (item?.revision) {
|
||||
notes.push(`Atasan/Bagian Terkait: ${String(item.revision)}`);
|
||||
}
|
||||
if (item?.mutu_revision) {
|
||||
notes.push(`Komite Mutu: ${String(item.mutu_revision)}`);
|
||||
}
|
||||
if (item?.turt_revision) {
|
||||
notes.push(`TURT: ${String(item.turt_revision)}`);
|
||||
}
|
||||
const revision = notes.length ? notes.join('\n\n') : 'Tidak ada catatan revisi.';
|
||||
Swal.fire({
|
||||
title: 'Catatan Revisi',
|
||||
text: revision,
|
||||
@ -486,6 +597,119 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
confirmButtonText: 'Tutup'
|
||||
});
|
||||
}
|
||||
|
||||
window.infoRejectPersetujuan = function(label, revision){
|
||||
Swal.fire({
|
||||
title: `Catatan ${label}`,
|
||||
text: revision || 'Tidak ada catatan revisi.',
|
||||
icon: 'info',
|
||||
confirmButtonText: 'Tutup'
|
||||
});
|
||||
}
|
||||
|
||||
window.approvePersetujuan = function(type, id, fileName){
|
||||
const endpoint = type === 'mutu'
|
||||
? `/pengajuan-file/${id}/approve-mutu`
|
||||
: `/pengajuan-file/${id}/approve-turt`;
|
||||
const label = type === 'mutu' ? 'Komite Mutu' : 'TURT';
|
||||
|
||||
Swal.fire({
|
||||
title: `Approve ${label}?`,
|
||||
text: fileName || 'Dokumen akan disetujui.',
|
||||
icon: 'question',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Approve',
|
||||
cancelButtonText: 'Batal',
|
||||
}).then((result) => {
|
||||
if (!result.isConfirmed) return;
|
||||
fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': csrfToken,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
}).then(async(res) => {
|
||||
const data = await res.json();
|
||||
if (!res.ok || !data?.status) {
|
||||
throw new Error(data?.message || 'Gagal approve.');
|
||||
}
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: data.message || 'Dokumen disetujui.',
|
||||
timer: 1500,
|
||||
showConfirmButton: false
|
||||
});
|
||||
fetchData();
|
||||
}).catch((err) => {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: err.message || 'Terjadi kesalahan.'
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
window.rejectPersetujuan = function(type, id, fileName){
|
||||
const endpoint = type === 'mutu'
|
||||
? `/pengajuan-file/${id}/reject-mutu`
|
||||
: `/pengajuan-file/${id}/reject-turt`;
|
||||
const label = type === 'mutu' ? 'Komite Mutu' : 'TURT';
|
||||
|
||||
Swal.fire({
|
||||
title: `Reject ${label}?`,
|
||||
text: fileName || 'Dokumen akan ditolak.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Reject',
|
||||
cancelButtonText: 'Batal',
|
||||
input: 'textarea',
|
||||
inputLabel: 'Catatan',
|
||||
inputPlaceholder: 'Tulis alasan atau catatan revisi...',
|
||||
inputAttributes: {
|
||||
'aria-label': 'Catatan'
|
||||
},
|
||||
preConfirm: (value) => {
|
||||
const revision = (value || '').trim();
|
||||
if (!revision) {
|
||||
Swal.showValidationMessage('Catatan revisi wajib diisi.');
|
||||
}
|
||||
return revision;
|
||||
}
|
||||
}).then((result) => {
|
||||
if (!result.isConfirmed) return;
|
||||
fetch(endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': csrfToken,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
revision: result.value
|
||||
})
|
||||
}).then(async(res) => {
|
||||
const data = await res.json();
|
||||
if (!res.ok || !data?.status) {
|
||||
throw new Error(data?.message || 'Gagal reject.');
|
||||
}
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: data.message || 'Dokumen ditolak.',
|
||||
timer: 1500,
|
||||
showConfirmButton: false
|
||||
});
|
||||
fetchData();
|
||||
}).catch((err) => {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal',
|
||||
text: err.message || 'Terjadi kesalahan.'
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
window.infoDok = function(e){
|
||||
let fileUrl = $(e).data('file');
|
||||
let noDokumen = $(e).data('no_dokumen')
|
||||
|
||||
@ -200,8 +200,8 @@
|
||||
<span class="small text-muted">Tampilkan</span>
|
||||
<select id="tablePageSize" class="form-select form-select-sm" style="width: 80px;">
|
||||
<option value="5">5</option>
|
||||
<option value="10" selected>10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="10" >10</option>
|
||||
<option value="20" selected>20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
@ -198,8 +198,8 @@
|
||||
<span class="small text-muted">Tampilkan</span>
|
||||
<select id="tablePageSize" class="form-select form-select-sm" style="width: 80px;">
|
||||
<option value="5">5</option>
|
||||
<option value="10" selected>10</option>
|
||||
<option value="20">20</option>
|
||||
<option value="10">10</option>
|
||||
<option value="20" selected>20</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
|
||||
@ -114,5 +114,9 @@
|
||||
</div>
|
||||
</div>
|
||||
@include('pendingFile.modal.view')
|
||||
<script>
|
||||
window.isKomiteMutu = @json($isKomiteMutu);
|
||||
window.isTurt = @json($isTurt);
|
||||
</script>
|
||||
<script src="{{ ver('/js/pendingFile/index.js') }}"></script>
|
||||
@endsection
|
||||
|
||||
@ -46,6 +46,11 @@
|
||||
<li class="nav-item">
|
||||
<button class="nav-link active" type="button" data-mode="pengajuan">Data Pengajuan</button>
|
||||
</li>
|
||||
@if($isKomiteMutu || $isTurt)
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" type="button" data-mode="persetujuan">Data Persetujuan</button>
|
||||
</li>
|
||||
@endif
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" type="button" data-mode="history">Log History</button>
|
||||
</li>
|
||||
@ -151,6 +156,8 @@
|
||||
@include('dataUnit.modal.create')
|
||||
<script>
|
||||
window.katDok = @json($katDok);
|
||||
window.isKomiteMutu = @json($isKomiteMutu);
|
||||
window.isTurt = @json($isTurt);
|
||||
</script>
|
||||
<script src="{{ ver('/js/pengajuanFile/index.js') }}"></script>
|
||||
@endsection
|
||||
|
||||
@ -71,6 +71,10 @@ Route::middleware(['auth:admin,web'])->group(function(){
|
||||
Route::get('/pengajuan-file', [DashboardController::class, 'pengajuanFile']);
|
||||
Route::get('/datatable/pengajuan-file', [DashboardController::class, 'dataPengajuanFile']);
|
||||
Route::post('/pengajuan-file/{id}/update', [DashboardController::class, 'updatePengajuanFile']);
|
||||
Route::post('/pengajuan-file/{id}/approve-mutu', [DashboardController::class, 'approvePendingFileMutu']);
|
||||
Route::post('/pengajuan-file/{id}/approve-turt', [DashboardController::class, 'approvePendingFileTurt']);
|
||||
Route::post('/pengajuan-file/{id}/reject-mutu', [DashboardController::class, 'rejectPendingFileMutu']);
|
||||
Route::post('/pengajuan-file/{id}/reject-turt', [DashboardController::class, 'rejectPendingFileTurt']);
|
||||
|
||||
// Route::middleware(['master.persetujuan'])->group(function () {
|
||||
Route::get('/pending-file', [DashboardController::class, 'pendingFile']);
|
||||
@ -78,6 +82,10 @@ Route::middleware(['auth:admin,web'])->group(function(){
|
||||
Route::post('/pending-file/{id}/approve', [DashboardController::class, 'approvePendingFile']);
|
||||
Route::post('/pending-file/approve-multiple', [DashboardController::class, 'approvePendingFileMultiple']);
|
||||
Route::post('/pending-file/{id}/reject', [DashboardController::class, 'rejectPendingFile']);
|
||||
Route::post('/pending-file/{id}/approve-mutu', [DashboardController::class, 'approvePendingFileMutu']);
|
||||
Route::post('/pending-file/{id}/approve-turt', [DashboardController::class, 'approvePendingFileTurt']);
|
||||
Route::post('/pending-file/{id}/reject-mutu', [DashboardController::class, 'rejectPendingFileMutu']);
|
||||
Route::post('/pending-file/{id}/reject-turt', [DashboardController::class, 'rejectPendingFileTurt']);
|
||||
Route::get('/data/count-pending', [DashboardController::class, 'countDataPending']);
|
||||
Route::get('/data/count-rejected', [DashboardController::class, 'countRejectedPengajuan']);
|
||||
// });
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user