Perbaiki validasi, logika, dan tampilan terkait dokumen jaminan

- Menambahkan validasi untuk `permohonan_id` pada `DokumenJaminanRequest`.
- Memperbaiki logika penggabungan parameter query untuk rute tertentu.
- Merapikan formatting kode pada tampilan blade, termasuk elemen HTML dan JavaScript.
- Mengatasi beberapa bug minor terkait aksi dan tampilan dokumen jaminan.
This commit is contained in:
Daeng Deni Mardaeni
2024-12-27 09:36:07 +07:00
parent 407306e085
commit 66b8a9053b
4 changed files with 88 additions and 86 deletions

View File

@@ -146,7 +146,6 @@
$debitur = Debiture::find($id);
$validate = $request->validated();
if ($validate) {
try {
DB::beginTransaction();

View File

@@ -13,16 +13,17 @@
: array
{
$rules = [
'debiture_id' => 'required|exists:debitures,id',
'pemilik_jaminan_id' => 'required',
'jenis_jaminan_id' => 'required',
'province_code' => 'nullable|exists:provinces,code',
'city_code' => 'nullable|exists:cities,code',
'district_code' => 'nullable|exists:districts,code',
'village_code' => 'nullable|exists:villages,code',
'address' => 'nullable|string',
'postal_code' => 'nullable|string|max:10',
'status' => 'nullable|boolean',
'debiture_id' => 'required|exists:debitures,id',
'permohonan_id' => 'required|exists:permohonan,id',
'pemilik_jaminan_id' => 'required',
'jenis_jaminan_id' => 'required',
'province_code' => 'nullable|exists:provinces,code',
'city_code' => 'nullable|exists:cities,code',
'district_code' => 'nullable|exists:districts,code',
'village_code' => 'nullable|exists:villages,code',
'address' => 'nullable|string',
'postal_code' => 'nullable|string|max:10',
'status' => 'nullable|boolean',
];
return $rules;

View File

@@ -3,7 +3,7 @@
@method('PUT')
@endif
@csrf
<input type="hidden" name="permohonan_id" value="{{ $document->id ?? request()->get('permohonan_id') }}">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Debitur
@@ -427,13 +427,13 @@
@push('scripts')
{{--Pemilik Jaminan--}}
<script>
document.addEventListener("DOMContentLoaded", function () {
document.addEventListener("DOMContentLoaded", function() {
const namaSertifikatDiv = document.getElementById("nama_sertifikat");
// Function to add delete event listeners to existing buttons
function addDeleteListeners() {
document.querySelectorAll(".delete-button").forEach(button => {
button.addEventListener("click", function () {
button.addEventListener("click", function() {
this.closest(".flex.items-baseline.flex-wrap.lg\\:flex-nowrap.gap-2\\.5.mb-5").remove();
});
});
@@ -442,7 +442,7 @@
// Add delete listeners to existing buttons
addDeleteListeners();
document.getElementById("tambah_sertifikat").addEventListener("click", function () {
document.getElementById("tambah_sertifikat").addEventListener("click", function() {
const newDiv = document.createElement("div");
newDiv.className = "flex items-baseline flex-wrap lg:flex-nowrap gap-2.5 mb-5";
newDiv.innerHTML = `
@@ -509,7 +509,7 @@
${index + 1}. ${item.name}
</label>
<input type="hidden" name="jenis_legalitas_jaminan_id[]" value="${item.jenis_legalitas_jaminan_id}">
${item.is_existing ? `<input type="hidden" name="detail_dokumen_jaminan_id[]" value="${item.id}">` : ''}
${item.is_existing ? `<input type="hidden" name="detail_dokumen_jaminan_id[]" value="${item.id}">` : ""}
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
@@ -517,7 +517,7 @@
Nomor
</label>
<div class="flex flex-wrap items-baseline w-full">
<input class="input" type="text" name="name[]" value="${item.name || ''}" placeholder="Nomor">
<input class="input" type="text" name="name[]" value="${item.name || ""}" placeholder="Nomor">
</div>
</div>
@@ -527,7 +527,7 @@
</label>
<div class="flex flex-wrap items-baseline w-full" id="file-container-${index}">
<div class="flex flex-col w-full gap-2">
${item.dokumen_jaminan ? renderExistingFiles(item.dokumen_jaminan, debiturId, item.id, item.dokumen_nomor) : ''}
${item.dokumen_jaminan ? renderExistingFiles(item.dokumen_jaminan, debiturId, item.id, item.dokumen_nomor) : ""}
</div>
<div class="flex items-center gap-2 my-2 w-full">
<input class="flex-1 input" type="text" name="dokumen_nomor[${index}][]" placeholder="Nomor Dokumen">
@@ -546,26 +546,26 @@
${getCustomFieldInput(item.custom_field_type, item.custom_field, item.details)}
</div>
</div>
` : ''}
` : ""}
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Keterangan
</label>
<div class="flex flex-wrap items-baseline w-full">
<textarea class="textarea" rows="3" name="keterangan[]">${item.keterangan || ''}</textarea>
<textarea class="textarea" rows="3" name="keterangan[]">${item.keterangan || ""}</textarea>
</div>
</div>
`;
});
})
.catch(error => console.error('Error:', error));
.catch(error => console.error("Error:", error));
}
function addFileInput(index) {
const container = document.getElementById(`file-container-${index}`);
const newInput = document.createElement('div');
newInput.className = 'flex items-center gap-2 mb-2 w-full';
const newInput = document.createElement("div");
newInput.className = "flex items-center gap-2 mb-2 w-full";
newInput.innerHTML = `
<input class="flex-1 input" type="text" name="dokumen_nomor[${index}][]" placeholder="Nomor Dokumen">
<input class="flex-1 file-input" type="file" name="dokumen_jaminan[${index}][]" accept=".pdf,image/*">
@@ -575,60 +575,60 @@
}
function removeFileInput(button) {
button.closest('.flex.items-center.gap-2.mb-2').remove();
button.closest(".flex.items-center.gap-2.mb-2").remove();
}
function renderExistingFiles(dokumenJaminan, debiturId, itemId, dokumenNomor) {
if (typeof dokumenJaminan === 'string' && typeof dokumenNomor === 'string') {
if (typeof dokumenJaminan === "string" && typeof dokumenNomor === "string") {
return `
<div class="flex w-full lg:w-[30%]">
<span class="flex-1 mt-2 text-info text-sm">Nomor Dokumen : ${dokumenNomor}</span>
<a href="/debitur/${debiturId}/jaminan/download?dokumen=${itemId}" class="flex-none badge badge-sm badge-outline mt-2">
${dokumenJaminan.split('/').pop()}
${dokumenJaminan.split("/").pop()}
<i class="ki-filled ki-cloud-download"></i>
</a>
</div>
`;
} else if (typeof dokumenJaminan === 'string' && dokumenNomor === null) {
} else if (typeof dokumenJaminan === "string" && dokumenNomor === null) {
return `
<div class="flex w-full lg:w-[30%]">
<span class="flex-1 mt-2 text-info text-sm">Nomor Dokumen : --</span>
<a href="/debitur/${debiturId}/jaminan/download?dokumen=${itemId}" class="flex-none badge badge-sm badge-outline mt-2">
${dokumenJaminan.split('/').pop()}
${dokumenJaminan.split("/").pop()}
<i class="ki-filled ki-cloud-download"></i>
</a>
</div>
`;
} else if (Array.isArray(dokumenJaminan) && Array.isArray(dokumenNomor)) {
return dokumenJaminan.map((file, index) => `<div class="flex w-full lg:w-[30%]">
<span class="flex-1 mt-2 text-info text-sm">Nomor Dokumen : ${dokumenNomor[index] || 'N/A'}</span>
<span class="flex-1 mt-2 text-info text-sm">Nomor Dokumen : ${dokumenNomor[index] || "N/A"}</span>
<a href="/debitur/${debiturId}/jaminan/download?dokumen=${itemId}&file=${file}" class="flex-none badge badge-sm badge-outline mt-2 mr-2">
${file.split('/').pop()}
${file.split("/").pop()}
<i class="ki-filled ki-cloud-download"></i>
</a></div>
`).join('');
} else if (Array.isArray(dokumenJaminan) && typeof dokumenNomor === 'string') {
`).join("");
} else if (Array.isArray(dokumenJaminan) && typeof dokumenNomor === "string") {
return dokumenJaminan.map((file, index) => `<div class="flex w-full lg:w-[30%]">
<span class="flex-1 mt-2 text-info text-sm">Nomor Dokumen : ${dokumenNomor} || 'N/A'}</span>
<a href="/debitur/${debiturId}/jaminan/download?dokumen=${itemId}&file=${file}" class="flex-none badge badge-sm badge-outline mt-2 mr-2">
${file.split('/').pop()}
${file.split("/").pop()}
<i class="ki-filled ki-cloud-download"></i>
</a></div>
`).join('');
} else if (Array.isArray(dokumenJaminan) && dokumenNomor === 'null') {
`).join("");
} else if (Array.isArray(dokumenJaminan) && dokumenNomor === "null") {
return dokumenJaminan.map((file, index) => `<div class="flex w-full lg:w-[30%]">
<span class="flex-1 mt-2 text-info text-sm">Nomor Dokumen : ${dokumenNomor} || 'N/A'}</span>
<a href="/debitur/${debiturId}/jaminan/download?dokumen=${itemId}&file=${file}" class="flex-none badge badge-sm badge-outline mt-2 mr-2">
${file.split('/').pop()}
${file.split("/").pop()}
<i class="ki-filled ki-cloud-download"></i>
</a></div>
`).join('');
`).join("");
}
return dokumenNomor;
}
function getCustomFieldInput(type, fieldName, value) {
value = value ? JSON.parse(value)[fieldName] || '' : '';
value = value ? JSON.parse(value)[fieldName] || "" : "";
switch (type) {
case "text":
return `<input class="input" type="text" name="custom_field[][${fieldName}]" value="${value}">`;

View File

@@ -24,11 +24,11 @@
<div class="menu inline-flex" data-menu="true">
<div class="flex flex-nowrap justify-center gap-1.5">
@if(in_array(Auth::user()->roles[0]->name,['administrator','pemohon-eo']))
<a href="{{ route('debitur.jaminan.bulk.download',['id' => $debitur->id,'jaminan' => $document->id]) }}" class="btn btn-sm btn-icon btn-dark">
<i class="ki-outline ki-cloud-download"></i>
</a>
<a href="{{ route('debitur.jaminan.bulk.download',['id' => $debitur->id,'jaminan' => $document->id]) }}" class="btn btn-sm btn-icon btn-dark">
<i class="ki-outline ki-cloud-download"></i>
</a>
@endif
<a href="{{ route('debitur.jaminan.edit',['id' => $debitur->id,'jaminan' => $document->id]) }}" class="btn btn-sm btn-icon btn-outline btn-info">
<a href="{{ route('debitur.jaminan.edit',array_merge(request()->query(),['id' => $debitur->id,'jaminan' => $document->id])) }}" class="btn btn-sm btn-icon btn-outline btn-info">
<i class="ki-outline ki-notepad-edit"></i>
</a>
<a onclick="deleteData({{ $document->id }})" class="delete btn btn-sm btn-icon btn-outline btn-danger">
@@ -43,7 +43,7 @@
pemilik jaminan
</span>
<p class="text-2xs text-gray-600 text-right max-w-[250px]">
{{ $document->pemilik->name }}
{{ $document->pemilik->name }}
</p>
</div>
<div class="border-t border-gray-300 border-dashed">
@@ -77,14 +77,14 @@
$dokumen_nomor = is_array(json_decode($detail->dokumen_nomor)) ? json_decode($detail->dokumen_nomor) : ($detail->dokumen_nomor ? [$detail->dokumen_nomor] : []);
@endphp
@foreach($dokumen_jaminan as $index => $dokumen)
@if(in_array(Auth::user()->roles[0]->name,['administrator','pemohon-eo']))
<a href="{{ route('debitur.jaminan.download', ['id' => $debitur->id, 'dokumen' => $detail->id, 'index' => $index]) }}"
class="flex-none badge badge-sm badge-outline mt-2 mr-2">
{{ basename($dokumen) }}
<i class="ki-filled ki-cloud-download"></i>
</a>
@endif
<span class="badge badge-sm badge-outline badge-warning mt-2" onclick="viewPDF('{{ Storage::url($dokumen_jaminan[$index]) }}')"><i class="ki-filled ki-eye mr-2"></i>Preview</span>
@if(in_array(Auth::user()->roles[0]->name,['administrator','pemohon-eo']))
<a href="{{ route('debitur.jaminan.download', ['id' => $debitur->id, 'dokumen' => $detail->id, 'index' => $index]) }}"
class="flex-none badge badge-sm badge-outline mt-2 mr-2">
{{ basename($dokumen) }}
<i class="ki-filled ki-cloud-download"></i>
</a>
@endif
<span class="badge badge-sm badge-outline badge-warning mt-2" onclick="viewPDF('{{ Storage::url($dokumen_jaminan[$index]) }}')"><i class="ki-filled ki-eye mr-2"></i>Preview</span>
<br>
@endforeach
@endif
@@ -115,38 +115,40 @@
background-image: url('/assets/media/images/2600x1200/bg-4-dark.png');
}
</style>
<a class="card border-2 border-dashed border-brand-clarity bg-center bg-[length:600px] bg-no-repeat add-new-bg" href="{{ route('debitur.jaminan.create',$debitur->id) }}">
<div class="card-body grid items-center">
<div class="flex flex-col gap-3">
<div class="flex justify-center pt-5">
<div class="relative size-[60px] shrink-0">
<svg class="w-full h-full stroke-brand-clarity fill-light" fill="none" height="48" viewBox="0 0 44 48" width="44" xmlns="http://www.w3.org/2000/svg">
<path d="M16 2.4641C19.7128 0.320509 24.2872 0.320508 28 2.4641L37.6506 8.0359C41.3634 10.1795 43.6506 14.141 43.6506
@if(request()->get('permohonan_id'))
<a class="card border-2 border-dashed border-brand-clarity bg-center bg-[length:600px] bg-no-repeat add-new-bg" href="{{ route('debitur.jaminan.create',array_merge(request()->query(),['id'=>$debitur->id])) }}">
<div class="card-body grid items-center">
<div class="flex flex-col gap-3">
<div class="flex justify-center pt-5">
<div class="relative size-[60px] shrink-0">
<svg class="w-full h-full stroke-brand-clarity fill-light" fill="none" height="48" viewBox="0 0 44 48" width="44" xmlns="http://www.w3.org/2000/svg">
<path d="M16 2.4641C19.7128 0.320509 24.2872 0.320508 28 2.4641L37.6506 8.0359C41.3634 10.1795 43.6506 14.141 43.6506
18.4282V29.5718C43.6506 33.859 41.3634 37.8205 37.6506 39.9641L28 45.5359C24.2872 47.6795 19.7128 47.6795 16 45.5359L6.34937
39.9641C2.63655 37.8205 0.349365 33.859 0.349365 29.5718V18.4282C0.349365 14.141 2.63655 10.1795 6.34937 8.0359L16 2.4641Z" fill="">
</path>
<path d="M16.25 2.89711C19.8081 0.842838 24.1919 0.842837 27.75 2.89711L37.4006 8.46891C40.9587 10.5232 43.1506 14.3196 43.1506
</path>
<path d="M16.25 2.89711C19.8081 0.842838 24.1919 0.842837 27.75 2.89711L37.4006 8.46891C40.9587 10.5232 43.1506 14.3196 43.1506
18.4282V29.5718C43.1506 33.6804 40.9587 37.4768 37.4006 39.5311L27.75 45.1029C24.1919 47.1572 19.8081 47.1572 16.25 45.1029L6.59937
39.5311C3.04125 37.4768 0.849365 33.6803 0.849365 29.5718V18.4282C0.849365 14.3196 3.04125 10.5232 6.59937 8.46891L16.25 2.89711Z" stroke="">
</path>
</svg>
<div class="absolute leading-none left-2/4 top-2/4 -translate-y-2/4 -translate-x-2/4">
<i class="ki-filled ki-additem text-2xl text-brand">
</i>
</path>
</svg>
<div class="absolute leading-none left-2/4 top-2/4 -translate-y-2/4 -translate-x-2/4">
<i class="ki-filled ki-additem text-2xl text-brand">
</i>
</div>
</div>
</div>
</div>
<div class="flex flex-col text-center">
<span class="text-lg font-semibold text-gray-900 hover:text-primary-active mb-px">
Data Jaminan
</span>
<span class="text-2sm font-normal text-gray-600">
Tambah Pemilik dan Dokumen Jaminan
</span>
<div class="flex flex-col text-center">
<span class="text-lg font-semibold text-gray-900 hover:text-primary-active mb-px">
Data Jaminan
</span>
<span class="text-2sm font-normal text-gray-600">
Tambah Pemilik dan Dokumen Jaminan
</span>
</div>
</div>
</div>
</div>
</a>
</a>
@endif
</div>
@include('lpj::component.pdfviewer')
@@ -155,33 +157,33 @@
<script type="text/javascript">
function deleteData(data) {
Swal.fire({
title: 'Are you sure?',
title: "Are you sure?",
text: "You won't be able to revert this!",
icon: 'warning',
icon: "warning",
showCancelButton: true,
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Yes, delete it!'
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Yes, delete it!"
}).then((result) => {
if (result.isConfirmed) {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}'
"X-CSRF-TOKEN": '{{ csrf_token() }}'
}
});
$.ajax(`debitur/{{$debitur->id}}}/jaminan/${data}`, {
type: 'DELETE'
type: "DELETE"
}).then((response) => {
swal.fire('Deleted!', 'Document Jaminan has been deleted.', 'success').then(() => {
swal.fire("Deleted!", "Document Jaminan has been deleted.", "success").then(() => {
window.location.reload();
});
}).catch((error) => {
console.error('Error:', error);
Swal.fire('Error!', 'An error occurred while deleting the file.', 'error');
console.error("Error:", error);
Swal.fire("Error!", "An error occurred while deleting the file.", "error");
});
}
})
});
}
</script>
@endpush