translatedFormat('d F Y'); } return $waktu->translatedFormat('d F Y') . ' pukul ' . $waktu->format('H.i') . ' WIB'; } catch (Throwable $e) { return $date; } } function formatRupiah($number, $decimals = 0) { $number = (float) $number; return 'Rp ' . number_format($number, $decimals, ',', '.'); } 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) { $penawaran = PenawaranTender::find($id); $start_date = strtotime($penawaran->start_date); $end_date = strtotime($penawaran->end_date); $todays_date = strtotime(now()); //$todays_date = strtotime("+1 day", strtotime(now())); $allow = true; if ($todays_date >= $start_date && $todays_date <= $end_date) { //Penawaran dibuka $allow = true; } else { if ($todays_date < $start_date) { //Penawaran Belum dibuka $allow = true; } else { //Penawaran sudah ditutup $allow = false; } } return $allow; } function checkKelengkapanDetailKJPP($id) { $allow = true; // DB::enableQueryLog(); // detail_penawaran apakah isian biaya_penawaran, attachment, dokumen_persetujuan sudah lengkap? $query = PenawaranDetailTender::select('id')->where('penawaran_id', '=', $id)->where('status', '=', 1)->where( function ($query) { // no_proposal $query->orWhere('no_proposal', '', ""); $query->orWhereNull('no_proposal'); // tgl_proposal $query->orWhere('tgl_proposal', '', ""); $query->orWhereNull('tgl_proposal'); $query->orWhere('biaya_penawaran', '', ""); $query->orWhereNull('biaya_penawaran'); $query->orWhere('attachment', '', ""); $query->orWhereNull('attachment'); $query->orWhere('dokumen_persetujuan', '', ""); $query->orWhereNull('dokumen_persetujuan'); }, )->get(); // $sql = DB::getQueryLog(); if (sizeof($query) > 0) { $allow = false; } return $allow; } // convert function convertSlug($slug) { $words = explode('-', $slug); foreach ($words as $index => $word) { $words[$index] = strtoupper($word); } return implode(' ', $words); } // 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 // $penawaran = PenawaranTender::latest()->first(); $penawaran = PenawaranTender::where('code', '=', $maxCode)->first(); $code_penawaran_last = ''; // nomor di set 0001 $noUrutAkhirString = sprintf("%04s", 1); 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) && (ctype_digit($isNum))) { $code_penawaran_last = substr($maxCode, -4); $year_penawaran_last = Carbon::parse($penawaran->created_at)->year; $year_now = Carbon::now()->year; if ($year_now == $year_penawaran_last) { $noUrutAkhirString = sprintf("%04s", abs($code_penawaran_last + 1)); } // jika ternyata tahun tdk sama (kurang dari tahun sekarang), maka nomor di set 0001 } } return 'NP' . Carbon::now()->format('y') . $noUrutAkhirString; } // generate last penawaran.no_spk function onLastnumberCodePenawaranSPK($jenis_laporan_code) : string { // 20241124_001 ==> spk_no_core // XXX / PJ / JKT / MONTH-ROM / FR|SR / 2024 // 001 / PJ / JKT / XI / FR / 2024 $maxCode = PenawaranTender::max('spk_no_core'); $penawaran = PenawaranTender::where('spk_no_core', '=', $maxCode)->first(); $no_spk_penawaran_last = ''; $year_penawaran_last = ''; $year_now = Carbon::now()->year; // nomor di set 001 $noUrutAkhirString = sprintf("%03s", 1); if ($penawaran) { $no_spk_penawaran_last = substr($maxCode, -3); $year_penawaran_last = substr($maxCode, 0, 4); if ($year_now == $year_penawaran_last) { $noUrutAkhirString = sprintf("%03s", abs($no_spk_penawaran_last + 1)); } // jika ternyata tahun tdk sama (kurang dari tahun sekarang), maka nomor di set 001 } $month = onRomawi(Carbon::now()->month); $lastSPK = $noUrutAkhirString . ' / PJ / JKT / ' . $month . ' / ' . $jenis_laporan_code . ' / ' . $year_now; return $lastSPK; } function onRomawi(int $bln) : string { return convertToRoman($bln); } function penyebut($nilai) { $nilai = abs($nilai); $huruf = [ "", "satu", "dua", "tiga", "empat", "lima", "enam", "tujuh", "delapan", "sembilan", "sepuluh", "sebelas" ]; $temp = ""; if ($nilai < 12) { $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); } else if ($nilai < 1000) { $temp = penyebut($nilai / 100) . " ratus" . penyebut($nilai % 100); } else if ($nilai < 2000) { $temp = " seribu" . penyebut($nilai - 1000); } else if ($nilai < 1000000) { $temp = penyebut($nilai / 1000) . " ribu" . penyebut($nilai % 1000); } else if ($nilai < 1000000000) { $temp = penyebut($nilai / 1000000) . " juta" . penyebut($nilai % 1000000); } else if ($nilai < 1000000000000) { $temp = penyebut($nilai / 1000000000) . " milyar" . penyebut(fmod($nilai, 1000000000)); } else if ($nilai < 1000000000000000) { $temp = penyebut($nilai / 1000000000000) . " trilyun" . penyebut(fmod($nilai, 1000000000000)); } return $temp; } function terbilang($nilai) { if ($nilai < 0) { $hasil = "minus " . trim(penyebut($nilai)); } else { $hasil = trim(penyebut($nilai)); } return $hasil; } // andy add function hitungHariKerja($tanggalMulai, $tanggalSelesai) { $tanggalMulai = Carbon::parse($tanggalMulai)->startOfDay(); $tanggalSelesai = Carbon::parse($tanggalSelesai)->endOfDay(); $hariKerja = 0; $tanggalSekarang = $tanggalMulai->copy(); while ($tanggalSekarang <= $tanggalSelesai) { // Cek apakah hari ini bukan Sabtu atau Minggu dan bukan hari libur if (!$tanggalSekarang->isWeekend() && !in_array($tanggalSekarang->format('Y-m-d'), holidays())) { $hariKerja++; } $tanggalSekarang->addDay(); } return $hariKerja; } function countPermohonanForUser($userId) { $validStatuses = [ 'assign', 'survey-completed', 'proses-laporan', 'paparan', 'proses-paparan', 'revisi-laporan', 'revisi-paparan', 'survey', 'proses-survey', 'request-reschedule', 'reschedule', 'rejected-reschedule', 'approved-reschedule', 'revisi-survey', 'revisi-pembayaran' ]; $result = Penilaian::whereHas('userPenilai', function ($query) use ($userId) { $query->where('user_id', $userId); }) ->whereHas('permohonan', function ($query) use ($validStatuses) { $query->whereIn('status', $validStatuses); }) ->get() ->groupBy(function ($item) { // Pastikan mengakses properti dari model yang valid return $item->userPenilai->first()->user_id . '-' . $item->permohonan->id; }) ->map(function ($group) { return [ 'statuses' => $group->pluck('permohonan.status')->unique()->values()->all(), ]; }); return $result->count(); } function getMaxFileSize($jenis) { $jenisDokumen = JenisDokumen::where('name', $jenis)->first(); if (!$jenisDokumen) { return 2048; } //konversi ke KB (1 MB = 1024 KB) $maxSizeInKB = (int) $jenisDokumen->max_size * 1024; return $maxSizeInKB; } function getUser($userId) { return User::find($userId); } function generateLpjUniqueCode($randomLength = 6) { $year = date('y'); $month = str_pad(date('m'), 2, '0', STR_PAD_LEFT); $day = str_pad(date('d'), 2, '0', STR_PAD_LEFT); // Generate random numbers $randomNumber = str_pad(mt_rand(0, pow(10, $randomLength) - 1), $randomLength, '0', STR_PAD_LEFT); // Concatenate components to create the custom code return $year . $month . $day . $randomNumber; } 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') { $laporan = Laporan::where([ 'permohonan_id' => $permohonanId, 'dokumen_jaminan_id' => $documentId, ])->first(); if (!$laporan) { return $type == 'nomor_laporan' ? '-' : null; } return $type == 'nomor_laporan' ? $laporan->nomor_laporan : $laporan->created_at; } function getCustomField($param) { if (is_numeric($param)) { $field = CustomField::find($param); } else { $field = CustomField::where(['name' => $param])->first(); } if ($field) { return $field; } else { return null; } } function getWilayahName($code, $type) { try { $wilayah = null; if (!$code) { return null; } switch ($type) { case 'province': $wilayah = Province::where('code', $code)->first(); return $wilayah ? $wilayah->name : null; case 'city': $wilayah = City::where('code', $code)->first(); return $wilayah ? $wilayah->name : null; case 'district': $wilayah = District::where('code', $code)->first(); return $wilayah ? $wilayah->name : null; case 'village': $wilayah = Village::where('code', $code)->first(); return $wilayah ? $wilayah->name : null; default: return null; } } catch (Exception $e) { return null; } } function formatLabel($key) { static $labelCache = []; if (isset($labelCache[$key])) { return $labelCache[$key]; } $customLabel = CustomField::where('name', $key)->first(); $labelCache[$key] = $customLabel->label ?? ucwords(str_replace('_', ' ', $key)); return $labelCache[$key]; } function calculateSLA($permohonan, $type) { if (!$type) { return null; } $nilai_plafond = in_array($permohonan->nilai_plafond_id, [2, 3]); $nilai_plafond_2 = in_array($permohonan->nilai_plafond_id, [1]); $slaMap = [ 'resume' => $nilai_plafond ? 2 : null, 'paparan' => $nilai_plafond ? 2 : null, 'standard' => $nilai_plafond ? 3 : null, 'sederhana' => $nilai_plafond ? 2 : null, 'paparan' => $nilai_plafond_2 ? 3 : null, 'rap' => 3, 'memo' => $nilai_plafond ? 1 : null ]; if ($type === 'paparan' && isset($permohonan->tujuanPenilaian->name) && $permohonan->tujuanPenilaian->name === 'rap') { return 2; } 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) { $total = 0; if ($detailsArray) { foreach ($detailsArray as $item) { if (isset($item->jenis_legalitas_jaminan_id) && $item->jenis_legalitas_jaminan_id === $jenisLegalitas) { $details = json_decode($item->details, true); if (is_array($details)) { foreach ($details as $detail) { if (isset($detail[$key])) { $total += (int) $detail[$key]; } } } } } // Jika total masih 0, gunakan jenis jaminan ppjb if ($total === 0) { foreach ($detailsArray as $item) { if (isset($item->jenis_legalitas_jaminan_id) && $item->jenis_legalitas_jaminan_id === $defaultJenisLegalitas) { $details = json_decode($item->details, true); if (is_array($details)) { foreach ($details as $detail) { if (isset($detail[$key]) && $detail[$key] !== null) { $total += (int) $detail[$key]; } } } } } } // jika total masih kosong juga maka gunakan ppb if ($total === 0 && $fallbackJenisLegalitas !== null) { foreach ($detailsArray as $item) { if (isset($item->jenis_legalitas_jaminan_id) && $item->jenis_legalitas_jaminan_id === $fallbackJenisLegalitas) { $details = json_decode($item->details, true); if (is_array($details)) { foreach ($details as $detail) { if (isset($detail[$key]) && $detail[$key] !== null) { $total += (int) $detail[$key]; } } } } } } } return $total > 0 ? $total : 0; } function ubahNomorHp($nomorHp) { $nomorHp = preg_replace('/\D/', '', $nomorHp); if (strpos($nomorHp, '62') === 0) { $nomorBaru = substr($nomorHp, 0, 5) . "xxxxx"; return '+' . $nomorBaru; } else if (strpos($nomorHp, '0') === 0) { $nomorBaru = substr($nomorHp, 0, 5) . "xxxxxx"; return $nomorBaru; } else { return "Nomor HP tidak valid"; } } function parsePembandingMigration($keterangan) { $keterangan = preg_replace('/[-]{5,}/', '',$keterangan); // Hapus ------ $keterangan = preg_replace('/[.]{5,}/', '',$keterangan); // Hapus ..... $keterangan = preg_replace('/\s+/', ' ',$keterangan); $keterangan = preg_replace('/\s*\n\s*/', "\n",$keterangan); // Pecah teks per baris untuk diproses $lines = explode("\n",$keterangan); $cleaned = []; foreach ($lines as $line) { $line = trim($line); if (!empty($line)) { // Format angka dalam format Rp. 123.456.789 $line = preg_replace_callback('/Rp\.\s*([\d.,]+)/', function($matches) { $angka = str_replace(['.', ','], '', $matches[1]); return 'Rp. ' . number_format((int)$angka, 0, ',', '.'); }, $line); // Jika ada tanda pagar (#), pisahkan menjadi baris baru $line = str_replace('#', "\n#", $line); $cleaned[] = $line; } } return implode("\n", $cleaned); } /** * get full path to internal storage file or external storage file * * @param string $path * @return string */ function getFilePath($path) { // define base path external storage (use .env) example: 'F:\path\to\storage' in windows $externalBase = env('EXTERNAL_STORAGE_BASE_PATH', 'F:LPJ/lpj/LPJ Gambar/001/'); $segments = explode('/', $path); if(strtoupper($segments[0]) === 'SURVEYOR'){ $year = $segments[1]; $month = ucfirst(strtolower($segments[2])); $date = $segments[3]; $code = $segments[4]; $file = $segments[5] ?? ''; $extenalFullpath = $externalBase . $year . '/' . $month . '/' . $date . '/' . $code . '/' . $file; if(File::exists($extenalFullpath)){ return $extenalFullpath; } } // if not found in external storage, try to find in internal storage if (Storage::exists($path)) { return Storage::url('app/' . $path); } return $path; }