> */ public function rules(): array { return [ 'name' => ['required', 'string', 'max:255'], 'inci' => ['nullable', 'string'], 'effect' => ['nullable', 'string'], 'pos' => ['nullable', 'integer', 'min:0', 'max:255'], 'default_factor' => ['nullable', 'numeric', 'min:0'], 'min_stock_alert' => ['nullable', 'numeric', 'min:0'], 'material_quality_id' => ['nullable', 'integer', 'exists:material_qualities,id'], 'tax_rate_id' => ['nullable', 'integer', 'exists:tax_rates,id'], 'delivery_time' => ['nullable', 'string', 'max:255'], 'delivery_time_days' => ['nullable', 'integer', 'min:0', 'max:65535'], 'supplier_ids' => ['nullable', 'array'], 'supplier_ids.*' => ['integer', 'exists:suppliers,id'], 'active' => ['sometimes', 'boolean'], ]; } protected function prepareForValidation(): void { $this->merge([ 'active' => $this->boolean('active'), 'default_factor' => $this->normalizeDecimal($this->input('default_factor')), 'min_stock_alert' => $this->normalizeDecimal($this->input('min_stock_alert')), 'material_quality_id' => $this->nullIfEmpty($this->input('material_quality_id')), 'tax_rate_id' => $this->nullIfEmpty($this->input('tax_rate_id')), 'delivery_time_days' => $this->nullIfEmpty($this->input('delivery_time_days')), ]); } private function normalizeDecimal(mixed $value): ?string { if ($value === null || $value === '') { return null; } return (string) reFormatNumber($value); } private function nullIfEmpty(mixed $value): mixed { return $value === '' ? null : $value; } }