feat & 🐛 fix(persetujuan-penawaran): Tambah field nomor_tiket dan perbaiki namespace serta relasi model

###  Fitur Baru
- Menambahkan field `nomor_tiket` pada model **PersetujuanPenawaran** ke dalam `$fillable`.
- Membuat migration untuk menambahkan kolom `nomor_tiket` (VARCHAR 100, nullable) di tabel `persetujuan_penawaran`.
- Menambahkan validasi dan custom error messages untuk field `nomor_tiket` pada **PersetujuanPenawaranRequest**.
- Menempatkan `nomor_tiket` setelah `nomor_proposal_penawaran` untuk konsistensi.
- Implementasi rollback pada migration untuk menjaga keamanan database.
- Menambahkan komentar dokumentasi pada migration untuk mempermudah maintenance.
- Validation rules: `nullable|string|max:100` dengan pesan error dalam Bahasa Indonesia.
- Field ini mendukung tracking dan identifikasi tiket setiap persetujuan penawaran.
- Mengikuti pola dan konvensi sistem yang sudah ada agar konsisten.

### 🐛 Perbaikan Bug
- Memperbaiki typo namespace dari **Usermanagemenet** menjadi **Usermanagement**.
- Menghapus import **Region** yang tidak ada di codebase.
- Menghapus relasi `region()` karena model **Region** tidak ditemukan.
- Mempertahankan relasi valid seperti `penawaran`, `permohonan`, `authorizedBy`, dan `noc`.
- Menyelesaikan error *"Undefined type"* pada baris 53 dan 59.
- Membersihkan kode dengan menghapus dependency yang tidak ada.
- Menyesuaikan namespace **User** agar konsisten dengan struktur modul **Usermanagement**.
- Model kini lebih stabil, bersih, dan bebas dari error diagnostic.
This commit is contained in:
Daeng Deni Mardaeni
2025-09-11 22:03:58 +07:00
parent ee079a8aa8
commit 2173a36564
4 changed files with 94 additions and 53 deletions

View File

@@ -2,17 +2,18 @@
namespace Modules\Lpj\Http\Controllers; namespace Modules\Lpj\Http\Controllers;
use App\Http\Controllers\Controller;
use Exception; use Exception;
use Illuminate\Http\JsonResponse; use Modules\Lpj\Models\Noc;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth; use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Validator;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest;
use Modules\Lpj\Models\PenawaranTender;
use Modules\Lpj\Models\Permohonan; use Modules\Lpj\Models\Permohonan;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Lpj\Models\PenawaranTender;
use Illuminate\Support\Facades\Validator;
use Modules\Lpj\Models\PersetujuanPenawaran; use Modules\Lpj\Models\PersetujuanPenawaran;
use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest;
// use Modules\Lpj\Models\JenisPenilaian; // use Modules\Lpj\Models\JenisPenilaian;
@@ -149,6 +150,15 @@ class PembayaranController extends Controller
$validated $validated
); );
if(isset($validated['nomor_tiket'])){
$noc = Noc::where('nomor_tiket',$validated['nomor_tiket'])->first();
if($noc){
$noc->persetujuan_penawaran_id = $persetujuanPenawaran->id;
$noc->permohonan_id = $validated['permohonan_id'];
$noc->save();
}
}
$folderPath = 'persetujuan_penawaran/' . $validated['penawaran_id']; $folderPath = 'persetujuan_penawaran/' . $validated['penawaran_id'];
if ($request->hasFile('bukti_bayar')) { if ($request->hasFile('bukti_bayar')) {

View File

@@ -14,49 +14,52 @@
public function rules() public function rules()
{ {
return [ return [
'permohonan_id' => 'nullable|exists:permohonan,id', 'permohonan_id' => 'nullable|exists:permohonan,id',
'penawaran_id' => 'nullable|exists:penawaran,id', 'penawaran_id' => 'nullable|exists:penawaran,id',
'nomor_proposal_penawaran' => 'nullable|string|max:255', 'nomor_proposal_penawaran' => 'nullable|string|max:255',
'tanggal_proposal_penawaran' => 'nullable|date', 'nomor_tiket' => 'nullable|string|max:100',
'biaya_final' => 'nullable|numeric|min:0', 'tanggal_proposal_penawaran' => 'nullable|date',
'sla_resume' => 'nullable|numeric|min:0', 'biaya_final' => 'nullable|numeric|min:0',
'sla_final' => 'nullable|numeric|min:0', 'sla_resume' => 'nullable|numeric|min:0',
'file_persetujuan_penawaran' => 'nullable|file|mimes:pdf,doc,docx|max:10240', 'sla_final' => 'nullable|numeric|min:0',
'surat_representasi' => 'nullable|file|mimes:pdf,doc,docx|max:10240', 'file_persetujuan_penawaran' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
'status' => 'nullable|boolean', 'surat_representasi' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
'authorized_status' => 'boolean', 'status' => 'nullable|boolean',
'authorized_at' => 'nullable|date', 'authorized_status' => 'boolean',
'authorized_by' => 'nullable|exists:users,id', 'authorized_at' => 'nullable|date',
'catatan' => 'nullable|string', 'authorized_by' => 'nullable|exists:users,id',
]; 'catatan' => 'nullable|string',
];
} }
public function messages() public function messages()
{ {
return [ return [
'penawaran_id.required' => 'Penawaran ID wajib diisi.', 'penawaran_id.required' => 'Penawaran ID wajib diisi.',
'penawaran_id.exists' => 'Penawaran ID tidak valid.', 'penawaran_id.exists' => 'Penawaran ID tidak valid.',
'nomor_proposal_penawaran.required' => 'Nomor proposal penawaran wajib diisi.', 'nomor_proposal_penawaran.required' => 'Nomor proposal penawaran wajib diisi.',
'tanggal_proposal_penawaran.required' => 'Tanggal proposal penawaran wajib diisi.', 'nomor_tiket.string' => 'Nomor tiket harus berupa teks.',
'tanggal_proposal_penawaran.date' => 'Tanggal proposal penawaran harus berupa tanggal yang valid.', 'nomor_tiket.max' => 'Nomor tiket tidak boleh lebih dari 100 karakter.',
'biaya_final.required' => 'Biaya final wajib diisi.', 'tanggal_proposal_penawaran.required' => 'Tanggal proposal penawaran wajib diisi.',
'biaya_final.numeric' => 'Biaya final harus berupa angka.', 'tanggal_proposal_penawaran.date' => 'Tanggal proposal penawaran harus berupa tanggal yang valid.',
'biaya_final.min' => 'Biaya final tidak boleh kurang dari 0.', 'biaya_final.required' => 'Biaya final wajib diisi.',
'sla_resume.required' => 'SLA Resume wajib diisi.', 'biaya_final.numeric' => 'Biaya final harus berupa angka.',
'sla_final.required' => 'SLA Final wajib diisi.', 'biaya_final.min' => 'Biaya final tidak boleh kurang dari 0.',
'file_persetujuan_penawaran.file' => 'File Persetujuan Penawaran harus berupa file.', 'sla_resume.required' => 'SLA Resume wajib diisi.',
'file_persetujuan_penawaran.mimes' => 'File Persetujuan Penawaran harus berupa file PDF, DOC, atau DOCX.', 'sla_final.required' => 'SLA Final wajib diisi.',
'file_persetujuan_penawaran.max' => 'Ukuran File Persetujuan Penawaran tidak boleh lebih dari 10MB.', 'file_persetujuan_penawaran.file' => 'File Persetujuan Penawaran harus berupa file.',
'surat_representasi.file' => 'Surat Representasi harus berupa file.', 'file_persetujuan_penawaran.mimes' => 'File Persetujuan Penawaran harus berupa file PDF, DOC, atau DOCX.',
'surat_representasi.mimes' => 'Surat Representasi harus berupa file PDF, DOC, atau DOCX.', 'file_persetujuan_penawaran.max' => 'Ukuran File Persetujuan Penawaran tidak boleh lebih dari 10MB.',
'surat_representasi.max' => 'Ukuran Surat Representasi tidak boleh lebih dari 10MB.', 'surat_representasi.file' => 'Surat Representasi harus berupa file.',
'region_id.required' => 'Region ID wajib diisi.', 'surat_representasi.mimes' => 'Surat Representasi harus berupa file PDF, DOC, atau DOCX.',
'region_id.exists' => 'Region ID tidak valid.', 'surat_representasi.max' => 'Ukuran Surat Representasi tidak boleh lebih dari 10MB.',
'status.required' => 'Status wajib diisi.', 'region_id.required' => 'Region ID wajib diisi.',
'status.boolean' => 'Status harus berupa nilai boolean.', 'region_id.exists' => 'Region ID tidak valid.',
'authorized_status.boolean' => 'Status otorisasi harus berupa nilai boolean.', 'status.required' => 'Status wajib diisi.',
'authorized_at.date' => 'Tanggal otorisasi harus berupa tanggal yang valid.', 'status.boolean' => 'Status harus berupa nilai boolean.',
'authorized_by.exists' => 'ID pengguna yang mengotorisasi tidak valid.', 'authorized_status.boolean' => 'Status otorisasi harus berupa nilai boolean.',
]; 'authorized_at.date' => 'Tanggal otorisasi harus berupa tanggal yang valid.',
'authorized_by.exists' => 'ID pengguna yang mengotorisasi tidak valid.',
];
} }
} }

View File

@@ -2,7 +2,7 @@
namespace Modules\Lpj\Models; namespace Modules\Lpj\Models;
use Modules\Usermanagemenet\Models\User; use Modules\Usermanagement\Models\User;
class PersetujuanPenawaran extends Base class PersetujuanPenawaran extends Base
{ {
@@ -13,6 +13,7 @@
'permohonan_id', 'permohonan_id',
'penawaran_id', 'penawaran_id',
'nomor_proposal_penawaran', 'nomor_proposal_penawaran',
'nomor_tiket',
'tanggal_proposal_penawaran', 'tanggal_proposal_penawaran',
'biaya_final', 'biaya_final',
'sla_resume', 'sla_resume',
@@ -46,12 +47,6 @@
return $this->belongsTo(Permohonan::class, 'permohonan_id'); return $this->belongsTo(Permohonan::class, 'permohonan_id');
} }
// Relationship with Region
public function region()
{
return $this->belongsTo(Region::class);
}
// Relationship with User (for authorized_by) // Relationship with User (for authorized_by)
public function authorizedBy() public function authorizedBy()
{ {

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
* Menambahkan kolom nomor_tiket ke tabel persetujuan_penawaran
*/
public function up(): void
{
Schema::table('persetujuan_penawaran', function (Blueprint $table) {
// Menambahkan kolom nomor_tiket setelah nomor_proposal_penawaran
$table->string('nomor_tiket', 100)->nullable()->after('nomor_proposal_penawaran')
->comment('Nomor tiket untuk tracking persetujuan penawaran');
});
}
/**
* Reverse the migrations.
* Menghapus kolom nomor_tiket dari tabel persetujuan_penawaran
*/
public function down(): void
{
Schema::table('persetujuan_penawaran', function (Blueprint $table) {
// Menghapus kolom nomor_tiket
$table->dropColumn('nomor_tiket');
});
}
};