Update Koperasi
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Koperasi;
|
||||
|
||||
use App\Enums\Koperasi\FokusKomoditasKoperasi;
|
||||
use App\Enums\Koperasi\JenisKoperasi;
|
||||
use App\Enums\Koperasi\LayananKoperasi;
|
||||
use App\Enums\Koperasi\StatusAdArtKoperasi;
|
||||
use App\Enums\Koperasi\UrutanKoperasi;
|
||||
use App\Enums\Role;
|
||||
use App\Models\Koperasi\PengurusKoperasi;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class PengurusKoperasiService
|
||||
{
|
||||
public function __construct(private WilayahKoperasiService $wilayah) {}
|
||||
|
||||
public const RUPIAH_FIELDS = [
|
||||
'shu_2025', 'shu_2024', 'shu_2023', 'simpanan_terbesar', 'harga_premium_rupiah',
|
||||
'harga_segar_sekarang', 'harga_segar_1_tahun', 'harga_segar_2_tahun',
|
||||
'harga_basah_sekarang', 'harga_basah_1_tahun', 'harga_basah_2_tahun',
|
||||
'harga_kering_sekarang', 'harga_kering_1_tahun', 'harga_kering_2_tahun',
|
||||
'harga_fermentasi_sekarang', 'harga_fermentasi_1_tahun', 'harga_fermentasi_2_tahun',
|
||||
];
|
||||
|
||||
public function indexData(array $validated): array
|
||||
{
|
||||
$filters = [
|
||||
'search' => $validated['search'] ?? '',
|
||||
'kabupaten_kota_id' => $validated['kabupaten_kota_id'] ?? ($this->wilayah->available() ? $this->wilayah->defaultKabupaten()?->id : ''),
|
||||
'kecamatan_id' => $validated['kecamatan_id'] ?? '', 'desa_kelurahan_id' => $validated['desa_kelurahan_id'] ?? '',
|
||||
'jenis_koperasi' => $validated['jenis_koperasi'] ?? '',
|
||||
'layanan' => $validated['layanan'] ?? '', 'ad_art' => $validated['ad_art'] ?? '',
|
||||
'sort_by' => $validated['sort_by'] ?? UrutanKoperasi::TERBARU->value,
|
||||
];
|
||||
$query = PengurusKoperasi::query()->with('creator:id,name')
|
||||
->when(filled($filters['jenis_koperasi']), function ($query) use ($filters) {
|
||||
if ($filters['jenis_koperasi'] === JenisKoperasi::LAINNYA->value) {
|
||||
$standard = array_map(fn ($jenis) => $jenis->value, array_filter(JenisKoperasi::cases(), fn ($jenis) => $jenis !== JenisKoperasi::LAINNYA));
|
||||
|
||||
return $query->whereNotIn('jenis_koperasi', $standard);
|
||||
}
|
||||
|
||||
return $query->where('jenis_koperasi', $filters['jenis_koperasi']);
|
||||
})
|
||||
->when(filled($filters['layanan']), fn ($query) => $query->whereJsonContains('layanan_koperasi', $filters['layanan']))
|
||||
->when(filled($filters['ad_art']), fn ($query) => $query->where('ad_art', $filters['ad_art']))
|
||||
->when(filled($filters['search']), function ($query) use ($filters) {
|
||||
$query->where(function ($query) use ($filters) {
|
||||
foreach (['nama_koperasi', 'alamat_koperasi', 'jenis_koperasi', 'nama_lengkap'] as $field) {
|
||||
$query->orWhereLike($field, '%'.$filters['search'].'%');
|
||||
}
|
||||
});
|
||||
});
|
||||
$this->wilayah->applyFilters($query, $filters);
|
||||
$order = UrutanKoperasi::from($filters['sort_by']);
|
||||
match ($order) {
|
||||
UrutanKoperasi::NAMA_ASC, UrutanKoperasi::NAMA_DESC => $query->orderByRaw('LOWER(nama_koperasi) '.($order === UrutanKoperasi::NAMA_ASC ? 'asc' : 'desc')),
|
||||
UrutanKoperasi::ANGGOTA_ASC, UrutanKoperasi::ANGGOTA_DESC => $query
|
||||
->orderByRaw('CASE WHEN jumlah_anggota_dewasa IS NULL OR jumlah_anggota_anak IS NULL THEN 1 ELSE 0 END')
|
||||
->orderByRaw('(jumlah_anggota_dewasa + jumlah_anggota_anak) '.($order === UrutanKoperasi::ANGGOTA_ASC ? 'asc' : 'desc')),
|
||||
UrutanKoperasi::TERBARU => $query->latest(),
|
||||
};
|
||||
$koperasi = $query->orderByDesc('id')->paginate((int) ($validated['per_page'] ?? 10))->withQueryString();
|
||||
$ringkasanKoperasi = $koperasi->getCollection()->mapWithKeys(fn (PengurusKoperasi $item) => [$item->id => $this->profileSummary($item)]);
|
||||
$jenisTerdata = PengurusKoperasi::whereNotNull('jenis_koperasi')->where('jenis_koperasi', '!=', '')
|
||||
->distinct()->orderBy('jenis_koperasi')->pluck('jenis_koperasi');
|
||||
$jenisKoperasiOptions = collect(JenisKoperasi::cases())->map(fn ($jenis) => $jenis->value)
|
||||
->merge($jenisTerdata)->unique()->values();
|
||||
|
||||
return [
|
||||
'koperasi' => $koperasi,
|
||||
'ringkasanKoperasi' => $ringkasanKoperasi,
|
||||
'filters' => $filters,
|
||||
'jenisKoperasiOptions' => $jenisKoperasiOptions,
|
||||
...$this->wilayah->filterOptions($filters),
|
||||
'showEnumerator' => in_array(auth()->user()?->role, [Role::SUPER_ADMIN, Role::ADMIN], true),
|
||||
'totalKoperasi' => PengurusKoperasi::count(),
|
||||
'totalJenisKoperasi' => $jenisTerdata->count(),
|
||||
'totalDokumenLengkap' => PengurusKoperasi::where('ad_art', StatusAdArtKoperasi::LENGKAP->value)->count(),
|
||||
];
|
||||
}
|
||||
|
||||
public function profileViewData(?PengurusKoperasi $pengurus = null): array
|
||||
{
|
||||
return [
|
||||
'pengurus' => $pengurus ?? new PengurusKoperasi,
|
||||
'ringkasanProfil' => $this->profileSummary($pengurus),
|
||||
...$this->wilayah->profileOptions($pengurus, session()->getOldInput()),
|
||||
];
|
||||
}
|
||||
|
||||
public function profileSummary(?PengurusKoperasi $pengurus = null): array
|
||||
{
|
||||
$empty = 'Belum terisi';
|
||||
$dewasa = $pengurus?->jumlah_anggota_dewasa;
|
||||
$anak = $pengurus?->jumlah_anggota_anak;
|
||||
$count = fn ($value) => filled($value) ? number_format((int) $value, 0, ',', '.') : $empty;
|
||||
$layanan = collect($pengurus?->layanan_koperasi ?? [])->map(function (LayananKoperasi $item) use ($pengurus) {
|
||||
return $item === LayananKoperasi::LAINNYA && filled($pengurus->layanan_lainnya)
|
||||
? $item->label().': '.$pengurus->layanan_lainnya : $item->label();
|
||||
})->unique()->values()->all();
|
||||
|
||||
return [
|
||||
'judul' => filled($pengurus?->nama_koperasi) ? $pengurus->nama_koperasi : 'Nama Koperasi',
|
||||
'jenis' => filled($pengurus?->jenis_koperasi) ? $pengurus->jenis_koperasi : $empty,
|
||||
'alamat' => filled($pengurus?->alamat_koperasi) ? $pengurus->alamat_koperasi : $empty,
|
||||
'tahun_berdiri' => $pengurus?->tahun_berdiri ?? $empty,
|
||||
'anggota' => filled($dewasa) && filled($anak) ? $count((int) $dewasa + (int) $anak) : $empty,
|
||||
'anggota_rincian' => filled($dewasa) || filled($anak) ? 'Dewasa: '.$count($dewasa).' · Anak: '.$count($anak) : null,
|
||||
'pengurus' => $count($pengurus?->jumlah_pengurus),
|
||||
'layanan' => $layanan,
|
||||
'responden' => filled($pengurus?->nama_lengkap) ? $pengurus->nama_lengkap : $empty,
|
||||
'jabatan' => $pengurus?->posisi_dalam_koperasi?->value ?? $empty,
|
||||
'kontak' => filled($pengurus?->no_hp) ? $pengurus->no_hp : $empty,
|
||||
'diperbarui' => $pengurus?->updated_at ?? $pengurus?->created_at,
|
||||
'tersimpan' => $pengurus?->exists ?? false,
|
||||
];
|
||||
}
|
||||
|
||||
public static function normalizeRupiah(mixed $value): mixed
|
||||
{
|
||||
if (is_string($value) && preg_match('/^-?\d{1,3}(?:\.\d{3})+$/D', $value)) {
|
||||
return str_replace('.', '', $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public static function formatRupiah(mixed $value): string
|
||||
{
|
||||
$value = (string) self::normalizeRupiah($value);
|
||||
|
||||
return preg_match('/^-?\d+$/D', $value)
|
||||
? preg_replace('/\B(?=(\d{3})+(?!\d))/', '.', $value)
|
||||
: $value;
|
||||
}
|
||||
|
||||
public static function hasSelection(mixed $value, string $selection): bool
|
||||
{
|
||||
if ($value instanceof Collection) {
|
||||
$value = $value->all();
|
||||
}
|
||||
if ($value instanceof \BackedEnum) {
|
||||
$value = $value->value;
|
||||
}
|
||||
if (is_array($value)) {
|
||||
return in_array($selection, array_map(fn ($item) => $item instanceof \BackedEnum ? $item->value : $item, $value), true);
|
||||
}
|
||||
|
||||
$decoded = json_decode((string) $value, true);
|
||||
|
||||
return is_array($decoded)
|
||||
? in_array($selection, $decoded, true)
|
||||
: str_contains((string) $value, $selection);
|
||||
}
|
||||
|
||||
public function profileData(array $data): array
|
||||
{
|
||||
unset($data['provinsi_id'], $data['kabupaten_kota_id'], $data['kecamatan_id'], $data['created_by']);
|
||||
if (! $this->wilayah->available()) {
|
||||
unset($data['desa_kelurahan_id']);
|
||||
}
|
||||
if ($data['jenis_koperasi'] === JenisKoperasi::LAINNYA->value && ! empty($data['jenis_koperasi_lainnya'])) {
|
||||
$data['jenis_koperasi'] = $data['jenis_koperasi_lainnya'];
|
||||
}
|
||||
|
||||
unset($data['jenis_koperasi_lainnya']);
|
||||
|
||||
if (array_key_exists('fokus_komoditas', $data) && $data['fokus_komoditas'] !== FokusKomoditasKoperasi::YA->value) {
|
||||
$data['detail_fokus_komoditas'] = null;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function createProfile(array $data, int $creatorId): PengurusKoperasi
|
||||
{
|
||||
$data = $this->profileData($data);
|
||||
if ($this->wilayah->available()) {
|
||||
$data['created_by'] = $creatorId;
|
||||
}
|
||||
|
||||
return PengurusKoperasi::create($data);
|
||||
}
|
||||
|
||||
public function tabData(array $data): array
|
||||
{
|
||||
$model = new PengurusKoperasi;
|
||||
foreach ($data as $field => $value) {
|
||||
if (is_array($value) && ! $model->hasCast($field)) {
|
||||
$data[$field] = json_encode($value, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user