done pengembangan -> review

This commit is contained in:
JokoPrasetio 2026-06-19 15:53:48 +07:00
parent 798455de16
commit 353efd16b0
5 changed files with 455 additions and 139 deletions

View File

@ -1349,7 +1349,7 @@ class DashboardController extends Controller
$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']){
if(isset($data['master_kategori_directory_id'])){
list($master_kategori_directory_id, $nama_kategori) = explode('/', $data['master_kategori_directory_id'],2);
}
if(isset($data['akre'])){
@ -1372,10 +1372,7 @@ class DashboardController extends Controller
$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;
$status = $isAtasan ? 'approved' : null;
$payload = [
'id_unit_kerja' => $id_unit_kerja,
'id_sub_unit_kerja' => $id_sub_unit_kerja,
@ -1401,18 +1398,18 @@ class DashboardController extends Controller
];
$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
]);
@ -1446,7 +1443,7 @@ class DashboardController extends Controller
$payloadNotificationMutu = [
'created_at' => now(),
'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh " . auth()->user()->dataUser->namalengkap,
'url' => '/pengajuan-file',
'url' => '/pending-file',
'is_read' => false,
'unit_id' => 51,
];
@ -1457,7 +1454,7 @@ class DashboardController extends Controller
$payloadNotificationTurt = [
'created_at' => now(),
'text_notifikasi' => "Dokumen {$docNumber} memerlukan persetujuan. Diunggah oleh " . auth()->user()->dataUser->namalengkap,
'url' => '/pengajuan-file',
'url' => '/pending-file',
'is_read' => false,
'unit_id' => 22,
];
@ -1474,7 +1471,6 @@ class DashboardController extends Controller
'status_action' => $status
], 200);
} catch (\Throwable $th) {
dd($th);
DB::connection('dbDirectory')->rollback();
return response()->json([
'status' => false,
@ -1896,19 +1892,23 @@ class DashboardController extends Controller
$keyword = request('keyword');
$start = request('start_date');
$end = request('end_date');
$pegawaiId = auth()->user()->objectpegawaifk;
$objectpegawaifk = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where(fn($q) =>
$q->where('objectatasanlangsungfk', auth()->user()->objectpegawaifk)
->orWhere('objectpejabatpenilaifk', auth()->user()->objectpegawaifk)
$q->where('objectatasanlangsungfk', $pegawaiId)
->orWhere('objectpejabatpenilaifk', $pegawaiId)
)
->pluck('objectpegawaifk')
->unique()
->values()
->all();
if (!in_array($pegawaiId, $objectpegawaifk, true)) {
$objectpegawaifk[] = $pegawaiId;
}
$objectUnit = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
->where('objectpegawaifk', $pegawaiId)
->pluck('objectunitkerjapegawaifk')
->unique()
->values()
@ -1916,40 +1916,18 @@ class DashboardController extends Controller
$keyword = request('keyword');
$isKomiteMutu = in_array(51, $objectUnit);
$isTurt = in_array(22, $objectUnit);
$hasAtasanScope = !empty($objectpegawaifk);
// 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) {
$query->where(function ($root) use ($isKomiteMutu, $isTurt, $hasAtasanScope, $objectpegawaifk) {
if ($hasAtasanScope) {
$root->where(function ($atasanQuery) use ($objectpegawaifk, $hasAtasanScope) {
$atasanQuery->whereIn('pegawai_id_entry', $objectpegawaifk)->where(function ($qsa) {
$qsa->where('status_action', '!=', 'approved')
->orWhereNull('status_action')
->orWhere(function ($approvedButPending) {
$approvedButPending->where('status_action', 'approved')
->where(function ($needFurtherApproval) {
$approvedButPending->where(function ($needFurtherApproval) {
$needFurtherApproval
->where(function ($needTurt) {
$needTurt->whereNotNull('master_kategori_directory_id')
@ -1968,19 +1946,43 @@ class DashboardController extends Controller
});
});
});
});
}
if ($isKomiteMutu || $isTurt) {
$method = $hasAtasanScope ? 'orWhere' : 'where';
$root->{$method}(function ($roleQuery) use ($isKomiteMutu, $isTurt) {
$roleQuery->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) {
$innerMethod = $isTurt ? 'orWhere' : 'where';
$q->{$innerMethod}(function ($sub) {
$sub->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);
}
@ -1989,7 +1991,7 @@ class DashboardController extends Controller
}
$paginated = $query->paginate($perPage);
$data = $paginated->getCollection()->map(function($item){
$data = $paginated->getCollection()->map(function($item) use($objectpegawaifk){
$dataSlice = array_values(array_filter(explode('/', $item->file)));
return [
'file_directory_id' => $item->file_directory_id,
@ -2013,6 +2015,9 @@ class DashboardController extends Controller
'id_sub_unit_kerja' => $item->id_sub_unit_kerja,
'master_kategori_directory_id' => $item->master_kategori_directory_id,
'is_akre' => $item->is_akre,
'can_approve_atasan' => in_array($item->pegawai_id_entry, $objectpegawaifk),
'can_edit_submission' => (int) $item->pegawai_id_entry === (int) $pegawaiId,
'revision' => $item->revision,
];
});
return response()->json([
@ -2040,10 +2045,29 @@ class DashboardController extends Controller
'message' => 'Data tidak ditemukan'
], 404);
}
$objectUnit = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
->pluck('objectunitkerjapegawaifk')
->unique()
->values()
->all();
$requiresMutuApproval = $data->is_akre;
$requiresTurtApproval = $data->master_kategori_directory_id;
$isKomiteMutu = in_array(51, $objectUnit);
$isTurt = in_array(22, $objectUnit);
$mutuStatus = $isKomiteMutu && $requiresMutuApproval ? 'approved' : null;
$turtStatus = $isTurt && $requiresTurtApproval ? 'approved' : null;
$data->update([
'status_action' => 'approved',
'action_at' => now(),
'action_by' => auth()->user()->dataUser->id,
'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,
]);
$parts = array_values(array_filter(explode('/', $data->file)));
@ -2318,23 +2342,77 @@ class DashboardController extends Controller
public function countDataPending(){
try {
$pegawaiId = auth()->user()->objectpegawaifk;
$objectpegawaifk = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where(fn($q) =>
$q->where('objectatasanlangsungfk', auth()->user()->objectpegawaifk)
->orWhere('objectpejabatpenilaifk', auth()->user()->objectpegawaifk)
$q->where('objectatasanlangsungfk', $pegawaiId)
->orWhere('objectpejabatpenilaifk', $pegawaiId)
)
->pluck('objectpegawaifk')
->unique()
->values()
->all();
$count = FileDirectory::where('statusenabled', true)->whereIn('pegawai_id_entry', $objectpegawaifk)
->where(function($q){
$q->whereNotIn('status_action', ['approved', 'rejected'])->orWhereNull('status_action');
})->count();
// $authUnit = auth()->user()->masterPersetujuan->details->pluck('unit_pegawai_id')->unique()->toArray();
// $count= $query->whereIn('id_unit_kerja', $authUnit)->count();
// $count = $query->
if (!in_array($pegawaiId, $objectpegawaifk, true)) {
$objectpegawaifk[] = $pegawaiId;
}
$objectUnit = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where('objectpegawaifk', $pegawaiId)
->pluck('objectunitkerjapegawaifk')
->unique()
->values()
->all();
$isKomiteMutu = in_array(51, $objectUnit);
$isTurt = in_array(22, $objectUnit);
$hasAtasanScope = !empty($objectpegawaifk);
$query = FileDirectory::where('statusenabled', true);
$query->where(function ($root) use ($isKomiteMutu, $isTurt, $hasAtasanScope, $objectpegawaifk) {
if ($hasAtasanScope) {
$root->where(function ($atasanQuery) use ($objectpegawaifk) {
$atasanQuery->whereIn('pegawai_id_entry', $objectpegawaifk)
->where(function ($qsa) {
$qsa->where('status_action', '!=', 'approved')
->where(function ($notRejected) {
$notRejected->where('status_action', '!=', 'rejected')
->orWhereNull('status_action');
})
->orWhereNull('status_action');
});
});
}
if ($isKomiteMutu || $isTurt) {
$method = $hasAtasanScope ? 'orWhere' : 'where';
$root->{$method}(function ($roleQuery) use ($isKomiteMutu, $isTurt) {
$roleQuery->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) {
$innerMethod = $isTurt ? 'orWhere' : 'where';
$q->{$innerMethod}(function ($sub) {
$sub->where('is_akre', true)
->where(function ($pendingMutu) {
$pendingMutu->whereNull('status_mutu')
->orWhere('status_mutu', 'rejected');
});
});
}
});
});
}
});
$count = $query->count();
return response()->json([
'status' => true,
'count' => $count,
@ -2401,7 +2479,8 @@ class DashboardController extends Controller
$query = Notifkasi::query();
$query->where(function($q) use($pegawaiId, $objectUnit, $isKomiteMutu, $isTurt){
if($isKomiteMutu || $isTurt){
$q->orWhere(function($sub) use($objectUnit){
$q->where('pegawai_id', $pegawaiId)
->orWhere(function($sub) use($objectUnit){
$sub->whereNull('pegawai_id')->whereIn('unit_id', $objectUnit);
});
}else{
@ -2438,7 +2517,7 @@ class DashboardController extends Controller
]);
}
$pegawaiId = auth()->user()?->dataUser?->id;
$pegawaiId = auth()->user()?->objectpegawaifk;
$objectUnit = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
@ -2458,7 +2537,8 @@ class DashboardController extends Controller
$query = Notifkasi::query();
$query->where(function($q) use($pegawaiId, $isKomiteMutu, $isTurt, $objectUnit){
if($isKomiteMutu || $isTurt){
$q->orWhere(function($sub) use($objectUnit){
$q->where('pegawai_id', $pegawaiId)
->orWhere(function($sub) use($objectUnit){
$sub->whereNull('pegawai_id')->whereIn('unit_id', $objectUnit);
});
}else{
@ -2705,20 +2785,29 @@ class DashboardController extends Controller
$katDok = MasterKategori::where('statusenabled', true)
->select('master_kategori_directory_id', 'nama_kategori_directory')
->get();
$pegawaiId = auth()->user()->objectpegawaifk;
$objectUnit = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where('objectpegawaifk', auth()->user()->objectpegawaifk)
->where('objectpegawaifk', $pegawaiId)
->pluck('objectunitkerjapegawaifk')
->unique()
->values()
->all();
$isKomiteMutu = in_array(51, $objectUnit);
$isTurt = in_array(22, $objectUnit);
$isAtasan = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where(function ($q) use ($pegawaiId) {
$q->where('objectatasanlangsungfk', $pegawaiId)
->orWhere('objectpejabatpenilaifk', $pegawaiId);
})
->exists();
return view('pengajuanFile.index', [
'title' => 'Data Persetujuan',
'katDok' => $katDok,
'isKomiteMutu' => $isKomiteMutu,
'isTurt' => $isTurt
'isTurt' => $isTurt,
'isAtasan' => $isAtasan,
]);
}
@ -2739,11 +2828,20 @@ class DashboardController extends Controller
->all();
$isKomiteMutu = in_array(51, $objectUnit);
$isTurt = in_array(22, $objectUnit);
$isAtasan = MappingUnitKerjaPegawai::query()
->where('statusenabled', true)
->where(function ($q) use ($pegawaiId) {
$q->where('objectatasanlangsungfk', $pegawaiId)
->orWhere('objectpejabatpenilaifk', $pegawaiId);
})
->exists();
$query = FileDirectory::with('kategori')->where('statusenabled', true);
if ($mode === 'persetujuan' && ($isKomiteMutu || $isTurt)) {
$query->where(function ($q) use ($isKomiteMutu, $isTurt) {
if ($mode === 'persetujuan' && ($isKomiteMutu || $isTurt || $isAtasan)) {
$query->where(function ($root) use ($isKomiteMutu, $isTurt, $isAtasan, $pegawaiId) {
if ($isKomiteMutu || $isTurt) {
$root->where(function ($q) use ($isKomiteMutu, $isTurt) {
if ($isTurt) {
$q->whereNotNull('master_kategori_directory_id')
->where(function ($pendingTurt) {
@ -2762,6 +2860,33 @@ class DashboardController extends Controller
});
}
})->where('status_action', 'approved');
}
if ($isAtasan) {
$method = ($isKomiteMutu || $isTurt) ? 'orWhere' : 'where';
$root->{$method}(function ($ownSubmission) use ($pegawaiId) {
$ownSubmission->where('pegawai_id_entry', $pegawaiId)
->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');
});
})
->orWhere(function ($needMutu) {
$needMutu->where('is_akre', true)
->where(function ($pendingMutu) {
$pendingMutu->whereNull('status_mutu')
->orWhere('status_mutu', 'rejected');
});
});
});
});
}
});
} else {
$query->where('pegawai_id_entry', $pegawaiId)
->when($isHistory, function($q){
@ -3001,9 +3126,10 @@ class DashboardController extends Controller
$targetRoleNotifications = [];
$resetMutuApproval = $data->status_mutu === 'rejected';
$resetTurtApproval = $data->status_turt === 'rejected';
$resetAtasanApproval = $data->status_action === 'rejected';
if ($resetMutuApproval) {
$payload['status_mutu'] = null;
$payload['status_mutu'] = 'revised Mutu';
$payload['mutu_revision'] = null;
$payload['action_mutu_at'] = null;
$payload['action_mutu_by'] = null;
@ -3011,17 +3137,19 @@ class DashboardController extends Controller
}
if ($resetTurtApproval) {
$payload['status_turt'] = null;
$payload['status_turt'] = 'revised TURT';
$payload['turt_revision'] = null;
$payload['action_turt_at'] = null;
$payload['action_turt_by'] = null;
$targetRoleNotifications[] = 22;
}
if($resetAtasanApproval){
$payload['revision'] = null;
$payload['status_action'] = 'revised';
$payload['action_at'] = null;
$payload['action_by'] = null;
}
if (!empty($payload)) {
@ -3073,7 +3201,6 @@ class DashboardController extends Controller
'statusenabled' => true,
'nama_dokumen' => $data->nama_dokumen ?? null,
'no_dokumen' => $data->no_dokumen ?? 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',
@ -3231,6 +3358,7 @@ class DashboardController extends Controller
public function dataTableAkreditasi(Request $request)
{
$keyword = $request->query('keyword');
$page = max(1, (int) $request->query('page', 1));
$perPage = (int) $request->query('per_page', 10);
$perPage = max(1, min(100, $perPage));
@ -3266,28 +3394,131 @@ class DashboardController extends Controller
->orWhere('file', 'ILIKE', "%{$keyword}%"); // Cari juga berdasarkan nama file di path
});
});
$data = $query
->orderBy('entry_at', 'desc')
->paginate($perPage);
$items = $query->get();
$sortedItems = $this->sortAkreditasiRowsByJffOrder($items->all());
$total = count($sortedItems);
$offset = ($page - 1) * $perPage;
$pageItems = array_slice($sortedItems, $offset, $perPage);
$lastPage = max(1, (int) ceil($total / $perPage));
return response()->json([
'status' => true,
'message' => 'Berhasil mendapatkan data',
'data' => $data->items(),
'data' => array_values($pageItems),
'pagination' => [
'current_page' => $data->currentPage(),
'next_page' => $data->hasMorePages() ? $data->currentPage() + 1 : null,
'prev_page' => $data->currentPage() > 1 ? $data->currentPage() - 1 : null,
'total' => $data->total(),
'per_page' => $data->perPage(),
'last_page' => $data->lastPage(),
'has_more' => $data->hasMorePages(),
'from' => $data->firstItem(),
'to' => $data->lastItem(),
'current_page' => $page,
'next_page' => $page < $lastPage ? $page + 1 : null,
'prev_page' => $page > 1 ? $page - 1 : null,
'total' => $total,
'per_page' => $perPage,
'last_page' => $lastPage,
'has_more' => $page < $lastPage,
'from' => $total > 0 ? $offset + 1 : 0,
'to' => $offset + count($pageItems),
]
]);
}
private function sortAkreditasiRowsByJffOrder(array $items): array
{
$orderMap = $this->buildAkreditasiOrderMap();
usort($items, function ($left, $right) use ($orderMap) {
$leftPath = $this->getAkreditasiFolderPathFromFile($left->file ?? '');
$rightPath = $this->getAkreditasiFolderPathFromFile($right->file ?? '');
$pathCompare = $this->compareAkreditasiPaths($leftPath, $rightPath, $orderMap);
if ($pathCompare !== 0) {
return $pathCompare;
}
$leftName = Str::lower((string) ($left->nama_dokumen ?? $left->file ?? ''));
$rightName = Str::lower((string) ($right->nama_dokumen ?? $right->file ?? ''));
return strnatcasecmp($leftName, $rightName);
});
return $items;
}
private function buildAkreditasiOrderMap(): array
{
$path = public_path('json/akreditasi.jff');
if (!is_file($path)) {
return [];
}
$raw = @file_get_contents($path);
$data = json_decode($raw ?: '[]', true);
if (!is_array($data)) {
return [];
}
$orderMap = [];
foreach ($data as $typeIndex => $typeItem) {
$typeName = trim((string) ($typeItem['name'] ?? ''));
if ($typeName === '') {
continue;
}
$orderMap[$typeName] = [$typeIndex, -1, -1];
$segments = isset($typeItem['segment']) && is_array($typeItem['segment'])
? $typeItem['segment']
: [];
foreach ($segments as $segmentIndex => $segmentItem) {
$segmentName = trim((string) ($segmentItem['name'] ?? ''));
if ($segmentName === '') {
continue;
}
$segmentPath = $typeName . '/' . $segmentName;
$orderMap[$segmentPath] = [$typeIndex, $segmentIndex, -1];
$children = isset($segmentItem['turunan']) && is_array($segmentItem['turunan'])
? $segmentItem['turunan']
: [];
foreach ($children as $childIndex => $childItem) {
$childName = trim((string) ($childItem['name'] ?? ''));
if ($childName === '') {
continue;
}
$orderMap[$segmentPath . '/' . $childName] = [$typeIndex, $segmentIndex, $childIndex];
}
}
}
return $orderMap;
}
private function getAkreditasiFolderPathFromFile(?string $filePath): string
{
$parts = array_values(array_filter(explode('/', (string) $filePath)));
if (count($parts) <= 1) {
return '';
}
array_pop($parts);
return implode('/', $parts);
}
private function compareAkreditasiPaths(string $leftPath, string $rightPath, array $orderMap): int
{
$fallback = [PHP_INT_MAX, PHP_INT_MAX, PHP_INT_MAX];
$leftOrder = $orderMap[$leftPath] ?? $fallback;
$rightOrder = $orderMap[$rightPath] ?? $fallback;
for ($i = 0; $i < 3; $i++) {
if ($leftOrder[$i] !== $rightOrder[$i]) {
return $leftOrder[$i] <=> $rightOrder[$i];
}
}
return strnatcasecmp($leftPath, $rightPath);
}
public function expDokumen(){
$katDok = MasterKategori::where('statusenabled', true)->select('master_kategori_directory_id', 'nama_kategori_directory')->get();
$authMapping = auth()->user()?->dataUser?->mappingUnitKerjaPegawai[0];
@ -3818,7 +4049,7 @@ class DashboardController extends Controller
'statusenabled' => true,
'nama_dokumen' => $data->nama_dokumen ?? null,
'no_dokumen' => $data->no_dokumen ?? null,
'mod_change' => $revision,
'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' => 'Rejected Dokumen Turt',

View File

@ -115,15 +115,23 @@ document.addEventListener('DOMContentLoaded', () => {
return item?.status_action === 'approved';
}
function canApproveAsAtasan(item){
return item?.can_approve_atasan === true || item?.can_approve_atasan === 1 || item?.can_approve_atasan === '1';
}
function canEditSubmission(item){
return item?.can_edit_submission === true || item?.can_edit_submission === 1 || item?.can_edit_submission === '1';
}
function getSelectableIdsOnPage(){
return (tableState.data || [])
.filter((item) => !isRejected(item) && !isAtasanApproved(item))
.filter((item) => !isRejected(item) && !isAtasanApproved(item) && canApproveAsAtasan(item))
.map((item) => String(item.file_directory_id));
}
function updateSelectAllState(){
if (!selectAllCheckbox) return;
if (tableState.mode === 'history' || isKomiteMutu || isTurt) {
if (tableState.mode === 'history') {
selectAllCheckbox.checked = false;
selectAllCheckbox.indeterminate = false;
selectAllCheckbox.disabled = true;
@ -145,9 +153,11 @@ document.addEventListener('DOMContentLoaded', () => {
function updateSelectionUI(){
const count = selectedIds.size;
const selectableIds = getSelectableIdsOnPage();
const canBulkApprove = tableState.mode !== 'history' && selectableIds.length > 0;
if (selectedCountEl) selectedCountEl.textContent = String(count);
if (bulkApproveBtn) bulkApproveBtn.disabled = count === 0 || tableState.mode === 'history' || isKomiteMutu || isTurt;
if (clearSelectionBtn) clearSelectionBtn.disabled = count === 0 || tableState.mode === 'history' || isKomiteMutu || isTurt;
if (bulkApproveBtn) bulkApproveBtn.disabled = count === 0 || !canBulkApprove;
if (clearSelectionBtn) clearSelectionBtn.disabled = count === 0 || !canBulkApprove;
updateSelectAllState();
}
@ -158,6 +168,7 @@ document.addEventListener('DOMContentLoaded', () => {
const id = String(item.file_directory_id);
const rejected = isRejected(item);
const atasanApproved = isAtasanApproved(item);
const canAtasanApprove = canApproveAsAtasan(item);
const checked = selectedIds.has(id);
const actions = [
`<button class="btn btn-sm btn-primary" onclick="infoDok(this)"
@ -172,11 +183,15 @@ document.addEventListener('DOMContentLoaded', () => {
];
if (isKomiteMutu || isTurt) {
if (isKomiteMutu && item.is_akre && item.status_mutu !== 'approved') {
if (canAtasanApprove && !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>`);
}
if (atasanApproved && 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') {
if (atasanApproved && isTurt && item.master_kategori_directory_id && 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>`);
}
@ -193,6 +208,14 @@ document.addEventListener('DOMContentLoaded', () => {
}
}
if (rejected) {
actions.length = 1;
actions.push(`<button class="btn btn-sm btn-info" onclick="infoRejectPending('${item.file_directory_id}')"><i class="fa-solid fa-circle-info"></i></button>`);
if (canEditSubmission(item)) {
actions.push(`<button class="btn btn-sm btn-primary" onclick="editRejectedFromPending('${item.file_directory_id}')"><i class="fa-solid fa-pen-to-square"></i></button>`);
}
}
const statusContent = (isKomiteMutu || isTurt)
? getWorkflowStatusBadges(item).join(' ')
: getWorkflowStatusBadges(item).join(' ');
@ -203,9 +226,9 @@ document.addEventListener('DOMContentLoaded', () => {
class="form-check-input row-select"
data-id="${id}"
${checked ? 'checked' : ''}
${(rejected || atasanApproved || isKomiteMutu || isTurt) ? 'disabled' : ''}>
${(rejected || atasanApproved || !canAtasanApprove) ? 'disabled' : ''}>
</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 class="text-center text-nowrap"><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>${statusContent}</td>
<td>${aksesBadge(item?.permission_file)}</td>
@ -454,7 +477,7 @@ document.addEventListener('DOMContentLoaded', () => {
showConfirmButton: false
});
selectedIds.delete(String(id));
countData();
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({
@ -511,7 +534,7 @@ document.addEventListener('DOMContentLoaded', () => {
showConfirmButton: false
});
selectedIds.delete(String(id));
countData();
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({
@ -532,6 +555,33 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
window.infoRejectPending = function(id){
const item = getItemById(id);
const notes = [];
if (item?.revision) {
notes.push(`Atasan: ${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)}`);
}
Swal.fire({
title: 'Catatan Revisi',
text: notes.length ? notes.join('\n\n') : 'Tidak ada catatan revisi.',
icon: 'info',
confirmButtonText: 'Tutup'
});
}
window.editRejectedFromPending = function(id){
const targetUrl = new URL('/pengajuan-file', window.location.origin);
targetUrl.searchParams.set('edit', id);
window.location.href = targetUrl.toString();
}
window.approvePendingRole = function(type, id, fileName){
const endpoint = type === 'mutu'
? `/pending-file/${id}/approve-mutu`
@ -565,6 +615,7 @@ document.addEventListener('DOMContentLoaded', () => {
timer: 1500,
showConfirmButton: false
});
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({
@ -623,6 +674,7 @@ document.addEventListener('DOMContentLoaded', () => {
timer: 1500,
showConfirmButton: false
});
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({
@ -733,7 +785,7 @@ document.addEventListener('DOMContentLoaded', () => {
timer: 1500,
showConfirmButton: false
});
countData();
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({

View File

@ -29,6 +29,7 @@ document.addEventListener('DOMContentLoaded', () => {
const selectedIds = new Set();
const isKomiteMutu = !!window.isKomiteMutu;
const isTurt = !!window.isTurt;
let editFromQueryId = new URLSearchParams(window.location.search).get('edit');
if (pageSizeSelect) {
const initialSize = parseInt(pageSizeSelect.value);
@ -254,8 +255,8 @@ document.addEventListener('DOMContentLoaded', () => {
return `
<tr>
<td class="text-center">-</td>
<td><div class="d-flex gap-1 flex-wrap">${actions.join('')}</div></td>
<td class="text-center"></td>
<td class="text-center align-middle"><div class="d-flex justify-content-center gap-1 flex-nowrap">${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>
@ -422,6 +423,19 @@ document.addEventListener('DOMContentLoaded', () => {
renderPagination(activeState.lastPage || 1);
updateSelectionUI();
maybeOpenEditFromQuery();
}
function maybeOpenEditFromQuery(){
if (!editFromQueryId || tableState.mode !== 'pengajuan') return;
const item = getItemById(editFromQueryId);
if (!item) return;
const cleanUrl = new URL(window.location.href);
cleanUrl.searchParams.delete('edit');
window.history.replaceState({}, '', cleanUrl.toString());
const pendingId = editFromQueryId;
editFromQueryId = null;
window.editFileReject(pendingId);
}
let searchDebounce;
@ -640,6 +654,7 @@ document.addEventListener('DOMContentLoaded', () => {
timer: 1500,
showConfirmButton: false
});
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({
@ -700,6 +715,7 @@ document.addEventListener('DOMContentLoaded', () => {
timer: 1500,
showConfirmButton: false
});
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({
@ -1120,6 +1136,7 @@ document.addEventListener('DOMContentLoaded', () => {
showConfirmButton: false
});
$("#modalEditPengajuanFile").modal('hide');
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
}).catch((err) => {
Swal.fire({
@ -1548,6 +1565,7 @@ document.addEventListener('DOMContentLoaded', () => {
const modalInstance = bootstrap.Modal.getInstance(modalCreate);
modalInstance?.hide();
resetCreateForm();
if (typeof window.refreshPendingCount === 'function') window.refreshPendingCount();
fetchData();
if(responseData.status_action === null || responseData.status_action === undefined){
Swal.fire({

View File

@ -52,9 +52,21 @@
{{-- AKTIVITAS --}}
<li class="nav-small-cap"><span class="hide-menu">Aktivitas</span></li>
@php
$isAtasan = \App\Models\MappingUnitKerjaPegawai::where('statusenabled', true)->where('objectatasanlangsungfk', auth()->user()->objectpegawaifk)->exists();
$pegawaiId = auth()->user()->objectpegawaifk;
$userUnitIds = auth()->user()->dataUser->mappingUnitKerjaPegawai()
->where('statusenabled', true)
->pluck('objectunitkerjapegawaifk')
->unique()
->values()
->all();
$isAtasan = \App\Models\MappingUnitKerjaPegawai::where('statusenabled', true)
->where(function ($q) use ($pegawaiId) {
$q->where('objectatasanlangsungfk', $pegawaiId)
->orWhere('objectpejabatpenilaifk', $pegawaiId);
})->exists();
$isRoleApprover = in_array(51, $userUnitIds, true) || in_array(22, $userUnitIds, true);
@endphp
@if($isAtasan)
@if($isAtasan || $isRoleApprover)
@if(!Auth::guard('admin')->check())
<li class="sidebar-item">
<a class="sidebar-link d-flex align-items-center justify-content-between"
@ -215,6 +227,8 @@
}
}
window.refreshPendingCount = countData;
countData();
// setInterval(countData, 60000);

View File

@ -46,7 +46,7 @@
<li class="nav-item">
<button class="nav-link active" type="button" data-mode="pengajuan">Data Pengajuan</button>
</li>
@if($isKomiteMutu || $isTurt)
@if($isKomiteMutu || $isTurt || $isAtasan)
<li class="nav-item">
<button class="nav-link" type="button" data-mode="persetujuan">Data Persetujuan</button>
</li>
@ -158,6 +158,7 @@
window.katDok = @json($katDok);
window.isKomiteMutu = @json($isKomiteMutu);
window.isTurt = @json($isTurt);
window.isAtasan = @json($isAtasan);
</script>
<script src="{{ ver('/js/pengajuanFile/index.js') }}"></script>
@endsection