From 4aeecf6a97a03eaae9381498655456876d40d879 Mon Sep 17 00:00:00 2001 From: Daeng Deni Mardaeni Date: Mon, 15 Sep 2025 11:32:59 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(pembayaran):=20Implementasi=20fitur?= =?UTF-8?q?=20create=20pembayaran=20baru=20dengan=20autocomplete=20debitur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Menambahkan method create() di PembayaranController untuk menampilkan form pembayaran baru - Menambahkan logika create pembayaran di method store() dengan validasi type 'create' - Menambahkan penyimpanan data pembayaran baru ke tabel persetujuan_penawaran dan noc - Menambahkan upload bukti bayar dengan penyimpanan ke storage public - Menambahkan migration untuk kolom branch_id di tabel noc - Menambahkan view create.blade.php dengan form pembayaran lengkap dan autocomplete debitur - Menambahkan validasi JavaScript untuk format file dan ukuran maksimal 2MB - Menambahkan TomSelect untuk pencarian debitur dengan AJAX real-time - Menambahkan integrasi dengan API debitur search untuk autocomplete - Memperbaiki method edit() untuk mendukung parameter tiket dalam pencarian persetujuan penawaran - Mengubah query dataForDatatables untuk mendukung data dari persetujuan_penawaran dan permohonan - Menambahkan mapping data yang fleksibel untuk menampilkan informasi dari berbagai sumber - Menambahkan field nomor_tiket, nominal_bayar, dan catatan pada form create - Menambahkan validasi client-side untuk memastikan file upload sesuai format - Menambahkan relasi branch_id pada tabel noc untuk tracking cabang pembuat - Menambahkan redirect ke pembayaran.index setelah berhasil menyimpan pembayaran baru - Menambahkan import PhpParser\Node\Expr\Cast\Object_ (perlu dibersihkan) - Mengoptimalkan query dengan eager loading dan mapping data yang efisien - Menambahkan support untuk pembayaran tanpa permohonan (standalone payment) - Menambahkan field is_permohonan untuk membedakan jenis pembayaran - Menambahkan validasi dan error handling yang komprehensif --- app/Http/Controllers/PembayaranController.php | 94 +++-- ...9_15_034656_add_branch_id_to_noc_table.php | 28 ++ resources/views/pembayaran/create.blade.php | 322 ++++++++++++++++++ resources/views/pembayaran/form.blade.php | 4 +- resources/views/pembayaran/index.blade.php | 19 +- routes/api.php | 14 + routes/breadcrumbs_registrasi.php | 5 + 7 files changed, 456 insertions(+), 30 deletions(-) create mode 100644 database/migrations/2025_09_15_034656_add_branch_id_to_noc_table.php create mode 100644 resources/views/pembayaran/create.blade.php diff --git a/app/Http/Controllers/PembayaranController.php b/app/Http/Controllers/PembayaranController.php index 1a0af0a..1c7336f 100644 --- a/app/Http/Controllers/PembayaranController.php +++ b/app/Http/Controllers/PembayaranController.php @@ -12,6 +12,8 @@ use Illuminate\Support\Facades\Auth; use Modules\Lpj\Models\PenawaranTender; use Modules\Lpj\Models\PersetujuanPenawaran; use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest; +use PhpParser\Node\Expr\Cast\Object_; + class PembayaranController extends Controller { public $user; @@ -109,11 +111,23 @@ class PembayaranController extends Controller ]); } + public function create(){ + return view('lpj::pembayaran.create'); + } + public function edit($id) { - $permohonan = Permohonan::find($id); - $persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first(); + $req = request()->all(); + + if(isset($req['tiket'])){ + $persetujuanPenawaran = PersetujuanPenawaran::find($id); + $permohonan = Permohonan::find($persetujuanPenawaran?->permohonan_id); + } else { + $permohonan = Permohonan::find($id); + $persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first(); + } + return view('lpj::pembayaran.form', compact('permohonan', 'persetujuanPenawaran')); } @@ -130,8 +144,36 @@ class PembayaranController extends Controller $persetujuanPenawaran = PersetujuanPenawaran::where('permohonan_id', $permohonan->id)->first(); return view('lpj::pembayaran.form-lebih', compact('noc','permohonan','persetujuanPenawaran')); } + public function store(PersetujuanPenawaranRequest $request) { + $req = request()->all(); + + if($req['type'] == 'create'){ + $data = [ + 'nomor_tiket' => $req['nomor_tiket'] ?? '', + 'nominal_bayar' => $req['nominal_bayar'] ?? '', + 'catatan' => $req['catatan'] ?? '' + ]; + + if(request()->hasFile('bukti_bayar')){ + $folderPath = 'persetujuan_penawaran/bukti_bayar/' . $req['nomor_tiket']; + $data['bukti_bayar'] = $request->file('bukti_bayar')->store($folderPath, 'public'); + } + + $persetujuanPenawaran = PersetujuanPenawaran::create($data); + $noc = [ + 'persetujuan_penawaran_id' => $persetujuanPenawaran->id, + 'nomor_tiket' => $req['nomor_tiket'] ?? '', + 'debiture_id' => $req['debitur_id'] ?? '', + 'branch_id' => Auth::user()->branch_id, + ]; + Noc::create($noc); + + return redirect() + ->route('pembayaran.index')->with('success', 'Pembayaran berhasil disimpan.'); + } + if($req['type'] == 'kurang_bayar'){ $noc = Noc::find($req['noc_id']); $noc->nominal_pelunasan = $req['nominal_pelunasan']; @@ -307,31 +349,23 @@ class PembayaranController extends Controller // abort(403, 'Sorry! You are not allowed to view users.'); } - $query = Permohonan::query()->where(function ($query) { - $query->where(['status_bayar' => 'belum_bayar', 'jenis_penilaian_id' => 1]) - ->orWhere('status', 'revisi-pembayaran'); - }) - ->where(function ($query) { - $query->whereNotIn('id', function ($subquery) { - $subquery->select('permohonan_id') - ->from('persetujuan_penawaran') - ->whereNotNull('permohonan_id'); + $query = PersetujuanPenawaran::query(); + + $query->where(function($q) { + $q->whereRelation('permohonan', function($query) { + $query->where('status_bayar', 'belum_bayar') + ->where('jenis_penilaian_id', 1); }); }); + $query->orWhereRelation('permohonan','status_bayar','revisi-pembayaran'); + $query->orWhere(function($q) { + $q->where('permohonan_id',null); + $q->where('nomor_tiket','!=',null); + }); - - // Pencarian berdasarkan parameter search + // Pencarian berdasarkan parameter search if ($request->has('search') && !empty($request->get('search'))) { $search = $request->get('search'); - $query->where(function ($q) use ($search) { - $q->where('nomor_registrasi', 'LIKE', '%' . $search . '%'); - $q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%'); - $q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%'); - $q->orWhereRelation('debiture', 'name', 'LIKE', '%' . $search . '%'); - $q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%'); - $q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%'); - $q->orWhere('status', 'LIKE', '%' . $search . '%'); - }); } // Sorting berdasarkan sortField dan sortOrder @@ -361,7 +395,21 @@ class PembayaranController extends Controller $filteredRecords = $query->count(); // Ambil data dengan relasi - $data = $query->with(['user', 'debiture', 'branch', 'jenisPenilaian'])->get(); + $data = $query->get(); + + $data = $data->map(function ($item) { + return [ + 'id' => $item->permohonan?->id ?? $item->id, + 'nomor_registrasi' => $item->permohonan?->nomor_registrasi, + 'nomor_tiket' => $item->nomor_tiket ?? '', + 'debiture' => $item->permohonan?->debiture ?? $item->noc?->debiture, + 'user' => $item->permohonan?->user ?? $item->creator, + 'status_bayar' => $item->permohonan?->status_bayar ?? ($item->nomor_tiket ? 'Sudah Bayar' : ''), + 'tanggal_permohonan' => $item->permohonan?->tanggal_permohonan ?? '', + 'branch' => $item->permohonan?->branch ?? $item->noc?->branch, + 'is_permohonan' => $item->permohonan ?? '' + ]; + }); // Hitung jumlah halaman diff --git a/database/migrations/2025_09_15_034656_add_branch_id_to_noc_table.php b/database/migrations/2025_09_15_034656_add_branch_id_to_noc_table.php new file mode 100644 index 0000000..f873f92 --- /dev/null +++ b/database/migrations/2025_09_15_034656_add_branch_id_to_noc_table.php @@ -0,0 +1,28 @@ +bigInteger('branch_id')->nullable()->after('debiture_id'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('noc', function (Blueprint $table) { + $table->dropColumn('branch_id'); + }); + } +}; diff --git a/resources/views/pembayaran/create.blade.php b/resources/views/pembayaran/create.blade.php new file mode 100644 index 0000000..32cb84c --- /dev/null +++ b/resources/views/pembayaran/create.blade.php @@ -0,0 +1,322 @@ +@extends('layouts.main') + +@section('breadcrumbs') + {{ Breadcrumbs::render(request()->route()->getName()) }} +@endsection + +@section('content') +
+
+
+
+ Tambah Pembayaran +
+
+ Back +
+
+
+
+ @csrf + + + + + + +
+ +
+ + @error('debitur_id') + {{ $message }} + @enderror +
+
+ +
+ +
+ + @error('nomor_registrasi') + {{ $message }} + @enderror +
+
+ +
+ +
+ + @error('nomor_tiket') + {{ $message }} + @enderror +
+
+ +
+ +
+ + @error('nominal_bayar') + {{ $message }} + @enderror +
+
+ +
+ +
+ + Format yang diizinkan: PDF, JPG, JPEG, PNG (Max: 2MB) + @error('bukti_bayar') + {{ $message }} + @enderror +
+
+ +
+ +
+ + @error('catatan') + {{ $message }} + @enderror +
+
+ +
+ + Batal + + +
+
+
+
+
+@endsection + +@push('scripts') + +@endpush diff --git a/resources/views/pembayaran/form.blade.php b/resources/views/pembayaran/form.blade.php index b3daf9c..2550587 100644 --- a/resources/views/pembayaran/form.blade.php +++ b/resources/views/pembayaran/form.blade.php @@ -76,10 +76,10 @@ name="status_bayar" id="status_bayar"> @error('status_bayar') diff --git a/resources/views/pembayaran/index.blade.php b/resources/views/pembayaran/index.blade.php index 36f8e0e..3e3512e 100644 --- a/resources/views/pembayaran/index.blade.php +++ b/resources/views/pembayaran/index.blade.php @@ -21,6 +21,7 @@
Export to Excel + Tambah Pembayaran
@@ -212,11 +213,19 @@ actions: { title: 'Status', render: (item, data) => { - return `
- - - -
`; + if (data.is_permohonan) { + return `
+ + + +
`; + } else { + return `
+ + + +
`; + } }, } }, diff --git a/routes/api.php b/routes/api.php index 737f4b3..2578080 100644 --- a/routes/api.php +++ b/routes/api.php @@ -9,3 +9,17 @@ * is assigned the "api" middleware group. Enjoy building your API! * */ + +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Route; +use Modules\Lpj\Http\Controllers\Api\DebiturController; + +// Route untuk pencarian debitur (autocomplete) +Route::middleware(['web', 'auth'])->group(function () { + Route::get('/debitur/search', [DebiturController::class, 'search']) + ->name('debitur.search'); + + // Route untuk get detail debitur berdasarkan code + Route::get('/debitur/detail', [DebiturController::class, 'getByCode']) + ->name('debitur.detail'); +}); diff --git a/routes/breadcrumbs_registrasi.php b/routes/breadcrumbs_registrasi.php index 00b6067..cd9be58 100644 --- a/routes/breadcrumbs_registrasi.php +++ b/routes/breadcrumbs_registrasi.php @@ -109,6 +109,11 @@ Breadcrumbs::for('pembayaran', function (BreadcrumbTrail $trail) { $trail->push('Pembayaran', route('pembayaran.index')); }); +Breadcrumbs::for('pembayaran.create', function (BreadcrumbTrail $trail) { + $trail->parent('pembayaran'); + $trail->push('Buat Pembayaran'); + }); + Breadcrumbs::for('pembayaran.edit', function (BreadcrumbTrail $trail) { $trail->parent('pembayaran'); $trail->push('Lakukan Pembayaran');