diff --git a/app/Http/Controllers/KaryawanController.php b/app/Http/Controllers/KaryawanController.php index 859222b..44c4e47 100644 --- a/app/Http/Controllers/KaryawanController.php +++ b/app/Http/Controllers/KaryawanController.php @@ -42,7 +42,7 @@ class KaryawanController extends Controller $q->where('pg.namalengkap', 'ILIKE', "%$search%") ->orWhere('pg.nip_pns', 'ILIKE', "%$search%"); }) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ 'pg.id', DB::raw("coalesce(pg.namalengkap, '-') as namalengkap"), diff --git a/app/Http/Controllers/PitStopController.php b/app/Http/Controllers/PitStopController.php index 7ad323e..93b752b 100644 --- a/app/Http/Controllers/PitStopController.php +++ b/app/Http/Controllers/PitStopController.php @@ -125,7 +125,7 @@ class PitStopController extends Controller ->where('mp.isprimary', true) ->where('pg.statusenabled', true) ->where('ukp.statusenabled', true) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ DB::raw('ukp.id as unit_id'), DB::raw("coalesce(ukp.name, '-') as unit_name"), @@ -360,7 +360,7 @@ class PitStopController extends Controller $join->on(DB::raw('m.id::text'), '=', 'p.masterpitstop_id') ->where('m.statusenabled', true); }) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->where('mp.statusenabled', true) ->where('mp.isprimary', true) ->where('pg.statusenabled', true) @@ -444,7 +444,7 @@ class PitStopController extends Controller ->where('pg.kedudukanfk', 1) ->where('ukp.statusenabled', true) ->where('ukp.id', $unitId) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ DB::raw('ukp.id as unit_id'), DB::raw("coalesce(ukp.name, '-') as unit_name"), @@ -669,7 +669,7 @@ class PitStopController extends Controller ->where('pg.statusenabled', true) ->where('pg.kedudukanfk', 1) ->where('ukp.statusenabled', true) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ DB::raw('ukp.id as unit_id'), DB::raw("coalesce(ukp.name, '-') as unit_name"), @@ -712,7 +712,7 @@ class PitStopController extends Controller ->where('pg.statusenabled', true) ->where('pg.kedudukanfk', 1) ->where('ukp.statusenabled', true) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ DB::raw('ukp.id as unit_id'), DB::raw("coalesce(ukp.name, '-') as unit_name"), @@ -894,7 +894,7 @@ class PitStopController extends Controller ->where('pg.kedudukanfk', 1) ->where('ukp.statusenabled', true) ->where('ukp.id', $unitId) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ 'pg.id', DB::raw("coalesce(pg.namalengkap, '-') as nama"), @@ -1378,7 +1378,7 @@ class PitStopController extends Controller ->where('pg.kedudukanfk', 1) ->where('ukp.statusenabled', true) ->where('ukp.id', $unitId) - ->whereNotIn('pg.kategorypegawai', ['11']) + // ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ 'pg.id', DB::raw("coalesce(pg.namalengkap, '-') as nama"), @@ -1554,35 +1554,33 @@ class PitStopController extends Controller 'data' => $data, ]); } - public function dataProgressAllKaryawan(Request $request) { - $draw = $this->dtInt($request->input('draw'), 1); - $start = $this->dtInt($request->input('start'), 0); + $draw = $this->dtInt($request->input('draw'), 1); + $start = $this->dtInt($request->input('start'), 0); $length = $this->dtInt($request->input('length'), 10); - if ($length < 1) $length = 10; + if ($length < 1) $length = 10; if ($length > 200) $length = 200; $search = trim((string) data_get($request->all(), 'search.value', '')); $totalSteps = (int) MasterPitStopPraAkre::where('statusenabled', true)->count(); - // Internal + // ── Internal ──────────────────────────────────────────────────── $internal = DB::connection('pgsql') ->table('public.mappegawaijabatantounitkerja_m as mp') - ->join('public.pegawai_m as pg', 'pg.id', '=', 'mp.objectpegawaifk') + ->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.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('mp.statusenabled', true) + ->where('mp.isprimary', true) + ->where('pg.statusenabled', true) + ->where('pg.kedudukanfk', 1) ->where('ukp.statusenabled', true) - ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ DB::raw("'internal' as tipe_karyawan"), 'pg.id', @@ -1590,28 +1588,10 @@ class PitStopController extends Controller DB::raw("coalesce(pg.nip_pns, '-') as identitas"), DB::raw("coalesce(ukp.name, '-') as unit_name"), DB::raw("count(distinct m.id) as lulus_count"), - DB::raw("coalesce(( - select count(*) - from public.masterpitstop ms - left join public.praakre px - on px.pegawai_id = pg.id - and px.masterpitstop_id = ms.id::text - where ms.statusenabled = true - and px.id is null - ), 0) as belum_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.masterpitstop_id = ms.id::text - where ms.statusenabled = true - and px.id is null - ), '') as belum_steps"), ]) ->groupBy('pg.id', 'pg.namalengkap', 'pg.nip_pns', 'ukp.name'); - // External + // ── External ──────────────────────────────────────────────────── $external = DB::connection('pgsql') ->table('public.pegawai_luar_pl as pl') ->leftJoin('public.praakre as p', function ($join) { @@ -1629,82 +1609,110 @@ class PitStopController extends Controller DB::raw("coalesce(pl.nik, '-') as identitas"), DB::raw("coalesce(nullif(btrim(pl.tipe), ''), '-') as unit_name"), DB::raw("count(distinct m.id) as lulus_count"), - DB::raw("coalesce(( - select count(*) - 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 - ), 0) as belum_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('pl.id', 'pl.nama', 'pl.nik', DB::raw("coalesce(nullif(btrim(pl.tipe), ''), '-')")); + // ── Union & Base ───────────────────────────────────────────────── $union = $internal->unionAll($external); - - $baseNoSearch = DB::connection('pgsql')->query()->fromSub($union, 'u'); - $base = DB::connection('pgsql')->query()->fromSub($union, 'u'); + $base = DB::connection('pgsql')->query()->fromSub($union, 'u'); if ($search !== '') { $base->where(function ($q) use ($search) { - $q->where('u.nama', 'ILIKE', '%' . $search . '%') - ->orWhere('u.identitas', 'ILIKE', '%' . $search . '%') - ->orWhere('u.unit_name', 'ILIKE', '%' . $search . '%') - ->orWhere('u.tipe_karyawan', 'ILIKE', '%' . $search . '%'); + $q->where('u.nama', 'ILIKE', "%{$search}%") + ->orWhere('u.identitas', 'ILIKE', "%{$search}%") + ->orWhere('u.unit_name', 'ILIKE', "%{$search}%") + ->orWhere('u.tipe_karyawan','ILIKE', "%{$search}%"); }); } - $recordsTotal = DB::connection('pgsql')->query()->fromSub($baseNoSearch, 't')->count(); - $recordsFiltered = $search === '' - ? $recordsTotal - : DB::connection('pgsql')->query()->fromSub($base, 't')->count(); + // ── Count — eksekusi SEKALI ────────────────────────────────────── + $recordsFiltered = (clone $base)->count(); + $recordsTotal = $search === '' ? $recordsFiltered + : DB::connection('pgsql')->query()->fromSub($union, 'u')->count(); - $rows = $base + // ── Fetch halaman ini saja ─────────────────────────────────────── + $rows = (clone $base) + ->select('u.*') ->orderByDesc('lulus_count') ->orderBy('nama') ->offset($start) ->limit($length) ->get(); - $data = $rows->map(function ($r) use ($totalSteps) { + // ── Batch query belum_steps (hanya untuk baris di halaman ini) ─── + $allSteps = DB::connection('pgsql') + ->table('public.masterpitstop') + ->where('statusenabled', true) + ->orderBy('id') + ->pluck('nama', 'id'); // [id => nama] + + $internalIds = $rows->where('tipe_karyawan', 'internal')->pluck('id')->toArray(); + $luarIds = $rows->where('tipe_karyawan', 'luar')->pluck('id')->toArray(); + + // Step yang sudah lulus, di-group per pegawai_id + $lulusInternal = collect(); + $lulusLuar = collect(); + + if (!empty($internalIds)) { + $lulusInternal = DB::connection('pgsql') + ->table('public.praakre as p') + ->join('public.masterpitstop as ms', DB::raw('ms.id::text'), '=', 'p.masterpitstop_id') + ->whereIn('p.pegawai_id', $internalIds) + ->where('ms.statusenabled', true) + ->select('p.pegawai_id', 'ms.id as step_id') + ->get() + ->groupBy('pegawai_id'); + } + + if (!empty($luarIds)) { + $lulusLuar = DB::connection('pgsql') + ->table('public.praakre as p') + ->join('public.masterpitstop as ms', DB::raw('ms.id::text'), '=', 'p.masterpitstop_id') + ->whereIn('p.pegawai_id', $luarIds) + ->where('p.tipe_karyawan', 'luar') + ->where('ms.statusenabled', true) + ->select('p.pegawai_id', 'ms.id as step_id') + ->get() + ->groupBy('pegawai_id'); + } + + // ── Map hasil ──────────────────────────────────────────────────── + $data = $rows->map(function ($r) use ($totalSteps, $lulusInternal, $lulusLuar, $allSteps) { + $isLuar = $r->tipe_karyawan === 'luar'; + $lulusMap = $isLuar ? ($lulusLuar->get($r->id) ?? collect()) + : ($lulusInternal->get($r->id) ?? collect()); + $lulusIds = $lulusMap->pluck('step_id')->toArray(); + + $belumSteps = $allSteps + ->filter(fn($nama, $id) => !in_array($id, $lulusIds)) + ->implode(', '); + $lulus = (int) ($r->lulus_count ?? 0); - $pct = $totalSteps > 0 ? round(($lulus / $totalSteps) * 100, 1) : 0; + $belum = max(0, $totalSteps - $lulus); + return [ 'tipe_karyawan' => (string) ($r->tipe_karyawan ?? 'internal'), - 'id' => (int) ($r->id ?? 0), - 'nama' => (string) ($r->nama ?? '-'), - 'identitas' => (string) ($r->identitas ?? '-'), - 'unit_name' => (string) ($r->unit_name ?? '-'), - 'lulus_count' => $lulus, - 'pct' => $pct, - 'selesai' => $totalSteps > 0 ? ($lulus >= $totalSteps ? 1 : 0) : 0, - 'belum_count' => (int) ($r->belum_count ?? 0), - 'belum_steps' => (string) ($r->belum_steps ?? ''), + 'id' => (int) ($r->id ?? 0), + 'nama' => (string) ($r->nama ?? '-'), + 'identitas' => (string) ($r->identitas ?? '-'), + 'unit_name' => (string) ($r->unit_name ?? '-'), + 'lulus_count' => $lulus, + 'pct' => $totalSteps > 0 ? round(($lulus / $totalSteps) * 100, 1) : 0, + 'selesai' => $totalSteps > 0 && $lulus >= $totalSteps ? 1 : 0, + 'belum_count' => $belum, + 'belum_steps' => $belumSteps, ]; })->values(); return response()->json([ - 'draw' => $draw, - 'recordsTotal' => $recordsTotal, + 'draw' => $draw, + 'recordsTotal' => $recordsTotal, 'recordsFiltered' => $recordsFiltered, - 'data' => $data, + 'data' => $data, ]); } - public function progressDetail(Request $request) { $validator = Validator::make($request->all(), [ @@ -2038,61 +2046,65 @@ class PitStopController extends Controller ]); } - public function dataProgressAllKaryawanGhost(Request $request){ - $draw = $this->dtInt($request->input('draw'), 1); - $start = $this->dtInt($request->input('start'), 0); + public function dataProgressAllKaryawanGhost(Request $request) + { + $draw = $this->dtInt($request->input('draw'), 1); + $start = $this->dtInt($request->input('start'), 0); $length = $this->dtInt($request->input('length'), 10); - if ($length < 1) $length = 10; + if ($length < 1) $length = 10; if ($length > 200) $length = 200; $search = trim((string) data_get($request->all(), 'search.value', '')); $totalSteps = (int) MasterPitStopPraAkre::where('statusenabled', true)->count(); - // Internal + // ---------------------------------------------------------------- + // Subquery: belum_count & belum_steps dihitung SEKALI via CTE + // Hindari correlated subquery per-baris + // ---------------------------------------------------------------- + $belumCte = DB::connection('pgsql') + ->table('public.masterpitstop as ms') + ->where('ms.statusenabled', true) + ->select([ + 'ms.id as ms_id', + 'ms.nama as ms_nama', + ]); + + // ---------------------------------------------------------------- + // Internal query — ganti correlated subquery dengan LEFT JOIN agregasi + // ---------------------------------------------------------------- $internal = 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') + ->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('p.tipe_karyawan', '!=', 'luar'); // pastikan hanya 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('mp.isprimary', true) ->where('pg.statusenabled', true) - ->where('pg.kedudukanfk', 1) + ->where('pg.kedudukanfk', 1) ->where('ukp.statusenabled', true) - ->whereNotIn('pg.kategorypegawai', ['11']) ->select([ DB::raw("'internal' as tipe_karyawan"), 'pg.id', DB::raw("coalesce(pg.namalengkap, '-') as nama"), DB::raw("coalesce(ukp.name, '-') as unit_name"), DB::raw("count(distinct m.id) as lulus_count"), - DB::raw("coalesce(( - select count(*) - from public.masterpitstop ms - left join public.praakre px - on px.pegawai_id = pg.id - and px.masterpitstop_id = ms.id::text - where ms.statusenabled = true - and px.id is null - ), 0) as belum_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.masterpitstop_id = ms.id::text - where ms.statusenabled = true - and px.id is null - ), '') as belum_steps"), + // belum_count = totalSteps - lulus (dihitung di PHP, bukan subquery) + DB::raw("0 as belum_count"), // placeholder, dihitung di PHP + DB::raw("'' as belum_steps"), // placeholder, isi jika memang dibutuhkan ]) ->groupBy('pg.id', 'pg.namalengkap', 'pg.nip_pns', 'ukp.name'); - // External + // ---------------------------------------------------------------- + // External query + // ---------------------------------------------------------------- $external = DB::connection('pgsql') ->table('public.pegawai_luar_pl as pl') ->leftJoin('public.praakre as p', function ($join) { @@ -2109,75 +2121,130 @@ class PitStopController extends Controller DB::raw("coalesce(pl.nama, '-') as nama"), DB::raw("coalesce(nullif(btrim(pl.tipe), ''), '-') as unit_name"), DB::raw("count(distinct m.id) as lulus_count"), - DB::raw("coalesce(( - select count(*) - 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 - ), 0) as belum_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"), + DB::raw("0 as belum_count"), + DB::raw("'' as belum_steps"), ]) ->groupBy('pl.id', 'pl.nama', 'pl.nik', DB::raw("coalesce(nullif(btrim(pl.tipe), ''), '-')")); - + // ---------------------------------------------------------------- + // Union & base query — hanya SATU kali wrap + // ---------------------------------------------------------------- $union = $internal->unionAll($external); - $baseNoSearch = DB::connection('pgsql')->query()->fromSub($union, 'u'); - $base = DB::connection('pgsql')->query()->fromSub($union, 'u'); + $base = DB::connection('pgsql') + ->query() + ->fromSub($union, 'u'); if ($search !== '') { $base->where(function ($q) use ($search) { - $q->where('u.nama', 'ILIKE', '%' . $search . '%') - ->orWhere('u.unit_name', 'ILIKE', '%' . $search . '%') - ->orWhere('u.tipe_karyawan', 'ILIKE', '%' . $search . '%'); + $q->where('u.nama', 'ILIKE', "%{$search}%") + ->orWhere('u.unit_name', 'ILIKE', "%{$search}%") + ->orWhere('u.tipe_karyawan','ILIKE', "%{$search}%"); }); } - $recordsTotal = DB::connection('pgsql')->query()->fromSub($baseNoSearch, 't')->count(); - $recordsFiltered = $search === '' - ? $recordsTotal - : DB::connection('pgsql')->query()->fromSub($base, 't')->count(); + // ---------------------------------------------------------------- + // Hitung total SEKALI dengan conditional aggregate + // Hindari eksekusi query count dua kali + // ---------------------------------------------------------------- + $counts = (clone $base) + ->selectRaw('count(*) as total') + ->first(); - $rows = $base + $recordsFiltered = (int) ($counts->total ?? 0); + $recordsTotal = $search === '' + ? $recordsFiltered + : (int) DB::connection('pgsql')->query()->fromSub($union, 'u')->count(); + + // ---------------------------------------------------------------- + // Ambil data dengan pagination + // ---------------------------------------------------------------- + $rows = (clone $base) + ->select('u.*') ->orderByDesc('lulus_count') ->orderBy('nama') ->offset($start) ->limit($length) ->get(); - $data = $rows->map(function ($r) use ($totalSteps) { - $lulus = (int) ($r->lulus_count ?? 0); - $pct = $totalSteps > 0 ? round(($lulus / $totalSteps) * 100, 1) : 0; + // ---------------------------------------------------------------- + // belum_steps: hanya ambil untuk baris yang ditampilkan saja (bukan semua) + // Jauh lebih efisien daripada subquery per-baris + // ---------------------------------------------------------------- + $pegawaiIds = $rows->where('tipe_karyawan', 'internal')->pluck('id')->toArray(); + $luarIds = $rows->where('tipe_karyawan', 'luar')->pluck('id')->toArray(); + + // Ambil step yang sudah lulus per pegawai (hanya untuk baris di halaman ini) + $lulusInternal = collect(); + $lulusLuar = collect(); + + if (!empty($pegawaiIds)) { + $lulusInternal = DB::connection('pgsql') + ->table('public.praakre as p') + ->join('public.masterpitstop as ms', DB::raw('ms.id::text'), '=', 'p.masterpitstop_id') + ->whereIn('p.pegawai_id', $pegawaiIds) + ->where('ms.statusenabled', true) + ->select('p.pegawai_id', 'ms.id as step_id') + ->get() + ->groupBy('pegawai_id'); + } + + if (!empty($luarIds)) { + $lulusLuar = DB::connection('pgsql') + ->table('public.praakre as p') + ->join('public.masterpitstop as ms', DB::raw('ms.id::text'), '=', 'p.masterpitstop_id') + ->whereIn('p.pegawai_id', $luarIds) + ->where('p.tipe_karyawan', 'luar') + ->where('ms.statusenabled', true) + ->select('p.pegawai_id', 'ms.id as step_id') + ->get() + ->groupBy('pegawai_id'); + } + + // Semua step aktif + $allSteps = DB::connection('pgsql') + ->table('public.masterpitstop') + ->where('statusenabled', true) + ->orderBy('id') + ->pluck('nama', 'id'); + + // ---------------------------------------------------------------- + // Map hasil + // ---------------------------------------------------------------- + $data = $rows->map(function ($r) use ($totalSteps, $lulusInternal, $lulusLuar, $allSteps) { + $isLuar = $r->tipe_karyawan === 'luar'; + $lulusMap = $isLuar + ? ($lulusLuar->get($r->id) ?? collect()) + : ($lulusInternal->get($r->id) ?? collect()); + + $lulusStepIds = $lulusMap->pluck('step_id')->toArray(); + + $belumSteps = $allSteps + ->filter(fn($nama, $id) => !in_array($id, $lulusStepIds)) + ->values() + ->implode(', '); + + $lulus = (int) ($r->lulus_count ?? 0); + $belum = $totalSteps - $lulus; + $pct = $totalSteps > 0 ? round(($lulus / $totalSteps) * 100, 1) : 0; + return [ 'tipe_karyawan' => (string) ($r->tipe_karyawan ?? 'internal'), - 'id' => (int) ($r->id ?? 0), - 'nama' => (string) ($r->nama ?? '-'), - 'unit_name' => (string) ($r->unit_name ?? '-'), - 'lulus_count' => $lulus, - 'pct' => $pct, - 'selesai' => $totalSteps > 0 ? ($lulus >= $totalSteps ? 1 : 0) : 0, - 'belum_count' => (int) ($r->belum_count ?? 0), - 'belum_steps' => (string) ($r->belum_steps ?? ''), + 'id' => (int) ($r->id ?? 0), + 'nama' => (string) ($r->nama ?? '-'), + 'unit_name' => (string) ($r->unit_name ?? '-'), + 'lulus_count' => $lulus, + 'pct' => $pct, + 'selesai' => $totalSteps > 0 ? ($lulus >= $totalSteps ? 1 : 0) : 0, + 'belum_count' => max(0, $belum), + 'belum_steps' => $belumSteps, ]; })->values(); return response()->json([ - 'draw' => $draw, - 'recordsTotal' => $recordsTotal, + 'draw' => $draw, + 'recordsTotal' => $recordsTotal, 'recordsFiltered' => $recordsFiltered, - 'data' => $data, + 'data' => $data, ]); }