Update BUMDes

This commit is contained in:
2026-11-05 19:20:05 +07:00
parent 9cdd178297
commit c55ff109a0
73 changed files with 6699 additions and 1548 deletions
@@ -0,0 +1,633 @@
<?php
namespace App\Services\Bumdes;
use App\Enums\Bumdes\AsetProduktifBumdes;
use App\Enums\Bumdes\BentukProdukBumdes;
use App\Enums\Bumdes\CakupanLayananBumdes;
use App\Enums\Bumdes\DukunganDesaBumdes;
use App\Enums\Bumdes\FormatPembukuanBumdes;
use App\Enums\Bumdes\HambatanUsahaBumdes;
use App\Enums\Bumdes\HubunganPemasokBumdes;
use App\Enums\Bumdes\InfrastrukturPascapanenBumdes;
use App\Enums\Bumdes\JabatanBumdes;
use App\Enums\Bumdes\JabatanPengurusIntiBumdes;
use App\Enums\Bumdes\KemitraanEksternalBumdes;
use App\Enums\Bumdes\KeterlibatanKoordinasiBumdes;
use App\Enums\Bumdes\KondisiAsetProduktifBumdes;
use App\Enums\Bumdes\KondisiInfrastrukturBumdes;
use App\Enums\Bumdes\KondisiKeuanganBumdes;
use App\Enums\Bumdes\KontribusiPadesBumdes;
use App\Enums\Bumdes\LayananPetaniBumdes;
use App\Enums\Bumdes\MekanismePembayaranBumdes;
use App\Enums\Bumdes\ModelFermentasiBumdes;
use App\Enums\Bumdes\PencatatanPetaniBumdes;
use App\Enums\Bumdes\PenetapanHargaBeliBumdes;
use App\Enums\Bumdes\PengalamanOfftakerBumdes;
use App\Enums\Bumdes\PeranRantaiNilaiBumdes;
use App\Enums\Bumdes\PeriodePanenBumdes;
use App\Enums\Bumdes\PerjanjianPetaniBumdes;
use App\Enums\Bumdes\PertanggungjawabanMusdesBumdes;
use App\Enums\Bumdes\SaluranPenjualanBumdes;
use App\Enums\Bumdes\SifatAuditBumdes;
use App\Enums\Bumdes\StatusAdArtBumdes;
use App\Enums\Bumdes\StatusBadanHukumBumdes;
use App\Enums\Bumdes\StatusFermentasiBumdes;
use App\Enums\Bumdes\StatusKeaktifanBumdes;
use App\Enums\Bumdes\StatusKepemilikanAsetBumdes;
use App\Enums\Bumdes\StatusPembukuanBumdes;
use App\Enums\Bumdes\StatusPengeringanBumdes;
use App\Enums\Bumdes\StatusSortasiBumdes;
use App\Enums\Bumdes\StatusUnitKomoditasBumdes;
use App\Enums\Bumdes\SumberPasokanBumdes;
use App\Enums\Bumdes\UnitUsahaBumdes;
use App\Enums\Pendidikan;
use App\Enums\Role;
use App\Models\Bumdes\KelembagaanAktorBumdes;
use App\Models\Bumdes\PengurusBumdes;
use App\Models\Wilayah\DesaKelurahan;
use App\Models\Wilayah\KabupatenKota;
use App\Models\Wilayah\Kecamatan;
use App\Models\Wilayah\Provinsi;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class PengurusBumdesService
{
// BUMDes memakai seluruh master wilayah, termasuk wilayah di luar lokasi program aktif.
public function indexData(array $validated): array
{
$defaultKabupaten = KabupatenKota::withoutGlobalScope('program')->select('id', 'nama')
->whereRaw('lower(nama) like ?', ['%ngada%'])->orderBy('nama')->first();
$filters = [
'search' => $validated['search'] ?? null,
'kabupaten_kota_id' => $validated['kabupaten_kota_id'] ?? $defaultKabupaten?->id,
'kecamatan_id' => $validated['kecamatan_id'] ?? null,
'desa_kelurahan_id' => $validated['desa_kelurahan_id'] ?? null,
'status_keaktifan' => $validated['status_keaktifan'] ?? null,
'sort_by' => in_array($validated['sort_by'] ?? null, ['nama_asc', 'nama_desc'], true)
? $validated['sort_by'] : null,
];
$query = $this->pengurusQuery()->with([
...$this->wilayahRelationsWithoutProgramScope(),
'creator:id,name',
'kelembagaanAktor',
]);
if (filled($filters['search'])) {
$search = '%'.Str::lower($filters['search']).'%';
$query->where(function ($query) use ($search) {
$query->whereRaw('lower(nama) like ?', [$search])
->orWhereHas('desaKelurahan', function ($query) use ($search) {
$query->withoutGlobalScope('program')->where(function ($query) use ($search) {
$query->whereRaw('lower(nama) like ?', [$search])
->orWhereHas('kecamatan', fn ($query) => $query->withoutGlobalScope('program')->whereRaw('lower(nama) like ?', [$search]));
});
});
});
}
$query->when($filters['kabupaten_kota_id'], function ($query, $id) {
$query->whereHas('desaKelurahan', function ($query) use ($id) {
$query->withoutGlobalScope('program')->whereHas('kecamatan', function ($query) use ($id) {
$query->withoutGlobalScope('program')->where('kabupaten_kota_id', $id);
});
});
})->when($filters['kecamatan_id'], function ($query, $id) {
$query->whereHas('desaKelurahan', fn ($query) => $query->withoutGlobalScope('program')->where('kecamatan_id', $id));
})->when($filters['desa_kelurahan_id'], fn ($query, $id) => $query->where('desa_kelurahan_id', $id));
$query->when($filters['status_keaktifan'], fn ($query, $value) => $query
->whereHas('kelembagaanAktor', fn ($query) => $query->where('status_keaktifan', $value)));
$summaryQuery = clone $query;
$totalBumdes = (clone $summaryQuery)->count();
$totalBumdesAktif = (clone $summaryQuery)->whereHas('kelembagaanAktor', fn ($query) => $query
->whereIn('status_keaktifan', [StatusKeaktifanBumdes::AKTIF_PENUH->value, StatusKeaktifanBumdes::AKTIF_TERBATAS->value]))->count();
$totalBerbadanHukum = (clone $summaryQuery)->whereHas('kelembagaanAktor', fn ($query) => $query
->where('status_badan_hukum', StatusBadanHukumBumdes::SUDAH_BERBADAN_HUKUM->value))->count();
$totalDesaKelurahan = (clone $summaryQuery)->distinct('desa_kelurahan_id')->count('desa_kelurahan_id');
if ($filters['sort_by']) {
$namaDesa = DesaKelurahan::withoutGlobalScope('program')->select('nama')
->whereColumn('master_desa_kelurahan.id', 'bumdes_pengurus.desa_kelurahan_id')->limit(1);
$query->orderBy($namaDesa, $filters['sort_by'] === 'nama_asc' ? 'asc' : 'desc');
} else {
$query->latest();
}
$perPage = (int) ($validated['per_page'] ?? 10);
$pengurus = $query->orderByDesc('id')->paginate($perPage)->appends([...$filters, 'per_page' => $perPage]);
$ringkasanBumdes = $pengurus->getCollection()
->mapWithKeys(fn (PengurusBumdes $item) => [$item->id => $this->profileSummary($item)]);
$selectedKabupaten = $filters['kabupaten_kota_id']
? KabupatenKota::withoutGlobalScope('program')->select('id', 'nama')->find($filters['kabupaten_kota_id']) : null;
$kecamatanOptions = $filters['kabupaten_kota_id']
? Kecamatan::withoutGlobalScope('program')->select('id', 'nama')->where('kabupaten_kota_id', $filters['kabupaten_kota_id'])->orderBy('nama')->get()
: collect();
$desaOptions = $filters['kecamatan_id']
? DesaKelurahan::withoutGlobalScope('program')->select('id', 'nama')->where('kecamatan_id', $filters['kecamatan_id'])->orderBy('nama')->get()
: collect();
$statusKeaktifanOptions = StatusKeaktifanBumdes::options();
$userRole = auth()->user()->role->value;
$showEnumerator = in_array($userRole, ['super_admin', 'admin']);
return compact(
'pengurus',
'ringkasanBumdes',
'totalBumdes',
'totalBumdesAktif',
'totalBerbadanHukum',
'totalDesaKelurahan',
'showEnumerator', 'filters', 'selectedKabupaten', 'kecamatanOptions', 'desaOptions',
'statusKeaktifanOptions'
);
}
public function profileData(?PengurusBumdes $pengurus = null): array
{
$pengurus?->loadMissing([...$this->wilayahRelationsWithoutProgramScope(), 'kelembagaanAktor']);
return [
'pengurus' => $pengurus,
'ringkasanProfil' => $this->profileSummary($pengurus),
'provinsi' => $this->provinsiOptions(),
'jabatan' => JabatanBumdes::options(),
'pendidikan' => Pendidikan::options(),
...$this->profileLocationOptions($pengurus),
...$this->profileBumdesOptions($pengurus),
];
}
public function sectionData(PengurusBumdes $pengurus): array
{
$pengurus->loadMissing([...$this->wilayahRelationsWithoutProgramScope(), 'kelembagaanAktor']);
return [
'pengurus' => $pengurus,
'ringkasanProfil' => $this->profileSummary($pengurus),
'kelembagaanAktor' => $pengurus->kelembagaanAktor?->attributesToArray(),
...$this->kelembagaanAktorOptions(),
];
}
private function profileSummary(?PengurusBumdes $pengurus): array
{
$data = $pengurus?->kelembagaanAktor;
$desa = $pengurus?->desaKelurahan;
$keaktifan = $data?->status_keaktifan;
$hukum = $data?->status_badan_hukum;
$unitUsaha = collect($data?->unit_usaha ?? [])->map(function (UnitUsahaBumdes $unit) use ($data) {
return $unit === UnitUsahaBumdes::JASA_LAINNYA && filled($data->unit_usaha_jasa_lainnya)
? $unit->label().': '.$data->unit_usaha_jasa_lainnya : $unit->label();
})->all();
$updatedAt = collect([
$pengurus?->updated_at ?? $pengurus?->created_at,
$data?->updated_at ?? $data?->created_at,
])->filter()->sortByDesc(fn ($date) => $date->getTimestamp())->first();
return [
'judul' => $pengurus
? ($desa?->nama ? 'BUMDes · '.$desa->nama : 'Profil BUMDes') : 'Profil BUMDes Baru',
'lokasi' => collect([
$desa?->kecamatan?->nama, $desa?->kecamatan?->kabupatenKota?->nama,
$desa?->kecamatan?->kabupatenKota?->provinsi?->nama,
])->filter(fn ($value) => filled($value))->implode(' · ') ?: 'Lokasi belum terisi',
'alamat' => $pengurus?->alamat ?: 'Belum terisi',
'keaktifan' => [
'label' => $keaktifan?->label() ?? 'Belum terisi',
'warna' => match ($keaktifan) {
StatusKeaktifanBumdes::AKTIF_PENUH => 'success',
StatusKeaktifanBumdes::AKTIF_TERBATAS => 'warning',
StatusKeaktifanBumdes::TIDAK_AKTIF_VAKUM => 'danger',
default => 'secondary',
},
],
'hukum' => [
'label' => $hukum?->label() ?? 'Belum terisi',
'warna' => match ($hukum) {
StatusBadanHukumBumdes::SUDAH_BERBADAN_HUKUM => 'success',
StatusBadanHukumBumdes::PROSES_PENDAFTARAN => 'warning',
default => 'secondary',
},
],
'unit_usaha' => $unitUsaha,
'responden' => $pengurus?->nama ?: 'Belum terisi',
'jabatan' => $pengurus ? $pengurus->nama_jabatan : 'Belum terisi',
'nomor_telepon' => $pengurus?->nomor_telepon ?: 'Belum terisi',
'diperbarui' => $updatedAt,
];
}
public function storeProfile(array $data): PengurusBumdes
{
return DB::transaction(function () use ($data) {
$pengurus = PengurusBumdes::create([
...$this->respondentData($data),
'uid' => 'BMD-'.strtoupper(Str::random(10)),
'created_by' => auth()->id(), 'updated_by' => auth()->id(),
]);
$this->saveSection($pengurus, $data, 'profil');
return $pengurus;
});
}
public function updateProfile(PengurusBumdes $pengurus, array $data): void
{
DB::transaction(function () use ($pengurus, $data) {
$pengurus->update([...$this->respondentData($data), 'updated_by' => auth()->id()]);
$this->saveSection($pengurus, $data, 'profil');
});
}
private function respondentData(array $data): array
{
$data = array_intersect_key($data, array_flip([
'nama', 'jenis_kelamin', 'tempat_lahir', 'tanggal_lahir', 'pendidikan_terakhir',
'alamat', 'desa_kelurahan_id', 'nomor_telepon', 'jabatan', 'jabatan_lainnya', 'lama_menjabat_tahun',
]));
return $this->formatData($data);
}
public function saveSection(PengurusBumdes $pengurus, array $validatedData, string $section): void
{
$data = array_intersect_key(
$section === 'rantai-nilai' ? $this->formatRantaiNilaiData($validatedData) : $this->formatKelembagaanAktorData($validatedData),
array_flip(KelembagaanAktorBumdes::sectionFields($section))
);
// Kolom kepemilikan lama tetap dipertahankan untuk data sebelum kepemilikan dipisah per aset.
if ($section === 'operasional' && ! array_key_exists('status_kepemilikan_aset', $validatedData)) {
unset($data['status_kepemilikan_aset']);
}
KelembagaanAktorBumdes::updateOrCreate(
['pengurus_bumdes_id' => $pengurus->id],
[
...$data,
'created_by' => $pengurus->kelembagaanAktor?->created_by ?? auth()->id(),
'updated_by' => auth()->id(),
]
);
}
private function profileBumdesOptions(?PengurusBumdes $pengurus = null): array
{
return [
'kelembagaanAktor' => $pengurus?->kelembagaanAktor?->attributesToArray(),
'statusKeaktifanOptions' => StatusKeaktifanBumdes::options(),
'pengurusIntiRows' => JabatanPengurusIntiBumdes::options(),
];
}
private function pengurusQuery()
{
$query = PengurusBumdes::query();
if (auth()->user()->role === Role::ENUMERATOR) {
$query->where('created_by', auth()->id());
}
return $query;
}
// Master wilayah BUMDes tidak dibatasi lokasi program, sama seperti halaman profilnya.
private function provinsiOptions()
{
return Provinsi::withoutGlobalScope('program')
->select('id', 'kode', 'nama')
->orderBy('kode', 'asc')
->get();
}
private function wilayahRelationsWithoutProgramScope(): array
{
return [
'desaKelurahan' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama', 'kecamatan_id'),
'desaKelurahan.kecamatan' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama', 'kabupaten_kota_id'),
'desaKelurahan.kecamatan.kabupatenKota' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama', 'provinsi_id'),
'desaKelurahan.kecamatan.kabupatenKota.provinsi' => fn ($query) => $query->withoutGlobalScope('program')->select('id', 'nama'),
];
}
private function profileLocationOptions(?PengurusBumdes $pengurus = null): array
{
$locationId = static fn ($value) => is_scalar($value) && filter_var($value, FILTER_VALIDATE_INT) !== false ? (int) $value : null;
$provinsiId = $locationId(old('provinsi_id', $pengurus?->desaKelurahan?->kecamatan?->kabupatenKota?->provinsi_id));
$kabupatenId = $locationId(old('kabupaten_id', $pengurus?->desaKelurahan?->kecamatan?->kabupaten_kota_id));
$kecamatanId = $locationId(old('kecamatan_id', $pengurus?->desaKelurahan?->kecamatan_id));
return [
'kabupatenOptions' => $provinsiId ? KabupatenKota::withoutGlobalScope('program')->where('provinsi_id', $provinsiId)->orderBy('nama')->get() : collect(),
'kecamatanOptions' => $kabupatenId ? Kecamatan::withoutGlobalScope('program')->where('kabupaten_kota_id', $kabupatenId)->orderBy('nama')->get() : collect(),
'desaOptions' => $kecamatanId ? DesaKelurahan::withoutGlobalScope('program')->where('kecamatan_id', $kecamatanId)->orderBy('nama')->get() : collect(),
];
}
private function formatData(array $data): array
{
$data['tanggal_lahir'] = Carbon::createFromFormat('d-m-Y', $data['tanggal_lahir'])->format('Y-m-d');
$data['tanggal_mulai_menjabat'] = Carbon::now()
->subYears((int) $data['lama_menjabat_tahun'])
->format('Y-m-d');
if (($data['jabatan'] ?? null) !== JabatanBumdes::LAINNYA->value) {
$data['jabatan_lainnya'] = null;
}
return $data;
}
private function formatRantaiNilaiData(array $data): array
{
$defaults = array_fill_keys(KelembagaanAktorBumdes::sectionFields('rantai-nilai'), null);
foreach (['sumber_pasokan', 'bentuk_produk_dibeli', 'volume_pembelian', 'saluran_penjualan', 'bentuk_produk_dijual', 'volume_penjualan', 'hubungan_petani_pemasok', 'harga_beli_petani'] as $field) {
$defaults[$field] = [];
}
$postharvest = $this->formatPascapanenData($data);
$defaults['melakukan_jual_beli'] = in_array($data['melakukan_jual_beli'] ?? null, [true, 1, '1'], true);
if (! $defaults['melakukan_jual_beli']) {
return array_replace($defaults, $postharvest);
}
$payload = array_replace($defaults, $data);
foreach (['sumber_pasokan', 'bentuk_produk_dibeli', 'saluran_penjualan', 'bentuk_produk_dijual', 'hubungan_petani_pemasok'] as $field) {
$payload[$field] = array_values($payload[$field] ?? []);
}
foreach (['sumber_pasokan' => 'sumber_pasokan_lainnya', 'saluran_penjualan' => 'saluran_penjualan_lainnya', 'hubungan_petani_pemasok' => 'hubungan_petani_pemasok_lainnya'] as $field => $other) {
if (! in_array('lainnya', $payload[$field], true)) {
$payload[$other] = null;
}
}
if ($payload['mekanisme_pembayaran_petani'] !== MekanismePembayaranBumdes::LAINNYA->value) {
$payload['mekanisme_pembayaran_lainnya'] = null;
}
if ($payload['penetapan_harga_beli'] !== PenetapanHargaBeliBumdes::LAINNYA->value) {
$payload['penetapan_harga_beli_lainnya'] = null;
}
$periods = array_keys(PeriodePanenBumdes::options());
foreach (['volume_pembelian', 'volume_penjualan'] as $field) {
$payload[$field] = collect($payload[$field] ?? [])->only($periods)->filter(fn ($value) => $value !== null && $value !== '')->all();
}
if (in_array(SaluranPenjualanBumdes::BELUM_MENJUAL->value, $payload['saluran_penjualan'], true)) {
$payload['bentuk_produk_dijual'] = [];
$payload['volume_penjualan'] = [];
}
$payload['harga_beli_petani'] = collect($payload['harga_beli_petani'] ?? [])->only($payload['bentuk_produk_dibeli'])
->map(fn ($row) => collect($row)->only($periods)->filter(fn ($value) => $value !== null && $value !== '')->all())
->filter(fn ($row) => count($row) > 0)->all();
return array_replace($payload, $postharvest);
}
private function formatPascapanenData(array $data): array
{
$processing = in_array($data['melakukan_pengolahan_pascapanen'] ?? null, [true, 1, '1'], true);
$payload = [
'melakukan_pengolahan_pascapanen' => ($data['melakukan_pengolahan_pascapanen'] ?? null) === null ? null : $processing,
'status_sortasi' => null, 'kriteria_sortasi' => null,
'status_pengeringan' => null, 'cara_tempat_pengeringan' => null,
'status_fermentasi' => null, 'model_fermentasi' => [],
'proses_fermentasi' => null, 'premium_harga_pascapanen' => null,
];
if (! $processing) {
return $payload;
}
$payload = array_replace($payload, array_intersect_key($data, $payload));
if (! in_array($payload['status_sortasi'], [StatusSortasiBumdes::RUTIN_STANDAR->value, StatusSortasiBumdes::TIDAK_KONSISTEN->value], true)) {
$payload['kriteria_sortasi'] = null;
}
if (! in_array($payload['status_pengeringan'], [StatusPengeringanBumdes::RUTIN->value, StatusPengeringanBumdes::KADANG->value], true)) {
$payload['cara_tempat_pengeringan'] = null;
}
if (! in_array($payload['status_fermentasi'], [StatusFermentasiBumdes::RUTIN->value, StatusFermentasiBumdes::PERNAH_MENCOBA->value], true)) {
$payload['model_fermentasi'] = [];
$payload['proses_fermentasi'] = null;
}
$payload['model_fermentasi'] = array_values($payload['model_fermentasi'] ?? []);
return $payload;
}
private function formatKelembagaanAktorData(array $data): array
{
$payload = array_merge([
'status_badan_hukum' => null,
'nomor_dasar_hukum' => null,
'tahun_dasar_hukum' => null,
'status_keaktifan' => null,
'alasan_tidak_aktif' => null,
'unit_usaha' => [],
'unit_usaha_jasa_lainnya' => null,
'status_unit_komoditas' => null,
'nama_unit_komoditas' => null,
'status_ad_art' => null,
'tahun_ad_art' => null,
'pengurus_inti' => [],
'memiliki_staf' => null,
'jumlah_staf' => null,
'unit_usaha_staf' => null,
'modal_awal' => null,
'tahun_modal_awal' => null,
'pernah_penambahan_modal' => null,
'penambahan_modal' => [],
'aset_produktif' => [],
'aset_produktif_lainnya' => null,
'status_kepemilikan_aset' => null,
'infrastruktur_pascapanen' => [],
'infrastruktur_pascapanen_lainnya' => null,
'status_pembukuan' => null,
'format_pembukuan' => null,
'pernah_audit' => null,
'sifat_audit' => [],
'pelaksana_audit' => null,
'tahun_audit' => null,
'pertanggungjawaban_musdes' => null,
'tahun_laporan_musdes' => null,
'kondisi_keuangan' => null,
'kontribusi_pades' => null,
'nominal_kontribusi_pades' => null,
'cakupan_layanan' => null,
'desa_lain_dilayani' => null,
'jumlah_petani_desa_sendiri' => null,
'jumlah_petani_desa_lain' => null,
'pencatatan_petani' => null,
'layanan_petani' => [],
'layanan_petani_lainnya' => null,
'peran_rantai_nilai' => null,
'pengalaman_offtaker' => null,
'nama_offtaker' => null,
'tahun_mulai_offtaker' => null,
'alasan_berhenti_offtaker' => null,
'hambatan_usaha' => [],
'hambatan_usaha_lainnya' => null,
'ada_alokasi_desa' => null,
'jumlah_alokasi_desa' => null,
'dukungan_desa' => [],
'dukungan_desa_lainnya' => null,
'keterlibatan_koordinasi_desa' => null,
'kemitraan_eksternal' => [],
'kemitraan_eksternal_lainnya' => null,
], $data);
foreach (['sifat_audit', 'layanan_petani', 'hambatan_usaha'] as $field) {
$payload[$field] = array_values($payload[$field] ?? []);
}
if (! (bool) $payload['pernah_audit']) {
$payload['sifat_audit'] = [];
$payload['pelaksana_audit'] = null;
$payload['tahun_audit'] = null;
}
if ($payload['pertanggungjawaban_musdes'] !== PertanggungjawabanMusdesBumdes::TAHUNAN->value) {
$payload['tahun_laporan_musdes'] = null;
}
if (! in_array($payload['kontribusi_pades'], [KontribusiPadesBumdes::RUTIN->value, KontribusiPadesBumdes::TIDAK_RUTIN->value], true)) {
$payload['nominal_kontribusi_pades'] = null;
}
if ($payload['cakupan_layanan'] !== CakupanLayananBumdes::DESA_LAIN->value) {
$payload['desa_lain_dilayani'] = null;
$payload['jumlah_petani_desa_lain'] = null;
}
if (! in_array(LayananPetaniBumdes::LAINNYA->value, $payload['layanan_petani'], true)) {
$payload['layanan_petani_lainnya'] = null;
}
if (! in_array(HambatanUsahaBumdes::LAINNYA->value, $payload['hambatan_usaha'], true)) {
$payload['hambatan_usaha_lainnya'] = null;
}
if ($payload['pengalaman_offtaker'] !== PengalamanOfftakerBumdes::BERJALAN->value) {
$payload['nama_offtaker'] = null;
$payload['tahun_mulai_offtaker'] = null;
}
if ($payload['pengalaman_offtaker'] !== PengalamanOfftakerBumdes::BERHENTI->value) {
$payload['alasan_berhenti_offtaker'] = null;
}
$payload['dukungan_desa'] = array_values($payload['dukungan_desa'] ?? []);
$payload['kemitraan_eksternal'] = array_values($payload['kemitraan_eksternal'] ?? []);
if (! (bool) $payload['ada_alokasi_desa']) {
$payload['jumlah_alokasi_desa'] = null;
}
if (! in_array(DukunganDesaBumdes::LAINNYA->value, $payload['dukungan_desa'], true)) {
$payload['dukungan_desa_lainnya'] = null;
}
if (! in_array(KemitraanEksternalBumdes::LAINNYA->value, $payload['kemitraan_eksternal'], true)) {
$payload['kemitraan_eksternal_lainnya'] = null;
}
$payload['unit_usaha'] = array_values($payload['unit_usaha'] ?? []);
$payload['pengurus_inti'] = $this->filterRows($payload['pengurus_inti'] ?? [], ['nama']);
$payload['penambahan_modal'] = $this->filterRows($payload['penambahan_modal'] ?? [], ['tahun', 'jumlah']);
foreach (['aset_produktif', 'infrastruktur_pascapanen'] as $field) {
$payload[$field] = collect($payload[$field] ?? [])
->filter(fn ($row) => in_array($row['dipilih'] ?? null, [true, 1, '1'], true))
->values()->all();
}
if (($payload['status_badan_hukum'] ?? null) !== 'sudah_berbadan_hukum') {
$payload['nomor_dasar_hukum'] = null;
$payload['tahun_dasar_hukum'] = null;
}
if (($payload['status_keaktifan'] ?? null) !== 'tidak_aktif_vakum') {
$payload['alasan_tidak_aktif'] = null;
}
if (! in_array('jasa_lainnya', $payload['unit_usaha'], true)) {
$payload['unit_usaha_jasa_lainnya'] = null;
}
if (($payload['status_unit_komoditas'] ?? null) !== 'ya') {
$payload['nama_unit_komoditas'] = null;
}
if (($payload['status_ad_art'] ?? null) !== 'ada_lengkap') {
$payload['tahun_ad_art'] = null;
}
if (! (bool) ($payload['memiliki_staf'] ?? false)) {
$payload['jumlah_staf'] = null;
$payload['unit_usaha_staf'] = null;
}
if (! (bool) ($payload['pernah_penambahan_modal'] ?? false)) {
$payload['penambahan_modal'] = null;
}
if (! collect($payload['aset_produktif'] ?? [])->contains(fn ($row) => ($row['aset'] ?? null) === 'lainnya')) {
$payload['aset_produktif_lainnya'] = null;
}
if (! collect($payload['infrastruktur_pascapanen'] ?? [])->contains(fn ($row) => ($row['infrastruktur'] ?? null) === 'lainnya')) {
$payload['infrastruktur_pascapanen_lainnya'] = null;
}
return $payload;
}
private function filterRows(array $rows, array $valueKeys): array
{
return collect($rows)
->map(function ($row) {
return collect($row)
->map(fn ($value) => $value === '' ? null : $value)
->all();
})
->filter(function ($row) use ($valueKeys) {
foreach ($valueKeys as $key) {
if (filled($row[$key] ?? null)) {
return true;
}
}
return false;
})
->values()
->all();
}
private function kelembagaanAktorOptions(): array
{
return [
'statusSortasiOptions' => StatusSortasiBumdes::options(),
'statusPengeringanOptions' => StatusPengeringanBumdes::options(),
'statusFermentasiOptions' => StatusFermentasiBumdes::options(),
'modelFermentasiOptions' => ModelFermentasiBumdes::options(),
'sumberPasokanOptions' => SumberPasokanBumdes::options(),
'bentukProdukOptions' => BentukProdukBumdes::options(),
'periodePanenOptions' => PeriodePanenBumdes::options(),
'saluranPenjualanOptions' => SaluranPenjualanBumdes::options(),
'hubunganPemasokOptions' => HubunganPemasokBumdes::options(),
'mekanismePembayaranOptions' => MekanismePembayaranBumdes::options(),
'perjanjianPetaniOptions' => PerjanjianPetaniBumdes::options(),
'penetapanHargaBeliOptions' => PenetapanHargaBeliBumdes::options(),
'statusBadanHukumOptions' => StatusBadanHukumBumdes::options(),
'statusKeaktifanOptions' => StatusKeaktifanBumdes::options(),
'unitUsahaOptions' => UnitUsahaBumdes::options(),
'statusUnitKomoditasOptions' => StatusUnitKomoditasBumdes::options(),
'statusAdArtOptions' => StatusAdArtBumdes::options(),
'pengurusIntiRows' => JabatanPengurusIntiBumdes::options(),
'asetProduktifRows' => AsetProduktifBumdes::options(),
'kondisiAsetProduktifOptions' => KondisiAsetProduktifBumdes::options(),
'statusKepemilikanAsetOptions' => StatusKepemilikanAsetBumdes::options(),
'infrastrukturPascapanenRows' => InfrastrukturPascapanenBumdes::options(),
'statusPembukuanOptions' => StatusPembukuanBumdes::options(),
'formatPembukuanOptions' => FormatPembukuanBumdes::options(),
'sifatAuditOptions' => SifatAuditBumdes::options(),
'pertanggungjawabanMusdesOptions' => PertanggungjawabanMusdesBumdes::options(),
'kondisiKeuanganOptions' => KondisiKeuanganBumdes::options(),
'kontribusiPadesOptions' => KontribusiPadesBumdes::options(),
'cakupanLayananOptions' => CakupanLayananBumdes::options(),
'pencatatanPetaniOptions' => PencatatanPetaniBumdes::options(),
'layananPetaniOptions' => LayananPetaniBumdes::options(),
'peranRantaiNilaiOptions' => PeranRantaiNilaiBumdes::options(),
'pengalamanOfftakerOptions' => PengalamanOfftakerBumdes::options(),
'hambatanUsahaOptions' => HambatanUsahaBumdes::options(),
'dukunganDesaOptions' => DukunganDesaBumdes::options(),
'keterlibatanKoordinasiOptions' => KeterlibatanKoordinasiBumdes::options(),
'kemitraanEksternalOptions' => KemitraanEksternalBumdes::options(),
'kondisiInfrastrukturOptions' => KondisiInfrastrukturBumdes::options(),
];
}
}