Compare commits
278
Commits
7cc3e0e8f1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f455f8b878 | ||
|
|
f1112e3b68 | ||
|
|
c1370a26ca | ||
|
|
013cb7b728 | ||
|
|
4ab745cfe5 | ||
|
|
c66eed56e2 | ||
|
|
8be0906a2e | ||
|
|
fcd79b7cfe | ||
|
|
bea9be8a39 | ||
|
|
5220b10de7 | ||
|
|
24725e3df1 | ||
|
|
60d32a88e9 | ||
|
|
4370d3c3d0 | ||
|
|
7699430301 | ||
|
|
df2b5a1312 | ||
|
|
2e8271d27a | ||
|
|
9b5c0a7309 | ||
|
|
9d56b67998 | ||
|
|
f95f43999a | ||
|
|
3e172cf915 | ||
|
|
3a9b3dbd7b | ||
|
|
80f0056efe | ||
|
|
aef27704f2 | ||
|
|
f49bb0c2db | ||
|
|
8a2c0292ac | ||
|
|
9ea324e553 | ||
|
|
94c3288ea7 | ||
|
|
8539bdcec4 | ||
|
|
77de648ded | ||
|
|
393cf0d0d1 | ||
|
|
7fdf9b400d | ||
|
|
be4d46004e | ||
|
|
fef5358402 | ||
|
|
02eed6da34 | ||
|
|
94d3f2a582 | ||
|
|
471ca5ac0e | ||
|
|
8ec8f0c9d6 | ||
|
|
4d7d16e9f6 | ||
|
|
1155b9b95b | ||
|
|
607533a327 | ||
|
|
6b25bff2c4 | ||
|
|
71b4d42ea2 | ||
|
|
c42a2571f5 | ||
|
|
16903b21e3 | ||
|
|
1d4a44b8ac | ||
|
|
539239b507 | ||
|
|
a76b014056 | ||
|
|
d50c292cf7 | ||
|
|
dacaec7a86 | ||
|
|
6967eafe98 | ||
|
|
118cda625a | ||
|
|
a3f7cb4669 | ||
|
|
ec009a2c55 | ||
|
|
b63dafdaee | ||
|
|
b97f682cd3 | ||
|
|
404019bab6 | ||
|
|
609919ba30 | ||
|
|
047cb4a779 | ||
|
|
530c297b53 | ||
|
|
8fbf68e6ef | ||
|
|
ac8b370248 | ||
|
|
88762f7afb | ||
|
|
b96de514e3 | ||
|
|
6830142a82 | ||
|
|
4b26e82afb | ||
|
|
b855a857b2 | ||
|
|
ba7520a23c | ||
|
|
0b333ab4e9 | ||
|
|
3b1f15d5b3 | ||
|
|
605506bba8 | ||
|
|
c960ba14b1 | ||
|
|
a4f38998d5 | ||
|
|
0d9f6c0b64 | ||
|
|
81775b0c13 | ||
|
|
ba1a318d09 | ||
|
|
0761d64254 | ||
|
|
67c3c6c809 | ||
|
|
04387268cd | ||
|
|
946fabb9a5 | ||
|
|
0a0c86d648 | ||
|
|
8b21fab8b8 | ||
|
|
16a0a3c56c | ||
|
|
d4c6b64ba6 | ||
|
|
b4089d72b3 | ||
|
|
01990ccec1 | ||
|
|
8aed88a31f | ||
|
|
4aa0780802 | ||
|
|
4e41246382 | ||
|
|
43fe9e5f7f | ||
|
|
c8d1994d3b | ||
|
|
cf0f4b47b4 | ||
|
|
24a8016710 | ||
|
|
20e1eee6ff | ||
|
|
c0432cd5f8 | ||
|
|
0ce0936a80 | ||
|
|
502c932f21 | ||
|
|
e60a66eeb7 | ||
|
|
4475cd0098 | ||
|
|
67c111a2b3 | ||
|
|
3bcaa3ea50 | ||
|
|
bed9a6f620 | ||
|
|
712b10e405 | ||
|
|
6cfcf46ba6 | ||
|
|
b1b9828514 | ||
|
|
7af7e1bdaf | ||
|
|
bd05fc7f0f | ||
|
|
17b5687db8 | ||
|
|
e7f48b6500 | ||
|
|
a5884d0f8c | ||
|
|
9576c6295e | ||
|
|
079e300d5d | ||
|
|
2c94316439 | ||
|
|
690b53e5a2 | ||
|
|
50c9adfdc7 | ||
|
|
696c7dede8 | ||
|
|
5967e7d6f3 | ||
|
|
4c66d72dc5 | ||
|
|
c43483a9f8 | ||
|
|
e02a34a527 | ||
|
|
713355ce0a | ||
|
|
12f8d0bbda | ||
|
|
8afe7f9b38 | ||
|
|
fbf84eb4cb | ||
|
|
e04093ad3f | ||
|
|
3e1d3a33ee | ||
|
|
e316d064ef | ||
|
|
0c289ec244 | ||
|
|
089f1b515d | ||
|
|
4c647ea8ce | ||
|
|
419404e273 | ||
|
|
837e542851 | ||
|
|
9378d15d71 | ||
|
|
0381e9bf0e | ||
|
|
3a70445e9a | ||
|
|
d2ed2c58fd | ||
|
|
9b201efa06 | ||
|
|
2b3a0b7c58 | ||
|
|
a187fb1095 | ||
|
|
6b44c11181 | ||
|
|
090153e53a | ||
|
|
a79a93d291 | ||
|
|
62f0f1bdbc | ||
|
|
f0acd8c7ed | ||
|
|
3908b0be71 | ||
|
|
05cc3be9d3 | ||
|
|
f4c83d348a | ||
|
|
61bd8dc388 | ||
|
|
002d6044b4 | ||
|
|
30196278d7 | ||
|
|
08c19c0714 | ||
|
|
d6c036e19a | ||
|
|
981bc0d494 | ||
|
|
857da1e900 | ||
|
|
66fc7227e6 | ||
|
|
3edfc57ba7 | ||
|
|
4a560ebc4e | ||
|
|
d4eb27e583 | ||
|
|
d1c0f90afd | ||
|
|
a1dadd1b1b | ||
|
|
2c28bb06db | ||
|
|
96a53c8754 | ||
|
|
fcc5d7dcc5 | ||
|
|
e383aacbeb | ||
|
|
5b776b2ae8 | ||
|
|
c4e3e460b1 | ||
|
|
a7dc1dc58b | ||
|
|
d01c737364 | ||
|
|
8d50757b51 | ||
|
|
f146cb2608 | ||
|
|
095d84ec7f | ||
|
|
f259c6728a | ||
|
|
a241a62136 | ||
|
|
4755c8a482 | ||
|
|
7672877299 | ||
|
|
92e8efb247 | ||
|
|
599269410b | ||
|
|
c5b5721b31 | ||
|
|
2bf2a68a3a | ||
|
|
b445392e9f | ||
|
|
bcc15d5240 | ||
|
|
d33bc8a42b | ||
|
|
df5bfeb67f | ||
|
|
b0e1f3f131 | ||
|
|
a19871366a | ||
|
|
b4b851c7a9 | ||
|
|
e6f6257434 | ||
|
|
469e57ba28 | ||
|
|
d06da22ae5 | ||
|
|
350df6adcf | ||
|
|
1788efaed5 | ||
|
|
d49bd4953c | ||
|
|
26f6e83328 | ||
|
|
79f6426125 | ||
|
|
9557d1ec64 | ||
|
|
7bab43df71 | ||
|
|
316b256ae0 | ||
|
|
bfabab96c5 | ||
|
|
bd9b0873a3 | ||
|
|
3464a802e2 | ||
|
|
6c95c462cb | ||
|
|
626fdba065 | ||
|
|
2152079b26 | ||
|
|
6559a97f43 | ||
|
|
05c2e53378 | ||
|
|
3df381a66c | ||
|
|
6fac76127d | ||
|
|
a1d9b34d93 | ||
|
|
c01ba6a906 | ||
|
|
4976948bc6 | ||
|
|
734c3fba65 | ||
|
|
457288b325 | ||
|
|
9220cf23c2 | ||
|
|
884b911767 | ||
|
|
e1fde05ba0 | ||
|
|
74572fe586 | ||
|
|
2eb40f8a1a | ||
|
|
ff3f930939 | ||
|
|
b3d805fe98 | ||
|
|
e2c778a934 | ||
|
|
34865b34be | ||
|
|
11d836713a | ||
|
|
f448257980 | ||
|
|
f9f507a115 | ||
|
|
6ddf978ba7 | ||
|
|
1fd47b517b | ||
|
|
13c71d2612 | ||
|
|
d0e41dc1d2 | ||
|
|
21679486ea | ||
|
|
7cd32b1116 | ||
|
|
e9e598616e | ||
|
|
bd40cd9357 | ||
|
|
eea9f4dec8 | ||
|
|
27e084bc9e | ||
|
|
3b1a0f52dd | ||
|
|
5cee65f8df | ||
|
|
5c1fe22fa0 | ||
|
|
8886629e02 | ||
|
|
e1979b51dd | ||
|
|
55598fbf1d | ||
|
|
90f13438db | ||
|
|
c454a0b453 | ||
|
|
a4a81447ab | ||
|
|
c4ff20facd | ||
|
|
8710176b2c | ||
|
|
10df07b473 | ||
|
|
cc6a732de7 | ||
|
|
839e9aa572 | ||
|
|
280f76510e | ||
|
|
02890ae9ae | ||
|
|
1517dd38cf | ||
|
|
871b015ce2 | ||
|
|
7d40bcfb53 | ||
|
|
aecca02269 | ||
|
|
d5f1a5f625 | ||
|
|
cdbfff4424 | ||
|
|
e640cba74f | ||
|
|
18bdb3abca | ||
|
|
8cba4118bf | ||
|
|
f8304f8f84 | ||
|
|
8ead70787c | ||
|
|
d7e2cd7692 | ||
|
|
9d3b64a54d | ||
|
|
35b50cba36 | ||
|
|
b6c94ddb07 | ||
|
|
bf1fe7fcfe | ||
|
|
f270c1f0b6 | ||
|
|
482c3fc474 | ||
|
|
d509a79576 | ||
|
|
a355a1d1d8 | ||
|
|
f11be9d288 | ||
|
|
dca09168c9 | ||
|
|
af170284c8 | ||
|
|
f7cdeca2e6 | ||
|
|
316a98dc15 | ||
|
|
7a4199e3f0 | ||
|
|
381a9662ea | ||
|
|
b15504e009 | ||
|
|
1ca9d96779 |
@@ -63,3 +63,9 @@ AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
|
||||
# Optional CA bundle path for Yahoo Finance when PHP has no system CA configured.
|
||||
YAHOO_FINANCE_CA_BUNDLE=
|
||||
|
||||
|
||||
ALPHA_VANTAGE_API_KEY=
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\AksesPasar;
|
||||
|
||||
enum PraktikFermentasi: string
|
||||
{
|
||||
case RUTIN_SENDIRI = 'Ya, rutin — dilakukan sendiri/individual';
|
||||
case RUTIN_KELOMPOK = 'Ya, rutin — bersama kelompok tani/kolektif';
|
||||
case PERNAH_SENDIRI = 'Pernah mencoba — sendiri';
|
||||
case PERNAH_KELOMPOK = 'Pernah mencoba — bersama kelompok';
|
||||
case BELUM_PERNAH = 'Belum pernah';
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return [
|
||||
['value' => self::RUTIN_SENDIRI->value, 'label' => 'Ya, rutin — dilakukan sendiri/individual'],
|
||||
['value' => self::RUTIN_KELOMPOK->value, 'label' => 'Ya, rutin — bersama kelompok tani/kolektif'],
|
||||
['value' => self::PERNAH_SENDIRI->value, 'label' => 'Pernah mencoba — sendiri'],
|
||||
['value' => self::PERNAH_KELOMPOK->value, 'label' => 'Pernah mencoba — bersama kelompok'],
|
||||
['value' => self::BELUM_PERNAH->value, 'label' => 'Belum pernah'],
|
||||
];
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\AksesPasar;
|
||||
|
||||
enum SaluranTerdahulu: string
|
||||
{
|
||||
case TENGKULAK = 'Tengkulak–pedagang lokal';
|
||||
case KOPERASI = 'Koperasi';
|
||||
case BUMDES = 'BUMDes';
|
||||
case LANGSUNG_PEMBELI = 'Langsung ke pembeli–eksportir';
|
||||
case LAINNYA = 'Lainnya';
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return [
|
||||
['value' => self::TENGKULAK->value, 'label' => 'Tengkulak–pedagang lokal'],
|
||||
['value' => self::KOPERASI->value, 'label' => 'Koperasi'],
|
||||
['value' => self::BUMDES->value, 'label' => 'BUMDes'],
|
||||
['value' => self::LANGSUNG_PEMBELI->value, 'label' => 'Langsung ke pembeli–eksportir'],
|
||||
['value' => self::LAINNYA->value, 'label' => 'Lainnya'],
|
||||
];
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\AksesPasar;
|
||||
|
||||
enum SkorKesadaranPremium: int
|
||||
{
|
||||
case BELUM_PERNAH_DENGAR = 1;
|
||||
case PERNAH_BELUM_PAHAM = 2;
|
||||
case PERNAH_SEDIKIT_PAHAM = 3;
|
||||
case SANGAT_PAHAM_BELUM_AKSES = 4;
|
||||
case SUDAH_AKSES_KONSISTEN = 5;
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return [
|
||||
['value' => self::BELUM_PERNAH_DENGAR->value, 'label' => 'Belum pernah dengar'],
|
||||
['value' => self::PERNAH_BELUM_PAHAM->value, 'label' => 'Pernah dengar tapi belum paham syarat'],
|
||||
['value' => self::PERNAH_SEDIKIT_PAHAM->value, 'label' => 'Pernah dengar & sedikit paham syarat'],
|
||||
['value' => self::SANGAT_PAHAM_BELUM_AKSES->value, 'label' => 'Sangat paham syarat tapi belum pernah akses'],
|
||||
['value' => self::SUDAH_AKSES_KONSISTEN->value, 'label' => 'Sudah akses & dapat harga premium konsisten'],
|
||||
];
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\AksesPasar;
|
||||
|
||||
enum SkorPengalaman: int
|
||||
{
|
||||
case BELUM_PERNAH = 1;
|
||||
case PERNAH_BERHENTI_TIDAK_ADA_AKSES = 2;
|
||||
case PERNAH_BERHENTI_MUNGKIN_KEMBALI = 3;
|
||||
case PERNAH_SESEKALI_JUAL = 4;
|
||||
case PERNAH_MASIH_AKTIF = 5;
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return [
|
||||
['value' => self::BELUM_PERNAH->value, 'label' => 'Belum pernah coba saluran lain'],
|
||||
['value' => self::PERNAH_BERHENTI_TIDAK_ADA_AKSES->value, 'label' => 'Pernah, sudah berhenti & tidak ada akses'],
|
||||
['value' => self::PERNAH_BERHENTI_MUNGKIN_KEMBALI->value, 'label' => 'Pernah, berhenti tapi masih mungkin kembali'],
|
||||
['value' => self::PERNAH_SESEKALI_JUAL->value, 'label' => 'Pernah & sesekali masih jual ke sana'],
|
||||
['value' => self::PERNAH_MASIH_AKTIF->value, 'label' => 'Pernah & masih punya akses aktif'],
|
||||
];
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\AksesPasar;
|
||||
|
||||
enum TingkatKepercayaanPembeli: int
|
||||
{
|
||||
case SANGAT_PERCAYA = 1;
|
||||
case CUKUP_PERCAYA = 2;
|
||||
case RAGU_RAGU = 3;
|
||||
case TIDAK_PERCAYA = 4;
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return [
|
||||
['value' => self::SANGAT_PERCAYA->value, 'label' => 'Sangat percaya, berani langsung coba'],
|
||||
['value' => self::CUKUP_PERCAYA->value, 'label' => 'Cukup percaya, tapi hati hati'],
|
||||
['value' => self::RAGU_RAGU->value, 'label' => 'Ragu ragu'],
|
||||
['value' => self::TIDAK_PERCAYA->value, 'label' => 'Tidak percaya, enggan mencoba'],
|
||||
];
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\Bumdes;
|
||||
|
||||
enum JabatanBumdes: string
|
||||
{
|
||||
case DIREKTUR = 'direktur';
|
||||
case DIREKTUR_KETUA = 'direktur_ketua';
|
||||
case SEKRETARIS = 'sekretaris';
|
||||
case BENDAHARA = 'bendahara';
|
||||
case KEPALA_UNIT_USAHA = 'kepala_unit_usaha';
|
||||
case PENGAWAS = 'pengawas';
|
||||
case PENASIHAT = 'penasihat';
|
||||
case ANGGOTA = 'anggota';
|
||||
case STAF_OPERASIONAL = 'staf_operasional';
|
||||
case LAINNYA = 'lainnya';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DIREKTUR => 'Direktur/Ketua',
|
||||
self::DIREKTUR_KETUA => 'Direktur/Ketua',
|
||||
self::SEKRETARIS => 'Sekretaris',
|
||||
self::BENDAHARA => 'Bendahara',
|
||||
self::KEPALA_UNIT_USAHA => 'Kepala Unit Usaha',
|
||||
self::PENGAWAS => 'Pengawas',
|
||||
self::PENASIHAT => 'Penasihat',
|
||||
self::ANGGOTA => 'Anggota',
|
||||
self::STAF_OPERASIONAL => 'Staf Operasional',
|
||||
self::LAINNYA => 'Lainnya',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect([
|
||||
self::DIREKTUR_KETUA,
|
||||
self::SEKRETARIS,
|
||||
self::BENDAHARA,
|
||||
self::LAINNYA,
|
||||
])->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum KeparahanSerangan: string
|
||||
{
|
||||
case RINGAN = 'ringan';
|
||||
case SEDANG = 'sedang';
|
||||
case BERAT = 'berat';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::RINGAN => 'Ringan, hanya beberapa tanaman',
|
||||
self::SEDANG => 'Sedang, sebagian tanaman terdampak',
|
||||
self::BERAT => 'Parah, sebagian besar tanaman terdampak',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,27 @@ namespace App\Enums;
|
||||
|
||||
enum KondisiTanaman: string
|
||||
{
|
||||
case PRODUKTIF = 'productive';
|
||||
case KURANG_PRODUKTIF = 'less_productive';
|
||||
case TIDAK_PRODUKTIF = 'not_productive';
|
||||
case SAKIT = 'sick';
|
||||
case MATI = 'dead';
|
||||
case BAIK = 'baik';
|
||||
case SEDANG = 'sedang';
|
||||
case BURUK = 'buruk';
|
||||
//case SAKIT= 'sakit';
|
||||
case MATI = 'mati';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::BAIK => 'Baik, tumbuh lebat, banyak buah',
|
||||
self::SEDANG => 'Sedang, cukup tumbuh, ada masalah',
|
||||
self::BURUK => 'Buruk, banyak tanaman tua dan lemah/tidak berbuah',
|
||||
self::MATI => 'Mati, tanaman telah mati, tidak dapat tumbuh maupun berbuah',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\Koperasi;
|
||||
|
||||
enum PosisiKoperasi: string
|
||||
{
|
||||
case PENGURUS = 'Pengurus koperasi';
|
||||
case ANGGOTA = 'Anggota koperasi';
|
||||
case PENDAMPING = 'Pendamping koperasi';
|
||||
}
|
||||
@@ -19,13 +19,13 @@ enum Pendidikan: string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_SEKOLAH => 'Tidak Sekolah',
|
||||
self::SD => 'SD atau Sederajat',
|
||||
self::SMP => 'SMP atau Sederajat',
|
||||
self::SMA => 'SMA atau Sederajat',
|
||||
self::SD => 'SD',
|
||||
self::SMP => 'SMP',
|
||||
self::SMA => 'SMA/SMK',
|
||||
self::DIPLOMA => 'Diploma 1-3 (D1-D3)',
|
||||
self::SARJANA => 'Sarjana (S1) atau sederajat',
|
||||
self::MAGISTER => 'Magister (S2) atau sederajat',
|
||||
self::DOKTOR => 'Doktor (S3) atau sederajat',
|
||||
self::SARJANA => 'Sarjana (S1)',
|
||||
self::MAGISTER => 'Magister (S2)',
|
||||
self::DOKTOR => 'Doktor (S3)',
|
||||
self::PESANTREN => 'Pesantren, Semiari, Wihara, atau Pendidikan Keagamaan Formal',
|
||||
self::LAINNYA => 'Lainnya',
|
||||
};
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PendidikanPelatihan;
|
||||
|
||||
enum PelatihanGAP: string
|
||||
{
|
||||
case PEMANGKASAN = 'Pemangkasan atau perawatan tanaman';
|
||||
case PEMUPUKAN = 'Pemupukan atau nutrisi tanah';
|
||||
case PENGENDALIAN = 'Pengendalian hama dan penyakit';
|
||||
case PRAKTIK = 'Praktik Berkebun yang Baik (GAP)';
|
||||
case PENGOLAHAN = 'Pengolahan/pascapanen';
|
||||
case PENYERBUKAN = 'Penyerbukan manual (Vanili)';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum PenyakitTanaman: string
|
||||
{
|
||||
case BUSUK_BUAH = 'busuk_buah';
|
||||
case DAUN_MENGUNING = 'daun_menguning';
|
||||
case DAUN_BERCAK = 'daun_bercak';
|
||||
case TANAMAN_LAYU = 'tanaman_layu';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::BUSUK_BUAH => 'Busuk Buah',
|
||||
self::DAUN_MENGUNING => 'Daun Menguning',
|
||||
self::DAUN_BERCAK => 'Daun Bercak',
|
||||
self::TANAMAN_LAYU => 'Tanaman Layu',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum Bulan: string
|
||||
{
|
||||
case JANUARI = 'Januari';
|
||||
case FEBRUARI = 'Februari';
|
||||
case MARET = 'Maret';
|
||||
case APRIL = 'April';
|
||||
case MEI = 'Mei';
|
||||
case JUNI = 'Juni';
|
||||
case JULI = 'Juli';
|
||||
case AGUSTUS = 'Agustus';
|
||||
case SEPTEMBER = 'September';
|
||||
case OKTOBER = 'Oktober';
|
||||
case NOVEMBER = 'November';
|
||||
case DESEMBER = 'Desember';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum CaraSortasi: string
|
||||
{
|
||||
case DIPILAH = 'Dipilah manual dengan tangan (memilih satu per satu buah/biji yang bagus dan membuang yang rusak)';
|
||||
case ALAT_BANTU = 'Menggunakan alat bantu sederhana (tampah, ayakan, atau bak untuk memisahkan kotoran ringan)';
|
||||
case PERENDAMAN = 'Metode perendaman/tenggelam (memisahkan buah mengapung dan tenggelam)';
|
||||
case GRADING_KRITERIA = 'Grading berdasarkan kriteria (ukuran, warna, atau tingkat kematangan)';
|
||||
case PEMBERSIHAN = 'Hanya pembersihan kotoran kasar (membuang dahan atau sampah besar)';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::DIPILAH => 'Dipilah manual dengan tangan (memilih satu per satu buah/biji yang bagus dan membuang yang rusak)',
|
||||
self::ALAT_BANTU => 'Menggunakan alat bantu sederhana (tampah, ayakan, atau bak untuk memisahkan kotoran ringan)',
|
||||
self::PERENDAMAN => 'Metode perendaman/tenggelam (memisahkan buah mengapung dan tenggelam)',
|
||||
self::GRADING_KRITERIA => 'Grading berdasarkan kriteria (ukuran, warna, atau tingkat kematangan)',
|
||||
self::PEMBERSIHAN => 'Hanya pembersihan kotoran kasar (membuang dahan atau sampah besar)',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum DasarPenentuanPanen: int
|
||||
{
|
||||
case KEBUTUHAN_UANG = 1;
|
||||
case UMUR_TANPA_KONDISI_BUAH = 2;
|
||||
case BUAH_JATUH = 3;
|
||||
case TINGKAT_KEPADATAN = 4;
|
||||
case WARNA_KULIT_BUAH = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::KEBUTUHAN_UANG => 'Kebutuhan uang mendesak, tanpa mempertimbangkan kematangan',
|
||||
self::UMUR_TANPA_KONDISI_BUAH => 'Umur/jadwal tetap, tanpa melihat kondisi buah langsung',
|
||||
self::BUAH_JATUH => 'Buah jatuh/matang pohon (sudah terlalu matang saat dipetik)',
|
||||
self::TINGKAT_KEPADATAN => 'Bersuara saat diketuk atau tingkat kepadatan buah',
|
||||
self::WARNA_KULIT_BUAH => 'Warna kulit buah (indikator paling akurat dan konsisten untuk menentukan kematangan optimal)',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum EstimasiKehilanganHasil: string
|
||||
{
|
||||
case TIDAK_ADA = 'Tidak ada kehilangan';
|
||||
case SEDIKIT = 'Sedikit, sekitar 25 % dari total panen';
|
||||
case LUMAYAN = 'Lumayan, sekitar 50% dari total panen';
|
||||
case BANYAK = 'Banyak, sekitar 75% dari total panen';
|
||||
case HAMPIR_SEMUA = 'Hampir semua rusak, lebih dari 75%';
|
||||
case TIDAK_TAHU = 'Hanya pembersihan kotoran kasar (membuang dahan atau sampah besar)';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_ADA => 'Tidak ada kehilangan',
|
||||
self::SEDIKIT => 'Sedikit, sekitar 25 % dari total panen',
|
||||
self::LUMAYAN => 'Lumayan, sekitar 50% dari total panen',
|
||||
self::BANYAK => 'Banyak, sekitar 75% dari total panen',
|
||||
self::HAMPIR_SEMUA => 'Hampir semua rusak, lebih dari 75%',
|
||||
self::TIDAK_TAHU => 'Tidak tahu/sulit memperkirakan',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum FrekuensiPemangkasanPendamping: string
|
||||
{
|
||||
case TIDAK_PERNAH = 'Tidak pernah memangkas sama sekali';
|
||||
case TIDAK_RUTIN = 'Memangkas, tapi tidak rutin dan tidak tahu tekniknya';
|
||||
case SATU_KALI_TAHUN = 'Memangkas 1 kali/tahun, tahu jenis tekniknya';
|
||||
case DUA_KALI_TAHUN = 'Memangkas 2 kali/tahun, tahu jenis tekniknya';
|
||||
case LEBIH_DUA_KALI_TAHUN = 'Memangkas lebih dari 2 kali/tahun dengan teknik yang tepat, dan pohon penaung juga dipangkas rutin';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_PERNAH => 'Tidak pernah memangkas sama sekali',
|
||||
self::TIDAK_RUTIN => 'Memangkas, tapi tidak rutin dan tidak tahu tekniknya',
|
||||
self::SATU_KALI_TAHUN => 'Memangkas 1 kali/tahun, tahu jenis tekniknya',
|
||||
self::DUA_KALI_TAHUN => 'Memangkas 2 kali/tahun, tahu jenis tekniknya',
|
||||
self::LEBIH_DUA_KALI_TAHUN => 'Memangkas lebih dari 2 kali/tahun dengan teknik yang tepat, dan pohon penaung juga dipangkas rutin',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum FrekuensiPemangkasanUtama: int
|
||||
{
|
||||
case TIDAK_PERNAH = 1;
|
||||
case TIDAK_RUTIN = 2;
|
||||
case SATU_KALI_TAHUN = 3;
|
||||
case DUA_KALI_TAHUN = 4;
|
||||
case LEBIH_DUA_KALI_TAHUN = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_PERNAH => 'Tidak pernah memangkas sama sekali',
|
||||
self::TIDAK_RUTIN => 'Memangkas, tapi tidak rutin dan tidak tahu tekniknya',
|
||||
self::SATU_KALI_TAHUN => 'Memangkas 1 kali/tahun, tahu jenis tekniknya',
|
||||
self::DUA_KALI_TAHUN => 'Memangkas 2 kali/tahun, tahu jenis tekniknya',
|
||||
self::LEBIH_DUA_KALI_TAHUN => 'Memangkas lebih dari 2 kali/tahun dengan teknik yang tepat, dan pohon penaung juga dipangkas rutin',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum FrekuensiSanitasiLahan: int
|
||||
{
|
||||
case TIDAK_PERNAH = 1;
|
||||
case SESEKALI = 2;
|
||||
case SETIAP_PANEN = 3;
|
||||
case RUTIN_TIDAK_TERJADWAL = 4;
|
||||
case RUTIN_TERJADWAL = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_PERNAH => 'Tidak pernah',
|
||||
self::SESEKALI => 'Sesekali, tidak terjadwal',
|
||||
self::SETIAP_PANEN => 'Setiap panen, tapi tidak menyeluruh',
|
||||
self::RUTIN_TIDAK_TERJADWAL => 'Rutin, tapi tanpa jadwal yang jelas',
|
||||
self::RUTIN_TERJADWAL => 'Rutin terjadwal dan menyeluruh',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum IntensitasSeranganHamaPenyakit: string
|
||||
{
|
||||
case RINGAN = 'Ringan - hanya beberapa tanaman terdampak';
|
||||
case SEDANG = 'Sedang - sebagian tanaman terdampak';
|
||||
case PARAH = 'Parah - sebagian besar tanaman terdampak';
|
||||
case BERVARIASI = 'Bervariasi - tergantung musim';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::RINGAN => 'Ringan - hanya beberapa tanaman terdampak',
|
||||
self::SEDANG => 'Sedang - sebagian tanaman terdampak',
|
||||
self::PARAH => 'Parah - sebagian besar tanaman terdampak',
|
||||
self::BERVARIASI => 'Bervariasi - tergantung musim',
|
||||
};
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => $case->value)->toArray();
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum JenisPupuk: string
|
||||
{
|
||||
case TIDAK_MEMBERI = 'Tidak memberi pupuk';
|
||||
case ORGANIK = 'Pupuk organik (kompos/kandang)';
|
||||
case KIMIA = 'Pupuk kimia';
|
||||
case KEDUANYA = 'Keduanya';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_MEMBERI => 'Tidak memberi pupuk',
|
||||
self::ORGANIK => 'Pupuk organik (kompos/kandang)',
|
||||
self::KIMIA => 'Pupuk kimia',
|
||||
self::KEDUANYA => 'Keduanya',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum KebutuhanAirPerMusim: string
|
||||
{
|
||||
case TIDAK_BUTUH = 'Tidak butuh, hujan cukup';
|
||||
case KURANG = 'Kurang, sering kekurangan air';
|
||||
case CUKUP = 'Cukup terpenuhi';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_BUTUH => 'Tidak butuh, hujan cukup',
|
||||
self::KURANG => 'Kurang, sering kekurangan air',
|
||||
self::CUKUP => 'Cukup terpenuhi',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum KondisiPengelolaanAir: int
|
||||
{
|
||||
case KURANG_TIDAK_ADA_UPAYA = 1;
|
||||
case KURANG_TIDAK_SUDAH_BERUPAYA = 2;
|
||||
case CUKUP_DARI_HUJAN = 3;
|
||||
case CUKUP_IRIGASI_PINJAM = 4;
|
||||
case CUKUP_IRIGASI_SENDIRI = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::KURANG_TIDAK_ADA_UPAYA => 'Kebutuhan air kurang terpenuhi, sering kekurangan air, tidak ada upaya mengatasinya',
|
||||
self::KURANG_TIDAK_SUDAH_BERUPAYA => 'Kebutuhan air kurang terpenuhi, sering kekurangan air, tapi sudah mencoba mengandalkan sumber lain (sumur/sungai) walau belum cukup',
|
||||
self::CUKUP_DARI_HUJAN => 'Kebutuhan air cukup terpenuhi hanya dari hujan, tanpa sistem irigasi tambahan',
|
||||
self::CUKUP_IRIGASI_PINJAM => 'Kebutuhan air cukup terpenuhi, ada sistem irigasi tambahan (sungai/mata air/sumur) tapi pinjam',
|
||||
self::CUKUP_IRIGASI_SENDIRI => 'Kebutuhan air cukup terpenuhi, punya akses irigasi sendiri (sungai/mata air/sumur) yang dikelola baik',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum MetodePenangananHamaPenyakit: int
|
||||
{
|
||||
case TIDAK_ADA = 1;
|
||||
case CARA_TRADISIONAL = 2;
|
||||
case PESTISIDA_SANITASI = 3;
|
||||
case KOMBINASI = 4;
|
||||
case PHT = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_ADA => 'Tidak ada penanganan',
|
||||
self::CARA_TRADISIONAL => 'Cara tradisional (doa/ritual)',
|
||||
self::PESTISIDA_SANITASI => 'Pestisida atau sanitasi',
|
||||
self::KOMBINASI => 'Kombinasi pestisida dan sanitasi',
|
||||
self::PHT => 'Pengendalian hama terpadu (PHT)',
|
||||
};
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => $case->value)->toArray();
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum PemahamanManfaatKonservasi: string
|
||||
{
|
||||
case YA_PAHAM = 'Ya, tahu manfaatnya';
|
||||
case TIDAK_PAHAM = 'Dilakukan tapi tidak tahu manfaatnya, kebiasaan turun-temurun';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::YA_PAHAM => 'Ya, tahu manfaatnya',
|
||||
self::TIDAK_PAHAM => 'Dilakukan tapi tidak tahu manfaatnya, kebiasaan turun-temurun',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum PemberianPupuk: int
|
||||
{
|
||||
case TIDAK_PERNAH = 1;
|
||||
case JENIS_DOSIS_WAKTU_TIDAK_MENENTU = 2;
|
||||
case JENIS_SESUAI_DOSIS_TIDAK_MENENTU = 3;
|
||||
case JENIS_DOSIS_SESUAI_WAKTU_CUKUP_TEPAT = 4;
|
||||
case JENIS_DOSIS_SESUAI_WAKTU_TEPAT = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_PERNAH => 'Tidak pernah memberi pupuk',
|
||||
self::JENIS_DOSIS_WAKTU_TIDAK_MENENTU => 'Memberi pupuk, tapi jenis/dosis tidak menentu, waktu sembarangan',
|
||||
self::JENIS_SESUAI_DOSIS_TIDAK_MENENTU => 'Memberi pupuk dengan jenis yang sesuai (organik/kimia/keduanya), tapi dosis atau waktu belum tepat',
|
||||
self::JENIS_DOSIS_SESUAI_WAKTU_CUKUP_TEPAT => 'Memberi pupuk dengan jenis dan dosis yang sesuai, waktu cukup tepat',
|
||||
self::JENIS_DOSIS_SESUAI_WAKTU_TEPAT => 'Memberi pupuk rutin dengan jenis tepat, dosis tepat, dan waktu tepat sesuai kebutuhan tanaman',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum PenangananGulma: int
|
||||
{
|
||||
case DIBIARKAN = 1;
|
||||
case DICABUT = 2;
|
||||
case DISEMPROT = 3;
|
||||
case RUTIN_DICABUT_TANPA_JADWAL = 4;
|
||||
case RUTIN_TERJADWAL = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::DIBIARKAN => 'Dibiarkan saja, tidak pernah ditangani',
|
||||
self::DICABUT => 'Dicabut/dibersihkan sesekali, tidak terjadwal',
|
||||
self::DISEMPROT => 'Disemprot herbisida sesekali, tidak terjadwal',
|
||||
self::RUTIN_DICABUT_TANPA_JADWAL => 'Rutin dicabut/dipangkas, tapi tanpa jadwal yang jelas',
|
||||
self::RUTIN_TERJADWAL => 'Rutin terjadwal dengan metode yang konsisten (dicabut/dipangkas/dikelola sebagai mulsa)',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum PenangananSisaBuahRanting: string
|
||||
{
|
||||
case DIBIARKAN = 'Dibiarkan di kebun';
|
||||
case DIKUMPULKAN = 'Dikumpulkan dan dibuang';
|
||||
case KOMPOS = 'Dijadikan kompos';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::DIBIARKAN => 'Dibiarkan di kebun',
|
||||
self::DIKUMPULKAN => 'Dikumpulkan dan dibuang',
|
||||
self::KOMPOS => 'Dijadikan kompos',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum PenyerbukanManual: string
|
||||
{
|
||||
case SELALU = 'Selalu, setiap musim berbunga';
|
||||
case KADANG_KADANG = 'Kadang-kadang, tergantung kondisi';
|
||||
case TIDAK_PERNAH = 'Tidak pernah';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::SELALU => 'Selalu, setiap musim berbunga',
|
||||
self::KADANG_KADANG => 'Kadang-kadang, tergantung kondisi',
|
||||
self::TIDAK_PERNAH => 'Tidak pernah',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum PraktikSortasi: int
|
||||
{
|
||||
case TIDAK_PERNAH = 1;
|
||||
case SANGAT_SEDERHANA = 2;
|
||||
case TIDAK_SETIAP_PANEN = 3;
|
||||
case SETIAP_PANEN = 4;
|
||||
case KETAT = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::TIDAK_PERNAH => 'Tidak pernah melakukan sortasi sama sekali',
|
||||
self::SANGAT_SEDERHANA => 'Sortasi sangat sederhana, hanya membuang yang jelas-jelas rusak/busuk',
|
||||
self::TIDAK_SETIAP_PANEN => 'Sortasi dilakukan tapi tidak setiap panen (kadang dilakukan, kadang tidak)',
|
||||
self::SETIAP_PANEN => 'Sortasi dilakukan setiap panen, tapi standarnya belum konsisten',
|
||||
self::KETAT => 'Sortasi ketat dengan standar yang jelas dan konsisten setiap panen',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum TenagaKerja: string
|
||||
{
|
||||
case DIKERJAKAN_SENDIRI = 'Dikerjakan Sendiri';
|
||||
case DIBANTU_ANGGOTA_KELUARGA = 'Dibantu Anggota Keluarga';
|
||||
case UPAH_TENAGA_KERJA = 'Upah Tenaga Kerja';
|
||||
case GOTONG_ROYONG = 'Gotong Royong/Swadaya Komunitas';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::DIKERJAKAN_SENDIRI => 'Dikerjakan Sendiri',
|
||||
self::DIBANTU_ANGGOTA_KELUARGA => 'Dibantu Anggota Keluarga',
|
||||
self::UPAH_TENAGA_KERJA => 'Upah Tenaga Kerja',
|
||||
self::GOTONG_ROYONG => 'Gotong Royong/Swadaya Komunitas',
|
||||
};
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => $case->value)->toArray();
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum TindakanPanenReject: string
|
||||
{
|
||||
case BUANG = 'Dibuang';
|
||||
case JUAL = 'Dijual ke tempat lain';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::BUANG => 'Dibuang',
|
||||
self::JUAL => 'Dijual ke tempat lain',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum TingkatPanenReject: int
|
||||
{
|
||||
case SERING = 1;
|
||||
case CUKUP_SERING = 2;
|
||||
case KADANG = 3;
|
||||
case JARANG = 4;
|
||||
case TIDAK_ADA = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::SERING => 'Sering ditolak, lebih dari 50% hasil panen biasanya ditolak/tidak laku karena mutu',
|
||||
self::CUKUP_SERING => 'Cukup sering, sekitar 25–50% hasil panen ditolak/tidak laku',
|
||||
self::KADANG => 'Kadang ditolak, sekitar 10–25% hasil panen',
|
||||
self::JARANG => 'Jarang ditolak, kurang dari 10% hasil panen',
|
||||
self::TIDAK_ADA => 'Tidak ada yang ditolak, semua hasil panen sesuai standar pasar utama',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PraktikBudidaya;
|
||||
|
||||
enum WaktuKemunculanTerparahHamaPenyakit: string
|
||||
{
|
||||
case HUJAN = 'Musim hujan';
|
||||
case KEMARAU = 'Musim kemarau';
|
||||
case SEPANJANG_TAHUN = 'Sepanjang tahun';
|
||||
case TIDAK_TENTU = 'Tidak tentu';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::HUJAN => 'Musim hujan',
|
||||
self::KEMARAU => 'Musim kemarau',
|
||||
self::SEPANJANG_TAHUN => 'Sepanjang tahun',
|
||||
self::TIDAK_TENTU => 'Tidak tentu',
|
||||
};
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => $case->value)->toArray();
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum SeranganHama: string
|
||||
{
|
||||
case ULAT = 'ulat';
|
||||
case BELALANG = 'belalang';
|
||||
case KUTU = 'kutu';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::ULAT => 'Ulat',
|
||||
self::BELALANG => 'Belalang',
|
||||
self::KUTU => 'Kutu',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum AlasanKreditDitolak: string
|
||||
{
|
||||
case TIDAK_PUNYA_JAMINAN_AGUNAN = 'tidak_punya_jaminan_agunan';
|
||||
case PROSES_TERLALU_RUMIT = 'proses_terlalu_rumit';
|
||||
case TAKUT_TIDAK_BISA_BAYAR = 'takut_tidak_bisa_bayar';
|
||||
case TIDAK_TAHU_CARANYA = 'tidak_tahu_caranya';
|
||||
case LAINNYA = 'lainnya';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_PUNYA_JAMINAN_AGUNAN => 'Tidak punya jaminan-agunan',
|
||||
self::PROSES_TERLALU_RUMIT => 'Proses terlalu rumit',
|
||||
self::TAKUT_TIDAK_BISA_BAYAR => 'Takut tidak bisa bayar',
|
||||
self::TIDAK_TAHU_CARANYA => 'Tidak tahu caranya',
|
||||
self::LAINNYA => 'Lainnya',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum BisaBeliPupukBersubsidi: string
|
||||
{
|
||||
case YA = 'ya';
|
||||
case TIDAK = 'tidak';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::YA => 'Ya',
|
||||
self::TIDAK => 'Tidak',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum JenisAsetProduktif: string
|
||||
{
|
||||
case TERNAK = 'ternak';
|
||||
case KENDARAAN = 'kendaraan';
|
||||
case ALAT_PERTANIAN = 'alat_pertanian';
|
||||
case LAINNYA = 'lainnya';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TERNAK => 'Ternak',
|
||||
self::KENDARAAN => 'Kendaraan',
|
||||
self::ALAT_PERTANIAN => 'Alat pertanian',
|
||||
self::LAINNYA => 'Lainnya',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KategoriPendapatanKomoditas: string
|
||||
{
|
||||
case UTAMA = 'utama';
|
||||
case LAINNYA = 'lainnya';
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KeaktifanPertemuanKelompok: int
|
||||
{
|
||||
case TIDAK_PERNAH_HADIR = 1;
|
||||
case JARANG_HADIR = 2;
|
||||
case SERING_HADIR_LEBIH_BANYAK_DIAM = 3;
|
||||
case HAMPIR_SELALU_HADIR_KADANG_DISKUSI = 4;
|
||||
case SELALU_HADIR_AKTIF_DISKUSI = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_PERNAH_HADIR => 'Tidak pernah hadir',
|
||||
self::JARANG_HADIR => 'Jarang hadir',
|
||||
self::SERING_HADIR_LEBIH_BANYAK_DIAM => 'Sering hadir tapi lebih banyak diam',
|
||||
self::HAMPIR_SELALU_HADIR_KADANG_DISKUSI => 'Hampir selalu hadir & kadang diskusi',
|
||||
self::SELALU_HADIR_AKTIF_DISKUSI => 'Selalu hadir & aktif diskusi',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KebebasanMemilihPembeli: int
|
||||
{
|
||||
case TIDAK_BEBAS_TERIKAT_SATU_PEMBELI = 1;
|
||||
case AGAK_TERIKAT_ADA_TEKANAN = 2;
|
||||
case AGAK_BEBAS_CENDERUNG_PEMBELI_SAMA = 3;
|
||||
case CUKUP_BEBAS_SESEKALI_PINDAH = 4;
|
||||
case SANGAT_BEBAS_PINDAH_KAPAN_SAJA = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_BEBAS_TERIKAT_SATU_PEMBELI => 'Tidak bebas, terikat satu pembeli',
|
||||
self::AGAK_TERIKAT_ADA_TEKANAN => 'Agak terikat, ada tekanan',
|
||||
self::AGAK_BEBAS_CENDERUNG_PEMBELI_SAMA => 'Agak bebas, cenderung pembeli sama',
|
||||
self::CUKUP_BEBAS_SESEKALI_PINDAH => 'Cukup bebas, sesekali pindah',
|
||||
self::SANGAT_BEBAS_PINDAH_KAPAN_SAJA => 'Sangat bebas, pindah kapan saja',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KedekatanSesamaAnggota: string
|
||||
{
|
||||
case SANGAT_DEKAT = 'sangat_dekat';
|
||||
case CUKUP_DEKAT = 'cukup_dekat';
|
||||
case SEBATAS_KENAL = 'sebatas_kenal';
|
||||
case TIDAK_BEGITU_KENAL = 'tidak_begitu_kenal';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SANGAT_DEKAT => 'Sangat dekat',
|
||||
self::CUKUP_DEKAT => 'Cukup dekat',
|
||||
self::SEBATAS_KENAL => 'Sebatas kenal',
|
||||
self::TIDAK_BEGITU_KENAL => 'Tidak begitu kenal',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KemauanIkutProgram: int
|
||||
{
|
||||
case TIDAK_MAU = 1;
|
||||
case RAGU_RAGU = 2;
|
||||
case MAU_PERLU_DIPASTIKAN_MANFAAT = 3;
|
||||
case MAU_LIHAT_PROGRAM_DULU = 4;
|
||||
case MAU_LANGSUNG_IKUT = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_MAU => 'Tidak mau',
|
||||
self::RAGU_RAGU => 'Ragu-ragu',
|
||||
self::MAU_PERLU_DIPASTIKAN_MANFAAT => 'Mau, perlu dipastikan manfaatnya',
|
||||
self::MAU_LIHAT_PROGRAM_DULU => 'Mau, ingin lihat programnya dulu',
|
||||
self::MAU_LANGSUNG_IKUT => 'Mau, langsung ikut',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KemauanMencobaPraktikBaru: int
|
||||
{
|
||||
case TIDAK_MAU = 1;
|
||||
case RAGU_RAGU = 2;
|
||||
case MAU_LIHAT_HASIL_DULU = 3;
|
||||
case MAU_LANGSUNG_COBA = 4;
|
||||
case MAU_COBA_SAMPAI_BERHASIL = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_MAU => 'Tidak mau',
|
||||
self::RAGU_RAGU => 'Ragu-ragu',
|
||||
self::MAU_LIHAT_HASIL_DULU => 'Mau, lihat hasil dulu',
|
||||
self::MAU_LANGSUNG_COBA => 'Mau langsung coba',
|
||||
self::MAU_COBA_SAMPAI_BERHASIL => 'Mau coba sampai berhasil',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KeterikatanHutangPanen: int
|
||||
{
|
||||
case TIDAK_BERSEDIA_MENJAWAB = 0;
|
||||
case HUTANG_BESAR_HAMPIR_SELURUH_PANEN_TERIKAT = 1;
|
||||
case HUTANG_LEBIH_DARI_SEPARUH_PANEN_TERIKAT = 2;
|
||||
case HUTANG_SEBAGIAN_KECIL_TERIKAT = 3;
|
||||
case HUTANG_KECIL_TIDAK_MENGIKAT_PANEN = 4;
|
||||
case TIDAK_ADA = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_BERSEDIA_MENJAWAB => 'Tidak bersedia menjawab',
|
||||
self::HUTANG_BESAR_HAMPIR_SELURUH_PANEN_TERIKAT => 'Ada hutang besar, hampir seluruh panen terikat',
|
||||
self::HUTANG_LEBIH_DARI_SEPARUH_PANEN_TERIKAT => 'Ada hutang, >separuh panen terikat',
|
||||
self::HUTANG_SEBAGIAN_KECIL_TERIKAT => 'Ada hutang, sebagian kecil terikat',
|
||||
self::HUTANG_KECIL_TIDAK_MENGIKAT_PANEN => 'Ada hutang kecil, tidak mengikat panen',
|
||||
self::TIDAK_ADA => 'Tidak ada',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KeterlibatanProgramKeuanganFormal: int
|
||||
{
|
||||
case TIDAK_PERNAH_MENERIMA = 1;
|
||||
case PERNAH_SATU_TIDAK_BERMANFAAT = 2;
|
||||
case SEDANG_MENERIMA_SATU = 3;
|
||||
case SEDANG_MENERIMA_LEBIH_DARI_SATU = 4;
|
||||
case AKTIF_BEBERAPA_PROGRAM_BERMANFAAT = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_PERNAH_MENERIMA => 'Tidak pernah menerima',
|
||||
self::PERNAH_SATU_TIDAK_BERMANFAAT => 'Pernah 1 program, tidak lagi & tidak bermanfaat',
|
||||
self::SEDANG_MENERIMA_SATU => 'Sedang menerima 1 program',
|
||||
self::SEDANG_MENERIMA_LEBIH_DARI_SATU => 'Sedang menerima >1 program',
|
||||
self::AKTIF_BEBERAPA_PROGRAM_BERMANFAAT => 'Aktif beberapa program & merasakan manfaat nyata',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum KondisiAsetProduktif: int
|
||||
{
|
||||
case TIDAK_ADA = 1;
|
||||
case ADA_SATU_KURANG_BAIK = 2;
|
||||
case ADA_SATU_BAIK = 3;
|
||||
case ADA_DUA_LEBIH_SEBAGIAN_KURANG_BAIK = 4;
|
||||
case ADA_DUA_LEBIH_SEMUA_BAIK = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_ADA => 'Tidak ada',
|
||||
self::ADA_SATU_KURANG_BAIK => 'Ada 1 jenis, kondisi kurang baik',
|
||||
self::ADA_SATU_BAIK => 'Ada 1 jenis, kondisi baik',
|
||||
self::ADA_DUA_LEBIH_SEBAGIAN_KURANG_BAIK => 'Ada 2+ jenis, sebagian kurang baik',
|
||||
self::ADA_DUA_LEBIH_SEMUA_BAIK => 'Ada 2+ jenis, semua kondisi baik',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum ManfaatKelompokTani: int
|
||||
{
|
||||
case TIDAK_ADA_MANFAAT = 1;
|
||||
case MANFAAT_SOSIAL_SAJA = 2;
|
||||
case SEDIKIT_MANFAAT_PRODUKSI_PEMASARAN = 3;
|
||||
case MANFAAT_CUKUP_TERASA = 4;
|
||||
case MANFAAT_NYATA_SIGNIFIKAN = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_ADA_MANFAAT => 'Tidak ada manfaat',
|
||||
self::MANFAAT_SOSIAL_SAJA => 'Manfaat sosial saja',
|
||||
self::SEDIKIT_MANFAAT_PRODUKSI_PEMASARAN => 'Sedikit manfaat produksi-pemasaran',
|
||||
self::MANFAAT_CUKUP_TERASA => 'Manfaat cukup terasa',
|
||||
self::MANFAAT_NYATA_SIGNIFIKAN => 'Manfaat nyata & signifikan',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum MinatPembeliHargaStabil: string
|
||||
{
|
||||
case MAU_HARGA_STABIL_LEBIH_PENTING = 'mau_harga_stabil_lebih_penting';
|
||||
case MAU_TAPI_INGIN_BANDINGKAN_DULU = 'mau_tapi_ingin_bandingkan_dulu';
|
||||
case RAGU_RAGU = 'ragu_ragu';
|
||||
case TIDAK_MAU_CARI_HARGA_TERBAIK = 'tidak_mau_cari_harga_terbaik';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::MAU_HARGA_STABIL_LEBIH_PENTING => 'Mau-harga stabil lebih penting',
|
||||
self::MAU_TAPI_INGIN_BANDINGKAN_DULU => 'Mau tapi ingin bandingkan dulu',
|
||||
self::RAGU_RAGU => 'Ragu-ragu',
|
||||
self::TIDAK_MAU_CARI_HARGA_TERBAIK => 'Tidak mau-cari harga terbaik tiap jual',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum OrientasiRencanaJangkaPanjang: int
|
||||
{
|
||||
case BELUM_KEPIKIRAN = 1;
|
||||
case INGIN_TETAP_SEPERTI_SEKARANG = 2;
|
||||
case INGIN_BERUBAH_BELUM_TAHU_CARANYA = 3;
|
||||
case INGIN_SUDAH_MULAI_DIPIKIRKAN = 4;
|
||||
case PUNYA_RENCANA_KONKRET = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::BELUM_KEPIKIRAN => 'Belum kepikiran',
|
||||
self::INGIN_TETAP_SEPERTI_SEKARANG => 'Ingin tetap seperti sekarang',
|
||||
self::INGIN_BERUBAH_BELUM_TAHU_CARANYA => 'Ada keinginan berubah tapi belum tahu caranya',
|
||||
self::INGIN_SUDAH_MULAI_DIPIKIRKAN => 'Ada keinginan & sudah mulai dipikirkan',
|
||||
self::PUNYA_RENCANA_KONKRET => 'Sudah punya rencana konkret',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PanutanPetaniSukses: int
|
||||
{
|
||||
case TIDAK_ADA = 1;
|
||||
case ADA_DENGAR_DARI_ORANG_LAIN = 2;
|
||||
case TAHU_SIAPA_TIDAK_KENAL = 3;
|
||||
case KENAL_BELUM_DISKUSI = 4;
|
||||
case KENAL_PERNAH_DISKUSI_LANGSUNG = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_ADA => 'Tidak ada',
|
||||
self::ADA_DENGAR_DARI_ORANG_LAIN => 'Ada, dengar dari orang lain saja',
|
||||
self::TAHU_SIAPA_TIDAK_KENAL => 'Tahu siapa, tapi tidak kenal',
|
||||
self::KENAL_BELUM_DISKUSI => 'Kenal, belum pernah diskusi',
|
||||
self::KENAL_PERNAH_DISKUSI_LANGSUNG => 'Kenal & pernah diskusi langsung',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PemahamanMutuHarga: int
|
||||
{
|
||||
case TIDAK_TAHU = 1;
|
||||
case PERNAH_DENGAR_TIDAK_YAKIN = 2;
|
||||
case TAHU_BEDA_BELUM_BUKTIKAN = 3;
|
||||
case TAHU_PERNAH_HARGA_LEBIH_TINGGI = 4;
|
||||
case TAHU_BETUL_BISA_JELASKAN_RINCI = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_TAHU => 'Tidak tahu',
|
||||
self::PERNAH_DENGAR_TIDAK_YAKIN => 'Pernah dengar, tidak yakin',
|
||||
self::TAHU_BEDA_BELUM_BUKTIKAN => 'Tahu ada beda, belum buktikan',
|
||||
self::TAHU_PERNAH_HARGA_LEBIH_TINGGI => 'Tahu & pernah dapat harga lebih tinggi',
|
||||
self::TAHU_BETUL_BISA_JELASKAN_RINCI => 'Tahu betul & bisa jelaskan rinci',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PengalamanKreditKebun: int
|
||||
{
|
||||
case TIDAK_PERNAH_MENCOBA = 1;
|
||||
case PERNAH_COBA_DITOLAK = 2;
|
||||
case SEDANG_PROSES = 3;
|
||||
case BERHASIL_MASIH_PELUNASAN = 4;
|
||||
case BERHASIL_SUDAH_LUNAS = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_PERNAH_MENCOBA => 'Tidak pernah mencoba',
|
||||
self::PERNAH_COBA_DITOLAK => 'Pernah coba tapi ditolak',
|
||||
self::SEDANG_PROSES => 'Sedang dalam proses',
|
||||
self::BERHASIL_MASIH_PELUNASAN => 'Berhasil, masih proses pelunasan',
|
||||
self::BERHASIL_SUDAH_LUNAS => 'Berhasil & sudah lunas',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PengetahuanHargaHasilOlah: string
|
||||
{
|
||||
case TIDAK_TAHU = 'tidak_tahu';
|
||||
case PERNAH_DENGAR_TIDAK_TAHU_PENGARUH = 'pernah_dengar_tidak_tahu_pengaruh';
|
||||
case TAHU_BEDA_HARGA_BELUM_COBA = 'tahu_beda_harga_belum_coba';
|
||||
case PERNAH_JUAL_HASIL_OLAH_HARGA_LEBIH_TINGGI = 'pernah_jual_hasil_olah_harga_lebih_tinggi';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_TAHU => 'Tidak tahu',
|
||||
self::PERNAH_DENGAR_TIDAK_TAHU_PENGARUH => 'Pernah dengar tapi tidak tahu pengaruh ke harga',
|
||||
self::TAHU_BEDA_HARGA_BELUM_COBA => 'Tahu ada beda harga tapi belum coba',
|
||||
self::PERNAH_JUAL_HASIL_OLAH_HARGA_LEBIH_TINGGI => 'Sudah pernah jual hasil olah dengan harga lebih tinggi',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PeranDalamKelompok: int
|
||||
{
|
||||
case ANGGOTA_PASIF = 1;
|
||||
case ANGGOTA_BIASA_KADANG_DILIBATKAN = 2;
|
||||
case ANGGOTA_BIASA_CUKUP_AKTIF = 3;
|
||||
case PENGURUS_BELUM_BANYAK_TANGGUNG_JAWAB = 4;
|
||||
case KETUA_PENGURUS_AKTIF = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::ANGGOTA_PASIF => 'Anggota pasif',
|
||||
self::ANGGOTA_BIASA_KADANG_DILIBATKAN => 'Anggota biasa, kadang dilibatkan',
|
||||
self::ANGGOTA_BIASA_CUKUP_AKTIF => 'Anggota biasa, cukup aktif',
|
||||
self::PENGURUS_BELUM_BANYAK_TANGGUNG_JAWAB => 'Pengurus, belum banyak menjalankan tanggung jawab',
|
||||
self::KETUA_PENGURUS_AKTIF => 'Ketua-pengurus aktif & menjalankan tanggung jawab nyata',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PeriodePendapatan: string
|
||||
{
|
||||
case MUSIM = 'musim';
|
||||
case TAHUN = 'tahun';
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PernahBantuanNgoPerusahaan: string
|
||||
{
|
||||
case PERNAH = 'pernah';
|
||||
case TIDAK_PERNAH = 'tidak_pernah';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::PERNAH => 'Pernah',
|
||||
self::TIDAK_PERNAH => 'Tidak pernah',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PernahJualHargaLebihTinggi: string
|
||||
{
|
||||
case BELUM_PERNAH = 'belum_pernah';
|
||||
case PERNAH = 'pernah';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::BELUM_PERNAH => 'Belum pernah',
|
||||
self::PERNAH => 'Pernah',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PihakMembantuKonflik: string
|
||||
{
|
||||
case TIDAK_ADA_SELESAIKAN_SENDIRI = 'Tidak ada-selesaikan sendiri';
|
||||
case ADA = 'Ada';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PinjamanTokohAdatPanen: string
|
||||
{
|
||||
case TIDAK_ADA = 'tidak_ada';
|
||||
case ADA = 'ada';
|
||||
case TIDAK_BERSEDIA_MENJAWAB = 'tidak_bersedia_menjawab';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_ADA => 'Tidak ada',
|
||||
self::ADA => 'Ada',
|
||||
self::TIDAK_BERSEDIA_MENJAWAB => 'Tidak bersedia menjawab',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum PraktikIjon: int
|
||||
{
|
||||
case TIDAK_BERSEDIA_MENJAWAB = 0;
|
||||
case HAMPIR_SELURUH_PANEN_TERIKAT = 1;
|
||||
case SEBAGIAN_BESAR_TERIKAT = 2;
|
||||
case SESEKALI_SEBAGIAN_KECIL = 3;
|
||||
case PERNAH_SUDAH_LAMA_TIDAK_LAGI = 4;
|
||||
case TIDAK_PERNAH = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_BERSEDIA_MENJAWAB => 'Tidak bersedia menjawab',
|
||||
self::HAMPIR_SELURUH_PANEN_TERIKAT => 'Hampir seluruh panen terikat ijon',
|
||||
self::SEBAGIAN_BESAR_TERIKAT => 'Sebagian besar terikat',
|
||||
self::SESEKALI_SEBAGIAN_KECIL => 'Sesekali-sebagian kecil',
|
||||
self::PERNAH_SUDAH_LAMA_TIDAK_LAGI => 'Pernah, sudah lama tidak lagi',
|
||||
self::TIDAK_PERNAH => 'Tidak pernah',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum SkorKecukupanPenghasilan: int
|
||||
{
|
||||
case SANGAT_TIDAK_CUKUP = 1;
|
||||
case KURANG_SERING_BERHUTANG = 2;
|
||||
case CUKUP_PAS_PASAN = 3;
|
||||
case CUKUP_ADA_SISA = 4;
|
||||
case LEBIH_DARI_CUKUP = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SANGAT_TIDAK_CUKUP => 'Sangat tidak cukup',
|
||||
self::KURANG_SERING_BERHUTANG => 'Kurang, sering berhutang',
|
||||
self::CUKUP_PAS_PASAN => 'Cukup pas-pasan',
|
||||
self::CUKUP_ADA_SISA => 'Cukup, kadang ada sisa',
|
||||
self::LEBIH_DARI_CUKUP => 'Lebih dari cukup',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum SkorKejelasanStatusLahan: int
|
||||
{
|
||||
case TIDAK_ADA_DOKUMEN_ADA_SENGKETA = 1;
|
||||
case ADA_DOKUMEN_MASIH_SENGKETA = 2;
|
||||
case PERNAH_SENGKETA_SELESAI = 3;
|
||||
case LAHAN_ADAT_TANPA_SENGKETA = 4;
|
||||
case BERSERTIFIKAT_TANPA_SENGKETA = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_ADA_DOKUMEN_ADA_SENGKETA => 'Tidak ada dokumen & ada sengketa',
|
||||
self::ADA_DOKUMEN_MASIH_SENGKETA => 'Ada dokumen tapi masih sengketa',
|
||||
self::PERNAH_SENGKETA_SELESAI => 'Pernah sengketa, sudah selesai',
|
||||
self::LAHAN_ADAT_TANPA_SENGKETA => 'Lahan adat/keluarga/perhutanan sosial tanpa sengketa',
|
||||
self::BERSERTIFIKAT_TANPA_SENGKETA => 'Bersertifikat & tidak ada sengketa',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum SkorKemampuanMenabung: int
|
||||
{
|
||||
case TIDAK_BISA = 1;
|
||||
case PERNAH_TERPAKAI = 2;
|
||||
case KADANG_KADANG = 3;
|
||||
case BISA_TIDAK_TETAP = 4;
|
||||
case RUTIN_TETAP = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_BISA => 'Tidak bisa sama sekali',
|
||||
self::PERNAH_TERPAKAI => 'Pernah tapi selalu terpakai',
|
||||
self::KADANG_KADANG => 'Kadang-kadang',
|
||||
self::BISA_TIDAK_TETAP => 'Bisa tapi tidak tetap',
|
||||
self::RUTIN_TETAP => 'Rutin & jumlah tetap',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum SkorPeriodePaceklik: int
|
||||
{
|
||||
case LEBIH_DARI_EMPAT_BULAN = 1;
|
||||
case TIGA_SAMPAI_EMPAT_BULAN = 2;
|
||||
case SATU_SAMPAI_DUA_BULAN = 3;
|
||||
case SEBENTAR_TIDAK_MENENTU = 4;
|
||||
case TIDAK_ADA_STABIL = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::LEBIH_DARI_EMPAT_BULAN => '>4 bulan',
|
||||
self::TIGA_SAMPAI_EMPAT_BULAN => '3-4 bulan',
|
||||
self::SATU_SAMPAI_DUA_BULAN => '1-2 bulan',
|
||||
self::SEBENTAR_TIDAK_MENENTU => 'Sebentar & tidak menentu',
|
||||
self::TIDAK_ADA_STABIL => 'Tidak ada, stabil',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum StatusKartuTani: string
|
||||
{
|
||||
case BELUM_PUNYA = 'belum_punya';
|
||||
case SUDAH_PUNYA_BELUM_AKTIF = 'sudah_punya_belum_aktif';
|
||||
case SUDAH_PUNYA_AKTIF_DIGUNAKAN = 'sudah_punya_aktif_digunakan';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::BELUM_PUNYA => 'Belum punya',
|
||||
self::SUDAH_PUNYA_BELUM_AKTIF => 'Sudah punya tapi belum aktif',
|
||||
self::SUDAH_PUNYA_AKTIF_DIGUNAKAN => 'Sudah punya & aktif digunakan',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum StatusKepemilikanLahanSosialEkonomi: string
|
||||
{
|
||||
case MILIK_PRIBADI = 'Milik pribadi';
|
||||
case MILIK_ORANG_TUA_KELUARGA = 'Milik orang tua-keluarga';
|
||||
case SEWA_BAGI_HASIL = 'Sewa-bagi hasil';
|
||||
case LAHAN_ADAT = 'Lahan adat';
|
||||
case PERHUTANAN_SOSIAL = 'Perhutanan sosial';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum StatusKonflik: string
|
||||
{
|
||||
case SUDAH_SELESAI = 'Sudah selesai';
|
||||
case BELUM_MASIH_BERLANJUT = 'Belum, masih berlanjut';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum StatusProgramKeuanganFormal: string
|
||||
{
|
||||
case SEDANG_MENERIMA = 'sedang_menerima';
|
||||
case PERNAH_TAPI_TIDAK_LAGI = 'pernah_tapi_tidak_lagi';
|
||||
case BELUM_PERNAH = 'belum_pernah';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SEDANG_MENERIMA => 'Sedang Menerima',
|
||||
self::PERNAH_TAPI_TIDAK_LAGI => 'Pernah tapi Tidak Lagi',
|
||||
self::BELUM_PERNAH => 'Belum Pernah',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum StatusRekeningTabungan: int
|
||||
{
|
||||
case TIDAK_PUNYA_REKENING = 1;
|
||||
case PUNYA_TIDAK_AKTIF = 2;
|
||||
case PUNYA_KADANG_DIGUNAKAN = 3;
|
||||
case PUNYA_CUKUP_RUTIN = 4;
|
||||
case AKTIF_RUTIN_DIGUNAKAN = 5;
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_PUNYA_REKENING => 'Tidak punya rekening',
|
||||
self::PUNYA_TIDAK_AKTIF => 'Punya tapi tidak aktif',
|
||||
self::PUNYA_KADANG_DIGUNAKAN => 'Punya, kadang digunakan',
|
||||
self::PUNYA_CUKUP_RUTIN => 'Punya, cukup rutin',
|
||||
self::AKTIF_RUTIN_DIGUNAKAN => 'Aktif & rutin digunakan',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum TekananJualSegera: string
|
||||
{
|
||||
case TIDAK_ADA = 'tidak_ada';
|
||||
case ADA = 'ada';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::TIDAK_ADA => 'Tidak ada',
|
||||
self::ADA => 'Ada',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum TerdaftarKelompokTani: string
|
||||
{
|
||||
case YA = 'ya';
|
||||
case TIDAK = 'tidak';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::YA => 'Ya',
|
||||
self::TIDAK => 'Tidak',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\SosialEkonomi;
|
||||
|
||||
enum UsahaMutuTambahanHarga: string
|
||||
{
|
||||
case SEBANDING_COCOK_DICOBA = 'sebanding_cocok_dicoba';
|
||||
case TIDAK_YAKIN = 'tidak_yakin';
|
||||
case TIDAK_SEBANDING_TERLALU_BANYAK_USAHA = 'tidak_sebanding_terlalu_banyak_usaha';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SEBANDING_COCOK_DICOBA => 'Sebanding-cocok dicoba',
|
||||
self::TIDAK_YAKIN => 'Tidak yakin',
|
||||
self::TIDAK_SEBANDING_TERLALU_BANYAK_USAHA => 'Tidak sebanding-terlalu banyak usaha',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Wilayah\DesaKelurahan;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use App\Http\Resources\Wilayah\DesaKelurahanResource;
|
||||
use App\Http\Resources\Wilayah\DesaKelurahanCollectionResource;
|
||||
|
||||
class DesaKelurahanController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$size = $request->integer('size') ?: 10;
|
||||
|
||||
$master = DesaKelurahan::with('kecamatan')
|
||||
->when($request->search, function ($q, $search) {
|
||||
$search = strtolower($search);
|
||||
$q->where(function ($query) use ($search) {
|
||||
$query->whereRaw('lower(kode) like ?', ["%{$search}%"])
|
||||
->orWhereRaw('lower(nama) like ?', ["%{$search}%"]);
|
||||
});
|
||||
})
|
||||
->when($request->kecamatan_id, fn($q,$v) => $q->where('kecamatan_id',$v))
|
||||
->when($request->kabupaten_kota_id, fn ($q, $v) =>
|
||||
$q->whereHas('kecamatan', fn ($k) =>
|
||||
$k->where('kabupaten_kota_id', $v)
|
||||
)
|
||||
)
|
||||
->when($request->provinsi_id, fn ($q, $v) =>
|
||||
$q->whereHas('kecamatan.kabupatenkota', fn ($k) =>
|
||||
$k->where('provinsi_id', $v)
|
||||
)
|
||||
);
|
||||
|
||||
if ($request->filled('sort')) {
|
||||
$dir = str_starts_with($request->sort, '-') ? 'desc' : 'asc';
|
||||
$column = ltrim($request->sort, '-');
|
||||
|
||||
$allowed = ['id', 'kode', 'nama'];
|
||||
|
||||
if (in_array($column, $allowed)) {
|
||||
$master->orderBy($column, $dir);
|
||||
}
|
||||
} else {
|
||||
$master->orderBy('kode', 'asc');
|
||||
}
|
||||
|
||||
$masterList = $master->paginate($size);
|
||||
|
||||
return DesaKelurahanResource::collection($masterList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
return response()->json(DesaKelurahanResource::make(DesaKelurahan::with('kecamatan')->findOrFail($id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,7 @@ use App\Models\Core\Program;
|
||||
|
||||
class ValueBasisDataController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
|
||||
public function index(Request $request, string $tabelId): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
@@ -92,6 +90,7 @@ class ValueBasisDataController extends Controller
|
||||
MAX(
|
||||
CASE
|
||||
WHEN kolom_id = {$k->id}
|
||||
AND value_enum IS NOT NULL
|
||||
THEN (
|
||||
SELECT elem->>'label'
|
||||
FROM ekosistem_basis_data_kolom k,
|
||||
@@ -148,9 +147,70 @@ class ValueBasisDataController extends Controller
|
||||
return response()->json($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
private function prepareValidationRules($kolom)
|
||||
{
|
||||
$rules = [];
|
||||
foreach ($kolom as $k) {
|
||||
if ($k->validasi && is_array($k->validasi)) {
|
||||
$rules[$k->kolom] = $k->validasi;
|
||||
|
||||
if (!in_array('required', $k->validasi) && !in_array('nullable', $k->validasi)) {
|
||||
$rules[$k->kolom][] = 'nullable';
|
||||
}
|
||||
|
||||
if (!in_array('string', $k->validasi) && ($k->tipe == 'varchar' || $k->tipe == 'text')) {
|
||||
$rules[$k->kolom][] = 'string';
|
||||
}
|
||||
if (!in_array('max', $k->validasi) && ($k->tipe == 'varchar')) {
|
||||
$rules[$k->kolom][] = 'max:255';
|
||||
}
|
||||
if (!in_array('integer', $k->validasi) && $k->tipe == 'integer') {
|
||||
$rules[$k->kolom][] = 'integer';
|
||||
}
|
||||
if (!in_array('boolean', $k->validasi) && $k->tipe == 'boolean') {
|
||||
$rules[$k->kolom][] = 'boolean';
|
||||
}
|
||||
if (!in_array('date', $k->validasi) && ($k->tipe == 'date' || $k->tipe == 'datetime')) {
|
||||
$rules[$k->kolom][] = 'date';
|
||||
}
|
||||
if ($k->tipe == 'foreign_key') {
|
||||
$rules[$k->kolom][] = 'exists:' . $k->relasi_tabel . ',' . $k->relasi_kolom_id;
|
||||
}
|
||||
if ($k->tipe == 'enum') {
|
||||
$enumValues = collect($k->enum_opsi)->pluck('value')->toArray();
|
||||
$rules[$k->kolom][] = Rule::in($enumValues);
|
||||
}
|
||||
|
||||
} else {
|
||||
$rules[$k->kolom] = ['nullable'];
|
||||
|
||||
if ($k->tipe == 'varchar' || $k->tipe == 'text') {
|
||||
$rules[$k->kolom][] = 'string';
|
||||
}
|
||||
if ($k->tipe == 'varchar') {
|
||||
$rules[$k->kolom][] = 'max:255';
|
||||
}
|
||||
if ($k->tipe == 'integer') {
|
||||
$rules[$k->kolom][] = 'integer';
|
||||
}
|
||||
if ($k->tipe == 'boolean') {
|
||||
$rules[$k->kolom][] = 'boolean';
|
||||
}
|
||||
if ($k->tipe == 'date' || $k->tipe == 'datetime') {
|
||||
$rules[$k->kolom][] = 'date';
|
||||
}
|
||||
if ($k->tipe == 'foreign_key') {
|
||||
$rules[$k->kolom][] = 'exists:' . $k->relasi_tabel . ',' . $k->relasi_kolom_id;
|
||||
}
|
||||
if ($k->tipe == 'enum') {
|
||||
$enumValues = collect($k->enum_opsi)->pluck('value')->toArray();
|
||||
$rules[$k->kolom][] = Rule::in($enumValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function store(Request $request, string $tabelId): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
@@ -182,15 +242,7 @@ class ValueBasisDataController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$validationRules = [];
|
||||
foreach ($kolom as $k) {
|
||||
if ($k->validasi && is_array($k->validasi)) {
|
||||
$validationRules[$k->kolom] = $k->validasi;
|
||||
} else {
|
||||
$validationRules[$k->kolom] = ['nullable'];
|
||||
}
|
||||
}
|
||||
$validated = $request->validate($validationRules);
|
||||
$validated = $request->validate($this->prepareValidationRules($kolom));
|
||||
|
||||
DB::transaction(function () use ($program, $tabelId, $validated, $kolom) {
|
||||
$maxId = ValueBasisData::where('tabel_id', $tabelId)
|
||||
@@ -219,18 +271,12 @@ class ValueBasisDataController extends Controller
|
||||
return response()->json(['message' => 'Data berhasil disimpan.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
public function update(Request $request, string $tabelId, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
@@ -270,15 +316,7 @@ class ValueBasisDataController extends Controller
|
||||
abort(404, 'Data tidak ditemukan.');
|
||||
}
|
||||
|
||||
$validationRules = [];
|
||||
foreach ($kolom as $k) {
|
||||
if ($k->validasi && is_array($k->validasi)) {
|
||||
$validationRules[$k->kolom] = $k->validasi;
|
||||
} else {
|
||||
$validationRules[$k->kolom] = ['nullable'];
|
||||
}
|
||||
}
|
||||
$validated = $request->validate($validationRules);
|
||||
$validated = $request->validate($this->prepareValidationRules($kolom));
|
||||
|
||||
DB::transaction(function () use ($program, $tabelId, $validated, $kolom, $id, $values) {
|
||||
foreach ($validated as $kol => $val) {
|
||||
@@ -314,10 +352,7 @@ class ValueBasisDataController extends Controller
|
||||
return response()->json(['message' => 'Data berhasil diperbarui.']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $tabelId, string $id): JsonResponse
|
||||
public function destroy(Request $request, string $tabelId, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Models\Facilitator\Facilitator;
|
||||
|
||||
class FacilitatorController extends Controller
|
||||
{
|
||||
/**
|
||||
* Menampilkan daftar user detail dengan fitur search, sort, dan filter.
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$size = +$request->get('size') ?: 10;
|
||||
$query = Facilitator::query();
|
||||
|
||||
// Fitur Pencarian (berdasarkan nama atau email)
|
||||
if ($request->has('search')) {
|
||||
$s = strtolower($request->get('search'));
|
||||
$query->where(function($q) use ($s) {
|
||||
$q->whereRaw('lower(full_name) like (?)', ["%{$s}%"])
|
||||
->orWhereRaw('lower(user_email) like (?)', ["%{$s}%"]);
|
||||
});
|
||||
}
|
||||
|
||||
// Fitur Sorting (contoh: ?sort=-full_name)
|
||||
if ($request->has('sort')) {
|
||||
$order = $request->get('sort');
|
||||
$firstChar = substr($order, 0, 1);
|
||||
$dir = $firstChar === '-' ? 'desc' : 'asc';
|
||||
$field = $firstChar === '-' ? substr($order, 1) : $order;
|
||||
$query->orderBy($field, $dir);
|
||||
}
|
||||
|
||||
// Fitur Filter Wilayah
|
||||
if ($request->has('province')) {
|
||||
$query->where('province', $request->get('province'));
|
||||
}
|
||||
if ($request->has('regency')) {
|
||||
$query->where('regency', $request->get('regency'));
|
||||
}
|
||||
if ($request->has('is_active')) {
|
||||
$query->where('is_active', $request->boolean('is_active'));
|
||||
}
|
||||
|
||||
$users = $query->paginate($size);
|
||||
|
||||
return response()->json($users);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menyimpan data user detail baru.
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
|
||||
$validated = $request->validate([
|
||||
'user_email' => ['required', 'email', 'unique:facilitator,user_email'],
|
||||
'full_name' => ['required', 'string', 'max:255'],
|
||||
'role' => ['required', 'string'],
|
||||
'village' => ['nullable', 'string'],
|
||||
'district' => ['nullable', 'string'],
|
||||
'regency' => ['nullable', 'string'],
|
||||
'province' => ['nullable', 'string'],
|
||||
'phone' => ['nullable', 'string'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
$user = Facilitator::create($validated);
|
||||
|
||||
return response()->json($user, 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menampilkan detail satu user.
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
|
||||
$user = Facilitator::findOrFail($id);
|
||||
return response()->json($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Memperbarui data user detail.
|
||||
*/
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
|
||||
$user = Facilitator::findOrFail($id);
|
||||
|
||||
$validated = $request->validate([
|
||||
'user_email' => ['required', 'email', 'unique:facilitator,user_email,' . $id],
|
||||
'full_name' => ['required', 'string', 'max:255'],
|
||||
'role' => ['required', 'string'],
|
||||
'village' => ['nullable', 'string'],
|
||||
'district' => ['nullable', 'string'],
|
||||
'regency' => ['nullable', 'string'],
|
||||
'province' => ['nullable', 'string'],
|
||||
'phone' => ['nullable', 'string'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
$user->update($validated);
|
||||
|
||||
return response()->json($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Menghapus data user detail.
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
|
||||
$user = Facilitator::findOrFail($id);
|
||||
$user->delete();
|
||||
|
||||
return response()->json(['message' => 'User deleted successfully']);
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Models\Wilayah\Provinsi;
|
||||
use App\Models\Wilayah\KabupatenKota;
|
||||
use App\Http\Resources\Wilayah\KabupatenKotaResource;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class KabupatenKotaController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$size = $request->integer('size') ?: 10;
|
||||
|
||||
$master = KabupatenKota::with('provinsi')
|
||||
->when($request->search, function ($q, $search) {
|
||||
$search = strtolower($search);
|
||||
$q->where(function ($query) use ($search) {
|
||||
$query->whereRaw('lower(kode) like ?', ["%{$search}%"])
|
||||
->orWhereRaw('lower(nama) like ?', ["%{$search}%"]);
|
||||
});
|
||||
})
|
||||
->when($request->provinsi_id, fn($q,$v) => $q->where('provinsi_id',$v));
|
||||
|
||||
if ($request->filled('sort')) {
|
||||
$dir = str_starts_with($request->sort, '-') ? 'desc' : 'asc';
|
||||
$column = ltrim($request->sort, '-');
|
||||
|
||||
$allowed = ['id', 'kode', 'nama'];
|
||||
|
||||
if (in_array($column, $allowed)) {
|
||||
$master->orderBy($column, $dir);
|
||||
}
|
||||
} else {
|
||||
$master->orderBy('kode', 'asc');
|
||||
}
|
||||
|
||||
$masterList = $master->paginate($size);
|
||||
|
||||
return KabupatenKotaResource::collection($masterList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
return response()->json(KabupatenKotaResource::make(KabupatenKota::with('provinsi')->findOrFail($id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\Wilayah\Kecamatan;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use App\Http\Resources\Wilayah\KecamatanResource;
|
||||
|
||||
class KecamatanController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$size = $request->integer('size') ?: 10;
|
||||
|
||||
$master = Kecamatan::with('kabupatenKota')
|
||||
->when($request->search, function ($q, $search) {
|
||||
$search = strtolower($search);
|
||||
$q->where(function ($query) use ($search) {
|
||||
$query->whereRaw('lower(kode) like ?', ["%{$search}%"])
|
||||
->orWhereRaw('lower(nama) like ?', ["%{$search}%"]);
|
||||
});
|
||||
})
|
||||
->when($request->kabupaten_kota_id, fn($q,$v) => $q->where('kabupaten_kota_id',$v))
|
||||
->when($request->provinsi_id, fn ($q, $v) =>
|
||||
$q->whereHas('kabupatenKota.provinsi', fn ($k) =>
|
||||
$k->where('provinsi_id', $v)
|
||||
)
|
||||
);
|
||||
|
||||
if ($request->filled('sort')) {
|
||||
$dir = str_starts_with($request->sort, '-') ? 'desc' : 'asc';
|
||||
$column = ltrim($request->sort, '-');
|
||||
|
||||
$allowed = ['id', 'kode', 'nama'];
|
||||
|
||||
if (in_array($column, $allowed)) {
|
||||
$master->orderBy($column, $dir);
|
||||
}
|
||||
} else {
|
||||
$master->orderBy('kode', 'asc');
|
||||
}
|
||||
|
||||
$masterList = $master->paginate($size);
|
||||
|
||||
return KecamatanResource::collection($masterList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
return response()->json(KecamatanResource::make(Kecamatan::with('kabupatenKota')->findOrFail($id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
+18
-22
@@ -1,21 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Konfigurasi;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Profile;
|
||||
|
||||
use App\Http\Resources\UserResource;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
public function login(Request $request): JSONResponse
|
||||
public function login(Request $request): JsonResponse
|
||||
{
|
||||
$credentials = $request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
@@ -29,6 +27,13 @@ class AuthController extends Controller
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
if ($user->status === 'pending') {
|
||||
return response()->json([
|
||||
'message' => 'Akun Anda masih berstatus pending. Silakan tunggu verifikasi dari Super Admin.'
|
||||
], 403);
|
||||
}
|
||||
|
||||
$user->tokens()->delete();
|
||||
|
||||
$token = $user->createToken('mobile-token')->plainTextToken;
|
||||
@@ -39,14 +44,13 @@ class AuthController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function signup(Request $request): JSONResponse
|
||||
public function signup(Request $request): JsonResponse
|
||||
{
|
||||
$credentials = $request->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
'username' => ['required', 'string', 'max:255'],
|
||||
'role' => ['string'],
|
||||
'uid' => ['required','string', 'unique:users'],
|
||||
]);
|
||||
|
||||
@@ -55,35 +59,27 @@ class AuthController extends Controller
|
||||
'email' => $credentials['email'],
|
||||
'password' => Hash::make($credentials['password']),
|
||||
'username' => $credentials['username'],
|
||||
'role' => $credentials['role'],
|
||||
'uid' => $credentials['uid'],
|
||||
'role' => null,
|
||||
'status' => 'pending',
|
||||
]);
|
||||
|
||||
$profile = Profile::create([
|
||||
'nama' => $credentials['name'],
|
||||
'email' => $credentials['email'],
|
||||
'role' => $credentials['role'],
|
||||
'user_uid' => $credentials['uid'],
|
||||
'user_id' => $user->id,
|
||||
'created_by' => $user->id,
|
||||
'updated_by' => $user->id,
|
||||
|
||||
|
||||
'role' => null,
|
||||
]);
|
||||
|
||||
if (!Auth::attempt($credentials)) {
|
||||
return response()->json([
|
||||
'message' => 'Email dan/atau password tidak sesuai'
|
||||
], 401);
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$user->tokens()->delete();
|
||||
|
||||
$token = $user->createToken('mobile-token')->plainTextToken;
|
||||
|
||||
|
||||
return response()->json([
|
||||
'access_token' => $token,
|
||||
'token_type' => 'Bearer',
|
||||
]);
|
||||
'message' => 'Registrasi berhasil. Akun Anda berstatus pending dan sedang menunggu verifikasi Super Admin.'
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function me(Request $request): JSONResponse
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Master;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
use App\Http\Resources\Pertanian\JenisKomoditasResource;
|
||||
use App\Models\Pertanian\JenisKomoditas;
|
||||
|
||||
class JenisKomoditasController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$size = $request->integer('size') ?: 10;
|
||||
|
||||
$jenisKomoditasList = JenisKomoditas::when($request->search, function ($q, $search) {
|
||||
$search = strtolower($search);
|
||||
$q->whereRaw('lower(nama) like ?', ["%{$search}%"]);
|
||||
})
|
||||
->when($request->kode, fn($q, $v) => $q->where('kode', $v));
|
||||
|
||||
if ($request->filled('sort')) {
|
||||
$dir = str_starts_with($request->sort, '-') ? 'desc' : 'asc';
|
||||
$column = ltrim($request->sort, '-');
|
||||
|
||||
$allowed = ['id', 'nama', 'kode'];
|
||||
|
||||
if (in_array($column, $allowed)) {
|
||||
$jenisKomoditasList->orderBy($column, $dir);
|
||||
}
|
||||
} else {
|
||||
$jenisKomoditasList->orderBy('nama', 'asc');
|
||||
}
|
||||
|
||||
$jenisKomoditasList = $jenisKomoditasList->paginate($size);
|
||||
|
||||
return JenisKomoditasResource::collection($jenisKomoditasList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'kode' => ['required', 'string', 'max:50', 'unique:jenis_komoditas,kode'],
|
||||
'keterangan' => ['nullable', 'string'],
|
||||
]);
|
||||
|
||||
$jenisKomoditas = JenisKomoditas::create($validated);
|
||||
|
||||
return (new JenisKomoditasResource($jenisKomoditas))
|
||||
->response()
|
||||
->setStatusCode(201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$jenisKomoditas = JenisKomoditas::findOrFail($id);
|
||||
|
||||
return (new JenisKomoditasResource($jenisKomoditas))->response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$jenisKomoditas = JenisKomoditas::findOrFail($id);
|
||||
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'kode' => ['required', 'string', 'max:50', Rule::unique('jenis_komoditas', 'kode')->ignore($jenisKomoditas->id)],
|
||||
'keterangan' => ['nullable', 'string'],
|
||||
]);
|
||||
|
||||
$jenisKomoditas->update($validated);
|
||||
|
||||
return (new JenisKomoditasResource($jenisKomoditas))->response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$jenisKomoditas = JenisKomoditas::findOrFail($id);
|
||||
$jenisKomoditas->delete();
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Map\PanenTanaman;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Exception;
|
||||
|
||||
class PanenTanamanController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$panenTanaman = PanenTanaman::latest()->get();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Daftar data panen tanaman berhasil diambil.',
|
||||
'data' => $panenTanaman
|
||||
], 200);
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Terjadi kesalahan saat mengambil data.',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'panen_id' => 'required|integer',
|
||||
'tanaman_id' => 'required|integer',
|
||||
'commodity_name' => 'required|string|max:255',
|
||||
'sync_status' => 'nullable|string|max:50',
|
||||
'weight_kg' => 'required|numeric|min:0',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validasi gagal.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
try {
|
||||
$panenTanaman = PanenTanaman::create($request->all());
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data panen tanaman berhasil disimpan.',
|
||||
'data' => $panenTanaman
|
||||
], 201);
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Gagal menyimpan data.',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(PanenTanaman $panenTanaman)
|
||||
{
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Detail data panen tanaman ditemukan.',
|
||||
'data' => $panenTanaman
|
||||
], 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, PanenTanaman $panenTanaman)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'panen_id' => 'sometimes|required|integer',
|
||||
'tanaman_id' => 'sometimes|required|integer',
|
||||
'commodity_name' => 'sometimes|required|string|max:255',
|
||||
'sync_status' => 'nullable|string|max:50',
|
||||
'weight_kg' => 'sometimes|required|numeric|min:0',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Validasi gagal.',
|
||||
'errors' => $validator->errors()
|
||||
], 422);
|
||||
}
|
||||
|
||||
try {
|
||||
$panenTanaman->update($request->all());
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data panen tanaman berhasil diperbarui.',
|
||||
'data' => $panenTanaman
|
||||
], 200);
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Gagal memperbarui data.',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(PanenTanaman $panenTanaman)
|
||||
{
|
||||
try {
|
||||
$panenTanaman->delete(); // Karena pakai SoftDeletes, data tidak terhapus permanen di DB
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data panen tanaman berhasil dihapus (soft delete).'
|
||||
], 200);
|
||||
} catch (Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Gagal menghapus data.',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Map\InsLahan;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Map\Inspeksi;
|
||||
+38
-8
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -16,7 +16,7 @@ use App\Enums\StatusLahan;
|
||||
|
||||
class LahanController extends Controller
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
@@ -97,11 +97,12 @@ class LahanController extends Controller
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'status_kepemilikan' => ['required', new Enum(StatusLahan::class)],
|
||||
'desa_kelurahan_id' => ['nullable', 'numeric', 'exists:master_desa_kelurahan,id'],
|
||||
'path' => ['nullable', 'array'],
|
||||
'path.*' => ['array'],
|
||||
'path' => ['nullable', 'string'],
|
||||
'luas_lahan' => ['nullable', 'numeric'],
|
||||
'uid' => ['required', 'string'],
|
||||
'profile_id' => $profileRule,
|
||||
'foto' => ['nullable', 'array'],
|
||||
'foto.*' => ['image', 'mimes:jpeg,png,jpg', 'max:5120'], // Max 5MB
|
||||
]);
|
||||
|
||||
$targetProfileId = $user->role === 'fasilitator'
|
||||
@@ -120,10 +121,22 @@ class LahanController extends Controller
|
||||
? $profile->desa_kelurahan_id
|
||||
: ($validated['desa_kelurahan_id'] ?? $profile->desa_kelurahan_id);
|
||||
|
||||
$fotoPaths = [];
|
||||
if ($request->hasFile('foto')) {
|
||||
foreach ($request->file('foto') as $file) {
|
||||
$fotoPaths[] = $file->store('foto_lahan', 'public');
|
||||
}
|
||||
}
|
||||
|
||||
$lahan = Lahan::create([
|
||||
...$validated,
|
||||
'profile_id' => $profile->id,
|
||||
'nama' => $validated['nama'],
|
||||
'status_kepemilikan' => $validated['status_kepemilikan'],
|
||||
'desa_kelurahan_id' => $desaKelurahanId,
|
||||
'path' => $validated['path'] ?? null,
|
||||
'luas_lahan' => $validated['luas_lahan'] ?? null,
|
||||
'uid' => $validated['uid'],
|
||||
'profile_id' => $profile->id,
|
||||
'foto' => $fotoPaths,
|
||||
]);
|
||||
|
||||
return (new LahanResource($lahan))
|
||||
@@ -153,7 +166,7 @@ class LahanController extends Controller
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
@@ -173,9 +186,26 @@ class LahanController extends Controller
|
||||
'path' => ['nullable', 'array'],
|
||||
'path.*' => ['array'],
|
||||
'luas_lahan' => ['nullable', 'numeric'],
|
||||
'foto' => ['nullable', 'array'],
|
||||
'foto.*' => ['image', 'mimes:jpeg,png,jpg', 'max:5120'],
|
||||
]);
|
||||
|
||||
$lahan->update($validated);
|
||||
$fotoPaths = $lahan->foto ?? [];
|
||||
|
||||
if ($request->hasFile('foto')) {
|
||||
foreach ($request->file('foto') as $file) {
|
||||
$fotoPaths[] = $file->store('foto_lahan', 'public');
|
||||
}
|
||||
}
|
||||
|
||||
$lahan->update([
|
||||
'nama' => $validated['nama'],
|
||||
'status_kepemilikan' => $validated['status_kepemilikan'],
|
||||
'desa_kelurahan_id' => $validated['desa_kelurahan_id'] ?? $lahan->desa_kelurahan_id,
|
||||
'path' => $validated['path'] ?? null,
|
||||
'luas_lahan' => $validated['luas_lahan'] ?? null,
|
||||
'foto' => $fotoPaths,
|
||||
]);
|
||||
|
||||
return (new LahanResource($lahan))->response();
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use App\Models\Map\Panen;
|
||||
|
||||
class PanenController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$profile = $user->profile;
|
||||
|
||||
$profileId = $user->role === 'petani' ? $profile->id : $request->id;
|
||||
$listPanen = Panen::when($profileId, fn($q,$v) => $q->where('farmer_id',$user->id))->get();
|
||||
|
||||
return response()->json($listPanen);
|
||||
}
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'uid' => ['required', 'string'],
|
||||
'title' => ['required', 'string'],
|
||||
'land_id' => ['required', 'integer'],
|
||||
'farmer_id' => ['required', 'integer'],
|
||||
'land_description' => ['nullable', 'string'],
|
||||
'harvest_date' => ['required', 'date'],
|
||||
'commodities' => ['required', 'array', 'min:1'],
|
||||
'commodities.*.tanaman_id' => ['nullable', 'integer'],
|
||||
'commodities.*.commodity_name' => ['required', 'string'],
|
||||
'commodities.*.weight_kg' => ['required', 'numeric'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
]);
|
||||
|
||||
try {
|
||||
$panen = DB::transaction(function () use ($validated) {
|
||||
|
||||
$panenData = collect($validated)->except('commodities')->toArray();
|
||||
$panen = Panen::create($panenData);
|
||||
|
||||
foreach ($validated['commodities'] as $commodity) {
|
||||
\App\Models\Map\PanenTanaman::create([
|
||||
'panen_id' => $panen->id,
|
||||
'tanaman_id' => $commodity['tanaman_id'] ?? null,
|
||||
'commodity_name' => $commodity['commodity_name'],
|
||||
'weight_kg' => $commodity['weight_kg'],
|
||||
'sync_status' => 'synced',
|
||||
]);
|
||||
}
|
||||
|
||||
return $panen;
|
||||
});
|
||||
$panen->load('panenTanaman');
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Data panen dan detail tanaman berhasil disimpan.',
|
||||
'data' => $panen
|
||||
], 201);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Gagal menyimpan data ke database.',
|
||||
'error' => $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$panen = Panen::findOrFail($id);
|
||||
return response()->json($panen);
|
||||
}
|
||||
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$panen = Panen::findOrFail($id);
|
||||
|
||||
$validated = $request->validate([
|
||||
'commodity_name' => ['string', 'max:255'],
|
||||
'weight_kg' => ['numeric'],
|
||||
'harvest_date' => ['date'],
|
||||
'notes' => ['nullable', 'string'],
|
||||
]);
|
||||
|
||||
$panen->update($validated);
|
||||
return response()->json($panen);
|
||||
}
|
||||
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
Gate::authorize(['petani', 'fasilitator']);
|
||||
Panen::findOrFail($id)->delete();
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
|
||||
/**
|
||||
* Digunakan untuk sinkronisasi massal dari data lokal (offline)
|
||||
*/
|
||||
public function batchUpsert(Request $request): JsonResponse
|
||||
{
|
||||
if (Gate::authorize(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$profileId = Auth::user()->profile->id;
|
||||
|
||||
$validated = $request->validate([
|
||||
'panens' => ['required', 'array'],
|
||||
'panens.*.id' => ['nullable', 'integer'],
|
||||
'panens.*.land_id' => ['required', 'integer'],
|
||||
'panens.*.plant_id' => ['required', 'integer'],
|
||||
'panens.*.commodity_name' => ['required', 'string'],
|
||||
'panens.*.weight_kg' => ['required', 'numeric'],
|
||||
'panens.*.harvest_date' => ['required', 'date'],
|
||||
]);
|
||||
|
||||
$dataUpsert = [];
|
||||
foreach ($validated['panens'] as $item) {
|
||||
$dataUpsert[] = [
|
||||
'id' => $item['id'] ?? null,
|
||||
'land_id' => $item['land_id'],
|
||||
'plant_id' => $item['plant_id'],
|
||||
'farmer_id' => $profileId,
|
||||
'commodity_name' => $item['commodity_name'],
|
||||
'weight_kg' => $item['weight_kg'],
|
||||
'harvest_date' => $item['harvest_date'],
|
||||
'sync_status' => 'synced',
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
];
|
||||
}
|
||||
|
||||
// Melakukan upsert berdasarkan ID
|
||||
Panen::upsert($dataUpsert, ['id'], [
|
||||
'weight_kg', 'commodity_name', 'harvest_date', 'sync_status', 'updated_at'
|
||||
]);
|
||||
|
||||
return response()->json(['status' => 'success'], 200);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -10,7 +10,7 @@ use Illuminate\Support\Facades\Gate;
|
||||
|
||||
use App\Models\Map\Panen;
|
||||
|
||||
class PanenController extends Controller
|
||||
class PanenController01 extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Produktivitas;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Validation\Rules\Enum;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
use App\Http\Resources\Pertanian\TanamanResource;
|
||||
use App\Models\Pertanian\Tanaman;
|
||||
use App\Enums\KondisiTanaman;
|
||||
|
||||
class TanamanController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$user = Auth::user();
|
||||
$profile = $user->profile;
|
||||
$profileId = $user->role === 'petani' ? $profile->id : $request->profile_id;
|
||||
|
||||
$size = $request->integer('size') ?: 10;
|
||||
|
||||
$tanamanList = Tanaman::when($request->search, function ($q, $search) {
|
||||
$search = strtolower($search);
|
||||
$q->whereRaw('lower(nama) like ?', ["%{$search}%"]);
|
||||
})
|
||||
->when($profileId, fn($q,$v) => $q->where('profile_id',$v))
|
||||
->when($request->status_kepemilikan, fn($q,$v) => $q->where('status_kepemilikan',$v))
|
||||
->when($request->lahan_id, fn($q,$v) => $q->where('lahan_id',$v))
|
||||
->when($request->komoditas_id, fn($q,$v) => $q->where('komoditas_id',$v))
|
||||
->when($request->desa_kelurahan_id, fn($q,$v) =>
|
||||
$q->whereHas('lahan', fn($k)
|
||||
=> $k->where('desa_kelurahan_id',$v)
|
||||
)
|
||||
)
|
||||
->when($request->kecamatan_id, fn ($q, $v) =>
|
||||
$q->whereHas('lahan.desaKelurahan', fn ($k) =>
|
||||
$k->where('kecamatan_id', $v)
|
||||
)
|
||||
)
|
||||
->when($request->kabupaten_kota_id, fn ($q, $v) =>
|
||||
$q->whereHas('lahan.desaKelurahan.kecamatan', fn ($k) =>
|
||||
$k->where('kabupaten_kota_id', $v)
|
||||
)
|
||||
)
|
||||
->when($request->provinsi_id, fn ($q, $v) =>
|
||||
$q->whereHas('lahan.desaKelurahan.kecamatan.kabupatenkota', fn ($k) =>
|
||||
$k->where('provinsi_id', $v)
|
||||
)
|
||||
);
|
||||
|
||||
if ($request->filled('sort')) {
|
||||
$dir = str_starts_with($request->sort, '-') ? 'desc' : 'asc';
|
||||
$column = ltrim($request->sort, '-');
|
||||
|
||||
$allowed = ['id', 'nama'];
|
||||
|
||||
if (in_array($column, $allowed)) {
|
||||
$tanamanList->orderBy($column, $dir);
|
||||
}
|
||||
} else {
|
||||
$tanamanList->orderBy('nama', 'asc');
|
||||
}
|
||||
|
||||
$tanamanList = $tanamanList->paginate($size);
|
||||
|
||||
return TanamanResource::collection($tanamanList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$profile = $user->profile;
|
||||
$profileId = $user->role === 'petani' ? $profile->id : $request->profile_id;
|
||||
|
||||
$request->merge([
|
||||
'komoditas_id' => $request->input('komoditas.id') ?? $request->input('komoditas_id'),
|
||||
'lahan_id' => $request->input('lahan.id') ?? $request->input('lahan_id'),
|
||||
'profile_id' => $profileId,
|
||||
]);
|
||||
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'komoditas_id' => ['required', 'exists:master_komoditas,id'],
|
||||
'lahan_id' => [
|
||||
'required',
|
||||
Rule::exists('map_lahan', 'id')->where(function ($query) use ($profileId) {
|
||||
$query->where('profile_id', $profileId)
|
||||
->whereNull('deleted_at');
|
||||
}),
|
||||
],
|
||||
'latitude' => ['nullable', 'numeric', 'between:-90,90', 'required_with:longitude'],
|
||||
'longitude' => ['nullable', 'numeric', 'between:-180,180', 'required_with:latitude'],
|
||||
'kondisi_tanaman' => ['nullable', 'string', new Enum(KondisiTanaman::class)],
|
||||
]);
|
||||
|
||||
$tanaman = Tanaman::create([
|
||||
...$validated,
|
||||
'profile_id' => $profile->id,
|
||||
]);
|
||||
|
||||
return (new TanamanResource($tanaman))
|
||||
->response()
|
||||
->setStatusCode(201);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tanaman = Tanaman::findOrFail($id);
|
||||
if ($tanaman->profile_id !== Auth::user()->profile->id) {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
return (new TanamanResource($tanaman))->response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$tanaman = Tanaman::findOrFail($id);
|
||||
if ($tanaman->profile_id !== Auth::user()->profile->id) {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
$profile = Auth::user()->profile;
|
||||
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'komoditas_id' => ['required', 'exists:master_komoditas,id'],
|
||||
'lahan_id' => [
|
||||
'required',
|
||||
Rule::exists('map_lahan', 'id')->where(function ($query) use ($profile) {
|
||||
$query->where('profile_id', $profile->id)
|
||||
->whereNull('deleted_at');
|
||||
}),
|
||||
],
|
||||
'latitude' => ['nullable', 'numeric', 'between:-90,90', 'required_with:longitude'],
|
||||
'longitude' => ['nullable', 'numeric', 'between:-180,180', 'required_with:latitude'],
|
||||
'kondisi_tanaman' => ['nullable', 'string', new Enum(KondisiTanaman::class)],
|
||||
]);
|
||||
|
||||
$tanaman->update($validated);
|
||||
|
||||
return (new TanamanResource($tanaman))->response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$tanaman = Tanaman::findOrFail($id);
|
||||
if ($tanaman->profile_id !== Auth::user()->profile->id) {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
$tanaman->delete();
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use App\Models\Wilayah\Provinsi;
|
||||
use App\Http\Resources\Wilayah\ProvinsiResource;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class ProvinsiController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$size = $request->integer('size') ?: 10;
|
||||
|
||||
$master = Provinsi::when($request->search, function ($q, $search) {
|
||||
$search = strtolower($search);
|
||||
$q->where(function ($query) use ($search) {
|
||||
$query->whereRaw('lower(kode) like ?', ["%{$search}%"])
|
||||
->orWhereRaw('lower(nama) like ?', ["%{$search}%"]);
|
||||
});
|
||||
});
|
||||
|
||||
if ($request->filled('sort')) {
|
||||
$dir = str_starts_with($request->sort, '-') ? 'desc' : 'asc';
|
||||
$column = ltrim($request->sort, '-');
|
||||
|
||||
$allowed = ['id', 'kode', 'nama'];
|
||||
|
||||
if (in_array($column, $allowed)) {
|
||||
$master->orderBy($column, $dir);
|
||||
}
|
||||
} else {
|
||||
$master->orderBy('kode', 'asc');
|
||||
}
|
||||
|
||||
$masterList = $master->paginate($size);
|
||||
|
||||
return ProvinsiResource::collection($masterList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
return response()->json(ProvinsiResource::make(Provinsi::findOrFail($id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -96,35 +96,39 @@ class TanamanController extends Controller
|
||||
}
|
||||
|
||||
$user = Auth::user();
|
||||
$profile = $user->profile;
|
||||
$profileId = $user->role === 'petani' ? $profile->id : $request->profile_id;
|
||||
$profileId = $user->role === 'petani' ? $user->profile->id : $request->profile_id;
|
||||
$lahanId = $request->input('lahan_id') ?? $request->input('land_id') ?? $request->input('lahan.id');
|
||||
|
||||
$request->merge([
|
||||
'komoditas_id' => $request->input('komoditas.id') ?? $request->input('komoditas_id'),
|
||||
'lahan_id' => $request->input('lahan.id') ?? $request->input('lahan_id'),
|
||||
'lahan_id' => $lahanId,
|
||||
'profile_id' => $profileId,
|
||||
'uid' => $request->input('uid'),
|
||||
'created_by' => $user->id,
|
||||
]);
|
||||
|
||||
$validated = $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'komoditas_id' => ['required', 'exists:master_komoditas,id'],
|
||||
'lahan_id' => [
|
||||
'required',
|
||||
Rule::exists('map_lahan', 'id')->where(function ($query) use ($profileId) {
|
||||
$query->where('profile_id', $profileId)
|
||||
->whereNull('deleted_at');
|
||||
}),
|
||||
],
|
||||
'latitude' => ['nullable', 'numeric', 'between:-90,90', 'required_with:longitude'],
|
||||
'longitude' => ['nullable', 'numeric', 'between:-180,180', 'required_with:latitude'],
|
||||
'kondisi_tanaman' => ['nullable', 'string', new Enum(KondisiTanaman::class)],
|
||||
'uid' => ['required', 'string'],
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'komoditas_id' => ['required', 'exists:master_komoditas,id'],
|
||||
'lahan_id' => ['required', 'exists:map_lahan,id'],
|
||||
'profile_id' => ['required', 'exists:profiles,id'],
|
||||
'latitude' => ['nullable', 'numeric', 'between:-90,90', 'required_with:longitude'],
|
||||
'longitude' => ['nullable', 'numeric', 'between:-180,180', 'required_with:latitude'],
|
||||
'kondisi_tanaman' => ['nullable', 'string', new Enum(KondisiTanaman::class)],
|
||||
'uid' => ['required', 'string'],
|
||||
'jenis_komoditas_id' => ['nullable', 'exists:jenis_komoditas,id'],
|
||||
'komoditas_kode' => ['nullable', 'string', 'max:255'],
|
||||
'varietas_id' => ['nullable', 'numeric'],
|
||||
'metode_pengumpulan' => ['nullable', 'string'],
|
||||
'deskripsi' => ['nullable', 'string'],
|
||||
'created_by' => ['nullable', 'numeric'],
|
||||
]);
|
||||
|
||||
|
||||
$tanaman = Tanaman::create([
|
||||
...$validated,
|
||||
'profile_id' => $profile->id,
|
||||
'uid' => $validated['uid'] ?? $request->input('uid'),
|
||||
// 'profile_id' => $profileId,
|
||||
// 'uid' => $validated['uid'],
|
||||
// 'komoditas_kode' => $validated['komoditas_kode'] ?? null,
|
||||
// 'jenis_komoditas_id' => $validated['jenis_komoditas_id'] ?? null,
|
||||
]);
|
||||
|
||||
return (new TanamanResource($tanaman))
|
||||
|
||||
@@ -0,0 +1,580 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Bumdes;
|
||||
|
||||
use App\Enums\Bumdes\JabatanBumdes;
|
||||
use App\Enums\Pendidikan;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Bumdes\KelembagaanAktorBumdes;
|
||||
use App\Models\Bumdes\PengurusBumdes;
|
||||
use App\Models\Wilayah\Provinsi;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class PengurusBumdesController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$query = PengurusBumdes::with([
|
||||
...$this->wilayahRelationsWithoutProgramScope(),
|
||||
'creator:id,name',
|
||||
])
|
||||
->orderBy('created_at', 'desc');
|
||||
|
||||
if ($request->search) {
|
||||
$query->where(function ($query) use ($request) {
|
||||
$query->where('nama', 'like', '%' . $request->search . '%')
|
||||
->orWhere('jabatan', 'like', '%' . $request->search . '%')
|
||||
->orWhere('jabatan_lainnya', 'like', '%' . $request->search . '%');
|
||||
});
|
||||
}
|
||||
|
||||
if (auth()->user()->role->value === 'fasilitator') {
|
||||
$query->where('created_by', auth()->id());
|
||||
}
|
||||
|
||||
$summaryQuery = clone $query;
|
||||
$totalPengurus = (clone $summaryQuery)->count();
|
||||
$totalLakiLaki = (clone $summaryQuery)->where('jenis_kelamin', true)->count();
|
||||
$totalPerempuan = (clone $summaryQuery)->where('jenis_kelamin', false)->count();
|
||||
$totalDesaKelurahan = (clone $summaryQuery)->distinct('desa_kelurahan_id')->count('desa_kelurahan_id');
|
||||
$totalJabatan = (clone $summaryQuery)->distinct('jabatan')->count('jabatan');
|
||||
|
||||
$pengurus = $query->paginate($request->per_page ?? 10);
|
||||
$userRole = auth()->user()->role->value;
|
||||
$showEnumerator = in_array($userRole, ['super_admin', 'admin']);
|
||||
|
||||
return view('bumdes.profil.index', compact(
|
||||
'pengurus',
|
||||
'totalPengurus',
|
||||
'totalLakiLaki',
|
||||
'totalPerempuan',
|
||||
'totalDesaKelurahan',
|
||||
'totalJabatan',
|
||||
'showEnumerator'
|
||||
));
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$provinsi = $this->provinsiOptions();
|
||||
$jabatan = JabatanBumdes::options();
|
||||
$pendidikan = Pendidikan::options();
|
||||
|
||||
return view('bumdes.profil.add', compact('provinsi', 'jabatan', 'pendidikan'));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$validatedData = $this->validatedData($request);
|
||||
|
||||
$pengurus = PengurusBumdes::create([
|
||||
...$this->formatData($validatedData),
|
||||
'uid' => 'BMD-' . strtoupper(Str::random(10)),
|
||||
'created_by' => auth()->id(),
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('bumdes.edit', $pengurus->id)->with('success', 'Data pengurus BUMDes berhasil ditambahkan.');
|
||||
}
|
||||
|
||||
public function show(string $id)
|
||||
{
|
||||
return redirect()->route('bumdes.edit', $id);
|
||||
}
|
||||
|
||||
public function edit(string $id)
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$pengurus = $this->pengurusQuery()
|
||||
->with($this->wilayahRelationsWithoutProgramScope())
|
||||
->findOrFail($id);
|
||||
$provinsi = $this->provinsiOptions();
|
||||
$jabatan = JabatanBumdes::options();
|
||||
$pendidikan = Pendidikan::options();
|
||||
|
||||
return view('bumdes.profil.edit', compact('pengurus', 'provinsi', 'jabatan', 'pendidikan'));
|
||||
}
|
||||
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$pengurus = $this->pengurusQuery()->findOrFail($id);
|
||||
$validatedData = $this->validatedData($request);
|
||||
|
||||
$pengurus->update([
|
||||
...$this->formatData($validatedData),
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
return redirect()->route('bumdes.edit', $pengurus->id)->with('success', 'Data pengurus BUMDes berhasil diupdate.');
|
||||
}
|
||||
|
||||
public function destroy(string $id)
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$pengurus = $this->pengurusQuery()->findOrFail($id);
|
||||
$pengurus->update(['deleted_by' => auth()->id()]);
|
||||
$pengurus->delete();
|
||||
|
||||
return response()->json(['message' => 'Data pengurus BUMDes berhasil dihapus.']);
|
||||
}
|
||||
|
||||
public function kelembagaanAktor(string $id)
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$pengurus = $this->pengurusQuery()
|
||||
->with([
|
||||
...$this->wilayahRelationsWithoutProgramScope(),
|
||||
'kelembagaanAktor',
|
||||
])
|
||||
->findOrFail($id);
|
||||
$kelembagaanAktor = $pengurus->kelembagaanAktor;
|
||||
|
||||
return view('bumdes.kelembagaan-aktor.index', array_merge(
|
||||
compact('pengurus', 'kelembagaanAktor'),
|
||||
$this->kelembagaanAktorOptions()
|
||||
));
|
||||
}
|
||||
|
||||
public function storeKelembagaanAktor(Request $request, string $id)
|
||||
{
|
||||
if (! Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$pengurus = $this->pengurusQuery()->findOrFail($id);
|
||||
$validatedData = $this->validatedKelembagaanAktorData($request);
|
||||
|
||||
KelembagaanAktorBumdes::updateOrCreate(
|
||||
['pengurus_bumdes_id' => $pengurus->id],
|
||||
[
|
||||
...$this->formatKelembagaanAktorData($validatedData),
|
||||
'created_by' => $pengurus->kelembagaanAktor?->created_by ?? auth()->id(),
|
||||
'updated_by' => auth()->id(),
|
||||
]
|
||||
);
|
||||
|
||||
return redirect()
|
||||
->route('bumdes.kelembagaan-aktor.index', $pengurus->id)
|
||||
->with('success', 'Data kelembagaan dan aktor BUMDes berhasil disimpan.');
|
||||
}
|
||||
|
||||
private function pengurusQuery()
|
||||
{
|
||||
$query = PengurusBumdes::query();
|
||||
|
||||
if (auth()->user()->role->value === 'fasilitator') {
|
||||
$query->where('created_by', auth()->id());
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
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 validatedData(Request $request): array
|
||||
{
|
||||
return $request->validate([
|
||||
'nama' => ['required', 'string', 'max:255'],
|
||||
'jenis_kelamin' => ['required', 'boolean'],
|
||||
'tempat_lahir' => ['required', 'string', 'max:255'],
|
||||
'tanggal_lahir' => ['required', 'date_format:d-m-Y'],
|
||||
'pendidikan_terakhir' => ['required', Rule::enum(Pendidikan::class)],
|
||||
'alamat' => ['required', 'string', 'max:500'],
|
||||
'desa_kelurahan_id' => ['required', 'exists:master_desa_kelurahan,id'],
|
||||
'nomor_telepon' => ['nullable', 'digits_between:11,13'],
|
||||
'jabatan' => ['required', Rule::enum(JabatanBumdes::class)],
|
||||
'jabatan_lainnya' => ['nullable', 'required_if:jabatan,' . JabatanBumdes::LAINNYA->value, 'string', 'max:255'],
|
||||
'lama_menjabat_tahun' => ['required', 'integer', 'min:0', 'max:80'],
|
||||
], [
|
||||
'nama.required' => 'Nama harus diisi.',
|
||||
'jenis_kelamin.required' => 'Jenis kelamin harus dipilih.',
|
||||
'tempat_lahir.required' => 'Tempat lahir harus diisi.',
|
||||
'tanggal_lahir.required' => 'Tanggal lahir harus diisi.',
|
||||
'tanggal_lahir.date_format' => 'Tanggal lahir harus menggunakan format tanggal yang valid.',
|
||||
'pendidikan_terakhir.required' => 'Pendidikan terakhir harus dipilih.',
|
||||
'alamat.required' => 'Alamat harus diisi.',
|
||||
'desa_kelurahan_id.required' => 'Desa kelurahan harus dipilih.',
|
||||
'desa_kelurahan_id.exists' => 'Desa kelurahan tidak ditemukan.',
|
||||
'nomor_telepon.digits_between' => 'Nomor telepon harus berupa angka 11 sampai 13 digit.',
|
||||
'jabatan.required' => 'Jabatan/peran harus dipilih.',
|
||||
'jabatan_lainnya.required_if' => 'Jabatan lainnya harus diisi.',
|
||||
'lama_menjabat_tahun.required' => 'Lama menjabat harus diisi.',
|
||||
'lama_menjabat_tahun.integer' => 'Lama menjabat harus berupa angka tahun.',
|
||||
]);
|
||||
}
|
||||
|
||||
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 validatedKelembagaanAktorData(Request $request): array
|
||||
{
|
||||
$this->normalizeKelembagaanAktorInput($request);
|
||||
$maxYear = now()->year + 1;
|
||||
|
||||
return $request->validate([
|
||||
'status_badan_hukum' => ['nullable', Rule::in(array_keys($this->statusBadanHukumOptions()))],
|
||||
'nomor_dasar_hukum' => ['nullable', 'string', 'max:255'],
|
||||
'tahun_dasar_hukum' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
|
||||
'status_keaktifan' => ['nullable', Rule::in(array_keys($this->statusKeaktifanOptions()))],
|
||||
'alasan_tidak_aktif' => ['nullable', 'string'],
|
||||
'unit_usaha' => ['nullable', 'array'],
|
||||
'unit_usaha.*' => ['string', Rule::in(array_keys($this->unitUsahaOptions()))],
|
||||
'unit_usaha_jasa_lainnya' => ['nullable', 'string', 'max:255'],
|
||||
'status_unit_komoditas' => ['nullable', Rule::in(array_keys($this->statusUnitKomoditasOptions()))],
|
||||
'nama_unit_komoditas' => ['nullable', 'string', 'max:255'],
|
||||
'status_ad_art' => ['nullable', Rule::in(array_keys($this->statusAdArtOptions()))],
|
||||
'tahun_ad_art' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
|
||||
'pengurus_inti' => ['nullable', 'array'],
|
||||
'pengurus_inti.*.jabatan' => ['nullable', 'string', 'max:255'],
|
||||
'pengurus_inti.*.nama' => ['nullable', 'string', 'max:255'],
|
||||
'pengurus_inti.*.aktif' => ['nullable', 'boolean'],
|
||||
'memiliki_staf' => ['nullable', 'boolean'],
|
||||
'jumlah_staf' => ['nullable', 'integer', 'min:0'],
|
||||
'unit_usaha_staf' => ['nullable', 'string'],
|
||||
'modal_awal' => ['nullable', 'integer', 'min:0'],
|
||||
'tahun_modal_awal' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
|
||||
'pernah_penambahan_modal' => ['nullable', 'boolean'],
|
||||
'penambahan_modal' => ['nullable', 'array'],
|
||||
'penambahan_modal.*.tahun' => ['nullable', 'integer', 'digits:4', 'min:1900', 'max:' . $maxYear],
|
||||
'penambahan_modal.*.jumlah' => ['nullable', 'integer', 'min:0'],
|
||||
'aset_produktif' => ['nullable', 'array'],
|
||||
'aset_produktif.*.aset' => ['nullable', 'string', 'max:255'],
|
||||
'aset_produktif.*.dipilih' => ['nullable', 'boolean'],
|
||||
'aset_produktif.*.jumlah' => ['nullable', 'string', 'max:255'],
|
||||
'aset_produktif.*.kondisi' => ['nullable', 'string', 'max:255'],
|
||||
'aset_produktif_lainnya' => ['nullable', 'string', 'max:255'],
|
||||
'status_kepemilikan_aset' => ['nullable', Rule::in(array_keys($this->statusKepemilikanAsetOptions()))],
|
||||
'infrastruktur_pascapanen' => ['nullable', 'array'],
|
||||
'infrastruktur_pascapanen.*.infrastruktur' => ['nullable', 'string', 'max:255'],
|
||||
'infrastruktur_pascapanen.*.dipilih' => ['nullable', 'boolean'],
|
||||
'infrastruktur_pascapanen.*.jumlah' => ['nullable', 'string', 'max:255'],
|
||||
'infrastruktur_pascapanen.*.kondisi' => ['nullable', Rule::in(array_keys($this->kondisiInfrastrukturOptions()))],
|
||||
'infrastruktur_pascapanen_lainnya' => ['nullable', 'string', 'max:255'],
|
||||
], $this->kelembagaanAktorValidationMessages(), $this->kelembagaanAktorValidationAttributes());
|
||||
}
|
||||
|
||||
private function normalizeKelembagaanAktorInput(Request $request): void
|
||||
{
|
||||
foreach (['modal_awal'] as $field) {
|
||||
if ($request->has($field)) {
|
||||
$request->merge([$field => preg_replace('/\D/', '', (string) $request->input($field))]);
|
||||
}
|
||||
}
|
||||
|
||||
$penambahanModal = collect($request->input('penambahan_modal', []))
|
||||
->map(function ($row) {
|
||||
if (isset($row['jumlah'])) {
|
||||
$row['jumlah'] = preg_replace('/\D/', '', (string) $row['jumlah']);
|
||||
}
|
||||
|
||||
return $row;
|
||||
})
|
||||
->all();
|
||||
|
||||
if ($request->has('penambahan_modal')) {
|
||||
$request->merge(['penambahan_modal' => $penambahanModal]);
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
], $data);
|
||||
|
||||
$payload['unit_usaha'] = array_values($payload['unit_usaha'] ?? []);
|
||||
$payload['pengurus_inti'] = $this->filterRows($payload['pengurus_inti'] ?? [], ['nama', 'aktif']);
|
||||
$payload['penambahan_modal'] = $this->filterRows($payload['penambahan_modal'] ?? [], ['tahun', 'jumlah']);
|
||||
$payload['aset_produktif'] = $this->filterRows($payload['aset_produktif'] ?? [], ['dipilih', 'jumlah', 'kondisi']);
|
||||
$payload['infrastruktur_pascapanen'] = $this->filterRows($payload['infrastruktur_pascapanen'] ?? [], ['dipilih', 'jumlah', 'kondisi']);
|
||||
|
||||
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 [
|
||||
'statusBadanHukumOptions' => $this->statusBadanHukumOptions(),
|
||||
'statusKeaktifanOptions' => $this->statusKeaktifanOptions(),
|
||||
'unitUsahaOptions' => $this->unitUsahaOptions(),
|
||||
'statusUnitKomoditasOptions' => $this->statusUnitKomoditasOptions(),
|
||||
'statusAdArtOptions' => $this->statusAdArtOptions(),
|
||||
'pengurusIntiRows' => $this->pengurusIntiRows(),
|
||||
'asetProduktifRows' => $this->asetProduktifRows(),
|
||||
'statusKepemilikanAsetOptions' => $this->statusKepemilikanAsetOptions(),
|
||||
'infrastrukturPascapanenRows' => $this->infrastrukturPascapanenRows(),
|
||||
'kondisiInfrastrukturOptions' => $this->kondisiInfrastrukturOptions(),
|
||||
];
|
||||
}
|
||||
|
||||
private function statusBadanHukumOptions(): array
|
||||
{
|
||||
return [
|
||||
'sudah_berbadan_hukum' => 'Sudah berbadan hukum (terdaftar Kemenkumham)',
|
||||
'proses_pendaftaran' => 'Proses pendaftaran',
|
||||
'belum_berbadan_hukum' => 'Belum berbadan hukum',
|
||||
'tidak_tahu' => 'Tidak tahu',
|
||||
];
|
||||
}
|
||||
|
||||
private function statusKeaktifanOptions(): array
|
||||
{
|
||||
return [
|
||||
'aktif_penuh' => 'Aktif beroperasi penuh',
|
||||
'aktif_terbatas' => 'Aktif tapi terbatas (sebagian unit usaha berjalan)',
|
||||
'tidak_aktif_vakum' => 'Tidak aktif/vakum',
|
||||
'berdiri_belum_beroperasi' => 'Sudah berdiri tapi belum pernah beroperasi',
|
||||
];
|
||||
}
|
||||
|
||||
private function unitUsahaOptions(): array
|
||||
{
|
||||
return [
|
||||
'simpan_pinjam' => 'Simpan pinjam',
|
||||
'perdagangan_toko_desa' => 'Perdagangan/toko desa',
|
||||
'pengelolaan_air_bersih' => 'Pengelolaan air bersih',
|
||||
'wisata_desa_agrowisata' => 'Wisata desa/agrowisata',
|
||||
'pengelolaan_hasil_pertanian_komoditas' => 'Pengelolaan hasil pertanian/komoditas',
|
||||
'penyewaan_alat_aset' => 'Penyewaan alat/aset',
|
||||
'jasa_lainnya' => 'Jasa lainnya',
|
||||
];
|
||||
}
|
||||
|
||||
private function statusUnitKomoditasOptions(): array
|
||||
{
|
||||
return [
|
||||
'ya' => 'Ya, ada unit khusus',
|
||||
'ditangani_pengurus_inti' => 'Tidak ada unit khusus, ditangani langsung pengurus inti',
|
||||
'direncanakan' => 'Belum ada, masih direncanakan',
|
||||
];
|
||||
}
|
||||
|
||||
private function statusAdArtOptions(): array
|
||||
{
|
||||
return [
|
||||
'ada_lengkap' => 'Ada, lengkap',
|
||||
'ada_tidak_lengkap' => 'Ada tapi tidak lengkap',
|
||||
'tidak_ada' => 'Tidak ada',
|
||||
'tidak_tahu' => 'Tidak tahu',
|
||||
];
|
||||
}
|
||||
|
||||
private function pengurusIntiRows(): array
|
||||
{
|
||||
return [
|
||||
'penasihat_kepala_desa' => 'Penasihat (Kepala Desa)',
|
||||
'ketua_pengawas' => 'Ketua Pengawas',
|
||||
'direktur_ketua_bumdes' => 'Direktur/Ketua BUMDes',
|
||||
'sekretaris' => 'Sekretaris',
|
||||
'bendahara' => 'Bendahara',
|
||||
'kepala_unit_usaha_komoditas' => 'Kepala Unit Usaha Komoditas',
|
||||
'lainnya' => 'Lainnya',
|
||||
];
|
||||
}
|
||||
|
||||
private function asetProduktifRows(): array
|
||||
{
|
||||
return [
|
||||
'bangunan_kantor' => 'Bangunan / kantor',
|
||||
'gudang_penyimpanan' => 'Gudang penyimpanan',
|
||||
'kendaraan_operasional_angkut' => 'Kendaraan operasional/angkut',
|
||||
'lahan_usaha' => 'Lahan usaha',
|
||||
'alat_pengolahan_komoditas' => 'Alat pengolahan komoditas',
|
||||
'lainnya' => 'Lainnya',
|
||||
];
|
||||
}
|
||||
|
||||
private function statusKepemilikanAsetOptions(): array
|
||||
{
|
||||
return [
|
||||
'milik_bumdes_sendiri' => 'Milik BUMDes sendiri',
|
||||
'milik_desa_dipinjamkan_dikelola' => 'Milik desa (dipinjamkan/dikelola)',
|
||||
'sewa_pinjam_pihak_lain' => 'Sewa/pinjam pihak lain',
|
||||
];
|
||||
}
|
||||
|
||||
private function infrastrukturPascapanenRows(): array
|
||||
{
|
||||
return [
|
||||
'gudang_penyimpanan_hasil_panen' => 'Gudang penyimpanan hasil panen',
|
||||
'alat_mesin_pengering' => 'Alat/mesin pengering',
|
||||
'mesin_pulper_huller' => 'Mesin pulper/huller',
|
||||
'timbangan' => 'Timbangan',
|
||||
'alat_sortasi' => 'Alat sortasi',
|
||||
'lainnya' => 'Lainnya',
|
||||
];
|
||||
}
|
||||
|
||||
private function kondisiInfrastrukturOptions(): array
|
||||
{
|
||||
return [
|
||||
'baik_berfungsi' => 'Baik dan berfungsi',
|
||||
'rusak_tidak_terpakai' => 'Rusak/tidak terpakai',
|
||||
];
|
||||
}
|
||||
|
||||
private function kelembagaanAktorValidationMessages(): array
|
||||
{
|
||||
return [
|
||||
'integer' => ':attribute harus berupa angka.',
|
||||
'digits' => ':attribute harus terdiri dari :digits digit.',
|
||||
'min' => ':attribute tidak boleh kurang dari :min.',
|
||||
'max' => ':attribute tidak valid.',
|
||||
'in' => ':attribute tidak valid.',
|
||||
'array' => ':attribute harus berupa daftar data.',
|
||||
'boolean' => ':attribute harus dipilih.',
|
||||
];
|
||||
}
|
||||
|
||||
private function kelembagaanAktorValidationAttributes(): array
|
||||
{
|
||||
return [
|
||||
'status_badan_hukum' => 'Status badan hukum',
|
||||
'nomor_dasar_hukum' => 'Nomor dasar hukum',
|
||||
'tahun_dasar_hukum' => 'Tahun dasar hukum',
|
||||
'status_keaktifan' => 'Status keaktifan',
|
||||
'unit_usaha' => 'Unit usaha',
|
||||
'status_unit_komoditas' => 'Unit usaha komoditas',
|
||||
'status_ad_art' => 'Dokumen AD/ART',
|
||||
'memiliki_staf' => 'Status staf/karyawan',
|
||||
'jumlah_staf' => 'Jumlah staf',
|
||||
'modal_awal' => 'Modal awal',
|
||||
'tahun_modal_awal' => 'Tahun modal awal',
|
||||
'pernah_penambahan_modal' => 'Status penambahan modal',
|
||||
'status_kepemilikan_aset' => 'Status kepemilikan aset',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Dashboard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
use App\Models\Pertanian\Petani;
|
||||
use App\Models\Pertanian\Komoditas;
|
||||
use App\Models\Pertanian\Lahan;
|
||||
use App\Models\Pertanian\PendapatanKomoditas;
|
||||
use App\Models\Pertanian\SosialEkonomi;
|
||||
|
||||
class DemografiPetaniController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
return redirect()->route('dashboard.karakteristik-petani', array_merge($request->query(), [
|
||||
'tab' => 'demografi-petani',
|
||||
]));
|
||||
}
|
||||
|
||||
public function karakteristik(Request $request)
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$activeTab = $request->query('tab') === 'indeks-petani'
|
||||
? 'indeks-petani'
|
||||
: 'demografi-petani';
|
||||
|
||||
$demografiData = $this->contentData($request);
|
||||
$indeksData = app(IndeksPetaniController::class)->contentData($request);
|
||||
|
||||
$tableFilters = [
|
||||
'gender' => ['Gender', ['1' => 'Laki-laki', '0' => 'Perempuan']],
|
||||
'umur' => ['Kelompok Umur', ['kurang_30' => '< 30 tahun', '30_39' => '30–39 tahun', '40_49' => '40–49 tahun', '50_59' => '50–59 tahun', '60_keatas' => '≥ 60 tahun']],
|
||||
'pendidikan' => ['Pendidikan', ['tidak_sekolah' => 'Tidak Sekolah', 'sd' => 'SD', 'smp' => 'SMP', 'sma' => 'SMA', 'diploma' => 'Diploma', 's1_keatas' => 'Sarjana ke atas']],
|
||||
'jumlah_tanggungan' => ['Jumlah Tanggungan', ['0' => '0 orang', '1_2' => '1–2 orang', '3_4' => '3–4 orang', '5_keatas' => '≥ 5 orang']],
|
||||
'kelompok_tani' => ['Keanggotaan Kelompok Tani', ['terdaftar' => 'Terdaftar', 'tidak_terdaftar' => 'Tidak Terdaftar', 'belum_terisi' => 'Belum Terisi']],
|
||||
'komoditas' => ['Komoditas', $indeksData['komoditas']->pluck('nama', 'id')->all()],
|
||||
'luas_lahan' => ['Luas Lahan', ['kurang_05' => '< 0,5 ha', '05_1' => '0,5–1 ha', '1_2' => '> 1–2 ha', 'lebih_2' => '> 2 ha']],
|
||||
'status_kepemilikan_lahan' => ['Status Kepemilikan Lahan', ['sendiri' => 'Milik Pribadi', 'sewa' => 'Sewa', 'adat' => 'Tanah Adat']],
|
||||
'penghasilan' => ['Rentang Pendapatan', ['kurang_1' => '< Rp1 juta', '1_3' => 'Rp1–3 juta', '3_5' => '> Rp3–5 juta', '5_10' => '> Rp5–10 juta', 'lebih_10' => '> Rp10 juta']],
|
||||
];
|
||||
|
||||
return view('dashboard.karakteristik-petani', [
|
||||
'activeTab' => $activeTab,
|
||||
'tableFilters' => $tableFilters,
|
||||
'dashboardFilters' => $request->only([
|
||||
'provinsi_id',
|
||||
'kabupatenKota_id',
|
||||
'kecamatan_id',
|
||||
'desaKelurahan_id',
|
||||
'komoditas_id',
|
||||
'segmen',
|
||||
]),
|
||||
'indeksFilterAction' => route('dashboard.karakteristik-petani'),
|
||||
] + $demografiData + $indeksData);
|
||||
}
|
||||
|
||||
public function contentData(Request $request): array
|
||||
{
|
||||
$filteredPetaniIds = $this->filteredPetaniIdsQuery($request);
|
||||
|
||||
$petaniCounts = Petani::whereIn('petani.id', clone $filteredPetaniIds)->selectRaw("
|
||||
COUNT(*) as total,
|
||||
COUNT(*) FILTER (WHERE jenis_kelamin = true) as laki,
|
||||
COUNT(*) FILTER (WHERE jenis_kelamin = false) as perempuan
|
||||
")->first();
|
||||
|
||||
$totalPetani = $petaniCounts->total;
|
||||
$petaniLakilaki = $petaniCounts->laki;
|
||||
$petaniPerempuan = $petaniCounts->perempuan;
|
||||
|
||||
$totalKomoditas = Komoditas::query()
|
||||
->where('is_utama', true)
|
||||
->whereHas('petani', fn ($query) => $query->whereIn('petani.id', clone $filteredPetaniIds))
|
||||
->count();
|
||||
|
||||
$totalLuasLahan = Lahan::has('petani')
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->sum('luas_lahan');
|
||||
$ratarataLuasLahan = $totalLuasLahan && $totalPetani ? $totalLuasLahan / $totalPetani : 0;
|
||||
|
||||
$umurCounts = Petani::whereIn('petani.id', clone $filteredPetaniIds)
|
||||
->whereNotNull('tanggal_lahir')->selectRaw("
|
||||
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) < 30) as kurang_30,
|
||||
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 39) as umur_30_39,
|
||||
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 49) as umur_40_49,
|
||||
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 59) as umur_50_59,
|
||||
COUNT(*) FILTER (WHERE EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60) as umur_60_keatas
|
||||
")->first();
|
||||
|
||||
$pendidikanCounts = Petani::whereIn('petani.id', clone $filteredPetaniIds)
|
||||
->whereNotNull('pendidikan_terakhir')
|
||||
->select('pendidikan_terakhir', DB::raw('COUNT(*) as total'))
|
||||
->groupBy('pendidikan_terakhir')
|
||||
->pluck('total', 'pendidikan_terakhir');
|
||||
|
||||
$pendidikan = [
|
||||
'tidak_sekolah' => (int) ($pendidikanCounts['01_tidak_sekolah'] ?? 0),
|
||||
'sd' => (int) ($pendidikanCounts['02_sd'] ?? 0),
|
||||
'smp' => (int) ($pendidikanCounts['03_smp'] ?? 0),
|
||||
'sma' => (int) ($pendidikanCounts['04_sma'] ?? 0),
|
||||
'diploma' => (int) ($pendidikanCounts['05_diploma'] ?? 0),
|
||||
's1_keatas' => (int) ($pendidikanCounts['06_sarjana'] ?? 0) + (int) ($pendidikanCounts['07_magister'] ?? 0),
|
||||
];
|
||||
|
||||
$jumlahTanggunganBuckets = SosialEkonomi::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->whereNotNull('jumlah_tanggungan')
|
||||
->selectRaw("
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan = 0) as tanggungan_0,
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan BETWEEN 1 AND 2) as tanggungan_1_2,
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan BETWEEN 3 AND 4) as tanggungan_3_4,
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE jumlah_tanggungan >= 5) as tanggungan_5_keatas
|
||||
")
|
||||
->first();
|
||||
|
||||
$jumlahTanggungan = [
|
||||
'0' => (int) ($jumlahTanggunganBuckets->tanggungan_0 ?? 0),
|
||||
'1_2' => (int) ($jumlahTanggunganBuckets->tanggungan_1_2 ?? 0),
|
||||
'3_4' => (int) ($jumlahTanggunganBuckets->tanggungan_3_4 ?? 0),
|
||||
'5_keatas' => (int) ($jumlahTanggunganBuckets->tanggungan_5_keatas ?? 0),
|
||||
];
|
||||
|
||||
$kelompokTaniBuckets = Petani::query()
|
||||
->whereIn('petani.id', clone $filteredPetaniIds)
|
||||
->leftJoin('sosial_ekonomi', function ($join) {
|
||||
$join->on('sosial_ekonomi.petani_id', '=', 'petani.id')
|
||||
->whereNull('sosial_ekonomi.deleted_at');
|
||||
})
|
||||
->selectRaw("
|
||||
COUNT(DISTINCT petani.id) FILTER (WHERE sosial_ekonomi.terdaftar_kelompok_tani = 'ya') as terdaftar,
|
||||
COUNT(DISTINCT petani.id) FILTER (WHERE sosial_ekonomi.terdaftar_kelompok_tani = 'tidak') as tidak_terdaftar,
|
||||
COUNT(DISTINCT petani.id) FILTER (WHERE sosial_ekonomi.terdaftar_kelompok_tani IS NULL OR sosial_ekonomi.terdaftar_kelompok_tani NOT IN ('ya', 'tidak')) as belum_terisi
|
||||
")
|
||||
->first();
|
||||
|
||||
$kelompokTani = [
|
||||
'terdaftar' => (int) ($kelompokTaniBuckets->terdaftar ?? 0),
|
||||
'tidak_terdaftar' => (int) ($kelompokTaniBuckets->tidak_terdaftar ?? 0),
|
||||
'belum_terisi' => (int) ($kelompokTaniBuckets->belum_terisi ?? 0),
|
||||
];
|
||||
|
||||
$desaSasaranRows = Petani::query()
|
||||
->leftJoin('master_desa_kelurahan as desa', 'petani.desa_kelurahan_id', '=', 'desa.id')
|
||||
->whereIn('petani.id', clone $filteredPetaniIds)
|
||||
->selectRaw('petani.desa_kelurahan_id as desa_id')
|
||||
->selectRaw("COALESCE(desa.nama, 'Tidak diketahui') as desa")
|
||||
->selectRaw('COUNT(*) as total')
|
||||
->groupBy('petani.desa_kelurahan_id', 'desa.nama')
|
||||
->orderByDesc('total')
|
||||
->orderBy('desa')
|
||||
->get();
|
||||
|
||||
$komoditasUtama = Komoditas::query()
|
||||
->whereHas('petani', fn ($query) => $query->whereIn('petani.id', clone $filteredPetaniIds))
|
||||
->withCount(['petani' => fn ($query) => $query->whereIn('petani.id', clone $filteredPetaniIds)])
|
||||
->orderByDesc('petani_count')
|
||||
->get(['id', 'nama']);
|
||||
|
||||
$luasLahanBuckets = DB::query()->fromSub(
|
||||
Lahan::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->select('petani_id')
|
||||
->selectRaw('luas_lahan'),
|
||||
'agg'
|
||||
)->selectRaw("
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan < 0.5) as kurang_05,
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan >= 0.5 AND luas_lahan <= 1) as luas_05_1,
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan > 1 AND luas_lahan <= 2) as luas_1_2,
|
||||
COUNT(DISTINCT petani_id) FILTER (WHERE luas_lahan > 2) as lebih_2
|
||||
")->first();
|
||||
|
||||
$luasLahan = [
|
||||
'kurang_05' => $luasLahanBuckets->kurang_05,
|
||||
'05_1' => $luasLahanBuckets->luas_05_1,
|
||||
'1_2' => $luasLahanBuckets->luas_1_2,
|
||||
'lebih_2' => $luasLahanBuckets->lebih_2,
|
||||
];
|
||||
|
||||
$statusKepemilikanLahanRows = Lahan::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->whereNotNull('status_kepemilikan')
|
||||
->selectRaw('status_kepemilikan as status')
|
||||
->selectRaw('COUNT(DISTINCT petani_id) as total')
|
||||
->groupBy('status_kepemilikan')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
$pendapatanPerPetaniQuery = PendapatanKomoditas::query()
|
||||
->join('sosial_ekonomi', 'sosial_ekonomi.id', '=', 'pendapatan_komoditas.sosial_ekonomi_id')
|
||||
->whereNotNull('sosial_ekonomi.petani_id')
|
||||
->whereIn('sosial_ekonomi.petani_id', clone $filteredPetaniIds)
|
||||
->groupBy('sosial_ekonomi.petani_id')
|
||||
->selectRaw('SUM(pendapatan_komoditas.pendapatan) as total_pendapatan');
|
||||
|
||||
$penghasilanBuckets = DB::query()->fromSub(
|
||||
clone $pendapatanPerPetaniQuery,
|
||||
'agg'
|
||||
)->selectRaw("
|
||||
AVG(total_pendapatan) as rata_rata,
|
||||
COUNT(*) FILTER (WHERE total_pendapatan < 1000000) as kurang_1,
|
||||
COUNT(*) FILTER (WHERE total_pendapatan >= 1000000 AND total_pendapatan <= 3000000) as p1_3,
|
||||
COUNT(*) FILTER (WHERE total_pendapatan > 3000000 AND total_pendapatan <= 5000000) as p3_5,
|
||||
COUNT(*) FILTER (WHERE total_pendapatan > 5000000 AND total_pendapatan <= 10000000) as p5_10,
|
||||
COUNT(*) FILTER (WHERE total_pendapatan > 10000000) as lebih_10
|
||||
")->first();
|
||||
|
||||
$ratarataPenghasilan = (float) ($penghasilanBuckets->rata_rata ?? 0);
|
||||
|
||||
$penghasilan = [
|
||||
'kurang_1' => $penghasilanBuckets->kurang_1,
|
||||
'1_3' => $penghasilanBuckets->p1_3,
|
||||
'3_5' => $penghasilanBuckets->p3_5,
|
||||
'5_10' => $penghasilanBuckets->p5_10,
|
||||
'lebih_10' => $penghasilanBuckets->lebih_10,
|
||||
];
|
||||
|
||||
$data = [
|
||||
'total_petani' => $totalPetani,
|
||||
'petani_lakilaki' => $petaniLakilaki,
|
||||
'petani_perempuan' => $petaniPerempuan,
|
||||
'total_komoditas' => $totalKomoditas,
|
||||
'total_luas_lahan' => $totalLuasLahan,
|
||||
'ratarata_luas_lahan' => $ratarataLuasLahan,
|
||||
'ratarata_penghasilan' => $ratarataPenghasilan,
|
||||
'kelompok_umur' => [
|
||||
'kurang_30' => $umurCounts->kurang_30,
|
||||
'30_39' => $umurCounts->umur_30_39,
|
||||
'40_49' => $umurCounts->umur_40_49,
|
||||
'50_59' => $umurCounts->umur_50_59,
|
||||
'60_keatas' => $umurCounts->umur_60_keatas,
|
||||
],
|
||||
'pendidikan' => $pendidikan,
|
||||
'jumlah_tanggungan' => $jumlahTanggungan,
|
||||
'kelompok_tani' => $kelompokTani,
|
||||
'desa_sasaran' => [
|
||||
'total' => $desaSasaranRows->count(),
|
||||
'ids' => $desaSasaranRows->pluck('desa_id')->values(),
|
||||
'labels' => $desaSasaranRows->pluck('desa')->values(),
|
||||
'series' => $desaSasaranRows->pluck('total')->map(fn ($v) => (int) $v)->values(),
|
||||
],
|
||||
'komoditas_utama' => [
|
||||
'ids' => $komoditasUtama->pluck('id')->values(),
|
||||
'labels' => $komoditasUtama->pluck('nama')->values(),
|
||||
'series' => $komoditasUtama->pluck('petani_count')->map(fn ($v) => (int) $v)->values(),
|
||||
],
|
||||
'luas_lahan' => $luasLahan,
|
||||
'status_kepemilikan_lahan' => [
|
||||
'keys' => $statusKepemilikanLahanRows->pluck('status')->values(),
|
||||
'labels' => $statusKepemilikanLahanRows
|
||||
->pluck('status')
|
||||
->map(fn ($status) => $this->statusLahanLabel((string) $status))
|
||||
->values(),
|
||||
'series' => $statusKepemilikanLahanRows->pluck('total')->map(fn ($v) => (int) $v)->values(),
|
||||
],
|
||||
'penghasilan' => $penghasilan,
|
||||
];
|
||||
|
||||
return compact('data');
|
||||
}
|
||||
|
||||
private function filteredPetaniIdsQuery(Request $request)
|
||||
{
|
||||
$query = Petani::query()
|
||||
->leftJoin('master_desa_kelurahan as desa', 'petani.desa_kelurahan_id', '=', 'desa.id')
|
||||
->leftJoin('master_kecamatan as kecamatan', 'desa.kecamatan_id', '=', 'kecamatan.id')
|
||||
->leftJoin('master_kabupaten_kota as kabupaten', 'kecamatan.kabupaten_kota_id', '=', 'kabupaten.id')
|
||||
->when($request->filled('provinsi_id'), fn ($query) => $query->where('kabupaten.provinsi_id', $request->provinsi_id))
|
||||
->when($request->filled('kabupatenKota_id'), fn ($query) => $query->where('kecamatan.kabupaten_kota_id', $request->kabupatenKota_id))
|
||||
->when($request->filled('kecamatan_id'), fn ($query) => $query->where('desa.kecamatan_id', $request->kecamatan_id))
|
||||
->when($request->filled('desaKelurahan_id'), fn ($query) => $query->where('petani.desa_kelurahan_id', $request->desaKelurahan_id))
|
||||
->when($request->filled('komoditas_id'), fn ($query) => $query->where('petani.komoditas_id', $request->komoditas_id));
|
||||
|
||||
if ($request->filled('segmen')) {
|
||||
$query->whereHas('skor', function ($query) use ($request) {
|
||||
match ($request->segmen) {
|
||||
'Penggerak' => $query->where('skor_kesiapan_adopsi', '>=', 4),
|
||||
'Perintis' => $query->where('skor_kesiapan_adopsi', '>=', 3)
|
||||
->where('skor_kesiapan_adopsi', '<', 4),
|
||||
'Pemerhati' => $query->where('skor_kesiapan_adopsi', '>=', 2)
|
||||
->where('skor_kesiapan_adopsi', '<', 3),
|
||||
'Pemula' => $query->where('skor_kesiapan_adopsi', '>=', 1)
|
||||
->where('skor_kesiapan_adopsi', '<', 2),
|
||||
'Belum Lengkap' => $query->where(function ($query) {
|
||||
$query->whereNull('skor_kesiapan_adopsi')
|
||||
->orWhere('skor_kesiapan_adopsi', '<', 1);
|
||||
}),
|
||||
default => null,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
return $query->select('petani.id');
|
||||
}
|
||||
|
||||
private function statusLahanLabel(string $status): string
|
||||
{
|
||||
return match ($status) {
|
||||
'sendiri' => 'Milik Pribadi',
|
||||
'sewa' => 'Sewa',
|
||||
'adat' => 'Tanah Adat',
|
||||
default => ucwords(str_replace('_', ' ', $status)),
|
||||
};
|
||||
}
|
||||
|
||||
public function data(Request $request)
|
||||
{
|
||||
$filteredPetaniIds = $this->filteredPetaniIdsQuery($request);
|
||||
$pendapatanSub = PendapatanKomoditas::query()
|
||||
->join('sosial_ekonomi', 'sosial_ekonomi.id', '=', 'pendapatan_komoditas.sosial_ekonomi_id')
|
||||
->whereColumn('sosial_ekonomi.petani_id', 'petani.id')
|
||||
->selectRaw('SUM(pendapatan_komoditas.pendapatan)');
|
||||
|
||||
$query = Petani::with('komoditas')
|
||||
->whereIn('petani.id', clone $filteredPetaniIds)
|
||||
->withSum('lahans as total_luas_lahan', 'luas_lahan')
|
||||
->addSelect(['total_pendapatan' => $pendapatanSub]);
|
||||
|
||||
if ($request->filled('search')) {
|
||||
$query->where('nama', 'ILIKE', "%{$request->search}%");
|
||||
}
|
||||
|
||||
if ($request->has('gender') && $request->gender !== '') {
|
||||
$query->where('jenis_kelamin', $request->gender);
|
||||
}
|
||||
|
||||
if ($request->filled('umur')) {
|
||||
match ($request->umur) {
|
||||
'kurang_30' => $query->whereNotNull('tanggal_lahir')
|
||||
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) < 30"),
|
||||
'30_39' => $query->whereNotNull('tanggal_lahir')
|
||||
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 30 AND 39"),
|
||||
'40_49' => $query->whereNotNull('tanggal_lahir')
|
||||
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 40 AND 49"),
|
||||
'50_59' => $query->whereNotNull('tanggal_lahir')
|
||||
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) BETWEEN 50 AND 59"),
|
||||
'60_keatas' => $query->whereNotNull('tanggal_lahir')
|
||||
->whereRaw("EXTRACT(YEAR FROM AGE(CURRENT_DATE, tanggal_lahir)) >= 60"),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
if ($request->filled('pendidikan')) {
|
||||
$pendidikanMap = [
|
||||
'tidak_sekolah' => ['01_tidak_sekolah'],
|
||||
'sd' => ['02_sd'],
|
||||
'smp' => ['03_smp'],
|
||||
'sma' => ['04_sma'],
|
||||
'diploma' => ['05_diploma'],
|
||||
's1_keatas' => ['06_sarjana', '07_magister'],
|
||||
];
|
||||
|
||||
if (isset($pendidikanMap[$request->pendidikan])) {
|
||||
$query->whereIn('pendidikan_terakhir', $pendidikanMap[$request->pendidikan]);
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->filled('jumlah_tanggungan')) {
|
||||
$tanggunganQuery = SosialEkonomi::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->whereNotNull('jumlah_tanggungan')
|
||||
->select('petani_id')
|
||||
->distinct();
|
||||
|
||||
match ($request->jumlah_tanggungan) {
|
||||
'0' => $tanggunganQuery->where('jumlah_tanggungan', 0),
|
||||
'1_2' => $tanggunganQuery->whereBetween('jumlah_tanggungan', [1, 2]),
|
||||
'3_4' => $tanggunganQuery->whereBetween('jumlah_tanggungan', [3, 4]),
|
||||
'5_keatas' => $tanggunganQuery->where('jumlah_tanggungan', '>=', 5),
|
||||
default => null,
|
||||
};
|
||||
|
||||
$query->whereIn('petani.id', $tanggunganQuery);
|
||||
}
|
||||
|
||||
if ($request->filled('kelompok_tani')) {
|
||||
match ($request->kelompok_tani) {
|
||||
'terdaftar' => $query->whereIn('petani.id', SosialEkonomi::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->where('terdaftar_kelompok_tani', 'ya')
|
||||
->select('petani_id')
|
||||
->distinct()),
|
||||
'tidak_terdaftar' => $query->whereIn('petani.id', SosialEkonomi::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->where('terdaftar_kelompok_tani', 'tidak')
|
||||
->select('petani_id')
|
||||
->distinct()),
|
||||
'belum_terisi' => $query->whereNotIn('petani.id', SosialEkonomi::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->whereIn('terdaftar_kelompok_tani', ['ya', 'tidak'])
|
||||
->select('petani_id')
|
||||
->distinct()),
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
if ($request->filled('komoditas')) {
|
||||
$query->where('komoditas_id', $request->komoditas);
|
||||
}
|
||||
|
||||
if ($request->filled('penghasilan')) {
|
||||
[$min, $max] = match ($request->penghasilan) {
|
||||
'kurang_1' => [null, 999999],
|
||||
'1_3' => [1000000, 3000000],
|
||||
'3_5' => [3000001, 5000000],
|
||||
'5_10' => [5000001, 10000000],
|
||||
'lebih_10' => [10000001, null],
|
||||
default => [null, null],
|
||||
};
|
||||
|
||||
$query->whereIn('id', function ($sub) use ($min, $max) {
|
||||
$sub->from('pendapatan_komoditas')
|
||||
->join('sosial_ekonomi', 'sosial_ekonomi.id', '=', 'pendapatan_komoditas.sosial_ekonomi_id')
|
||||
->whereNotNull('sosial_ekonomi.petani_id')
|
||||
->groupBy('sosial_ekonomi.petani_id')
|
||||
->select('sosial_ekonomi.petani_id')
|
||||
->when($min !== null, fn ($q) => $q->havingRaw('SUM(pendapatan_komoditas.pendapatan) >= ?', [$min]))
|
||||
->when($max !== null, fn ($q) => $q->havingRaw('SUM(pendapatan_komoditas.pendapatan) <= ?', [$max]));
|
||||
});
|
||||
}
|
||||
|
||||
if ($request->filled('luas_lahan')) {
|
||||
$lahanQuery = Lahan::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->select('petani_id')
|
||||
->distinct();
|
||||
|
||||
match ($request->luas_lahan) {
|
||||
'kurang_05' => $lahanQuery->where('luas_lahan', '<', 0.5),
|
||||
'05_1' => $lahanQuery->whereBetween('luas_lahan', [0.5, 1]),
|
||||
'1_2' => $lahanQuery->where('luas_lahan', '>', 1)->where('luas_lahan', '<=', 2),
|
||||
'lebih_2' => $lahanQuery->where('luas_lahan', '>', 2),
|
||||
default => null,
|
||||
};
|
||||
|
||||
$query->whereIn('petani.id', $lahanQuery);
|
||||
}
|
||||
|
||||
if ($request->filled('status_kepemilikan_lahan')) {
|
||||
$query->whereIn('petani.id', Lahan::query()
|
||||
->whereIn('petani_id', clone $filteredPetaniIds)
|
||||
->where('status_kepemilikan', $request->status_kepemilikan_lahan)
|
||||
->select('petani_id')
|
||||
->distinct());
|
||||
}
|
||||
|
||||
$daftarPetani = $query->orderBy('id')->paginate(10);
|
||||
|
||||
$pendidikanLabels = [
|
||||
'01_tidak_sekolah' => 'Tidak Sekolah',
|
||||
'02_sd' => 'SD',
|
||||
'03_smp' => 'SMP',
|
||||
'04_sma' => 'SMA',
|
||||
'05_diploma' => 'Diploma',
|
||||
'06_sarjana' => 'Sarjana',
|
||||
'07_magister' => 'Magister',
|
||||
];
|
||||
|
||||
$rows = collect($daftarPetani->items())->map(function ($petani) use ($pendidikanLabels) {
|
||||
$umur = $petani->tanggal_lahir ? \Carbon\Carbon::parse($petani->tanggal_lahir)->age : null;
|
||||
$pendidikanRaw = $petani->getRawOriginal('pendidikan_terakhir');
|
||||
$pendapatan = $petani->total_pendapatan;
|
||||
|
||||
$rentangPenghasilan = match (true) {
|
||||
$pendapatan === null => '-',
|
||||
$pendapatan < 1000000 => '< Rp1 juta',
|
||||
$pendapatan <= 3000000 => 'Rp1 - 3 juta',
|
||||
$pendapatan <= 5000000 => 'Rp3 - 5 juta',
|
||||
$pendapatan <= 10000000 => 'Rp5 - 10 juta',
|
||||
default => '> Rp10 juta',
|
||||
};
|
||||
|
||||
return [
|
||||
'id' => $petani->id,
|
||||
'nama' => $petani->nama ?? '-',
|
||||
'jenis_kelamin' => $petani->jenis_kelamin,
|
||||
'gender' => $petani->jenis_kelamin == 1 ? 'Laki-laki' : 'Perempuan',
|
||||
'umur' => $umur,
|
||||
'komoditas' => $petani->komoditas?->nama ?? '-',
|
||||
'luas_lahan' => (float) ($petani->total_luas_lahan ?? 0),
|
||||
'pendidikan' => $pendidikanLabels[$pendidikanRaw] ?? '-',
|
||||
'rentang_penghasilan' => $rentangPenghasilan,
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'data' => $rows,
|
||||
'pagination' => [
|
||||
'current_page' => $daftarPetani->currentPage(),
|
||||
'last_page' => $daftarPetani->lastPage(),
|
||||
'per_page' => $daftarPetani->perPage(),
|
||||
'total' => $daftarPetani->total(),
|
||||
'from' => $daftarPetani->firstItem(),
|
||||
'to' => $daftarPetani->lastItem(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Dashboard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
|
||||
class DistribusiController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (!Gate::allows('super_admin') && !Gate::allows('admin')) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$title = 'Distribusi Dashboard';
|
||||
|
||||
return view('dashboard.distribusi', compact('title'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,590 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Dashboard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
use App\Models\Pertanian\Petani;
|
||||
use App\Models\Pertanian\Komoditas;
|
||||
use App\Models\Pertanian\Lahan;
|
||||
use App\Models\Pertanian\SkorPetani;
|
||||
|
||||
|
||||
class IndeksPetaniController extends Controller
|
||||
{
|
||||
|
||||
private function filters(Request $request): array
|
||||
{
|
||||
return [
|
||||
'desaKelurahan_id' => $request->desaKelurahan_id,
|
||||
'kecamatan_id' => $request->kecamatan_id,
|
||||
'kabupatenKota_id' => $request->kabupatenKota_id,
|
||||
'provinsi_id' => $request->provinsi_id,
|
||||
'komoditas_id' => $request->komoditas_id,
|
||||
'segmen' => $request->segmen,
|
||||
];
|
||||
}
|
||||
|
||||
private function petaniQuery(array $filters): Builder
|
||||
{
|
||||
$petaniQuery = Petani::query()
|
||||
->leftJoin('master_desa_kelurahan', 'petani.desa_kelurahan_id', '=', 'master_desa_kelurahan.id')
|
||||
->leftJoin('master_kecamatan', 'master_desa_kelurahan.kecamatan_id', '=', 'master_kecamatan.id')
|
||||
->leftJoin('master_kabupaten_kota', 'master_kecamatan.kabupaten_kota_id', '=', 'master_kabupaten_kota.id')
|
||||
->leftJoin('master_provinsi', 'master_kabupaten_kota.provinsi_id', '=', 'master_provinsi.id')
|
||||
->whereNull('petani.deleted_at')
|
||||
->when($filters['provinsi_id'], fn($q, $id) => $q->where('master_kabupaten_kota.provinsi_id', $id))
|
||||
->when($filters['kabupatenKota_id'], fn($q, $id) => $q->where('master_kecamatan.kabupaten_kota_id', $id))
|
||||
->when($filters['kecamatan_id'], fn($q, $id) => $q->where('master_desa_kelurahan.kecamatan_id', $id))
|
||||
->when($filters['desaKelurahan_id'], fn($q, $id) => $q->where('petani.desa_kelurahan_id', $id))
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('petani.komoditas_id', $id));
|
||||
|
||||
if ($filters['segmen']) {
|
||||
$petaniQuery->whereHas('skor', fn (Builder $query) => $this->applySegmentFilter($query, $filters['segmen']));
|
||||
}
|
||||
|
||||
return $petaniQuery;
|
||||
}
|
||||
|
||||
private function skorPetaniQuery(array $filters, array $komoditas): Builder
|
||||
{
|
||||
$skor = SkorPetani::query()
|
||||
->join('petani', 'petani_skor.petani_id', '=', 'petani.id')
|
||||
->leftJoin('master_desa_kelurahan', 'petani.desa_kelurahan_id', '=', 'master_desa_kelurahan.id')
|
||||
->leftJoin('master_kecamatan', 'master_desa_kelurahan.kecamatan_id', '=', 'master_kecamatan.id')
|
||||
->leftJoin('master_kabupaten_kota', 'master_kecamatan.kabupaten_kota_id', '=', 'master_kabupaten_kota.id')
|
||||
->leftJoin('master_provinsi', 'master_kabupaten_kota.provinsi_id', '=', 'master_provinsi.id')
|
||||
->whereNull('petani.deleted_at')
|
||||
->when($filters['provinsi_id'], fn($q, $id) => $q->where('master_kabupaten_kota.provinsi_id', $id))
|
||||
->when($filters['kabupatenKota_id'], fn($q, $id) => $q->where('master_kecamatan.kabupaten_kota_id', $id))
|
||||
->when($filters['kecamatan_id'], fn($q, $id) => $q->where('master_desa_kelurahan.kecamatan_id', $id))
|
||||
->when($filters['desaKelurahan_id'], fn($q, $id) => $q->where('petani.desa_kelurahan_id', $id))
|
||||
->whereIn('petani.komoditas_id', $komoditas);
|
||||
|
||||
return $this->applySegmentFilter($skor, $filters['segmen']);
|
||||
}
|
||||
|
||||
private function applySegmentFilter(Builder $query, ?string $segment): Builder
|
||||
{
|
||||
$ranges = [
|
||||
'Penggerak' => [4, null],
|
||||
'Perintis' => [3, 4],
|
||||
'Pemerhati' => [2, 3],
|
||||
'Pemula' => [1, 2],
|
||||
];
|
||||
|
||||
if (isset($ranges[$segment])) {
|
||||
[$min, $max] = $ranges[$segment];
|
||||
|
||||
return $query->where('skor_kesiapan_adopsi', '>=', $min)
|
||||
->when($max !== null, fn (Builder $query) => $query->where('skor_kesiapan_adopsi', '<', $max));
|
||||
}
|
||||
|
||||
if ($segment === 'Belum Lengkap') {
|
||||
$query->where(fn (Builder $query) => $query->whereNull('skor_kesiapan_adopsi')
|
||||
->orWhere('skor_kesiapan_adopsi', '<', 1));
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'fasilitator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
return redirect()->route('dashboard.karakteristik-petani', array_merge($request->query(), [
|
||||
'tab' => 'indeks-petani',
|
||||
]));
|
||||
}
|
||||
|
||||
public function contentData(Request $request): array
|
||||
{
|
||||
$filters = $this->filters($request);
|
||||
|
||||
$segments = $this->segments();
|
||||
$colors = collect($segments)
|
||||
->pluck('color')
|
||||
->map(fn($c) => "var(--bs-{$c})")
|
||||
->values();
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)->get(['id', 'nama']);
|
||||
$petaniQuery = $this->petaniQuery(array_fill_keys(array_keys($filters), null));
|
||||
|
||||
$desaKelurahan = $petaniQuery->clone()
|
||||
->selectRaw("
|
||||
master_desa_kelurahan.id as desa_kelurahan_id,
|
||||
master_desa_kelurahan.nama as desa_kelurahan,
|
||||
master_kecamatan.id as kecamatan_id,
|
||||
master_kecamatan.nama as kecamatan,
|
||||
master_kabupaten_kota.id as kabupaten_id,
|
||||
master_kabupaten_kota.nama as kabupaten,
|
||||
master_provinsi.id as provinsi_id,
|
||||
master_provinsi.nama as provinsi
|
||||
")
|
||||
->whereNotNull('master_provinsi.id')
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
$provinsi = $desaKelurahan
|
||||
->unique('provinsi_id')
|
||||
->sortBy('provinsi')
|
||||
->values();
|
||||
|
||||
$wilayah = $desaKelurahan
|
||||
->groupBy('provinsi_id')
|
||||
->map(function ($provinsi) {
|
||||
return [
|
||||
'id' => $provinsi->first()->provinsi_id,
|
||||
'nama' => $provinsi->first()->provinsi,
|
||||
'kabupaten' => $provinsi
|
||||
->groupBy('kabupaten_id')
|
||||
->map(function ($kabupaten) {
|
||||
return [
|
||||
'id' => $kabupaten->first()->kabupaten_id,
|
||||
'nama' => $kabupaten->first()->kabupaten,
|
||||
'kecamatan' => $kabupaten
|
||||
->groupBy('kecamatan_id')
|
||||
->map(function ($kecamatan) {
|
||||
return [
|
||||
'id' => $kecamatan->first()->kecamatan_id,
|
||||
'nama' => $kecamatan->first()->kecamatan,
|
||||
'desa' => $kecamatan->map(function ($desa) {
|
||||
return [
|
||||
'id' => $desa->desa_kelurahan_id,
|
||||
'nama' => $desa->desa_kelurahan,
|
||||
];
|
||||
})->values(),
|
||||
];
|
||||
})->values(),
|
||||
];
|
||||
})->values(),
|
||||
];
|
||||
})->values();
|
||||
|
||||
return array_merge($filters,
|
||||
compact(
|
||||
'komoditas',
|
||||
'desaKelurahan',
|
||||
'provinsi',
|
||||
'wilayah',
|
||||
'segments',
|
||||
'colors',
|
||||
));
|
||||
}
|
||||
|
||||
public function summary(Request $request): JsonResponse
|
||||
{
|
||||
$filters = $this->filters($request);
|
||||
$petaniQuery = $this->petaniQuery($filters);
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get(['id', 'nama']);
|
||||
|
||||
$counts = $petaniQuery->clone()
|
||||
->selectRaw('COUNT(*) as petani')
|
||||
->selectRaw('COUNT(DISTINCT petani.komoditas_id) FILTER (WHERE petani.komoditas_id IN (SELECT id FROM master_komoditas WHERE is_utama = true AND deleted_at IS NULL)) as komoditas')
|
||||
->selectRaw('COUNT(DISTINCT petani.desa_kelurahan_id) FILTER (WHERE petani.komoditas_id IN (SELECT id FROM master_komoditas WHERE is_utama = true AND deleted_at IS NULL)) as desa')
|
||||
->selectRaw('COUNT(DISTINCT master_kecamatan.id) FILTER (WHERE petani.komoditas_id IN (SELECT id FROM master_komoditas WHERE is_utama = true AND deleted_at IS NULL)) as kecamatan')
|
||||
->first();
|
||||
|
||||
$filteredPetaniIds = $petaniQuery->clone()->select('petani.id');
|
||||
$lahan = Lahan::query()
|
||||
->whereIn('petani_id', $filteredPetaniIds)
|
||||
->whereIn('komoditas_id', $komoditas->pluck('id'))
|
||||
->selectRaw('COALESCE(SUM(luas_lahan), 0) as total, AVG(luas_lahan) as rata_rata')
|
||||
->first();
|
||||
|
||||
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
|
||||
$avgSkor = $skorQuery->clone()->avg('skor_kesiapan_adopsi');
|
||||
|
||||
if ($avgSkor >= 4.0) {
|
||||
$avgSegmen = 'Penggerak';
|
||||
} elseif ($avgSkor >= 3.0) {
|
||||
$avgSegmen = 'Perintis';
|
||||
} elseif ($avgSkor >= 2.0) {
|
||||
$avgSegmen = 'Pemerhati';
|
||||
} elseif ($avgSkor >= 1.0) {
|
||||
$avgSegmen = 'Pemula';
|
||||
} else {
|
||||
$avgSegmen = 'Belum Lengkap';
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'petani' => (int) $counts->petani,
|
||||
'komoditas' => (int) $counts->komoditas,
|
||||
'sum_lahan' => (float) $lahan->total,
|
||||
'avg_lahan' => (float) $lahan->rata_rata,
|
||||
'desa' => (int) $counts->desa,
|
||||
'kecamatan' => (int) $counts->kecamatan,
|
||||
'skor' => $avgSkor,
|
||||
'segmen' => $avgSegmen
|
||||
]);
|
||||
}
|
||||
|
||||
private function segments(): array
|
||||
{
|
||||
$segments = [
|
||||
[
|
||||
'name' => 'Penggerak',
|
||||
'range' => '4.0 - 5.0',
|
||||
'icon' => 'tabler-crown',
|
||||
'color' => 'success',
|
||||
],
|
||||
[
|
||||
'name' => 'Perintis',
|
||||
'range' => '3.0 - 3.9',
|
||||
'icon' => 'tabler-flag',
|
||||
'color' => 'info',
|
||||
],
|
||||
[
|
||||
'name' => 'Pemerhati',
|
||||
'range' => '2.0 - 2.9',
|
||||
'icon' => 'tabler-eye',
|
||||
'color' => 'warning',
|
||||
],
|
||||
[
|
||||
'name' => 'Pemula',
|
||||
'range' => '1.0 - 1.9',
|
||||
'icon' => 'tabler-seedling',
|
||||
'color' => 'danger',
|
||||
],
|
||||
];
|
||||
|
||||
return $segments;
|
||||
}
|
||||
|
||||
private function cases(): string
|
||||
{
|
||||
$case = "
|
||||
CASE
|
||||
WHEN skor_kesiapan_adopsi >= 4.0 THEN 'Penggerak'
|
||||
WHEN skor_kesiapan_adopsi >= 3.0 THEN 'Perintis'
|
||||
WHEN skor_kesiapan_adopsi >= 2.0 THEN 'Pemerhati'
|
||||
WHEN skor_kesiapan_adopsi >= 1.0 THEN 'Pemula'
|
||||
ELSE 'Belum Lengkap'
|
||||
END
|
||||
";
|
||||
|
||||
return $case;
|
||||
}
|
||||
public function segmen(Request $request): JsonResponse
|
||||
{
|
||||
$filters = $this->filters($request);
|
||||
$segments = $this->segments();
|
||||
$case = $this->cases();
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get(['id', 'nama']);
|
||||
|
||||
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
|
||||
|
||||
$countSegmentasi = $skorQuery->clone()
|
||||
->selectRaw("$case AS segmen, COUNT(*) AS total")
|
||||
->groupByRaw($case)
|
||||
->get();
|
||||
|
||||
$series = collect($segments)
|
||||
->map(function ($segment) use ($countSegmentasi) {
|
||||
return $countSegmentasi
|
||||
->where('segmen', $segment['name'])
|
||||
->sum('total');
|
||||
})
|
||||
->values();
|
||||
|
||||
$countPetani = $series->sum();
|
||||
|
||||
$persentase = collect($segments)
|
||||
->map(function ($segment) use ($countSegmentasi, $countPetani) {
|
||||
$total = $countSegmentasi
|
||||
->where('segmen', $segment['name'])
|
||||
->sum('total');
|
||||
|
||||
return $countPetani > 0
|
||||
? ($total / $countPetani) * 100
|
||||
: 0;
|
||||
})
|
||||
->values();
|
||||
|
||||
return response()->json([
|
||||
'series' => $series,
|
||||
'persentase' => $persentase,
|
||||
]);
|
||||
}
|
||||
|
||||
public function segmenByKomoditas(Request $request): JsonResponse
|
||||
{
|
||||
$filters = $this->filters($request);
|
||||
$segments = $this->segments();
|
||||
$case = $this->cases();
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get(['id', 'nama']);
|
||||
|
||||
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
|
||||
|
||||
$countSegmentasiByKomoditas = $skorQuery->clone()
|
||||
->selectRaw("
|
||||
petani.komoditas_id,
|
||||
$case AS segmen,
|
||||
COUNT(petani.id) AS total
|
||||
")
|
||||
->groupBy('petani.komoditas_id')
|
||||
->groupByRaw($case)
|
||||
->get();
|
||||
|
||||
$seriesSegmentasiKomoditas = collect($segments)->map(function ($segment) use ($countSegmentasiByKomoditas, $komoditas) {
|
||||
return [
|
||||
'name' => $segment['name'],
|
||||
'data' => $komoditas->map(function ($item) use ($countSegmentasiByKomoditas, $segment) {
|
||||
|
||||
return optional(
|
||||
$countSegmentasiByKomoditas->first(function ($row) use ($item, $segment) {
|
||||
return $row->komoditas_id == $item->id
|
||||
&& $row->segmen == $segment['name'];
|
||||
})
|
||||
)->total ?? 0;
|
||||
|
||||
})->values(),
|
||||
];
|
||||
})->values();
|
||||
|
||||
return response()->json([
|
||||
'categories' => $komoditas->pluck('nama')->values(),
|
||||
'series' => $seriesSegmentasiKomoditas,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function dimensi(Request $request): JsonResponse
|
||||
{
|
||||
$filters = $this->filters($request);
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get(['id', 'nama']);
|
||||
|
||||
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
|
||||
|
||||
$avgDimensi = $skorQuery->clone()
|
||||
->selectRaw("
|
||||
avg(skor_d2_sistem_praktik_budidaya) as skor_d2_sistem_praktik_budidaya,
|
||||
avg(skor_d4_sosial_ekonomi) as skor_d4_sosial_ekonomi,
|
||||
avg(skor_d6_rantai_nilai_akses_pasar) as skor_d6_rantai_nilai_akses_pasar")
|
||||
->first();
|
||||
|
||||
return response()->json([
|
||||
'radarDimensi' => [
|
||||
round($avgDimensi->skor_d2_sistem_praktik_budidaya, 2),
|
||||
round($avgDimensi->skor_d4_sosial_ekonomi, 2),
|
||||
round($avgDimensi->skor_d6_rantai_nilai_akses_pasar, 2),
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function komponen(Request $request): JsonResponse
|
||||
{
|
||||
$filters = $this->filters($request);
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get(['id', 'nama']);
|
||||
|
||||
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
|
||||
|
||||
$avgKomponen = $skorQuery->clone()
|
||||
->selectRaw("avg(skor_komp_1_d4_k3_motivasi_kapasitas_adopsi) as skor_komp_1_d4_k3_motivasi_kapasitas_adopsi,
|
||||
avg(skor_komp_2_d4_k2_ekonomi_rumah_tangga) as skor_komp_2_d4_k2_ekonomi_rumah_tangga,
|
||||
avg(skor_komp_3_d2_praktik_budidaya_gap) as skor_komp_3_d2_praktik_budidaya_gap,
|
||||
avg(skor_komp_4_d4_k4_keterlibatan_kelembagaan) as skor_komp_4_d4_k4_keterlibatan_kelembagaan,
|
||||
avg(skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan) as skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan,
|
||||
avg(skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar) as skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar")
|
||||
->first();
|
||||
|
||||
return response()->json([
|
||||
'radarKomponen' => [
|
||||
round($avgKomponen->skor_komp_1_d4_k3_motivasi_kapasitas_adopsi, 2),
|
||||
round($avgKomponen->skor_komp_2_d4_k2_ekonomi_rumah_tangga, 2),
|
||||
round($avgKomponen->skor_komp_3_d2_praktik_budidaya_gap, 2),
|
||||
round($avgKomponen->skor_komp_4_d4_k4_keterlibatan_kelembagaan, 2),
|
||||
round($avgKomponen->skor_komp_5_d4_k5_k6_akses_kebebasan_keuangan, 2),
|
||||
round($avgKomponen->skor_komp_6_d6_k1_k4_k5_rantai_nilai_akses_pasar, 2)
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
private function villageData(array $filters, bool $includePath = true): \Illuminate\Support\Collection
|
||||
{
|
||||
$case = $this->cases();
|
||||
|
||||
$petaniQuery = $this->petaniQuery($filters);
|
||||
|
||||
$desaKelurahan = $petaniQuery->clone()
|
||||
->selectRaw("
|
||||
master_desa_kelurahan.id as desa_kelurahan_id,
|
||||
master_desa_kelurahan.nama as desa_kelurahan,
|
||||
master_kecamatan.id as kecamatan_id,
|
||||
master_kecamatan.nama as kecamatan,
|
||||
master_kabupaten_kota.id as kabupaten_id,
|
||||
master_kabupaten_kota.nama as kabupaten,
|
||||
master_provinsi.id as provinsi_id,
|
||||
master_provinsi.nama as provinsi
|
||||
")
|
||||
->when($includePath, fn (Builder $query) => $query->addSelect('master_desa_kelurahan.path as path'))
|
||||
->distinct()
|
||||
->get();
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get(['id', 'nama']);
|
||||
|
||||
$skorQuery = $this->skorPetaniQuery($filters, $komoditas->pluck('id')->toArray());
|
||||
|
||||
$mapSegmentasi = $skorQuery->clone()
|
||||
->selectRaw("petani.desa_kelurahan_id,
|
||||
$case AS segmen,
|
||||
COUNT(petani.id) AS total
|
||||
")
|
||||
->groupBy('petani.desa_kelurahan_id')
|
||||
->groupByRaw($case)
|
||||
->get();
|
||||
|
||||
$mapAvgSkorSegmentasi = $skorQuery->clone()
|
||||
->selectRaw("petani.desa_kelurahan_id,
|
||||
COUNT(petani.id) AS jumlah_petani,
|
||||
avg(skor_kesiapan_adopsi) AS skor,
|
||||
CASE
|
||||
WHEN AVG(skor_kesiapan_adopsi) >= 4 THEN 'Penggerak'
|
||||
WHEN AVG(skor_kesiapan_adopsi) >= 3 THEN 'Perintis'
|
||||
WHEN AVG(skor_kesiapan_adopsi) >= 2 THEN 'Pemerhati'
|
||||
WHEN AVG(skor_kesiapan_adopsi) >= 1 THEN 'Pemula'
|
||||
ELSE 'Belum Lengkap'
|
||||
END AS segmen
|
||||
")
|
||||
->groupBy('petani.desa_kelurahan_id')
|
||||
->get();
|
||||
|
||||
$segmentasiGroups = $mapSegmentasi->groupBy('desa_kelurahan_id');
|
||||
$jumlahSegmenByDesa = $segmentasiGroups
|
||||
->map(fn ($items) => $items->pluck('total', 'segmen'));
|
||||
|
||||
$segmenDominan = $segmentasiGroups
|
||||
->map(function ($items) {
|
||||
return $items->reduce(fn ($largest, $item) => $largest === null || $item->total > $largest->total ? $item : $largest);
|
||||
});
|
||||
|
||||
$mapAvgSkorSegmentasi->each(function ($item) use ($segmenDominan, $jumlahSegmenByDesa) {
|
||||
$dominan = $segmenDominan->get($item->desa_kelurahan_id);
|
||||
|
||||
$item->segmen_dominan = $dominan?->segmen;
|
||||
$item->jumlah_dominan = $dominan?->total;
|
||||
$item->jumlah_segmen = $jumlahSegmenByDesa->get($item->desa_kelurahan_id, collect());
|
||||
});
|
||||
|
||||
$segmentasiByDesa = $mapAvgSkorSegmentasi->keyBy('desa_kelurahan_id');
|
||||
$desaLookup = $desaKelurahan->keyBy('desa_kelurahan_id');
|
||||
|
||||
$mapDesaSegmentasi = $segmentasiByDesa->map(function ($segmentasi, $desaId) use ($desaLookup) {
|
||||
$desa = $desaLookup->get($desaId);
|
||||
if (!$desa) {
|
||||
return null;
|
||||
}
|
||||
$desa->segmentasi = $segmentasi;
|
||||
|
||||
return $desa;
|
||||
})->filter()->values();
|
||||
|
||||
return $mapDesaSegmentasi;
|
||||
}
|
||||
|
||||
public function map(Request $request): JsonResponse
|
||||
{
|
||||
return response()->json($this->villageData($this->filters($request)));
|
||||
}
|
||||
|
||||
public function desa(Request $request): JsonResponse
|
||||
{
|
||||
$segmentStyles = collect($this->segments())->keyBy('name');
|
||||
$mapDesaSegmentasi = $this->villageData($this->filters($request), false);
|
||||
|
||||
$segmentNames = ['Pemula', 'Perintis', 'Pemerhati', 'Penggerak', 'Belum Lengkap'];
|
||||
$rows = $mapDesaSegmentasi->map(function ($desa) use ($segmentStyles, $segmentNames) {
|
||||
$total = (int) $desa->segmentasi->jumlah_petani;
|
||||
|
||||
$style = $segmentStyles[$desa->segmentasi->segmen] ?? ['color' => 'secondary'];
|
||||
$styleDominan = $segmentStyles[$desa->segmentasi->segmen_dominan] ?? ['color' => 'secondary'];
|
||||
|
||||
return [
|
||||
'desa' => $desa->desa_kelurahan,
|
||||
'jumlah_petani' => $desa->segmentasi->jumlah_petani,
|
||||
'segmen' => $desa->segmentasi->segmen,
|
||||
'skor' => $desa->segmentasi->skor,
|
||||
'segmen_dominan' => $desa->segmentasi->segmen_dominan,
|
||||
'jumlah_dominan' => $desa->segmentasi->jumlah_dominan,
|
||||
'color' => $style['color'],
|
||||
'color_dominan' => $styleDominan['color'],
|
||||
'segments' => collect($segmentNames)
|
||||
->mapWithKeys(function ($name) use ($desa, $segmentStyles, $total) {
|
||||
$count = (int) $desa->segmentasi->jumlah_segmen->get($name, 0);
|
||||
|
||||
return [strtolower(str_replace(' ', '_', $name)) => [
|
||||
'count' => $count,
|
||||
'percentage' => $total > 0 ? round($count / $total * 100, 2) : 0,
|
||||
'color' => $segmentStyles[$name]['color'] ?? 'secondary',
|
||||
]];
|
||||
})->all(),
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json($rows);
|
||||
}
|
||||
|
||||
public function data(Request $request): JsonResponse
|
||||
{
|
||||
$filters = $this->filters($request);
|
||||
$segments = $this->segments();
|
||||
|
||||
$segmentStyles = collect($segments)->keyBy('name');
|
||||
|
||||
$petaniQuery = $this->petaniQuery($filters);
|
||||
|
||||
$komoditas = Komoditas::where('is_utama', true)
|
||||
->when($filters['komoditas_id'], fn($q, $id) => $q->where('id', $id))->get(['id', 'nama']);
|
||||
|
||||
$daftarPetani = $petaniQuery->clone()
|
||||
->select('petani.*')
|
||||
->with(['desaKelurahan', 'komoditas', 'skor'])
|
||||
->withSum('lahans as total_luas_lahan', 'luas_lahan')
|
||||
->whereIn('komoditas_id', $komoditas->pluck('id'))
|
||||
->get();
|
||||
|
||||
$data = $daftarPetani
|
||||
->map(function ($item) use ($segmentStyles) {
|
||||
$segmen = $item->skor
|
||||
? $item->segmen()
|
||||
: null;
|
||||
$style = $segmentStyles[$segmen]
|
||||
?? ['color' => 'secondary'];
|
||||
|
||||
return [
|
||||
'id' => $item->id,
|
||||
'nama' => $item->nama,
|
||||
'desa' => $item->desaKelurahan?->nama,
|
||||
'desa_kelurahan_id' => $item->desa_kelurahan_id,
|
||||
'komoditas' => $item->komoditas?->nama,
|
||||
'luas_lahan' => (float) ($item->total_luas_lahan ?? 0),
|
||||
'skor' => $item->skor
|
||||
? $item->skor->skor_kesiapan_adopsi
|
||||
: null,
|
||||
'segmen' => $segmen,
|
||||
'color' => $style['color'],
|
||||
'url' => route('dashboard.profil-petani', $item->id),
|
||||
];
|
||||
})
|
||||
->values();
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,769 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Dashboard;
|
||||
|
||||
use App\Enums\KeparahanSerangan;
|
||||
use App\Enums\PenyakitTanaman;
|
||||
use App\Enums\PraktikBudidaya\PemberianPupuk;
|
||||
use App\Enums\SeranganHama;
|
||||
use App\Enums\SosialEkonomi\StatusKepemilikanLahanSosialEkonomi;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Pertanian\Komoditas;
|
||||
use App\Models\Pertanian\Lahan;
|
||||
use App\Models\Pertanian\Petani;
|
||||
use App\Models\Pertanian\PraktikBudidaya;
|
||||
use App\Models\Pertanian\Produksi;
|
||||
use App\Models\Pertanian\SkorPetani;
|
||||
use App\Models\Pertanian\SosialEkonomi;
|
||||
use App\Models\Pertanian\SurveyProduktivitas;
|
||||
use App\Models\Wilayah\DesaKelurahan;
|
||||
use App\Models\Wilayah\KabupatenKota;
|
||||
use App\Models\Wilayah\Kecamatan;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class IndikatorPertanianController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$kabupatenOptions = $this->kabupatenOptions();
|
||||
$ngadaOption = collect($kabupatenOptions)->first(
|
||||
fn ($option) => str_contains(strtolower($option['label']), 'ngada')
|
||||
);
|
||||
$initialFilters = $this->selectedFilters($request, $ngadaOption['value'] ?? 'all');
|
||||
|
||||
$totalPetani = $this->applyPetaniFilters(Petani::query(), $initialFilters)->count();
|
||||
$totalLuasLahan = ((float) $this->applyLahanFilters(Lahan::query(), $initialFilters)->sum('luas_lahan')) / 10000;
|
||||
$rataRataLuasLahan = $totalPetani > 0
|
||||
? $totalLuasLahan / $totalPetani
|
||||
: 0;
|
||||
$totalProduksiKg = $this->totalProduksiKg($initialFilters);
|
||||
$rataRataProduksiKg = $totalPetani > 0
|
||||
? $totalProduksiKg / $totalPetani
|
||||
: 0;
|
||||
$rataRataProduktivitas = $totalLuasLahan > 0
|
||||
? $totalProduksiKg / $totalLuasLahan
|
||||
: 0;
|
||||
|
||||
$filterOptions = [
|
||||
[
|
||||
'key' => 'kabupaten',
|
||||
'label' => 'Kabupaten',
|
||||
'options' => $kabupatenOptions,
|
||||
'icon' => 'tabler-map-pin',
|
||||
'readonly' => true,
|
||||
],
|
||||
[
|
||||
'key' => 'kecamatan',
|
||||
'label' => 'Kecamatan',
|
||||
'options' => $this->kecamatanOptions(),
|
||||
],
|
||||
[
|
||||
'key' => 'desa',
|
||||
'label' => 'Desa',
|
||||
'options' => $this->desaOptions(),
|
||||
],
|
||||
[
|
||||
'key' => 'komoditas',
|
||||
'label' => 'Komoditas',
|
||||
'options' => $this->komoditasOptions(),
|
||||
],
|
||||
[
|
||||
'key' => 'segmentasi',
|
||||
'label' => 'Segmentasi',
|
||||
'options' => $this->segmentasiOptions(),
|
||||
],
|
||||
];
|
||||
|
||||
$summaryData = [
|
||||
[
|
||||
'value' => number_format($totalPetani, 0, ',', '.'),
|
||||
'label' => 'Petani Terdata',
|
||||
'description' => 'Total petani yang masuk sistem',
|
||||
'icon' => 'tabler-users',
|
||||
'variant' => 'primary',
|
||||
],
|
||||
[
|
||||
'value' => number_format($totalLuasLahan, 2, ',', '.').' ha',
|
||||
'label' => 'Total Luas Lahan',
|
||||
'description' => 'Rata-rata '.number_format($rataRataLuasLahan, 2, ',', '.').' ha/petani',
|
||||
'icon' => 'tabler-mountain',
|
||||
'variant' => 'success',
|
||||
],
|
||||
[
|
||||
'value' => number_format($totalProduksiKg, 0, ',', '.').' kg',
|
||||
'label' => 'Total Produksi (Semua Komoditas)',
|
||||
'description' => 'Rata-rata '.number_format($rataRataProduksiKg, 0, ',', '.').' kg/petani',
|
||||
'icon' => 'tabler-wheat',
|
||||
'variant' => 'warning',
|
||||
],
|
||||
[
|
||||
'value' => number_format($rataRataProduktivitas, 0, ',', '.').' kg/ha',
|
||||
'label' => 'Rata-rata Produktivitas',
|
||||
'description' => 'Semua komoditas berdasarkan total produksi dan luas lahan',
|
||||
'icon' => 'tabler-chart-bar',
|
||||
'variant' => 'info',
|
||||
],
|
||||
];
|
||||
|
||||
return view('dashboard.indikator-pertanian', [
|
||||
'title' => 'Indikator Pertanian',
|
||||
'initialFilters' => $initialFilters,
|
||||
'filterOptions' => $filterOptions,
|
||||
'summaryData' => $summaryData,
|
||||
'chartData' => [
|
||||
'petaniPerKomoditas' => $this->petaniPerKomoditasChart($initialFilters),
|
||||
'luasLahanPerKecamatan' => $this->luasLahanPerKecamatanChart($initialFilters),
|
||||
'kondisiTanaman' => $this->kondisiTanamanChart($initialFilters),
|
||||
'statusKepemilikanLahan' => $this->statusKepemilikanLahanChart($initialFilters),
|
||||
'seranganHama' => $this->seranganHamaChart($initialFilters),
|
||||
'penyakitTanaman' => $this->penyakitTanamanChart($initialFilters),
|
||||
'keparahanSerangan' => $this->keparahanSeranganChart($initialFilters),
|
||||
'statusHakKelolaLahan' => $this->statusHakKelolaLahanChart($initialFilters),
|
||||
'praktikPemupukan' => $this->praktikPemupukanChart($initialFilters),
|
||||
'produksiPerKomoditas' => $this->produksiPerKomoditasChart($initialFilters),
|
||||
'produktivitasPerKomoditas' => $this->produktivitasPerKomoditasChart($initialFilters),
|
||||
'luasPanenPerKomoditas' => $this->luasPanenPerKomoditasChart($initialFilters),
|
||||
'statusPanen' => $this->statusPanenChart($initialFilters),
|
||||
'surveyProduktivitasHa' => $this->surveyProduktivitasByUnitChart($initialFilters, 'ha_tahun'),
|
||||
'surveyProduktivitasPohon' => $this->surveyProduktivitasByUnitChart($initialFilters, 'pohon_tahun'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
private function selectedFilters(Request $request, string $defaultKabupaten): array
|
||||
{
|
||||
$filters = [
|
||||
'kabupaten' => $defaultKabupaten,
|
||||
'kecamatan' => $this->validFilterValue($request->query('kecamatan'), Kecamatan::class),
|
||||
'desa' => $this->validFilterValue($request->query('desa'), DesaKelurahan::class),
|
||||
'komoditas' => $this->validFilterValue($request->query('komoditas'), Komoditas::class),
|
||||
'segmentasi' => $this->validSegmentasi((string) $request->query('segmentasi', 'all')),
|
||||
];
|
||||
|
||||
if ($filters['desa'] !== 'all') {
|
||||
$desa = DesaKelurahan::query()->find($filters['desa']);
|
||||
|
||||
if (! $desa || ($filters['kecamatan'] !== 'all' && (string) $desa->kecamatan_id !== $filters['kecamatan'])) {
|
||||
$filters['desa'] = 'all';
|
||||
}
|
||||
}
|
||||
|
||||
if ($filters['kecamatan'] === 'all') {
|
||||
$filters['desa'] = 'all';
|
||||
}
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
private function validFilterValue(mixed $value, string $modelClass): string
|
||||
{
|
||||
if (! $value || $value === 'all') {
|
||||
return 'all';
|
||||
}
|
||||
|
||||
return $modelClass::query()->whereKey($value)->exists()
|
||||
? (string) $value
|
||||
: 'all';
|
||||
}
|
||||
|
||||
private function validSegmentasi(string $value): string
|
||||
{
|
||||
return in_array($value, [
|
||||
'Penggerak',
|
||||
'Perintis',
|
||||
'Pemerhati',
|
||||
'Pemula',
|
||||
'Belum tersegmentasi',
|
||||
'all',
|
||||
], true) ? $value : 'all';
|
||||
}
|
||||
|
||||
private function kabupatenOptions(): array
|
||||
{
|
||||
return $this->withAllOption(
|
||||
'Semua Kabupaten',
|
||||
KabupatenKota::query()
|
||||
->orderBy('nama')
|
||||
->get(['id', 'kode', 'nama'])
|
||||
->map(fn (KabupatenKota $kabupaten) => [
|
||||
'value' => (string) $kabupaten->id,
|
||||
'label' => $this->kabupatenLabel($kabupaten),
|
||||
])
|
||||
->values()
|
||||
->all()
|
||||
);
|
||||
}
|
||||
|
||||
private function kecamatanOptions(): array
|
||||
{
|
||||
return $this->withAllOption(
|
||||
'Semua Kecamatan',
|
||||
Kecamatan::query()
|
||||
->orderBy('nama')
|
||||
->get(['id', 'nama'])
|
||||
->map(fn (Kecamatan $kecamatan) => [
|
||||
'value' => (string) $kecamatan->id,
|
||||
'label' => $kecamatan->nama,
|
||||
])
|
||||
->values()
|
||||
->all()
|
||||
);
|
||||
}
|
||||
|
||||
private function desaOptions(): array
|
||||
{
|
||||
return $this->withAllOption(
|
||||
'Semua Desa',
|
||||
DesaKelurahan::query()
|
||||
->orderBy('nama')
|
||||
->get(['id', 'nama', 'kecamatan_id'])
|
||||
->map(fn (DesaKelurahan $desa) => [
|
||||
'value' => (string) $desa->id,
|
||||
'label' => $desa->nama,
|
||||
'parent' => (string) $desa->kecamatan_id,
|
||||
])
|
||||
->values()
|
||||
->all()
|
||||
);
|
||||
}
|
||||
|
||||
private function komoditasOptions(): array
|
||||
{
|
||||
return $this->withAllOption(
|
||||
'Semua Komoditas',
|
||||
Komoditas::query()
|
||||
->orderBy('nama')
|
||||
->get(['id', 'nama'])
|
||||
->map(fn (Komoditas $komoditas) => [
|
||||
'value' => (string) $komoditas->id,
|
||||
'label' => $komoditas->nama,
|
||||
])
|
||||
->values()
|
||||
->all()
|
||||
);
|
||||
}
|
||||
|
||||
private function segmentasiOptions(): array
|
||||
{
|
||||
// Aggregate bucket counts in SQL instead of pulling every skor_kesiapan_adopsi
|
||||
// value into PHP just to map/filter/unique it.
|
||||
$row = SkorPetani::query()->selectRaw("
|
||||
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 4) as penggerak,
|
||||
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 3 AND skor_kesiapan_adopsi < 4) as perintis,
|
||||
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 2 AND skor_kesiapan_adopsi < 3) as pemerhati,
|
||||
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi >= 1 AND skor_kesiapan_adopsi < 2) as pemula,
|
||||
COUNT(*) FILTER (WHERE skor_kesiapan_adopsi IS NOT NULL AND skor_kesiapan_adopsi < 1) as belum_tersegmentasi
|
||||
")->first();
|
||||
|
||||
$order = [
|
||||
'Penggerak' => $row->penggerak,
|
||||
'Perintis' => $row->perintis,
|
||||
'Pemerhati' => $row->pemerhati,
|
||||
'Pemula' => $row->pemula,
|
||||
'Belum tersegmentasi' => $row->belum_tersegmentasi,
|
||||
];
|
||||
|
||||
$segments = collect($order)
|
||||
->filter(fn ($count) => $count > 0)
|
||||
->keys()
|
||||
->map(fn ($segment) => [
|
||||
'value' => $segment,
|
||||
'label' => $segment,
|
||||
])
|
||||
->values()
|
||||
->all();
|
||||
|
||||
return $this->withAllOption('Semua Segmentasi', $segments);
|
||||
}
|
||||
|
||||
private function totalProduksiKg(array $filters): float
|
||||
{
|
||||
$expr = $this->kgCaseExpr('jumlah_panen', 'satuan');
|
||||
|
||||
return (float) ($this->applyProduksiFilters(Produksi::query(), $filters)
|
||||
->whereNotNull('jumlah_panen')
|
||||
->selectRaw("SUM({$expr}) as total")
|
||||
->value('total') ?? 0);
|
||||
}
|
||||
|
||||
private function petaniPerKomoditasChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applyPetaniFilters(Petani::query(), $filters)
|
||||
->leftJoin('master_komoditas as k', 'k.id', '=', 'petani.komoditas_id')
|
||||
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
|
||||
->selectRaw('COUNT(petani.id) as total')
|
||||
->groupBy('k.id', 'k.nama')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
return [
|
||||
'labels' => $rows->pluck('label')->values()->all(),
|
||||
'series' => $rows->pluck('total')->map(fn ($value) => (int) $value)->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function luasLahanPerKecamatanChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
|
||||
->leftJoin('master_desa_kelurahan as d', 'd.id', '=', 'map_lahan.desa_kelurahan_id')
|
||||
->leftJoin('master_kecamatan as k', 'k.id', '=', 'd.kecamatan_id')
|
||||
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
|
||||
->selectRaw('SUM(map_lahan.luas_lahan) / 10000 as total')
|
||||
->groupBy('k.id', 'k.nama')
|
||||
->havingRaw('SUM(map_lahan.luas_lahan) > 0')
|
||||
->orderByDesc('total')
|
||||
->limit(8)
|
||||
->get()
|
||||
->filter(fn ($row) => round((float) $row->total, 2) > 0)
|
||||
->values();
|
||||
|
||||
return [
|
||||
'labels' => $rows->pluck('label')->values()->all(),
|
||||
'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function kondisiTanamanChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applyTanamanTableFilters(DB::table('map_tanaman'), $filters)
|
||||
->whereNull('map_tanaman.deleted_at')
|
||||
->whereNotNull('map_tanaman.kondisi_tanaman')
|
||||
->selectRaw('map_tanaman.kondisi_tanaman as label')
|
||||
->selectRaw('COUNT(map_tanaman.id) as total')
|
||||
->groupBy('map_tanaman.kondisi_tanaman')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
if ($rows->isEmpty()) {
|
||||
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
|
||||
->whereNull('deleted_at')
|
||||
->whereNotNull('kondisi_tanaman')
|
||||
->selectRaw('kondisi_tanaman as label')
|
||||
->selectRaw('COUNT(map_lahan.id) as total')
|
||||
->groupBy('kondisi_tanaman')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
}
|
||||
|
||||
return [
|
||||
'labels' => $rows->pluck('label')->map(fn ($label) => $this->shortEnumLabel((string) $label))->values()->all(),
|
||||
'series' => $rows->pluck('total')->map(fn ($value) => (int) $value)->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function seranganHamaChart(array $filters): array
|
||||
{
|
||||
return $this->tanamanAttributeChart(
|
||||
$filters,
|
||||
'serangan_hama',
|
||||
fn ($label) => $this->enumLabel(SeranganHama::class, (string) $label)
|
||||
);
|
||||
}
|
||||
|
||||
private function penyakitTanamanChart(array $filters): array
|
||||
{
|
||||
return $this->tanamanAttributeChart(
|
||||
$filters,
|
||||
'penyakit_tanaman',
|
||||
fn ($label) => $this->enumLabel(PenyakitTanaman::class, (string) $label)
|
||||
);
|
||||
}
|
||||
|
||||
private function keparahanSeranganChart(array $filters): array
|
||||
{
|
||||
return $this->tanamanAttributeChart(
|
||||
$filters,
|
||||
'keparahan_serangan',
|
||||
fn ($label) => $this->keparahanSeranganLabel((string) $label)
|
||||
);
|
||||
}
|
||||
|
||||
private function statusKepemilikanLahanChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
|
||||
->whereNotNull('status_kepemilikan')
|
||||
->selectRaw('status_kepemilikan as label')
|
||||
->selectRaw('COUNT(map_lahan.id) as total')
|
||||
->groupBy('status_kepemilikan')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
return $this->chartFromRows($rows, fn ($label) => $this->shortEnumLabel((string) $label));
|
||||
}
|
||||
|
||||
private function statusHakKelolaLahanChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applySosialEkonomiFilters(SosialEkonomi::query(), $filters)
|
||||
->whereNotNull('status_kepemilikan_lahan')
|
||||
->selectRaw('status_kepemilikan_lahan as label')
|
||||
->selectRaw('COUNT(sosial_ekonomi.id) as total')
|
||||
->groupBy('status_kepemilikan_lahan')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
return $this->chartFromRows(
|
||||
$rows,
|
||||
fn ($label) => $this->enumLabel(StatusKepemilikanLahanSosialEkonomi::class, (string) $label)
|
||||
);
|
||||
}
|
||||
|
||||
private function praktikPemupukanChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applyPraktikBudidayaFilters(PraktikBudidaya::query(), $filters)
|
||||
->whereNotNull('pemberian_pupuk')
|
||||
->selectRaw('pemberian_pupuk as label')
|
||||
->selectRaw('COUNT(praktik_budidaya.id) as total')
|
||||
->groupBy('pemberian_pupuk')
|
||||
->orderBy('pemberian_pupuk')
|
||||
->get();
|
||||
|
||||
return $this->chartFromRows(
|
||||
$rows,
|
||||
fn ($label) => $this->pemberianPupukLabel((int) $label)
|
||||
);
|
||||
}
|
||||
|
||||
private function produksiPerKomoditasChart(array $filters): array
|
||||
{
|
||||
$expr = $this->kgCaseExpr('produksi.jumlah_panen', 'produksi.satuan');
|
||||
|
||||
$rows = $this->applyProduksiFilters(Produksi::query(), $filters)
|
||||
->leftJoin('master_komoditas as k', 'k.id', '=', 'produksi.komoditas_id')
|
||||
->whereNotNull('jumlah_panen')
|
||||
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
|
||||
->selectRaw("SUM({$expr}) as total")
|
||||
->groupBy('k.id', 'k.nama')
|
||||
->get()
|
||||
->filter(fn ($row) => round((float) $row->total, 2) > 0)
|
||||
->sortByDesc('total')
|
||||
->values();
|
||||
|
||||
return [
|
||||
'labels' => $rows->pluck('label')->values()->all(),
|
||||
'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function produktivitasPerKomoditasChart(array $filters): array
|
||||
{
|
||||
$expr = $this->kgCaseExpr('produksi.jumlah_panen', 'produksi.satuan');
|
||||
|
||||
$rows = $this->applyProduksiFilters(Produksi::query(), $filters)
|
||||
->leftJoin('master_komoditas as k', 'k.id', '=', 'produksi.komoditas_id')
|
||||
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
|
||||
->selectRaw('AVG(produksi.produktivitas) FILTER (WHERE produksi.produktivitas > 0) as avg_prod')
|
||||
->selectRaw("SUM({$expr}) as total_kg")
|
||||
->selectRaw('SUM(produksi.luas_panen) as total_luas')
|
||||
->groupBy('k.id', 'k.nama')
|
||||
->get()
|
||||
->map(function ($row) {
|
||||
$avgProd = (float) $row->avg_prod;
|
||||
$totalLuas = (float) $row->total_luas;
|
||||
$totalKg = (float) $row->total_kg;
|
||||
|
||||
$value = $avgProd > 0
|
||||
? $avgProd
|
||||
: ($totalLuas > 0 ? $totalKg / $totalLuas : 0);
|
||||
|
||||
return (object) ['label' => $row->label, 'total' => round($value, 2)];
|
||||
})
|
||||
->filter(fn ($row) => $row->total > 0)
|
||||
->sortByDesc('total')
|
||||
->values();
|
||||
|
||||
return [
|
||||
'labels' => $rows->pluck('label')->values()->all(),
|
||||
'series' => $rows->pluck('total')->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function luasPanenPerKomoditasChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applyProduksiFilters(Produksi::query(), $filters)
|
||||
->leftJoin('master_komoditas as k', 'k.id', '=', 'produksi.komoditas_id')
|
||||
->whereNotNull('luas_panen')
|
||||
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
|
||||
->selectRaw('SUM(produksi.luas_panen) as total')
|
||||
->groupBy('k.id', 'k.nama')
|
||||
->havingRaw('SUM(produksi.luas_panen) > 0')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
return [
|
||||
'labels' => $rows->pluck('label')->values()->all(),
|
||||
'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function statusPanenChart(array $filters): array
|
||||
{
|
||||
$rows = $this->applyProduksiFilters(Produksi::query(), $filters)
|
||||
->whereNotNull('status_panen')
|
||||
->selectRaw("COALESCE(status_panen, 'Belum ditentukan') as label")
|
||||
->selectRaw('COUNT(produksi.id) as total')
|
||||
->groupBy('status_panen')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
return $this->chartFromRows($rows, fn ($label) => $this->shortEnumLabel((string) $label));
|
||||
}
|
||||
|
||||
private function surveyProduktivitasByUnitChart(array $filters, string $unit): array
|
||||
{
|
||||
$rows = $this->applySurveyProduktivitasFilters(SurveyProduktivitas::query(), $filters)
|
||||
->leftJoin('master_komoditas as k', 'k.id', '=', 'survey_produktivitas.komoditas_id')
|
||||
->where('satuan', $unit)
|
||||
->whereNotNull('kuantitas')
|
||||
->selectRaw("COALESCE(k.nama, 'Belum ditentukan') as label")
|
||||
->selectRaw('AVG(survey_produktivitas.kuantitas) as total')
|
||||
->groupBy('k.id', 'k.nama')
|
||||
->havingRaw('AVG(survey_produktivitas.kuantitas) > 0')
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
return [
|
||||
'labels' => $rows->pluck('label')->values()->all(),
|
||||
'series' => $rows->pluck('total')->map(fn ($value) => round((float) $value, 2))->values()->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function chartFromRows($rows, callable $labelResolver): array
|
||||
{
|
||||
return [
|
||||
'labels' => $rows
|
||||
->pluck('label')
|
||||
->map(fn ($label) => $labelResolver($label))
|
||||
->values()
|
||||
->all(),
|
||||
'series' => $rows
|
||||
->pluck('total')
|
||||
->map(fn ($value) => (int) $value)
|
||||
->values()
|
||||
->all(),
|
||||
];
|
||||
}
|
||||
|
||||
private function tanamanAttributeChart(array $filters, string $field, callable $labelResolver): array
|
||||
{
|
||||
$qualifiedField = 'map_tanaman.'.$field;
|
||||
|
||||
$rows = $this->applyTanamanTableFilters(DB::table('map_tanaman'), $filters)
|
||||
->whereNull('map_tanaman.deleted_at')
|
||||
->whereNotNull($qualifiedField)
|
||||
->selectRaw($qualifiedField.' as label')
|
||||
->selectRaw('COUNT(map_tanaman.id) as total')
|
||||
->groupBy($qualifiedField)
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
|
||||
if ($rows->isEmpty()) {
|
||||
$rows = $this->applyLahanFilters(Lahan::query(), $filters)
|
||||
->whereNotNull($field)
|
||||
->selectRaw($field.' as label')
|
||||
->selectRaw('COUNT(map_lahan.id) as total')
|
||||
->groupBy($field)
|
||||
->orderByDesc('total')
|
||||
->get();
|
||||
}
|
||||
|
||||
return $this->chartFromRows($rows, $labelResolver);
|
||||
}
|
||||
|
||||
private function applyPetaniFilters($query, array $filters)
|
||||
{
|
||||
return $query
|
||||
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
|
||||
$query->whereHas('desaKelurahan', fn ($desa) => $desa->where('kecamatan_id', $filters['kecamatan']));
|
||||
})
|
||||
->when($filters['desa'] !== 'all', fn ($query) => $query->where('desa_kelurahan_id', $filters['desa']))
|
||||
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']))
|
||||
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
|
||||
$query->whereHas('skor', function ($skor) use ($filters) {
|
||||
$this->applySegmentasiRange($skor, $filters['segmentasi']);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private function applyLahanFilters($query, array $filters)
|
||||
{
|
||||
return $query
|
||||
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
|
||||
$query->whereHas('desaKelurahan', fn ($desa) => $desa->where('kecamatan_id', $filters['kecamatan']));
|
||||
})
|
||||
->when($filters['desa'] !== 'all', fn ($query) => $query->where('desa_kelurahan_id', $filters['desa']))
|
||||
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']))
|
||||
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
|
||||
$query->whereIn('petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']));
|
||||
});
|
||||
}
|
||||
|
||||
private function applyProduksiFilters($query, array $filters)
|
||||
{
|
||||
return $query
|
||||
->when($filters['kecamatan'] !== 'all' || $filters['desa'] !== 'all' || $filters['segmentasi'] !== 'all', function ($query) use ($filters) {
|
||||
$query->whereHas('lahan', function ($lahan) use ($filters) {
|
||||
$this->applyLahanFilters($lahan, $filters);
|
||||
});
|
||||
})
|
||||
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']));
|
||||
}
|
||||
|
||||
private function applySosialEkonomiFilters($query, array $filters)
|
||||
{
|
||||
return $query->whereHas('petani', function ($petani) use ($filters) {
|
||||
$this->applyPetaniFilters($petani, $filters);
|
||||
});
|
||||
}
|
||||
|
||||
private function applyPraktikBudidayaFilters($query, array $filters)
|
||||
{
|
||||
return $query->whereHas('petani', function ($petani) use ($filters) {
|
||||
$this->applyPetaniFilters($petani, $filters);
|
||||
});
|
||||
}
|
||||
|
||||
private function applySurveyProduktivitasFilters($query, array $filters)
|
||||
{
|
||||
return $query
|
||||
->whereHas('petani', function ($petani) use ($filters) {
|
||||
$this->applyPetaniFilters($petani, $filters);
|
||||
})
|
||||
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('komoditas_id', $filters['komoditas']));
|
||||
}
|
||||
|
||||
private function applyTanamanTableFilters($query, array $filters)
|
||||
{
|
||||
return $query
|
||||
->leftJoin('map_lahan as l', 'l.id', '=', 'map_tanaman.lahan_id')
|
||||
->when($filters['kecamatan'] !== 'all', function ($query) use ($filters) {
|
||||
$query
|
||||
->leftJoin('master_desa_kelurahan as d', 'd.id', '=', 'l.desa_kelurahan_id')
|
||||
->where('d.kecamatan_id', $filters['kecamatan']);
|
||||
})
|
||||
->when($filters['desa'] !== 'all', fn ($query) => $query->where('l.desa_kelurahan_id', $filters['desa']))
|
||||
->when($filters['komoditas'] !== 'all', fn ($query) => $query->where('map_tanaman.komoditas_id', $filters['komoditas']))
|
||||
->when($filters['segmentasi'] !== 'all', function ($query) use ($filters) {
|
||||
$query->where(function ($query) use ($filters) {
|
||||
$query
|
||||
->whereIn('map_tanaman.petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']))
|
||||
->orWhereIn('l.petani_id', $this->segmentasiPetaniIdsQuery($filters['segmentasi']));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private function segmentasiPetaniIdsQuery(string $segmentasi)
|
||||
{
|
||||
return Petani::query()
|
||||
->select('id')
|
||||
->whereHas('skor', function ($skor) use ($segmentasi) {
|
||||
$this->applySegmentasiRange($skor, $segmentasi);
|
||||
});
|
||||
}
|
||||
|
||||
private function applySegmentasiRange($query, string $segmentasi)
|
||||
{
|
||||
return match ($segmentasi) {
|
||||
'Penggerak' => $query->where('skor_kesiapan_adopsi', '>=', 4),
|
||||
'Perintis' => $query->where('skor_kesiapan_adopsi', '>=', 3)->where('skor_kesiapan_adopsi', '<', 4),
|
||||
'Pemerhati' => $query->where('skor_kesiapan_adopsi', '>=', 2)->where('skor_kesiapan_adopsi', '<', 3),
|
||||
'Pemula' => $query->where('skor_kesiapan_adopsi', '>=', 1)->where('skor_kesiapan_adopsi', '<', 2),
|
||||
default => $query->where(function ($query) {
|
||||
$query->whereNull('skor_kesiapan_adopsi')->orWhere('skor_kesiapan_adopsi', '<', 1);
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* SQL CASE expression converting a jumlah/satuan pair to kilograms,
|
||||
* so aggregation happens in the database instead of pulling every
|
||||
* row of `produksi` into PHP to sum with toKilograms().
|
||||
*/
|
||||
private function kgCaseExpr(string $jumlahColumn, string $satuanColumn): string
|
||||
{
|
||||
return "CASE LOWER({$satuanColumn})
|
||||
WHEN 'ton' THEN {$jumlahColumn} * 1000
|
||||
WHEN 'kuintal' THEN {$jumlahColumn} * 100
|
||||
WHEN 'kwintal' THEN {$jumlahColumn} * 100
|
||||
ELSE {$jumlahColumn}
|
||||
END";
|
||||
}
|
||||
|
||||
private function shortEnumLabel(string $value): string
|
||||
{
|
||||
return str($value)
|
||||
->replace('_', ' ')
|
||||
->headline()
|
||||
->toString();
|
||||
}
|
||||
|
||||
private function enumLabel(string $enumClass, int|string $value): string
|
||||
{
|
||||
$case = $enumClass::tryFrom($value);
|
||||
|
||||
if (! $case) {
|
||||
return $this->shortEnumLabel((string) $value);
|
||||
}
|
||||
|
||||
return method_exists($case, 'label')
|
||||
? $case->label()
|
||||
: $this->shortEnumLabel((string) $case->value);
|
||||
}
|
||||
|
||||
private function keparahanSeranganLabel(string $value): string
|
||||
{
|
||||
return match (KeparahanSerangan::tryFrom($value)) {
|
||||
KeparahanSerangan::RINGAN => 'Ringan',
|
||||
KeparahanSerangan::SEDANG => 'Sedang',
|
||||
KeparahanSerangan::BERAT => 'Parah',
|
||||
default => $this->shortEnumLabel($value),
|
||||
};
|
||||
}
|
||||
|
||||
private function pemberianPupukLabel(int $value): string
|
||||
{
|
||||
return match (PemberianPupuk::tryFrom($value)) {
|
||||
PemberianPupuk::TIDAK_PERNAH => 'Tidak pernah',
|
||||
PemberianPupuk::JENIS_DOSIS_WAKTU_TIDAK_MENENTU => 'Tidak menentu',
|
||||
PemberianPupuk::JENIS_SESUAI_DOSIS_TIDAK_MENENTU => 'Jenis sesuai',
|
||||
PemberianPupuk::JENIS_DOSIS_SESUAI_WAKTU_CUKUP_TEPAT => 'Cukup tepat',
|
||||
PemberianPupuk::JENIS_DOSIS_SESUAI_WAKTU_TEPAT => 'Tepat & rutin',
|
||||
default => $this->shortEnumLabel((string) $value),
|
||||
};
|
||||
}
|
||||
|
||||
private function toKilograms(float $value, string $unit): float
|
||||
{
|
||||
return match (strtolower($unit)) {
|
||||
'ton' => $value * 1000,
|
||||
'kuintal', 'kwintal' => $value * 100,
|
||||
default => $value,
|
||||
};
|
||||
}
|
||||
|
||||
private function withAllOption(string $label, array $options): array
|
||||
{
|
||||
return array_merge([
|
||||
[
|
||||
'value' => 'all',
|
||||
'label' => $label,
|
||||
],
|
||||
], $options);
|
||||
}
|
||||
|
||||
private function kabupatenLabel(KabupatenKota $kabupaten): string
|
||||
{
|
||||
return preg_replace('/^(kabupaten|kota)\s+/i', '', $kabupaten->nama);
|
||||
}
|
||||
|
||||
private function segmentLabel(float $score): string
|
||||
{
|
||||
return match (true) {
|
||||
$score >= 4.0 => 'Penggerak',
|
||||
$score >= 3.0 => 'Perintis',
|
||||
$score >= 2.0 => 'Pemerhati',
|
||||
$score >= 1.0 => 'Pemula',
|
||||
default => 'Belum tersegmentasi',
|
||||
};
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Web\Dashboard;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Services\AlphaVantageMarket;
|
||||
use Illuminate\Contracts\Cache\Repository;
|
||||
use Illuminate\Http\Client\Pool;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Throwable;
|
||||
|
||||
class InternationalMarketController extends Controller
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
abort_unless(Gate::allows('super_admin') || Gate::allows('admin') || Gate::allows('fasilitator'), 403);
|
||||
|
||||
// File cache keeps external quotes independent of the application database.
|
||||
$cache = Cache::store('file');
|
||||
$marketData = $cache->remember('market.yahoo.quotes.v3', 300, function () use ($cache) {
|
||||
$commodities = [
|
||||
['name' => 'Kopi Arabica', 'symbol' => 'KC=F'],
|
||||
['name' => 'Kakao (Cocoa)', 'symbol' => 'CC=F'],
|
||||
];
|
||||
|
||||
try {
|
||||
$responses = Http::pool(function (Pool $pool) use ($commodities) {
|
||||
return array_map(fn ($commodity) => $pool->as($commodity['symbol'])
|
||||
->acceptJson()->withHeaders(['User-Agent' => 'Mozilla/5.0'])
|
||||
->withOptions(['verify' => config('services.yahoo_finance.ca_bundle') ?: true])
|
||||
->connectTimeout(3)->timeout(8)
|
||||
->get('https://query1.finance.yahoo.com/v8/finance/chart/'.rawurlencode($commodity['symbol']), [
|
||||
'interval' => '1d', 'range' => '5d',
|
||||
]), [...$commodities, ['symbol' => 'IDR=X']]);
|
||||
});
|
||||
} catch (Throwable $exception) {
|
||||
report($exception);
|
||||
$responses = [];
|
||||
}
|
||||
|
||||
$exchangeRate = $cache->get('market.yahoo.usd_idr');
|
||||
if (is_array($exchangeRate)) {
|
||||
$exchangeRate['stale'] = true;
|
||||
}
|
||||
$rateResponse = $responses['IDR=X'] ?? null;
|
||||
if ($rateResponse instanceof \Illuminate\Http\Client\Response && $rateResponse->successful()) {
|
||||
$meta = $rateResponse->json('chart.result.0.meta');
|
||||
if (is_array($meta) && ($meta['symbol'] ?? null) === 'IDR=X'
|
||||
&& ($meta['currency'] ?? null) === 'IDR'
|
||||
&& is_numeric($meta['regularMarketPrice'] ?? null) && $meta['regularMarketPrice'] > 0
|
||||
&& is_numeric($meta['regularMarketTime'] ?? null)) {
|
||||
$exchangeRate = [
|
||||
'value' => (float) $meta['regularMarketPrice'],
|
||||
'quoted_at' => gmdate('c', (int) $meta['regularMarketTime']),
|
||||
'source' => 'Yahoo Finance',
|
||||
'source_url' => 'https://finance.yahoo.com/quote/IDR%3DX/',
|
||||
'stale' => false,
|
||||
];
|
||||
$cache->put('market.yahoo.usd_idr', $exchangeRate, now()->addDays(7));
|
||||
}
|
||||
}
|
||||
|
||||
$quotes = array_map(function ($commodity) use ($responses, $cache) {
|
||||
$symbol = $commodity['symbol'];
|
||||
$key = 'market.yahoo.last.'.rawurlencode($symbol);
|
||||
$quote = $commodity + [
|
||||
'source' => 'Yahoo Finance',
|
||||
'source_url' => 'https://finance.yahoo.com/quote/'.rawurlencode($symbol).'/',
|
||||
'price' => null, 'currency' => null, 'unit' => null,
|
||||
'quoted_at' => null, 'stale' => false,
|
||||
];
|
||||
|
||||
try {
|
||||
$response = $responses[$symbol] ?? null;
|
||||
if (!$response instanceof \Illuminate\Http\Client\Response || !$response->successful()) {
|
||||
throw new \RuntimeException('Quote unavailable');
|
||||
}
|
||||
$meta = $response->json('chart.result.0.meta');
|
||||
if ($response->json('chart.error') || !is_array($meta)
|
||||
|| ($meta['symbol'] ?? null) !== $symbol
|
||||
|| !is_numeric($meta['regularMarketPrice'] ?? null)
|
||||
|| (float) $meta['regularMarketPrice'] <= 0
|
||||
|| !is_numeric($meta['regularMarketTime'] ?? null)
|
||||
|| !is_string($meta['currency'] ?? null)) {
|
||||
throw new \RuntimeException('Invalid quote');
|
||||
}
|
||||
|
||||
$quote['price'] = (float) $meta['regularMarketPrice'];
|
||||
$quote['currency'] = $meta['currency'];
|
||||
// Yahoo quotes Arabica in US cents/lb; cocoa and robusta in USD/tonne.
|
||||
// Apply the unit only when the API currency matches that convention.
|
||||
$quote['unit'] = match (true) {
|
||||
$symbol === 'KC=F' && $meta['currency'] === 'USX' => 'sen AS / lb',
|
||||
$symbol === 'CC=F' && $meta['currency'] === 'USD' => 'USD / ton metrik',
|
||||
default => $meta['currency'].' (satuan mengikuti sumber)',
|
||||
};
|
||||
$quote['quoted_at'] = gmdate('c', (int) $meta['regularMarketTime']);
|
||||
$cache->put($key, $quote, now()->addDays(7));
|
||||
|
||||
return $quote;
|
||||
} catch (Throwable $exception) {
|
||||
$previous = $cache->get($key);
|
||||
if (is_array($previous)) {
|
||||
$previous['stale'] = true;
|
||||
return $previous;
|
||||
}
|
||||
return $quote;
|
||||
}
|
||||
}, $commodities);
|
||||
|
||||
return ['quotes' => $quotes, 'exchange_rate' => $exchangeRate];
|
||||
});
|
||||
|
||||
$quotes = $marketData['quotes'];
|
||||
$exchangeRate = $marketData['exchange_rate'];
|
||||
foreach ($quotes as &$quote) {
|
||||
$quote['id'] = 'yahoo:'.$quote['symbol'];
|
||||
$quote['description'] = 'Estimasi konversi harga kontrak berjangka internasional.';
|
||||
$quote['period'] = $quote['quoted_at'];
|
||||
$quote['frequency'] = 'market';
|
||||
}
|
||||
unset($quote);
|
||||
$quotes = array_merge($quotes, $this->imfQuotes($cache), app(AlphaVantageMarket::class)->quotes($cache));
|
||||
$quotes = array_values(array_filter($quotes, fn ($quote) => is_numeric($quote['price']) && is_finite((float) $quote['price']) && $quote['price'] > 0));
|
||||
foreach ($quotes as &$quote) {
|
||||
// All active providers quote either US cents/lb or USD/metric tonne.
|
||||
$usdPerKg = match ($quote['unit']) {
|
||||
'sen AS / lb' => $quote['price'] / 100 / 0.45359237,
|
||||
'USD / ton metrik' => $quote['price'] / 1000,
|
||||
default => null,
|
||||
};
|
||||
$quote['price_idr_per_kg'] = $exchangeRate && $usdPerKg !== null
|
||||
? round($usdPerKg * $exchangeRate['value'], 2) : null;
|
||||
unset($quote['usd_per_kg']); // Old Alpha cache entries may contain this field.
|
||||
}
|
||||
unset($quote);
|
||||
|
||||
return response()->json([
|
||||
'quotes' => $quotes,
|
||||
'exchange_rate' => $exchangeRate,
|
||||
])->header('Cache-Control', 'no-store');
|
||||
}
|
||||
|
||||
private function imfQuotes(Repository $cache): array
|
||||
{
|
||||
// IMF observations are monthly averages; fetch at most once a day.
|
||||
return $cache->remember('market.imf.monthly.v1', 86400, function () use ($cache) {
|
||||
try {
|
||||
$response = Http::withHeaders(['Accept' => 'text/csv', 'User-Agent' => 'Mozilla/5.0'])
|
||||
->withOptions(['verify' => config('services.yahoo_finance.ca_bundle') ?: true])
|
||||
->connectTimeout(3)->timeout(10)
|
||||
->get('https://api.imf.org/external/sdmx/2.1/data/IMF.RES,PCPS/G001.PCOFFOTM+PCOFFROB+PCOCO.USD.M', [
|
||||
'startPeriod' => now()->subYears(2)->format('Y-m'), 'format' => 'csvfile',
|
||||
])->throw();
|
||||
$stream = fopen('php://memory', 'r+');
|
||||
try {
|
||||
fwrite($stream, $response->body());
|
||||
rewind($stream);
|
||||
$headers = fgetcsv($stream, 0, ',', '"', '');
|
||||
if (!$headers || array_diff(['COUNTRY', 'INDICATOR', 'DATA_TRANSFORMATION', 'FREQUENCY', 'TIME_PERIOD', 'OBS_VALUE', 'SCALE'], $headers)) {
|
||||
throw new \RuntimeException('Unexpected IMF CSV format');
|
||||
}
|
||||
$latest = [];
|
||||
while (($values = fgetcsv($stream, 0, ',', '"', '')) !== false) {
|
||||
if (count($values) !== count($headers)) continue;
|
||||
$row = array_combine($headers, $values);
|
||||
if ($row['COUNTRY'] !== 'G001' || $row['DATA_TRANSFORMATION'] !== 'USD' || $row['FREQUENCY'] !== 'M'
|
||||
|| $row['SCALE'] !== '0' || !is_numeric($row['OBS_VALUE']) || $row['OBS_VALUE'] <= 0
|
||||
|| !preg_match('/^\d{4}-M(0[1-9]|1[0-2])$/', $row['TIME_PERIOD'])) continue;
|
||||
$indicator = $row['INDICATOR'];
|
||||
if (!isset($latest[$indicator]) || $row['TIME_PERIOD'] > $latest[$indicator]['TIME_PERIOD']) {
|
||||
$latest[$indicator] = $row;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
fclose($stream);
|
||||
}
|
||||
$definitions = [
|
||||
'PCOFFOTM' => ['Kopi Arabica', 'USX', 'sen AS / lb', 'Biji kopi Arabica (Other Milds). Estimasi konversi harga acuan rata-rata bulanan IMF.'],
|
||||
'PCOFFROB' => ['Kopi Robusta', 'USX', 'sen AS / lb', 'Biji kopi Robusta. Estimasi konversi harga acuan rata-rata bulanan IMF.'],
|
||||
'PCOCO' => ['Kakao (Cocoa)', 'USD', 'USD / ton metrik', 'Biji kakao. Estimasi konversi harga acuan rata-rata bulanan IMF.'],
|
||||
];
|
||||
$quotes = [];
|
||||
foreach ($definitions as $indicator => [$name, $currency, $unit, $description]) {
|
||||
if (!isset($latest[$indicator])) continue;
|
||||
$row = $latest[$indicator];
|
||||
$quotes[] = [
|
||||
'id' => 'imf:'.$indicator, 'symbol' => $indicator, 'name' => $name,
|
||||
'price' => (float) $row['OBS_VALUE'], 'currency' => $currency, 'unit' => $unit,
|
||||
'source' => 'IMF · PCPS', 'source_url' => 'https://data.imf.org/Datasets/PCPS',
|
||||
'description' => $description, 'frequency' => 'monthly',
|
||||
'period' => str_replace('-M', '-', $row['TIME_PERIOD']), 'stale' => false,
|
||||
];
|
||||
}
|
||||
if (!$quotes) throw new \RuntimeException('No valid IMF observations');
|
||||
$cache->put('market.imf.last.v1', $quotes, now()->addDays(30));
|
||||
return $quotes;
|
||||
} catch (Throwable $exception) {
|
||||
report($exception);
|
||||
return array_map(function ($quote) {
|
||||
$quote['stale'] = true;
|
||||
return $quote;
|
||||
}, $cache->get('market.imf.last.v1', []));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user