Compare commits

...

40 Commits

Author SHA1 Message Date
putrakuningan
79e66226b0 Merge pull request 'feature/senior-officer' (#141) from feature/senior-officer into staging
Reviewed-on: #141
2025-05-20 17:27:41 +07:00
majid
500118d787 fix: perbaikkan update surveyor dan penilai 2025-05-20 17:27:41 +07:00
Daeng Deni Mardaeni
e731e9cea0 fix(laporan-penilaian): perbaiki logika paginasi dan tambahkan kontrol pagination di view
- Ubah logika default nilai parameter halaman ketika tidak ada input dari request.
- Tambahkan elemen kontrol pagination dan jumlah data per halaman di tampilan UI.
- Pastikan data table kembali ke halaman pertama saat melakukan ekspor data.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-07 13:31:34 +07:00
Daeng Deni Mardaeni
980b4e8e9f feat(noc): tambah fitur penyelesaian dan memo penyelesaian NOC
- Menambahkan relasi `noc` pada data laporan.
- Memperbarui logika `update` NOC untuk memproses memo penyelesaian.
- Menambahkan tombol "Penyelesaian" pada halaman laporan jika data NOC belum selesai.
- Memperbaiki pengecekan keberadaan file memo dengan disk publik.
- Mengimplementasikan view dan form baru untuk input memo penyelesaian pada NOC.
- Menambahkan routing dan breadcrumbs untuk proses penyelesaian memo NOC.
- Menambahkan validasi dan penyimpanan file memo penyelesaian.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-07 10:29:02 +07:00
Daeng Deni Mardaeni
8158f3058f feat(noc): tambahkan fitur bukti bayar dan nominal diterima
- Menambahkan kolom "Bukti Bayar" dan "Nominal Diterima" pada tampilan daftar noc.
- Menambahkan input untuk bukti bayar dan nominal diterima pada form noc.
- Mengubah logika pengecekan input file bukti KSL agar sesuai kondisi.
- Memperbaiki placeholder dan label form untuk konsistensi.
- Memperbaiki render data bukti bayar pada tabular untuk mendukung tindakan download atau lihat file.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-07 09:19:41 +07:00
Daeng Deni Mardaeni
eea49b7943 feat(noc): tambah fitur penyelesaian NOC
- Tambah atribut baru: `tanggal_pembayaran`, `memo_penyelesaian`, `bukti_penyelesaian`, dan `nominal_penyelesaian`.
- Update logika penyimpanan dan update data NOC dengan atribut baru.
- Tambah validasi dan handling untuk memproses pembayaran dan penyelesaian NOC.
- Update form NOC untuk mendukung input penyelesaian, termasuk file memo dan bukti penyelesaian.
- Update tampilan tabel data untuk menampilkan atribut baru di halaman index NOC.
- Tambah logika untuk memeriksa keberadaan memo penyelesaian di view form NOC.
- Penyesuaian endpoint dan logika dalam controller untuk mendukung penyelesaian data NOC.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-06 13:41:36 +07:00
Daeng Deni Mardaeni
5e8067ad72 feat(noc): tambahkan integrasi dan validasi data NOC
- Tambahkan model NOC ke NocController, PersetujuanPenawaranController, dan validasi pada NocRequest.
- Implementasi penyimpanan data NOC menggunakan `updateOrCreate` di beberapa alur proses.
- Tambahkan properti baru `catatan_noc` pada model, migrasi database, dan form terkait.
- Revisi aturan validasi pada NocRequest dan PersetujuanPenawaranRequest.
- Tingkatkan tampilan form NOC dengan penanganan file upload dan pratinjau file yang sudah diunggah.
- Perbaikan beberapa nama properti seperti `status_bayar` menjadi `status_pembayar`.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-05 14:13:54 +07:00
Daeng Deni Mardaeni
7f6c702683 refactor(controllers): perbaikan struktur kode controllers Permohonan dan Penilai
- Reformat kode untuk meningkatkan keterbacaan, termasuk penghapusan spasi kosong yang tidak diperlukan.
- Penyesuaian indentasi dan konsistensi format import pada `PermohonanController`.
- Optimasi fungsi data handling pada fungsi-fungsi terkait permohonan seperti `update`, `destroy`, `dataForDatatables`, dan `dataForAuthorization`.
- Penyesuaian pemetaan data output dalam format JSON pada datatables.
- Penghapusan elemen komentar yang tidak relevan atau redundant.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-05 11:39:05 +07:00
Daeng Deni Mardaeni
e6d05cc4aa feat(noc): tambahkan fitur Noc untuk pengelolaan data penyelesaian
- Menambahkan model baru untuk tabel `noc` beserta relasinya pada `Permohonan` dan `PersetujuanPenawaran`.
- Menambahkan migrasi untuk membuat tabel `noc` di database.
- Memodifikasi logika dan format data pada `NocController` untuk mendukung data terkait `noc`.
- Mendefinisikan relasi baru di model `Permohonan` dan `PersetujuanPenawaran` untuk mendukung fitur `noc`.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-05 11:37:51 +07:00
Daeng Deni Mardaeni
4ebc700283 refactor(Lpj): optimalkan kode untuk peningkatan efisiensi
- Ganti `isNumeric` dengan `ctype_digit` dan hapus fungsi `isNumeric` yang tidak diperlukan.
- Simplifikasi fungsi `onRomawi` dengan memanfaatkan fungsi `convertToRoman`.
- Hapus fungsi `holidays` karena tidak digunakan lagi dalam kode.

Signed-off-by: Daeng Deni Mardaeni <ddeni05@gmail.com>
2025-05-05 11:35:32 +07:00
Daeng Deni Mardaeni
121d099402 refactor(migrations): hapus dan perbaiki struktur tabel database
- Menghapus migration `create_currencies_table` dan `create_label_name_inspeksi_table` yang tidak digunakan.
- Menambahkan `timestamps` dan `softDeletes` pada beberapa tabel untuk peningkatan konsistensi dan fitur auditing.
- Mengubah `authorized_status` dari wajib menjadi nullable di beberapa tabel untuk fleksibilitas data.
2025-05-04 20:39:59 +07:00
Daeng Deni Mardaeni
54668820b1 refactor(models): ubah inheritance model ke base class
- Mengubah inheritance pada semua model di `Modules/Lpj` dari `Model` ke `Base` untuk konsistensi struktur.
- Menghapus model `SLA` beserta migrasi terkait karena tidak lagi digunakan.
2025-05-04 20:17:56 +07:00
Daeng Deni Mardaeni
d63108dea1 refactor(noc): optimalkan kode dan penyederhanaan logika dalam controller dan view
- Perbaiki dan konsistenkan penulisan conditional pada `NocController`.
- Sederhanakan logika pengambilan dan mapping data di controller.
- Hapus penggunaan fungsi render di view untuk data yang sudah diolah di controller.
- Refactor partial query logic di `PembayaranController` untuk efisiensi.
2025-05-04 05:53:05 +07:00
Daeng Deni Mardaeni
5cdc4b08b3 feat(laporan-hasil-penilaian): tambahkan render untuk kolom bukti kepemilikan
- Menambahkan fungsi render untuk kolom bukti kepemilikan pada tabel laporan hasil penilaian.
- Mengganti karakter baris baru dengan tag <br> untuk menampilkan data dalam format HTML.
- Menyediakan nilai default '-' jika tidak ada bukti kepemilikan yang tersedia.
2025-04-23 22:43:08 +07:00
Daeng Deni Mardaeni
dd11f467fa fix(laporan-hasil-penilaian): perbaiki penanganan nilai null pada kolom data
- Mengubah cara penanganan nilai null untuk kolom nilai_tanah, nilai_bangunan, nilai_njop, nilai_pasar_wajar, dan nilai_likuidasi.
- Menggunakan operator nullish coalescing (??) untuk menampilkan '-' jika nilai tidak ada.
2025-04-23 16:04:14 +07:00
Daeng Deni Mardaeni
49b13e6689 feat(laporan-penilaian): tambahkan filter penilai untuk mencakup surveyor
- Mengubah opsi filter penilai untuk menampilkan pengguna dengan peran 'penilai' dan 'surveyor'.
- Memperluas fungsionalitas pemfilteran pada laporan penilaian jaminan.
2025-04-23 16:01:13 +07:00
Daeng Deni Mardaeni
b9d0d9f03b feat(laporan-hasil-penilaian): tambahkan filter penilai pada laporan hasil penilaian jaminan internal dan eksternal
- Menambahkan filter untuk memilih penilai pada halaman laporan hasil penilaian.
- Memperbarui logika kueri untuk menyertakan filter penilai saat mengambil data.
- Memperbaiki tampilan dan struktur HTML untuk mendukung filter baru.
- Menambahkan fungsionalitas untuk menerapkan filter dan mengupdate tabel data secara dinamis.
2025-04-23 15:51:19 +07:00
Daeng Deni Mardaeni
0972f3fcff feat(laporan-hasil-penilaian): tambahkan filter penilai pada laporan penilaian jaminan
- Menambahkan filter untuk memilih penilai pada halaman laporan penilaian jaminan.
- Memperbarui query untuk menyertakan filter penilai saat mengambil data.
- Memperbaiki tampilan dengan menambahkan elemen input untuk filter penilai.
2025-04-23 15:51:03 +07:00
Daeng Deni Mardaeni
d251c7655d feat(laporan-hasil-penilaian): tambahkan halaman laporan hasil penilaian jaminan internal dan eksternal
- Menambahkan rute dan breadcrumb untuk halaman laporan hasil penilaian jaminan internal dan eksternal.
- Membuat tampilan baru dengan tabel untuk menampilkan data laporan.
- Menyediakan fungsionalitas pencarian dan filter berdasarkan tanggal dan cabang.
- Menambahkan opsi untuk mengekspor laporan ke Excel.
2025-04-23 13:28:34 +07:00
Daeng Deni Mardaeni
afbdad43db feat(laporan-hasil-penilaian): tambahkan rute dan breadcrumb untuk laporan hasil penilaian jaminan internal dan eksternal
- Menambahkan breadcrumb untuk 'Laporan Hasil Penilaian Jaminan Internal External'.
- Menambahkan rute baru untuk 'laporan-hasil-penilaian-jaminan-internal-external' dengan metode:
  - dataForDatatables
  - export
  - index
2025-04-23 13:28:20 +07:00
Daeng Deni Mardaeni
886a382f57 feat(export): tambahkan fungsionalitas ekspor laporan hasil penilaian jaminan internal dan eksternal
- Menambahkan kelas LaporanHasilPenilaianJaminanInternalExternalExport untuk mengelola ekspor data.
- Mengimplementasikan metode collection untuk mengambil data permohonan dengan filter.
- Menambahkan metode map untuk memetakan data permohonan ke format yang sesuai untuk ekspor.
- Menyediakan judul dan heading untuk laporan yang diekspor.
- Mengatur format dan gaya untuk laporan yang dihasilkan.
2025-04-23 13:28:03 +07:00
Daeng Deni Mardaeni
c1c37f5716 feat(laporan-hasil-penilaian): tambahkan controller untuk laporan hasil penilaian jaminan internal dan eksternal
- Menambahkan method index untuk menampilkan halaman laporan.
- Menambahkan method dataForDatatables untuk mengambil dan memfilter data permohonan.
- Menambahkan method export untuk mengunduh laporan dalam format Excel.
- Mengimplementasikan pencarian dan pengurutan data berdasarkan parameter yang diberikan.
2025-04-23 13:27:41 +07:00
Daeng Deni Mardaeni
89957190c7 feat(permohonan): tambahkan kolom dan pencarian untuk Nomor LPJ Lama
- Menambahkan kolom "Nomor LPJ Lama" pada tabel permohonan.
- Memperbarui fungsi pencarian untuk mencakup "Nomor LPJ Lama".
2025-04-23 12:52:47 +07:00
Daeng Deni Mardaeni
0167919542 feat(laporan-penilaian-jaminan): perbarui tanggal laporan dan tanggal review
- Menambahkan logika untuk menampilkan tanggal laporan berdasarkan approval.
- Memperbarui tanggal review dengan tanggal kunjungan dari penilaian.
2025-04-23 11:29:01 +07:00
Daeng Deni Mardaeni
b3ccf3bb8f feat(laporan-penilaian-jaminan): tambahkan fungsionalitas ekspor laporan penilaian jaminan
- Menambahkan judul dan informasi cabang pada laporan.
- Menyertakan periode dan tanggal ekspor di laporan.
- Menambahkan informasi pengguna yang melakukan ekspor.
- Memperbaiki format dan gaya header pada laporan.
- Mengatur auto-size kolom dan menambahkan border pada sel data.
2025-04-23 11:23:09 +07:00
Daeng Deni Mardaeni
d434680f0e feat(laporan-penilaian-jaminan): tambahkan menu untuk laporan penilaian jaminan
- Menambahkan entri menu baru untuk "Laporan Penilaian Jaminan".
- Menetapkan path dan ikon untuk menu baru.
- Mengatur peran yang diperlukan untuk mengakses laporan.
2025-04-23 10:43:46 +07:00
Daeng Deni Mardaeni
53c86a79d0 feat(laporan-permohonan): perbaiki query dan aktifkan breadcrumbs
- Mengubah query pada metode collection untuk menggunakan Permohonan::query() alih-alih Permohonan::with().
- Mengaktifkan tampilan breadcrumbs pada halaman laporan permohonan.
2025-04-23 10:41:54 +07:00
Daeng Deni Mardaeni
f7b851d295 feat(laporan-penilaian-jaminan): tambahkan tampilan dan fungsionalitas untuk laporan penilaian jaminan
- Menambahkan struktur tampilan untuk laporan penilaian jaminan.
- Menyediakan filter berdasarkan tanggal dan cabang.
- Menambahkan fungsionalitas pencarian untuk laporan.
- Menyediakan opsi ekspor laporan ke Excel.
- Mengimplementasikan tabel data dengan kolom yang relevan.
2025-04-23 10:39:32 +07:00
Daeng Deni Mardaeni
baf0000a3f feat(laporan-penilaian-jaminan): tambahkan rute dan breadcrumb untuk laporan penilaian jaminan
- Menambahkan breadcrumb untuk 'Laporan Penilai Jaminan' yang mengacu pada 'Laporan'.
- Menambahkan rute baru untuk 'laporan-penilaian-jaminan' dengan metode untuk data, ekspor, dan indeks.
2025-04-23 10:39:17 +07:00
Daeng Deni Mardaeni
5b50a36a60 feat(laporan-penilaian-jaminan): tambahkan ekspor laporan penilaian jaminan
- Membuat kelas LaporanPenilaianJaminanExport untuk mengekspor data penilaian jaminan.
- Menambahkan filter berdasarkan tanggal, cabang, dan pencarian untuk query.
- Mengimplementasikan metode collection, map, dan headings untuk format ekspor.
2025-04-23 10:36:27 +07:00
Daeng Deni Mardaeni
45f911cef9 feat(laporan-admin-kredit): tambahkan controller untuk laporan penilaian jaminan
- Menambahkan LaporanPenilaianJaminanController untuk mengelola laporan penilaian jaminan.
- Implementasi fungsi index untuk menampilkan halaman laporan.
- Menambahkan fungsi dataForDatatables untuk mengambil dan memfilter data permohonan.
- Menyediakan fungsi export untuk mengunduh laporan dalam format Excel.
2025-04-23 10:36:03 +07:00
Daeng Deni Mardaeni
aa3efd6015 feat(laporan-admin-kredit): optimalkan query permohonan
- Menghapus eager loading pada relasi yang tidak diperlukan.
- Mempercepat pengambilan data permohonan dengan status 'done'.
2025-04-23 10:35:32 +07:00
Daeng Deni Mardaeni
fd21a5b86f feat(lpj): perbarui fungsi dan struktur kode
- Mengatur ulang urutan penggunaan namespace untuk konsistensi.
- Memperbaiki penanganan kesalahan pada fungsi formatTanggalIndonesia.
- Menambahkan logika untuk memeriksa rentang tanggal aktif pada fungsi checkActiveDateRangePenawaran.
- Memperbaiki dan menyederhanakan logika pada fungsi checkKelengkapanDetailKJPP.
- Memperbarui fungsi generateLpjUniqueCode untuk menghasilkan kode unik dengan format yang lebih baik.
- Menyempurnakan fungsi formatNotifikasi untuk menampilkan pesan yang lebih informatif.
2025-04-23 09:26:42 +07:00
Daeng Deni Mardaeni
d1744b07ec feat(permohonan): hapus notifikasi saat membuat permohonan
- Menghapus kode yang mengirim notifikasi kepada pengguna setelah permohonan dibuat.
- Memperbaiki alur penyimpanan data dengan mengurangi ketergantungan pada notifikasi.
2025-04-23 09:26:33 +07:00
Daeng Deni Mardaeni
10aa59d65d feat(permohonan): tambahkan fungsi notifikasi saat membuat riwayat permohonan
- Menambahkan pemanggilan fungsi createNotification setelah membuat riwayat permohonan.
- Mengimplementasikan logika untuk mengirim notifikasi kepada pengguna terkait status 'order'.
- Menggunakan kelas PermohonanNotif untuk mengirim pesan notifikasi.
2025-04-23 09:26:08 +07:00
Daeng Deni Mardaeni
2506b6115c feat(notifikasi): tambahkan pesan pada notifikasi permohonan
- Menambahkan properti message pada kelas PermohonanNotif.
- Memperbarui konstruktor untuk menerima parameter message.
- Memperbarui metode toArray untuk menyertakan message dalam representasi array notifikasi.
2025-04-23 09:25:42 +07:00
Daeng Deni Mardaeni
acfc282e25 feat(notifikasi): tambahkan kelas PermohonanNotif untuk notifikasi permohonan
- Menambahkan kelas PermohonanNotif yang mengimplementasikan notifikasi di Laravel.
- Menggunakan saluran pengiriman 'mail' dan 'database'.
- Menyediakan metode untuk mengirim representasi email dan array dari notifikasi.
2025-04-22 13:58:23 +07:00
Daeng Deni Mardaeni
ffb24b8cd6 feat(notifikasi): tambahkan fungsi formatNotifikasi untuk permohonan
- Menambahkan fungsi formatNotifikasi untuk memformat data notifikasi.
- Menggunakan json_decode untuk mengubah data menjadi objek.
- Menghasilkan array notifikasi dengan judul dan pesan berdasarkan status permohonan.
2025-04-22 13:58:23 +07:00
Daeng Deni Mardaeni
d4c70fba00 feat(permohonan): tambahkan notifikasi saat permohonan dibuat
- Menambahkan penggunaan notifikasi PermohonanNotif untuk memberitahukan pengguna saat permohonan baru dibuat.
- Mengambil pengguna yang membuat permohonan menggunakan ID dari kolom created_by.
2025-04-22 13:58:23 +07:00
Daeng Deni Mardaeni
7b14c16af1 fix(Base): tambahkan trait Notifiable pada model Base
- Menambahkan trait Notifiable untuk mendukung notifikasi dalam model Base.
- Memastikan model dapat mengirimkan notifikasi sesuai kebutuhan aplikasi.
2025-04-22 13:58:23 +07:00
107 changed files with 3772 additions and 1291 deletions

View File

@@ -0,0 +1,288 @@
<?php
namespace Modules\Lpj\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\Branch;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
class LaporanHasilPenilaianJaminanInternalExternalExport implements FromCollection, WithHeadings, WithMapping, WithTitle, WithCustomStartCell, WithEvents
{
protected $request;
public function __construct($request)
{
$this->request = $request;
}
public function collection()
{
$query = Permohonan::query();
$query = $query->where('status', 'done');
// Apply date range filter if provided
if ($this->request->has('start_date') || $this->request->has('end_date')) {
$query->whereBetween('tanggal_permohonan', [
$this->request->start_date ?? '1900-01-01',
$this->request->end_date ?? now()->toDateString()
]);
}
// Apply branch filter if provided
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
$query->where('branch_id', $this->request->branch_id);
}
if ($this->request->has('penilai_id') && !empty($this->request->penilai_id)) {
$request = $this->request; // Store in a local variable
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function($q) use ($request) {
$q->where('user_id', $request->penilai_id);
});
}
// Apply search filter if provided
if ($this->request->has('search') && !empty($this->request->search)) {
$search = $this->request->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('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
$q->orWhere('status', 'LIKE', '%' . $search . '%');
});
}
// Default ordering
$query->orderBy('nomor_registrasi', 'asc');
return $query->get();
}
protected $rowNumber = 0;
public function map($permohonan): array
{
$this->rowNumber++;
$luas_tanah = 0;
$luas_bangunan = 0;
$nilai_tanah = 0;
$nilai_bangunan = 0;
$npw = 0;
$nilai_liquidasi = 0;
if (isset($permohonan->penilai->lpj)) {
$lpj = json_decode($permohonan->penilai->lpj, true);
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
$luas_tanah = $lpj['luas_tanah'] ?? 0;
$luas_bangunan = $lpj['luas_bangunan'] ?? 0;
$nilai_tanah = str_replace('.', '', $lpj['nilai_tanah_2'] ?? 0);
$nilai_bangunan = str_replace('.', '', $lpj['nilai_bangunan_2'] ?? 0);
$nilai_liquidasi = str_replace('.', '', $lpj['likuidasi_nilai_2'] ?? 0);
}
return [
$this->rowNumber,
$permohonan->nomor_registrasi,
$permohonan->tanggal_permohonan,
$permohonan->debiture->branch->name,
$permohonan->creator->name,
$permohonan->debiture->cif,
$permohonan->debiture->name,
$permohonan->jenisPenilaian->name,
$permohonan->tujuanPenilaian->name,
$permohonan->jenisFasilitasKredit->name,
$permohonan->documents->pluck('jenisJaminan.name')->unique()->implode(', '),
$permohonan->documents->map(function ($document) {
return formatAlamat($document);
})->unique()->implode(', '),
$permohonan->documents->flatMap(function ($document) {
return $document->detail->map(function ($detail) {
return (!empty($detail->dokumen_nomor) && is_array($detail->dokumen_nomor))
? ($detail->jenisLegalitasJaminan->name ?? '') . "\n" . implode(', ', $detail->dokumen_nomor)
: null;
});
})->filter()->unique()->implode(', '),
$permohonan->documents->pluck('pemilik.name')->unique()->implode(', '),
$luas_tanah . ' m²',
formatRupiah($nilai_tanah, 2),
$luas_bangunan . ' m²',
formatRupiah($nilai_bangunan, 2),
formatRupiah($permohonan->nilai_njop ?? 0, 2),
formatRupiah($npw, 2),
formatRupiah($nilai_liquidasi, 2),
$permohonan->documents->map(function ($document) {
return formatTanggalIndonesia($document->created_at);
})->first(),
'', // tanggal_spk
'', // nomor_spk
'', // tanggal_rencana_kunjungan
$permohonan->penilaian->tanggal_kunjungan ? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan) : '',
'', // tanggal_delivered
'', // jangka_waktu_sla
($permohonan->approval_dd_at || $permohonan->approval_eo_at) ?
formatTanggalIndonesia($permohonan->approval_dd_at ?? $permohonan->approval_eo_at) : '',
$permohonan->penilaian->tanggal_kunjungan ? formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan) : '',
$permohonan->penilaian->_user_penilai->userPenilaiTeam->name ?? '',
$permohonan->penilaian->teams ?? '',
'', // saran
'' // catatan
];
}
public function headings(): array
{
return [
'No',
'Nomor Registrasi',
'Tanggal Permohonan',
'Cabang',
'Pemohon',
'CIF',
'Nama Debitur',
'Jenis Penilaian',
'Tujuan Penilaian',
'Jenis Fasilitas Kredit',
'Jenis Agunan',
'Alamat Agunan',
'Bukti Kepemilikan',
'Nama Pemilik',
'Luas Tanah',
'Nilai Tanah',
'Luas Bangunan',
'Nilai Bangunan',
'Nilai NJOP',
'Nilai Pasar Wajar',
'Nilai Likuidasi',
'Tanggal Dokumen Diterima',
'Tanggal SPK',
'Nomor SPK',
'Tanggal Rencana Kunjungan',
'Tanggal Kunjungan',
'Tanggal Delivered',
'Jangka Waktu SLA',
'Tanggal Laporan',
'Tanggal Review',
'Nama Penilai',
'Nama Team Leader',
'Saran',
'Catatan'
];
}
/**
* @return string
*/
public function title(): string
{
return 'Laporan Hasil Penilaian Jaminan Internal & External';
}
/**
* @return string
*/
public function startCell(): string
{
return 'A7';
}
/**
* @return array
*/
public function registerEvents(): array
{
return [
AfterSheet::class => function(AfterSheet $event) {
// Get the sheet
$sheet = $event->sheet->getDelegate();
// Set the title
$sheet->setCellValue('A1', 'LAPORAN PENILAIAN JAMINAN');
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(16);
// Merge cells for title
$sheet->mergeCells('A1:AH1');
$sheet->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
// Set the branch information if filtered
$branchInfo = '';
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
$branch = Branch::find($this->request->branch_id);
if ($branch) {
$branchInfo = 'Cabang: ' . $branch->name;
$sheet->setCellValue('A2', $branchInfo);
$sheet->mergeCells('A2:AH2');
$sheet->getStyle('A2')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$sheet->getStyle('A2')->getFont()->setBold(true);
}
}
// Set the period
$startDate = $this->request->start_date ?? '';
$endDate = $this->request->end_date ?? '';
$rowIndex = $branchInfo ? 3 : 2;
if ($startDate && $endDate) {
$startDateFormatted = Carbon::parse($startDate)->format('d F Y');
$endDateFormatted = Carbon::parse($endDate)->format('d F Y');
$sheet->setCellValue('A' . $rowIndex, 'Periode: ' . $startDateFormatted . ' - ' . $endDateFormatted);
} else {
$sheet->setCellValue('A' . $rowIndex, 'Periode: Semua Data');
}
$sheet->mergeCells('A' . $rowIndex . ':AH' . $rowIndex);
$sheet->getStyle('A' . $rowIndex)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
// Set the date of export
$rowIndex++;
$sheet->setCellValue('A' . $rowIndex, 'Tanggal Export: ' . Carbon::now()->format('d F Y H:i:s'));
// Set the user who exported
$rowIndex++;
$userName = Auth::user() ? Auth::user()->name : 'System';
$sheet->setCellValue('A' . $rowIndex, 'Diexport oleh: ' . $userName);
// Add a blank line
$rowIndex++;
$sheet->setCellValue('A' . $rowIndex, '');
// Style the header row
$headerRange = 'A7:' . $sheet->getHighestColumn() . '7';
$sheet->getStyle($headerRange)->getFont()->setBold(true);
$sheet->getStyle($headerRange)->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->getStartColor()->setARGB('FFCCCCCC');
// Auto-size columns - fixed to handle columns beyond Z
$highestColumn = $sheet->getHighestColumn();
$highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn);
for ($i = 1; $i <= $highestColumnIndex; $i++) {
$currentColumn = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($i);
$sheet->getColumnDimension($currentColumn)->setAutoSize(true);
}
// Add borders to all cells with data
$dataRange = 'A7:' . $sheet->getHighestColumn() . $sheet->getHighestRow();
$sheet->getStyle($dataRange)->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
// Center align the header row
$sheet->getStyle($headerRange)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
// Set text wrap for header cells
$sheet->getStyle($headerRange)->getAlignment()->setWrapText(true);
},
];
}
}

View File

@@ -0,0 +1,245 @@
<?php
namespace Modules\Lpj\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\WithCustomStartCell;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\Branch;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
class LaporanPenilaianJaminanExport implements FromCollection, WithHeadings, WithMapping, WithTitle, WithCustomStartCell, WithEvents
{
protected $request;
public function __construct($request)
{
$this->request = $request;
}
public function collection()
{
$query = Permohonan::query();
$query = $query->where('status', 'done');
// Apply date range filter if provided
if ($this->request->has('start_date') || $this->request->has('end_date')) {
$query->whereBetween('tanggal_permohonan', [
$this->request->start_date ?? '1900-01-01',
$this->request->end_date ?? now()->toDateString()
]);
}
// Apply branch filter if provided
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
$query->where('branch_id', $this->request->branch_id);
}
if ($this->request->has('penilai_id') && !empty($this->request->penilai_id)) {
$request = $this->request; // Store in a local variable
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function($q) use ($request) {
$q->where('user_id', $request->penilai_id);
});
}
// Apply search filter if provided
if ($this->request->has('search') && !empty($this->request->search)) {
$search = $this->request->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('tujuanPenilaian', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search . '%');
$q->orWhere('status', 'LIKE', '%' . $search . '%');
});
}
// Default ordering
$query->orderBy('nomor_registrasi', 'asc');
return $query->with(['debiture.branch'])->get();
}
protected $rowNumber = 0;
public function map($permohonan): array
{
$this->rowNumber++;
$luas_tanah = 0;
$luas_bangunan = 0;
$nilai_tanah = 0;
$nilai_bangunan = 0;
$npw = 0;
$nilai_liquidasi = 0;
if (isset($permohonan->penilai->lpj)) {
$lpj = json_decode($permohonan->penilai->lpj, true);
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
$luas_tanah = $lpj['luas_tanah'] ?? 0;
$luas_bangunan = $lpj['luas_bangunan'] ?? 0;
$nilai_tanah = str_replace('.', '', $lpj['nilai_tanah_2'] ?? 0);
$nilai_bangunan = str_replace('.', '', $lpj['nilai_bangunan_2'] ?? 0);
$nilai_liquidasi = str_replace('.', '', $lpj['likuidasi_nilai_2'] ?? 0);
}
return [
$this->rowNumber,
$permohonan->nomor_registrasi,
$permohonan->tanggal_permohonan,
$permohonan->debiture->branch->name,
$permohonan->debiture->name,
$permohonan->creator->name,
$permohonan->tujuanPenilaian->name,
$permohonan->documents->pluck('jenisJaminan.name')->unique()->implode(', '),
$permohonan->documents->map(function ($document) {
return formatAlamat($document);
})->unique()->implode(', '),
$luas_tanah . ' m²',
formatRupiah($nilai_tanah, 2),
$luas_bangunan . ' m²',
formatRupiah($nilai_bangunan, 2),
($permohonan->approval_dd_at || $permohonan->approval_eo_at) ?
formatTanggalIndonesia($permohonan->approval_dd_at ?? $permohonan->approval_eo_at) : '',
$permohonan->penilaian->tanggal_kunjungan ?
formatTanggalIndonesia($permohonan->penilaian->tanggal_kunjungan) : '',
formatRupiah($npw, 2),
formatRupiah($nilai_liquidasi, 2),
$permohonan->penilaian->_user_penilai->userPenilaiTeam->name,
];
}
public function headings(): array
{
return [
'No',
'Nomor Registrasi',
'Tanggal Permohonan',
'Cabang',
'Nama Debitur',
'Pemohon',
'Tujuan Penilaian',
'Jenis Agunan',
'Alamat Agunan',
'Luas Tanah',
'Nilai Tanah',
'Luas Bangunan',
'Nilai Bangunan',
'Tanggal Laporan',
'Tanggal Review',
'Nilai Pasar Wajar',
'Nilai Likuidasi',
'Nama Penilai',
];
}
/**
* @return string
*/
public function title(): string
{
return 'Laporan Penilaian Jaminan';
}
/**
* @return string
*/
public function startCell(): string
{
return 'A7';
}
/**
* @return array
*/
public function registerEvents(): array
{
return [
AfterSheet::class => function(AfterSheet $event) {
// Get the sheet
$sheet = $event->sheet->getDelegate();
// Set the title
$sheet->setCellValue('A1', 'LAPORAN PENILAIAN JAMINAN');
$sheet->getStyle('A1')->getFont()->setBold(true)->setSize(16);
// Merge cells for title
$sheet->mergeCells('A1:R1');
$sheet->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
// Set the branch information if filtered
$branchInfo = '';
if ($this->request->has('branch_id') && !empty($this->request->branch_id)) {
$branch = Branch::find($this->request->branch_id);
if ($branch) {
$branchInfo = 'Cabang: ' . $branch->name;
$sheet->setCellValue('A2', $branchInfo);
$sheet->mergeCells('A2:R2');
$sheet->getStyle('A2')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
$sheet->getStyle('A2')->getFont()->setBold(true);
}
}
// Set the period
$startDate = $this->request->start_date ?? '';
$endDate = $this->request->end_date ?? '';
$rowIndex = $branchInfo ? 3 : 2;
if ($startDate && $endDate) {
$startDateFormatted = Carbon::parse($startDate)->format('d F Y');
$endDateFormatted = Carbon::parse($endDate)->format('d F Y');
$sheet->setCellValue('A' . $rowIndex, 'Periode: ' . $startDateFormatted . ' - ' . $endDateFormatted);
} else {
$sheet->setCellValue('A' . $rowIndex, 'Periode: Semua Data');
}
$sheet->mergeCells('A' . $rowIndex . ':R' . $rowIndex);
$sheet->getStyle('A' . $rowIndex)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
// Set the date of export
$rowIndex++;
$sheet->setCellValue('A' . $rowIndex, 'Tanggal Export: ' . Carbon::now()->format('d F Y H:i:s'));
// Set the user who exported
$rowIndex++;
$userName = Auth::user() ? Auth::user()->name : 'System';
$sheet->setCellValue('A' . $rowIndex, 'Diexport oleh: ' . $userName);
// Add a blank line
$rowIndex++;
$sheet->setCellValue('A' . $rowIndex, '');
// Style the header row
$headerRange = 'A7:' . $sheet->getHighestColumn() . '7';
$sheet->getStyle($headerRange)->getFont()->setBold(true);
$sheet->getStyle($headerRange)->getFill()
->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID)
->getStartColor()->setARGB('FFCCCCCC');
// Auto-size columns
foreach(range('A', $sheet->getHighestColumn()) as $column) {
$sheet->getColumnDimension($column)->setAutoSize(true);
}
// Add borders to all cells with data
$dataRange = 'A7:' . $sheet->getHighestColumn() . $sheet->getHighestRow();
$sheet->getStyle($dataRange)->getBorders()->getAllBorders()->setBorderStyle(\PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN);
// Center align the header row
$sheet->getStyle($headerRange)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
// Set text wrap for header cells
$sheet->getStyle($headerRange)->getAlignment()->setWrapText(true);
},
];
}
}

View File

@@ -19,8 +19,7 @@
public function collection()
{
$query = Permohonan::with(['user', 'branch', 'tujuanPenilaian', 'jenisFasilitasKredit', 'jenisPenilaian'])
->select('permohonan.*');
$query = Permohonan::query();
// Apply role-based filtering
if (!Auth::user()->hasAnyRole(['administrator'])) {

View File

@@ -1,23 +1,23 @@
<?php
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Modules\Lpj\Models\CustomField;
use Modules\Lpj\Models\HolidayCalendar;
use Modules\Lpj\Models\PenawaranDetailTender;
use Modules\Lpj\Models\PenawaranTender;
use Modules\Lpj\Models\Penilaian;
use Modules\Lpj\Models\JenisDokumen;
use Modules\Lpj\Models\TeamsUsers;
use Modules\Lpj\Models\Laporan;
use Modules\Usermanagement\Models\User;
use Modules\Location\Models\Province;
use Modules\Location\Models\City;
use Modules\Location\Models\District;
use Modules\Location\Models\Village;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Modules\Location\Models\City;
use Modules\Location\Models\District;
use Modules\Location\Models\Province;
use Modules\Location\Models\Village;
use Modules\Lpj\Models\CustomField;
use Modules\Lpj\Models\HolidayCalendar;
use Modules\Lpj\Models\JenisDokumen;
use Modules\Lpj\Models\Laporan;
use Modules\Lpj\Models\PenawaranDetailTender;
use Modules\Lpj\Models\PenawaranTender;
use Modules\Lpj\Models\Penilaian;
use Modules\Lpj\Models\TeamsUsers;
use Modules\Usermanagement\Models\User;
function formatTanggalIndonesia($date, $time = false)
{
function formatTanggalIndonesia($date, $time = false)
{
Carbon::setLocale('id');
try {
$waktu = Carbon::parse($date);
@@ -25,28 +25,28 @@ function formatTanggalIndonesia($date, $time = false)
return $waktu->translatedFormat('d F Y');
}
return $waktu->translatedFormat('d F Y') . ' pukul ' . $waktu->format('H.i') . ' WIB';
} catch (\Throwable $e) {
} catch (Throwable $e) {
return $date;
}
}
}
function formatRupiah($number,$decimals = 0)
{
function formatRupiah($number, $decimals = 0)
{
$number = (float) $number;
return 'Rp ' . number_format($number, $decimals, ',', '.');
}
}
function formatAlamat($alamat)
{
function formatAlamat($alamat)
{
return ($alamat->address ? $alamat->address . ', ' : '') . (isset($alamat->village) ? $alamat->village->name . ', ' : '') . (isset($alamat->city) ? $alamat->city->name . ', ' : '') . (isset($alamat->province) ? $alamat->province->name . ', ' : '') . ($alamat->village->postal_code ?? '');
}
}
// andy add
function checkActiveDateRangePenawaran($id)
{
// andy add
function checkActiveDateRangePenawaran($id)
{
$penawaran = PenawaranTender::find($id);
$start_date = strtotime($penawaran->start_date);
@@ -69,10 +69,10 @@ function checkActiveDateRangePenawaran($id)
}
return $allow;
}
}
function checkKelengkapanDetailKJPP($id)
{
function checkKelengkapanDetailKJPP($id)
{
$allow = true;
// DB::enableQueryLog();
// detail_penawaran apakah isian biaya_penawaran, attachment, dokumen_persetujuan sudah lengkap?
@@ -104,11 +104,11 @@ function checkKelengkapanDetailKJPP($id)
}
return $allow;
}
}
// convert
function convertSlug($slug)
{
// convert
function convertSlug($slug)
{
$words = explode('-', $slug);
foreach ($words as $index => $word) {
@@ -116,11 +116,12 @@ function convertSlug($slug)
}
return implode(' ', $words);
}
}
// generate last penawaran.code
function onLastnumberCodePenawaran(): string
{
// generate last penawaran.code
function onLastnumberCodePenawaran()
: string
{
// ambil code terakhir
$maxCode = PenawaranTender::max('code');
// chek data penawaran terakhir --> mengurutkan data berdasarkan kolom `created_at` secara DESC
@@ -133,7 +134,7 @@ function onLastnumberCodePenawaran(): string
if ($penawaran) {
$isNum = substr($maxCode, 2); // memastikan string ke 3 s/d 8 adalan numiric
$isNP = substr($maxCode, 0, 2);
if ((8 == strlen($maxCode)) && ("NP" == $isNP) && (isNumeric($isNum))) {
if ((8 == strlen($maxCode)) && ("NP" == $isNP) && (ctype_digit($isNum))) {
$code_penawaran_last = substr($maxCode, -4);
$year_penawaran_last = Carbon::parse($penawaran->created_at)->year;
$year_now = Carbon::now()->year;
@@ -146,16 +147,12 @@ function onLastnumberCodePenawaran(): string
}
return 'NP' . Carbon::now()->format('y') . $noUrutAkhirString;
}
}
function isNumeric($str)
{
return ctype_digit($str);
}
// generate last penawaran.no_spk
function onLastnumberCodePenawaranSPK($jenis_laporan_code): string
{
// generate last penawaran.no_spk
function onLastnumberCodePenawaranSPK($jenis_laporan_code)
: string
{
// 20241124_001 ==> spk_no_core
// XXX / PJ / JKT / MONTH-ROM / FR|SR / 2024
@@ -179,97 +176,73 @@ function onLastnumberCodePenawaranSPK($jenis_laporan_code): string
$month = onRomawi(Carbon::now()->month);
$lastSPK = $noUrutAkhirString.' / PJ / JKT / '. $month .' / ' .$jenis_laporan_code.' / '.$year_now;
$lastSPK = $noUrutAkhirString . ' / PJ / JKT / ' . $month . ' / ' . $jenis_laporan_code . ' / ' . $year_now;
return $lastSPK;
}
function onRomawi(int $bln): string
{
switch ($bln) {
case 1:
return "I";
break;
case 2:
return "II";
break;
case 3:
return "III";
break;
case 4:
return "IV";
break;
case 5:
return "V";
break;
case 6:
return "VI";
break;
case 7:
return "VII";
break;
case 8:
return "VIII";
break;
case 9:
return "IX";
break;
case 10:
return "X";
break;
case 11:
return "XI";
break;
case 12:
return "XII";
break;
}
}
function onRomawi(int $bln)
: string
{
return convertToRoman($bln);
}
function penyebut($nilai)
{
function penyebut($nilai)
{
$nilai = abs($nilai);
$huruf = array("", "satu", "dua", "tiga", "empat", "lima", "enam", "tujuh", "delapan", "sembilan", "sepuluh", "sebelas");
$huruf = [
"",
"satu",
"dua",
"tiga",
"empat",
"lima",
"enam",
"tujuh",
"delapan",
"sembilan",
"sepuluh",
"sebelas"
];
$temp = "";
if ($nilai < 12) {
$temp = " ". $huruf[$nilai];
} elseif ($nilai < 20) {
$temp = penyebut($nilai - 10). " belas";
} elseif ($nilai < 100) {
$temp = penyebut($nilai / 10)." puluh". penyebut($nilai % 10);
} elseif ($nilai < 200) {
$temp = " " . $huruf[$nilai];
} else if ($nilai < 20) {
$temp = penyebut($nilai - 10) . " belas";
} else if ($nilai < 100) {
$temp = penyebut($nilai / 10) . " puluh" . penyebut($nilai % 10);
} else if ($nilai < 200) {
$temp = " seratus" . penyebut($nilai - 100);
} elseif ($nilai < 1000) {
} else if ($nilai < 1000) {
$temp = penyebut($nilai / 100) . " ratus" . penyebut($nilai % 100);
} elseif ($nilai < 2000) {
} else if ($nilai < 2000) {
$temp = " seribu" . penyebut($nilai - 1000);
} elseif ($nilai < 1000000) {
} else if ($nilai < 1000000) {
$temp = penyebut($nilai / 1000) . " ribu" . penyebut($nilai % 1000);
} elseif ($nilai < 1000000000) {
} else if ($nilai < 1000000000) {
$temp = penyebut($nilai / 1000000) . " juta" . penyebut($nilai % 1000000);
} elseif ($nilai < 1000000000000) {
} else if ($nilai < 1000000000000) {
$temp = penyebut($nilai / 1000000000) . " milyar" . penyebut(fmod($nilai, 1000000000));
} elseif ($nilai < 1000000000000000) {
} else if ($nilai < 1000000000000000) {
$temp = penyebut($nilai / 1000000000000) . " trilyun" . penyebut(fmod($nilai, 1000000000000));
}
return $temp;
}
}
function terbilang($nilai)
{
function terbilang($nilai)
{
if ($nilai < 0) {
$hasil = "minus ". trim(penyebut($nilai));
$hasil = "minus " . trim(penyebut($nilai));
} else {
$hasil = trim(penyebut($nilai));
}
return $hasil;
}
// andy add
}
// andy add
function hitungHariKerja($tanggalMulai, $tanggalSelesai)
{
function hitungHariKerja($tanggalMulai, $tanggalSelesai)
{
$tanggalMulai = Carbon::parse($tanggalMulai)->startOfDay();
$tanggalSelesai = Carbon::parse($tanggalSelesai)->endOfDay();
@@ -285,19 +258,10 @@ function hitungHariKerja($tanggalMulai, $tanggalSelesai)
}
return $hariKerja;
}
}
function holidays()
{
return HolidayCalendar::pluck('date')->map(
function ($item) {
return Carbon::parse($item)->format('Y-m-d');
},
)->toArray();
}
function countPermohonanForUser($userId)
{
function countPermohonanForUser($userId)
{
$validStatuses = [
'assign',
'survey-completed',
@@ -334,11 +298,11 @@ function countPermohonanForUser($userId)
});
return $result->count();
}
}
function getMaxFileSize($jenis)
{
function getMaxFileSize($jenis)
{
$jenisDokumen = JenisDokumen::where('name', $jenis)->first();
if (!$jenisDokumen) {
return 2048;
@@ -347,15 +311,15 @@ function getMaxFileSize($jenis)
$maxSizeInKB = (int) $jenisDokumen->max_size * 1024;
return $maxSizeInKB;
}
}
function getUser($userId)
{
function getUser($userId)
{
return User::find($userId);
}
}
function generateLpjUniqueCode($randomLength = 6)
{
function generateLpjUniqueCode($randomLength = 6)
{
$year = date('y');
$month = str_pad(date('m'), 2, '0', STR_PAD_LEFT);
@@ -366,20 +330,20 @@ function generateLpjUniqueCode($randomLength = 6)
// Concatenate components to create the custom code
return $year . $month . $day . $randomNumber;
}
}
function checkRegionUserName($userId)
{
function checkRegionUserName($userId)
{
$region = TeamsUsers::where('user_id', $userId)->first();
if ($region) {
return $region->team->regions->name;
} else {
return null;
}
}
}
function getNomorLaporan($permohonanId, $documentId, $type = 'nomor_laporan')
{
function getNomorLaporan($permohonanId, $documentId, $type = 'nomor_laporan')
{
$laporan = Laporan::where([
'permohonan_id' => $permohonanId,
@@ -391,10 +355,10 @@ function getNomorLaporan($permohonanId, $documentId, $type = 'nomor_laporan')
}
return $type == 'nomor_laporan' ? $laporan->nomor_laporan : $laporan->created_at;
}
}
function getCustomField($param)
{
function getCustomField($param)
{
if (is_numeric($param)) {
$field = CustomField::find($param);
} else {
@@ -405,9 +369,10 @@ function getCustomField($param)
} else {
return null;
}
}
function getWilayahName($code, $type)
{
}
function getWilayahName($code, $type)
{
try {
$wilayah = null;
@@ -435,14 +400,14 @@ function getWilayahName($code, $type)
default:
return null;
}
} catch (\Exception $e) {
} catch (Exception $e) {
return null;
}
}
}
function formatLabel($key)
{
function formatLabel($key)
{
static $labelCache = [];
if (isset($labelCache[$key])) {
@@ -453,10 +418,10 @@ function formatLabel($key)
$labelCache[$key] = $customLabel->label ?? ucwords(str_replace('_', ' ', $key));
return $labelCache[$key];
}
}
function calculateSLA($permohonan, $type)
{
function calculateSLA($permohonan, $type)
{
if (!$type) {
return null;
}
@@ -479,19 +444,20 @@ function calculateSLA($permohonan, $type)
}
return $slaMap[$type] ?? null;
}
}
/**
/**
* Menghitung total nilai berdasarkan key dan jenis legalitas.
*
* @param array $detailsArray
* @param string $key
* @param int $jenisLegalitas
*
* @return int
*/
function calculateTotalLuas($detailsArray, $key, $jenisLegalitas, $defaultJenisLegalitas, $fallbackJenisLegalitas)
{
function calculateTotalLuas($detailsArray, $key, $jenisLegalitas, $defaultJenisLegalitas, $fallbackJenisLegalitas)
{
$total = 0;
if ($detailsArray) {
@@ -545,20 +511,34 @@ function calculateTotalLuas($detailsArray, $key, $jenisLegalitas, $defaultJenisL
}
return $total > 0 ? $total : 0;
}
}
function ubahNomorHp($nomorHp) {
function ubahNomorHp($nomorHp)
{
$nomorHp = preg_replace('/\D/', '', $nomorHp);
if (strpos($nomorHp, '62') === 0) {
$nomorBaru = substr($nomorHp, 0, 5) . "xxxxx";
return '+' . $nomorBaru;
} elseif (strpos($nomorHp, '0') === 0) {
} else if (strpos($nomorHp, '0') === 0) {
$nomorBaru = substr($nomorHp, 0, 5) . "xxxxxx";
return $nomorBaru;
} else {
return "Nomor HP tidak valid";
}
}
}
function formatNotifikasi($notifikasi)
{
$data = json_decode(json_encode($notifikasi->data));
$message = $data->message;
$data = $data->data;
$notifikasi = [
'title' => 'Permohonan : ' . $data->nomor_registrasi,
'message' => $message,
];
return $notifikasi;
}

View File

@@ -19,12 +19,7 @@
*/
public function index()
{
$permohonan = Permohonan::with([
'documents.jenisJaminan',
'penilaian._user_penilai',
'penilai',
'documents.detail.jenisLegalitasJaminan'
])->where(['status' => 'done'])->get();
$permohonan = Permohonan::where(['status' => 'done'])->get();
foreach ($permohonan as $_permohonan) {
$npw = 0;
if (isset($_permohonan->penilai->lpj)) {

View File

@@ -123,7 +123,7 @@ class LaporanController extends Controller
$filteredRecords = $query->count();
// 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
$pageCount = ceil($totalRecords / $size);

View File

@@ -0,0 +1,211 @@
<?php
namespace Modules\Lpj\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Lpj\Exports\LaporanHasilPenilaianJaminanInternalExternalExport;
use Modules\Lpj\Models\Permohonan;
class LaporanHasilPenilaianJaminanInternalExternalController extends Controller
{
public $user;
/**
* Display a listing of the resource.
*/
public function index()
{
return view('lpj::laporan_hasil_penilaian_jaminan_internal_external.index');
}
public function dataForDatatables(Request $request)
{
if (is_null($this->user) || !$this->user->can('laporan-admin-kredit.view')) {
//abort(403, 'Sorry! You are not allowed to view laporan admin kredit.');
}
// Retrieve data from the database
$query = Permohonan::query();
$query = $query->where('status', 'done');
// Apply search filter if provided
if ($request->has('search') && !empty($request->get('search'))) {
$search = json_decode($request->get('search'));
if (isset($search->start_date) || isset($search->end_date)) {
$query->whereBetween('tanggal_permohonan', [
$search->start_date ?? '1900-01-01',
$search->end_date ?? now()->toDateString()
]);
}
// Filter by branch if provided
if (isset($search->branch_id) && !empty($search->branch_id)) {
$query->where('branch_id', $search->branch_id);
}
if (isset($search->penilai_id) && !empty($search->penilai_id)) {
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function ($q) use ($search) {
$q->where('user_id', $search->penilai_id);
});
}
if (isset($search->search)) {
$query->where(function ($q) use ($search) {
$q->where('nomor_registrasi', 'LIKE', '%' . $search->search . '%');
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhere('status', 'LIKE', '%' . $search->search . '%');
});
}
}
// Apply sorting if provided
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
$order = $request->get('sortOrder');
$column = $request->get('sortField');
$query->orderBy($column, $order);
}
// Get the total count of records
$totalRecords = $query->count();
// Apply pagination if provided
if ($request->has('page') && $request->has('size')) {
$page = $request->get('page');
$size = $request->get('size');
$offset = ($page - 1) * $size; // Calculate the offset
$query->skip($offset)->take($size);
}
// Get the filtered count of records
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query->with(['debiture.branch'])->get();
$data = $data->map(function ($permohonan) {
$luas_tanah = 0;
$luas_bangunan = 0;
$nilai_tanah = 0;
$nilai_bangunan = 0;
$npw = 0;
$nilai_liquidasi = 0;
if (isset($permohonan->penilai->lpj)) {
$lpj = json_decode($permohonan->penilai->lpj, true);
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
$luas_tanah = $lpj['luas_tanah'] ?? 0;
$luas_bangunan = $lpj['luas_bangunan'] ?? 0;
// Calculate nilai_tanah dynamically by looking for all keys that start with 'nilai_tanah_'
$nilai_tanah = str_replace('.', '', $lpj['nilai_tanah_2'] ?? 0);
$nilai_bangunan = str_replace('.', '', $lpj['nilai_bangunan_2'] ?? 0);
$nilai_liquidasi = str_replace('.', '', $lpj['likuidasi_nilai_2'] ?? 0);
}
return [
'id' => $permohonan->id,
'nomor_registrasi' => $permohonan->nomor_registrasi,
'jenis_penilaian' => $permohonan->jenisPenilaian?->name,
'tujuan_penilaian' => $permohonan->tujuanPenilaian?->name,
'jenis_fasilitas_kredit' => $permohonan->jenisFasilitasKredit?->name,
'branch' => $permohonan->debiture->branch?->name,
'pemohon' => $permohonan->creator?->name,
'cif' => $permohonan->debiture->cif,
'name' => $permohonan->debiture?->name,
'jenis_agunan' => $permohonan->documents?->pluck('jenisJaminan.name')
->unique()
->implode(', '),
'alamat_agunan' => $permohonan->documents?->map(function ($document) {
return formatAlamat($document);
})->unique()->implode(', '),
'bukti_kepemilikan' => (function() use ($permohonan) {
$legalitasItems = $permohonan->documents?->flatMap(function ($document) {
return $document->detail->map(function ($detail) {
// Jika tidak ada jenis legalitas jaminan, lewati
if (empty($detail->jenisLegalitasJaminan)) {
return null;
}
// Hanya tampilkan detail yang memiliki dokumen_jaminan
if (empty($detail->dokumen_jaminan)) {
return null;
}
// Tampilkan nama legalitas jaminan saja
return $detail->jenisLegalitasJaminan->name ?? '';
});
})->filter()->unique()->values()->toArray();
// Buat daftar bernomor
$result = '';
foreach ($legalitasItems as $index => $item) {
$result .= ($index + 1) . '. ' . $item . "\n";
}
return $result;
})(),
'nama_pemilik' => $permohonan->documents?->pluck('pemilik.name')
->unique()
->implode(', '),
'luas_tanah' => $luas_tanah . ' m²',
'nilai_tanah' => formatRupiah($nilai_tanah, 2),
'luas_bangunan' => $luas_bangunan . ' m²',
'nilai_bangunan' => formatRupiah($nilai_bangunan, 2),
'nilai_njop' => formatRupiah($permohonan->nilai_njop, 2),
'nilai_pasar_wajar' => formatRupiah($npw, 2),
'nilai_likuidasi' => formatRupiah($nilai_liquidasi, 2),
'tanggal_documen_diterima' => $permohonan->documents?->map(function ($document) {
return $document->created_at->format('d-m-Y');
}),
'tanggal_spk' => '',
'nomor_spk' => '',
'tanggal_rencana_kunjunagn' => '',
'tanggal_kunjungan' => '',
'taggal_delivered' => '',
'jangka_waktu_sla' => '',
'nama_penilai' => $permohonan->penilaian?->_user_penilai?->userPenilaiTeam?->name,
'nama_team_leader' => $permohonan->penilaian?->teams,
'saran' => '',
'catatan' => '',
'tanggal_permohonan' => $permohonan->tanggal_permohonan,
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
'tanggal_review' => $permohonan->penilaian?->tanggal_kunjungan ?? '',
];
});
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = $request->get('page') ?: 1;
// Return the response data as a JSON object
return response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
'totalCount' => $totalRecords,
'data' => $data,
]);
}
public function export(Request $request)
{
return Excel::download(new LaporanHasilPenilaianJaminanInternalExternalExport($request), 'laporan_hasil_penilaian_jaminan_internal_external.xlsx');
}
}

View File

@@ -0,0 +1,161 @@
<?php
namespace Modules\Lpj\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Modules\Lpj\Exports\LaporanPenilaianJaminanExport;
use Modules\Lpj\Models\Permohonan;
use Maatwebsite\Excel\Facades\Excel;
class LaporanPenilaianJaminanController extends Controller
{
public $user;
/**
* Display a listing of the resource.
*/
public function index()
{
return view('lpj::laporan_penilaian_jaminan.index');
}
public function dataForDatatables(Request $request)
{
if (is_null($this->user) || !$this->user->can('laporan-admin-kredit.view')) {
//abort(403, 'Sorry! You are not allowed to view laporan admin kredit.');
}
// Retrieve data from the database
$query = Permohonan::query();
$query = $query->where('status', 'done');
// Apply search filter if provided
if ($request->has('search') && !empty($request->get('search'))) {
$search = json_decode($request->get('search'));
if (isset($search->start_date) || isset($search->end_date)) {
$query->whereBetween('tanggal_permohonan', [
$search->start_date ?? '1900-01-01',
$search->end_date ?? now()->toDateString()
]);
}
// Filter by branch if provided
if (isset($search->branch_id) && !empty($search->branch_id)) {
$query->where('branch_id', $search->branch_id);
}
if (isset($search->penilai_id) && !empty($search->penilai_id)) {
$query->whereHas('penilaian._user_penilai.userPenilaiTeam', function($q) use ($search) {
$q->where('user_id', $search->penilai_id);
});
}
if (isset($search->search)) {
$query->where(function ($q) use ($search) {
$q->where('nomor_registrasi', 'LIKE', '%' . $search->search . '%');
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('tujuanPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('branch', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('jenisFasilitasKredit', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhereRelation('jenisPenilaian', 'name', 'LIKE', '%' . $search->search . '%');
$q->orWhere('status', 'LIKE', '%' . $search->search . '%');
});
}
}
// Apply sorting if provided
if ($request->has('sortOrder') && !empty($request->get('sortOrder'))) {
$order = $request->get('sortOrder');
$column = $request->get('sortField');
$query->orderBy($column, $order);
}
// Get the total count of records
$totalRecords = $query->count();
// Apply pagination if provided
if ($request->has('page') && $request->has('size')) {
$page = $request->get('page');
$size = $request->get('size');
$offset = ($page - 1) * $size; // Calculate the offset
$query->skip($offset)->take($size);
}
// Get the filtered count of records
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query->with(['debiture.branch'])->get();
$data = $data->map(function ($permohonan) {
$luas_tanah = 0;
$luas_bangunan = 0;
$nilai_tanah = 0;
$nilai_bangunan = 0;
$npw = 0;
$nilai_liquidasi = 0;
if (isset($permohonan->penilai->lpj)) {
$lpj = json_decode($permohonan->penilai->lpj, true);
$npw = str_replace('.', '', $lpj['total_nilai_pasar_wajar'] ?? 0);
$luas_tanah = $lpj['luas_tanah'] ?? 0;
$luas_bangunan = $lpj['luas_bangunan'] ?? 0;
// Calculate nilai_tanah dynamically by looking for all keys that start with 'nilai_tanah_'
$nilai_tanah = str_replace('.', '', $lpj['nilai_tanah_2'] ?? 0);
$nilai_bangunan = str_replace('.', '', $lpj['nilai_bangunan_2'] ?? 0);
$nilai_liquidasi = str_replace('.', '', $lpj['likuidasi_nilai_2'] ?? 0);
}
return [
'id' => $permohonan->id,
'nomor_registrasi' => $permohonan->nomor_registrasi,
'tanggal_permohonan' => $permohonan->tanggal_permohonan,
'branch' => $permohonan->debiture?->branch?->name,
'name' => $permohonan->debiture?->name,
'pemohon' => $permohonan->creator?->name,
'tujuan_penilaian' => $permohonan->tujuanPenilaian?->name,
'jenis_agunan' => $permohonan->documents?->pluck('jenisJaminan.name')->unique()->implode(', '),
'alamat_agunan' => $permohonan->documents?->map(function ($document) {
return formatAlamat($document);
})->unique()->implode(', '),
'luas_tanah' => $luas_tanah . ' m²',
'nilai_tanah' => formatRupiah($nilai_tanah,2),
'luas_bangunan' => $luas_bangunan . ' m²',
'nilai_bangunan' => formatRupiah($nilai_bangunan,2),
'tanggal_laporan' => $permohonan->approval_dd_at ?? $permohonan->approval_eo_at ?? '',
'tanggal_review' => $permohonan->penilaian?->tanggal_kunjungan ?? '',
'nilai_pasar_wajar' => formatRupiah($npw,2),
'nilai_likuidasi' => formatRupiah($nilai_liquidasi,2),
'nama_penilai' => $permohonan->penilaian?->_user_penilai?->userPenilaiTeam?->name,
];
});
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
// Calculate the current page number
$currentPage = $request->get('page', 1);
// Return the response data as a JSON object
return response()->json([
'draw' => $request->get('draw'),
'recordsTotal' => $totalRecords,
'recordsFiltered' => $filteredRecords,
'pageCount' => $pageCount,
'page' => $currentPage,
'totalCount' => $totalRecords,
'data' => $data,
]);
}
public function export(Request $request)
{
return Excel::download(new LaporanPenilaianJaminanExport($request), 'laporan_penilaian_jaminan.xlsx');
}
}

View File

@@ -6,6 +6,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Modules\Lpj\Http\Requests\NocRequest;
use Modules\Lpj\Models\Noc;
use Modules\Lpj\Models\PenawaranTender;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\PersetujuanPenawaran;
@@ -43,34 +44,43 @@
$status = "persetujuan-penawaran";
}
$persetujuanPenawaran = PersetujuanPenawaran::updateOrCreate(
['penawaran_id' => $validated['penawaran_id']],
$validated,
$dataNoc = [
'nominal_bayar' => $validated['nominal_bayar'],
'tanggal_pembayaran' => $validated['tanggal_pembayaran'] ?? date('Y-m-d'),
'status_bayar' => $validated['nominal_bayar'] < $validated['total_harus_bayar'] ? false : true,
'catatan_noc' => $validated['catatan_noc'],
];
$noc = Noc::updateOrCreate(
[
'permohonan_id' => $validated['permohonan_id'],
'persetujuan_penawaran_id' => $validated['persetujuan_penawaran_id'],
],
$dataNoc,
);
$folderPath = 'noc/' . $validated['penawaran_id'];
$folderPath = 'noc/' . request()->get('persetujuan_penawaran_id') . '/bukti_ksl/';
if ($request->hasFile('bukti_ksl')) {
$persetujuanPenawaran->bukti_ksl = $request->file('bukti_ksl')->store(
$noc->bukti_ksl = $request->file('bukti_ksl')->store(
$folderPath,
'public',
);
}
$persetujuanPenawaran->save();
$noc->save();
// Update the status of the related permohonan to 'spk'
$permohonan = Permohonan::find(request()->get('permohonan_id'));
if ($permohonan) {
$permohonan->status_bayar = request()->get('status_bayar');
if($permohonan->jenis_penilaian_id==2) {
$permohonan->status_bayar = request()->get('status_pembayar');
if ($permohonan->jenis_penilaian_id == 2) {
$permohonan->status = $status;
}
$permohonan->save();
// andy add, update status penawaran.status='spk'
// $penawaran = PenawaranTender::where('nomor_registrasi',$permohonan->nomor_registrasi)->first();
if($permohonan->jenis_penilaian_id==2) {
if ($permohonan->jenis_penilaian_id == 2) {
PenawaranTender::where('nomor_registrasi', $permohonan->nomor_registrasi)->update([
'status' => $status,
'updated_by' => Auth::id(),
@@ -81,7 +91,7 @@
}
return redirect()
->route('noc.index')->with('success', 'Penyelesaian KSL berhasil disimpan.');
->route('noc.index')->with('success', 'NOC berhasil disimpan.');
}
/**
@@ -90,12 +100,56 @@
public function update(NocRequest $request, PersetujuanPenawaran $persetujuanPenawaran)
{
$validated = $request->validated();
$validated['updated_by'] = Auth::id();
$persetujuanPenawaran->update($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('noc.index')->with('success', 'Persetujuan Penawaran updated successfully');
->route('laporan.index')->with('success', 'Memo Penyelesaian updated successfully');
}
$dataNoc = [
'nominal_penyelesaian' => $validated['nominal_penyelesaian'],
'tanggal_penyelesaian' => $validated['tanggal_penyelesaian'] ?? date('Y-m-d'),
'status_pelunasan' => ((int)$validated['nominal_bayar'] + (int)$validated['nominal_penyelesaian']) === (int)$validated['total_harus_bayar'] ? true : false,
'catatan_noc' => $validated['catatan_noc'],
];
$noc = Noc::updateOrCreate(
[
'permohonan_id' => $validated['permohonan_id'],
'persetujuan_penawaran_id' => $validated['persetujuan_penawaran_id'],
],
$dataNoc,
);
$folderPath = 'noc/' . request()->get('persetujuan_penawaran_id') . '/bukti_penyelesaian/';
if ($request->hasFile('bukti_penyelesaian')) {
$noc->bukti_penyelesaian = $request->file('bukti_penyelesaian')->store(
$folderPath,
'public',
);
}
$noc->save();
return redirect()
->route('noc.index')->with('success', 'NOC updated successfully');
}
/**
@@ -109,16 +163,18 @@
/**
* 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.
*/
public function edit($id)
{
$persetujuanPenawaran = PersetujuanPenawaran::where('id', $id)->with(
['penawaran.detail', 'penawaran.permohonan.debiture','permohonan'],
)->first();
$persetujuanPenawaran = PersetujuanPenawaran::where('id', $id)->first();
return view('lpj::noc.form', compact('persetujuanPenawaran'));
}
@@ -173,18 +229,36 @@
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query
->with(
[
'penawaran.permohonan.debiture',
'penawaran.permohonan.branch',
'permohonan.debiture',
'permohonan.branch',
'penawaran.detail',
'penawaran.persetujuan',
],
)->get();
$data = $query->get();
$data = $data->map(function ($persetujuanPenawaran) {
return [
'id' => $persetujuanPenawaran->id,
'nomor_registrasi' => $persetujuanPenawaran->permohonan->nomor_registrasi ?? $persetujuanPenawaran->penawaran->nomor_registrasi,
'nama_debitur' => $persetujuanPenawaran->permohonan->debiture->name ?? $persetujuanPenawaran->penawaran->permohonan->debiture->name,
'cabang' => $persetujuanPenawaran->permohonan->branch->name ?? $persetujuanPenawaran->penawaran->permohonan->branch->name,
'tanggal_pembayaran' => dateFormat(
$persetujuanPenawaran->noc->tanggal_pembayaran ?? $persetujuanPenawaran->noc?->created_at,
true,
),
'nominal_bayar' => currencyFormat($persetujuanPenawaran->nominal_bayar ?? 0,
),
'nominal_diterima' => currencyFormat(
$persetujuanPenawaran->noc->nominal_bayar ?? 0,
),
'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,
'nominal_penyelesaian' => currencyFormat(
$persetujuanPenawaran->noc->nominal_penyelesaian ?? $persetujuanPenawaran->nominal_penyelesaian ?? 0,
),
'bukti_penyelesaian' => $persetujuanPenawaran->noc->bukti_penyelesaian ?? $persetujuanPenawaran->bukti_penyelesaian ?? null,
'tanggal_penyelesaian' => $persetujuanPenawaran->noc?->tanggal_penyelesaian ? dateFormat(
$persetujuanPenawaran->noc?->tanggal_penyelesaian,
true) : '-',
'updated_at' => dateFormat($persetujuanPenawaran->updated_at, true),
];
})->sortBy('updated_at', 1);
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));

View File

@@ -263,8 +263,7 @@ class PembayaranController extends Controller
$subquery->select('permohonan_id')
->from('persetujuan_penawaran')
->whereNotNull('permohonan_id');
})
->orWhere('status', 'revisi-pembayaran');
});
});

View File

@@ -82,7 +82,7 @@ class PenilaiController extends Controller
public function sederhana(Request $request, $id)
{
$documentId = $request->query('documentId');
$documentId = $request->query('dokument');
$jaminanId = $request->query('jaminanId');
$permohonan = $this->surveyorController->getPermohonanJaminanId($id, $documentId, $jaminanId);
$basicData = $this->surveyorController->getCommonData();
@@ -148,10 +148,15 @@ class PenilaiController extends Controller
public function standar(Request $request, $id)
{
$documentId = $request->query('documentId');
$documentId = $request->query('dokument');
$jaminanId = $request->query('jaminanId');
$permohonan = $this->surveyorController->getPermohonanJaminanId($id, $documentId, $jaminanId);
if ($permohonan->status == 'proses-laporan') {
return redirect()->back()->with('error', 'Masih dalam proses laporan');
}
$basicData = $this->surveyorController->getCommonData();
$noLpSederhana = $this->generateNoLaporan($permohonan, $documentId, 'lpj');
@@ -218,6 +223,11 @@ class PenilaiController extends Controller
$jaminanId = $request->query('jaminanId');
$permohonan = $this->surveyorController->getPermohonanJaminanId($permohonanId, $documentId, $jaminanId);
if ($permohonan->status == 'proses-laporan') {
return redirect()->back()->with('error', 'Masih dalam proses laporan');
}
$nomorLaporan = $this->generateNoLaporan($permohonan, $documentId, 'resume');
$inspeksi = Inspeksi::where('permohonan_id', $permohonanId)->where('dokument_id', $documentId)->first();
$noLpresume = $this->generateNoLaporan($permohonan, $documentId, 'resume');
@@ -253,6 +263,9 @@ class PenilaiController extends Controller
$data = $this->getDataPermohonanWithPenilaiAndInspeksi($req['permohonanId'], $req['documentId'], $req['jaminanId']);
$permohonan = $data['permohonan'];
if ($permohonan->status == 'proses-laporan') {
return redirect()->back()->with('error', 'Masih dalam proses laporan');
}
$nomorLaporan = $this->generateNoLaporan($permohonan, $req['documentId'], 'memo');
$inspeksi = Inspeksi::where('permohonan_id', $req['permohonanId'])->where('dokument_id', $req['documentId'])->first();
@@ -388,10 +401,15 @@ class PenilaiController extends Controller
{
$permohonanId = $request->query('permohonanId');
$documentId = $request->query('documentId');
$documentId = $request->query('dokument');
$jaminanId = $request->query('jaminanId');
$provinces = Province::all();
$permohonan = $this->surveyorController->getPermohonanJaminanId($permohonanId, $documentId, $jaminanId);
if ($permohonan->status == 'proses-laporan') {
return redirect()->back()->with('error', 'Masih dalam proses laporan');
}
$nomorLaporan = $this->generateNoLaporan($permohonan, $documentId, 'rap');
$basicData = $this->surveyorController->getCommonData();
$inspeksi = Inspeksi::where('permohonan_id', $permohonanId)->where('dokument_id', $documentId)->first();
@@ -470,6 +488,9 @@ class PenilaiController extends Controller
$jaminanId = $request->query('jaminanId');
$provinces = Province::all();
$permohonan = $this->surveyorController->getPermohonanJaminanId($permohonanId, $documentId, $jaminanId);
if ($permohonan->status == 'proses-laporan') {
return redirect()->back()->with('error', 'Masih dalam proses laporan');
}
$nomorLaporan = $this->generateNoLaporan($permohonan, $documentId, 'call-report');
$basicData = $this->surveyorController->getCommonData();
$inspeksi = Inspeksi::where('permohonan_id', $permohonanId)->where('dokument_id', $documentId)->first();

View File

@@ -1,35 +1,34 @@
<?php
namespace Modules\Lpj\Http\Controllers;
namespace Modules\Lpj\Http\Controllers;
use App\Http\Controllers\Controller;
use Barryvdh\DomPDF\Facade\Pdf;
use Exception;
use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Location\Models\City;
use Modules\Location\Models\District;
use Modules\Location\Models\Province;
use Modules\Location\Models\Village;
use Modules\Lpj\Models\PermohonanPembatalan;
use Modules\Lpj\Exports\PermohonanExport;
use Modules\Lpj\Http\Requests\PermohonanRequest;
use Modules\Lpj\Models\Branch;
use Modules\Lpj\Models\Debiture;
use Modules\Lpj\Models\DokumenJaminan;
use Modules\Lpj\Models\JenisFasilitasKredit;
use Modules\Lpj\Models\NilaiPlafond;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\StatusPermohonan;
use Modules\Lpj\Models\TujuanPenilaian;
use Modules\Lpj\Services\PermohonanHistoryService;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\DB;
use Modules\Lpj\Models\Penilaian;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Maatwebsite\Excel\Facades\Excel;
use Modules\Location\Models\City;
use Modules\Location\Models\District;
use Modules\Location\Models\Province;
use Modules\Location\Models\Village;
use Modules\Lpj\Exports\PermohonanExport;
use Modules\Lpj\Http\Requests\PermohonanRequest;
use Modules\Lpj\Models\Branch;
use Modules\Lpj\Models\Debiture;
use Modules\Lpj\Models\DokumenJaminan;
use Modules\Lpj\Models\JenisFasilitasKredit;
use Modules\Lpj\Models\NilaiPlafond;
use Modules\Lpj\Models\Penilaian;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\PermohonanPembatalan;
use Modules\Lpj\Models\StatusPermohonan;
use Modules\Lpj\Models\TujuanPenilaian;
use Modules\Lpj\Services\PermohonanHistoryService;
class PermohonanController extends Controller
{
class PermohonanController extends Controller
{
public $user;
protected $historyService;
@@ -75,7 +74,10 @@ class PermohonanController extends Controller
$documents = DokumenJaminan::where('permohonan_id', $permohonan->id)->get();
if (count($documents) < 1) {
return redirect()->route('debitur.jaminan.create', array_merge(['permohonan_id' => $permohonan->id], ['id' => $permohonan->debiture->id]))->with('success', 'Permohonan created successfully, Lengkapi data jaminan terlebih dahulu');
return redirect()->route(
'debitur.jaminan.create',
array_merge(['permohonan_id' => $permohonan->id], ['id' => $permohonan->debiture->id]),
)->with('success', 'Permohonan created successfully, Lengkapi data jaminan terlebih dahulu');
}
return redirect()
->route('permohonan.index')->with('success', 'Permohonan created successfully');
@@ -144,35 +146,6 @@ class PermohonanController extends Controller
);
}
public function update(PermohonanRequest $request, $id)
{
$permohonan = Permohonan::findOrFail($id);
$beforeRequest = $permohonan->toArray();
$validate = $request->validated();
if ($validate) {
try {
// Update in database
if ($permohonan->status == 'revisi') {
$validate['status'] = 'order';
}
$permohonan->update($validate);
$documents = DokumenJaminan::where('permohonan_id', $permohonan->id)->get();
if (count($documents) < 1) {
return redirect()->route('debitur.jaminan.create', array_merge(['permohonan_id' => $permohonan->id], ['id' => $permohonan->debiture->id]))->with('success', 'Permohonan created successfully, Lengkapi data jaminan terlebih dahulu');
}
return redirect()
->route('permohonan.index')->with('success', 'Permohonan updated successfully');
} catch (Exception $e) {
return redirect()
->route('permohonan.edit', $id)->with('error', 'Failed to update permohonan');
}
}
}
public function destroy($id)
{
try {
@@ -205,6 +178,7 @@ class PermohonanController extends Controller
$search = $request->get('search');
$query->where(function ($q) use ($search) {
$q->where('nomor_registrasi', 'LIKE', '%' . $search . '%');
$q->orWhere('mig_mst_lpj_nomor_jaminan', 'LIKE', '%' . $search . '%');
$q->orWhere('tanggal_permohonan', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('user', 'name', 'LIKE', '%' . $search . '%');
$q->orWhereRelation('debiture', 'name', 'LIKE', '%' . $search . '%');
@@ -241,7 +215,37 @@ class PermohonanController extends Controller
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian', 'penilaian','documents'])->get();
$data = $query->get();
$data = $data->map(function ($item) {
return [
'id' => $item->id,
'nomor_registrasi' => $item->nomor_registrasi,
'mig_mst_lpj_nomor_jaminan' => $item->mig_mst_lpj_nomor_jaminan,
'tanggal_permohonan' => $item->tanggal_permohonan ? dateFormat(
$item->tanggal_permohonan,
) : null,
'pemohon' => $item->user->name ?? 'N/A',
'branch' => $item->branch->name ?? 'N/A',
'debiture' => [
'name' => $item->debiture->name,
],
'tujuan_penilaian' => [
'code' => $item->tujuanPenilaian->code ?? null,
'name' => $item->tujuanPenilaian->name ?? null,
],
'status' => $item->status,
'documents' => count($item->documents),
'keterangan' => $item->keterangan,
'penilaian' => [
'id' => $item->penilaian->id ?? null,
'waktu_penilaian' => $item->penilaian->waktu_penilaian ?? null,
'rejected_note' => $item->penilaian->rejected_note ?? null,
'authorized_status' => $item->penilaian->authorized_status ?? null,
],
'registrasi_catatan' => $item->registrasi_catatan,
];
});
// Calculate the page count
$pageCount = ceil($totalRecords / $size);
@@ -321,8 +325,7 @@ class PermohonanController extends Controller
$filteredRecords = $query->count();
// Get the data for the current page
$data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian'])->get(
);
$data = $query->with(['user', 'debiture', 'branch', 'tujuanPenilaian'])->get();
// Calculate the page count
$pageCount = ceil($totalRecords / $request->get('size'));
@@ -380,11 +383,10 @@ class PermohonanController extends Controller
public function showPembatalan($id)
{
$permohonan = Permohonan::with(['pembatalan','debiture'])->findOrFail($id);
$permohonan = Permohonan::with(['pembatalan', 'debiture'])->findOrFail($id);
return view('lpj::permohonan.pembatalan-form', compact('permohonan'));
}
public function pembatalan(Request $request)
{
// Validate the request
@@ -411,8 +413,8 @@ class PermohonanController extends Controller
return redirect()->route('permohonan.index')->with('success', 'Pembatalan Permohonan Menunggu Approval');
}
public function storeAproved(Request $request, $id): JsonResponse
{
public function storeAproved(Request $request, $id)
: JsonResponse {
$data = [];
if (request()->ajax()) {
try {
@@ -424,16 +426,15 @@ class PermohonanController extends Controller
$permohonan = Permohonan::findOrFail($request->permohonan_id);
$permohonan->update([
'status' => 'proses-survey'
'status' => 'proses-survey',
]);
$data['status'] = 'success';
$data['message'] = 'Jadwal '.$request->noReg.' berhasil di aprove';
} catch (\Exception $e) {
$data['message'] = 'Jadwal ' . $request->noReg . ' berhasil di aprove';
} catch (Exception $e) {
$data['status'] = 'error';
$data['message'] = 'Gagal membuat jadwal: ' . $e->getMessage();
}
} else {
$data['status'] = 'error';
$data['message'] = "no ajax request";
@@ -442,6 +443,37 @@ class PermohonanController extends Controller
return response()->json($data);
}
public function update(PermohonanRequest $request, $id)
{
$permohonan = Permohonan::findOrFail($id);
$beforeRequest = $permohonan->toArray();
$validate = $request->validated();
if ($validate) {
try {
// Update in database
if ($permohonan->status == 'revisi') {
$validate['status'] = 'order';
}
$permohonan->update($validate);
$documents = DokumenJaminan::where('permohonan_id', $permohonan->id)->get();
if (count($documents) < 1) {
return redirect()->route(
'debitur.jaminan.create',
array_merge(['permohonan_id' => $permohonan->id], ['id' => $permohonan->debiture->id]),
)->with('success', 'Permohonan created successfully, Lengkapi data jaminan terlebih dahulu');
}
return redirect()
->route('permohonan.index')->with('success', 'Permohonan updated successfully');
} catch (Exception $e) {
return redirect()
->route('permohonan.edit', $id)->with('error', 'Failed to update permohonan');
}
}
}
public function storeRescheduleSurvey(Request $request, $id)
{
@@ -452,14 +484,14 @@ class PermohonanController extends Controller
'nomor_registrasi' => 'required',
'reschedule_note' => 'required',
'reschedule_date' => 'required',
'keterangan' => 'required'
'keterangan' => 'required',
]);
DB::beginTransaction();
$permohonan = Permohonan::findOrFail($request->permohonan_id);
$permohonan->update([
'status' => 'request-reschedule'
'status' => 'request-reschedule',
]);
$penilaian = Penilaian::findOrFail($id);
@@ -472,9 +504,9 @@ class PermohonanController extends Controller
DB::commit();
return response()->json([
'status' => 'success',
'message' => 'Proses request reschedule permohonan Nomor registrasi '.$request->nomor_registrasi.' berhasil',
'message' => 'Proses request reschedule permohonan Nomor registrasi ' . $request->nomor_registrasi . ' berhasil',
]);
} catch (\Exception $e) {
} catch (Exception $e) {
DB::rollBack();
return response()->json([
'status' => 'error',
@@ -483,4 +515,4 @@ class PermohonanController extends Controller
}
}
}
}

View File

@@ -6,6 +6,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Modules\Lpj\Http\Requests\PersetujuanPenawaranRequest;
use Modules\Lpj\Models\Noc;
use Modules\Lpj\Models\PenawaranDetailTender;
use Modules\Lpj\Models\PenawaranDetailTenderLog;
use Modules\Lpj\Models\PenawaranTender;
@@ -67,6 +68,22 @@
$persetujuanPenawaran->save();
// Save NOC
try {
$noc = Noc::updateOrCreate([
'permohonan_id' => $persetujuanPenawaran->permohonan_id,
'persetujuan_penawaran_id' => $persetujuanPenawaran->id
],[
'bukti_bayar' => $persetujuanPenawaran->bukti_bayar,
]);
} catch (\Exception $e) {
\Log::error('Failed to create or update NOC: ' . $e->getMessage());
return redirect()
->route('persetujuan-penawaran.index')
->with('error', 'Persetujuan Penawaran berhasil disimpan tetapi gagal membuat NOC: ' . $e->getMessage());
}
return redirect()
->route('persetujuan-penawaran.index')->with('success', 'Persetujuan Penawaran berhasil disimpan.');
}

View File

@@ -4,20 +4,150 @@
use Illuminate\Foundation\Http\FormRequest;
/**
* Form Request untuk validasi data NOC (Notice of Completion)
*/
class NocRequest extends FormRequest
{
/**
* Konstanta untuk jenis file yang diizinkan
*/
private const ALLOWED_FILE_TYPES = 'pdf,jpg,jpeg,png';
/**
* Konstanta untuk ukuran file maksimum (dalam KB)
*/
private const MAX_FILE_SIZE = 10240;
/**
* Menentukan apakah pengguna berwenang untuk melakukan request ini
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Mengumpulkan semua aturan validasi
*
* @return array
*/
public function rules()
{
return array_merge(
$this->getBasicInfoRules(),
$this->getPaymentRules(),
$this->getSettlementRules(),
$this->getAuthorizationRules(),
);
}
/**
* Aturan validasi untuk informasi dasar
*
* @return array
*/
private function getBasicInfoRules()
{
return [
'penawaran_id' => 'nullable|exists:penawaran,id',
'nominal_bayar' => 'nullable|numeric|min:0',
'bukti_ksl' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:10240',
'permohonan_id' => 'required|exists:permohonan,id',
'persetujuan_penawaran_id' => 'required|exists:persetujuan_penawaran,id',
'status' => 'nullable|boolean',
'created_by' => 'nullable|exists:users,id',
'updated_by' => 'nullable|exists:users,id',
];
}
/**
* Aturan validasi untuk data pembayaran
*
* @return array
*/
private function getPaymentRules()
{
$fileRule = 'nullable|file|mimes:' . self::ALLOWED_FILE_TYPES . '|max:' . self::MAX_FILE_SIZE;
return [
'total_harus_bayar' => 'nullable|numeric|min:0',
'nominal_bayar' => 'nullable|numeric|min:0',
'bukti_ksl' => $fileRule,
'bukti_bayar' => $fileRule,
'status_bayar' => 'nullable|boolean',
'tanggal_pembayaran' => 'nullable|date',
];
}
/**
* Aturan validasi untuk data penyelesaian
*
* @return array
*/
private function getSettlementRules()
{
$fileRule = 'nullable|file|mimes:' . self::ALLOWED_FILE_TYPES . '|max:' . self::MAX_FILE_SIZE;
return [
'nominal_penyelesaian' => 'nullable|numeric|min:0',
'status_penyelesaian' => 'nullable|boolean',
'tanggal_penyelesaian' => 'nullable|date',
'bukti_penyelesaian' => $fileRule,
'memo_penyelesaian' => $fileRule,
'catatan_noc' => 'nullable|string',
];
}
/**
* Aturan validasi untuk otorisasi
*
* @return array
*/
private function getAuthorizationRules()
{
return [
'authorized_status' => 'nullable|boolean',
'authorized_at' => 'nullable|date',
'authorized_by' => 'nullable|exists:users,id',
];
}
/**
* Pesan khusus untuk validasi
*
* @return array
*/
public function messages()
{
return [
'permohonan_id.required' => 'ID Permohonan harus diisi',
'permohonan_id.exists' => 'ID Permohonan tidak valid',
'persetujuan_penawaran_id.required' => 'ID Persetujuan Penawaran harus diisi',
'persetujuan_penawaran_id.exists' => 'ID Persetujuan Penawaran tidak valid',
'nominal_bayar.numeric' => 'Nominal Bayar harus berupa angka',
'nominal_bayar.min' => 'Nominal Bayar minimal 0',
'bukti_ksl.file' => 'Bukti KSL harus berupa file',
'bukti_ksl.mimes' => 'Bukti KSL harus berformat pdf, jpg, jpeg, atau png',
'bukti_ksl.max' => 'Ukuran Bukti KSL maksimal 10MB',
'bukti_bayar.file' => 'Bukti Bayar harus berupa file',
'bukti_bayar.mimes' => 'Bukti Bayar harus berformat pdf, jpg, jpeg, atau png',
'bukti_bayar.max' => 'Ukuran Bukti Bayar maksimal 10MB',
'status.boolean' => 'Status harus berupa boolean',
'status_bayar.boolean' => 'Status Bayar harus berupa boolean',
'tanggal_pembayaran.date' => 'Format Tanggal Pembayaran tidak valid',
'nominal_penyelesaian.numeric' => 'Nominal Penyelesaian harus berupa angka',
'nominal_penyelesaian.min' => 'Nominal Penyelesaian minimal 0',
'status_penyelesaian.boolean' => 'Status Penyelesaian harus berupa boolean',
'tanggal_penyelesaian.date' => 'Format Tanggal Penyelesaian tidak valid',
'bukti_penyelesaian.file' => 'Bukti Penyelesaian harus berupa file',
'bukti_penyelesaian.mimes' => 'Bukti Penyelesaian harus berformat pdf, jpg, jpeg, atau png',
'bukti_penyelesaian.max' => 'Ukuran Bukti Penyelesaian maksimal 10MB',
'memo_penyelesaian.file' => 'Memo Penyelesaian harus berupa file',
'memo_penyelesaian.mimes' => 'Memo Penyelesaian harus berformat pdf, jpg, jpeg, atau png',
'memo_penyelesaian.max' => 'Ukuran Memo Penyelesaian maksimal 10MB',
'authorized_status.boolean' => 'Status Otorisasi harus berupa boolean',
'authorized_at.date' => 'Format Tanggal Otorisasi tidak valid',
'authorized_by.exists' => 'User Otorisasi tidak valid',
];
}
}

View File

@@ -23,8 +23,6 @@
'sla_final' => 'nullable|numeric|min:0',
'file_persetujuan_penawaran' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
'surat_representasi' => 'nullable|file|mimes:pdf,doc,docx|max:10240',
'bukti_bayar' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:10240',
'nominal_bayar' => 'nullable|numeric|min:0',
'status' => 'nullable|boolean',
'authorized_status' => 'boolean',
'authorized_at' => 'nullable|date',
@@ -52,9 +50,6 @@
'surat_representasi.file' => 'Surat Representasi harus berupa file.',
'surat_representasi.mimes' => 'Surat Representasi harus berupa file PDF, DOC, atau DOCX.',
'surat_representasi.max' => 'Ukuran Surat Representasi tidak boleh lebih dari 10MB.',
'bukti_bayar.file' => 'Bukti Bayar harus berupa file.',
'bukti_bayar.mimes' => 'Bukti Bayar harus berupa file PDF, JPG, JPEG, atau PNG.',
'bukti_bayar.max' => 'Ukuran Bukti Bayar tidak boleh lebih dari 10MB.',
'region_id.required' => 'Region ID wajib diisi.',
'region_id.exists' => 'Region ID tidak valid.',
'status.required' => 'Status wajib diisi.',
@@ -62,8 +57,6 @@
'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.',
'status_bayar.required' => 'Status bayar wajib diisi.',
'status_bayar.in' => 'Status bayar harus berupa "sudah_bayar", "belum_bayar" atau "tidak bayar".',
];
}
}

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\AnalisaFactory;
class Analisa extends Model
class Analisa extends Base
{
use HasFactory;
protected $table = 'analisa';

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\AnalisaFaktaFactory;
class AnalisaFakta extends Model
class AnalisaFakta extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\AnalisaLingkunganFactory;
class AnalisaLingkungan extends Model
class AnalisaLingkungan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\AnalisaTanahBagunanFactory;
class AnalisaTanahBagunan extends Model
class AnalisaTanahBagunan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\AnalisaUnitFactory;
class AnalisaUnit extends Model
class AnalisaUnit extends Base
{
use HasFactory;

View File

@@ -7,6 +7,7 @@
use Spatie\Activitylog\LogOptions;
use Spatie\Activitylog\Traits\LogsActivity;
use Wildside\Userstamps\Userstamps;
use Illuminate\Notifications\Notifiable;
/**
@@ -14,7 +15,7 @@
*/
class Base extends Model
{
use LogsActivity, SoftDeletes, Userstamps;
use LogsActivity, SoftDeletes, Userstamps, Notifiable;
protected $connection;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\BentukTanahFactory;
class BentukTanah extends Model
class BentukTanah extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\BentukUnitFactory;
class BentukUnit extends Model
class BentukUnit extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\DenahFactory;
class Denah extends Model
class Denah extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\FasilitasObjekFactory;
class FasilitasObjek extends Model
class FasilitasObjek extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\FotoJaminanFactory;
class FotoJaminan extends Model
class FotoJaminan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\FotoObjekJaminanFactory;
class FotoObjekJaminan extends Model
class FotoObjekJaminan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\GolonganMasySekitarFactory;
class GolonganMasySekitar extends Model
class GolonganMasySekitar extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\InspeksiFactory;
class Inspeksi extends Model
class Inspeksi extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\JenisBangunanFactory;
class JenisBangunan extends Model
class JenisBangunan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\JenisKapalFactory;
class JenisKapal extends Model
class JenisKapal extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\JenisKendaraanFactory;
class JenisKendaraan extends Model
class JenisKendaraan extends Base
{
use HasFactory;

View File

@@ -5,7 +5,7 @@ namespace Modules\Lpj\Models;
use Illuminate\Database\Eloquent\Model;
use Modules\Lpj\Database\Factories\JenisPenilaianFactory;
use Modules\Lpj\Models\Penilaian;
class JenisPenilaian extends Model
class JenisPenilaian extends Base
{
/**

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\JenisPesawatFactory;
class JenisPesawat extends Model
class JenisPesawat extends Base
{
use HasFactory;

View File

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\JenisUnitFactory;
class JenisUnit extends Model
class JenisUnit extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\KetinggianTanahFactory;
class KetinggianTanah extends Model
class KetinggianTanah extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\KondisiBangunanFactory;
class KondisiBangunan extends Model
class KondisiBangunan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\KondisiFisikTanahFactory;
class KondisiFisikTanah extends Model
class KondisiFisikTanah extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\KonturTanahFactory;
class KonturTanah extends Model
class KonturTanah extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\LaluLintasLokasiFactory;
class LaluLintasLokasi extends Model
class LaluLintasLokasi extends Base
{
use HasFactory;
protected $table = 'lalu_lintas_lokasi';

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\LokasiUnitFactory;
class Lantai extends Model
class Lantai extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\LantaiUnitFactory;
class LantaiUnit extends Model
class LantaiUnit extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\LaporanFactory;
class Laporan extends Model
class Laporan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\LingkunganFactory;
class Lingkungan extends Model
class Lingkungan extends Base
{
use HasFactory;

View File

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\MerupakanDaerahFactory;
class MerupakanDaerah extends Model
class MerupakanDaerah extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\ModelAlatBeratFactory;
class ModelAlatBerat extends Model
class ModelAlatBerat extends Base
{
use HasFactory;

62
app/Models/Noc.php Normal file
View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Lpj\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\NocFactory;
class Noc extends Base
{
protected $table = 'noc';
protected $fillable = [
'permohonan_id',
'persetujuan_penawaran_id',
'bukti_bayar',
'nominal_bayar',
'status_bayar',
'tanggal_pembayaran',
'nominal_penyelesaian',
'status_penyelesaiaan',
'tanggal_penyelesaian',
'bukti_penyelesaian',
'bukti_ksl',
'memo_penyelesaian',
'catatan_noc',
'status',
'authorized_status',
'authorized_at',
'authorized_by',
];
protected $casts = [
'nominal_bayar' => 'decimal:2',
'status_bayar' => 'boolean',
'tanggal_pembayaran' => 'date',
'nominal_penyelesaian' => 'decimal:2',
'status_penyelesaiaan' => 'boolean',
'tanggal_penyelesaian' => 'date',
'status' => 'boolean',
'authorized_status' => 'boolean',
'authorized_at' => 'datetime',
];
// Relationship with Permohonan
public function permohonan()
{
return $this->belongsTo(Permohonan::class, 'permohonan_id');
}
// Relationship with PersetujuanPenawaran
public function persetujuanPenawaran()
{
return $this->belongsTo(PersetujuanPenawaran::class, 'persetujuan_penawaran_id');
}
// Relationship with User (for authorized_by)
public function authorizedBy()
{
return $this->belongsTo(User::class, 'authorized_by');
}
}

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\ObjekJaminanFactory;
class ObjekJaminan extends Model
class ObjekJaminan extends Base
{
use HasFactory;

View File

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
// use Modules\Lpj\Database\Factories\PenawaranDetailTenderFactory;
class PenawaranDetailTenderLog extends Model
class PenawaranDetailTenderLog extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\PenilaiFactory;
class Penilai extends Model
class Penilai extends Base
{
use HasFactory;

View File

@@ -10,7 +10,7 @@ use Modules\Lpj\Models\Teams;
use Modules\Lpj\Models\Permohonan;
use Modules\Usermanagement\Models\User;
class Penilaian extends Model
class Penilaian extends Base
{
/**
* The attributes that are mass assignable.
@@ -32,6 +32,17 @@ class Penilaian extends Model
return $this->belongsTo(Teams::class, 'teams_id', 'id');
}
public function teamLeader(){
return $this->belongsTo(Teams::class, 'teams_id', 'id')
->with(['teamsUsers' => function($query) {
$query->whereHas('user', function($q) {
$q->whereHas('roles', function($r) {
$r->where('name', 'senior-officer');
});
})->with('user');
}]);
}
public function userPenilai()
{
return $this->hasMany(PenilaianTeam::class, 'penilaian_id', 'id');

View File

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\PenilaianTeamFactory;
class PenilaianTeam extends Model
class PenilaianTeam extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\PerizinanFactory;
class Perizinan extends Model
class Perizinan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\PerkerasanJalanFactory;
class PerkerasanJalan extends Model
class PerkerasanJalan extends Base
{
use HasFactory;

View File

@@ -259,4 +259,10 @@
return $this->belongsTo(Inspeksi::class, 'permohonan_id');
}
// Add this relationship
public function noc()
{
return $this->hasOne(Noc::class, 'permohonan_id');
}
}

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\PermohonanJaminanFactory;
class PermohonanJaminan extends Model
class PermohonanJaminan extends Base
{
use HasFactory;
protected $table = 'dokumen_jaminan';

View File

@@ -25,7 +25,6 @@
'authorized_status',
'authorized_at',
'authorized_by',
'status',
'catatan',
];
@@ -58,4 +57,10 @@
{
return $this->belongsTo(User::class, 'authorized_by');
}
// Relationship with Noc
public function noc()
{
return $this->hasOne(Noc::class, 'persetujuan_penawaran_id');
}
}

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\PosisiKavlingFactory;
class PosisiKavling extends Model
class PosisiKavling extends Base
{
use HasFactory;

View File

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\PosisiUnitFactory;
class PosisiUnit extends Model
class PosisiUnit extends Base
{
use HasFactory;

View File

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\RegionsFactory;
use Modules\Lpj\Models\Teams;
class Regions extends Model
class Regions extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\RuteJaminanFactory;
class RuteJaminan extends Model
class RuteJaminan extends Base
{
use HasFactory;

View File

@@ -1,18 +0,0 @@
<?php
namespace Modules\Lpj\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class SLA extends Model
{
use HasFactory;
protected $table = 'sla';
/**
* The attributes that are mass assignable.
*/
protected $guarded = ['id'];
}

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\SaranaPelengkapFactory;
class SaranaPelengkap extends Model
class SaranaPelengkap extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\SifatBangunanFactory;
class SifatBangunan extends Model
class SifatBangunan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\SpekBagunanAnalisaFactory;
class SpekBagunanAnalisa extends Model
class SpekBagunanAnalisa extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\SpekBagunanAnalisaDetailFactory;
class SpekBagunanAnalisaDetail extends Model
class SpekBagunanAnalisaDetail extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\SpekBangunanFactory;
class SpekBangunan extends Model
class SpekBangunan extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\SpekKategoritBangunanFactory;
class SpekKategoritBangunan extends Model
class SpekKategoritBangunan extends Base
{
use HasFactory;

View File

@@ -10,7 +10,7 @@ use Modules\Lpj\Models\Regions;
use Modules\Lpj\Models\Penilaian;
class Teams extends Model
class Teams extends Base
{
/**
* The attributes that are mass assignable.

View File

@@ -8,7 +8,7 @@ use Modules\Usermanagement\Models\User;
use Modules\Lpj\Models\Teams;
use Modules\Lpj\Models\Penilaian;
class TeamsUsers extends Model
class TeamsUsers extends Base
{
/**

View File

@@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
// use Modules\Lpj\Database\Factories\TerletakAreaFactory;
class TerletakArea extends Model
class TerletakArea extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\TingkatKeramaianFactory;
class TingkatKeramaian extends Model
class TingkatKeramaian extends Base
{
use HasFactory;

View File

@@ -6,7 +6,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Modules\Lpj\Database\Factories\ViewUnitFactory;
class ViewUnit extends Model
class ViewUnit extends Base
{
use HasFactory;

View File

@@ -0,0 +1,58 @@
<?php
namespace Modules\Lpj\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class PermohonanNotif extends Notification
{
use Queueable;
protected $permohonan;
protected $message;
/**
* Create a new notification instance.
*/
public function __construct($permohonan, $message)
{
$this->permohonan = $permohonan;
$this->message = $message;
}
/**
* Get the notification's delivery channels.
*/
public function via($notifiable)
: array
{
return ['mail', 'database'];
}
/**
* Get the mail representation of the notification.
*/
public function toMail($notifiable)
: MailMessage
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', 'https://laravel.com')
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*/
public function toArray($notifiable)
: array
{
return [
'data' => $this->permohonan,
'message' => $this->message,
];
}
}

View File

@@ -4,6 +4,8 @@ namespace Modules\Lpj\Services;
use Modules\Lpj\Models\Permohonan;
use Modules\Lpj\Models\PermohonanHistory;
use Modules\Lpj\Notifications\PermohonanNotif;
use Modules\Usermanagement\Models\User;
class PermohonanHistoryService
{
@@ -21,6 +23,8 @@ class PermohonanHistoryService
'user_id' => auth()->id(),
]);
$this->createNotification($permohonan, $status, $beforeRequest, $afterRequest);
} catch (\Exception $e) {
// Log the error
\Log::error('Error creating PermohonanHistory: ' . $e->getMessage());
@@ -34,4 +38,25 @@ class PermohonanHistoryService
throw new \Exception('Failed to create PermohonanHistory: ' . $e->getMessage());
}
}
private function createNotification(Permohonan $permohonan, string $status, array $beforeRequest, array $afterRequest)
{
$beforeStatus = '';
if(!empty($beforeRequest)){
$beforeStatus = $beforeRequest['status'] ?? '';
}
if($beforeStatus !== $status){
if($status === 'order'){
$users = User::where(['branch_id' => $permohonan->branch_id])->whereHas('roles',function($q){
$q->where('name', 'pemohon-eo');
})->get();
foreach ($users as $user) {
$message = "telah diorder oleh {$permohonan->creator->name}, Mohon Lakukan konfirmasi";
$user->notify(new PermohonanNotif($permohonan,$message));
}
}
}
}
}

View File

@@ -1,40 +0,0 @@
<?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::create('currencies', function (Blueprint $table) {
$table->id();
$table->string('code', 3)->unique();
$table->string('name');
$table->integer('decimal_places')->default(2);
$table->boolean('status')->default(true)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->char('authorized_status', 1)->nullable();
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down()
: void
{
Schema::dropIfExists('currencies');
}
};

View File

@@ -21,10 +21,10 @@ return new class extends Migration
$table->string('dokumen_persetujuan')->nullable();
$table->boolean('status')->nullable();
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->timestamp('deleted_at')->nullable();
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();

View File

@@ -19,12 +19,12 @@ return new class extends Migration
$table->string('luas');
$table->unsignedBigInteger('jenis_jaminan_id');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -29,14 +29,12 @@ return new class extends Migration
$table->string('sifat_bangunan');
$table->string('sarana_pelengkap');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -25,14 +25,12 @@ return new class extends Migration
$table->string('bentuk_unit');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -19,15 +19,13 @@ return new class extends Migration
$table->unsignedBigInteger('analisa_tanah_bangunan_id');
$table->foreign('analisa_tanah_bangunan_id')->references('id')->on('analisa_tanah_bangunan');
$table->char('authorized_status', 1);
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->unsignedBigInteger('created_by');
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -19,15 +19,13 @@ return new class () extends Migration {
$table->unsignedBigInteger('spek_bangunan_analisa_id');
$table->foreign('spek_bangunan_analisa_id')->references('id')->on('spek_bagunan_analisa');
$table->char('authorized_status', 1);
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->unsignedBigInteger('created_by');
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -37,15 +37,13 @@ return new class () extends Migration {
$table->string('lng');
$table->text('keterangan');
$table->char('authorized_status', 1);
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps(); // created_at and updated_at
$table->unsignedBigInteger('created_by');
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -30,15 +30,13 @@ return new class () extends Migration {
$table->string('merupakan_daerah');
$table->string('fasilitas_dekat_object');
$table->char('authorized_status', 1);
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps(); // created_at and updated_at
$table->unsignedBigInteger('created_by');
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -20,14 +20,12 @@ return new class () extends Migration {
$table->string('luas');
$table->unsignedBigInteger('jenis_jaminan_id');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps(); // created_at and updated_at
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -18,14 +18,12 @@ return new class () extends Migration {
$table->string('pendamping');
$table->unsignedBigInteger('jenis_jaminan_id');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps(); // created_at and updated_at
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -21,14 +21,12 @@ return new class () extends Migration {
$table->unsignedBigInteger('jenis_jaminan_id');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps(); // created_at and updated_at
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -20,14 +20,12 @@ return new class () extends Migration {
$table->string('foto_linkungan');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -21,14 +21,12 @@ return new class () extends Migration {
$table->string('foto_rute');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps(); // created_at and updated_at
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});
}

View File

@@ -18,13 +18,12 @@ return new class extends Migration
$table->string('foto_lantai_unit');
$table->char('authorized_status', 1)->nullable();
$table->timestamps();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->timestamps();
$table->softDeletes();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->timestamp('deleted_at')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
});

View File

@@ -1,27 +0,0 @@
<?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::create('sla', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('sla');
}
};

View File

@@ -1,28 +0,0 @@
<?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::create('label_name_inspeksi', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('label_name_inspeksi');
}
};

View File

@@ -0,0 +1,52 @@
<?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::create('noc', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('permohonan_id');
$table->unsignedBigInteger('persetujuan_penawaran_id');
$table->string('bukti_bayar')->nullable();
$table->decimal('nominal_bayar', 15, 2)->nullable();
$table->boolean('status_bayar')->default(false);
$table->date('tanggal_pembayaran')->nullable();
$table->decimal('nominal_penyelesaian', 15, 2)->nullable();
$table->boolean('status_penyelesaiaan')->default(false);
$table->date('tanggal_penyelesaian')->nullable();
$table->string('bukti_penyelesaian')->nullable();
$table->string('bukti_ksl')->nullable();
$table->text('memo_penyelesaian')->nullable();
$table->boolean('status')->default(true);
$table->string('catatan_noc')->nullable();
$table->char('authorized_status', 1)->nullable();
$table->timestamp('authorized_at')->nullable();
$table->unsignedBigInteger('authorized_by')->nullable();
$table->unsignedBigInteger('created_by')->nullable();
$table->unsignedBigInteger('updated_by')->nullable();
$table->unsignedBigInteger('deleted_by')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('permohonan_id')->references('id')->on('permohonan');
$table->foreign('persetujuan_penawaran_id')->references('id')->on('persetujuan_penawaran');
});
}
/**
* Reverse the migrations.
*/
public function down()
: void
{
Schema::dropIfExists('noc');
}
};

View File

@@ -81,6 +81,40 @@
"EO Appraisal",
"senior-officer"
]
},
{
"title": "Laporan Pernilaan Jaminan",
"path": "laporan-penilaian-jaminan",
"icon": "ki-filled ki-filter-tablet text-lg text-primary",
"classes": "",
"attributes": [],
"permission": "",
"roles": [
"administrator",
"pemohon-ao",
"pemohon-eo",
"admin",
"DD Appraisal",
"EO Appraisal",
"senior-officer"
]
},
{
"title": "Laporan Hasil Pernilaan Jaminan Internal & External",
"path": "laporan-hasil-penilaian-jaminan-internal-external",
"icon": "ki-filled ki-filter-tablet text-lg text-primary",
"classes": "",
"attributes": [],
"permission": "",
"roles": [
"administrator",
"pemohon-ao",
"pemohon-eo",
"admin",
"DD Appraisal",
"EO Appraisal",
"senior-officer"
]
}
],
"otorisator": [

View File

@@ -36,7 +36,7 @@
Informasi dan pembanding
</h3>
<div class="card-tools">
<a href="{{ route('penilai.showDataPembanding', ['id' => $permohonan->id]) }}?dokument={{ request()->documentId }}&jenis_jaminan={{ request()->jaminanId }}"
<a href="{{ route('penilai.showDataPembanding', ['id' => $permohonan->id]) }}?dokument={{ request()->dokument }}&jenis_jaminan={{ request()->jaminanId }}"
class="btn btn-primary" data-bs-toggle="modal">
Edit Data Pembanding
</a>
@@ -553,7 +553,7 @@
const urlParams = new URLSearchParams(window.location.search);
const permohonanId = {{ $permohonan->id }};
const documentId = urlParams.get('documentId');
const documentId = urlParams.get('dokument');
const inspeksiId = urlParams.get('inspeksiId');
const requestUrl =

View File

@@ -237,8 +237,17 @@
const type = data.penilai?.type || '';
let laporanButton = '';
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) {
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

@@ -0,0 +1,499 @@
@extends('layouts.main')
@section('breadcrumbs')
{{ Breadcrumbs::render('laporan-hasil-penilaian-jaminan-internal-external') }}
@endsection
@section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<!-- Filter Card -->
<div class="card border border-agi-100">
<div class="card-header bg-agi-50 py-5">
<h3 class="card-title">Filter Laporan</h3>
</div>
<div class="card-body grid gap-4">
<!-- Search field at the top, full width -->
<div class="flex flex-col w-full">
<label class="text-sm font-medium mb-1">Pencarian</label>
<label class="input input-sm">
<i class="ki-filled ki-magnifier"></i>
<input placeholder="Search Laporan Hasil Penilaian Jaminan Internal & External" id="search" type="text" value="">
</label>
</div>
<!-- Other filter fields in grid layout -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Tanggal Awal</label>
<label class="input">
<input placeholder="Tanggal Awal" id="start_date" type="date">
</label>
</div>
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Tanggal Akhir</label>
<label class="input">
<input placeholder="Tanggal Akhir" id="end_date" type="date">
</label>
</div>
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Cabang</label>
<select class="select tomselect" id="branch_filter">
<option value="">Semua Cabang</option>
@foreach(\Modules\Basicdata\Models\Branch::where('status', 1)->get() as $branch)
<option value="{{ $branch->id }}">{{ $branch->name }}</option>
@endforeach
</select>
</div>
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Penilai</label>
<select class="select tomselect" id="penilai_filter">
<option value="">Semua Penilai</option>
@foreach(\MOdules\Usermanagement\Models\User::role(['penilai','surveyor'])->get() as $penilai)
<option value="{{ $penilai->id }}">{{ $penilai->name }}</option>
@endforeach
</select>
</div>
</div>
<!-- Buttons row at the bottom -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-2">
<button class="btn btn-sm btn-primary" id="filter_tanggal">
<i class="ki-outline ki-filter fs-2 me-1"></i>
Terapkan Filter
</button>
<a class="btn btn-sm btn-light" href="{{ route('laporan-hasil-penilaian-jaminan-internal-external.export') }}" id="export-btn">
<i class="ki-outline ki-file-down fs-2 me-1"></i>
Export to Excel
</a>
</div>
</div>
</div>
<!-- Data Table Card -->
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="laporan-hasil-penilaian-jaminan-internal-external-table" data-api-url="{{ route('laporan-hasil-penilaian-jaminan-internal-external.data') }}">
<div class="card-header bg-agi-50 py-5 flex-wrap">
<h3 class="card-title">
Laporan Hasil Penilaian Jaminan Internal & External
</h3>
</div>
<div class="card-body">
<div class="scrollable-x-auto">
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm" data-datatable-table="true">
<thead>
<tr>
<th class="w-14">
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
</th>
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="branch">
<span class="sort"> <span class="sort-label"> Cabang </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="pemohon">
<span class="sort"> <span class="sort-label"> Pemohon </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="cif">
<span class="sort"> <span class="sort-label"> CIF </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="name">
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="jenis_penilaian">
<span class="sort"> <span class="sort-label"> Jenis Penilaian </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="jenis_fasilitas_kredit">
<span class="sort"> <span class="sort-label"> Jenis Fasilitas Kredit </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
<span class="sort"> <span class="sort-label"> Jenis Agunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
<span class="sort"> <span class="sort-label"> Alamat Agunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="bukti_kepemilikan">
<span class="sort"> <span class="sort-label"> Bukti Kepemilikan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nama_pemilik">
<span class="sort"> <span class="sort-label"> Nama Pemilik </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="luas_tanah">
<span class="sort"> <span class="sort-label"> Luas Tanah </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_tanah">
<span class="sort"> <span class="sort-label"> Nilai Tanah </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="luas_bangunan">
<span class="sort"> <span class="sort-label"> Luas Bangunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_bangunan">
<span class="sort"> <span class="sort-label"> Nilai Bangunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_njop">
<span class="sort"> <span class="sort-label"> Nilai NJOP </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_pasar_wajar">
<span class="sort"> <span class="sort-label"> Nilai Pasar Wajar </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_likuidasi">
<span class="sort"> <span class="sort-label"> Nilai Likuidasi </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_documen_diterima">
<span class="sort"> <span class="sort-label"> Tanggal Dokumen Diterima </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_spk">
<span class="sort"> <span class="sort-label"> Tanggal SPK </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nomor_spk">
<span class="sort"> <span class="sort-label"> Nomor SPK </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_rencana_kunjunagn">
<span class="sort"> <span class="sort-label"> Tanggal Rencana Kunjungan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_kunjungan">
<span class="sort"> <span class="sort-label"> Tanggal Kunjungan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="taggal_delivered">
<span class="sort"> <span class="sort-label"> Tanggal Delivered </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="jangka_waktu_sla">
<span class="sort"> <span class="sort-label"> Jangka Waktu SLA </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_laporan">
<span class="sort"> <span class="sort-label"> Tanggal Laporan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
<span class="sort"> <span class="sort-label"> Tanggal Review </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nama_penilai">
<span class="sort"> <span class="sort-label"> Nama Penilai </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nama_team_leader">
<span class="sort"> <span class="sort-label"> Nama Team Leader </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="saran">
<span class="sort"> <span class="sort-label"> Saran </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="catatan">
<span class="sort"> <span class="sort-label"> Catatan </span>
<span class="sort-icon"> </span> </span>
</th>
</tr>
</thead>
</table>
</div>
<div class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
<div class="flex items-center gap-2">
Show
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per page
</div>
<div class="flex items-center gap-4">
<span data-datatable-info="true"> </span>
<div class="pagination" data-datatable-pagination="true">
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script type="module">
const element = document.querySelector('#laporan-hasil-penilaian-jaminan-internal-external-table');
const searchInput = document.getElementById('search');
const startDateInput = document.getElementById('start_date');
const endDateInput = document.getElementById('end_date');
const branchFilter = document.getElementById('branch_filter');
const penilaiFilter = document.getElementById('penilai_filter');
const filterTanggalButton = document.getElementById('filter_tanggal');
const exportBtn = document.getElementById('export-btn');
const apiUrl = element.getAttribute('data-api-url');
const dataTableOptions = {
apiEndpoint: apiUrl,
pageSize: 5,
columns: {
select: {
render: (item, data, context) => {
const checkbox = document.createElement('input');
checkbox.className = 'checkbox checkbox-sm';
checkbox.type = 'checkbox';
checkbox.value = data.id.toString();
checkbox.setAttribute('data-datatable-row-check', 'true');
return checkbox.outerHTML.trim();
},
},
nomor_registrasi: {
title: 'Nomor Registrasi',
},
tanggal_permohonan: {
title: 'Tanggal Permohonan',
render: (item, data) => {
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
},
},
branch: {
title: 'Cabang',
},
pemohon: {
title: 'Pemohon',
},
cif: {
title: 'CIF',
},
name: {
title: 'Nama Debitur',
},
jenis_penilaian: {
title: 'Jenis Penilaian',
},
tujuan_penilaian: {
title: 'Tujuan Penilaian',
},
jenis_fasilitas_kredit: {
title: 'Jenis Fasilitas Kredit',
},
jenis_agunan: {
title: 'Jenis Agunan',
},
alamat_agunan: {
title: 'Alamat Agunan',
},
bukti_kepemilikan: {
title: 'Bukti Kepemilikan',
render: (item, data) => {
if (data.bukti_kepemilikan) {
// Ganti karakter baris baru dengan tag <br> untuk HTML
return data.bukti_kepemilikan.split('\n').join('<br>');
}
return '-';
},
},
nama_pemilik: {
title: 'Nama Pemilik',
},
luas_tanah: {
title: 'Luas Tanah',
},
nilai_tanah: {
title: 'Nilai Tanah',
render: (item, data) => {
return data.nilai_tanah ?? '-';
},
},
luas_bangunan: {
title: 'Luas Bangunan',
},
nilai_bangunan: {
title: 'Nilai Bangunan',
render: (item, data) => {
return data.nilai_bangunan ?? '-';
},
},
nilai_njop: {
title: 'Nilai NJOP',
render: (item, data) => {
return data.nilai_njop ?? '-';
},
},
nilai_pasar_wajar: {
title: 'Nilai Pasar Wajar',
render: (item, data) => {
return data.nilai_pasar_wajar ?? '-';
},
},
nilai_likuidasi: {
title: 'Nilai Likuidasi',
render: (item, data) => {
return data.nilai_likuidasi ?? '-';
},
},
tanggal_documen_diterima: {
title: 'Tanggal Dokumen Diterima',
render: (item, data) => {
return data.tanggal_documen_diterima ? window.formatTanggalIndonesia(data.tanggal_documen_diterima) : '-';
},
},
tanggal_spk: {
title: 'Tanggal SPK',
render: (item, data) => {
return data.tanggal_spk ? window.formatTanggalIndonesia(data.tanggal_spk) : '-';
},
},
nomor_spk: {
title: 'Nomor SPK',
},
tanggal_rencana_kunjunagn: {
title: 'Tanggal Rencana Kunjungan',
render: (item, data) => {
return data.tanggal_rencana_kunjunagn ? window.formatTanggalIndonesia(data.tanggal_rencana_kunjunagn) : '-';
},
},
tanggal_kunjungan: {
title: 'Tanggal Kunjungan',
render: (item, data) => {
return data.tanggal_kunjungan ? window.formatTanggalIndonesia(data.tanggal_kunjungan) : '-';
},
},
taggal_delivered: {
title: 'Tanggal Delivered',
render: (item, data) => {
return data.taggal_delivered ? window.formatTanggalIndonesia(data.taggal_delivered) : '-';
},
},
jangka_waktu_sla: {
title: 'Jangka Waktu SLA',
},
tanggal_laporan: {
title: 'Tanggal Laporan',
render: (item, data) => {
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
},
},
tanggal_review: {
title: 'Tanggal Review',
render: (item, data) => {
return data.tanggal_review ? window.formatTanggalIndonesia(data.tanggal_review) : '-';
},
},
nama_penilai: {
title: 'Nama Penilai',
},
nama_team_leader: {
title: 'Nama Team Leader',
},
saran: {
title: 'Saran',
},
catatan: {
title: 'Catatan',
}
}
};
let dataTable = new KTDataTable(element, dataTableOptions);
// Function to apply all filters
function applyFilters() {
let filters = {};
const startDate = startDateInput.value;
const endDate = endDateInput.value;
const branch = branchFilter.value;
const penilai = penilaiFilter.value;
if (searchInput.value) {
filters.search = searchInput.value;
}
if (startDate) {
filters.start_date = startDate;
}
if (endDate) {
filters.end_date = endDate;
}
if (branch) {
filters.branch_id = branch;
}
if (penilai) {
filters.penilai_id = penilai;
}
dataTable.search(filters);
}
// Update export URL with filters
function updateExportUrl() {
dataTable.goPage(1);
let url = new URL(exportBtn.href);
if (startDateInput.value) {
url.searchParams.set('start_date', startDateInput.value);
} else {
url.searchParams.delete('start_date');
}
if (endDateInput.value) {
url.searchParams.set('end_date', endDateInput.value);
} else {
url.searchParams.delete('end_date');
}
if (branchFilter.value) {
url.searchParams.set('branch_id', branchFilter.value);
} else {
url.searchParams.delete('branch_id');
}
if (penilaiFilter.value) {
url.searchParams.set('penilai_id', penilaiFilter.value);
} else {
url.searchParams.delete('penilai_id');
}
if (searchInput.value) {
url.searchParams.set('search', searchInput.value);
} else {
url.searchParams.delete('search');
}
exportBtn.href = url.toString();
}
// Add event listeners for all inputs
searchInput.addEventListener('input', () => {
applyFilters();
updateExportUrl();
});
filterTanggalButton.addEventListener('click', () => {
applyFilters();
updateExportUrl();
});
// Initial update of export URL
updateExportUrl();
</script>
@endpush

View File

@@ -0,0 +1,354 @@
@extends('layouts.main')
@section('breadcrumbs')
{{ Breadcrumbs::render('laporan-penilaian-jaminan') }}
@endsection
@section('content')
<div class="w-full grid gap-5 lg:gap-7.5 mx-auto">
<!-- Filter Card -->
<div class="card border border-agi-100">
<div class="card-header bg-agi-50 py-5">
<h3 class="card-title">Filter Laporan</h3>
</div>
<div class="card-body grid gap-4">
<!-- Search field at the top, full width -->
<div class="flex flex-col w-full">
<label class="text-sm font-medium mb-1">Pencarian</label>
<label class="input input-sm">
<i class="ki-filled ki-magnifier"></i>
<input placeholder="Search Laporan Penilaian Jaminan" id="search" type="text" value="">
</label>
</div>
<!-- Other filter fields in grid layout -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Tanggal Awal</label>
<label class="input">
<input placeholder="Tanggal Awal" id="start_date" type="date">
</label>
</div>
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Tanggal Akhir</label>
<label class="input">
<input placeholder="Tanggal Akhir" id="end_date" type="date">
</label>
</div>
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Cabang</label>
<select class="select tomselect" id="branch_filter">
<option value="">Semua Cabang</option>
@foreach(\Modules\Basicdata\Models\Branch::where('status', 1)->get() as $branch)
<option value="{{ $branch->id }}">{{ $branch->name }}</option>
@endforeach
</select>
</div>
<div class="flex flex-col">
<label class="text-base font-medium mb-1">Penilai</label>
<select class="select tomselect" id="penilai_filter">
<option value="">Semua Penilai</option>
@foreach(\MOdules\Usermanagement\Models\User::role(['penilai','surveyor'])->get() as $penilai)
<option value="{{ $penilai->id }}">{{ $penilai->name }}</option>
@endforeach
</select>
</div>
</div>
<!-- Buttons row at the bottom -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-2">
<button class="btn btn-sm btn-primary" id="filter_tanggal">
<i class="ki-outline ki-filter fs-2 me-1"></i>
Terapkan Filter
</button>
<a class="btn btn-sm btn-light" href="{{ route('laporan-hasil-penilaian-jaminan-internal-external.export') }}" id="export-btn">
<i class="ki-outline ki-file-down fs-2 me-1"></i>
Export to Excel
</a>
</div>
</div>
</div>
<!-- Data Table Card -->
<div class="card border border-agi-100 card-grid min-w-full" data-datatable="false" data-datatable-page-size="10" data-datatable-state-save="false" id="laporan-penilaian-jaminan-table" data-api-url="{{ route('laporan-penilaian-jaminan.data') }}">
<div class="card-header bg-agi-50 py-5 flex-wrap">
<h3 class="card-title">
Laporan Penilaian Jaminan
</h3>
</div>
<div class="card-body">
<div class="scrollable-x-auto">
<table class="table table-auto table-border align-middle text-gray-700 font-medium text-sm" data-datatable-table="true">
<thead>
<tr>
<th class="w-14">
<input class="checkbox checkbox-sm" data-datatable-check="true" type="checkbox"/>
</th>
<th class="min-w-[150px]" data-datatable-column="nomor_registrasi">
<span class="sort"> <span class="sort-label"> Nomor Registrasi </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_permohonan">
<span class="sort"> <span class="sort-label"> Tanggal Permohonan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="branch">
<span class="sort"> <span class="sort-label"> Cabang </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="pemohon">
<span class="sort"> <span class="sort-label"> Pemohon </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="name">
<span class="sort"> <span class="sort-label"> Nama Debitur </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tujuan_penilaian">
<span class="sort"> <span class="sort-label"> Tujuan Penilaian </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="jenis_agunan">
<span class="sort"> <span class="sort-label"> Jenis Agunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="alamat_agunan">
<span class="sort"> <span class="sort-label"> Alamat Agunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="luas_tanah">
<span class="sort"> <span class="sort-label"> Luas Tanah </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_tanah">
<span class="sort"> <span class="sort-label"> Nilai Tanah </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="luas_bangunan">
<span class="sort"> <span class="sort-label"> Luas Bangunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_bangunan">
<span class="sort"> <span class="sort-label"> Nilai Bangunan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_laporan">
<span class="sort"> <span class="sort-label"> Tanggal Laporan </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="tanggal_review">
<span class="sort"> <span class="sort-label"> Tanggal Review </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_pasar_wajar">
<span class="sort"> <span class="sort-label"> Nilai Pasar Wajar </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nilai_likuidasi">
<span class="sort"> <span class="sort-label"> Nilai Likuidasi </span>
<span class="sort-icon"> </span> </span>
</th>
<th class="min-w-[150px]" data-datatable-column="nama_penilai">
<span class="sort"> <span class="sort-label"> Nama Penilai </span>
<span class="sort-icon"> </span> </span>
</th>
</tr>
</thead>
</table>
</div>
<div class="card-footer justify-center md:justify-between flex-col md:flex-row gap-3 text-gray-600 text-2sm font-medium">
<div class="flex items-center gap-2">
Show
<select class="select select-sm w-16" data-datatable-size="true" name="perpage"> </select> per
page
</div>
<div class="flex items-center gap-4">
<span data-datatable-info="true"> </span>
<div class="pagination" data-datatable-pagination="true">
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('scripts')
<script type="module">
const element = document.querySelector('#laporan-penilaian-jaminan-table');
const searchInput = document.getElementById('search');
const startDateInput = document.getElementById('start_date');
const endDateInput = document.getElementById('end_date');
const branchFilter = document.getElementById('branch_filter');
const filterTanggalButton = document.getElementById('filter_tanggal');
const penilaiFilter = document.getElementById('penilai_filter');
const exportBtn = document.getElementById('export-btn');
const apiUrl = element.getAttribute('data-api-url');
const dataTableOptions = {
apiEndpoint: apiUrl,
pageSize: 5,
columns: {
select: {
render: (item, data, context) => {
const checkbox = document.createElement('input');
checkbox.className = 'checkbox checkbox-sm';
checkbox.type = 'checkbox';
checkbox.value = data.id.toString();
checkbox.setAttribute('data-datatable-row-check', 'true');
return checkbox.outerHTML.trim();
},
},
nomor_registrasi: {
title: 'Nomor Registrasi',
},
tanggal_permohonan: {
title: 'Tanggal Permohonan',
render: (item, data) => {
return data.tanggal_permohonan ? window.formatTanggalIndonesia(data.tanggal_permohonan) : '-';
},
},
branch: {
title: 'Cabang',
},
name: {
title: 'Nama Debitur',
},
pemohon: {
title: 'Pemohon',
},
tujuan_penilaian: {
title: 'Tujuan Penilaian',
},
jenis_agunan: {
title: 'Jenis Agunan',
},
alamat_agunan: {
title: 'Alamat Agunan',
},
luas_tanah: {
title: 'Luas Tanah',
},
nilai_tanah: {
title: 'Nilai Tanah',
},
luas_bangunan: {
title: 'Luas Bangunan',
},
nilai_bangunan: {
title: 'Nilai Bangunan',
},
tanggal_laporan: {
title: 'Tanggal Laporan',
render: (item, data) => {
return data.tanggal_laporan ? window.formatTanggalIndonesia(data.tanggal_laporan) : '-';
},
},
tanggal_review: {
title: 'Tanggal Review',
render: (item, data) => {
return data.tanggal_review ? window.formatTanggalIndonesia(data.tanggal_review) : '-';
},
},
nilai_pasar_wajar: {
title: 'Nilai Pasar Wajar',
render: (item, data) => {
return data.nilai_pasar_wajar;
},
},
nilai_likuidasi: {
title: 'Nilai Likuidasi',
},
nama_penilai: {
title: 'Nama Penilai',
}
}
};
let dataTable = new KTDataTable(element, dataTableOptions);
// Function to apply all filters
function applyFilters() {
let filters = {};
const startDate = startDateInput.value;
const endDate = endDateInput.value;
const branch = branchFilter.value;
const penilai = penilaiFilter.value;
if (searchInput.value) {
filters.search = searchInput.value;
}
if (startDate) {
filters.start_date = startDate;
}
if (endDate) {
filters.end_date = endDate;
}
if (branch) {
filters.branch_id = branch;
}
if (penilai) {
filters.penilai_id = penilai;
}
dataTable.search(filters);
}
// Update export URL with filters
function updateExportUrl() {
let url = new URL(exportBtn.href);
if (startDateInput.value) {
url.searchParams.set('start_date', startDateInput.value);
} else {
url.searchParams.delete('start_date');
}
if (endDateInput.value) {
url.searchParams.set('end_date', endDateInput.value);
} else {
url.searchParams.delete('end_date');
}
if (branchFilter.value) {
url.searchParams.set('branch_id', branchFilter.value);
} else {
url.searchParams.delete('branch_id');
}
if (searchInput.value) {
url.searchParams.set('search', searchInput.value);
} else {
url.searchParams.delete('search');
}
if (penilaiFilter.value) {
url.searchParams.set('penilai_id', penilaiFilter.value);
} else {
url.searchParams.delete('penilai_id');
}
exportBtn.href = url.toString();
}
// Add event listeners for all inputs
searchInput.addEventListener('input', () => {
applyFilters();
updateExportUrl();
});
filterTanggalButton.addEventListener('click', () => {
applyFilters();
updateExportUrl();
});
// Initial update of export URL
updateExportUrl();
</script>
@endpush

View File

@@ -1,7 +1,7 @@
@extends('layouts.main')
@section('breadcrumbs')
{{-- {{ Breadcrumbs::render('laporan-permohonan') }}--}}
{{ Breadcrumbs::render('laporan-permohonan') }}
@endsection
@section('content')

View File

@@ -4,21 +4,35 @@
{{ Breadcrumbs::render(request()->route()->getName()) }}
@endsection
@php
$hasMemo = false;
try {
$memoPath = $persetujuanPenawaran->noc->memo_penyelesaian ?? null;
$hasMemo = isset($memoPath) && !empty($memoPath) && Storage::disk('public')->exists($memoPath);
} catch (Exception $e) {
// Jika terjadi error, $hasMemo tetap false
}
@endphp
@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">
NOC
{{ $hasMemo ? 'Proses Penyelesaian NOC' : '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.store') }}" method="POST" class="grid gap-5" enctype="multipart/form-data">
<form action="{{ !$hasMemo ? route('noc.store') : route('noc.update',$persetujuanPenawaran) }}" method="POST" class="grid gap-5" enctype="multipart/form-data">
@csrf
@if($hasMemo)
@method('PUT')
@endif
<input type="hidden" name="penawaran_id" value="{{ $persetujuanPenawaran->penawaran_id ?? old('penawaran_id') }}">
<input type="hidden" name="persetujuan_penawaran_id" value="{{ $persetujuanPenawaran->id ?? old('persetujuan_penawaran_id') }}">
<input type="hidden" name="permohonan_id" value="{{ $persetujuanPenawaran->penawaran->permohonan->id ?? $persetujuanPenawaran->permohonan->id }}">
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
@@ -26,10 +40,10 @@
Status Bayar
</label>
<div class="flex flex-wrap items-baseline w-full">
<select class="input tomselect w-full @error('status_bayar') border-danger bg-danger-light @enderror" name="status_bayar" id="status_bayar">
<select class="input tomselect w-full @error('status_pembayar') border-danger bg-danger-light @enderror" name="status_pembayar" id="status_pembayar" {{ $hasMemo ? 'disabled' : '' }}>
<option value="">Pilih Status Bayar</option>
<option value="sudah_bayar" {{ (old('status_bayar') == 'sudah_bayar') || (isset($persetujuanPenawaran->penawaran->permohonan) && $persetujuanPenawaran->penawaran->permohonan->status_bayar == 'sudah_bayar') ? 'selected' : '' }}>Sudah Bayar</option>
<option value="belum_bayar" {{ (old('status_bayar') == 'belum_bayar') || (isset($persetujuanPenawaran->penawaran->permohonan) && $persetujuanPenawaran->penawaran->permohonan->status_bayar == 'belum_bayar') ? 'selected' : '' }}>Belum Bayar</option>
<option value="sudah_bayar" {{ (old('status_pembayar') == 'sudah_bayar') || ($persetujuanPenawaran?->penawaran?->permohonan?->status_bayar == 'sudah_bayar') ? 'selected' : '' }}>Sudah Bayar</option>
<option value="belum_bayar" {{ (old('status_pembayar') == 'belum_bayar') || ($persetujuanPenawaran?->penawaran?->permohonan?->status_bayar == 'belum_bayar') ? 'selected' : '' }}>Belum Bayar</option>
</select>
@error('status_bayar')
<em class="alert text-danger text-sm">{{ $message }}</em>
@@ -39,13 +53,16 @@
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Bukti KSL
Bukti Pembayaran
</label>
<div class="flex flex-wrap items-baseline w-full">
<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,.doc,.docx">
@error('bukti_ksl')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
@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>
@@ -54,19 +71,127 @@
Nominal Bayar
</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', $persetujuanPenawaran->nominal_bayar ?? '') }}" placeholder="Masukkan nominal bayar">
<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>
@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', $persetujuanPenawaran->noc->nominal_bayar ?? '') }}" placeholder="Masukkan nominal bayar" {{ $hasMemo ? '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($persetujuanPenawaran->noc->tanggal_pembayaran) ? date('Y-m-d', strtotime($persetujuanPenawaran->noc->tanggal_pembayaran)) : '') }}" {{ $hasMemo ? '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(!$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">
@error('bukti_ksl')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
@endif
@if(isset($persetujuanPenawaran->noc->bukti_ksl) && !empty($persetujuanPenawaran->noc->bukti_ksl))
<div class="mt-2 flex items-center">
<a href="{{ Storage::url($persetujuanPenawaran->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>
@if($hasMemo)
<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">
<div class="flex items-center">
<a href="{{ Storage::url($persetujuanPenawaran->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>
<input type="hidden" name="memo_penyelesaian_existing" value="{{ $persetujuanPenawaran->noc->memo_penyelesaian }}">
</div>
</div>
</div>
<div class="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label class="form-label max-w-56">
Bukti Penyelesaian
</label>
<div class="flex flex-wrap items-baseline w-full">
<input type="file" name="bukti_penyelesaian" id="bukti_penyelesaian" class="file-input w-full @error('bukti_penyelesaian') border-danger bg-danger-light @enderror" accept=".pdf,.jpg,.jpeg,.png">
@error('bukti_penyelesaian')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
@if(isset($persetujuanPenawaran->noc->bukti_penyelesaian) && !empty($persetujuanPenawaran->noc->bukti_penyelesaian))
<div class="mt-2 flex items-center">
<a href="{{ Storage::url($persetujuanPenawaran->noc->bukti_penyelesaian) }}" target="_blank" class="badge badge-sm badge-outline badge-warning">
<i class="ki-filled ki-eye mr-2"></i> Lihat File
</a>
<input type="hidden" name="bukti_penyelesaian_existing" value="{{ $persetujuanPenawaran->noc->bukti_penyelesaian }}">
</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 Penyelesaian
</label>
<div class="flex flex-wrap items-baseline w-full">
<input type="number" name="nominal_penyelesaian" id="nominal_penyelesaian" class="input w-full @error('nominal_penyelesaian') border-danger bg-danger-light @enderror" value="{{ old('nominal_penyelesaian', $persetujuanPenawaran->noc->nominal_penyelesaian ?? '') }}" placeholder="Masukkan nominal penyelesaian">
@error('nominal_penyelesaian')
<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 Penyelesaian
</label>
<div class="flex flex-wrap items-baseline w-full">
<input type="date" name="tanggal_penyelesaian" id="tanggal_penyelesaian" class="input w-full @error('tanggal_penyelesaian') border-danger bg-danger-light @enderror" value="{{ old('tanggal_penyelesaian', isset($persetujuanPenawaran->noc->tanggal_penyelesaian) ? date('Y-m-d', strtotime($persetujuanPenawaran->noc->tanggal_penyelesaian)) : '') }}">
@error('tanggal_penyelesaian')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
</div>
</div>
@endif
<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" placeholder="Masukkan catatan">{{ old('catatan', $persetujuanPenawaran->catatan ?? '') }}</textarea>
<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', $persetujuanPenawaran->catatan ?? '') }}</textarea>
@error('catatan')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror
@@ -78,7 +203,7 @@
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', $persetujuanPenawaran->catatan_noc ?? '') }}</textarea>
<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', $persetujuanPenawaran->noc->catatan_noc ?? '') }}</textarea>
@error('catatan_noc')
<em class="alert text-danger text-sm">{{ $message }}</em>
@enderror

Some files were not shown because too many files have changed in this diff Show More