feat(lampiran-dokumen): tambahkan fitur upload, download, dan delete lampiran dokumen
- Menambahkan controller LampiranDokumenController untuk mengelola lampiran dokumen. - Menambahkan model LampiranDokumen untuk interaksi dengan tabel lampiran_dokumen. - Membuat migrasi untuk tabel lampiran_dokumen dengan kolom yang diperlukan. - Menambahkan rute untuk mengupload, mendownload, dan menghapus lampiran dokumen. - Memperbarui tampilan detail-jaminan untuk menampilkan dan mengelola lampiran dokumen.
This commit is contained in:
44
app/Http/Controllers/LampiranDokumenController.php
Normal file
44
app/Http/Controllers/LampiranDokumenController.php
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Modules\Lpj\Models\LampiranDokumen;
|
||||
|
||||
class LampiranDokumenController extends Controller
|
||||
{
|
||||
public function download($id)
|
||||
{
|
||||
$lampiran = LampiranDokumen::findOrFail($id);
|
||||
return Storage::download($lampiran->path_file, $lampiran->nama_file);
|
||||
}
|
||||
|
||||
public function upload(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'permohonan_id' => 'required|exists:permohonan,id',
|
||||
'nama_file' => 'nullable|string|max:255',
|
||||
'file' => 'required|file|max:10240',
|
||||
'keterangan' => 'nullable|string|max:255',
|
||||
]);
|
||||
|
||||
$lampiran = LampiranDokumen::uploadLampiran($request->all());
|
||||
|
||||
if ($lampiran) {
|
||||
return response()->json(['message' => 'Lampiran uploaded successfully', 'data' => $lampiran]);
|
||||
} else {
|
||||
return response()->json(['message' => 'Unauthorized or upload failed'], 403);
|
||||
}
|
||||
}
|
||||
|
||||
public function delete(LampiranDokumen $lampiran)
|
||||
{
|
||||
if ($lampiran->deleteLampiran()) {
|
||||
return response()->json(['message' => 'Lampiran deleted successfully']);
|
||||
} else {
|
||||
return response()->json(['message' => 'Unauthorized or delete failed'], 403);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
app/Models/LampiranDokumen.php
Normal file
67
app/Models/LampiranDokumen.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Lpj\Models;
|
||||
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class LampiranDokumen extends Base
|
||||
{
|
||||
protected $table = 'lampiran_dokumen';
|
||||
|
||||
protected $fillable = ['permohonan_id', 'nama_file', 'path_file', 'keterangan'];
|
||||
|
||||
public function permohonan()
|
||||
{
|
||||
return $this->belongsTo(Permohonan::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload lampiran dokumen for penilai or administrator
|
||||
*
|
||||
* @param int $permohonanId
|
||||
* @param array $fileData
|
||||
* @return LampiranDokumen|null
|
||||
*/
|
||||
public static function uploadLampiran($fileData)
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user && ($user->hasRole('penilai') || $user->hasRole('administrator'))) {
|
||||
$file = $fileData['file'];
|
||||
$keterangan = $fileData['keterangan'] ?? null;
|
||||
|
||||
$fileName = $fileData['nama_file'] ?? time() . '_' . $file->getClientOriginalName();
|
||||
$filePath = $file->storeAs('lampiran_dokumen', $fileName, 'public');
|
||||
|
||||
return self::create([
|
||||
'permohonan_id' => $fileData['permohonan_id'] ?? null,
|
||||
'nama_file' => $fileName,
|
||||
'path_file' => $filePath,
|
||||
'keterangan' => $keterangan,
|
||||
]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete lampiran dokumen
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function deleteLampiran()
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user && ($user->hasRole('penilai') || $user->hasRole('administrator'))) {
|
||||
// Delete the file from storage
|
||||
Storage::disk('public')->delete($this->path_file);
|
||||
|
||||
// Delete the database record
|
||||
return $this->delete();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,8 @@
|
||||
return $this->belongsTo(JenisFasilitasKredit::class);
|
||||
}
|
||||
|
||||
public function jenisPenilaian(){
|
||||
public function jenisPenilaian()
|
||||
{
|
||||
return $this->belongsTo(JenisPenilaian::class);
|
||||
}
|
||||
|
||||
@@ -170,7 +171,8 @@
|
||||
return $this->belongsTo(Penilaian::class, 'nomor_registrasi', 'nomor_registrasi');
|
||||
}
|
||||
|
||||
public function penilai(){
|
||||
public function penilai()
|
||||
{
|
||||
return $this->belongsTo(Penilai::class, 'id', 'permohonan_id');
|
||||
}
|
||||
|
||||
@@ -199,27 +201,38 @@
|
||||
return $this->hasMany(DokumenJaminan::class);
|
||||
}
|
||||
|
||||
public function pembatalan(){
|
||||
public function pembatalan()
|
||||
{
|
||||
return $this->hasMany(PermohonanPembatalan::class);
|
||||
}
|
||||
|
||||
public function approveBayar(){
|
||||
public function approveBayar()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'approve_bayar_by', 'id');
|
||||
}
|
||||
|
||||
public function approveEo(){
|
||||
public function approveEo()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'approval_eo', 'id');
|
||||
}
|
||||
|
||||
public function approveDd(){
|
||||
public function approveDd()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'approval_dd', 'id');
|
||||
}
|
||||
|
||||
public function approveSo(){
|
||||
public function approveSo()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'approval_so', 'id');
|
||||
}
|
||||
|
||||
public function authorization(){
|
||||
public function authorization()
|
||||
{
|
||||
return $this->belongsTo(Authorization::class, 'id', 'permohonan_id');
|
||||
}
|
||||
|
||||
public function lampiranDokumen()
|
||||
{
|
||||
return $this->hasMany(LampiranDokumen::class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateLampiranDokumenTable extends Migration
|
||||
{
|
||||
public function up()
|
||||
{
|
||||
Schema::create('lampiran_dokumen', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('permohonan_id');
|
||||
$table->string('nama_file');
|
||||
$table->string('path_file');
|
||||
$table->text('keterangan')->nullable();
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
|
||||
$table->unsignedBigInteger('created_by')->nullable();
|
||||
$table->unsignedBigInteger('updated_by')->nullable();
|
||||
$table->unsignedBigInteger('deleted_by')->nullable();
|
||||
|
||||
$table->foreign('permohonan_id')->references('id')->on('permohonan')->onDelete('cascade');
|
||||
});
|
||||
}
|
||||
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('lampiran_dokumen');
|
||||
}
|
||||
}
|
||||
@@ -199,6 +199,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="card border border-agi-100 min-w-full">
|
||||
<div class="card-header light:bg-agi-50">
|
||||
<h3 class="card-title">
|
||||
@@ -348,6 +350,59 @@
|
||||
@if (!isset($status))
|
||||
</div>
|
||||
|
||||
<!-- New section for Lampiran Dokumen -->
|
||||
<div class="card border border-agi-100 min-w-full mt-5">
|
||||
<div class="card-header light:bg-agi-50">
|
||||
<h3 class="card-title">
|
||||
Lampiran Dokumen
|
||||
</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
@forelse($permohonan->lampiranDokumen as $lampiran)
|
||||
<div class="border p-4 rounded-lg">
|
||||
<h4 class="font-semibold mb-2">{{ $lampiran->nama_file }}</h4>
|
||||
<p class="text-sm text-gray-600 mb-2">Keterangan : {{ $lampiran->keterangan }}</p>
|
||||
<a href="{{ Storage::url($lampiran->path_file) }}" target="_blank" class="text-blue-600 hover:underline">
|
||||
<i class="ki-filled ki-eye mr-2"></i>View
|
||||
</a>
|
||||
<a href="{{ Storage::url($lampiran->path_file) }}" download="{{ Storage::url($lampiran->path_file) }}" class="text-green-600 hover:underline ml-4">
|
||||
<i class="ki-filled ki-cloud-download mr-2"></i>Download
|
||||
</a>
|
||||
</div>
|
||||
@empty
|
||||
<p class="col-span-3 text-center text-gray-500">Tidak ada lampiran dokumen.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
@if(Auth::user()->hasRole(['penilai', 'administrator']))
|
||||
<form action="{{ route('lampiran.upload',) }}" method="POST" enctype="multipart/form-data" class="mt-6">
|
||||
@csrf
|
||||
<input type="hidden" name="permohonan_id" value="{{ $permohonan->id }}">
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label for="nama_file" class="block text-sm font-medium text-gray-700">Nama File</label>
|
||||
<input type="text" name="nama_file" id="nama_file" required class="input mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
|
||||
</div>
|
||||
<div>
|
||||
<label for="file" class=" block text-sm font-medium text-gray-700">File</label>
|
||||
<input type="file" name="file" id="file" required class="file-input mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md">
|
||||
</div>
|
||||
<div class="md:col-span-2">
|
||||
<label for="keterangan" class="block text-sm font-medium text-gray-700">Keterangan</label>
|
||||
<textarea name="keterangan" id="keterangan" rows="3" class="textarea mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 rounded-md"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
||||
Upload Lampiran
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('lpj::component.history-permohonan')
|
||||
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@ use Modules\Lpj\Http\Controllers\JenisLaporanController;
|
||||
use Modules\Lpj\Http\Controllers\JenisLegalitasJaminanController;
|
||||
use Modules\Lpj\Http\Controllers\JenisPenilaianController;
|
||||
use Modules\Lpj\Http\Controllers\KJPPController;
|
||||
use Modules\Lpj\Http\Controllers\LaporanController;
|
||||
use Modules\Lpj\Http\Controllers\LampiranDokumenController;
|
||||
use Modules\Lpj\Http\Controllers\LaporanController;
|
||||
use Modules\Lpj\Http\Controllers\LaporanExternalController;
|
||||
use Modules\Lpj\Http\Controllers\NilaiPlafondController;
|
||||
use Modules\Lpj\Http\Controllers\NocController;
|
||||
@@ -645,6 +646,9 @@ Route::middleware(['auth'])->group(function () {
|
||||
});
|
||||
Route::resource('laporan-external', LaporanExternalController::class);
|
||||
|
||||
Route::get('/lampiran/download/{id}', [LampiranDokumenController::class, 'download'])->name('lampiran.download');
|
||||
Route::post('lampiran/upload', [LampiranDokumenController::class, 'upload'])->name('lampiran.upload');
|
||||
Route::delete('lampiran/{lampiran}', [LampiranDokumenController::class, 'delete'])->name('lampiran.delete');
|
||||
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user