feat(lpj): Perbaiki ekspor, pencarian, validasi tanggal, transaksi, logging, dan UI

- ActivityController: tambah default order `nomor_registrasi` desc; rapikan komentar & alur sorting
- LaporanHasilPenilaianJaminanInternalExternalController: pencarian debitur case-insensitive via `LOWER(name)`; normalisasi angka LPJ (luas_tanah, nilai_bangunan, likuidasi, NPW); perapihan spacing
- LaporanPenilaiJaminanController: validasi `start_date`/`end_date` dan buat nama file ekspor dinamis via `createNameLaporan`; gunakan `LaporanPenilaiJaminanExport($request)`; helper `getBranchId`
- LaporanPenilaianJaminanController: standarisasi respons JSON datatables; tambah `export(Request)` dengan nama `laporan_penilaian_jaminan_<start>_<end>.xlsx`
- NilaiPlafondController: bungkus proses datatables dalam transaksi DB (commit/rollback) dengan try/catch; tambah logging info/error; rapikan dan standarisasi respons JSON
- PenilaiController: map data pembanding ke `pembanding1/2/3`; tambah `print_out_laporan` dan `showLaporanInspeksi` (penentuan route back); stub `showInspectionReportReview`; perapihan minor
- Views debitur/components/debitur: perbaiki closing textarea, konsistensi event listener `function ()`, rapikan markup error
- Views debitur/components/jaminan: fallback `dokumen_nomor[$index] ?? ''` untuk hindari undefined index
- Views laporan/index: akses aman dengan optional chaining `?.`, fallback tanggal pada `formatDate`, akses `nilaiPlafond` aman
- Views laporan-penilai-jaminan/index + show: JS toggle tab (Laporan vs Hasil Inspeksi), CSS `hidden-tab`, gaya floating button, perapihan
- Views debitur/index: rapikan directive `@if` spacing pada tombol tambah
- Views noc/penyelesaian: perbaiki route key ke `noc.datatables.penyelesaian`
This commit is contained in:
Daeng Deni Mardaeni
2025-11-10 20:47:56 +07:00
parent 42d6e06a48
commit c153990c52
13 changed files with 964 additions and 623 deletions

View File

@@ -17,224 +17,238 @@
public $user;
/**
* Tampilkan halaman daftar Nilai Plafond.
*
* @return \Illuminate\Contracts\View\View
* Menampilkan halaman daftar Nilai Plafond.
* Log setiap akses dan sebelum return view.
*/
public function index()
{
Log::info('[NilaiPlafondController@index] Return view index nilai_plafond');
return view('lpj::nilai_plafond.index');
Log::info('NilaiPlafondController@index: akses halaman index');
return \view('lpj::nilai_plafond.index');
}
/**
* Simpan data Nilai Plafond baru ke database.
* Menggunakan transaksi untuk menjamin konsistensi data.
*
* @param NilaiPlafondRequest $request
* @return \Illuminate\Http\RedirectResponse
* Menyimpan data Nilai Plafond baru termasuk field biaya.
* Gunakan validasi dari NilaiPlafondRequest, log proses, dan bungkus dengan transaksi DB.
*/
public function store(NilaiPlafondRequest $request)
{
Log::info('NilaiPlafondController@store: mulai proses simpan');
$validate = $request->validated();
if ($validate) {
DB::beginTransaction();
try {
// Save to database
$created = NilaiPlafond::create($validate);
$record = NilaiPlafond::create($validate);
DB::commit();
Log::info('[NilaiPlafondController@store] NilaiPlafond created', ['id' => $created->id, 'payload' => $validate]);
return redirect()
Log::info('NilaiPlafondController@store: simpan berhasil', ['id' => $record->id]);
return \redirect()
->route('basicdata.nilai-plafond.index')
->with('success', 'Nilai Plafond berhasil dibuat');
} catch (Exception $e) {
DB::rollBack();
Log::error('[NilaiPlafondController@store] Failed to create nilai plafond', ['error' => $e->getMessage(), 'payload' => $validate]);
return redirect()
Log::error('NilaiPlafondController@store: simpan gagal', ['error' => $e->getMessage()]);
return \redirect()
->route('basicdata.nilai-plafond.create')
->with('error', 'Gagal membuat Nilai Plafond');
}
}
Log::warning('[NilaiPlafondController@store] Validation failed');
return redirect()
->route('basicdata.nilai-plafond.create')
->with('error', 'Validasi gagal');
}
/**
* Tampilkan form pembuatan Nilai Plafond.
*
* @return \Illuminate\Contracts\View\View
* Menampilkan form pembuatan Nilai Plafond.
* Log akses sebelum return view.
*/
public function create()
{
Log::info('[NilaiPlafondController@create] Return view create nilai_plafond');
return view('lpj::nilai_plafond.create');
Log::info('NilaiPlafondController@create: akses halaman create');
return \view('lpj::nilai_plafond.create');
}
/**
* Tampilkan form edit Nilai Plafond berdasarkan ID.
*
* @param int $id
* @return \Illuminate\Contracts\View\View
* Menampilkan form edit Nilai Plafond berdasarkan ID.
* Gunakan transaksi untuk pembacaan data dan logging.
*/
public function edit($id)
{
$nilaiPlafond = NilaiPlafond::find($id);
Log::info('[NilaiPlafondController@edit] Return view edit nilai_plafond', ['id' => $id]);
return view('lpj::nilai_plafond.create', compact('nilaiPlafond'));
Log::info('NilaiPlafondController@edit: mulai proses edit', ['id' => $id]);
DB::beginTransaction();
try {
$nilaiPlafond = NilaiPlafond::find($id);
DB::commit();
Log::info('NilaiPlafondController@edit: data ditemukan', ['id' => $id]);
return \view('lpj::nilai_plafond.create', compact('nilaiPlafond'));
} catch (Exception $e) {
DB::rollBack();
Log::error('NilaiPlafondController@edit: gagal mengambil data', ['id' => $id, 'error' => $e->getMessage()]);
return \redirect()
->route('basicdata.nilai-plafond.index')
->with('error', 'Gagal mengambil data Nilai Plafond');
}
}
/**
* Update data Nilai Plafond pada database.
* Menggunakan transaksi untuk menjamin konsistensi data.
*
* @param NilaiPlafondRequest $request
* @param int $id
* @return \Illuminate\Http\RedirectResponse
* Memperbarui data Nilai Plafond termasuk field biaya.
* Validasi input, logging, dan gunakan transaksi DB.
*/
public function update(NilaiPlafondRequest $request, $id)
{
Log::info('NilaiPlafondController@update: mulai proses update', ['id' => $id]);
$validate = $request->validated();
if ($validate) {
DB::beginTransaction();
try {
// Update in database
$nilaiPlafond = NilaiPlafond::find($id);
if (!$nilaiPlafond) {
Log::warning('NilaiPlafondController@update: data tidak ditemukan', ['id' => $id]);
DB::rollBack();
return \redirect()
->route('basicdata.nilai-plafond.index')
->with('error', 'Data Nilai Plafond tidak ditemukan');
}
$nilaiPlafond->update($validate);
DB::commit();
Log::info('[NilaiPlafondController@update] NilaiPlafond updated', ['id' => $id, 'payload' => $validate]);
return redirect()
Log::info('NilaiPlafondController@update: update berhasil', ['id' => $id]);
return \redirect()
->route('basicdata.nilai-plafond.index')
->with('success', 'Nilai Plafond berhasil diperbarui');
} catch (Exception $e) {
DB::rollBack();
Log::error('[NilaiPlafondController@update] Failed to update nilai plafond', ['id' => $id, 'error' => $e->getMessage(), 'payload' => $validate]);
return redirect()
Log::error('NilaiPlafondController@update: update gagal', ['id' => $id, 'error' => $e->getMessage()]);
return \redirect()
->route('basicdata.nilai-plafond.edit', $id)
->with('error', 'Gagal memperbarui Nilai Plafond');
}
}
Log::warning('[NilaiPlafondController@update] Validation failed', ['id' => $id]);
return redirect()
->route('basicdata.nilai-plafond.edit', $id)
->with('error', 'Validasi gagal');
}
/**
* Hapus data Nilai Plafond dari database.
* Menggunakan transaksi untuk menjamin konsistensi data.
*
* @param int $id
* @return void
* Menghapus data Nilai Plafond berdasarkan ID.
* Logging setiap langkah dan gunakan transaksi DB.
*/
public function destroy($id)
{
Log::info('NilaiPlafondController@destroy: mulai proses hapus', ['id' => $id]);
DB::beginTransaction();
try {
// Delete from database
$nilaiPlafond = NilaiPlafond::find($id);
if (!$nilaiPlafond) {
DB::rollBack();
Log::warning('NilaiPlafondController@destroy: data tidak ditemukan', ['id' => $id]);
return \response()->json(['success' => false, 'message' => 'Data Nilai Plafond tidak ditemukan']);
}
$nilaiPlafond->delete();
DB::commit();
Log::info('[NilaiPlafondController@destroy] NilaiPlafond deleted', ['id' => $id]);
echo json_encode(['success' => true, 'message' => 'Nilai Plafond berhasil dihapus']);
Log::info('NilaiPlafondController@destroy: hapus berhasil', ['id' => $id]);
return \response()->json(['success' => true, 'message' => 'Nilai Plafond berhasil dihapus']);
} catch (Exception $e) {
DB::rollBack();
Log::error('[NilaiPlafondController@destroy] Failed to delete nilai plafond', ['id' => $id, 'error' => $e->getMessage()]);
echo json_encode(['success' => false, 'message' => 'Gagal menghapus Nilai Plafond']);
Log::error('NilaiPlafondController@destroy: hapus gagal', ['id' => $id, 'error' => $e->getMessage()]);
return \response()->json(['success' => false, 'message' => 'Gagal menghapus Nilai Plafond']);
}
}
/**
* Endpoint data untuk DataTables custom.
* Menyediakan pencarian, sorting, dan pagination.
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
* Menyediakan data untuk datatables dengan pencarian, sortir, dan paginasi.
* Logging proses dan gunakan transaksi DB untuk konsistensi pembacaan.
*/
public function dataForDatatables(Request $request)
{
Log::info('NilaiPlafondController@dataForDatatables: mulai proses');
if (is_null($this->user) || !$this->user->can('nilai_plafond.view')) {
//abort(403, 'Sorry! You are not allowed to view users.');
}
// Retrieve data from the database
$query = NilaiPlafond::query();
DB::beginTransaction();
try {
// Retrieve data from the database
$query = NilaiPlafond::query();
// Apply search filter if provided
if ($request->has('search') && !empty($request->get('search'))) {
$search = $request->get('search');
$query->where(function ($q) use ($search) {
$q->where('code', 'LIKE', "%$search%");
$q->orWhere('name', 'LIKE', "%$search%");
// CAST ke TEXT agar LIKE bekerja di PostgreSQL
$q->orWhereRaw('CAST(biaya AS TEXT) LIKE ?', ["%$search%"]);
});
// Apply search filter if provided
if ($request->has('search') && !empty($request->get('search'))) {
$search = $request->get('search');
$query->where(function ($q) use ($search) {
$q->where('code', 'LIKE', "%$search%");
$q->orWhere('name', 'LIKE', "%$search%");
});
}
// Apply sorting if provided
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
$order = $request->get('sortOrder');
$column = $request->get('sortField');
$query->orderBy($column, $order);
}
// Get the total count of records
$totalRecords = $query->count();
// Apply pagination if provided
if ($request->has('page') && $request->has('size')) {
$page = $request->get('page');
$size = $request->get('size');
$offset = ($page - 1) * $size; // Calculate the offset
$query->skip($offset)->take($size);
}
// Get the filtered count of records
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query->get();
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = 0 + 1;
DB::commit();
Log::info('NilaiPlafondController@dataForDatatables: proses selesai, mengembalikan data');
// Return the response data as a JSON object
return \response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
'totalCount' => $totalRecords,
'data' => $data,
]);
} catch (Exception $e) {
DB::rollBack();
Log::error('NilaiPlafondController@dataForDatatables: gagal memproses data', ['error' => $e->getMessage()]);
return \response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => 0,
'recordsFiltered' => 0,
'pageCount' => 0,
'page' => 1,
'totalCount' => 0,
'data' => [],
]);
}
// Apply sorting if provided
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
$order = $request->get('sortOrder');
$column = $request->get('sortField');
$query->orderBy($column, $order);
}
// Get the total count of records
$totalRecords = $query->count();
// Apply pagination if provided
if ($request->has('page') && $request->has('size')) {
$page = $request->get('page');
$size = $request->get('size');
$offset = ($page - 1) * $size; // Calculate the offset
$query->skip($offset)->take($size);
}
// Get the filtered count of records
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query->get();
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = 0 + 1;
Log::info('[NilaiPlafondController@dataForDatatables] Return datatables payload', [
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
]);
// Return the response data as a JSON object
return response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
'totalCount' => $totalRecords,
'data' => $data,
]);
}
/**
* Export data Nilai Plafond ke file Excel.
*
* @return \Symfony\Component\HttpFoundation\BinaryFileResponse
* Mengekspor data Nilai Plafond ke Excel.
* Log akses sebelum proses download.
*/
public function export()
{
Log::info('[NilaiPlafondController@export] Export nilai_plafond to Excel');
Log::info('NilaiPlafondController@export: mulai proses export');
return Excel::download(new NilaiPlafondExport, 'nilai_plafond.xlsx');
}
}