boolean('melakukan_jual_beli'); $hasChoice = fn (string $field, string $value) => is_array($selected = $this->input($field)) && in_array($value, $selected, true); $notSold = $hasChoice('saluran_penjualan', SaluranPenjualanBumdes::BELUM_MENJUAL->value); $otherSource = $trading && $hasChoice('sumber_pasokan', SumberPasokanBumdes::LAINNYA->value); $otherChannel = $trading && $hasChoice('saluran_penjualan', SaluranPenjualanBumdes::LAINNYA->value); $otherRelationship = $trading && $hasChoice('hubungan_petani_pemasok', HubunganPemasokBumdes::LAINNYA->value); $otherPayment = $trading && $this->input('mekanisme_pembayaran_petani') === MekanismePembayaranBumdes::LAINNYA->value; $otherPrice = $trading && $this->input('penetapan_harga_beli') === PenetapanHargaBeliBumdes::LAINNYA->value; $periods = implode(',', array_keys(PeriodePanenBumdes::options())); $products = implode(',', array_keys(BentukProdukBumdes::options())); $rules = [...$this->pascapanenRules(), 'melakukan_jual_beli' => ['required', 'boolean'], 'redirect_fragment' => ['nullable', Rule::in(['section-rantai-penjualan', 'section-rantai-hubungan-pemasok', 'section-rantai-harga-beli', 'section-rantai-sortasi', 'section-rantai-pengeringan', 'section-rantai-fermentasi', 'section-rantai-premium-harga'])], 'sumber_pasokan' => [Rule::excludeIf(! $trading), 'nullable', 'array'], 'sumber_pasokan.*' => [Rule::excludeIf(! $trading), 'string', 'distinct', Rule::enum(SumberPasokanBumdes::class)], 'sumber_pasokan_lainnya' => [Rule::excludeIf(! $otherSource), Rule::requiredIf($otherSource), 'string', 'max:255'], 'bentuk_produk_dibeli' => [Rule::excludeIf(! $trading), 'nullable', 'array'], 'bentuk_produk_dibeli.*' => [Rule::excludeIf(! $trading), 'string', 'distinct', Rule::enum(BentukProdukBumdes::class)], 'volume_pembelian' => [Rule::excludeIf(! $trading), 'nullable', 'array:'.$periods], 'volume_pembelian.*' => [Rule::excludeIf(! $trading), 'nullable', 'numeric', 'decimal:0,3', 'min:0', 'max:999999999999.999'], 'saluran_penjualan' => [Rule::excludeIf(! $trading), 'nullable', 'array'], 'saluran_penjualan.*' => [Rule::excludeIf(! $trading), 'string', 'distinct', Rule::enum(SaluranPenjualanBumdes::class)], 'saluran_penjualan_lainnya' => [Rule::excludeIf(! $otherChannel), Rule::requiredIf($otherChannel), 'string', 'max:255'], 'bentuk_produk_dijual' => [Rule::excludeIf(! $trading || $notSold), 'nullable', 'array'], 'bentuk_produk_dijual.*' => [Rule::excludeIf(! $trading || $notSold), 'string', 'distinct', Rule::enum(BentukProdukBumdes::class)], 'volume_penjualan' => [Rule::excludeIf(! $trading || $notSold), 'nullable', 'array:'.$periods], 'volume_penjualan.*' => [Rule::excludeIf(! $trading || $notSold), 'nullable', 'numeric', 'decimal:0,3', 'min:0', 'max:999999999999.999'], 'hubungan_petani_pemasok' => [Rule::excludeIf(! $trading), 'nullable', 'array'], 'hubungan_petani_pemasok.*' => [Rule::excludeIf(! $trading), 'string', 'distinct', Rule::enum(HubunganPemasokBumdes::class)], 'hubungan_petani_pemasok_lainnya' => [Rule::excludeIf(! $otherRelationship), Rule::requiredIf($otherRelationship), 'string', 'max:255'], 'mekanisme_pembayaran_petani' => [Rule::excludeIf(! $trading), 'nullable', Rule::enum(MekanismePembayaranBumdes::class)], 'mekanisme_pembayaran_lainnya' => [Rule::excludeIf(! $otherPayment), Rule::requiredIf($otherPayment), 'string', 'max:255'], 'perjanjian_petani' => [Rule::excludeIf(! $trading), 'nullable', Rule::enum(PerjanjianPetaniBumdes::class)], 'harga_beli_petani' => [Rule::excludeIf(! $trading), 'nullable', 'array:'.$products], 'penetapan_harga_beli' => [Rule::excludeIf(! $trading), 'nullable', Rule::enum(PenetapanHargaBeliBumdes::class)], 'penetapan_harga_beli_lainnya' => [Rule::excludeIf(! $otherPrice), Rule::requiredIf($otherPrice), 'string', 'max:255'], ]; foreach (BentukProdukBumdes::cases() as $product) { $enabled = $trading && $hasChoice('bentuk_produk_dibeli', $product->value); $prefix = 'harga_beli_petani.'.$product->value; $rules[$prefix] = [Rule::excludeIf(! $enabled), 'nullable', 'array:'.$periods]; $rules[$prefix.'.*'] = [Rule::excludeIf(! $enabled), 'nullable', 'integer', 'min:0', 'max:9999999999999999']; } return $rules; } private function pascapanenRules(): array { $processing = $this->boolean('melakukan_pengolahan_pascapanen'); $sorting = $processing && in_array($this->input('status_sortasi'), [StatusSortasiBumdes::RUTIN_STANDAR->value, StatusSortasiBumdes::TIDAK_KONSISTEN->value], true); $drying = $processing && in_array($this->input('status_pengeringan'), [StatusPengeringanBumdes::RUTIN->value, StatusPengeringanBumdes::KADANG->value], true); $fermenting = $processing && in_array($this->input('status_fermentasi'), [StatusFermentasiBumdes::RUTIN->value, StatusFermentasiBumdes::PERNAH_MENCOBA->value], true); return [ 'melakukan_pengolahan_pascapanen' => ['required', 'boolean'], 'status_sortasi' => [Rule::excludeIf(! $processing), 'nullable', Rule::enum(StatusSortasiBumdes::class)], 'kriteria_sortasi' => [Rule::excludeIf(! $sorting), Rule::requiredIf($sorting), 'string', 'max:2000'], 'status_pengeringan' => [Rule::excludeIf(! $processing), 'nullable', Rule::enum(StatusPengeringanBumdes::class)], 'cara_tempat_pengeringan' => [Rule::excludeIf(! $drying), Rule::requiredIf($drying), 'string', 'max:2000'], 'status_fermentasi' => [Rule::excludeIf(! $processing), 'nullable', Rule::enum(StatusFermentasiBumdes::class)], 'model_fermentasi' => [Rule::excludeIf(! $fermenting), Rule::requiredIf($fermenting), 'array', 'min:1'], 'model_fermentasi.*' => [Rule::excludeIf(! $fermenting), 'string', 'distinct', Rule::enum(ModelFermentasiBumdes::class)], 'proses_fermentasi' => [Rule::excludeIf(! $fermenting), Rule::requiredIf($fermenting), 'string', 'max:2000'], 'premium_harga_pascapanen' => [Rule::excludeIf(! $processing), 'nullable', 'integer', 'min:0', 'max:9999999999999999'], ]; } protected function prepareForValidation(): void { $premium = $this->input('premium_harga_pascapanen'); if (is_string($premium) && preg_match('/^\d{1,3}(\.\d{3})+$/D', $premium)) { $this->merge(['premium_harga_pascapanen' => str_replace('.', '', $premium)]); } $prices = $this->input('harga_beli_petani'); if (! is_array($prices)) { return; } foreach ($prices as &$row) { if (! is_array($row)) { continue; } foreach ($row as &$value) { if (is_string($value) && preg_match('/^\d{1,3}(\.\d{3})+$/D', $value)) { $value = str_replace('.', '', $value); } } unset($value); } unset($row); $this->merge(['harga_beli_petani' => $prices]); } public function after(): array { return [function (Validator $validator) { $channels = $this->input('saluran_penjualan'); if ($this->boolean('melakukan_jual_beli') && is_array($channels) && count($channels) > 1 && in_array(SaluranPenjualanBumdes::BELUM_MENJUAL->value, $channels, true)) { $validator->errors()->add('saluran_penjualan', 'Belum pernah menjual tidak boleh dipilih bersama saluran penjualan lainnya.'); } }]; } public function messages(): array { return [...parent::messages(), 'melakukan_pengolahan_pascapanen.required' => 'Kegiatan pengolahan pascapanen wajib dipilih.', 'melakukan_jual_beli.required' => 'Kegiatan jual beli komoditas wajib dipilih.', 'model_fermentasi.min' => 'Pilih minimal satu model fermentasi.', 'premium_harga_pascapanen.max' => 'Premium harga tidak boleh melebihi Rp 9.999.999.999.999.999 per kg.', 'numeric' => ':attribute harus berupa angka.', 'decimal' => ':attribute boleh memiliki maksimal 3 angka di belakang koma.', 'distinct' => ':attribute tidak boleh dipilih lebih dari satu kali.', 'harga_beli_petani.*.*.max' => 'Harga beli tidak boleh melebihi Rp 9.999.999.999.999.999 per kg.', ]; } public function attributes(): array { return [...parent::attributes(), 'melakukan_pengolahan_pascapanen' => 'Kegiatan pengolahan pascapanen', 'status_sortasi' => 'Praktik sortasi', 'kriteria_sortasi' => 'Standar/kriteria sortasi', 'status_pengeringan' => 'Praktik pengeringan', 'cara_tempat_pengeringan' => 'Cara dan tempat pengeringan', 'status_fermentasi' => 'Praktik fermentasi/pengepresan', 'model_fermentasi' => 'Model fermentasi', 'proses_fermentasi' => 'Proses fermentasi', 'premium_harga_pascapanen' => 'Premium harga per kg', 'model_fermentasi.*' => 'Pilihan model fermentasi', 'melakukan_jual_beli' => 'Kegiatan jual beli komoditas', 'redirect_fragment' => 'Tujuan setelah penyimpanan', 'sumber_pasokan' => 'Sumber pasokan', 'sumber_pasokan.*' => 'Pilihan sumber pasokan', 'sumber_pasokan_lainnya' => 'Sumber pasokan lainnya', 'bentuk_produk_dibeli' => 'Bentuk produk yang dibeli', 'bentuk_produk_dibeli.*' => 'Pilihan bentuk produk yang dibeli', 'volume_pembelian' => 'Volume pembelian', 'volume_pembelian.*' => 'Volume pembelian pada musim panen terkait', 'saluran_penjualan' => 'Saluran penjualan', 'saluran_penjualan.*' => 'Pilihan saluran penjualan', 'saluran_penjualan_lainnya' => 'Saluran penjualan lainnya', 'bentuk_produk_dijual' => 'Bentuk produk yang dijual', 'bentuk_produk_dijual.*' => 'Pilihan bentuk produk yang dijual', 'volume_penjualan' => 'Volume penjualan', 'volume_penjualan.*' => 'Volume penjualan pada musim panen terkait', 'hubungan_petani_pemasok' => 'Hubungan dengan petani pemasok', 'hubungan_petani_pemasok.*' => 'Pilihan hubungan dengan petani pemasok', 'hubungan_petani_pemasok_lainnya' => 'Hubungan dengan petani pemasok lainnya', 'mekanisme_pembayaran_petani' => 'Mekanisme pembayaran kepada petani', 'mekanisme_pembayaran_lainnya' => 'Mekanisme pembayaran lainnya', 'perjanjian_petani' => 'Perjanjian dengan petani', 'harga_beli_petani' => 'Harga beli dari petani', 'harga_beli_petani.*' => 'Harga beli untuk bentuk produk terkait', 'harga_beli_petani.*.*' => 'Harga beli pada musim panen terkait', 'penetapan_harga_beli' => 'Penetapan harga beli', 'penetapan_harga_beli_lainnya' => 'Penetapan harga beli lainnya', ]; } }