'sometimes|nullable|array', "$prefix.registration_value" => 'nullable|numeric|min:0', "$prefix.registration_included_in_course" => "required_with:$prefix|boolean", "$prefix.registration_installments_allowed" => "required_with:$prefix|boolean", "$prefix.registration_max_installments" => 'nullable|integer|min:1', "$prefix.classes_value" => 'nullable|numeric|min:0', "$prefix.classes_included_in_course" => "required_with:$prefix|boolean", "$prefix.classes_installments_allowed" => "required_with:$prefix|boolean", "$prefix.classes_max_installments" => 'nullable|integer|min:1', "$prefix.classes_discount_percentage" => 'nullable|numeric|min:0|max:100', "$prefix.materials" => 'nullable|array', "$prefix.materials.*.product_id" => "required_with:$prefix.materials|integer|exists:products,id", "$prefix.materials.*.quantity" => "required_with:$prefix.materials|integer|min:1", "$prefix.materials.*.price" => "required_with:$prefix.materials|numeric|min:0", "$prefix.materials_included_in_course" => "required_with:$prefix|boolean", "$prefix.materials_installments_allowed" => "required_with:$prefix|boolean", "$prefix.materials_max_installments" => 'nullable|integer|min:1', "$prefix.total_value" => 'nullable|numeric|min:0', "$prefix.total_max_installments" => 'nullable|integer|min:1', ]; if ($withCondition) { $rules["$prefix.condition"] = 'nullable|string'; } return $rules; } /** * For each pricing block actually sent (present and not null), enforce * that exactly one of "included in course" / "allows installments" is * selected per section. */ protected function validateProposalPricingSections(Validator $validator, array $prefixes): void { $validator->after(function (Validator $validator) use ($prefixes) { foreach ($prefixes as $prefix) { if (!$this->has($prefix) || $this->input($prefix) === null) continue; foreach (['registration', 'classes', 'materials'] as $section) { $includedKey = "$prefix.{$section}_included_in_course"; $installmentsKey = "$prefix.{$section}_installments_allowed"; if (!$this->has($includedKey) && !$this->has($installmentsKey)) continue; $included = $this->boolean($includedKey); $installments = $this->boolean($installmentsKey); if ($included === $installments) { $validator->errors()->add( $includedKey, 'Selecione exatamente uma opção: incluso no valor do curso ou permite parcelar.' ); } } } }); } }