ValidatesProposalPricing.php 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. <?php
  2. namespace App\Http\Requests\Concerns;
  3. use Illuminate\Validation\Validator;
  4. trait ValidatesProposalPricing
  5. {
  6. /**
  7. * Validation rules for an optional Pavão/Irrecusável pricing block
  8. * (Matrícula, Aulas, Materiais, Valor Total do Curso), nested under
  9. * $prefix ("pavao"/"irrecusavel"). The block itself is optional — a
  10. * proposal can have Pavão, Irrecusável, both, or neither yet. Sending it
  11. * as `null` means "this proposal doesn't have this modality" (removes an
  12. * existing one); sending an object requires every sub-field.
  13. */
  14. protected function proposalPricingRules(string $prefix, bool $withCondition = false): array
  15. {
  16. $rules = [
  17. $prefix => 'sometimes|nullable|array',
  18. "$prefix.registration_value" => 'nullable|numeric|min:0',
  19. "$prefix.registration_included_in_course" => "required_with:$prefix|boolean",
  20. "$prefix.registration_installments_allowed" => "required_with:$prefix|boolean",
  21. "$prefix.registration_max_installments" => 'nullable|integer|min:1',
  22. "$prefix.classes_value" => 'nullable|numeric|min:0',
  23. "$prefix.classes_included_in_course" => "required_with:$prefix|boolean",
  24. "$prefix.classes_installments_allowed" => "required_with:$prefix|boolean",
  25. "$prefix.classes_max_installments" => 'nullable|integer|min:1',
  26. "$prefix.classes_discount_percentage" => 'nullable|numeric|min:0|max:100',
  27. "$prefix.materials" => 'nullable|array',
  28. "$prefix.materials.*.product_id" => "required_with:$prefix.materials|integer|exists:products,id",
  29. "$prefix.materials.*.quantity" => "required_with:$prefix.materials|integer|min:1",
  30. "$prefix.materials.*.price" => "required_with:$prefix.materials|numeric|min:0",
  31. "$prefix.materials_included_in_course" => "required_with:$prefix|boolean",
  32. "$prefix.materials_installments_allowed" => "required_with:$prefix|boolean",
  33. "$prefix.materials_max_installments" => 'nullable|integer|min:1',
  34. "$prefix.total_value" => 'nullable|numeric|min:0',
  35. "$prefix.total_max_installments" => 'nullable|integer|min:1',
  36. ];
  37. if ($withCondition) {
  38. $rules["$prefix.condition"] = 'nullable|string';
  39. }
  40. return $rules;
  41. }
  42. /**
  43. * For each pricing block actually sent (present and not null), enforce
  44. * that exactly one of "included in course" / "allows installments" is
  45. * selected per section.
  46. */
  47. protected function validateProposalPricingSections(Validator $validator, array $prefixes): void
  48. {
  49. $validator->after(function (Validator $validator) use ($prefixes) {
  50. foreach ($prefixes as $prefix) {
  51. if (!$this->has($prefix) || $this->input($prefix) === null) continue;
  52. foreach (['registration', 'classes', 'materials'] as $section) {
  53. $includedKey = "$prefix.{$section}_included_in_course";
  54. $installmentsKey = "$prefix.{$section}_installments_allowed";
  55. if (!$this->has($includedKey) && !$this->has($installmentsKey)) continue;
  56. $included = $this->boolean($includedKey);
  57. $installments = $this->boolean($installmentsKey);
  58. if ($included === $installments) {
  59. $validator->errors()->add(
  60. $includedKey,
  61. 'Selecione exatamente uma opção: incluso no valor do curso ou permite parcelar.'
  62. );
  63. }
  64. }
  65. }
  66. });
  67. }
  68. }