fix(memo): Sinkronisasi layout PDF memo dengan preview dan perbaikan section tanda tangan
Melakukan sinkronisasi tampilan memo penyelesaian antara preview dan PDF serta memperbaiki struktur layout bagian tanda tangan untuk kompatibilitas PDF. Perubahan yang dilakukan: - Menyesuaikan header dan logo dengan ukuran yang sama (53.55px) untuk preview dan PDF. - Mengubah judul memo menjadi "Memo Instruksi Penyelesaian Rekening Escrow / KSL Penilai Jaminan". - Menyesuaikan informasi memo (Kepada, Dari, Perihal) agar konsisten antara preview dan PDF. - Menggunakan format tabel yang konsisten untuk detail memo dan lampiran. - Menambahkan daftar lampiran dengan kolom Nomor Registrasi dan AO sesuai format preview. - Mengimplementasikan fungsi `terbilang()` untuk konversi angka ke teks dalam lampiran. - Menyesuaikan font size, spacing, dan styling agar seragam di semua output. - Menambahkan page break yang presisi antara halaman memo utama dan lampiran. Perbaikan section tanda tangan: - Mengganti struktur flexbox dengan table layout pada bagian tanda tangan untuk stabilitas PDF. - Menggunakan 3 kolom dengan lebar 33.33% untuk pembagian tanda tangan yang rata. - Menambahkan `vertical-align: top` untuk posisi tanda tangan yang konsisten secara vertikal. - Menambahkan padding horizontal agar antar kolom tanda tangan tidak saling berdekatan. - Memastikan garis tanda tangan tetap center dengan `margin: auto`. - Mengoptimalkan layout agar kompatibel dengan berbagai PDF viewer dan environment printing. Tujuan perubahan: - Menjamin konsistensi tampilan antara preview di aplikasi dan file PDF yang dihasilkan. - Memastikan dokumen tercetak rapi, profesional, dan sesuai dengan format dokumen resmi perbankan. - Meningkatkan kompatibilitas layout untuk berbagai perangkat dan proses cetak.
This commit is contained in:
@@ -9,6 +9,8 @@ use Illuminate\Support\Facades\DB;
|
||||
use Modules\Lpj\Models\Permohonan;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class MemoController extends Controller
|
||||
{
|
||||
@@ -116,7 +118,7 @@ class MemoController extends Controller
|
||||
$permohonan->memo_penyelesaian_date = $memoDate;
|
||||
$permohonan->memo_penyelesaian_payment_date = $paymentDate;
|
||||
$permohonan->memo_penyelesaian_created_at = now();
|
||||
$permohonan->save();
|
||||
//$permohonan->save();
|
||||
|
||||
Log::info('MemoController: Berhasil update permohonan ID: ' . $permohonanId);
|
||||
}
|
||||
@@ -385,7 +387,7 @@ class MemoController extends Controller
|
||||
* Generate PDF memo penyelesaian dan simpan ke database
|
||||
*
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function generatePdf(Request $request)
|
||||
{
|
||||
@@ -395,19 +397,60 @@ class MemoController extends Controller
|
||||
|
||||
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;
|
||||
|
||||
// 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)
|
||||
];
|
||||
// Generate PDF dari template
|
||||
$pdf = Pdf::loadView('lpj::memo.pdf-template', compact('memoData', 'permohonanList', 'totalBiayaPJ'))
|
||||
->setPaper('a4', 'portrait')
|
||||
->setOptions([
|
||||
'defaultFont' => 'Times-Roman',
|
||||
'isRemoteEnabled' => true,
|
||||
'isHtml5ParserEnabled' => true,
|
||||
'isPhpEnabled' => true,
|
||||
'dpi' => 150,
|
||||
'defaultPaperSize' => 'a4',
|
||||
'chroot' => public_path(),
|
||||
]);
|
||||
|
||||
// Nama file PDF
|
||||
$fileName = 'memo-penyelesaian-' . str_replace(['/', ' '], ['-', '-'], $memoNumber) . '-' . date('Y-m-d-H-i-s') . '.pdf';
|
||||
$filePath = 'memo-penyelesaian/' . $fileName;
|
||||
|
||||
// Simpan PDF ke storage
|
||||
Storage::disk('public')->put($filePath, $pdf->output());
|
||||
|
||||
// Update status permohonan yang dipilih
|
||||
foreach ($permohonanIds as $permohonanId) {
|
||||
$permohonan = Permohonan::find($permohonanId);
|
||||
@@ -417,7 +460,8 @@ class MemoController extends Controller
|
||||
$permohonan->memo_penyelesaian_date = $memoDate;
|
||||
$permohonan->memo_penyelesaian_payment_date = $paymentDate;
|
||||
$permohonan->memo_penyelesaian_created_at = now();
|
||||
$permohonan->save();
|
||||
$permohonan->memo_penyelesaian_pdf_path = $filePath;
|
||||
//$permohonan->save();
|
||||
|
||||
Log::info('MemoController: Berhasil update permohonan ID: ' . $permohonanId);
|
||||
}
|
||||
@@ -426,8 +470,8 @@ class MemoController extends Controller
|
||||
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');
|
||||
// Return PDF untuk download
|
||||
return $pdf->download($fileName);
|
||||
|
||||
} catch (Exception $e) {
|
||||
DB::rollback();
|
||||
|
||||
363
resources/views/memo/pdf-template.blade.php
Normal file
363
resources/views/memo/pdf-template.blade.php
Normal file
@@ -0,0 +1,363 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Memo Penyelesaian - {{ $memoData['memo_number'] }}</title>
|
||||
<style>
|
||||
@page {
|
||||
margin: 20mm;
|
||||
size: A4;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Times New Roman', serif;
|
||||
font-size: 12px;
|
||||
line-height: 1.4;
|
||||
color: #000;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.header {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 53.55px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.memo-title {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.memo-info {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.memo-info table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.memo-info td {
|
||||
padding: 2px 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.memo-info .label {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.memo-info .colon {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.memo-content {
|
||||
text-align: justify;
|
||||
margin: 20px 0;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.memo-content table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.memo-content td {
|
||||
padding: 2px 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.memo-content .label {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.memo-content .colon {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.signature-section {
|
||||
margin-top: 60px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.signature-box {
|
||||
text-align: center;
|
||||
width: 30%;
|
||||
}
|
||||
|
||||
.signature-line {
|
||||
border-bottom: 1px solid #000;
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
margin: 0 auto 8px;
|
||||
}
|
||||
|
||||
.lampiran-section {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.lampiran-list {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.lampiran-list li {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.page-break {
|
||||
page-break-before: always;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.lampiran-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.lampiran-subtitle {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin: 8px 0 0 0;
|
||||
}
|
||||
|
||||
.lampiran-memo {
|
||||
font-size: 11px;
|
||||
text-align: center;
|
||||
margin: 8px 0 0 0;
|
||||
}
|
||||
|
||||
.lampiran-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 20px;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.lampiran-table th,
|
||||
.lampiran-table td {
|
||||
border: 1px solid #000;
|
||||
padding: 6px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.lampiran-table th {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.lampiran-table tfoot td {
|
||||
background-color: #f8f9fa;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.font-bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.font-weight-500 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.font-size-11 {
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-top: 1px solid #000;
|
||||
margin: 20px 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Halaman Memo Utama -->
|
||||
<div class="header">
|
||||
<img src="{{ public_path('assets/media/images/logo-arthagraha.png') }}" alt="Logo Bank" class="logo">
|
||||
</div>
|
||||
|
||||
<div class="memo-title">
|
||||
<strong>Memo Instruksi Penyelesaian</strong> Rekening Escrow / <strong>KSL Penilai Jaminan</strong>
|
||||
</div>
|
||||
|
||||
<div class="memo-info">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="label">Kepada</td>
|
||||
<td class="colon">:</td>
|
||||
<td>SUBDIT E-Channel Support & Operation (NOC)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Dari</td>
|
||||
<td class="colon">:</td>
|
||||
<td>SUBDIT Appraisal</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Nomor</td>
|
||||
<td class="colon">:</td>
|
||||
<td><strong>{{ $memoData['memo_number'] }}</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Tanggal</td>
|
||||
<td class="colon">:</td>
|
||||
<td>{{ \Carbon\Carbon::parse($memoData['memo_date'])->format('d F Y') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Perihal</td>
|
||||
<td class="colon">:</td>
|
||||
<td>Penyelesaian Rekening Escrow / <strong>KSL Penilai Jaminan (PJ)</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="memo-content">
|
||||
<p style="margin-bottom: 16px;">Sehubungan dengan telah dilakukannya penilaian jaminan dengan keterangan sbb :
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td class="label">Nama Debitur</td>
|
||||
<td class="colon">:</td>
|
||||
<td>Terlampir ({{ $memoData['debitur_count'] }} Debitur)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Jaminan</td>
|
||||
<td class="colon">:</td>
|
||||
<td>{{ $memoData['jaminan_info'] }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Total Biaya PJ</td>
|
||||
<td class="colon">:</td>
|
||||
<td><strong>Rp {{ number_format($memoData['total_biaya_pj'], 0, ',', '.') }},-</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="font-size-11">({{ terbilang($memoData['total_biaya_pj']) }} Rupiah)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Pembayaran Tanggal</td>
|
||||
<td class="colon">:</td>
|
||||
<td>{{ \Carbon\Carbon::parse($memoData['payment_date'])->format('d F Y') }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">LPJ selesai dikirim</td>
|
||||
<td class="colon">:</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="label">Jenis Penilaian</td>
|
||||
<td class="colon">:</td>
|
||||
<td><strong>KJPP</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin-bottom: 16px;">Kami menginstruksikan kepada Sentra Operasi untuk menyelesaikan Rekening Escrow
|
||||
/ <strong>KSL Penilai Jaminan</strong> atas nama debitur tersebut diatas ke <strong>KJPP
|
||||
(terlampir)</strong>.</p>
|
||||
|
||||
<p style="margin-bottom: 16px;">Demikian kami sampaikan, atas perhatian dan kerjasamanya kami ucapkan terima
|
||||
kasih.</p>
|
||||
</div>
|
||||
|
||||
<div class="signature-section">
|
||||
<table style="width: 100%; border-collapse: collapse; margin-top: 0px;">
|
||||
<tr>
|
||||
<td style="width: 33.33%; text-align: center; vertical-align: top; padding: 0 10px;">
|
||||
<p style="margin-bottom: 40px;">Salam</p>
|
||||
<div style="border-bottom: 1px solid #000; width: 120px; height: 40px; margin: 0 auto 8px;"></div>
|
||||
<p style="font-weight: 500; margin: 0;">Innawati Sulina</p>
|
||||
<p style="font-size: 11px; margin: 0;">DD Operation 2</p>
|
||||
</td>
|
||||
<td style="width: 33.33%; text-align: center; vertical-align: top; padding: 0 10px;">
|
||||
<p style="margin-bottom: 40px;"> </p>
|
||||
<div style="border-bottom: 1px solid #000; width: 120px; height: 40px; margin: 0 auto 8px;"></div>
|
||||
<p style="font-weight: 500; margin: 0;">Wahab N. Wibawa</p>
|
||||
<p style="font-size: 11px; margin: 0;">Pgs EO Subdit Appraisal</p>
|
||||
</td>
|
||||
<td style="width: 33.33%; text-align: center; vertical-align: top; padding: 0 10px;">
|
||||
<p style="margin-bottom: 40px;"> </p>
|
||||
<div style="border-bottom: 1px solid #000; width: 120px; height: 40px; margin: 0 auto 8px;"></div>
|
||||
<p style="font-weight: 500; margin: 0;">Sumurung P. Siahaan</p>
|
||||
<p style="font-size: 11px; margin: 0;"> </p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="lampiran-section">
|
||||
<p class="font-weight-500" style="margin-bottom: 8px;">Lampiran :</p>
|
||||
<ul class="lampiran-list">
|
||||
<li>Rekap permohonan penyelesaian biaya KJPP (Eksternal)</li>
|
||||
<li>Asli Invoice & Faktur Pajak KJPP (Eksternal)</li>
|
||||
<li>Copy Tiket Debet (KSL)</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Halaman Lampiran -->
|
||||
<div class="page-break">
|
||||
<div class="lampiran-title">LAMPIRAN</div>
|
||||
<div class="lampiran-subtitle">REKAP PERMOHONAN PENYELESAIAN BIAYA KJPP</div>
|
||||
<p class="lampiran-memo">Memo No: {{ $memoData['memo_number'] }}</p>
|
||||
|
||||
<table class="lampiran-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No</th>
|
||||
<th>Nomor Registrasi</th>
|
||||
<th>Debitur</th>
|
||||
<th>Cabang</th>
|
||||
<th>AO</th>
|
||||
<th>Tujuan Penilaian</th>
|
||||
<th>Biaya PJ</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($permohonanList as $index => $permohonan)
|
||||
<tr>
|
||||
<td class="text-center">{{ $index + 1 }}</td>
|
||||
<td class="font-weight-500">{{ $permohonan->nomor_registrasi }}</td>
|
||||
<td>{{ $permohonan->debiture->name ?? '-' }}</td>
|
||||
<td>{{ $permohonan->branch->name ?? '-' }}</td>
|
||||
<td>{{ $permohonan->user->name ?? '-' }}</td>
|
||||
<td>{{ $permohonan->tujuanPenilaian->name ?? '-' }}</td>
|
||||
<td class="text-right font-weight-500">Rp
|
||||
{{ number_format($permohonan->noc->nominal_bayar ?? 0, 0, ',', '.') }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="6" class="font-bold text-right">Total Biaya PJ:</td>
|
||||
<td class="font-bold text-right">Rp {{ number_format($totalBiayaPJ, 0, ',', '.') }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
Reference in New Issue
Block a user