perling/app/Http/Controllers/PengumumanController.php

302 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\InformasiKegiatan;
use App\Models\Kabupaten;
use App\Models\Kecamatan;
use App\Models\Kelurahan;
use Carbon\Carbon;
class PengumumanController extends Controller
{
public function index()
{
$pengumuman = InformasiKegiatan::with('saranTanggapan')
->active()
->orderBy('TanggalMulaiPeriode', 'desc')
->get()
->map(function ($item, $index) {
return [
'no' => $index + 1,
'no_registrasi' => $item->NoRegistrasi,
'nama_perusahaan' => $item->Pemrakarsa,
'nama_kegiatan' => $item->NamaKegiatan,
'jenis_dokumen' => $item->JenisDokumen,
'periode' => $this->formatBusinessDayPeriod($item->TanggalMulaiPeriode, 10),
'status' => 'Menunggu Tanggapan',
'detail_url' => route('pengumuman.detail', $item->KegiatanID)
];
});
return view('pengumuman.index', compact('pengumuman'));
}
/**
* Generate business day period (10 working days excluding weekends and holidays)
*/
private function formatBusinessDayPeriod($startDate, $workingDays = 10)
{
$start = Carbon::parse($startDate);
$current = $start->copy();
$daysAdded = 0;
// Indonesian public holidays 2025 (tanggal merah)
$holidays = [
'2025-01-01', // Tahun Baru
'2025-01-29', // Tahun Baru Imlek
'2025-03-29', // Hari Raya Nyepi
'2025-03-30', // Wafat Isa Almasih
'2025-04-09', // Isra Miraj
'2025-05-01', // Hari Buruh
'2025-05-12', // Hari Raya Waisak
'2025-05-29', // Kenaikan Isa Almasih
'2025-06-01', // Hari Lahir Pancasila
'2025-06-06', // Idul Fitri 1446 H
'2025-06-07', // Idul Fitri 1446 H
'2025-08-17', // Hari Kemerdekaan RI
'2025-08-31', // Idul Adha 1446 H
'2025-09-21', // Tahun Baru Islam 1447 H
'2025-11-30', // Maulid Nabi Muhammad SAW
'2025-12-25', // Hari Raya Natal
];
while ($daysAdded < $workingDays) {
$current->addDay();
// Skip weekends (Saturday = 6, Sunday = 0)
if ($current->dayOfWeek == Carbon::SATURDAY || $current->dayOfWeek == Carbon::SUNDAY) {
continue;
}
// Skip public holidays
if (in_array($current->format('Y-m-d'), $holidays)) {
continue;
}
$daysAdded++;
}
return $start->format('d M') . ' - ' . $current->format('d M Y');
}
public function detail($id)
{
$kegiatan = InformasiKegiatan::with('saranTanggapanApproved')->findOrFail($id);
return view('pengumuman.detail', compact('kegiatan'));
}
public function create()
{
$kabupaten = Kabupaten::orderBy('NamaKabupaten', 'asc')->get();
return view('pengumuman.create', compact('kabupaten'));
}
/**
* Generate unique 12-digit registration number with enhanced security
* Format: Mixed alphanumeric with timestamp hash to prevent easy guessing
* Example: ENV4B7X9K2M
*/
private function generateRegistrationNumber()
{
do {
// Create a unique seed from current time, microtime, and random data
$seed = now()->timestamp . microtime(true) . random_int(100000, 999999);
// Generate hash and extract alphanumeric characters
$hash = hash('sha256', $seed);
// Create character pool (excluding similar looking characters)
$chars = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
// Start with prefix
$prefix = 'REG';
// Generate 9 additional characters from hash
$remaining = '';
$hashPos = 0;
while (strlen($remaining) < 9 && $hashPos < strlen($hash)) {
$hexChar = strtoupper($hash[$hashPos]);
// Convert hex to index in our character pool
$index = hexdec($hexChar) % strlen($chars);
$remaining .= $chars[$index];
$hashPos++;
}
// If we need more characters, use additional random generation
while (strlen($remaining) < 9) {
$remaining .= $chars[random_int(0, strlen($chars) - 1)];
}
$registrationNumber = $prefix . $remaining;
// Check if this number already exists
$exists = InformasiKegiatan::where('NoRegistrasi', $registrationNumber)->exists();
} while ($exists); // Keep generating until we get a unique number
return $registrationNumber;
}
public function store(Request $request)
{
$validated = $request->validate([
'jenis_dokumen' => 'required|string|max:50',
'nama_kegiatan' => 'required|string|max:255',
'pemrakarsa' => 'required|string|max:100',
'bidang_usaha' => 'required|string|max:100',
'deskripsi_kegiatan' => 'required|string',
'dampak_potensial' => 'required|string',
'kabupaten' => 'required|string|max:100',
'kecamatan' => 'required|string|max:100',
'kelurahan' => 'required|string|max:100',
'lokasi_kegiatan' => 'nullable|string|max:100',
'deskripsi_lokasi' => 'required|string',
'latitude' => 'nullable|numeric|between:-90,90',
'longitude' => 'nullable|numeric|between:-180,180',
'tanggal_mulai' => 'required|date|after_or_equal:today',
'skala_besaran' => 'nullable|string|max:50',
'kewenangan' => 'required|string|max:50',
'status' => 'required|in:aktif,nonaktif'
], [
'jenis_dokumen.required' => 'Jenis dokumen wajib dipilih',
'nama_kegiatan.required' => 'Nama kegiatan wajib diisi',
'pemrakarsa.required' => 'Pemrakarsa wajib diisi',
'bidang_usaha.required' => 'Bidang usaha wajib diisi',
'deskripsi_kegiatan.required' => 'Deskripsi kegiatan wajib diisi',
'dampak_potensial.required' => 'Dampak potensial wajib diisi',
'kabupaten.required' => 'Kabupaten wajib dipilih',
'kecamatan.required' => 'Kecamatan wajib dipilih',
'kelurahan.required' => 'Kelurahan wajib dipilih',
'deskripsi_lokasi.required' => 'Deskripsi lokasi wajib diisi',
'tanggal_mulai.required' => 'Tanggal mulai periode wajib diisi',
'tanggal_mulai.after_or_equal' => 'Tanggal mulai tidak boleh kurang dari hari ini',
'kewenangan.required' => 'Kewenangan wajib dipilih',
'status.required' => 'Status wajib dipilih',
'latitude.between' => 'Latitude harus antara -90 sampai 90',
'longitude.between' => 'Longitude harus antara -180 sampai 180'
]);
try {
// Generate unique registration number
$noRegistrasi = $this->generateRegistrationNumber();
// Calculate end date (10 business days from start date)
$startDate = Carbon::parse($validated['tanggal_mulai']);
$endDate = $this->calculateBusinessDayEnd($startDate, 10);
// Get location names from database
$kabupaten = Kabupaten::find($validated['kabupaten']);
$kecamatan = Kecamatan::find($validated['kecamatan']);
$kelurahan = Kelurahan::find($validated['kelurahan']);
$kombinasiLokasi = $kabupaten->NamaKabupaten . ', ' . $kecamatan->NamaKecamatan . ', ' . $kelurahan->NamaKelurahan;
InformasiKegiatan::create([
'NoRegistrasi' => $noRegistrasi,
'JenisDokumen' => $validated['jenis_dokumen'],
'NamaKegiatan' => $validated['nama_kegiatan'],
'Pemrakarsa' => $validated['pemrakarsa'],
'BidangUsaha' => $validated['bidang_usaha'],
'DeskripsiKegiatan' => $validated['deskripsi_kegiatan'],
'DampakPotensial' => $validated['dampak_potensial'],
'ProvinsiKota' => $kombinasiLokasi,
'LokasiKegiatan' => $validated['lokasi_kegiatan'],
'DeskripsiLokasi' => $validated['deskripsi_lokasi'],
'Latitude' => $validated['latitude'],
'Longitude' => $validated['longitude'],
'TanggalMulaiPeriode' => $startDate,
'TanggalSelesaiPeriode' => $endDate,
'SkalaBesaran' => $validated['skala_besaran'],
'Kewenangan' => $validated['kewenangan'],
'Status' => $validated['status']
]);
return redirect()->route('pengumuman.index')
->with('success', 'Pengumuman kegiatan berhasil ditambahkan dengan nomor registrasi: ' . $noRegistrasi);
} catch (\Exception $e) {
return back()
->withInput()
->with('error', 'Terjadi kesalahan saat menyimpan data: ' . $e->getMessage());
}
}
public function calculatePeriod(Request $request)
{
$startDate = Carbon::parse($request->start_date);
$endDate = $this->calculateBusinessDayEnd($startDate, 10);
$periode = $startDate->format('d M') . ' - ' . $endDate->format('d M Y');
return response()->json([
'success' => true,
'periode' => $periode,
'start_date' => $startDate->format('Y-m-d'),
'end_date' => $endDate->format('Y-m-d')
]);
}
/**
* Calculate business day end date (excludes weekends and holidays)
*/
private function calculateBusinessDayEnd($startDate, $workingDays = 10)
{
$current = $startDate->copy();
$daysAdded = 0;
// Indonesian public holidays 2025 (tanggal merah)
$holidays = [
'2025-01-01', '2025-01-29', '2025-03-29', '2025-03-30', '2025-04-09',
'2025-05-01', '2025-05-12', '2025-05-29', '2025-06-01', '2025-06-06',
'2025-06-07', '2025-08-17', '2025-08-31', '2025-09-21', '2025-11-30',
'2025-12-25'
];
while ($daysAdded < $workingDays) {
$current->addDay();
// Skip weekends and holidays
if ($current->dayOfWeek == Carbon::SATURDAY ||
$current->dayOfWeek == Carbon::SUNDAY ||
in_array($current->format('Y-m-d'), $holidays)) {
continue;
}
$daysAdded++;
}
return $current;
}
/**
* Get kecamatan by kabupaten ID
*/
public function getKecamatan(Request $request)
{
$kabupatenId = $request->kabupaten_id;
$kecamatan = Kecamatan::where('KabupatenId', $kabupatenId)
->orderBy('NamaKecamatan', 'asc')
->get(['KecamatanId', 'NamaKecamatan']);
return response()->json($kecamatan);
}
/**
* Get kelurahan by kecamatan ID
*/
public function getKelurahan(Request $request)
{
$kecamatanId = $request->kecamatan_id;
$kelurahan = Kelurahan::where('KecamatanId', $kecamatanId)
->orderBy('NamaKelurahan', 'asc')
->get(['KelurahanId', 'NamaKelurahan']);
return response()->json($kelurahan);
}
}