Merge branch 'staging' of https://git.putrakuningan.com/daengdeni/lpj into tender

This commit is contained in:
2025-05-07 11:49:04 +07:00
8 changed files with 256 additions and 10 deletions

View File

@@ -123,7 +123,7 @@ class LaporanController extends Controller
$filteredRecords = $query->count(); $filteredRecords = $query->count();
// Get the data for the current page // Get the data for the current page
$data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian','jenisFasilitasKredit', 'documents.inspeksi','penilai','documents.detail'])->get(); $data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian','jenisFasilitasKredit', 'documents.inspeksi','penilai','documents.detail','noc'])->get();
// Calculate the page count // Calculate the page count
$pageCount = ceil($totalRecords / $size); $pageCount = ceil($totalRecords / $size);

View File

@@ -100,6 +100,27 @@
public function update(NocRequest $request, PersetujuanPenawaran $persetujuanPenawaran) public function update(NocRequest $request, PersetujuanPenawaran $persetujuanPenawaran)
{ {
$validated = $request->validated(); $validated = $request->validated();
if($request->get('is_memo')){
$memo = Noc::find($request->get('is_memo'));
$folderPath = 'noc/' . request()->get('persetujuan_penawaran_id') . '/memo_penyelesaian/';
if ($request->hasFile('memo_penyelesaian')) {
$memo->memo_penyelesaian = $request->file('memo_penyelesaian')->store(
$folderPath,
'public',
);
}
$memo->catatan_noc = $validated['catatan_noc'];
$memo->save();
return redirect()
->route('laporan.index')->with('success', 'Memo Penyelesaian updated successfully');
}
$dataNoc = [ $dataNoc = [
'nominal_penyelesaian' => $validated['nominal_penyelesaian'], 'nominal_penyelesaian' => $validated['nominal_penyelesaian'],
'tanggal_penyelesaian' => $validated['tanggal_penyelesaian'] ?? date('Y-m-d'), 'tanggal_penyelesaian' => $validated['tanggal_penyelesaian'] ?? date('Y-m-d'),
@@ -142,7 +163,11 @@
/** /**
* Display the specified resource. * Display the specified resource.
*/ */
public function show($id) {} public function show(Request $request) {
$noc = Noc::find($request->get('id'));
return view('lpj::noc.memo', compact('noc'));
}
/** /**
* Show the form for editing the specified resource. * Show the form for editing the specified resource.
@@ -216,10 +241,13 @@
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at, $persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
true, true,
), ),
'nominal_bayar' => currencyFormat( 'nominal_bayar' => currencyFormat($persetujuanPenawaran->nominal_bayar ?? 0,
$persetujuanPenawaran->noc->nominal_bayar ?? $persetujuanPenawaran->nominal_bayar ?? 0, ),
'nominal_diterima' => currencyFormat(
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
), ),
'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null, 'bukti_ksl' => $persetujuanPenawaran->noc->bukti_ksl ?? $persetujuanPenawaran->bukti_ksl ?? null,
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar ?? null,
'memo_penyelesaian' => $persetujuanPenawaran->noc->memo_penyelesaian ?? $persetujuanPenawaran->memo_penyelesaian ?? null, 'memo_penyelesaian' => $persetujuanPenawaran->noc->memo_penyelesaian ?? $persetujuanPenawaran->memo_penyelesaian ?? null,
'nominal_penyelesaian' => currencyFormat( 'nominal_penyelesaian' => currencyFormat(
$persetujuanPenawaran->noc->nominal_penyelesaian ?? $persetujuanPenawaran->nominal_penyelesaian ?? 0, $persetujuanPenawaran->noc->nominal_penyelesaian ?? $persetujuanPenawaran->nominal_penyelesaian ?? 0,

View File

@@ -237,8 +237,17 @@
const type = data.penilai?.type || ''; const type = data.penilai?.type || '';
let laporanButton = ''; let laporanButton = '';
let resumeButton = ''; let resumeButton = '';
let penyelesaian = '';
if(data.noc) {
if (!data.noc?.tanggal_penyelesaian && !data.noc?.memo_penyelesaian) {
penyelesaian = `
<a href="{{ route('noc.penyelesaian') }}?id=${data.noc.id}&permohonanId=${data.noc.permohonan_id}&persetujuanPenawaranId=${data.noc.persetujuan_penawaran_id}" class="btn btn-sm btn-warning">
Penyelesaian
</a>`;
}
}
if(data.penilai.resume) { if(data.penilai.resume) {
resumeButton = ` resumeButton = `
@@ -270,7 +279,7 @@
} }
return `<div class="flex flex-wrap justify-end gap-1.5"> ${resumeButton} ${laporanButton} </div>`; return `<div class="flex flex-wrap justify-end gap-1.5"> ${penyelesaian} ${resumeButton} ${laporanButton} </div>`;
}, },
} }
}, },

View File

@@ -8,7 +8,7 @@
$hasMemo = false; $hasMemo = false;
try { try {
$memoPath = $persetujuanPenawaran->noc->memo_penyelesaian ?? null; $memoPath = $persetujuanPenawaran->noc->memo_penyelesaian ?? null;
$hasMemo = isset($memoPath) && !empty($memoPath) && Storage::exists($memoPath); $hasMemo = isset($memoPath) && !empty($memoPath) && Storage::disk('public')->exists($memoPath);
} catch (Exception $e) { } catch (Exception $e) {
// Jika terjadi error, $hasMemo tetap false // Jika terjadi error, $hasMemo tetap false
} }
@@ -19,7 +19,7 @@
<div class="card border border-agi-100 pb-2.5"> <div class="card border border-agi-100 pb-2.5">
<div class="card-header bg-agi-50" id="basic_settings"> <div class="card-header bg-agi-50" id="basic_settings">
<div class="card-title flex flex-row gap-1.5"> <div class="card-title flex flex-row gap-1.5">
NOC {{ $hasMemo ? 'Proses Penyelesaian NOC' : 'NOC' }}
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<a href="{{ route('noc.index') }}" class="btn btn-xs btn-info"><i class="ki-filled ki-exit-left"></i> Back</a> <a href="{{ route('noc.index') }}" class="btn btn-xs btn-info"><i class="ki-filled ki-exit-left"></i> Back</a>
@@ -53,7 +53,22 @@
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5"> <div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56"> <label class="form-label max-w-56">
Total Harus Bayar Bukti Pembayaran
</label>
<div class="flex flex-wrap items-baseline w-full">
@if(!empty($persetujuanPenawaran->bukti_bayar))
<div class="mt-2 flex items-center">
<a href="{{ Storage::url($persetujuanPenawaran->bukti_bayar) }}" target="_blank" class="badge badge-sm badge-outline badge-warning">
<i class="ki-filled ki-eye mr-2"></i> Lihat File
</a>
</div>
@endif
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Nominal Bayar
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input type="number" name="total_harus_bayar" id="total_harus_bayar" class="input w-full @error('total_harus_bayar') border-danger bg-danger-light @enderror" value="{{ old('total_harus_bayar', $persetujuanPenawaran->nominal_bayar ?? '') }}" readonly> <input type="number" name="total_harus_bayar" id="total_harus_bayar" class="input w-full @error('total_harus_bayar') border-danger bg-danger-light @enderror" value="{{ old('total_harus_bayar', $persetujuanPenawaran->nominal_bayar ?? '') }}" readonly>
@@ -65,7 +80,7 @@
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5"> <div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56"> <label class="form-label max-w-56">
Nominal Bayar Nominal Diterima
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input type="number" name="nominal_bayar" id="nominal_bayar" class="input w-full @error('nominal_bayar') border-danger bg-danger-light @enderror" value="{{ old('nominal_bayar', $persetujuanPenawaran->noc->nominal_bayar ?? '') }}" placeholder="Masukkan nominal bayar" {{ $hasMemo ? 'readonly' : '' }}> <input type="number" name="nominal_bayar" id="nominal_bayar" class="input w-full @error('nominal_bayar') border-danger bg-danger-light @enderror" value="{{ old('nominal_bayar', $persetujuanPenawaran->noc->nominal_bayar ?? '') }}" placeholder="Masukkan nominal bayar" {{ $hasMemo ? 'readonly' : '' }}>
@@ -93,7 +108,7 @@
Bukti KSL Bukti KSL
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
@if($hasMemo) @if(!$hasMemo)
<input type="file" name="bukti_ksl" id="bukti_ksl" class="file-input w-full @error('bukti_ksl') border-danger bg-danger-light @enderror" accept=".pdf,.jpg,.jpeg,.png"> <input type="file" name="bukti_ksl" id="bukti_ksl" class="file-input w-full @error('bukti_ksl') border-danger bg-danger-light @enderror" accept=".pdf,.jpg,.jpeg,.png">
@error('bukti_ksl') @error('bukti_ksl')
<em class="alert text-danger text-sm">{{ $message }}</em> <em class="alert text-danger text-sm">{{ $message }}</em>

View File

@@ -53,6 +53,14 @@
<span class="sort"> <span class="sort-label"> Nominal bayar </span> <span class="sort"> <span class="sort-label"> Nominal bayar </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
</th> </th>
<th class="min-w-[150px]" data-datatable-column="bukti_bayar">
<span class="sort"> <span class="sort-label"> Bukti Bayar </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nominal_diterima">
<span class="sort"> <span class="sort-label"> Nominal Diterima </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="bukti_ksl"> <th class="min-w-[150px]" data-datatable-column="bukti_ksl">
<span class="sort"> <span class="sort-label"> Bukti KSL </span> <span class="sort"> <span class="sort-label"> Bukti KSL </span>
<span class="sort-icon"> </span> </span> <span class="sort-icon"> </span> </span>
@@ -153,6 +161,21 @@
nominal_bayar: { nominal_bayar: {
title: 'Nominal Bayar', title: 'Nominal Bayar',
}, },
bukti_bayar: {
title: 'Bukti KSL',
render: (item, data) => {
if (data.bukti_bayar) {
return `<a href="storage/${data.bukti_bayar}" download="storage/${data.bukti_bayar}" target="_blank" class="badge badge-sm badge-outline">
Download <i class="ki-filled ki-cloud-download"></i>
</a>`;
} else {
return '-';
}
},
},
nominal_diterima: {
title: 'Nominal Diterima',
},
bukti_ksl: { bukti_ksl: {
title: 'Bukti KSL', title: 'Bukti KSL',
render: (item, data) => { render: (item, data) => {

View File

@@ -0,0 +1,163 @@
@extends('layouts.main')
@section('breadcrumbs')
{{ Breadcrumbs::render(request()->route()->getName()) }}
@endsection
@section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<div class="card border border-agi-100 pb-2.5">
<div class="card-header bg-agi-50" id="basic_settings">
<div class="card-title flex flex-row gap-1.5">
Memo Penyelesaian NOC
</div>
<div class="flex items-center gap-2">
<a href="{{ route('noc.index') }}" class="btn btn-xs btn-info"><i class="ki-filled ki-exit-left"></i> Back</a>
</div>
</div>
<div class="card-body">
<form action="{{ route('noc.update',$noc) }}" method="POST" class="grid gap-5" enctype="multipart/form-data">
@csrf
@method('PUT')
<input type="hidden" name="persetujuan_penawaran_id" value="{{ $noc->persetujuan_penawaran_id }}">
<input type="hidden" name="permohonan_id" value="{{ $noc->permohonan_id }}">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Status Bayar
</label>
<div class="flex flex-wrap items-baseline w-full">
<select class="input tomselect w-full @error('status_pembayar') border-danger bg-danger-light @enderror" name="status_pembayar" id="status_pembayar" disabled>
<option value="">Pilih Status Bayar</option>
<option value="sudah_bayar" {{ (old('status_pembayar') == 'sudah_bayar') || ($noc?->permohonan?->status_bayar == 'sudah_bayar') ? 'selected' : '' }}>Sudah Bayar</option>
<option value="belum_bayar" {{ (old('status_pembayar') == 'belum_bayar') || ($noc?->permohonan?->status_bayar == 'belum_bayar') ? 'selected' : '' }}>Belum Bayar</option>
</select>
@error('status_bayar')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Bukti Pembayaran
</label>
<div class="flex flex-wrap items-baseline w-full">
@if(!empty($noc->persetujuanPenawaran->bukti_bayar))
<div class="mt-2 flex items-center">
<a href="{{ Storage::url($noc->persetujuanPenawaran->bukti_bayar) }}" target="_blank" class="badge badge-sm badge-outline badge-warning">
<i class="ki-filled ki-eye mr-2"></i> Lihat File
</a>
</div>
@endif
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Nominal Bayar
</label>
<div class="flex flex-wrap items-baseline w-full">
<input type="number" name="total_harus_bayar" id="total_harus_bayar" class="input w-full @error('total_harus_bayar') border-danger bg-danger-light @enderror" value="{{ old('total_harus_bayar', $noc->nominal_bayar ?? '') }}" readonly>
@error('total_harus_bayar')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Nominal Diterima
</label>
<div class="flex flex-wrap items-baseline w-full">
<input type="number" name="nominal_bayar" id="nominal_bayar" class="input w-full @error('nominal_bayar') border-danger bg-danger-light @enderror" value="{{ old('nominal_bayar', $noc->nominal_bayar ?? '') }}" placeholder="Masukkan nominal bayar" readonly>
@error('nominal_bayar')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Tanggal Pembayaran
</label>
<div class="flex flex-wrap items-baseline w-full">
<input type="date" name="tanggal_pembayaran" id="tanggal_pembayaran" class="input w-full @error('tanggal_pembayaran') border-danger bg-danger-light @enderror" value="{{ old('tanggal_pembayaran', isset($noc->tanggal_pembayaran) ? date('Y-m-d', strtotime($noc->tanggal_pembayaran)) : '') }}" readonly>
@error('tanggal_pembayaran')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Bukti KSL
</label>
<div class="flex flex-wrap items-baseline w-full">
@if(isset($noc->bukti_ksl) && !empty($noc->bukti_ksl))
<div class="mt-2 flex items-center">
<a href="{{ Storage::url($noc->bukti_ksl) }}" target="_blank" class="badge badge-sm badge-outline badge-warning">
<i class="ki-filled ki-eye mr-2"></i> Lihat File
</a>
</div>
@endif
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Memo Penyelesaian
</label>
<div class="flex flex-wrap items-baseline w-full">
<input type="hidden" name="is_memo" value="{{ $noc->id }}">
<input type="file" name="memo_penyelesaian" id="memo_penyelesaian" class="file-input w-full @error('memo_penyelesaian') border-danger bg-danger-light @enderror" accept=".pdf,.jpg,.jpeg,.png">
@error('memo_penyelesaian')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
@if(isset($noc->memo_penyelesaian) && !empty($noc->memo_penyelesaian))
<div class="mt-2 flex items-center">
<a href="{{ Storage::url($noc->memo_penyelesaian) }}" target="_blank" class="badge badge-sm badge-outline badge-warning">
<i class="ki-filled ki-eye mr-2"></i> Lihat File
</a>
</div>
@endif
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Catatan
</label>
<div class="flex flex-wrap items-baseline w-full">
<textarea name="catatan" id="catatan" rows="4" class="textarea w-full @error('catatan') border-danger bg-danger-light @enderror" readonly placeholder="Masukkan catatan">{{ old('catatan', $noc->catatan ?? '') }}</textarea>
@error('catatan')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Catatan NOC
</label>
<div class="flex flex-wrap items-baseline w-full">
<textarea name="catatan_noc" id="catatan_noc" rows="4" class="textarea w-full @error('catatan_noc') border-danger bg-danger-light @enderror" placeholder="Masukkan catatan noc">{{ old('catatan_noc', $noc->catatan_noc ?? '') }}</textarea>
@error('catatan_noc')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
<div class="flex justify-end">
<button type="submit" class="btn btn-primary">
Proses
</button>
</div>
</form>
</div>
</div>
</div>
@endsection

View File

@@ -678,6 +678,11 @@ Breadcrumbs::for('noc.edit', function (BreadcrumbTrail $trail) {
$trail->push('Proses NOC'); $trail->push('Proses NOC');
}); });
Breadcrumbs::for('noc.penyelesaian', function (BreadcrumbTrail $trail) {
$trail->parent('noc');
$trail->push('Proses Memo Penyelesaian NOC');
});
Breadcrumbs::for('laporan-external', function (BreadcrumbTrail $trail) { Breadcrumbs::for('laporan-external', function (BreadcrumbTrail $trail) {
$trail->push('Laporan External', route('laporan-external.index')); $trail->push('Laporan External', route('laporan-external.index'));
}); });

View File

@@ -654,6 +654,9 @@ Route::middleware(['auth'])->group(function () {
Route::get('noc/datatables', [NocController::class, 'dataForDatatables']) Route::get('noc/datatables', [NocController::class, 'dataForDatatables'])
->name('noc.datatables'); ->name('noc.datatables');
Route::get('noc/penyelesaian',[NocController::class, 'show'])->name('noc.penyelesaian');
Route::post('noc/penyelesaian',[NocController::class, 'penyelesaian'])->name('noc.store.penyelesaian');
Route::resource('noc', NocController::class); Route::resource('noc', NocController::class);