new field akses pasar

This commit is contained in:
2026-10-15 15:10:18 +07:00
parent 3e172cf915
commit 7699430301
4 changed files with 164 additions and 5 deletions
@@ -128,6 +128,17 @@ class AksesPasarController extends Controller
return $request->validate([ return $request->validate([
'petani_id' => ['required', 'exists:petani,id'], 'petani_id' => ['required', 'exists:petani,id'],
'tujuan_penjualan' => ['nullable', 'array'],
'tujuan_penjualan.*' => ['string'],
'tujuan_penjualan_lainnya' => [
Rule::requiredIf(fn () => in_array('Lainnya', $request->input('tujuan_penjualan', []), true)),
'nullable', 'string', 'max:255'
],
'sifat_hubungan_bisnis' => ['nullable', 'string', 'max:255'],
'bentuk_penjualan' => ['nullable', 'string', 'max:255'],
'frekuensi_penjualan' => ['nullable', 'string', 'max:255'],
'skor_pengalaman' => ['nullable', 'integer', Rule::in(SkorPengalaman::values())], 'skor_pengalaman' => ['nullable', 'integer', Rule::in(SkorPengalaman::values())],
'alasan_berhenti' => [ 'alasan_berhenti' => [
Rule::requiredIf(fn () => in_array((int)$request->input('skor_pengalaman'), [ Rule::requiredIf(fn () => in_array((int)$request->input('skor_pengalaman'), [
@@ -168,6 +179,7 @@ class AksesPasarController extends Controller
], [ ], [
'petani_id.required' => 'Petani harus dipilih.', 'petani_id.required' => 'Petani harus dipilih.',
'petani_id.exists' => 'Petani tidak ditemukan.', 'petani_id.exists' => 'Petani tidak ditemukan.',
'tujuan_penjualan_lainnya.required' => 'Keterangan saluran penjualan lainnya harus diisi.',
'skor_pengalaman.integer' => 'Skor pengalaman harus berupa angka.', 'skor_pengalaman.integer' => 'Skor pengalaman harus berupa angka.',
'skor_pengalaman.in' => 'Skor pengalaman tidak valid.', 'skor_pengalaman.in' => 'Skor pengalaman tidak valid.',
'alasan_berhenti.required' => 'Alasan berhenti harus diisi.', 'alasan_berhenti.required' => 'Alasan berhenti harus diisi.',
@@ -204,6 +216,11 @@ class AksesPasarController extends Controller
{ {
$payload = collect($validated)->except(['harga_jual'])->all(); $payload = collect($validated)->except(['harga_jual'])->all();
// Bersihkan input teks "Lainnya" jika checkbox Lainnya tidak dipilih
if (!in_array('Lainnya', $payload['tujuan_penjualan'] ?? [], true)) {
$payload['tujuan_penjualan_lainnya'] = null;
}
if (!in_array((int)($payload['skor_pengalaman'] ?? 0), [ if (!in_array((int)($payload['skor_pengalaman'] ?? 0), [
SkorPengalaman::PERNAH_BERHENTI_TIDAK_ADA_AKSES->value, SkorPengalaman::PERNAH_BERHENTI_TIDAK_ADA_AKSES->value,
SkorPengalaman::PERNAH_BERHENTI_MUNGKIN_KEMBALI->value SkorPengalaman::PERNAH_BERHENTI_MUNGKIN_KEMBALI->value
@@ -223,7 +240,6 @@ class AksesPasarController extends Controller
return $payload; return $payload;
} }
private function syncHargaJual($petaniId, array $hargaJualData, $createdBy, $updatedBy = null): void private function syncHargaJual($petaniId, array $hargaJualData, $createdBy, $updatedBy = null): void
{ {
HargaJualPanen::where('petani_id', $petaniId)->delete(); HargaJualPanen::where('petani_id', $petaniId)->delete();
@@ -258,7 +274,7 @@ class AksesPasarController extends Controller
$data['harga_jual'][$index]['harga_tahun_lalu'] = $this->currencyDigits($item['harga_tahun_lalu']); $data['harga_jual'][$index]['harga_tahun_lalu'] = $this->currencyDigits($item['harga_tahun_lalu']);
} }
if (array_key_exists('harga_dua_tahun_lalu', $item)) { if (array_key_exists('harga_dua_tahun_lalu', $item)) {
$data['harga_jual'][$index]['harga_dua_tahun_lalu'] = $this->currencyDigits($item['harga_dua_tahun_lalu']); $data['harga_jual'][$index]['harga_dua_tahun_lalu'] = $this->currencyDigits($item['harga_dua_tahun_l'], 0); // fixed
} }
} }
} }
+6
View File
@@ -22,6 +22,11 @@ class AksesPasar extends Model
protected $fillable = [ protected $fillable = [
'uid', 'uid',
'petani_id', 'petani_id',
'tujuan_penjualan',
'tujuan_penjualan_lainnya',
'sifat_hubungan_bisnis',
'bentuk_penjualan',
'frekuensi_penjualan',
'skor_pengalaman', 'skor_pengalaman',
'saluran_terdahulu', 'saluran_terdahulu',
'saluran_terdahulu_lainnya', 'saluran_terdahulu_lainnya',
@@ -44,6 +49,7 @@ class AksesPasar extends Model
]; ];
protected $casts = [ protected $casts = [
'tujuan_penjualan' => 'array',
'saluran_terdahulu' => 'array', 'saluran_terdahulu' => 'array',
]; ];
@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('akses_pasar', function (Blueprint $table) {
$table->text('tujuan_penjualan')->nullable();
$table->string('tujuan_penjualan_lainnya')->nullable();
$table->text('sifat_hubungan_bisnis')->nullable();
$table->text('bentuk_penjualan')->nullable();
$table->string('frekuensi_penjualan')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('akses_pasar', function (Blueprint $table) {
$table->dropColumn([
'tujuan_penjualan',
'tujuan_penjualan_lainnya',
'sifat_hubungan_bisnis',
'bentuk_penjualan',
'frekuensi_penjualan'
]);
});
}
};
@@ -30,6 +30,106 @@
<div class="card mb-6"> <div class="card mb-6">
<div class="card-body pt-12"> <div class="card-body pt-12">
<h5 class="pb-3 border-bottom mb-4">Saluran Penjualan & Akses Pasar</h5>
<h6 class="fw-bold text-dark mb-2">Saluran Penjualan Utama</h6>
<div class="mb-4">
<label class="form-label fw-semibold">144. Kepada siapa Bapak/Ibu biasanya menjual hasil panen? (boleh pilih lebih dari satu)</label>
<div class="row g-2">
@php
$tujuanOptions = ['Tengkulak/pedagang lokal', 'Koperasi', 'BUMDes', 'Langsung ke pembeli/eksportir'];
@endphp
@foreach($tujuanOptions as $tujuan)
<div class="col-md-6">
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" name="tujuan_penjualan[]" value="{{ $tujuan }}" id="tujuan-{{ Str::slug($tujuan) }}" {{ in_array($tujuan, (array) old('tujuan_penjualan', $aksesPasar?->tujuan_penjualan ?? []), true) ? 'checked' : '' }}>
<label class="form-check-label" for="tujuan-{{ Str::slug($tujuan) }}">{{ $tujuan }}</label>
</div>
</div>
@endforeach
<div class="col-12 mt-2">
<div class="d-flex align-items-center gap-2 flex-wrap">
<div class="form-check mb-0">
<input class="form-check-input" type="checkbox" name="tujuan_penjualan[]" value="Lainnya" id="tujuan-lainnya" {{ in_array('Lainnya', (array) old('tujuan_penjualan', $aksesPasar?->tujuan_penjualan ?? []), true) ? 'checked' : '' }}>
<label class="form-check-label" for="tujuan-lainnya">Lainnya:</label>
</div>
<input type="text" class="form-control form-control-sm w-auto flex-grow-1 max-w-400" style="max-width: 400px;" name="tujuan_penjualan_lainnya" value="{{ old('tujuan_penjualan_lainnya', $aksesPasar?->tujuan_penjualan_lainnya) }}" placeholder="Sebutkan lainnya...">
</div>
</div>
</div>
</div>
<h6 class="fw-bold text-dark mt-4 mb-2">Sifat Hubungan dengan Pembeli</h6>
<div class="mb-4">
<label class="form-label fw-semibold">Bagaimana sifat hubungan jual Bapak/Ibu dengan pembeli utama saat ini?</label>
<div class="row g-2">
@php
$sifatHubunganOptions = [
'Bebas, bisa pindah pembeli kapan saja',
'Langganan tetap, tapi tidak terikat',
'Berbasis hutang, harus jual ke sana karena ada pinjaman',
'Titip jual,dibayar setelah produk terjual',
'Ada komitmen volume, sudah ada kesepakatan jumlah',
'Semi-kontrak, ada kesepakatan harga tertentu'
];
@endphp
@foreach($sifatHubunganOptions as $sifat)
<div class="col-md-6">
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="sifat_hubungan_bisnis" value="{{ $sifat }}" id="sifat-{{ Str::slug($sifat) }}" {{ old('sifat_hubungan_bisnis', $aksesPasar?->sifat_hubungan_bisnis) === $sifat ? 'checked' : '' }}>
<label class="form-check-label" for="sifat-{{ Str::slug($sifat) }}">{{ $sifat }}</label>
</div>
</div>
@endforeach
</div>
</div>
<h6 class="fw-bold text-dark mt-4 mb-2">Bentuk Produk yang Dijual</h6>
<div class="mb-4">
<label class="form-label fw-semibold">Dalam bentuk apa produk dijual?</label>
<div class="row g-2">
@php
$bentukPenjualanOptions = [
'Buah segar hasil petik (gelondongan)',
'Biji/polong basah (belum dikeringkan)',
'Biji/polong kering/biji kupas',
'Terfermentasi'
];
@endphp
@foreach($bentukPenjualanOptions as $bentuk)
<div class="col-md-6">
<div class="form-check mb-2">
<input class="form-check-input" type="radio" name="bentuk_penjualan" value="{{ $bentuk }}" id="bentuk-{{ Str::slug($bentuk) }}" {{ old('bentuk_penjualan', $aksesPasar?->bentuk_penjualan) === $bentuk ? 'checked' : '' }}>
<label class="form-check-label" for="bentuk-{{ Str::slug($bentuk) }}">{{ $bentuk }}</label>
</div>
</div>
@endforeach
</div>
</div>
<h6 class="fw-bold text-dark mt-4 mb-2">Frekuensi Penjualan</h6>
<div class="mb-4">
<label class="form-label fw-semibold">Kapan biasanya menjual hasil panen?</label>
<div class="d-flex flex-column gap-2">
@php
$frekuensiOptions = [
'Langsung setelah panen',
'Ditumpuk dulu beberapa waktu',
'Saat butuh uang mendesak'
];
@endphp
@foreach($frekuensiOptions as $freq)
<div class="form-check mb-1">
<input class="form-check-input" type="radio" name="frekuensi_penjualan" value="{{ $freq }}" id="freq-{{ Str::slug($freq) }}" {{ old('frekuensi_penjualan', $aksesPasar?->frekuensi_penjualan) === $freq ? 'checked' : '' }}>
<label class="form-check-label" for="freq-{{ Str::slug($freq) }}">{{ $freq }}</label>
</div>
@endforeach
</div>
</div>
<hr class="my-4">
<h5 class="pb-3 border-bottom mb-4">Pengalaman Saluran Lain</h5> <h5 class="pb-3 border-bottom mb-4">Pengalaman Saluran Lain</h5>
<div class="row"> <div class="row">
@@ -265,7 +365,6 @@
function formatRupiah(value) { function formatRupiah(value) {
const digits = onlyDigits(value); const digits = onlyDigits(value);
return digits.replace(/\B(?=(\d{3})+(?!\d))/g, '.'); return digits.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
} }