refactor(memo): Sesuaikan struktur form dan tambahkan kalkulasi Total Biaya PJ

Melakukan refactor dan penyesuaian form memo penyelesaian agar lebih sesuai dengan kebutuhan bisnis, serta menambahkan fitur perhitungan otomatis Total Biaya PJ.

Perubahan pada Form Input:
- Mengubah field "Judul Memo" menjadi "Nomor Memo" untuk identifikasi memo yang lebih spesifik.
- Menghapus field "Isi Memo" karena tidak relevan dengan proses bisnis saat ini.
- Menambahkan field "Tanggal Pembayaran" untuk tracking proses pembayaran.
- Mengatur "Tanggal Memo" menjadi otomatis mengikuti tanggal hari ini dan disimpan sebagai hidden field untuk keperluan audit.
- Menambahkan field readonly "Total Biaya PJ" untuk menampilkan akumulasi biaya dari NOC terkait permohonan yang dipilih.

Perubahan pada Controller:
- Mengupdate validasi request agar sesuai dengan field baru: `memo_number`, `payment_date`, dan `permohonan_ids`.
- Menghapus validasi `memo_content` karena field tersebut tidak lagi digunakan.
- Menambahkan method `getTotalBiayaPJ()` untuk endpoint AJAX yang menghitung total biaya PJ secara real-time.
- Menggunakan relasi model `Noc` dan `Permohonan` untuk menghitung sum dari `nominal_bayar`.
- Mengupdate method `create()` agar langsung menghitung total biaya PJ saat form dibuka.
- Tetap menggunakan DB transaction untuk memastikan integritas data.

Perubahan pada Database Schema:
- Mengganti field `memo_penyelesaian_title` menjadi `memo_penyelesaian_number`.
- Menghapus field `memo_penyelesaian_content`.
- Menambahkan field baru `memo_penyelesaian_payment_date` untuk menyimpan tanggal pembayaran.
- Mempertahankan field `memo_penyelesaian_date` sebagai audit trail.

Perubahan pada View:
- Menambahkan field readonly "Total Biaya PJ" dengan format mata uang Rupiah.
- Menambahkan icon kalkulator dan styling sesuai dengan tema form.
- Menggunakan AJAX untuk menghitung total biaya PJ ketika user memilih atau mengubah permohonan secara dinamis.
- Menampilkan pesan error dan feedback user secara jelas jika terjadi masalah saat perhitungan.

Routing dan API:
- Menambahkan route `memo.total-biaya-pj` sebagai endpoint untuk kalkulasi biaya PJ berbasis AJAX.
- Tetap menggunakan route resource untuk operasi CRUD memo penyelesaian.

Keamanan dan Validasi:
- Implementasi CSRF protection untuk AJAX request.
- Validasi `permohonan_ids` harus berupa array yang valid dan terfilter dengan baik.
- Penanganan error yang komprehensif baik di sisi controller maupun client-side.

Peningkatan User Experience:
- Form menjadi lebih sederhana, efisien, dan fokus pada input yang memang dibutuhkan oleh proses bisnis.
- Real-time feedback saat memilih permohonan sehingga user langsung mengetahui total biaya PJ.
- Layout form tetap responsive dan mudah digunakan di berbagai perangkat.
- Memberikan pengalaman yang konsisten dengan desain aplikasi lainnya.

Tujuan Perubahan:
- Menyederhanakan proses pembuatan memo penyelesaian sesuai kebutuhan operasional terbaru.
- Memastikan proses input lebih cepat dan akurat dengan kalkulasi otomatis Total Biaya PJ.
- Mengurangi potensi kesalahan input dan mempercepat workflow divisi terkait.
- Meningkatkan maintainability dan konsistensi kode dengan standar sistem yang ada.
This commit is contained in:
Daeng Deni Mardaeni
2025-07-17 09:41:20 +07:00
parent 5c3a93c49b
commit 274addb069
6 changed files with 339 additions and 172 deletions

View File

@@ -2,12 +2,13 @@
namespace Modules\Lpj\Http\Controllers;
use App\Http\Controllers\Controller;
use Exception;
use Modules\Lpj\Models\Noc;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Modules\Lpj\Models\Permohonan;
use Exception;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
class MemoController extends Controller
{
@@ -34,33 +35,49 @@ class MemoController extends Controller
{
Log::info('MemoController: Mengakses halaman create memo penyelesaian');
// Tambahkan validasi di awal method
$selectedIds = $request->get('selected_ids', []);
$selectedIds = explode(',', $selectedIds);
$permohonanList = [];
if (!empty($selectedIds)) {
// Pastikan $selectedIds selalu berupa array
if (is_string($selectedIds)) {
$selectedIds = explode(',', $selectedIds);
}
// Filter array untuk menghilangkan nilai kosong
$selectedIds = array_filter($selectedIds, function($id) {
return !empty(trim($id));
});
$permohonanList = [];
$totalBiayaPJ = 0;
if (!empty($selectedIds) && count($selectedIds) > 0) {
try {
$permohonanList = Permohonan::with([
'user',
'debiture',
'branch',
'tujuanPenilaian',
'penilaian',
'jenisFasilitasKredit',
'documents.inspeksi',
'penilai',
'documents.detail',
'noc'
])->whereIn('id', $selectedIds)->get();
$permohonanList = Permohonan::with([
'user',
'debiture',
'branch',
'tujuanPenilaian',
'penilaian',
'jenisFasilitasKredit',
'documents.inspeksi',
'penilai',
'documents.detail',
'noc'
])->whereIn('id', $selectedIds)->get();
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
$totalBiayaPJ = Noc::whereIn('permohonan_id', $selectedIds)
->sum('nominal_bayar');
Log::info('MemoController: Total Biaya PJ dihitung: ' . $totalBiayaPJ);
} catch (Exception $e) {
Log::error('MemoController: Error saat mengambil data permohonan - ' . $e->getMessage());
return redirect()->back()->with('error', 'Terjadi kesalahan saat memuat data');
}
}
return view('lpj::memo.create', compact('permohonanList'));
return view('lpj::memo.create', compact('permohonanList', 'totalBiayaPJ'));
}
/**
@@ -80,17 +97,30 @@ class MemoController extends Controller
$request->validate([
'permohonan_ids' => 'required|array',
'permohonan_ids.*' => 'exists:permohonan,id',
'memo_title' => 'required|string|max:255',
'memo_content' => 'required|string',
'memo_number' => 'required|string|max:255',
'payment_date' => 'required|date',
'memo_date' => 'required|date'
]);
$permohonanIds = $request->permohonan_ids;
$memoTitle = $request->memo_title;
$memoContent = $request->memo_content;
$memoNumber = $request->memo_number;
$paymentDate = $request->payment_date;
$memoDate = $request->memo_date;
dd($request->all());
// 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 menyimpan memo penyelesaian untuk ' . count($permohonanIds) . ' permohonan');
@@ -235,4 +265,53 @@ class MemoController extends Controller
'data' => $data,
]);
}
/**
* Mengambil total biaya PJ berdasarkan permohonan yang dipilih
*
* @param Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function getTotalBiayaPJ(Request $request)
{
Log::info('MemoController: Mengambil total biaya PJ');
try {
$permohonanIds = $request->get('permohonan_ids', []);
// Pastikan $permohonanIds selalu berupa array
if (is_string($permohonanIds)) {
$permohonanIds = explode(',', $permohonanIds);
}
// Filter array untuk menghilangkan nilai kosong
$permohonanIds = array_filter($permohonanIds, function($id) {
return !empty(trim($id));
});
$totalBiayaPJ = 0;
if (!empty($permohonanIds) && count($permohonanIds) > 0) {
// Hitung total biaya PJ dari nominal_bayar di tabel NOC
$totalBiayaPJ = \Modules\Lpj\Models\Noc::whereIn('permohonan_id', $permohonanIds)
->sum('nominal_bayar');
}
Log::info('MemoController: Total Biaya PJ berhasil dihitung: ' . $totalBiayaPJ);
return response()->json([
'success' => true,
'total_biaya_pj' => $totalBiayaPJ,
'total_biaya_pj_formatted' => 'Rp ' . number_format($totalBiayaPJ, 0, ',', '.')
]);
} catch (Exception $e) {
Log::error('MemoController: Error saat menghitung total biaya PJ - ' . $e->getMessage());
return response()->json([
'success' => false,
'message' => 'Terjadi kesalahan saat menghitung total biaya PJ'
], 500);
}
}
}

View File

@@ -1,5 +1,10 @@
@extends('layouts.main')
@section('breadcrumbs')
{{ Breadcrumbs::render('memo.create') }}
@endsection
@section('content')
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
<!-- Form Memo Penyelesaian -->
@@ -8,16 +13,16 @@
<h3 class="card-title">
Buat Memo Penyelesaian
</h3>
<div class="flex items-center gap-2">
<div class="flex gap-2 items-center">
<a href="{{ route('memo.index') }}" class="btn btn-sm btn-light">
<i class="ki-filled ki-black-left"></i>
Kembali
</a>
</div>
</div>
<div class="card-body">
@if(session('error'))
@if (session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@@ -25,46 +30,54 @@
<form action="{{ route('memo.store') }}" method="POST" id="memo-form">
@csrf
<!-- Form Input Memo -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5 mb-7">
<div class="grid grid-cols-1 gap-5 mb-7 lg:grid-cols-2">
<div class="flex flex-col gap-1">
<label class="form-label text-gray-900">Judul Memo <span class="text-red-500">*</span></label>
<input type="text" name="memo_title" class="input" placeholder="Masukkan judul memo penyelesaian"
value="{{ old('memo_title') }}" required>
@error('memo_title')
<span class="text-red-500 text-sm">{{ $message }}</span>
<label class="text-gray-900 form-label">Nomor Memo <span class="text-red-500">*</span></label>
<input type="text" name="memo_number" class="input"
placeholder="Masukkan nomor memo penyelesaian" value="{{ old('memo_number') }}" required>
@error('memo_number')
<span class="text-sm text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="flex flex-col gap-1">
<label class="form-label text-gray-900">Tanggal Memo <span class="text-red-500">*</span></label>
<input type="date" name="memo_date" class="input"
value="{{ old('memo_date', date('Y-m-d')) }}" required>
@error('memo_date')
<span class="text-red-500 text-sm">{{ $message }}</span>
<label class="text-gray-900 form-label">Tanggal Pembayaran <span
class="text-red-500">*</span></label>
<input type="date" name="payment_date" class="input" value="{{ old('payment_date') }}"
required>
@error('payment_date')
<span class="text-sm text-red-500">{{ $message }}</span>
@enderror
</div>
<div class="flex flex-col gap-1 lg:col-span-2">
<label class="text-gray-900 form-label">Total Biaya PJ</label>
<div class="relative">
<input type="text" id="total-biaya-pj" class="bg-gray-50 input"
value="Rp {{ number_format($totalBiayaPJ ?? 0, 0, ',', '.') }}" readonly>
<div class="flex absolute inset-y-0 right-0 items-center pr-3">
<i class="text-gray-400 ki-filled ki-calculator"></i>
</div>
</div>
<span class="text-sm text-gray-500">Total biaya dari nominal bayar NOC untuk permohonan yang
dipilih</span>
</div>
</div>
<div class="flex flex-col gap-1 mb-7">
<label class="form-label text-gray-900">Isi Memo <span class="text-red-500">*</span></label>
<textarea name="memo_content" class="textarea" rows="6"
placeholder="Masukkan isi memo penyelesaian" required>{{ old('memo_content') }}</textarea>
@error('memo_content')
<span class="text-red-500 text-sm">{{ $message }}</span>
@enderror
</div>
<!-- Hidden field untuk tanggal memo otomatis -->
<input type="hidden" name="memo_date" value="{{ date('Y-m-d') }}">
<!-- Daftar Permohonan yang Dipilih -->
@if(count($permohonanList) > 0)
@if (count($permohonanList) > 0)
<div class="mb-7">
<h4 class="text-lg font-semibold mb-4">Daftar Permohonan yang Akan Diproses</h4>
<h4 class="mb-4 text-lg font-semibold">Daftar Permohonan yang Akan Diproses</h4>
<div class="overflow-x-auto">
<table class="table table-border">
<thead>
<tr class="bg-gray-50">
<th class="text-center w-12">
<th class="w-12 text-center">
<input type="checkbox" id="select-all" class="checkbox checkbox-sm" checked>
</th>
<th>Nomor Registrasi</th>
@@ -76,19 +89,19 @@
</tr>
</thead>
<tbody>
@foreach($permohonanList as $permohonan)
@foreach ($permohonanList as $permohonan)
<tr>
<td class="text-center">
<input type="checkbox" name="permohonan_ids[]"
value="{{ $permohonan->id }}"
class="checkbox checkbox-sm permohonan-checkbox" checked>
<input type="checkbox" name="permohonan_ids[]"
value="{{ $permohonan->id }}"
class="checkbox checkbox-sm permohonan-checkbox" checked>
</td>
<td class="font-medium">{{ $permohonan->nomor_registrasi }}</td>
<td>{{ $permohonan->debiture->name ?? '-' }}</td>
<td>{{ $permohonan->branch->name ?? '-' }}</td>
<td>{{ $permohonan->user->name ?? '-' }}</td>
<td>
@if($permohonan->tujuanPenilaian)
@if ($permohonan->tujuanPenilaian)
<span class="badge badge-sm badge-primary">
{{ $permohonan->tujuanPenilaian->name }}
</span>
@@ -97,7 +110,7 @@
@endif
</td>
<td>
<span class="badge badge-sm badge-warning uppercase">
<span class="uppercase badge badge-sm badge-warning">
{{ $permohonan->status }}
</span>
</td>
@@ -106,21 +119,22 @@
</tbody>
</table>
</div>
<div class="mt-4 p-4 bg-blue-50 rounded-lg">
<div class="flex items-center gap-2">
<i class="ki-filled ki-information text-blue-600"></i>
<span class="text-blue-800 font-medium">Informasi:</span>
<div class="p-4 mt-4 bg-blue-50 rounded-lg">
<div class="flex gap-2 items-center">
<i class="text-blue-600 ki-filled ki-information"></i>
<span class="font-medium text-blue-800">Informasi:</span>
</div>
<p class="text-blue-700 mt-1">
Total <span id="selected-count">{{ count($permohonanList) }}</span> permohonan akan diproses untuk memo penyelesaian.
<p class="mt-1 text-blue-700">
Total <span id="selected-count">{{ count($permohonanList) }}</span> permohonan akan
diproses untuk memo penyelesaian.
Anda dapat menghapus centang pada permohonan yang tidak ingin diproses.
</p>
</div>
</div>
<!-- Tombol Submit -->
<div class="flex justify-end gap-2">
<div class="flex gap-2 justify-end">
<a href="{{ route('memo.index') }}" class="btn btn-light">
Batal
</a>
@@ -130,12 +144,12 @@
</button>
</div>
@else
<div class="text-center py-10">
<div class="py-10 text-center">
<div class="mb-4">
<i class="ki-filled ki-information-2 text-6xl text-gray-400"></i>
<i class="text-6xl text-gray-400 ki-filled ki-information-2"></i>
</div>
<h4 class="text-lg font-semibold text-gray-600 mb-2">Tidak Ada Data</h4>
<p class="text-gray-500 mb-4">Tidak ada permohonan yang dipilih untuk diproses.</p>
<h4 class="mb-2 text-lg font-semibold text-gray-600">Tidak Ada Data</h4>
<p class="mb-4 text-gray-500">Tidak ada permohonan yang dipilih untuk diproses.</p>
<a href="{{ route('memo.index') }}" class="btn btn-primary">
Kembali ke Daftar
</a>
@@ -155,6 +169,47 @@
const selectedCountSpan = document.getElementById('selected-count');
const submitBtn = document.getElementById('submit-btn');
const memoForm = document.getElementById('memo-form');
const totalBiayaPJInput = document.getElementById('total-biaya-pj');
/**
* Fungsi untuk mengupdate total biaya PJ
*/
function updateTotalBiayaPJ() {
const checkedBoxes = document.querySelectorAll('.permohonan-checkbox:checked');
const permohonanIds = Array.from(checkedBoxes).map(cb => cb.value);
if (permohonanIds.length === 0) {
if (totalBiayaPJInput) {
totalBiayaPJInput.value = 'Rp 0';
}
return;
}
// Kirim AJAX request untuk mendapatkan total biaya PJ
fetch('{{ route('memo.total-biaya-pj') }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute(
'content')
},
body: JSON.stringify({
permohonan_ids: permohonanIds
})
})
.then(response => response.json())
.then(data => {
if (data.success && totalBiayaPJInput) {
totalBiayaPJInput.value = data.total_biaya_pj_formatted;
}
})
.catch(error => {
console.error('Error:', error);
if (totalBiayaPJInput) {
totalBiayaPJInput.value = 'Error menghitung total';
}
});
}
/**
* Fungsi untuk mengupdate jumlah item yang dipilih
@@ -162,11 +217,11 @@
function updateSelectedCount() {
const checkedBoxes = document.querySelectorAll('.permohonan-checkbox:checked');
const count = checkedBoxes.length;
if (selectedCountSpan) {
selectedCountSpan.textContent = count;
}
// Disable submit button jika tidak ada yang dipilih
if (submitBtn) {
submitBtn.disabled = count === 0;
@@ -174,16 +229,20 @@
submitBtn.innerHTML = '<i class="ki-filled ki-check"></i> Pilih minimal 1 permohonan';
submitBtn.classList.add('btn-disabled');
} else {
submitBtn.innerHTML = `<i class="ki-filled ki-check"></i> Buat Memo Penyelesaian (${count} item)`;
submitBtn.innerHTML =
`<i class="ki-filled ki-check"></i> Buat Memo Penyelesaian (${count} item)`;
submitBtn.classList.remove('btn-disabled');
}
}
// Update select all checkbox state
if (selectAllCheckbox) {
selectAllCheckbox.checked = count === permohonanCheckboxes.length;
selectAllCheckbox.indeterminate = count > 0 && count < permohonanCheckboxes.length;
}
// Update total biaya PJ
updateTotalBiayaPJ();
}
/**
@@ -214,20 +273,22 @@
if (memoForm) {
memoForm.addEventListener('submit', function(e) {
const checkedBoxes = document.querySelectorAll('.permohonan-checkbox:checked');
if (checkedBoxes.length === 0) {
e.preventDefault();
alert('Pilih minimal 1 permohonan untuk diproses!');
return false;
}
// Konfirmasi sebelum submit
const confirmed = confirm(`Apakah Anda yakin ingin membuat memo penyelesaian untuk ${checkedBoxes.length} permohonan?`);
const confirmed = confirm(
`Apakah Anda yakin ingin membuat memo penyelesaian untuk ${checkedBoxes.length} permohonan?`
);
if (!confirmed) {
e.preventDefault();
return false;
}
// Disable submit button untuk mencegah double submit
if (submitBtn) {
submitBtn.disabled = true;
@@ -236,8 +297,8 @@
});
}
// Initialize count
// Initialize count dan total biaya PJ
updateSelectedCount();
});
</script>
@endpush
@endpush

View File

@@ -1,5 +1,9 @@
@extends('layouts.main')
@section('breadcrumbs')
{{ Breadcrumbs::render('memo.index') }}
@endsection
@section('content')
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
<div class="min-w-full border card border-agi-100 card-grid" data-datatable="false" data-datatable-page-size="10"

View File

@@ -1,5 +1,9 @@
@extends('layouts.main')
@section('breadcrumbs')
{{ Breadcrumbs::render('memo.show') }}
@endsection
@section('content')
<div class="grid gap-5 mx-auto w-full lg:gap-7.5">
<!-- Header -->
@@ -8,7 +12,7 @@
<h3 class="card-title">
Detail Memo Penyelesaian
</h3>
<div class="flex items-center gap-2">
<div class="flex gap-2 items-center">
<a href="{{ route('memo.index') }}" class="btn btn-sm btn-light">
<i class="ki-filled ki-black-left"></i>
Kembali
@@ -23,26 +27,26 @@
<!-- Detail Memo -->
<div class="card">
<div class="card-header bg-gray-50">
<h4 class="card-title text-lg">
<div class="bg-gray-50 card-header">
<h4 class="text-lg card-title">
Informasi Memo Penyelesaian
</h4>
</div>
<div class="card-body">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
<div class="grid grid-cols-1 gap-6 mb-8 lg:grid-cols-2">
<div class="space-y-4">
<div>
<label class="text-sm font-medium text-gray-600">Judul Memo:</label>
<p class="text-gray-900 font-semibold mt-1">
<p class="mt-1 font-semibold text-gray-900">
{{ $permohonan->memo_penyelesaian_title ?? 'Belum ada memo' }}
</p>
</div>
<div>
<label class="text-sm font-medium text-gray-600">Tanggal Memo:</label>
<p class="text-gray-900 mt-1">
@if($permohonan->memo_penyelesaian_date)
<p class="mt-1 text-gray-900">
@if ($permohonan->memo_penyelesaian_date)
{{ \Carbon\Carbon::parse($permohonan->memo_penyelesaian_date)->format('d F Y') }}
@else
-
@@ -50,23 +54,23 @@
</p>
</div>
</div>
<div class="space-y-4">
<div>
<label class="text-sm font-medium text-gray-600">Status:</label>
<p class="mt-1">
@if($permohonan->status === 'memo-penyelesaian')
<span class="badge badge-success uppercase">{{ $permohonan->status }}</span>
@if ($permohonan->status === 'memo-penyelesaian')
<span class="uppercase badge badge-success">{{ $permohonan->status }}</span>
@else
<span class="badge badge-warning uppercase">{{ $permohonan->status }}</span>
<span class="uppercase badge badge-warning">{{ $permohonan->status }}</span>
@endif
</p>
</div>
<div>
<label class="text-sm font-medium text-gray-600">Dibuat Pada:</label>
<p class="text-gray-900 mt-1">
@if($permohonan->memo_penyelesaian_created_at)
<p class="mt-1 text-gray-900">
@if ($permohonan->memo_penyelesaian_created_at)
{{ \Carbon\Carbon::parse($permohonan->memo_penyelesaian_created_at)->format('d F Y H:i') }}
@else
-
@@ -75,12 +79,12 @@
</div>
</div>
</div>
@if($permohonan->memo_penyelesaian_content)
@if ($permohonan->memo_penyelesaian_content)
<div class="mb-8">
<label class="text-sm font-medium text-gray-600 mb-3 block">Isi Memo:</label>
<label class="block mb-3 text-sm font-medium text-gray-600">Isi Memo:</label>
<div class="p-4 bg-gray-50 rounded-lg border">
<div class="prose max-w-none">
<div class="max-w-none prose">
{!! nl2br(e($permohonan->memo_penyelesaian_content)) !!}
</div>
</div>
@@ -91,68 +95,68 @@
<!-- Detail Permohonan -->
<div class="card">
<div class="card-header bg-blue-50">
<h4 class="card-title text-lg">
<div class="bg-blue-50 card-header">
<h4 class="text-lg card-title">
Detail Permohonan
</h4>
</div>
<div class="card-body">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
<div class="space-y-4">
<div>
<label class="text-sm font-medium text-gray-600">Nomor Registrasi:</label>
<p class="text-gray-900 font-semibold mt-1">{{ $permohonan->nomor_registrasi }}</p>
<p class="mt-1 font-semibold text-gray-900">{{ $permohonan->nomor_registrasi }}</p>
</div>
<div>
<label class="text-sm font-medium text-gray-600">Debitur:</label>
<p class="text-gray-900 mt-1">{{ $permohonan->debiture->name ?? '-' }}</p>
<p class="mt-1 text-gray-900">{{ $permohonan->debiture->name ?? '-' }}</p>
</div>
<div>
<label class="text-sm font-medium text-gray-600">Cabang/Direktorat:</label>
<p class="text-gray-900 mt-1">{{ $permohonan->branch->name ?? '-' }}</p>
<p class="mt-1 text-gray-900">{{ $permohonan->branch->name ?? '-' }}</p>
</div>
<div>
<label class="text-sm font-medium text-gray-600">Account Officer:</label>
<p class="text-gray-900 mt-1">{{ $permohonan->user->name ?? '-' }}</p>
<p class="mt-1 text-gray-900">{{ $permohonan->user->name ?? '-' }}</p>
</div>
</div>
<div class="space-y-4">
<div>
<label class="text-sm font-medium text-gray-600">Tujuan Penilaian:</label>
<p class="mt-1">
@if($permohonan->tujuanPenilaian)
@if ($permohonan->tujuanPenilaian)
<span class="badge badge-primary">{{ $permohonan->tujuanPenilaian->name }}</span>
@else
-
@endif
</p>
</div>
<div>
<label class="text-sm font-medium text-gray-600">Fasilitas Kredit:</label>
<p class="text-gray-900 mt-1">{{ $permohonan->jenisFasilitasKredit->name ?? '-' }}</p>
<p class="mt-1 text-gray-900">{{ $permohonan->jenisFasilitasKredit->name ?? '-' }}</p>
</div>
<div>
<label class="text-sm font-medium text-gray-600">Tanggal Permohonan:</label>
<p class="text-gray-900 mt-1">
@if($permohonan->tanggal_permohonan)
<p class="mt-1 text-gray-900">
@if ($permohonan->tanggal_permohonan)
{{ \Carbon\Carbon::parse($permohonan->tanggal_permohonan)->format('d F Y') }}
@else
-
@endif
</p>
</div>
@if($permohonan->nilai_liquidasi)
@if ($permohonan->nilai_liquidasi)
<div>
<label class="text-sm font-medium text-gray-600">Nilai Liquidasi:</label>
<p class="text-gray-900 font-semibold mt-1">
<p class="mt-1 font-semibold text-gray-900">
Rp {{ number_format($permohonan->nilai_liquidasi, 0, ',', '.') }}
</p>
</div>
@@ -163,41 +167,42 @@
</div>
<!-- Informasi Penilaian -->
@if($permohonan->penilaian)
@if ($permohonan->penilaian)
<div class="card">
<div class="card-header bg-green-50">
<h4 class="card-title text-lg">
<div class="bg-green-50 card-header">
<h4 class="text-lg card-title">
Informasi Penilaian
</h4>
</div>
<div class="card-body">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
<div class="space-y-4">
@if($permohonan->penilaian->waktu_penilaian)
@if ($permohonan->penilaian->waktu_penilaian)
<div>
<label class="text-sm font-medium text-gray-600">Waktu Penilaian:</label>
<p class="text-gray-900 mt-1">
<p class="mt-1 text-gray-900">
{{ \Carbon\Carbon::parse($permohonan->penilaian->waktu_penilaian)->format('d F Y H:i') }}
</p>
</div>
@endif
@if($permohonan->penilai)
@if ($permohonan->penilai)
<div>
<label class="text-sm font-medium text-gray-600">Tipe Penilai:</label>
<p class="mt-1">
<span class="badge badge-info uppercase">{{ $permohonan->penilai->type_penilai ?? '-' }}</span>
<span
class="uppercase badge badge-info">{{ $permohonan->penilai->type_penilai ?? '-' }}</span>
</p>
</div>
@endif
</div>
<div class="space-y-4">
@if($permohonan->penilaian->created_at)
@if ($permohonan->penilaian->created_at)
<div>
<label class="text-sm font-medium text-gray-600">Dibuat Pada:</label>
<p class="text-gray-900 mt-1">
<p class="mt-1 text-gray-900">
{{ \Carbon\Carbon::parse($permohonan->penilaian->created_at)->format('d F Y H:i') }}
</p>
</div>
@@ -210,25 +215,25 @@
<!-- Informasi Approval -->
<div class="card">
<div class="card-header bg-yellow-50">
<h4 class="card-title text-lg">
<div class="bg-yellow-50 card-header">
<h4 class="text-lg card-title">
Status Approval
</h4>
</div>
<div class="card-body">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="text-center p-4 border rounded-lg">
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
<div class="p-4 text-center rounded-lg border">
<div class="mb-2">
@if($permohonan->approval_so_at)
<i class="ki-filled ki-check-circle text-3xl text-green-500"></i>
@if ($permohonan->approval_so_at)
<i class="text-3xl text-green-500 ki-filled ki-check-circle"></i>
@else
<i class="ki-filled ki-time text-3xl text-gray-400"></i>
<i class="text-3xl text-gray-400 ki-filled ki-time"></i>
@endif
</div>
<h5 class="font-semibold text-gray-900">Senior Officer</h5>
<p class="text-sm text-gray-600 mt-1">
@if($permohonan->approval_so_at)
<p class="mt-1 text-sm text-gray-600">
@if ($permohonan->approval_so_at)
Disetujui pada<br>
{{ \Carbon\Carbon::parse($permohonan->approval_so_at)->format('d F Y H:i') }}
@else
@@ -236,18 +241,18 @@
@endif
</p>
</div>
<div class="text-center p-4 border rounded-lg">
<div class="p-4 text-center rounded-lg border">
<div class="mb-2">
@if($permohonan->approval_eo_at)
<i class="ki-filled ki-check-circle text-3xl text-green-500"></i>
@if ($permohonan->approval_eo_at)
<i class="text-3xl text-green-500 ki-filled ki-check-circle"></i>
@else
<i class="ki-filled ki-time text-3xl text-gray-400"></i>
<i class="text-3xl text-gray-400 ki-filled ki-time"></i>
@endif
</div>
<h5 class="font-semibold text-gray-900">Executive Officer</h5>
<p class="text-sm text-gray-600 mt-1">
@if($permohonan->approval_eo_at)
<p class="mt-1 text-sm text-gray-600">
@if ($permohonan->approval_eo_at)
Disetujui pada<br>
{{ \Carbon\Carbon::parse($permohonan->approval_eo_at)->format('d F Y H:i') }}
@else
@@ -255,18 +260,18 @@
@endif
</p>
</div>
<div class="text-center p-4 border rounded-lg">
<div class="p-4 text-center rounded-lg border">
<div class="mb-2">
@if($permohonan->approval_dd_at)
<i class="ki-filled ki-check-circle text-3xl text-green-500"></i>
@if ($permohonan->approval_dd_at)
<i class="text-3xl text-green-500 ki-filled ki-check-circle"></i>
@else
<i class="ki-filled ki-time text-3xl text-gray-400"></i>
<i class="text-3xl text-gray-400 ki-filled ki-time"></i>
@endif
</div>
<h5 class="font-semibold text-gray-900">Deputy Director</h5>
<p class="text-sm text-gray-600 mt-1">
@if($permohonan->approval_dd_at)
<p class="mt-1 text-sm text-gray-600">
@if ($permohonan->approval_dd_at)
Disetujui pada<br>
{{ \Carbon\Carbon::parse($permohonan->approval_dd_at)->format('d F Y H:i') }}
@else
@@ -283,24 +288,26 @@
@push('styles')
<style>
@media print {
.btn, .card-header .flex {
.btn,
.card-header .flex {
display: none !important;
}
.card {
box-shadow: none !important;
border: 1px solid #e5e7eb !important;
margin-bottom: 1rem !important;
}
body {
font-size: 12px !important;
}
.card-title {
font-size: 16px !important;
font-weight: bold !important;
}
}
</style>
@endpush
@endpush

View File

@@ -786,5 +786,22 @@ Breadcrumbs::for('laporan-debiture', function ($trail) {
Breadcrumbs::for('laporan-sla-penilai', function ($trail) {
$trail->push('Laporan SLA Penilai', route('laporan-sla-penilai.index'));
});
Breadcrumbs::for('memo.index', function (BreadcrumbTrail $trail) {
$trail->push('Memo Penyelesaian', route('memo.index'));
});
Breadcrumbs::for('memo.show', function (BreadcrumbTrail $trail) {
$trail->push('Memo Penyelesaian', route('memo.index'));
});
Breadcrumbs::for('memo.create', function (BreadcrumbTrail $trail) {
$trail->parent('memo.index');
$trail->push('Create', route('memo.index'));
});
// add andy
require __DIR__ . '/breadcrumbs_registrasi.php';

View File

@@ -398,14 +398,13 @@ Route::middleware(['auth'])->group(function () {
});
Route::resource('laporan', LaporanController::class);
// Memo Penyelesaian routes
Route::name('memo.')->prefix('memo')->group(function () {
Route::get('datatables', [MemoController::class, 'dataForDatatables'])->name('datatables');
Route::post('create-bulk', [MemoController::class, 'createBulk'])->name('create.bulk');
Route::group(['prefix' => 'memo'], 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::resource('memo', MemoController::class);
Route::name('resume.')->prefix('resume')->group(function () {
Route::get('/', [ResumeController::class, 'index'])->name('index');
Route::get('{id}/show', [ResumeController::class, 'show'])->name('show');