Compare commits
329
Commits
d6e25dd60a
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd93e0d265 | ||
|
|
8ef4ae1f15 | ||
|
|
89c5a1371a | ||
|
|
41da3a71ee | ||
|
|
b5b046ed86 | ||
|
|
aa91c3fe3f | ||
|
|
53913bebe9 | ||
|
|
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 | ||
|
|
7cc3e0e8f1 | ||
|
|
4021010618 | ||
|
|
58bb2951f7 | ||
|
|
17d384acf9 | ||
|
|
751f14cb02 | ||
|
|
0db7ca1fa9 | ||
|
|
7ec111274f | ||
|
|
d13069cd78 | ||
|
|
8e83413d34 | ||
|
|
a48d6d75b6 | ||
|
|
1d37da0edc | ||
|
|
02037ff0be | ||
|
|
7bf92ea619 | ||
|
|
3ce013c754 | ||
|
|
6ff0ef011c | ||
|
|
c4e4f396d2 | ||
|
|
fd42bf37fe | ||
|
|
b702659215 | ||
|
|
7681984d89 | ||
|
|
e194658c28 | ||
|
|
17c4c96693 | ||
|
|
05967cce75 | ||
|
|
fa90501455 | ||
|
|
a274f84fe2 | ||
|
|
12f0686965 | ||
|
|
e4f7d675a1 | ||
|
|
9231f25e5d | ||
|
|
037c482649 | ||
|
|
3f37dcb51e | ||
|
|
b08df8f6fa | ||
|
|
6341199fd5 | ||
|
|
60063b86ba | ||
|
|
7e8ad932a4 | ||
|
|
7669511220 | ||
|
|
5f6dbb4d1e | ||
|
|
9e748fc8cd | ||
|
|
1ca9d96779 | ||
|
|
6c0c47751c | ||
|
|
75d679f492 | ||
|
|
e9abd33d85 | ||
|
|
e0ab4bdace | ||
|
|
34d09d03bb | ||
|
|
36258344da | ||
|
|
066b50ab9c | ||
|
|
4333e16626 |
@@ -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=
|
||||
|
||||
+714
@@ -0,0 +1,714 @@
|
||||
# AISTANDAR — Standar Pengembangan Aplikasi database-pertani-web
|
||||
|
||||
Dokumen ini adalah **aturan wajib** bagi AI (dan developer) yang bekerja di repo ini.
|
||||
Baca seluruhnya sebelum membuat, mengubah, atau merefaktor kode.
|
||||
|
||||
## 0. Cara memakai dokumen ini
|
||||
|
||||
- Aturan di sini **mengalahkan** kebiasaan umum atau contoh dari luar. Jika ada konflik antara kode lama dan dokumen ini, ikuti dokumen ini **untuk kode baru**, dan ikuti Bagian 13 (Prosedur Refaktor) untuk kode lama.
|
||||
- Jika sesuatu **tidak diatur** di sini: lihat dulu bagaimana modul yang sudah sesuai standar melakukannya, lalu tiru polanya. Jika tetap tidak jelas, **tanya**, jangan mengarang pola baru.
|
||||
- **Jangan** menambah package/library baru, mengubah struktur database yang sudah ada, atau mengubah kontrak API tanpa izin eksplisit.
|
||||
- Bahasa: teks yang tampil ke pengguna (label, pesan, validasi) memakai **Bahasa Indonesia**. Nama domain (petani, lahan, komoditas) tetap Bahasa Indonesia; kata kerja teknis Laravel (`index`, `store`, `show`) tetap bahasa Inggris.
|
||||
|
||||
---
|
||||
|
||||
## 1. Stack
|
||||
|
||||
| Bagian | Teknologi |
|
||||
|---|---|
|
||||
| Framework | Laravel 12 |
|
||||
| Frontend web | Blade (tanpa Livewire/Inertia) |
|
||||
| UI template | Vuexy (Bootstrap 5), ikon Tabler |
|
||||
| Grafik | ApexCharts |
|
||||
| Peta | Leaflet |
|
||||
| Auth web | Session |
|
||||
| Auth API | Laravel Sanctum (token) |
|
||||
| Dokumentasi API | dedoc/scramble |
|
||||
| Role | `app/Enums/Role.php`: `super_admin`, `admin` (admin program), `koordinator` (per komoditas), `enumerator` (penginput data petani), `fasilitator` (pemateri workshop), `petani`, `offtaker` |
|
||||
|
||||
---
|
||||
|
||||
## 2. Struktur folder & penamaan
|
||||
|
||||
### 2.1 Pengelompokan per domain
|
||||
|
||||
Controller, Model, Request, dan View **dikelompokkan per domain yang sama**:
|
||||
|
||||
```
|
||||
Domain yang ada: Dashboard, Laporan, Produktivitas, Ekosistem, Program, Master,
|
||||
Bumdes, Koperasi, Konfigurasi
|
||||
```
|
||||
|
||||
| Lapisan | Lokasi |
|
||||
|---|---|
|
||||
| Controller web | `app/Http/Controllers/Web/{Domain}/{Model}Controller.php` |
|
||||
| Controller API | `app/Http/Controllers/Api/{Domain}/{Model}Controller.php` |
|
||||
| Form Request | `app/Http/Requests/{Domain}/Store{Model}Request.php`, `Update{Model}Request.php` |
|
||||
| Model | `app/Models/{DomainModel}/{Model}.php` (ikuti folder model yang ada: `Pertanian/`, `Wilayah/`, `Program/`, `Master/`, dst.) |
|
||||
| Enum | `app/Enums/` |
|
||||
| Service / Query | `app/Services/{Domain}/` |
|
||||
| View | `resources/views/{domain}/{modul}/` (huruf kecil, kebab-case) |
|
||||
|
||||
Controller baru **tidak boleh** ditaruh di root `app/Http/Controllers/`. Controller root yang sudah ada (`ProgramController`, `ProgramKomoditasController`, `ProgramLokasiController`) dipindahkan ke domain `Program/` saat direfaktor.
|
||||
|
||||
### 2.2 Konvensi nama
|
||||
|
||||
| Objek | Aturan | Contoh |
|
||||
|---|---|---|
|
||||
| Model | Singular, PascalCase | `Petani`, `JenisKomoditas` |
|
||||
| Tabel | snake_case, **selalu ditulis eksplisit** di model | `protected $table = 'petani';` |
|
||||
| Controller | `{Model}Controller` | `PetaniController` |
|
||||
| Route name | `{modul}.{aksi}`, kebab-case | `jenis-komoditas.index` |
|
||||
| URL | kebab-case | `/jenis-komoditas` |
|
||||
| View | `{domain}/{modul}/{aksi}.blade.php` | `master/provinsi/index.blade.php` |
|
||||
| Method tambahan | camelCase | `byProvinsi()`, `list()` |
|
||||
|
||||
> Karena nama domain berbahasa Indonesia, pluralisasi otomatis Laravel salah (`petanis`). **Wajib** set `$table` di setiap model, dan set parameter route bila perlu (`->parameters(['jenis-komoditas' => 'jenisKomoditas'])`).
|
||||
|
||||
---
|
||||
|
||||
## 3. Controller
|
||||
|
||||
> **Cakupan:** Bagian 3 berlaku untuk **modul CRUD** (pengelolaan data: tambah, ubah, hapus).
|
||||
> Controller **Dashboard** dan **Laporan/Reporting** tidak terikat aturan 7 method dan mengikuti aturan yang lebih fleksibel di **Bagian 11**.
|
||||
|
||||
### 3.1 Tujuh method resmi
|
||||
|
||||
Untuk modul CRUD, gunakan **hanya** nama method resource Laravel:
|
||||
|
||||
| Method | HTTP | URL | Route name | Fungsi |
|
||||
|---|---|---|---|---|
|
||||
| `index` | GET | `/items` | `items.index` | Daftar data |
|
||||
| `create` | GET | `/items/create` | `items.create` | Form tambah |
|
||||
| `store` | POST | `/items` | `items.store` | Simpan baru |
|
||||
| `show` | GET | `/items/{item}` | `items.show` | Detail |
|
||||
| `edit` | GET | `/items/{item}/edit` | `items.edit` | Form ubah |
|
||||
| `update` | PUT/PATCH | `/items/{item}` | `items.update` | Simpan perubahan |
|
||||
| `destroy` | DELETE | `/items/{item}` | `items.destroy` | Hapus (soft delete) |
|
||||
|
||||
**Dilarang** memakai nama `add`, `view`, `save`, `delete`, `remove`, `detail`, atau sejenisnya untuk aksi CRUD. (Larangan ini tidak berlaku untuk Dashboard dan Laporan, lihat Bagian 11.)
|
||||
|
||||
### 3.2 Prinsip controller tipis
|
||||
|
||||
- Validasi **selalu** di Form Request, tidak pernah `$request->validate()` di controller.
|
||||
- Controller hanya: terima request → panggil model/service → kembalikan respons.
|
||||
- Logika bisnis yang lebih dari ±15 baris, dipakai di lebih dari satu tempat, atau melibatkan banyak tabel → pindahkan ke `app/Services/{Domain}/`.
|
||||
- Operasi yang menulis ke lebih dari satu tabel → bungkus dengan `DB::transaction()`.
|
||||
- Pakai route model binding (`Petani $petani`), bukan `find($id)`.
|
||||
|
||||
### 3.3 Tiga pola resmi
|
||||
|
||||
Pilih **satu** pola per modul berdasarkan tabel ini:
|
||||
|
||||
| Pola | Kapan dipakai | Contoh |
|
||||
|---|---|---|
|
||||
| **A. Offcanvas (AJAX)** | Data referensi/sederhana: sedikit field, tanpa halaman detail yang kaya | Provinsi, Kabupaten, Komoditas, Varietas, Adat |
|
||||
| **B. Resource halaman** | Entitas utama: banyak field, ada relasi, perlu halaman detail | Lahan, Produksi, Workshop, BUMDes, Koperasi |
|
||||
| **C. Detail multi-tab** | Entitas induk dengan banyak bagian data yang diisi bertahap | Petani, Survey Kelompok Tani |
|
||||
|
||||
---
|
||||
|
||||
#### Pola A — Offcanvas (AJAX)
|
||||
|
||||
- `index` mengembalikan **view**; `store`, `show`, `update`, `destroy` mengembalikan **JSON**.
|
||||
- Tidak ada halaman `create`/`edit`; form ada di offcanvas di `index.blade.php`.
|
||||
- `show` dipakai JS untuk mengisi form edit di offcanvas.
|
||||
|
||||
```php
|
||||
// routes/web.php
|
||||
// Route tambahan WAJIB didaftarkan SEBELUM Route::resource agar tidak tertangkap {provinsi}
|
||||
Route::get('provinsi/list', [ProvinsiController::class, 'list'])->name('provinsi.list');
|
||||
Route::resource('provinsi', ProvinsiController::class)->except(['create', 'edit']);
|
||||
```
|
||||
|
||||
```php
|
||||
namespace App\Http\Controllers\Web\Master;
|
||||
|
||||
class ProvinsiController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$provinsi = Provinsi::query()
|
||||
->when($request->search, fn ($q, $s) => $q->where('nama', 'like', "%{$s}%"))
|
||||
->latest()
|
||||
->paginate(15)
|
||||
->withQueryString();
|
||||
|
||||
return view('master.provinsi.index', compact('provinsi'));
|
||||
}
|
||||
|
||||
public function store(StoreProvinsiRequest $request)
|
||||
{
|
||||
$provinsi = Provinsi::create($request->validated());
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Provinsi berhasil ditambahkan.',
|
||||
'data' => $provinsi,
|
||||
], 201);
|
||||
}
|
||||
|
||||
public function show(Provinsi $provinsi)
|
||||
{
|
||||
return response()->json(['success' => true, 'data' => $provinsi]);
|
||||
}
|
||||
|
||||
public function update(UpdateProvinsiRequest $request, Provinsi $provinsi)
|
||||
{
|
||||
$provinsi->update($request->validated());
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Provinsi berhasil diperbarui.',
|
||||
'data' => $provinsi,
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(Provinsi $provinsi)
|
||||
{
|
||||
DB::transaction(fn () => $provinsi->delete());
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Provinsi berhasil dihapus.',
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Dropdown berantai** (provinsi → kabupaten → kecamatan → desa): method `by{Induk}` di controller anak, mengembalikan JSON `[{id, nama}]`.
|
||||
|
||||
```php
|
||||
Route::get('kabupaten/by-provinsi/{provinsi}', [KabupatenController::class, 'byProvinsi'])
|
||||
->name('kabupaten.by-provinsi');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Pola B — Resource halaman
|
||||
|
||||
- Semua 7 method; view `index`, `create`, `edit`, `show` + partial `_form`.
|
||||
- Setelah `store`/`update`/`destroy` → **redirect** dengan flash message.
|
||||
|
||||
```php
|
||||
Route::resource('lahan', LahanController::class);
|
||||
```
|
||||
|
||||
```php
|
||||
namespace App\Http\Controllers\Web\Produktivitas;
|
||||
|
||||
class LahanController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$lahan = Lahan::query()
|
||||
->with(['petani', 'desa'])
|
||||
->when($request->search, fn ($q, $s) => $q->where('nama', 'like', "%{$s}%"))
|
||||
->latest()
|
||||
->paginate(15)
|
||||
->withQueryString();
|
||||
|
||||
return view('produktivitas.lahan.index', compact('lahan'));
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return view('produktivitas.lahan.create', ['lahan' => new Lahan()]);
|
||||
}
|
||||
|
||||
public function store(StoreLahanRequest $request)
|
||||
{
|
||||
$lahan = Lahan::create($request->validated());
|
||||
|
||||
return redirect()->route('lahan.show', $lahan)
|
||||
->with('success', 'Lahan berhasil ditambahkan.');
|
||||
}
|
||||
|
||||
public function show(Lahan $lahan)
|
||||
{
|
||||
$lahan->load(['petani', 'tanaman']);
|
||||
|
||||
return view('produktivitas.lahan.show', compact('lahan'));
|
||||
}
|
||||
|
||||
public function edit(Lahan $lahan)
|
||||
{
|
||||
return view('produktivitas.lahan.edit', compact('lahan'));
|
||||
}
|
||||
|
||||
public function update(UpdateLahanRequest $request, Lahan $lahan)
|
||||
{
|
||||
$lahan->update($request->validated());
|
||||
|
||||
return redirect()->route('lahan.show', $lahan)
|
||||
->with('success', 'Lahan berhasil diperbarui.');
|
||||
}
|
||||
|
||||
public function destroy(Lahan $lahan)
|
||||
{
|
||||
DB::transaction(fn () => $lahan->delete());
|
||||
|
||||
return redirect()->route('lahan.index')
|
||||
->with('success', 'Lahan berhasil dihapus.');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### Pola C — Detail multi-tab
|
||||
|
||||
- Controller induk (mis. `PetaniController`) memakai Pola B.
|
||||
- Setiap tab punya **controller sendiri** (`PetaniLahanController`, `PraktikBudidayaController`, …) yang tetap memakai nama method resmi.
|
||||
- Tab dirangkai sebagai **nested shallow resource** di bawah induk.
|
||||
- View: `header.blade.php` berisi kartu profil + navigasi tab; setiap tab punya subfolder.
|
||||
- Tab selain Profil **terkunci** sampai profil induk lengkap. Logika penguncian ditaruh di satu tempat (method di model induk, mis. `$petani->profilLengkap()`), bukan diulang di tiap view.
|
||||
|
||||
```
|
||||
resources/views/produktivitas/petani/
|
||||
├── index.blade.php
|
||||
├── create.blade.php
|
||||
├── edit.blade.php
|
||||
├── show.blade.php ← tab Profil
|
||||
├── header.blade.php ← kartu profil + navigasi tab
|
||||
├── _form.blade.php
|
||||
├── lahan-tanaman/
|
||||
│ ├── index.blade.php
|
||||
│ └── ...
|
||||
├── praktik-budidaya/
|
||||
└── ...
|
||||
```
|
||||
|
||||
```php
|
||||
Route::resource('petani', PetaniController::class);
|
||||
Route::resource('petani.praktik-budidaya', PraktikBudidayaController::class)->shallow();
|
||||
```
|
||||
|
||||
### 3.4 Batas resource
|
||||
|
||||
- Jika modul tidak butuh semua aksi, batasi dengan `->only([...])` / `->except([...])`. Jangan biarkan route yang tidak punya method terdaftar.
|
||||
- Method di luar 7 aksi resmi hanya boleh untuk: dropdown/list (`list`, `by{Induk}`), aksi status yang jelas (`verify`, `approve`), dan export (`export`). Daftarkan sebelum `Route::resource`.
|
||||
|
||||
---
|
||||
|
||||
## 4. Validasi
|
||||
|
||||
- Setiap `store` dan `update` memakai Form Request: `Store{Model}Request`, `Update{Model}Request`.
|
||||
- Pesan dan atribut dalam Bahasa Indonesia (`messages()` / `attributes()`, atau file `lang/id/validation.php`).
|
||||
- Form Request yang sama boleh dipakai controller Web dan API.
|
||||
- Untuk Pola A, Form Request otomatis mengembalikan JSON 422 karena request AJAX mengirim header `Accept: application/json`. **Jangan** menangkap error validasi secara manual.
|
||||
- **Unique wajib mengabaikan data yang sudah di-soft delete** (lihat 5.3).
|
||||
|
||||
```php
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'kode' => [
|
||||
'required', 'string', 'max:10',
|
||||
Rule::unique('provinsi', 'kode')
|
||||
->ignore($this->route('provinsi'))
|
||||
->withoutTrashed(),
|
||||
],
|
||||
'nama' => ['required', 'string', 'max:100'],
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Model, migration, dan soft delete
|
||||
|
||||
### 5.1 Model
|
||||
|
||||
```php
|
||||
class Lahan extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'lahan';
|
||||
|
||||
protected $fillable = ['petani_id', 'desa_id', 'nama', 'luas'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'luas' => 'decimal:2',
|
||||
'status_milik' => StatusKepemilikan::class, // Enum
|
||||
];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Pakai `$fillable`, bukan `$guarded = []`.
|
||||
- Pilihan tetap (jawaban survei, status) disimpan sebagai **PHP Enum** di `app/Enums/` dan di-cast di model. Jangan menulis daftar pilihan langsung di Blade.
|
||||
|
||||
### 5.2 Migration
|
||||
|
||||
Setiap tabel baru **wajib** memiliki:
|
||||
|
||||
```php
|
||||
$table->id();
|
||||
// ... kolom
|
||||
$table->foreignId('created_by')->nullable()->constrained('users'); // ikuti kolom audit yang sudah ada
|
||||
$table->foreignId('updated_by')->nullable()->constrained('users');
|
||||
$table->timestamps();
|
||||
$table->softDeletes();
|
||||
$table->foreignId('deleted_by')->nullable()->constrained('users');
|
||||
```
|
||||
|
||||
- Jangan mengubah migration yang sudah dijalankan di production; buat migration baru.
|
||||
- **Jangan** memakai unique index di database untuk kolom pada tabel ber-soft delete (data terhapus akan menghalangi input ulang). Keunikan dijaga di Form Request.
|
||||
|
||||
### 5.3 Soft delete (aturan utama)
|
||||
|
||||
1. **Semua penghapusan adalah soft delete.** `forceDelete()` dilarang di kode aplikasi.
|
||||
2. **`deleted_by` wajib terisi** dengan user yang menghapus. Gunakan mekanisme yang sudah ada di project (trait/observer). Jika belum ada, gunakan trait berikut dan pasang di semua model:
|
||||
|
||||
```php
|
||||
namespace App\Models\Concerns;
|
||||
|
||||
trait HasDeletedBy
|
||||
{
|
||||
protected static function bootHasDeletedBy(): void
|
||||
{
|
||||
static::deleting(function ($model) {
|
||||
if (! $model->isForceDeleting()) {
|
||||
$model->deleted_by = auth()->id();
|
||||
$model->saveQuietly();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **Hapus berantai (cascade soft delete).** Jika induk dihapus, **semua data anaknya ikut di-soft delete**, termasuk cucu dan seterusnya. Tulis di model induk:
|
||||
|
||||
```php
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::deleting(function (Petani $petani) {
|
||||
if ($petani->isForceDeleting()) {
|
||||
return;
|
||||
}
|
||||
// ->each->delete() memicu event per anak, sehingga deleted_by
|
||||
// terisi dan cascade berlanjut ke cucu
|
||||
$petani->lahan()->each->delete();
|
||||
$petani->praktikBudidaya()->each->delete();
|
||||
// ... semua relasi hasMany/hasOne milik petani
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
- **Jangan** memakai `$petani->lahan()->delete()` (query massal), karena tidak memicu event, sehingga `deleted_by` kosong dan cascade terputus.
|
||||
- Setiap kali menambah relasi anak baru, **tambahkan juga** ke blok `deleting` induknya.
|
||||
- Pemanggilan `delete()` di controller selalu dibungkus `DB::transaction()`.
|
||||
- Relasi `belongsTo` ke data master (Provinsi, Komoditas, dll.) **bukan** anak dan tidak ikut terhapus.
|
||||
4. **Restore** belum disediakan di aplikasi; dilakukan langsung di database oleh admin. Jangan membuat halaman sampah/restore tanpa diminta.
|
||||
|
||||
### 5.4 Global scope
|
||||
|
||||
- `KomoditasProgramScope` otomatis membatasi data ke komoditas milik program aktif (`SystemProgram`). Jika data "tidak muncul", periksa scope ini dulu.
|
||||
- Melewati scope hanya dengan `withoutGlobalScope(KomoditasProgramScope::class)` secara eksplisit, dengan komentar alasannya.
|
||||
- Jangan menambah global scope baru tanpa izin.
|
||||
|
||||
---
|
||||
|
||||
## 6. Routing
|
||||
|
||||
### 6.1 Route CRUD wajib memakai `Route::resource`
|
||||
|
||||
Semua modul CRUD (Pola A, B, C) **wajib** didaftarkan dengan `Route::resource`. **Dilarang** menulis route CRUD satu per satu secara manual.
|
||||
|
||||
```php
|
||||
// ❌ SALAH — route CRUD manual
|
||||
Route::get('provinsi', [ProvinsiController::class, 'index'])->name('provinsi.index');
|
||||
Route::post('provinsi/store', [ProvinsiController::class, 'store'])->name('provinsi.store');
|
||||
Route::get('provinsi/view/{id}', [ProvinsiController::class, 'view'])->name('provinsi.view');
|
||||
Route::post('provinsi/update/{id}', [ProvinsiController::class, 'update'])->name('provinsi.update');
|
||||
Route::get('provinsi/delete/{id}', [ProvinsiController::class, 'destroy'])->name('provinsi.destroy');
|
||||
|
||||
// ✅ BENAR
|
||||
Route::resource('provinsi', ProvinsiController::class)->except(['create', 'edit']);
|
||||
```
|
||||
|
||||
Aturan turunannya:
|
||||
|
||||
| Kebutuhan | Cara |
|
||||
|---|---|
|
||||
| Tidak semua aksi dipakai | `->only([...])` atau `->except([...])` |
|
||||
| Pola A (offcanvas) | `->except(['create', 'edit'])` |
|
||||
| Pola B (resource halaman) | `Route::resource(...)` penuh |
|
||||
| Pola C (multi-tab) | Induk `Route::resource`, tab `Route::resource('induk.tab', ...)->shallow()` |
|
||||
| Beberapa modul sekaligus | `Route::resources([...])` boleh dipakai dalam satu grup domain |
|
||||
| Nama parameter tidak sesuai model | `->parameters(['jenis-komoditas' => 'jenisKomoditas'])` |
|
||||
| Method tambahan (`list`, `by{Induk}`, `verify`, `export`) | `Route::get/post/patch` biasa, **ditulis sebelum** `Route::resource` modul yang sama |
|
||||
|
||||
- Form hapus/ubah memakai method spoofing Blade (`@method('DELETE')`, `@method('PUT')`), dan AJAX mengirim method HTTP yang sesuai. Jangan memakai `GET` untuk menghapus.
|
||||
- **Pengecualian:** Dashboard dan Laporan tidak memakai `Route::resource` (lihat Bagian 11). Halaman tunggal seperti Profil akun boleh memakai `Route::singleton('profil', ...)` atau route manual `edit`/`update`.
|
||||
|
||||
### 6.2 Aturan routing lainnya
|
||||
|
||||
- Semua route web di `routes/web.php`, API di `routes/api.php`.
|
||||
- Kelompokkan per domain dengan `Route::middleware(...)->group()` dan komentar judul domain.
|
||||
- Nested resource memakai `->shallow()`. Maksimal **dua tingkat** di URL (`/framework/{framework}/transformasi`). Hierarki lebih dalam (Framework → Transformasi → Aktivitas → Target) dipecah menjadi beberapa nested shallow resource berpasangan.
|
||||
- **Satu route hanya didaftarkan satu kali.** Sebelum menambah route, cari dulu apakah sudah ada (`php artisan route:list --name=...`).
|
||||
- Setelah login: `enumerator` → Dashboard Survei Petani; `fasilitator` → Profil akun (belum ada menu khusus); role lain → Dashboard Karakteristik Petani. Jangan mengubah logika ini tanpa izin.
|
||||
|
||||
---
|
||||
|
||||
## 7. Blade & Vuexy
|
||||
|
||||
### 7.1 Layout
|
||||
|
||||
- Semua halaman admin: `@extends('layout.main')` dan mengisi `@section('content')`.
|
||||
- Halaman auth memakai `auth/layout.blade.php`.
|
||||
- Jangan membuat layout baru; jangan menyalin `<head>`/sidebar ke halaman.
|
||||
|
||||
### 7.2 File view per pola
|
||||
|
||||
| File | Pola | Isi |
|
||||
|---|---|---|
|
||||
| `index.blade.php` | A, B, C | Tabel, pencarian, pagination (+ offcanvas form untuk Pola A) |
|
||||
| `create.blade.php` | B, C | Form tambah, `@include('..._form')` |
|
||||
| `edit.blade.php` | B, C | Form ubah, `@include('..._form')` |
|
||||
| `show.blade.php` | B, C | Detail |
|
||||
| `_form.blade.php` | A, B, C | Field form bersama untuk tambah dan ubah |
|
||||
| `header.blade.php` | C | Kartu profil + navigasi tab |
|
||||
|
||||
- File `add.blade.php` dan `view.blade.php` **tidak boleh** dibuat lagi (ganti dengan `create` dan `show`).
|
||||
- `_form.blade.php` menerima model (kosong saat tambah) dan memakai `old('field', $model->field)`.
|
||||
|
||||
### 7.3 Tampilan error validasi
|
||||
|
||||
```blade
|
||||
<input type="text" name="nama"
|
||||
class="form-control @error('nama') is-invalid @enderror"
|
||||
value="{{ old('nama', $lahan->nama) }}">
|
||||
@error('nama')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
```
|
||||
|
||||
Untuk Pola A, JS menampilkan error dari respons 422 dengan class yang sama (`is-invalid` + `invalid-feedback`).
|
||||
|
||||
### 7.4 Komponen
|
||||
|
||||
- Elemen yang muncul di lebih dari dua halaman dijadikan Blade component di `resources/views/components/` (contoh yang ada: `summary-card`, `wilayah-card`, `wilayah-dashboard`).
|
||||
- Utamakan komponen yang sudah ada sebelum membuat yang baru.
|
||||
|
||||
### 7.5 JavaScript & plugin
|
||||
|
||||
- JS halaman ditulis di **file terpisah per modul** (ikuti lokasi JS yang sudah dipakai project), dimuat lewat section/stack script di layout. Hindari blok `<script>` panjang di Blade.
|
||||
- Semua request AJAX mengirim header `X-CSRF-TOKEN` dan `Accept: application/json`.
|
||||
- URL di JS diambil dari `route()` yang dicetak Blade (mis. atribut `data-url`), **bukan** di-hardcode.
|
||||
- Pakai plugin yang sudah tersedia di template Vuexy. Jangan menambah library baru tanpa izin. Pembagian peran:
|
||||
|
||||
| Kebutuhan | Plugin |
|
||||
|---|---|
|
||||
| Konfirmasi hapus | SweetAlert2 (jika terpasang) |
|
||||
| Notifikasi sukses/gagal | Sesuai yang dipakai modul lain |
|
||||
| Select dengan pencarian / dropdown berantai | Select2 (jika terpasang) |
|
||||
| Input tanggal | Flatpickr (jika terpasang) |
|
||||
| Grafik | ApexCharts |
|
||||
| Peta | Leaflet |
|
||||
| Ikon | Tabler Icons (`ti ti-*`) |
|
||||
|
||||
---
|
||||
|
||||
## 8. Respons & pesan
|
||||
|
||||
### 8.1 Web (Pola B/C)
|
||||
|
||||
```php
|
||||
return redirect()->route('lahan.index')->with('success', 'Lahan berhasil dihapus.');
|
||||
return back()->withInput()->with('error', 'Data gagal disimpan.');
|
||||
```
|
||||
|
||||
Kunci flash: `success`, `error`, `warning`, `info`.
|
||||
|
||||
### 8.2 JSON (Pola A dan AJAX web)
|
||||
|
||||
```json
|
||||
{ "success": true, "message": "Provinsi berhasil ditambahkan.", "data": { } }
|
||||
```
|
||||
|
||||
- Error validasi: format 422 bawaan Laravel (`message` + `errors`).
|
||||
- Error lain: `{ "success": false, "message": "..." }` dengan kode HTTP yang sesuai.
|
||||
|
||||
### 8.3 Pola kalimat pesan
|
||||
|
||||
`{Nama data} berhasil ditambahkan.` / `diperbarui.` / `dihapus.`
|
||||
|
||||
---
|
||||
|
||||
## 9. Otorisasi
|
||||
|
||||
- Hak akses berdasarkan role pada `Role` yang sudah ada. Ikuti mekanisme pembatasan role yang sudah dipakai (middleware/policy/gate yang ada); jangan membuat sistem permission baru.
|
||||
- Penginput data petani adalah role `enumerator` (bukan `fasilitator`). `fasilitator` khusus pemateri workshop.
|
||||
- Semua route `petani/...` dibungkus middleware `akses.petani` (`BatasiAksesPetani`): hanya `super_admin`, `admin`, `koordinator`, `enumerator`; koordinator hanya boleh mengakses petani dengan komoditas utama yang ditugaskan (`koordinator_komoditas`, cek lewat `User::bolehAksesPetani()`). Route tab petani baru wajib diletakkan di dalam grup ini.
|
||||
- Menu sidebar hanya menampilkan item yang boleh diakses role pengguna, dan route-nya juga dilindungi di sisi server. Menyembunyikan menu saja tidak cukup.
|
||||
|
||||
---
|
||||
|
||||
## 10. API (`app/Http/Controllers/Api/`)
|
||||
|
||||
- API dipakai aplikasi mobile/lapangan. **Kontrak API (URL, nama field, format respons) tidak boleh diubah** tanpa izin eksplisit, termasuk saat refaktor.
|
||||
- Endpoint baru mengikuti pola dan format respons API yang sudah ada di folder `Api/`.
|
||||
- Auth memakai Sanctum; login dibatasi rate limit (5/menit). Jangan longgarkan.
|
||||
- Setiap endpoint baru harus terbaca rapi di dokumentasi Scramble (type-hint Form Request dan tipe return yang jelas).
|
||||
|
||||
---
|
||||
|
||||
## 11. Pengecualian
|
||||
|
||||
### 11.0 Prinsip umum Dashboard & Laporan
|
||||
|
||||
Dashboard dan laporan **bersifat baca (read-only)** dan bentuknya beragam, sehingga controller-nya **fleksibel**:
|
||||
|
||||
- **Nama method bebas**, asalkan deskriptif dan camelCase (`index`, `chartProduktivitas`, `petaSebaran`, `rekapPerDesa`, `exportExcel`).
|
||||
- Boleh satu controller dengan banyak method, atau controller satu aksi (`__invoke`) jika halamannya sederhana.
|
||||
- Route ditulis manual (`Route::get(...)`), **tidak** memakai `Route::resource`.
|
||||
- Tidak ada `create/store/edit/update/destroy`. Jika sebuah dashboard butuh input data, input itu dibuat sebagai modul CRUD terpisah.
|
||||
|
||||
Yang **tetap berlaku** walau fleksibel:
|
||||
|
||||
- Lokasi folder per domain (Bagian 2), penamaan route kebab-case dengan prefix (`dashboard.*`, `laporan.*`).
|
||||
- Validasi filter memakai Form Request jika filternya lebih dari 2–3 parameter.
|
||||
- Query sederhana boleh di controller. Query agregat yang panjang, berat, atau dipakai di lebih dari satu tempat dipindah ke `app/Services/{Dashboard|Laporan}/`.
|
||||
- Data yang ditampilkan tetap menghormati soft delete (data terhapus tidak ikut dihitung) dan global scope program.
|
||||
- Pembatasan akses per role (Bagian 9).
|
||||
|
||||
### 11.1 Dashboard
|
||||
|
||||
- Controller: `app/Http/Controllers/Web/Dashboard/{Nama}Controller.php`.
|
||||
- Pola yang disarankan: `index` mengembalikan halaman; data grafik/peta yang dimuat via AJAX memakai method bernama jelas yang mengembalikan JSON.
|
||||
- Filter umum diterima lewat query string: program, wilayah (provinsi → desa), periode.
|
||||
- Query berat di-cache (`Cache::remember`) dengan kunci yang memuat nilai filter.
|
||||
- View: satu file per dashboard di `resources/views/dashboard/`. Grafik ApexCharts, peta Leaflet.
|
||||
- Data eksternal (AlphaVantage di `InternationalMarketController`) wajib di-cache dan punya penanganan gagal (tampilkan pesan, jangan error 500).
|
||||
|
||||
```php
|
||||
// routes/web.php
|
||||
Route::prefix('dashboard')->name('dashboard.')->group(function () {
|
||||
Route::get('produktivitas', [ProduktivitasController::class, 'index'])->name('produktivitas');
|
||||
Route::get('produktivitas/chart-panen', [ProduktivitasController::class, 'chartPanen'])
|
||||
->name('produktivitas.chart-panen');
|
||||
});
|
||||
```
|
||||
|
||||
### 11.2 Laporan / reporting
|
||||
|
||||
- Controller: `app/Http/Controllers/Web/Laporan/{Nama}Controller.php`; view di `resources/views/laporan/{nama}/`.
|
||||
- Pola yang disarankan per laporan: halaman filter + pratinjau (`index`), lalu method export per format (`exportExcel`, `exportPdf`). Semua menerima **filter yang sama** dengan pratinjau.
|
||||
- Export kecil yang menempel pada satu modul CRUD atau dashboard boleh berupa method `export` di controller modul tersebut.
|
||||
- Laporan yang lambat (data besar) boleh diproses di queue, lalu file diunduh setelah siap.
|
||||
- Gunakan package export yang sudah terpasang di project. Jika belum ada, tanyakan dulu.
|
||||
|
||||
```php
|
||||
Route::prefix('laporan')->name('laporan.')->group(function () {
|
||||
Route::get('rekap-panen', [RekapPanenController::class, 'index'])->name('rekap-panen');
|
||||
Route::get('rekap-panen/excel', [RekapPanenController::class, 'exportExcel'])->name('rekap-panen.excel');
|
||||
Route::get('rekap-panen/pdf', [RekapPanenController::class, 'exportPdf'])->name('rekap-panen.pdf');
|
||||
});
|
||||
```
|
||||
|
||||
### 11.3 Ekosistem (form builder dinamis)
|
||||
|
||||
- Modul `Ekosistem/` (Group, Tabel, Kolom, Formulir, Ringkasan, Value) memiliki struktur dinamis dan **dikecualikan** dari pola CRUD standar.
|
||||
- Jangan direfaktor ke pola standar kecuali diminta secara eksplisit. Perubahan kecil tetap mengikuti aturan validasi, soft delete, dan kebersihan.
|
||||
|
||||
---
|
||||
|
||||
## 12. Kebersihan repo
|
||||
|
||||
- **Dilarang** menyimpan file salinan/cadangan: `* copy.php`, `*Backup*`, `*01.php`, `*_old*`, dll. Riwayat disimpan di Git.
|
||||
- Tidak ada kode yang dikomentari dalam jumlah besar ("kode mati"); hapus saja.
|
||||
- Tidak ada route ganda (lihat Bagian 6).
|
||||
- Satu commit = satu perubahan logis (satu modul/fitur). Pesan commit Bahasa Indonesia, singkat, diawali jenis: `feat:`, `fix:`, `refactor:`, `chore:`.
|
||||
|
||||
Masalah kebersihan yang **sudah diketahui** (selesaikan saat menyentuh area terkait):
|
||||
|
||||
- File duplikat/backup: `* copy.php`, `IndikatorPertanianBackupController`, `PanenController01`, `SummaryDashboardController copy.php`, file `composerlock` yang tidak semestinya.
|
||||
- Route ganda: `users` (resource + manual), `users.verify` (dua kali), `jenis-komoditas.by-komoditas`, `varietas.by-jenis-komoditas`.
|
||||
|
||||
---
|
||||
|
||||
## 13. Prosedur refaktor modul lama
|
||||
|
||||
Modul lama **wajib** disesuaikan dengan standar ini secara bertahap.
|
||||
|
||||
### 13.1 Aturan
|
||||
|
||||
1. **Satu modul per sesi/commit.** Jangan merefaktor beberapa modul sekaligus.
|
||||
2. Jangan merefaktor modul yang sedang dikerjakan (ada perubahan belum di-commit) tanpa konfirmasi.
|
||||
3. API **tidak** ikut diubah (Bagian 10).
|
||||
4. Perilaku untuk pengguna harus tetap sama; refaktor bukan tempat menambah fitur.
|
||||
|
||||
### 13.2 Langkah
|
||||
|
||||
1. Simpan daftar route modul: `php artisan route:list --name={modul} > /tmp/before.txt`.
|
||||
2. Tentukan pola target (A/B/C) sesuai 3.3.
|
||||
3. Cari **semua** pemakaian nama route, URL, dan view lama di seluruh repo (Blade, JS, controller lain, sidebar), mis. `grep -rn "provinsi.view\|provinsi/add\|master.provinsi.add" app resources routes`.
|
||||
4. Ubah:
|
||||
- method `add` → `create`, `view` → `show`;
|
||||
- file `add.blade.php` → `create.blade.php`, `view.blade.php` → `show.blade.php`;
|
||||
- route manual → `Route::resource` (+ `only/except`, route tambahan di atasnya);
|
||||
- validasi inline → Form Request (dengan `withoutTrashed()` pada unique);
|
||||
- pastikan model memakai `SoftDeletes`, `deleted_by` terisi, dan cascade ke anak sudah ditulis;
|
||||
- semua referensi yang ditemukan di langkah 3.
|
||||
5. Bandingkan `route:list` sesudah dengan `/tmp/before.txt`; pastikan tidak ada route yang hilang tanpa sengaja.
|
||||
6. Uji manual alur lengkap: index → tambah → detail → ubah → hapus (cek `deleted_at`, `deleted_by`, dan data anak).
|
||||
7. Perbarui tabel status di 13.3.
|
||||
|
||||
### 13.3 Status migrasi modul
|
||||
|
||||
Status: `Belum` / `Proses` / `Selesai` / `Dikecualikan`
|
||||
|
||||
| Domain | Modul | Pola target | Status | Catatan |
|
||||
|---|---|---|---|---|
|
||||
| Master | Provinsi | A | Belum | Ada `list` + dropdown berantai |
|
||||
| Master | Kabupaten/Kota | A | Belum | `by-provinsi` |
|
||||
| Master | Kecamatan | A | Belum | `by-kabupaten` |
|
||||
| Master | Desa/Kelurahan | A | Belum | `by-kecamatan` |
|
||||
| Master | Komoditas | A | Belum | |
|
||||
| Master | Jenis Komoditas | A | Belum | Route `by-komoditas` dobel |
|
||||
| Master | Varietas | A | Belum | Route `by-jenis-komoditas` dobel |
|
||||
| Master | Adat | A | Belum | |
|
||||
| Master | Keluarga | ? | Belum | Tentukan pola saat refaktor |
|
||||
| Produktivitas | Petani (+ semua tab) | C | Belum | |
|
||||
| Produktivitas | Lahan | B | Belum | |
|
||||
| Produktivitas | Tanaman | B | Belum | |
|
||||
| Produktivitas | MapTanaman | ? | Belum | |
|
||||
| Produktivitas | Produksi | B | Belum | |
|
||||
| Produktivitas | Survey Kelompok Tani (+ tab) | C | Belum | |
|
||||
| Produktivitas | Sebaran Petani | ? | Belum | Sedang dikerjakan, konfirmasi dulu |
|
||||
| Program | Program, Program Komoditas, Program Lokasi | B | Belum | Pindah dari root ke `Program/` |
|
||||
| Program | Framework → Transformasi → Aktivitas → Target | B | Belum | Nested shallow |
|
||||
| Program | Realisasi | B | Belum | |
|
||||
| Program | Verifikasi | ? | Belum | Sedang dikerjakan, konfirmasi dulu |
|
||||
| Program | Workshop (+ Sesi, Peserta) | B | Belum | Sesi/Peserta sedang dikerjakan |
|
||||
| Program | Kelompok Belajar Tani | B | Belum | |
|
||||
| Bumdes | Profil, Kelembagaan, Survei | B | Belum | |
|
||||
| Koperasi | Profil, Kelembagaan, Survei | B | Belum | |
|
||||
| Konfigurasi | User | B | Belum | Route `users` & `users.verify` dobel |
|
||||
| Konfigurasi | Profil akun | — | Belum | Hanya `edit`/`update` |
|
||||
| Ekosistem | Semua | — | Dikecualikan | Lihat 11.3 |
|
||||
| Dashboard | Semua | — | Dikecualikan | Ikuti 11.1 |
|
||||
|
||||
---
|
||||
|
||||
## 14. Checklist modul baru
|
||||
|
||||
- [ ] Pola ditentukan (A/B/C) sesuai 3.3
|
||||
- [ ] Migration: `id`, kolom audit, `timestamps`, `softDeletes`, `deleted_by`; tanpa unique index
|
||||
- [ ] Model: `$table` eksplisit, `$fillable`, `SoftDeletes`, `deleted_by` terisi, casts/Enum
|
||||
- [ ] Relasi anak ditambahkan ke cascade `deleting` di model induk
|
||||
- [ ] Form Request `Store`/`Update` dengan pesan Bahasa Indonesia dan unique `withoutTrashed()`
|
||||
- [ ] Controller di `Web/{Domain}/` dengan nama method resmi saja
|
||||
- [ ] Route: `Route::resource` (+ `only/except`, `shallow`), tidak dobel, route tambahan di atas resource
|
||||
- [ ] View di `{domain}/{modul}/`: `index`, `create`, `edit`, `show`, `_form` sesuai pola
|
||||
- [ ] JS di file terpisah, URL dari `route()`, CSRF terpasang
|
||||
- [ ] Menu sidebar ditambahkan dan dibatasi per role; route dilindungi di server
|
||||
- [ ] Respons/flash mengikuti Bagian 8
|
||||
- [ ] Diuji manual: tambah, ubah, detail, hapus (cek `deleted_at`, `deleted_by`, data anak)
|
||||
- [ ] Tidak ada file salinan/backup tertinggal
|
||||
@@ -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';
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum LayoutForm: string
|
||||
{
|
||||
case ROW = 'form-row';
|
||||
case COLUMN = 'form-column';
|
||||
case VALUE = 'form-value';
|
||||
case SECTION = 'form-section';
|
||||
case HR_LINE = 'form-hr-line';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match($this) {
|
||||
self::ROW => 'Row',
|
||||
self::COLUMN => 'Column',
|
||||
self::VALUE => 'Value',
|
||||
self::SECTION => 'Section',
|
||||
self::HR_LINE => 'HR Line',
|
||||
};
|
||||
}
|
||||
|
||||
public static function options(): array
|
||||
{
|
||||
return collect(self::cases())->map(fn ($case) => [
|
||||
'value' => $case->value,
|
||||
'label' => $case->label(),
|
||||
])->toArray();
|
||||
}
|
||||
}
|
||||
@@ -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,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums\PendidikanPelatihan;
|
||||
|
||||
enum PelatihanGAP: string
|
||||
{
|
||||
case PEMANGKASAN = 'Pemangkasan/perawatan tanaman';
|
||||
case PEMUPUKAN = 'Pemupukan/nutrisi';
|
||||
case PENGENDALIAN = 'Pengendalian hama & penyakit';
|
||||
case PRAKTIK = 'Praktik Berkebun yang Baik (GAP)';
|
||||
case PENGOLAHAN = 'Pengolahan/pascapanen';
|
||||
case PENYERBUKAN = 'Penyerbukan Manual (Vanili)';
|
||||
case LAINNYA = 'Lainnya';
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
+17
-2
@@ -2,11 +2,26 @@
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
enum Role: string
|
||||
enum Role: string
|
||||
{
|
||||
case SUPER_ADMIN = 'super_admin';
|
||||
case ADMIN = 'admin'; // admin program
|
||||
case FASILITATOR = 'fasilitator';
|
||||
case KOORDINATOR = 'koordinator'; // koordinator per komoditas
|
||||
case ENUMERATOR = 'enumerator'; // penginput data petani di lapangan
|
||||
case FASILITATOR = 'fasilitator'; // pemateri workshop
|
||||
case PETANI = 'petani';
|
||||
case OFFTAKER = 'offtaker';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::SUPER_ADMIN => 'Super Admin',
|
||||
self::ADMIN => 'Admin',
|
||||
self::KOORDINATOR => 'Koordinator',
|
||||
self::ENUMERATOR => 'Enumerator',
|
||||
self::FASILITATOR => 'Fasilitator',
|
||||
self::PETANI => 'Petani',
|
||||
self::OFFTAKER => 'Offtaker',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Enums;
|
||||
|
||||
// Status kelengkapan data profil petani.
|
||||
// Draf → Lengkap (ditandai enumerator penginput) → Terverifikasi (oleh koordinator, menu menyusul).
|
||||
enum StatusDataPetani: string
|
||||
{
|
||||
case DRAFT = 'draft';
|
||||
case LENGKAP = 'lengkap';
|
||||
case TERVERIFIKASI = 'terverifikasi';
|
||||
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DRAFT => 'Draf',
|
||||
self::LENGKAP => 'Lengkap',
|
||||
self::TERVERIFIKASI => 'Terverifikasi',
|
||||
};
|
||||
}
|
||||
|
||||
// Warna badge Vuexy (bg-label-{warna})
|
||||
public function warna(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::DRAFT => 'secondary',
|
||||
self::LENGKAP => 'info',
|
||||
self::TERVERIFIKASI => 'success',
|
||||
};
|
||||
}
|
||||
|
||||
public static function values(): array
|
||||
{
|
||||
return array_column(self::cases(), 'value');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Core;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use App\Models\Core\Program;
|
||||
use App\Http\Resources\Core\ProgramResource;
|
||||
|
||||
class ProgramController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
$perPage = $request->query('per_page', 10);
|
||||
$search = $request->query('search', '');
|
||||
|
||||
$program = Program::where('nama', 'like', "%$search%")
|
||||
->paginate($perPage);
|
||||
|
||||
return ProgramResource::collection($program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id): ProgramResource
|
||||
{
|
||||
$program = Program::findOrFail($id);
|
||||
return new ProgramResource($program);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Ekosistem;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use App\Models\Ekosistem\TabelBasisData;
|
||||
use App\Models\Ekosistem\KolomBasisData;
|
||||
use App\Models\Core\Program;
|
||||
|
||||
|
||||
class FormBasisDataController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request, string $tabelId): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tabel = TabelBasisData::with('kolom')
|
||||
->whereHas('kolom', function ($query) {
|
||||
$query->where('is_active', true);
|
||||
})->find($tabelId);
|
||||
if (!$tabel) {
|
||||
abort(404, 'Data tabel tidak ditemukan.');
|
||||
}
|
||||
$kolom = KolomBasisData::where('tabel_id', $tabelId)
|
||||
->where('is_active', true)->get();
|
||||
if ($kolom->isEmpty()) {
|
||||
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
|
||||
}
|
||||
|
||||
$program = null;
|
||||
if (app()->has('SystemProgram')) {
|
||||
$program = app('SystemProgram');
|
||||
} else {
|
||||
if ($request->has('program_id') && $request->query('program_id')) {
|
||||
$programId = $request->query('program_id');
|
||||
$program = Program::find($programId);
|
||||
}
|
||||
}
|
||||
if (!$program) {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
|
||||
$method = $request->query('method', 'add');
|
||||
|
||||
$list_relasi = null;
|
||||
if ($method == 'add' || $method == 'edit') {
|
||||
$list_relasi = [];
|
||||
foreach ($kolom as $k) {
|
||||
if ($k->tipe == 'foreign_key') {
|
||||
$relasi['kolom_id'] = $k->id;
|
||||
try {
|
||||
$options_kolom = DB::table($k->relasi_tabel)->selectRaw($k->relasi_kolom_label . ' as label, ' . $k->relasi_kolom_id . ' as value')->whereNull('deleted_at');
|
||||
$relasi['options'] = $options_kolom->get();
|
||||
$relasi['sql'] = $options_kolom->toSql();
|
||||
} catch (\Throwable $th) {
|
||||
$relasi['options'] = [];
|
||||
}
|
||||
$list_relasi[] = $relasi;
|
||||
}
|
||||
}
|
||||
$list_relasi = collect($list_relasi);
|
||||
} elseif ($method == 'view') {
|
||||
$id = $request->query('value_id');
|
||||
if (!$id) {
|
||||
abort(400, 'value_id query parameter diperlukan untuk view method.');
|
||||
}
|
||||
|
||||
$values = ValueBasisData::query()
|
||||
->where('tabel_id', $tabelId)
|
||||
->where('value_id', $id)
|
||||
->where('program_id', $program->id)
|
||||
->get();
|
||||
if ($values->isEmpty()) {
|
||||
abort(404, 'Data tidak ditemukan.');
|
||||
}
|
||||
|
||||
foreach ($values as $v) {
|
||||
$k = $kolom->where('id', $v->kolom_id)->first();
|
||||
if ($k->tipe == 'foreign_key') {
|
||||
$v->value_relasi_label = DB::table($k->relasi_tabel)->where($k->relasi_kolom_id, $v->value_relasi)->value($k->relasi_kolom_label);
|
||||
} else if ($k->tipe == 'enum') {
|
||||
$opsi = collect($k->enum_opsi);
|
||||
$found = $opsi->first(function ($item) use ($v) {
|
||||
return (string) $item['value'] === (string) $v->value_enum;
|
||||
});
|
||||
$v->value_enum_label = $found['label'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
$value_id = $id;
|
||||
}
|
||||
|
||||
|
||||
$errors = $request->query('errors', null);
|
||||
|
||||
return response()->json($tabel->renderHtml($method, $errors, $list_relasi));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(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)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Ekosistem;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
use App\Models\Ekosistem\TabelBasisData;
|
||||
|
||||
use App\Http\Resources\Ekosistem\TabelBasisDataResource;
|
||||
|
||||
class TabelBasisDataController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$perPage = $request->query('per_page', 10);
|
||||
$search = strtolower($request->query('search', ''));
|
||||
|
||||
$tabel = TabelBasisData::with('kolom')
|
||||
->whereHas('kolom', function ($query) {
|
||||
$query->where('is_active', true);
|
||||
})
|
||||
->whereRaw('lower(tabel) LIKE ?', ["%$search%"])
|
||||
->paginate($perPage);
|
||||
|
||||
return TabelBasisDataResource::collection($tabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tabel = TabelBasisData::with('kolom', 'form', 'form.form', 'form.form.form', 'form.form.form.kolom')->findOrFail($id);
|
||||
|
||||
return (new TabelBasisDataResource($tabel))
|
||||
->response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Ekosistem;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
use App\Models\Ekosistem\TabelBasisData;
|
||||
use App\Models\Ekosistem\KolomBasisData;
|
||||
use App\Models\Ekosistem\ValueBasisData;
|
||||
use App\Models\Core\Program;
|
||||
|
||||
class ValueBasisDataController extends Controller
|
||||
{
|
||||
|
||||
public function index(Request $request, string $tabelId): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$perPage = $request->query('per_page', 10);
|
||||
$search = strtolower($request->query('search', ''));
|
||||
|
||||
$program = null;
|
||||
$programList = Program::get();
|
||||
if (app()->has('SystemProgram')) {
|
||||
$program = app('SystemProgram');
|
||||
} else {
|
||||
if ($request->has('program_id') && $request->query('program_id')) {
|
||||
$programId = $request->query('program_id');
|
||||
$program = Program::find($programId);
|
||||
if (!$program) {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$tabel = TabelBasisData::with('kolom')
|
||||
->whereHas('kolom', function ($query) {
|
||||
$query->where('is_active', true);
|
||||
})
|
||||
->find($tabelId);
|
||||
if (!$tabel) {
|
||||
abort(404, 'Data tabel tidak ditemukan.');
|
||||
}
|
||||
$kolom = KolomBasisData::where('tabel_id', $tabelId)
|
||||
->where('is_active', true)
|
||||
->when('is_browse', function ($q) {
|
||||
$q->where('is_browse', true);
|
||||
})
|
||||
->orderBy('urutan', 'asc')
|
||||
->get();
|
||||
if ($kolom->isEmpty()) {
|
||||
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
|
||||
}
|
||||
|
||||
$selects = [];
|
||||
foreach ($kolom as $k) {
|
||||
if ($k->tipe == 'boolean') {
|
||||
$selects[] = "
|
||||
MAX(
|
||||
CASE
|
||||
WHEN kolom_id = {$k->id}
|
||||
THEN CASE
|
||||
WHEN value_boolean = true THEN 'Ya'
|
||||
WHEN value_boolean = false THEN 'Tidak'
|
||||
ELSE NULL
|
||||
END
|
||||
ELSE NULL
|
||||
END
|
||||
) AS \"{$k->kolom}\"
|
||||
";
|
||||
} elseif ($k->tipe == 'foreign_key') {
|
||||
$selects[] = "
|
||||
MAX(
|
||||
CASE
|
||||
WHEN kolom_id = {$k->id}
|
||||
THEN (select {$k->relasi_kolom_label} from {$k->relasi_tabel} where {$k->relasi_kolom_id} = value_relasi)
|
||||
ELSE NULL
|
||||
END
|
||||
) AS \"{$k->kolom}\"
|
||||
";
|
||||
} elseif ($k->tipe == 'enum') {
|
||||
$selects[] = "
|
||||
MAX(
|
||||
CASE
|
||||
WHEN kolom_id = {$k->id}
|
||||
AND value_enum IS NOT NULL
|
||||
THEN (
|
||||
SELECT elem->>'label'
|
||||
FROM ekosistem_basis_data_kolom k,
|
||||
jsonb_array_elements(k.enum_opsi::jsonb) AS elem
|
||||
WHERE k.id = kolom_id
|
||||
AND elem->>'value' = value_enum
|
||||
LIMIT 1
|
||||
)
|
||||
ELSE NULL
|
||||
END
|
||||
) AS \"{$k->kolom}\"
|
||||
";
|
||||
} else {
|
||||
$selects[] = "
|
||||
MAX(
|
||||
CASE
|
||||
WHEN kolom_id = {$k->id}
|
||||
THEN value_{$k->tipe}
|
||||
ELSE NULL
|
||||
END
|
||||
) AS \"{$k->kolom}\"
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
$base = ValueBasisData::query()
|
||||
->join('core_program', 'core_program.id', '=', 'ekosistem_basis_data_value.program_id')
|
||||
->where('tabel_id', $tabelId)
|
||||
->when($program, function ($query) use ($program) {
|
||||
$query->where('program_id', $program->id);
|
||||
})
|
||||
->selectRaw("
|
||||
core_program.id AS program_id,
|
||||
core_program.nama AS program_nama,
|
||||
tabel_id,
|
||||
value_id,
|
||||
" . implode(",\n", $selects) . "
|
||||
")
|
||||
->groupBy('core_program.id', 'core_program.nama', 'tabel_id', 'value_id')
|
||||
->orderBy('value_id', 'asc');
|
||||
|
||||
$values = DB::query()->fromSub($base, 'pivot')
|
||||
->when($search, function ($query) use ($search, $kolom) {
|
||||
$query->where(function ($q) use ($search, $kolom) {
|
||||
foreach ($kolom as $k) {
|
||||
if ($k->tipe == 'text' || $k->tipe == 'varchar') {
|
||||
$q->orWhereRaw("lower({$k->kolom}) LIKE ?", ["%$search%"]);
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
->paginate($perPage);
|
||||
|
||||
return response()->json($values);
|
||||
}
|
||||
|
||||
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', 'enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tabel = TabelBasisData::whereHas('kolom', function ($query) {
|
||||
$query->where('is_active', true);
|
||||
})->find($tabelId);
|
||||
if (!$tabel) {
|
||||
abort(404, 'Data tabel tidak ditemukan.');
|
||||
}
|
||||
$kolom = KolomBasisData::where('tabel_id', $tabelId)
|
||||
->where('is_active', true)->get();
|
||||
if ($kolom->isEmpty()) {
|
||||
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
|
||||
}
|
||||
if (app()->has('SystemProgram')) {
|
||||
$program = app('SystemProgram');
|
||||
} else {
|
||||
if ($request->has('program_id') && $request->query('program_id')) {
|
||||
$programId = $request->query('program_id');
|
||||
$program = Program::find($programId);
|
||||
if (!$program) {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
} else {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
}
|
||||
|
||||
$validated = $request->validate($this->prepareValidationRules($kolom));
|
||||
|
||||
DB::transaction(function () use ($program, $tabelId, $validated, $kolom) {
|
||||
$maxId = ValueBasisData::where('tabel_id', $tabelId)
|
||||
->where('program_id', $program->id)
|
||||
->whereNotNull('value_id')
|
||||
->max('value_id');
|
||||
foreach ($kolom as $k) {
|
||||
$values = [
|
||||
'program_id' => $program->id,
|
||||
'tabel_id' => (int)$tabelId,
|
||||
'kolom_id' => $k->id,
|
||||
'value_id' => ($maxId ?? 0) + 1,
|
||||
'created_by' => auth()->id(),
|
||||
'updated_by' => auth()->id(),
|
||||
];
|
||||
if ($k->tipe == 'foreign_key') {
|
||||
$values['value_relasi'] = $validated[$k->kolom] ?? null;
|
||||
} else {
|
||||
$values['value_' . $k->tipe] = $validated[$k->kolom] ?? null;
|
||||
}
|
||||
|
||||
ValueBasisData::create($values);
|
||||
}
|
||||
});
|
||||
|
||||
return response()->json(['message' => 'Data berhasil disimpan.']);
|
||||
}
|
||||
|
||||
public function show(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function update(Request $request, string $tabelId, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tabel = TabelBasisData::whereHas('kolom', function ($query) {
|
||||
$query->where('is_active', true);
|
||||
})->find($tabelId);
|
||||
if (!$tabel) {
|
||||
abort(404, 'Data tabel tidak ditemukan.');
|
||||
}
|
||||
$kolom = KolomBasisData::where('tabel_id', $tabelId)
|
||||
->where('is_active', true)->get();
|
||||
if ($kolom->isEmpty()) {
|
||||
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
|
||||
}
|
||||
if (app()->has('SystemProgram')) {
|
||||
$program = app('SystemProgram');
|
||||
} else {
|
||||
if ($request->has('program_id') && $request->query('program_id')) {
|
||||
$programId = $request->query('program_id');
|
||||
$program = Program::find($programId);
|
||||
if (!$program) {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
} else {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
}
|
||||
|
||||
$values = ValueBasisData::query()
|
||||
->where('tabel_id', $tabelId)
|
||||
->where('value_id', $id)
|
||||
->where('program_id', $program->id)
|
||||
->get();
|
||||
if ($values->isEmpty()) {
|
||||
abort(404, 'Data tidak ditemukan.');
|
||||
}
|
||||
|
||||
$validated = $request->validate($this->prepareValidationRules($kolom));
|
||||
|
||||
DB::transaction(function () use ($program, $tabelId, $validated, $kolom, $id, $values) {
|
||||
foreach ($validated as $kol => $val) {
|
||||
$k = $kolom->where('kolom', $kol)->first();
|
||||
if (!$k) {
|
||||
continue;
|
||||
}
|
||||
$v = $values->where('kolom_id', $k->id)->first();
|
||||
if (!$v) {
|
||||
$vals = [
|
||||
'program_id' => $program->id,
|
||||
'tabel_id' => (int)$tabelId,
|
||||
'kolom_id' => $k->id,
|
||||
'value_id' => $id,
|
||||
'created_by' => auth()->id(),
|
||||
'updated_by' => auth()->id(),
|
||||
];
|
||||
if ($k->tipe == 'foreign_key') {
|
||||
$vals['value_relasi'] = $validated[$k->kolom] ?? null;
|
||||
} else {
|
||||
$vals['value_' . $k->tipe] = $validated[$k->kolom] ?? null;
|
||||
}
|
||||
ValueBasisData::create($vals);
|
||||
} else {
|
||||
$v->update([
|
||||
'value_' . ($k->tipe == 'foreign_key' ? 'relasi' : $k->tipe) => $val,
|
||||
'updated_by' => auth()->id(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return response()->json(['message' => 'Data berhasil diperbarui.']);
|
||||
}
|
||||
|
||||
public function destroy(Request $request, string $tabelId, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'admin', 'enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tabel = TabelBasisData::whereHas('kolom', function ($query) {
|
||||
$query->where('is_active', true);
|
||||
})->find($tabelId);
|
||||
if (!$tabel) {
|
||||
abort(404, 'Data tabel tidak ditemukan.');
|
||||
}
|
||||
$kolom = KolomBasisData::where('tabel_id', $tabelId)->get();
|
||||
if ($kolom->isEmpty()) {
|
||||
abort(404, 'Data kolom tidak ditemukan untuk tabel ini.');
|
||||
}
|
||||
if (app()->has('SystemProgram')) {
|
||||
$program = app('SystemProgram');
|
||||
} else {
|
||||
if ($request->has('program_id') && $request->query('program_id')) {
|
||||
$programId = $request->query('program_id');
|
||||
$program = Program::find($programId);
|
||||
if (!$program) {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
} else {
|
||||
abort(400, 'Program tidak ditemukan.');
|
||||
}
|
||||
}
|
||||
|
||||
$values = ValueBasisData::query()
|
||||
->where('tabel_id', $tabelId)
|
||||
->where('value_id', $id)
|
||||
->where('program_id', $program->id)
|
||||
->get();
|
||||
if ($values->isEmpty()) {
|
||||
abort(404, 'Data tidak ditemukan.');
|
||||
}
|
||||
|
||||
ValueBasisData::query()
|
||||
->where('tabel_id', $tabelId)
|
||||
->where('value_id', $id)
|
||||
->where('program_id', $program->id)
|
||||
->delete();
|
||||
|
||||
return response()->json(['message' => 'Data berhasil dihapus.']);
|
||||
}
|
||||
}
|
||||
+21
-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,13 +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'],
|
||||
'role' => ['string'],
|
||||
'username' => ['required', 'string', 'max:255'],
|
||||
'uid' => ['required','string', 'unique:users'],
|
||||
]);
|
||||
|
||||
@@ -53,34 +58,28 @@ class AuthController extends Controller
|
||||
'name' => $credentials['name'],
|
||||
'email' => $credentials['email'],
|
||||
'password' => Hash::make($credentials['password']),
|
||||
'role' => $credentials['role'],
|
||||
'username' => $credentials['username'],
|
||||
'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
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Master;
|
||||
|
||||
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\Master;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -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', 'enumerator', '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', 'enumerator', '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', 'enumerator', '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', 'enumerator', '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', 'enumerator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$jenisKomoditas = JenisKomoditas::findOrFail($id);
|
||||
$jenisKomoditas->delete();
|
||||
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
namespace App\Http\Controllers\Api\Master;
|
||||
|
||||
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\Master;
|
||||
|
||||
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\Master;
|
||||
|
||||
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\Master;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-5
@@ -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;
|
||||
@@ -13,7 +13,7 @@ class DistributionController extends Controller
|
||||
{
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani','fasilitator', 'offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani','enumerator', 'offtaker'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class DistributionController extends Controller
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani','fasilitator', 'offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani','enumerator', 'offtaker'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class DistributionController extends Controller
|
||||
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani','fasilitator', 'offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani','enumerator', 'offtaker'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class DistributionController extends Controller
|
||||
|
||||
public function batchUpsert(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani','fasilitator', 'offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani','enumerator', 'offtaker'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
+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;
|
||||
+56
-22
@@ -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,12 +16,12 @@ use App\Enums\StatusLahan;
|
||||
|
||||
class LahanController extends Controller
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request): AnonymousResourceCollection
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class LahanController extends Controller
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -87,24 +87,29 @@ class LahanController extends Controller
|
||||
if (!$profile) {
|
||||
abort(404, 'Profile tidak ditemukan');
|
||||
}
|
||||
|
||||
$profileRule = $user->role === 'fasilitator' ? ['required', 'numeric', 'exists:profiles,id'] : ['nullable'];
|
||||
if ($request->has('profile_id')) {
|
||||
$request->merge(['profile_id' => (int) $request->profile_id]);
|
||||
}
|
||||
|
||||
$profileRule = $user->role === 'enumerator' ? ['required', 'numeric', 'exists:profiles,id'] : ['nullable'];
|
||||
|
||||
$validated = $request->validate([
|
||||
'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'
|
||||
$targetProfileId = $user->role === 'enumerator'
|
||||
? $validated['profile_id']
|
||||
: $profile->id;
|
||||
|
||||
if ($user->role === 'fasilitator') {
|
||||
if ($user->role === 'enumerator') {
|
||||
$targetProfile = Profile::findOrFail($targetProfileId);
|
||||
|
||||
if ($targetProfile->desa_kelurahan_id !== $profile->desa_kelurahan_id) {
|
||||
@@ -112,14 +117,26 @@ class LahanController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
$desaKelurahanId = $user->role === 'fasilitator'
|
||||
$desaKelurahanId = $user->role === 'enumerator'
|
||||
? $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))
|
||||
@@ -132,14 +149,14 @@ class LahanController extends Controller
|
||||
*/
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$lahan = Lahan::with('desaKelurahan')->findOrFail($id);
|
||||
if ($lahan->profile_id !== Auth::user()->profile->id && Auth::user()->role === 'petani') {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
} else if (Auth::user()->role === 'fasilitator' && $lahan->desa_kelurahan_id !== Auth::user()->profile->desa_kelurahan_id) {
|
||||
} else if (Auth::user()->role === 'enumerator' && $lahan->desa_kelurahan_id !== Auth::user()->profile->desa_kelurahan_id) {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
@@ -149,16 +166,16 @@ 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'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$lahan = Lahan::findOrFail($id);
|
||||
if ($lahan->profile_id !== Auth::user()->profile->id && Auth::user()->role === 'petani') {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
} else if (Auth::user()->role === 'fasilitator' && $lahan->desa_kelurahan_id !== Auth::user()->profile->desa_kelurahan_id) {
|
||||
} else if (Auth::user()->role === 'enumerator' && $lahan->desa_kelurahan_id !== Auth::user()->profile->desa_kelurahan_id) {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
@@ -169,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();
|
||||
}
|
||||
@@ -181,14 +215,14 @@ class LahanController extends Controller
|
||||
*/
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$lahan = Lahan::findOrFail($id);
|
||||
if ($lahan->profile_id !== Auth::user()->profile->id && Auth::user()->role === 'petani') {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
} else if (Auth::user()->role === 'fasilitator' && $lahan->desa_kelurahan_id !== Auth::user()->profile->desa_kelurahan_id) {
|
||||
} else if (Auth::user()->role === 'enumerator' && $lahan->desa_kelurahan_id !== Auth::user()->profile->desa_kelurahan_id) {
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
|
||||
@@ -199,7 +233,7 @@ class LahanController extends Controller
|
||||
|
||||
public function batchUpsert(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
+7
-7
@@ -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;
|
||||
@@ -12,7 +12,7 @@ class OfftakerController extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani', 'fasilitator', 'admin','offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani', 'enumerator', 'admin','offtaker'])) {
|
||||
abort(403, 'Unauthorized');
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class OfftakerController extends Controller
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani', 'fasilitator', 'admin','offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani', 'enumerator', 'admin','offtaker'])) {
|
||||
abort(403, 'Unauthorized');
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class OfftakerController extends Controller
|
||||
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani', 'fasilitator', 'admin','offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani', 'enumerator', 'admin','offtaker'])) {
|
||||
abort(403, 'Unauthorized');
|
||||
}
|
||||
$offtaker = Offtaker::findOrFail($id);
|
||||
@@ -67,7 +67,7 @@ class OfftakerController extends Controller
|
||||
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani', 'fasilitator', 'admin','offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani', 'enumerator', 'admin','offtaker'])) {
|
||||
abort(403, 'Unauthorized');
|
||||
}
|
||||
$offtaker = Offtaker::findOrFail($id);
|
||||
@@ -87,7 +87,7 @@ class OfftakerController extends Controller
|
||||
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani', 'fasilitator', 'admin','offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani', 'enumerator', 'admin','offtaker'])) {
|
||||
abort(403, 'Unauthorized');
|
||||
}
|
||||
Offtaker::findOrFail($id)->delete();
|
||||
@@ -100,7 +100,7 @@ class OfftakerController extends Controller
|
||||
*/
|
||||
public function batchUpsert(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['super_admin', 'petani', 'fasilitator', 'admin','offtaker'])) {
|
||||
if (!Gate::any(['super_admin', 'petani', 'enumerator', 'admin','offtaker'])) {
|
||||
abort(403, 'Unauthorized');
|
||||
}
|
||||
|
||||
@@ -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', 'enumerator','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', 'enumerator', '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', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$panen = Panen::findOrFail($id);
|
||||
return response()->json($panen);
|
||||
}
|
||||
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'enumerator','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', 'enumerator']);
|
||||
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', 'enumerator','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);
|
||||
}
|
||||
}
|
||||
+8
-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;
|
||||
@@ -10,11 +10,11 @@ use Illuminate\Support\Facades\Gate;
|
||||
|
||||
use App\Models\Map\Panen;
|
||||
|
||||
class PanenController extends Controller
|
||||
class PanenController01 extends Controller
|
||||
{
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class PanenController extends Controller
|
||||
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ class PanenController extends Controller
|
||||
|
||||
public function show(string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$panen = Panen::findOrFail($id);
|
||||
@@ -67,7 +67,7 @@ class PanenController extends Controller
|
||||
|
||||
public function update(Request $request, string $id): JsonResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator','super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$panen = Panen::findOrFail($id);
|
||||
@@ -85,7 +85,7 @@ class PanenController extends Controller
|
||||
|
||||
public function destroy(string $id): JsonResponse
|
||||
{
|
||||
Gate::authorize(['petani', 'fasilitator']);
|
||||
Gate::authorize(['petani', 'enumerator']);
|
||||
Panen::findOrFail($id)->delete();
|
||||
return response()->json(null, 204);
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class PanenController extends Controller
|
||||
*/
|
||||
public function batchUpsert(Request $request): JsonResponse
|
||||
{
|
||||
if (Gate::authorize(['petani', 'fasilitator','super_admin'])) {
|
||||
if (Gate::authorize(['petani', 'enumerator','super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
$profileId = Auth::user()->profile->id;
|
||||
+9
-9
@@ -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;
|
||||
@@ -23,7 +23,7 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
if(!Gate::any(['fasilitator', 'super_admin'])) {
|
||||
if(!Gate::any(['enumerator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class ProfileController extends Controller
|
||||
$profileId = $user->role === 'petani' ? $profile->id : $requestID;
|
||||
|
||||
$desaKelurahanId = null;
|
||||
if ($profile->role === 'fasilitator' || $profile->role === 'super_admin') {
|
||||
if ($profile->role === 'enumerator' || $profile->role === 'super_admin') {
|
||||
$desaKelurahanId = $profile->desa_kelurahan_id;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
if(!Gate::any(['fasilitator','super_admin'])){
|
||||
if(!Gate::any(['enumerator','super_admin'])){
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ class ProfileController extends Controller
|
||||
public function show(string $id): JSONResponse
|
||||
{
|
||||
// attempt to access profile, only for allowed roles
|
||||
if (!Gate::any(['petani', 'fasilitator', 'offtaker', 'super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator', 'offtaker', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ class ProfileController extends Controller
|
||||
*/
|
||||
public function update(Request $request, string $id): JSONResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'offtaker', 'super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator', 'offtaker', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ class ProfileController extends Controller
|
||||
|
||||
$profile = Profile::findOrFail($id);
|
||||
|
||||
if ($user->role === 'fasilitator' && $profile->desa_kelurahan_id != $user->profile->desa_kelurahan_id) {
|
||||
if ($user->role === 'enumerator' && $profile->desa_kelurahan_id != $user->profile->desa_kelurahan_id) {
|
||||
abort(403, 'Unauthorized');
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ class ProfileController extends Controller
|
||||
|
||||
public function downloadFile(string $id, string $type): JsonResponse | BinaryFileResponse
|
||||
{
|
||||
if (!Gate::any(['petani', 'fasilitator', 'super_admin'])) {
|
||||
if (!Gate::any(['petani', 'enumerator', 'super_admin'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ class ProfileController extends Controller
|
||||
|
||||
public function verify(Request $request, string $id): JSONResponse
|
||||
{
|
||||
if (!Gate::any(['fasilitator'])) {
|
||||
if (!Gate::any(['enumerator'])) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
@@ -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', 'enumerator','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', 'enumerator','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', 'enumerator','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', 'enumerator','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', 'enumerator','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);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user