done add keterangan pemberi penilaian

This commit is contained in:
JokoPrasetio 2026-05-12 11:01:56 +07:00
parent 684e0b1bb5
commit bc397b828e
7 changed files with 615 additions and 105 deletions

View File

@ -680,28 +680,174 @@ class PitStopController extends Controller
->orderBy('t.unit_name')
->get();
// Rekap karyawan (all unit)
$pegawaiRecap = DB::connection('pgsql')
->table('public.mappegawaijabatantounitkerja_m as mp')
->join('public.pegawai_m as pg', 'pg.id', '=', 'mp.objectpegawaifk')
->join('public.unitkerjapegawai_m as ukp', 'ukp.id', '=', 'mp.objectunitkerjapegawaifk')
->leftJoin('public.praakre as p', function ($join) {
$join->on('p.pegawai_id', '=', 'pg.id')
->where(function ($q) {
$q->whereNull('p.tipe_karyawan')
->orWhere('p.tipe_karyawan', 'internal');
});
})
->leftJoin('public.masterpitstop as m', function ($join) {
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->where('mp.statusenabled', true)
->where('mp.isprimary', true)
->where('pg.statusenabled', true)
->where('pg.kedudukanfk', 1)
->where('ukp.statusenabled', true)
->select([
DB::raw('ukp.id as unit_id'),
DB::raw("coalesce(ukp.name, '-') as unit_name"),
'pg.id',
DB::raw("coalesce(pg.namalengkap, '-') as nama"),
DB::raw("coalesce(pg.nip_pns, '-') as nip_pns"),
DB::raw("count(distinct m.id) as lulus_count"),
DB::raw("coalesce((
select string_agg(ms.nama, ', ' order by ms.id)
from public.masterpitstop ms
left join public.praakre px
on px.pegawai_id = pg.id
and (px.tipe_karyawan is null or px.tipe_karyawan = 'internal')
and px.masterpitstop_id = ms.id::text
where ms.statusenabled = true
and px.id is null
), '') as belum_steps"),
])
->groupBy('ukp.id', 'ukp.name', 'pg.id', 'pg.namalengkap', 'pg.nip_pns')
->orderBy('ukp.name')
->orderBy('pg.namalengkap')
->get();
$pegawaiIds = collect($pegawaiRecap)->pluck('id')->filter()->values()->all();
$praakreDetailAll = collect();
if (count($pegawaiIds) > 0) {
$praakreDetailAll = DB::connection('pgsql')
->table('public.praakre as p')
->leftJoin('public.masterpitstop as m', function ($join) {
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->whereIn('p.pegawai_id', $pegawaiIds)
->where(function ($q) {
$q->whereNull('p.tipe_karyawan')
->orWhere('p.tipe_karyawan', 'internal');
})
->whereNotNull('m.id')
->select([
'p.pegawai_id',
DB::raw("coalesce(m.nama, '-') as pitstop_nama"),
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
])
->orderBy('p.pegawai_id')
->orderBy('m.id')
->orderBy('p.id')
->get();
}
$filename = 'monitoring-pra-akreditasi-ringkasan-' . $generatedAt->format('Ymd-Hi') . '.xlsx';
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($unitAgg, $totalSteps) {
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Internal (Summary)');
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($unitAgg, $pegawaiRecap, $praakreDetailAll, $totalSteps) {
// Sheet 1: Rekap Unit
$unitSheet = $spreadsheet->getActiveSheet();
$unitSheet->setTitle('Rekap Unit');
$headers = ['Nama Unit', 'Total Pitstop', 'Total Karyawan', 'Karyawan Selesai'];
foreach ($headers as $i => $h) {
$sheet->setCellValueByColumnAndRow($i + 1, 1, $h);
$unitSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$sheet->getStyle('A1:E1')->getFont()->setBold(true);
$unitSheet->getStyle('A1:D1')->getFont()->setBold(true);
$row = 2;
foreach ($unitAgg as $r) {
$sheet->setCellValueByColumnAndRow(1, $row, (string) ($r->unit_name ?? '-'));
$sheet->setCellValueByColumnAndRow(2, $row, (int) $totalSteps);
$sheet->setCellValueByColumnAndRow(3, $row, (int) ($r->total_pegawai ?? 0));
$sheet->setCellValueByColumnAndRow(4, $row, (int) ($r->pegawai_selesai ?? 0));
$unitSheet->setCellValueByColumnAndRow(1, $row, (string) ($r->unit_name ?? '-'));
$unitSheet->setCellValueByColumnAndRow(2, $row, (int) $totalSteps);
$unitSheet->setCellValueByColumnAndRow(3, $row, (int) ($r->total_pegawai ?? 0));
$unitSheet->setCellValueByColumnAndRow(4, $row, (int) ($r->pegawai_selesai ?? 0));
$row++;
}
foreach(range('A', 'E') as $col){
$sheet->getColumnDimension($col)->setAutoSize(true);
foreach (range('A', 'D') as $col) {
$unitSheet->getColumnDimension($col)->setAutoSize(true);
}
// Sheet 2: Rekap Karyawan
$pegawaiSheet = $spreadsheet->createSheet();
$pegawaiSheet->setTitle('Rekap Karyawan');
$pegawaiHeaders = ['Nama Unit', 'Nama Karyawan', 'NIP', 'Lulus Pitstop', 'Total Pitstop', 'Belum Dikerjakan'];
foreach ($pegawaiHeaders as $i => $h) {
$pegawaiSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$pegawaiSheet->getStyle('A1:F1')->getFont()->setBold(true);
$pegawaiRow = 2;
foreach ($pegawaiRecap as $r) {
$pegawaiSheet->setCellValueByColumnAndRow(1, $pegawaiRow, (string) ($r->unit_name ?? '-'));
$pegawaiSheet->setCellValueByColumnAndRow(2, $pegawaiRow, (string) ($r->nama ?? '-'));
$pegawaiSheet->setCellValueExplicitByColumnAndRow(3, $pegawaiRow, (string) ($r->nip_pns ?? '-'), DataType::TYPE_STRING);
$pegawaiSheet->setCellValueByColumnAndRow(4, $pegawaiRow, (int) ($r->lulus_count ?? 0));
$pegawaiSheet->setCellValueByColumnAndRow(5, $pegawaiRow, (int) $totalSteps);
$pegawaiSheet->setCellValueByColumnAndRow(6, $pegawaiRow, (string) ($r->belum_steps ?? ''));
$pegawaiRow++;
}
foreach (range('A', 'F') as $col) {
$pegawaiSheet->getColumnDimension($col)->setAutoSize(true);
}
// Sheet 3: Detail PraAkre Karyawan
$detailSheet = $spreadsheet->createSheet();
$detailSheet->setTitle('Detail PraAkre');
$detailHeaders = ['Nama Unit', 'Nama Karyawan', 'NIP', 'Pitstop', 'Nilai', 'Penilai'];
foreach ($detailHeaders as $i => $h) {
$detailSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$detailSheet->getStyle('A1:F1')->getFont()->setBold(true);
$pegawaiById = collect($pegawaiRecap)->keyBy('id');
$detailRow = 2;
$lastPegawaiId = null;
foreach ($praakreDetailAll as $d) {
if (!is_null($lastPegawaiId) && (string) $lastPegawaiId !== (string) $d->pegawai_id) {
$detailSheet->getStyle('A' . $detailRow . ':F' . $detailRow)
->applyFromArray([
'borders' => [
'top' => [
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
'color' => ['argb' => 'FF999999'],
],
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['argb' => 'FF1E88E5'],
],
]);
$detailRow++;
}
$pg = $pegawaiById->get($d->pegawai_id);
$detailSheet->setCellValueByColumnAndRow(1, $detailRow, (string) data_get($pg, 'unit_name', '-'));
$detailSheet->setCellValueByColumnAndRow(2, $detailRow, (string) data_get($pg, 'nama', '-'));
$detailSheet->setCellValueExplicitByColumnAndRow(3, $detailRow, (string) data_get($pg, 'nip_pns', '-'), DataType::TYPE_STRING);
$detailSheet->setCellValueByColumnAndRow(4, $detailRow, (string) ($d->pitstop_nama ?? '-'));
$detailSheet->setCellValueByColumnAndRow(5, $detailRow, (string) ($d->nilai ?? ''));
$detailSheet->setCellValueByColumnAndRow(6, $detailRow, (string) ($d->penilai_nama ?? '-'));
$detailRow++;
$lastPegawaiId = $d->pegawai_id;
}
foreach (range('A', 'F') as $col) {
$detailSheet->getColumnDimension($col)->setAutoSize(true);
}
$spreadsheet->setActiveSheetIndex(0);
});
}
@ -715,11 +861,17 @@ class PitStopController extends Controller
abort_if(!$unit, 404);
$rows = DB::connection('pgsql')
$pegawaiRows = DB::connection('pgsql')
->table('public.mappegawaijabatantounitkerja_m as mp')
->join('public.pegawai_m as pg', 'pg.id', '=', 'mp.objectpegawaifk')
->join('public.unitkerjapegawai_m as ukp', 'ukp.id', '=', 'mp.objectunitkerjapegawaifk')
->leftJoin('public.praakre as p', 'p.pegawai_id', '=', 'pg.id')
->leftJoin('public.praakre as p', function ($join) {
$join->on('p.pegawai_id', '=', 'pg.id')
->where(function ($q) {
$q->whereNull('p.tipe_karyawan')
->orWhere('p.tipe_karyawan', 'internal');
});
})
->leftJoin('public.masterpitstop as m', function ($join) {
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
@ -740,6 +892,7 @@ class PitStopController extends Controller
from public.masterpitstop ms
left join public.praakre px
on px.pegawai_id = pg.id
and (px.tipe_karyawan is null or px.tipe_karyawan = 'internal')
and px.masterpitstop_id = ms.id::text
where ms.statusenabled = true
and px.id is null
@ -749,33 +902,108 @@ class PitStopController extends Controller
->orderBy('pg.namalengkap')
->get();
$pegawaiIds = collect($pegawaiRows)->pluck('id')->filter()->values()->all();
$praakreRows = collect();
if (count($pegawaiIds) > 0) {
$praakreRows = DB::connection('pgsql')
->table('public.praakre as p')
->leftJoin('public.masterpitstop as m', function ($join) {
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->whereIn('p.pegawai_id', $pegawaiIds)
->where(function ($q) {
$q->whereNull('p.tipe_karyawan')
->orWhere('p.tipe_karyawan', 'internal');
})
->whereNotNull('m.id')
->select([
'p.pegawai_id',
DB::raw("coalesce(m.nama, '-') as pitstop_nama"),
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
])
->orderBy('p.pegawai_id')
->orderBy('m.id')
->orderBy('p.id')
->get();
}
$filename = 'monitoring-pra-akreditasi-unit-' . (int) $unitId . '-' . $generatedAt->format('Ymd-Hi') . '.xlsx';
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($rows, $unit, $totalSteps) {
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('Internal (Detail)');
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($pegawaiRows, $praakreRows, $unit, $totalSteps) {
// Sheet 1: Rekap
$rekapSheet = $spreadsheet->getActiveSheet();
$rekapSheet->setTitle('Rekap');
$headers = ['Nama Unit', 'Nama Karyawan', 'NIP', 'Lulus Pitstop', 'Total Pitstop', 'Belum Dikerjakan'];
foreach ($headers as $i => $h) {
$sheet->setCellValueByColumnAndRow($i + 1, 1, $h);
$rekapHeaders = ['Nama Unit', 'Nama Karyawan', 'NIP', 'Lulus Pitstop', 'Total Pitstop', 'Belum Dikerjakan'];
foreach ($rekapHeaders as $i => $h) {
$rekapSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$sheet->getStyle('A1:I1')->getFont()->setBold(true);
$rekapSheet->getStyle('A1:F1')->getFont()->setBold(true);
$row = 2;
foreach ($rows as $r) {
$lulus = (int) ($r->lulus_count ?? 0);
$selesai = $totalSteps > 0 && $lulus >= $totalSteps ? 1 : 0;
$rekapRow = 2;
foreach ($pegawaiRows as $pg) {
$rekapSheet->setCellValueByColumnAndRow(1, $rekapRow, (string) ($unit->name ?? '-'));
$rekapSheet->setCellValueByColumnAndRow(2, $rekapRow, (string) ($pg->nama ?? '-'));
$rekapSheet->setCellValueExplicitByColumnAndRow(3, $rekapRow, (string) ($pg->nip_pns ?? '-'), DataType::TYPE_STRING);
$rekapSheet->setCellValueByColumnAndRow(4, $rekapRow, (int) ($pg->lulus_count ?? 0));
$rekapSheet->setCellValueByColumnAndRow(5, $rekapRow, (int) $totalSteps);
$rekapSheet->setCellValueByColumnAndRow(6, $rekapRow, (string) ($pg->belum_steps ?? ''));
$rekapRow++;
}
foreach (range('A', 'F') as $col) {
$rekapSheet->getColumnDimension($col)->setAutoSize(true);
}
$sheet->setCellValueByColumnAndRow(1, $row, (string) ($unit->name ?? '-'));
$sheet->setCellValueByColumnAndRow(2, $row, (string) ($r->nama ?? '-'));
$sheet->setCellValueExplicitByColumnAndRow(3, $row, (string) ($r->nip_pns ?? '-'), DataType::TYPE_STRING);
$sheet->setCellValueByColumnAndRow(4, $row, $lulus);
$sheet->setCellValueByColumnAndRow(5, $row, (int) $totalSteps);
$sheet->setCellValueByColumnAndRow(6, $row, (string) ($r->belum_steps ?? ''));
$row++;
// Sheet 2: Detail
$detailSheet = $spreadsheet->createSheet();
$detailSheet->setTitle('Detail PraAkre');
$detailHeaders = ['Nama Karyawan', 'NIP', 'Pitstop', 'Nilai', 'Penilai'];
foreach ($detailHeaders as $i => $h) {
$detailSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
foreach(range('A', 'I') as $col){
$sheet->getColumnDimension($col)->setAutoSize(true);
$detailSheet->getStyle('A1:E1')->getFont()->setBold(true);
$pegawaiById = collect($pegawaiRows)->keyBy('id');
$detailRow = 2;
$lastPegawaiId = null;
foreach ($praakreRows as $d) {
if (!is_null($lastPegawaiId) && (string) $lastPegawaiId !== (string) $d->pegawai_id) {
$detailSheet->getStyle('A' . $detailRow . ':E' . $detailRow)
->applyFromArray([
'borders' => [
'top' => [
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
'color' => ['argb' => 'FF999999'],
],
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['argb' => 'FF1E88E5'],
],
]);
$detailRow++;
}
$pg = $pegawaiById->get($d->pegawai_id);
$detailSheet->setCellValueByColumnAndRow(1, $detailRow, (string) data_get($pg, 'nama', '-'));
$detailSheet->setCellValueExplicitByColumnAndRow(2, $detailRow, (string) data_get($pg, 'nip_pns', '-'), DataType::TYPE_STRING);
$detailSheet->setCellValueByColumnAndRow(3, $detailRow, (string) ($d->pitstop_nama ?? '-'));
$detailSheet->setCellValueByColumnAndRow(4, $detailRow, (string) ($d->nilai ?? ''));
$detailSheet->setCellValueByColumnAndRow(5, $detailRow, (string) ($d->penilai_nama ?? '-'));
$detailRow++;
$lastPegawaiId = $d->pegawai_id;
}
foreach (range('A', 'E') as $col) {
$detailSheet->getColumnDimension($col)->setAutoSize(true);
}
// default active sheet
$spreadsheet->setActiveSheetIndex(0);
});
}
@ -819,28 +1047,159 @@ class PitStopController extends Controller
->orderBy('t.tipe')
->get();
// Rekap karyawan external (all tipe)
$pegawaiRecap = DB::connection('pgsql')
->table('public.pegawai_luar_pl as pl')
->leftJoin('public.praakre as p', function ($join) {
$join->on('p.pegawai_id', '=', 'pl.id')
->where('p.tipe_karyawan', 'luar');
})
->leftJoin('public.masterpitstop as m', function ($join) {
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->select([
DB::raw("coalesce(nullif(pl.tipe, ''), '-') as tipe"),
'pl.id',
DB::raw("coalesce(pl.nama, '-') as nama"),
DB::raw("coalesce(pl.nik, '-') as nik"),
DB::raw("count(distinct m.id) as lulus_count"),
DB::raw("coalesce((
select string_agg(ms.nama, ', ' order by ms.id)
from public.masterpitstop ms
left join public.praakre px
on px.pegawai_id = pl.id
and px.tipe_karyawan = 'luar'
and px.masterpitstop_id = ms.id::text
where ms.statusenabled = true
and px.id is null
), '') as belum_steps"),
])
->groupBy(DB::raw("coalesce(nullif(pl.tipe, ''), '-')"), 'pl.id', 'pl.nama', 'pl.nik')
->orderBy(DB::raw("coalesce(nullif(pl.tipe, ''), '-')"))
->orderBy('pl.nama')
->get();
$pegawaiIds = collect($pegawaiRecap)->pluck('id')->filter()->values()->all();
$praakreDetailAll = collect();
if (count($pegawaiIds) > 0) {
$praakreDetailAll = DB::connection('pgsql')
->table('public.praakre as p')
->leftJoin('public.masterpitstop as m', function ($join) {
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->whereIn('p.pegawai_id', $pegawaiIds)
->where('p.tipe_karyawan', 'luar')
->whereNotNull('m.id')
->select([
'p.pegawai_id',
DB::raw("coalesce(m.nama, '-') as pitstop_nama"),
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
])
->orderBy('p.pegawai_id')
->orderBy('m.id')
->orderBy('p.id')
->get();
}
$filename = 'monitoring-karyawan-luar-ringkasan-' . $generatedAt->format('Ymd-Hi') . '.xlsx';
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($tipeAgg, $totalSteps) {
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('External (Summary)');
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($tipeAgg, $pegawaiRecap, $praakreDetailAll, $totalSteps) {
// Sheet 1: Rekap Unit/Tipe
$unitSheet = $spreadsheet->getActiveSheet();
$unitSheet->setTitle('Rekap Unit');
$headers = ['Unit', 'Total Pitstop', 'Total Karyawan External', 'Karyawan External Selesai'];
foreach ($headers as $i => $h) {
$sheet->setCellValueByColumnAndRow($i + 1, 1, $h);
$unitSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$sheet->getStyle('A1:D1')->getFont()->setBold(true);
$unitSheet->getStyle('A1:D1')->getFont()->setBold(true);
$row = 2;
foreach ($tipeAgg as $r) {
$sheet->setCellValueByColumnAndRow(1, $row, (string) ($r->tipe ?? '-'));
$sheet->setCellValueByColumnAndRow(2, $row, (int) $totalSteps);
$sheet->setCellValueByColumnAndRow(3, $row, (int) ($r->total_pegawai ?? 0));
$sheet->setCellValueByColumnAndRow(4, $row, (int) ($r->pegawai_selesai ?? 0));
$unitSheet->setCellValueByColumnAndRow(1, $row, (string) ($r->tipe ?? '-'));
$unitSheet->setCellValueByColumnAndRow(2, $row, (int) $totalSteps);
$unitSheet->setCellValueByColumnAndRow(3, $row, (int) ($r->total_pegawai ?? 0));
$unitSheet->setCellValueByColumnAndRow(4, $row, (int) ($r->pegawai_selesai ?? 0));
$row++;
}
foreach(range('A', 'D') as $col){
$sheet->getColumnDimension($col)->setAutoSize(true);
foreach (range('A', 'D') as $col) {
$unitSheet->getColumnDimension($col)->setAutoSize(true);
}
// Sheet 2: Rekap Karyawan
$pegawaiSheet = $spreadsheet->createSheet();
$pegawaiSheet->setTitle('Rekap Karyawan');
$pegawaiHeaders = ['Unit', 'Nama', 'NIK', 'Lulus Pitstop', 'Total Pitstop', 'Belum Dikerjakan'];
foreach ($pegawaiHeaders as $i => $h) {
$pegawaiSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$pegawaiSheet->getStyle('A1:F1')->getFont()->setBold(true);
$pegawaiRow = 2;
foreach ($pegawaiRecap as $r) {
$pegawaiSheet->setCellValueByColumnAndRow(1, $pegawaiRow, (string) ($r->tipe ?? '-'));
$pegawaiSheet->setCellValueByColumnAndRow(2, $pegawaiRow, (string) ($r->nama ?? '-'));
$pegawaiSheet->setCellValueExplicitByColumnAndRow(3, $pegawaiRow, (string) ($r->nik ?? '-'), DataType::TYPE_STRING);
$pegawaiSheet->setCellValueByColumnAndRow(4, $pegawaiRow, (int) ($r->lulus_count ?? 0));
$pegawaiSheet->setCellValueByColumnAndRow(5, $pegawaiRow, (int) $totalSteps);
$pegawaiSheet->setCellValueByColumnAndRow(6, $pegawaiRow, (string) ($r->belum_steps ?? ''));
$pegawaiRow++;
}
foreach (range('A', 'F') as $col) {
$pegawaiSheet->getColumnDimension($col)->setAutoSize(true);
}
// Sheet 3: Detail PraAkre
$detailSheet = $spreadsheet->createSheet();
$detailSheet->setTitle('Detail PraAkre');
$detailHeaders = ['Unit', 'Nama', 'NIK', 'Pitstop', 'Nilai', 'Penilai'];
foreach ($detailHeaders as $i => $h) {
$detailSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$detailSheet->getStyle('A1:F1')->getFont()->setBold(true);
$pegawaiById = collect($pegawaiRecap)->keyBy('id');
$detailRow = 2;
$lastPegawaiId = null;
foreach ($praakreDetailAll as $d) {
if (!is_null($lastPegawaiId) && (string) $lastPegawaiId !== (string) $d->pegawai_id) {
$detailSheet->getStyle('A' . $detailRow . ':F' . $detailRow)
->applyFromArray([
'borders' => [
'top' => [
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
'color' => ['argb' => 'FF999999'],
],
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['argb' => 'FF1E88E5'],
],
]);
$detailRow++;
}
$pg = $pegawaiById->get($d->pegawai_id);
$detailSheet->setCellValueByColumnAndRow(1, $detailRow, (string) data_get($pg, 'tipe', '-'));
$detailSheet->setCellValueByColumnAndRow(2, $detailRow, (string) data_get($pg, 'nama', '-'));
$detailSheet->setCellValueExplicitByColumnAndRow(3, $detailRow, (string) data_get($pg, 'nik', '-'), DataType::TYPE_STRING);
$detailSheet->setCellValueByColumnAndRow(4, $detailRow, (string) ($d->pitstop_nama ?? '-'));
$detailSheet->setCellValueByColumnAndRow(5, $detailRow, (string) ($d->nilai ?? ''));
$detailSheet->setCellValueByColumnAndRow(6, $detailRow, (string) ($d->penilai_nama ?? '-'));
$detailRow++;
$lastPegawaiId = $d->pegawai_id;
}
foreach (range('A', 'F') as $col) {
$detailSheet->getColumnDimension($col)->setAutoSize(true);
}
$spreadsheet->setActiveSheetIndex(0);
});
}
@ -876,34 +1235,104 @@ class PitStopController extends Controller
->orderBy('pl.nama')
->get();
$pegawaiIds = collect($rows)->pluck('id')->filter()->values()->all();
$praakreRows = collect();
if (count($pegawaiIds) > 0) {
$praakreRows = DB::connection('pgsql')
->table('public.praakre as p')
->leftJoin('public.masterpitstop as m', function ($join) {
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->whereIn('p.pegawai_id', $pegawaiIds)
->where('p.tipe_karyawan', 'luar')
->whereNotNull('m.id')
->select([
'p.pegawai_id',
DB::raw("coalesce(m.nama, '-') as pitstop_nama"),
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
])
->orderBy('p.pegawai_id')
->orderBy('m.id')
->orderBy('p.id')
->get();
}
$filename = 'monitoring-karyawan-luar-' . preg_replace('/[^a-zA-Z0-9_-]+/', '-', (string) $tipe) . '-' . $generatedAt->format('Ymd-Hi') . '.xlsx';
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($rows, $tipe, $totalSteps) {
$sheet = $spreadsheet->getActiveSheet();
$sheet->setTitle('External (Detail)');
return $this->streamXlsx($filename, function (Spreadsheet $spreadsheet) use ($rows, $praakreRows, $tipe, $totalSteps) {
// Sheet 1: Rekap
$rekapSheet = $spreadsheet->getActiveSheet();
$rekapSheet->setTitle('Rekap');
$headers = ['Unit', 'Nama', 'NIK', 'Lulus Pitstop', 'Total Pitstop', 'Belum Dikerjakan'];
foreach ($headers as $i => $h) {
$sheet->setCellValueByColumnAndRow($i + 1, 1, $h);
$rekapHeaders = ['Unit', 'Nama', 'NIK', 'Lulus Pitstop', 'Total Pitstop', 'Belum Dikerjakan'];
foreach ($rekapHeaders as $i => $h) {
$rekapSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$sheet->getStyle('A1:H1')->getFont()->setBold(true);
$rekapSheet->getStyle('A1:F1')->getFont()->setBold(true);
$row = 2;
$rekapRow = 2;
foreach ($rows as $r) {
$lulus = (int) ($r->lulus_count ?? 0);
$selesai = $totalSteps > 0 && $lulus >= $totalSteps ? 1 : 0;
$sheet->setCellValueByColumnAndRow(1, $row, (string) $tipe);
$sheet->setCellValueByColumnAndRow(2, $row, (string) ($r->nama ?? '-'));
$sheet->setCellValueExplicitByColumnAndRow(3, $row, (string) ($r->nik ?? '-'), DataType::TYPE_STRING);
$sheet->setCellValueByColumnAndRow(4, $row, $lulus);
$sheet->setCellValueByColumnAndRow(5, $row, (int) $totalSteps);
$sheet->setCellValueByColumnAndRow(6, $row, (string) ($r->belum_steps ?? ''));
$row++;
$rekapSheet->setCellValueByColumnAndRow(1, $rekapRow, (string) $tipe);
$rekapSheet->setCellValueByColumnAndRow(2, $rekapRow, (string) ($r->nama ?? '-'));
$rekapSheet->setCellValueExplicitByColumnAndRow(3, $rekapRow, (string) ($r->nik ?? '-'), DataType::TYPE_STRING);
$rekapSheet->setCellValueByColumnAndRow(4, $rekapRow, (int) ($r->lulus_count ?? 0));
$rekapSheet->setCellValueByColumnAndRow(5, $rekapRow, (int) $totalSteps);
$rekapSheet->setCellValueByColumnAndRow(6, $rekapRow, (string) ($r->belum_steps ?? ''));
$rekapRow++;
}
foreach (range('A', 'F') as $col) {
$rekapSheet->getColumnDimension($col)->setAutoSize(true);
}
foreach(range('A', 'H') as $col){
$sheet->getColumnDimension($col)->setAutoSize(true);
// Sheet 2: Detail
$detailSheet = $spreadsheet->createSheet();
$detailSheet->setTitle('Detail PraAkre');
$detailHeaders = ['Unit', 'Nama', 'NIK', 'Pitstop', 'Nilai', 'Penilai'];
foreach ($detailHeaders as $i => $h) {
$detailSheet->setCellValueByColumnAndRow($i + 1, 1, $h);
}
$detailSheet->getStyle('A1:F1')->getFont()->setBold(true);
$pegawaiById = collect($rows)->keyBy('id');
$detailRow = 2;
$lastPegawaiId = null;
foreach ($praakreRows as $d) {
if (!is_null($lastPegawaiId) && (string) $lastPegawaiId !== (string) $d->pegawai_id) {
$detailSheet->getStyle('A' . $detailRow . ':F' . $detailRow)
->applyFromArray([
'borders' => [
'top' => [
'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN,
'color' => ['argb' => 'FF999999'],
],
],
'fill' => [
'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID,
'startColor' => ['argb' => 'FF1E88E5'],
],
]);
$detailRow++;
}
$pg = $pegawaiById->get($d->pegawai_id);
$detailSheet->setCellValueByColumnAndRow(1, $detailRow, (string) $tipe);
$detailSheet->setCellValueByColumnAndRow(2, $detailRow, (string) data_get($pg, 'nama', '-'));
$detailSheet->setCellValueExplicitByColumnAndRow(3, $detailRow, (string) data_get($pg, 'nik', '-'), DataType::TYPE_STRING);
$detailSheet->setCellValueByColumnAndRow(4, $detailRow, (string) ($d->pitstop_nama ?? '-'));
$detailSheet->setCellValueByColumnAndRow(5, $detailRow, (string) ($d->nilai ?? ''));
$detailSheet->setCellValueByColumnAndRow(6, $detailRow, (string) ($d->penilai_nama ?? '-'));
$detailRow++;
$lastPegawaiId = $d->pegawai_id;
}
foreach (range('A', 'F') as $col) {
$detailSheet->getColumnDimension($col)->setAutoSize(true);
}
$spreadsheet->setActiveSheetIndex(0);
});
}
@ -1271,6 +1700,9 @@ class PitStopController extends Controller
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->where('p.pegawai_id', $pegawaiId)
// ->where('p.status', 'lulus')
->whereNotNull('m.id')
@ -1279,6 +1711,7 @@ class PitStopController extends Controller
'p.masterpitstop_id',
DB::raw("coalesce(m.nama, '-') as step_nama"),
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
DB::raw("to_char(p.created_at, 'DD-MM-YYYY HH24:MI') as created_at"),
])
->orderByDesc('p.id')
@ -1313,6 +1746,9 @@ class PitStopController extends Controller
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->where('p.tipe_karyawan', 'luar')
->where('p.pegawai_id', $pegawaiId)
->whereNotNull('m.id')
@ -1321,6 +1757,7 @@ class PitStopController extends Controller
'p.masterpitstop_id',
DB::raw("coalesce(m.nama, '-') as step_nama"),
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
DB::raw("to_char(p.created_at, 'DD-MM-YYYY HH24:MI') as created_at"),
])
->orderByDesc('p.id')
@ -1503,6 +1940,9 @@ class PitStopController extends Controller
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->where('p.pegawai_id', $pegawaiId)
->whereNotNull('m.id')
->select([
@ -1510,6 +1950,7 @@ class PitStopController extends Controller
'p.masterpitstop_id',
DB::raw("coalesce(m.nama, '-') as step_nama"),
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
DB::raw("to_char(p.created_at, 'DD-MM-YYYY HH24:MI') as created_at"),
])
->orderByDesc('p.id')
@ -1544,6 +1985,9 @@ class PitStopController extends Controller
$join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id')
->where('m.statusenabled', true);
})
->leftJoin('public.pegawai_m as pen', function ($join) {
$join->on(DB::raw('pen.id::text'), '=', 'p.action_at');
})
->where('p.tipe_karyawan', 'luar')
->where('p.status', 'lulus')
->where('p.pegawai_id', $pegawaiId)
@ -1553,6 +1997,8 @@ class PitStopController extends Controller
'p.masterpitstop_id',
DB::raw("coalesce(m.nama, '-') as step_nama"),
'p.status',
'p.nilai',
DB::raw("coalesce(pen.namalengkap, '-') as penilai_nama"),
DB::raw("to_char(p.created_at, 'DD-MM-YYYY HH24:MI') as created_at"),
])
->orderByDesc('p.id')

View File

@ -20,10 +20,10 @@
.right-panel {
background: #ffffff;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
}
.card-custom {
@ -51,49 +51,50 @@
.hide-xs {
display: none !important;
}
.right-panel {
min-height: auto;
padding: 20px 16px;
align-items: flex-start;
}
.left-panel {
min-height: auto;
padding: 16px;
}
.login-hero-title {
font-size: 22px;
line-height: 1.25;
}
.login-monitor-card {
border-radius: 12px;
box-shadow: 0 8px 25px rgba(0,0,0,0.06);
border: none;
}
#searchAllKaryawan {
width: 100% !important;
}
}
@media (min-width: 576px) {
.right-panel {
min-height: 100vh;
}
}
</style>
@endsection
@section('content')
<div class="container-fluid">
<div class="row">
<div class="col-md-8 left-panel d-flex align-items-center justify-content-center">
<div class="d-flex align-items-center justify-content-center h-75 flex-column">
<div class="card h-150 flex-column">
<div class="card-body table-responsive">
<div class="d-flex justify-content-between align-items-center mb-4">
<h4 class="fw-bold mb-0">Monitoring Pra Akreditasi</h4>
<input type="text" id="searchAllKaryawan"
class="form-control w-250px"
placeholder="Cari karyawan...">
</div>
<table id="tblAllKaryawan" class="table align-middle table-row-dashed fs-6 gy-3 w-100">
<thead>
<tr class="text-muted fw-semibold fs-7 text-uppercase gs-0">
<th>Nama</th>
<th>Unit / Tipe</th>
<th style="width: 320px">Progress</th>
<th>Belum dikerjakan</th>
<th class="text-end">Jenis</th>
<th class="text-end">Aksi</th>
</tr>
</thead>
<tbody class="fw-semibold text-gray-800"></tbody>
</table>
</div>
<div class="row g-0">
<div class="col-12 col-md-4 right-panel order-1 order-md-2">
<div class="w-100" style="max-width: 440px;">
<div class="text-center mb-8">
<img src="{{ asset('assets/img/logo-fullname.png') }}" alt="Logo" class="img-fluid" style="max-height: 72px;">
<h1 class="mt-6 mb-0 fw-bold login-hero-title">Login Admin Pra Akreditasi</h1>
<div class="text-muted mt-2">Masuk untuk mengelola penilaian dan monitoring.</div>
</div>
</div>
</div>
<div class="col-md-4 right-panel">
<div class="d-flex align-items-center justify-content-center h-100 flex-column">
<center>
<img src="{{ asset('assets/img/logo-fullname.png') }}" alt="" srcset="" class="w-50">
<h1 class="mt-5">Login Admin Pra Akreditasi</h1>
</center>
<form id="form_login" class="form mt-10 w-75" action="/login" autocomplete="off" method="POST">
<div class="card card-custom">
<div class="card-body p-8 p-md-10">
<form id="form_login" class="form" action="/login" autocomplete="off" method="POST">
@csrf
<div class="fv-row mb-7">
<label class="required fw-semibold fs-6 mb-2">Username</label>
@ -116,7 +117,36 @@
Please wait... <span class="spinner-border spinner-border-sm align-middle ms-2"></span>
</span>
</button>
</form>
</form>
</div>
</div>
</div>
</div>
<div class="col-12 col-md-8 left-panel order-2 order-md-1 d-flex align-items-start align-items-md-center justify-content-center">
<div class="w-100" style="max-width: 980px;">
<div class="card login-monitor-card">
<div class="card-body table-responsive">
<div class="d-flex flex-column flex-sm-row justify-content-between align-items-start align-items-sm-center gap-3 mb-4">
<h4 class="fw-bold mb-0">Monitoring Pra Akreditasi</h4>
<input type="text" id="searchAllKaryawan"
class="form-control w-250px"
placeholder="Cari karyawan...">
</div>
<table id="tblAllKaryawan" class="table align-middle table-row-dashed fs-6 gy-3 w-100">
<thead>
<tr class="text-muted fw-semibold fs-7 text-uppercase gs-0">
<th>Nama</th>
<th>Unit / Tipe</th>
<th style="width: 320px">Progress</th>
<th>Belum dikerjakan</th>
<th class="text-end">Jenis</th>
<th class="text-end">Aksi</th>
</tr>
</thead>
<tbody class="fw-semibold text-gray-800"></tbody>
</table>
</div>
</div>
</div>
</div>
</div>

View File

@ -1,9 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<html lang="id" translate="no" class="notranslate">
<!--begin::Head-->
<head><base href=""/>
<title>Pra Akreditasi {{ $title ? "| {$title}" : ' '}}</title>
<meta property="og:type" content="article" />
<meta name="google" content="notranslate">
<meta http-equiv="Content-Language" content="id">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" />

View File

@ -1,9 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<html lang="id" translate="no" class="notranslate">
<!--begin::Head-->
<head><base href=""/>
<title>Pra Akreditasi RSAB Harapan Kita</title>
<meta property="og:type" content="article" />
<meta name="google" content="notranslate">
<meta http-equiv="Content-Language" content="id">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="canonical" />

View File

@ -67,6 +67,14 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<style>
.modal .cell-ellipsis {
max-width: 220px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<div class="text-muted mb-4" id="detailNamaLuar"></div>
<div class="table-responsive">
<table class="table align-middle table-row-dashed fs-6 gy-3">
@ -74,6 +82,7 @@
<tr class="text-muted fw-semibold fs-7 text-uppercase gs-0">
<th>Nama Step</th>
<th>Nilai</th>
<th style="width: 240px">Pemberi Nilai</th>
<th class="text-end">Waktu</th>
</tr>
</thead>
@ -135,6 +144,7 @@
<tr>
<td>${escapeHtml(r.step_nama ?? '-')}</td>
<td>${r.nilai}</td>
<td><span class="d-inline-block cell-ellipsis" title="${escapeHtml(r.penilai_nama ?? '-')}">${escapeHtml(r.penilai_nama ?? '-')}</span></td>
<td class="text-end">${escapeHtml(waktu)}</td>
</tr>`;
})

View File

@ -151,6 +151,14 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<style>
.modal .cell-ellipsis {
max-width: 220px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<div class="text-muted mb-4" id="allDetailNama"></div>
<div class="table-responsive">
<table class="table align-middle table-row-dashed fs-6 gy-3">
@ -158,6 +166,7 @@
<tr class="text-muted fw-semibold fs-7 text-uppercase gs-0">
<th>Nama Step</th>
<th>Nilai</th>
<th style="width: 240px">Pemberi Nilai</th>
<th class="text-end">Waktu</th>
</tr>
</thead>
@ -223,6 +232,7 @@
<tr>
<td>${escapeHtml(r.step_nama ?? '-')}</td>
<td>${r.nilai}</td>
<td><span class="d-inline-block cell-ellipsis" title="${escapeHtml(r.penilai_nama ?? '-')}">${escapeHtml(r.penilai_nama ?? '-')}</span></td>
<td class="text-end">${escapeHtml(waktu)}</td>
</tr>`;
})

View File

@ -67,6 +67,14 @@
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<style>
.modal .cell-ellipsis {
max-width: 220px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
</style>
<div class="text-muted mb-4" id="detailNama"></div>
<div class="table-responsive">
<table class="table align-middle table-row-dashed fs-6 gy-3">
@ -74,6 +82,7 @@
<tr class="text-muted fw-semibold fs-7 text-uppercase gs-0">
<th>Nama Step</th>
<th>Nilai</th>
<th style="width: 240px">Pemberi Nilai</th>
<th class="text-end">Waktu</th>
</tr>
</thead>
@ -140,6 +149,7 @@
<tr>
<td>${escapeHtml(r.step_nama ?? '-')}</td>
<td>${r.nilai}</td>
<td><span class="d-inline-block cell-ellipsis" title="${escapeHtml(r.penilai_nama ?? '-')}">${escapeHtml(r.penilai_nama ?? '-')}</span></td>
<td class="text-end">${escapeHtml(waktu)}</td>
</tr>`;
})