Merge remote-tracking branch 'origin/tender' into staging

This commit is contained in:
Daeng Deni Mardaeni
2024-10-08 17:16:29 +07:00
10 changed files with 201 additions and 41 deletions

View File

@@ -5,8 +5,6 @@ namespace Modules\Lpj\Http\Controllers;
use Exception; use Exception;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Modules\Lpj\Models\KJPP; use Modules\Lpj\Models\KJPP;
use Illuminate\Http\Response;
use Modules\Lpj\Models\Penawaran;
use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\DB;
use Modules\Lpj\Models\Permohonan; use Modules\Lpj\Models\Permohonan;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
@@ -36,8 +34,14 @@ class TenderController extends Controller
*/ */
public function penawaran_create($noreg) public function penawaran_create($noreg)
{ {
$penawaran = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first(); $penawaranExists = PenawaranTender::where('nomor_registrasi', '=', $noreg)->exists();
// Jika nomor_registrasi sudah ada, kembalikan respon 403 Forbidden
if ($penawaranExists) {
abort(403, 'Penawaran dengan nomor registrasi ini sudah ada.');
}
$permohonan = Permohonan::where('nomor_registrasi', '=', $noreg)->first();
$status = StatusPermohonan::all(); $status = StatusPermohonan::all();
$tujuan_penilaian_kjpp = TujuanPenilaianKJPP::all(); $tujuan_penilaian_kjpp = TujuanPenilaianKJPP::all();
@@ -45,7 +49,7 @@ class TenderController extends Controller
$kjpp = KJPP::all(); $kjpp = KJPP::all();
return view('lpj::penawaran/create', compact('status', 'tujuan_penilaian_kjpp', 'jenis_laporan', 'kjpp', 'penawaran', 'noreg')); return view('lpj::penawaran/create', compact('status', 'tujuan_penilaian_kjpp', 'jenis_laporan', 'kjpp', 'noreg', 'permohonan'));
} }
/** /**
@@ -58,12 +62,19 @@ class TenderController extends Controller
DB::beginTransaction(); DB::beginTransaction();
try { try {
$penawaran = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first(); $permohonan = Permohonan::where('nomor_registrasi', '=', $noreg)->first();
$validated['nomor_registrasi'] = $penawaran->nomor_registrasi; // Add created_by/updated_by from the authenticated user
$userId = auth()->user()->id;
$validated['status'] = $request->input('status') ?? 'Tender'; $validated['nomor_registrasi'] = $permohonan->nomor_registrasi;
$validated['status'] = $request->input('status') ?? 'tender';
$validated['updated_by'] = $userId; // Updating the record
$permohonan->update($validated);
// Adding created_by for the new PenawaranTender record
$validated['created_by'] = $userId;
$penawaranId = PenawaranTender::create($validated); $penawaranId = PenawaranTender::create($validated);
$kjpps = $request->input('kjpp', []); $kjpps = $request->input('kjpp', []);
@@ -71,7 +82,9 @@ class TenderController extends Controller
foreach ($kjpps as $kjpp) { foreach ($kjpps as $kjpp) {
PenawaranDetailTender::create([ PenawaranDetailTender::create([
'penawaran_id' => $penawaranId->id, 'penawaran_id' => $penawaranId->id,
'kjpp_rekanan_id' => $kjpp 'kjpp_rekanan_id' => $kjpp,
'created_by' => $userId, // Set created_by for details
'updated_by' => $userId
]); ]);
} }
@@ -100,6 +113,8 @@ class TenderController extends Controller
$tujuan_penilaian_kjpp = null; $tujuan_penilaian_kjpp = null;
$jenis_laporan = null; $jenis_laporan = null;
$penawaranExists = PenawaranTender::where('nomor_registrasi', $noreg)->exists();
$penawaran1 = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first(); $penawaran1 = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first();
// dd($penawaran1->id); // dd($penawaran1->id);
if ($penawaran1) { if ($penawaran1) {
@@ -115,7 +130,7 @@ class TenderController extends Controller
// dd($kjpps); // dd($kjpps);
return view('lpj::penawaran.show', compact('noreg', 'penawaran', 'kjpps', 'tujuan_penilaian_kjpp', 'jenis_laporan')); return view('lpj::penawaran.show', compact('noreg', 'penawaran', 'kjpps', 'tujuan_penilaian_kjpp', 'jenis_laporan', 'penawaranExists'));
} }
/** /**
@@ -125,6 +140,7 @@ class TenderController extends Controller
{ {
// Find the specific penawaran by its ID // Find the specific penawaran by its ID
$penawaran = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first(); $penawaran = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first();
$permohonan = Permohonan::where('nomor_registrasi', '=', $noreg)->first();
$status = StatusPermohonan::all(); $status = StatusPermohonan::all();
$tujuan_penilaian_kjpp = TujuanPenilaianKJPP::all(); $tujuan_penilaian_kjpp = TujuanPenilaianKJPP::all();
@@ -135,7 +151,7 @@ class TenderController extends Controller
$kjpp = KJPP::all(); $kjpp = KJPP::all();
return view('lpj::penawaran.edit', compact('status', 'tujuan_penilaian_kjpp', 'jenis_laporan', 'kjpp', 'penawaran', 'noreg', 'kjpps')); return view('lpj::penawaran.edit', compact('status', 'tujuan_penilaian_kjpp', 'jenis_laporan', 'kjpp', 'penawaran', 'noreg', 'kjpps', 'permohonan'));
} }
@@ -151,9 +167,20 @@ class TenderController extends Controller
try { try {
// Ambil data penawaran berdasarkan nomor registrasi // Ambil data penawaran berdasarkan nomor registrasi
$penawaran = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first(); $penawaran = PenawaranTender::where('nomor_registrasi', '=', $noreg)->first();
$permohonan = Permohonan::where('nomor_registrasi', '=', $noreg)->first();
// Ambil ID user yang sedang login
$userId = auth()->user()->id;
// Jangan ubah created_by untuk data yang sudah ada
$validated['nomor_registrasi'] = $penawaran->nomor_registrasi; $validated['nomor_registrasi'] = $penawaran->nomor_registrasi;
$validated['status'] = $request->input('status') ?? 'tender'; $validated['status'] = $request->input('status') ?? 'tender';
$validated['created_by'] = $userId;
$validated['updated_by'] = $userId; // Hanya update 'updated_by'
// Update data penawaran dan permohonan
$penawaran->update($validated); $penawaran->update($validated);
$permohonan->update($validated);
$kjpps = $request->input('kjpp', []); $kjpps = $request->input('kjpp', []);
@@ -162,6 +189,8 @@ class TenderController extends Controller
if (!in_array($kjpp->kjpp_rekanan_id, $kjpps)) { if (!in_array($kjpp->kjpp_rekanan_id, $kjpps)) {
// Ubah status KJPP lama menjadi 0 // Ubah status KJPP lama menjadi 0
$kjpp->status = 0; $kjpp->status = 0;
$kjpp->created_by = $userId;
$kjpp->updated_by = $userId; // Set updated_by
$kjpp->save(); $kjpp->save();
} }
} }
@@ -172,10 +201,14 @@ class TenderController extends Controller
->where('kjpp_rekanan_id', $kjpp) ->where('kjpp_rekanan_id', $kjpp)
->first(); ->first();
// dd($existingDetail);
if ($existingDetail) { if ($existingDetail) {
// Jika KJPP sudah ada, pastikan statusnya aktif (1) // Jika KJPP sudah ada, pastikan statusnya aktif (1)
if ($existingDetail->status == 0) { if ($existingDetail->status == 0) {
$existingDetail->status = 1; $existingDetail->status = 1;
$existingDetail->created_by = $userId;
$existingDetail->updated_by = $userId; // Set updated_by
$existingDetail->save(); $existingDetail->save();
} }
} else { } else {
@@ -184,6 +217,8 @@ class TenderController extends Controller
'penawaran_id' => $penawaran->id, 'penawaran_id' => $penawaran->id,
'kjpp_rekanan_id' => $kjpp, 'kjpp_rekanan_id' => $kjpp,
'status' => 1, // Default status untuk KJPP baru adalah 1 'status' => 1, // Default status untuk KJPP baru adalah 1
'created_by' => $userId, // Set created_by untuk data baru
'updated_by' => $userId, // Set updated_by juga
]); ]);
} }
} }
@@ -207,6 +242,7 @@ class TenderController extends Controller
/** /**
* Remove the specified resource from storage. * Remove the specified resource from storage.
*/ */

View File

@@ -61,16 +61,25 @@ class TenderPenawaranRequest extends FormRequest
$validator->after(function ($validator) { $validator->after(function ($validator) {
$startDate = strtotime($this->input('start_date')); $startDate = strtotime($this->input('start_date'));
$endDate = strtotime($this->input('end_date')); $endDate = strtotime($this->input('end_date'));
$today = strtotime(date('Y-m-d'));
if ($endDate < $startDate) { if ($endDate < $startDate) {
$validator->errors()->add('end_date', 'Tanggal Akhir tidak boleh lebih awal dari Tanggal Awal.'); $validator->errors()->add('end_date', 'Tanggal Akhir tidak boleh lebih awal dari Tanggal Awal.');
} }
if ($startDate < $today) {
$validator->errors()->add('start_date', 'Tanggal Awal tidak boleh sebelum hari ini.');
}
// Validasi minimal 3 pilihan pada nama_kjpp // Validasi minimal 3 pilihan pada nama_kjpp
$namaKjpp = $this->input('kjpp', []); $namaKjpp = $this->input('kjpp', []);
// jika nama KJPP itu kosong
if (empty($namaKjpp)) {
$validator->errors()->add('kjpp', 'Nama KJPP wajib diisi.');
}
// jika terisi kurang dari 3 item // jika terisi kurang dari 3 item
if (is_array($namaKjpp) && count($namaKjpp) < 3) { elseif (is_array($namaKjpp) && count($namaKjpp) < 3) {
$validator->errors()->add('kjpp', 'Nama KJPP Sebelumnya harus memiliki minimal 3 pilihan jika diisi.'); $validator->errors()->add('kjpp', 'Nama KJPP Sebelumnya harus memiliki minimal 3 pilihan jika diisi.');
} }
}); });

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('penawaran', function (Blueprint $table) {
$table->unsignedBigInteger('created_by')->nullable()->after('created_at');
$table->unsignedBigInteger('updated_by')->nullable()->after('updated_at');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('penawaran', function (Blueprint $table) {
$table->dropColumn('created_by');
$table->dropColumn('updated_by');
});
}
};

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('detail_penawaran', function (Blueprint $table) {
$table->unsignedBigInteger('created_by')->nullable()->after('created_at');
$table->unsignedBigInteger('updated_by')->nullable()->after('updated_at');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('detail_penawaran', function (Blueprint $table) {
$table->dropColumn('created_by');
$table->dropColumn('updated_by');
});
}
};

View File

@@ -29,7 +29,7 @@
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text" <input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text"
name="nomor_registrasi" readonly value="{{ $penawaran->nomor_registrasi ?? '-' }}"> name="nomor_registrasi" readonly value="{{ $permohonan->nomor_registrasi ?? '-' }}">
</div> </div>
</div> </div>
<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">
@@ -38,7 +38,7 @@
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text" <input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text"
name="nama_kjpp_sebelumnya" readonly value="{{ $penawaran->nama_kjpp_sebelumnya ?? '' }}"> name="nama_kjpp_sebelumnya" readonly value="">
</div> </div>
</div> </div>
<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">
@@ -47,15 +47,14 @@
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text" <input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text"
name="biaya_kjpp_sebelumnya" readonly value="{{ $penawaran->biaya_kjpp_sebelumnya ?? '' }}"> name="biaya_kjpp_sebelumnya" readonly value="">
</div> </div>
<label class="form-label max-w-56"> <label class="form-label max-w-56">
Tanggal Penilaian Sebelumnya Tanggal Penilaian Sebelumnya
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text" <input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text"
name="tanggal_penilaian_sebelumnya" readonly name="tanggal_penilaian_sebelumnya" readonly value="">
value="{{ $penawaran->tanggal_penilaian_sebelumnya ?? '' }}">
</div> </div>
</div> </div>
<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">
@@ -207,5 +206,12 @@
outline: none; outline: none;
box-shadow: none; box-shadow: none;
} }
@media (prefers-color-scheme: dark) {
input.input-custom {
background: none;
color: var(--tw-gray-600);
}
}
</style> </style>
@endpush @endpush

View File

@@ -31,7 +31,7 @@
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text" <input class="flex w-full text-gray-600 font-medium text-sm input-custom" type="text"
name="nomor_registrasi" readonly value="{{ $penawaran->nomor_registrasi ?? '-' }}"> name="nomor_registrasi" readonly value="{{ $permohonan->nomor_registrasi ?? '-' }}">
</div> </div>
</div> </div>
<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">
@@ -212,5 +212,12 @@
outline: none; outline: none;
box-shadow: none; box-shadow: none;
} }
@media (prefers-color-scheme: dark) {
input.input-custom {
background: none;
color: var(--tw-gray-600);
}
}
</style> </style>
@endpush @endpush

View File

@@ -107,6 +107,12 @@
return months[month - return months[month -
1]; 1];
} }
function capitalizeWords(str) {
return str.replace(/\b\w/g, function(char) {
return char.toUpperCase();
});
}
</script> </script>
<script type="module"> <script type="module">
const element = document.querySelector('#penawaran-table'); const element = document.querySelector('#penawaran-table');
@@ -161,22 +167,43 @@
}, },
}, },
status: { status: {
title: 'Status' title: 'Status',
render: (item, data) => {
return capitalizeWords(data.status)
}
}, },
actions: { actions: {
title: 'Action', title: 'Action',
render: (item, data) => { render: (item, data) => {
return `<div class="flex flex-nowrap justify-center"> // Display default links first
return `<div class="flex flex-nowrap justify-center" id="action-${data.nomor_registrasi}">
<a class="btn btn-sm btn-icon btn-clear btn-primary" title="Detail" href="tender/penawaran/${data.nomor_registrasi}/show"> <a class="btn btn-sm btn-icon btn-clear btn-primary" title="Detail" href="tender/penawaran/${data.nomor_registrasi}/show">
<i class="ki-outline ki-abstract-26"></i> <i class="ki-outline ki-abstract-26"></i>
</a> </a>
<a class="btn btn-sm btn-icon btn-clear btn-info" title="Penawaran" href="tender/penawaran/${data.nomor_registrasi}/create"> <a class="btn btn-sm btn-icon btn-clear btn-info" title="Penawaran" href="tender/penawaran/${data.nomor_registrasi}/create" id="penawaran-link-${data.nomor_registrasi}">
<i class="ki-outline ki-arrow-circle-right"></i> <i class="ki-outline ki-arrow-circle-right"></i>
</a> </a>
</div>`; </div>`;
}, },
createdRow: function(row, data, dataIndex) {
// Call checkPenawaranExistence after the row is rendered
checkPenawaranExistence(data.nomor_registrasi)
.then(penawaranExists => {
// Update link based on penawaranExists status
let penawaranUrl = penawaranExists ?
`tender/penawaran/${data.nomor_registrasi}/edit` :
`tender/penawaran/${data.nomor_registrasi}/create`;
// Update href of the Penawaran link
$(`#penawaran-link-${data.nomor_registrasi}`).attr('href', penawaranUrl);
})
.catch(error => {
console.error("Error fetching penawaran existence:", error);
});
} }
}
}, },
}; };

View File

@@ -44,10 +44,14 @@
Detail Penawaran Detail Penawaran
</h3> </h3>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<a href="{{ route('tender.penawaran.ulang.index') }}" class="btn btn-xs btn-danger" title="Penawaran"><i @if ($penawaranExists)
class="ki-filled ki-arrow-circle-left"></i> Penawaran Ulang</a> <a href="{{ route('tender.penawaran.editPenawaran', $noreg) }}" class="btn btn-xs btn-danger"
title="Penawaran"><i class="ki-filled ki-arrow-circle-left"></i> Penawaran Ulang</a>
@endif
@if (!$penawaranExists)
<a href="{{ route('tender.penawaran.createPenawaran', $noreg) }}" class="btn btn-xs btn-primary" <a href="{{ route('tender.penawaran.createPenawaran', $noreg) }}" class="btn btn-xs btn-primary"
title="Penawaran"><i class="ki-filled ki-arrow-circle-right"></i> Tambah Penawaran</a> title="Penawaran"><i class="ki-filled ki-arrow-circle-right"></i> Tambah Penawaran</a>
@endif
<a href="{{ route('tender.penawaran.index') }}" class="btn btn-xs btn-info"><i <a href="{{ route('tender.penawaran.index') }}" class="btn btn-xs btn-info"><i
class="ki-filled ki-exit-left"></i> Back</a> class="ki-filled ki-exit-left"></i> Back</a>
</div> </div>
@@ -62,14 +66,16 @@
{{ $penawaran->nomor_registrasi ?? '' }} {{ $penawaran->nomor_registrasi ?? '' }}
</p> </p>
</div> </div>
@if ($penawaran->code)
<label class="form-label max-w-56"> <label class="form-label max-w-56">
No. Penawaran No. Penawaran
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<p class="flex w-full text-gray-600 font-medium text-sm"> <p class="flex w-full text-gray-600 font-medium text-sm">
{{ $penawaran->code ?? '' }} {{ $penawaran->code }}
</p> </p>
</div> </div>
@endif
</div> </div>
<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">

View File

@@ -107,6 +107,12 @@
return months[month - return months[month -
1]; 1];
} }
function capitalizeWords(str) {
return str.replace(/\b\w/g, function(char) {
return char.toUpperCase();
});
}
</script> </script>
<script type="module"> <script type="module">
const element = document.querySelector('#penawaran-table'); const element = document.querySelector('#penawaran-table');
@@ -161,7 +167,10 @@
}, },
}, },
status: { status: {
title: 'Status' title: 'Status',
render: (item, data) => {
return capitalizeWords(data.status);
}
}, },
actions: { actions: {
title: 'Action', title: 'Action',

View File

@@ -67,7 +67,7 @@
</label> </label>
<div class="flex flex-wrap items-baseline w-full"> <div class="flex flex-wrap items-baseline w-full">
<p class="flex w-full text-gray-600 font-medium text-sm"> <p class="flex w-full text-gray-600 font-medium text-sm">
{{ $penawaran->code ?? '' }} {{ $penawaran->code ?? 'Tidak Ada' }}
</p> </p>
</div> </div>
</div> </div>