From 0c2c0c9e20ddb4cb33157c00f79078dc6e353e6e Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Thu, 17 Jul 2025 09:55:06 +0700 Subject: [PATCH] feat(memo): Tambah halaman preview dan PDF memo penyelesaian Menambahkan fitur preview memo penyelesaian sebelum data disimpan ke database, untuk memastikan user dapat memeriksa kembali detail permohonan dan biaya terkait. Perubahan pada Controller: - Menambahkan method `preview()` di MemoController untuk menampilkan halaman preview memo penyelesaian. - Menambahkan method `generatePdf()` untuk menghasilkan PDF resmi memo dengan format sesuai standar bank. - Mengimplementasikan validasi input lengkap sebelum proses preview dan PDF generation. - Mengintegrasikan helper fungsi terbilang untuk konversi total biaya ke dalam format huruf. Perubahan pada View: - Menambahkan view `preview.blade.php` sebagai template resmi memo penyelesaian dengan layout AGI header, informasi memo, daftar permohonan, total biaya PJ, dan tanda tangan. - Menampilkan tabel daftar permohonan terlampir dengan informasi debitur, cabang, AO, dan nominal biaya PJ. - Menyediakan fitur print preview dengan styling khusus untuk pencetakan dokumen resmi. - Menambahkan UI interaktif untuk mempermudah navigasi sebelum menyimpan data. Perubahan pada Form Create: - Mengubah alur form `create.blade.php` agar mengarahkan ke halaman preview terlebih dahulu sebelum penyimpanan. - Menambahkan tombol untuk melanjutkan proses ke simpan atau kembali ke pengisian form. Routing dan Navigasi: - Menambahkan route baru `memo.preview` untuk preview dan `memo.generate-pdf` untuk generate PDF memo penyelesaian. - Menambahkan breadcrumb untuk halaman preview agar navigasi lebih jelas. Fitur Tambahan: - Implementasi JavaScript untuk interaksi form preview, print action, dan konfirmasi user. - Penambahan fitur terbilang untuk memudahkan verifikasi nominal dalam format teks. - Penanganan error secara komprehensif dengan logging dan rollback pada transaksi jika terjadi kesalahan. - Menjamin data tetap konsisten meskipun user hanya melakukan preview tanpa menyimpan. Tujuan Perubahan: - Memberikan fasilitas preview agar user dapat memverifikasi data sebelum menyimpan memo penyelesaian. - Memastikan output memo dalam format PDF resmi yang sesuai dengan template bank. - Meningkatkan user experience dan mengurangi potensi kesalahan input sebelum proses finalisasi. - Mempermudah proses cetak memo dengan fitur print-friendly dan PDF yang siap dikirim atau diarsipkan. --- app/Http/Controllers/MemoController.php | 143 ++++++++++++ resources/views/memo/create.blade.php | 6 +- resources/views/memo/preview.blade.php | 298 ++++++++++++++++++++++++ routes/breadcrumbs.php | 5 + routes/web.php | 2 + 5 files changed, 451 insertions(+), 3 deletions(-) create mode 100644 resources/views/memo/preview.blade.php diff --git a/app/Http/Controllers/MemoController.php b/app/Http/Controllers/MemoController.php index b38c09e..28cfe7a 100644 --- a/app/Http/Controllers/MemoController.php +++ b/app/Http/Controllers/MemoController.php @@ -314,4 +314,147 @@ class MemoController extends Controller ], 500); } } + + /** + * Menampilkan preview memo penyelesaian sebelum menyimpan + * + * @param Request $request + * @return \Illuminate\View\View + */ + public function preview(Request $request) + { + Log::info('MemoController: Mengakses halaman preview memo penyelesaian'); + + // Validasi input + $request->validate([ + 'permohonan_ids' => 'required|array', + 'permohonan_ids.*' => 'exists:permohonan,id', + 'memo_number' => 'required|string|max:255', + 'payment_date' => 'required|date', + 'memo_date' => 'required|date' + ]); + + $permohonanIds = $request->permohonan_ids; + $memoNumber = $request->memo_number; + $paymentDate = $request->payment_date; + $memoDate = $request->memo_date; + + try { + // Ambil data permohonan yang dipilih + $permohonanList = Permohonan::with([ + 'user', + 'debiture', + 'branch', + 'tujuanPenilaian', + 'penilaian', + 'jenisFasilitasKredit', + 'documents.inspeksi', + 'penilai', + 'documents.detail', + 'noc' + ])->whereIn('id', $permohonanIds)->get(); + + // Hitung total biaya PJ dari nominal_bayar di tabel NOC + $totalBiayaPJ = Noc::whereIn('permohonan_id', $permohonanIds) + ->sum('nominal_bayar'); + + // Data untuk template memo + $memoData = [ + 'memo_number' => $memoNumber, + 'memo_date' => $memoDate, + 'payment_date' => $paymentDate, + 'total_biaya_pj' => $totalBiayaPJ, + 'permohonan_list' => $permohonanList, + 'debitur_count' => $permohonanList->count(), + 'jaminan_info' => $this->getJaminanInfo($permohonanList) + ]; + + Log::info('MemoController: Data preview memo berhasil disiapkan'); + + return view('lpj::memo.preview', compact('memoData', 'permohonanList', 'totalBiayaPJ')); + + } catch (Exception $e) { + Log::error('MemoController: Error saat menyiapkan preview memo - ' . $e->getMessage()); + return redirect()->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat menyiapkan preview memo: ' . $e->getMessage()); + } + } + + /** + * Generate PDF memo penyelesaian dan simpan ke database + * + * @param Request $request + * @return \Illuminate\Http\RedirectResponse + */ + public function generatePdf(Request $request) + { + Log::info('MemoController: Memulai generate PDF memo penyelesaian'); + + DB::beginTransaction(); + + try { + // Validasi input + $request->validate([ + 'permohonan_ids' => 'required|array', + 'permohonan_ids.*' => 'exists:permohonan,id', + 'memo_number' => 'required|string|max:255', + 'payment_date' => 'required|date', + 'memo_date' => 'required|date' + ]); + + $permohonanIds = $request->permohonan_ids; + $memoNumber = $request->memo_number; + $paymentDate = $request->payment_date; + $memoDate = $request->memo_date; + + // Update status permohonan yang dipilih + foreach ($permohonanIds as $permohonanId) { + $permohonan = Permohonan::find($permohonanId); + if ($permohonan) { + $permohonan->status = 'memo-penyelesaian'; + $permohonan->memo_penyelesaian_number = $memoNumber; + $permohonan->memo_penyelesaian_date = $memoDate; + $permohonan->memo_penyelesaian_payment_date = $paymentDate; + $permohonan->memo_penyelesaian_created_at = now(); + $permohonan->save(); + + Log::info('MemoController: Berhasil update permohonan ID: ' . $permohonanId); + } + } + + DB::commit(); + Log::info('MemoController: Berhasil generate PDF dan menyimpan memo penyelesaian untuk ' . count($permohonanIds) . ' permohonan'); + + return redirect()->route('memo.index') + ->with('success', 'Memo penyelesaian berhasil dibuat dan disimpan untuk ' . count($permohonanIds) . ' permohonan'); + + } catch (Exception $e) { + DB::rollback(); + Log::error('MemoController: Error saat generate PDF memo penyelesaian - ' . $e->getMessage()); + + return redirect()->back() + ->withInput() + ->with('error', 'Terjadi kesalahan saat generate PDF memo penyelesaian: ' . $e->getMessage()); + } + } + + /** + * Helper function untuk mendapatkan informasi jaminan + * + * @param $permohonanList + * @return string + */ + private function getJaminanInfo($permohonanList) + { + $jaminanTypes = []; + foreach ($permohonanList as $permohonan) { + if ($permohonan->tujuanPenilaian) { + $jaminanTypes[] = $permohonan->tujuanPenilaian->name; + } + } + + $uniqueJaminan = array_unique($jaminanTypes); + return implode(' & ', $uniqueJaminan); + } } diff --git a/resources/views/memo/create.blade.php b/resources/views/memo/create.blade.php index 9e94178..a53929c 100644 --- a/resources/views/memo/create.blade.php +++ b/resources/views/memo/create.blade.php @@ -28,7 +28,7 @@ @endif -
+ @csrf @@ -139,8 +139,8 @@ Batal @else diff --git a/resources/views/memo/preview.blade.php b/resources/views/memo/preview.blade.php new file mode 100644 index 0000000..68129f6 --- /dev/null +++ b/resources/views/memo/preview.blade.php @@ -0,0 +1,298 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render('memo.create') }} +@endsection + +@section('content') +
+ +
+
+

+ Preview Memo Penyelesaian +

+
+ +
+
+ +
+ @if (session('error')) +
+ {{ session('error') }} +
+ @endif + + +
+ +
+
+
+ AGI +
+
+
+

BANK

+

ARTHA GRAHA

+

INTERNASIONAL

+
+
+ + +
+

Memo Instruksi Penyelesaian

+

Rekening Escrow / KSL Penilai Jaminan

+
+ + +
+
+ Kepada + : + SUBDIT E-Channel Support & Operation (NOC) +
+
+ Dari + : + SUBDIT Appraisal +
+
+ Nomor + : + {{ $memoData['memo_number'] }} +
+
+ Tanggal + : + {{ \Carbon\Carbon::parse($memoData['memo_date'])->format('d F Y') }} +
+
+ Perihal + : + Penyelesaian Rekening Escrow / KSL Penilai Jaminan (PJ) +
+
+ +
+ + +
+

Sehubungan dengan telah dilakukannya penilaian jaminan dengan keterangan sbb :

+ +
+
+ Nama Debitur + : + Terlampir ({{ $memoData['debitur_count'] }} Debitur) +
+
+ Jaminan + : + {{ $memoData['jaminan_info'] }} +
+
+ Total Biaya PJ + : + Rp + {{ number_format($memoData['total_biaya_pj'], 0, ',', '.') }},- +
+
+ ({{ terbilang($memoData['total_biaya_pj']) }} Rupiah) +
+
+ Pembayaran Tanggal + : + {{ \Carbon\Carbon::parse($memoData['payment_date'])->format('d F Y') }} +
+
+ LPJ selesai dikirim + : + - +
+
+ Jenis Penilaian + : + KJPP +
+
+ +

+ Kami menginstruksikan kepada Sentra Operasi untuk menyelesaikan Rekening Escrow / + KSL Penilai Jaminan atas nama debitur tersebut diatas ke KJPP + (terlampir). +

+ +

Demikian kami sampaikan, atas perhatian dan kerjasamanya kami ucapkan terima kasih.

+
+ + +
+
+

Salam

+
+

Innawati Sulina

+

DD Operation 2

+
+
+

 

+
+

Wahab N. Wibawa

+

Pgs EO Subdit Appraisal

+
+
+

 

+
+

Sumurung P. Siahaan

+

 

+
+
+ + +
+

Lampiran :

+
    +
  • Rekap permohonan penyelesaian biaya KJPP (Eksternal)
  • +
  • Asli Invoice & Faktur Pajak KJPP (Eksternal)
  • +
  • Copy Tiket Debet (KSL)
  • +
+
+
+ + +
+

Daftar Permohonan Terlampir

+
+ + + + + + + + + + + + + + @foreach ($permohonanList as $index => $permohonan) + + + + + + + + + + @endforeach + + + + + + + +
NoNomor RegistrasiDebiturCabangAOTujuan PenilaianBiaya PJ
{{ $index + 1 }}{{ $permohonan->nomor_registrasi }}{{ $permohonan->debiture->name ?? '-' }}{{ $permohonan->branch->name ?? '-' }}{{ $permohonan->user->name ?? '-' }} + @if ($permohonan->tujuanPenilaian) + + {{ $permohonan->tujuanPenilaian->name }} + + @else + - + @endif + + Rp {{ number_format($permohonan->noc->nominal_bayar ?? 0, 0, ',', '.') }} +
Total Biaya PJ:Rp {{ number_format($totalBiayaPJ, 0, ',', '.') }}
+
+
+ + + + @csrf + @foreach ($permohonanList as $permohonan) + + @endforeach + + + + +
+ + + +
+ +
+
+
+@endsection + +@push('scripts') + +@endpush diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index 8ac7616..2dfe2ea 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -801,6 +801,11 @@ Breadcrumbs::for('memo.create', function (BreadcrumbTrail $trail) { $trail->push('Create', route('memo.index')); }); +Breadcrumbs::for('memo.preview', function (BreadcrumbTrail $trail) { + $trail->parent('memo.create'); + $trail->push('Preview', route('memo.index')); +}); + // add andy diff --git a/routes/web.php b/routes/web.php index c9213c4..2f5e522 100644 --- a/routes/web.php +++ b/routes/web.php @@ -402,6 +402,8 @@ Route::middleware(['auth'])->group(function () { Route::get('datatables', [MemoController::class, 'dataForDatatables'])->name('memo.datatables'); Route::get('create-bulk', [MemoController::class, 'create'])->name('memo.create.bulk'); Route::post('total-biaya-pj', [MemoController::class, 'getTotalBiayaPJ'])->name('memo.total-biaya-pj'); + Route::post('preview', [MemoController::class, 'preview'])->name('memo.preview'); + Route::post('generate-pdf', [MemoController::class, 'generatePdf'])->name('memo.generate-pdf'); }); Route::resource('memo', MemoController::class);