StudentContractDownPaymentTest.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace Tests\Unit;
  3. use App\Models\City;
  4. use App\Models\Country;
  5. use App\Models\State;
  6. use App\Models\Student;
  7. use App\Models\StudentContractInstallment;
  8. use App\Models\Unit;
  9. use App\Services\StudentContractService;
  10. use Illuminate\Foundation\Testing\RefreshDatabase;
  11. use Tests\TestCase;
  12. /**
  13. * Taxa de Contratação / Entrada: abate do Total do Curso antes de dividir as
  14. * parcelas restantes, e gera sua própria parcela (REF. ENTRADA), do mesmo
  15. * jeito que a matrícula já funciona.
  16. */
  17. class StudentContractDownPaymentTest extends TestCase
  18. {
  19. use RefreshDatabase;
  20. private Unit $unit;
  21. private StudentContractService $service;
  22. protected function setUp(): void
  23. {
  24. parent::setUp();
  25. $this->unit = $this->makeUnit();
  26. $this->service = new StudentContractService();
  27. }
  28. public function test_down_payment_reduces_total_installments_basis_and_creates_its_own_installment(): void
  29. {
  30. $student = Student::create([
  31. 'name' => 'Aluno Teste',
  32. 'unit_id' => $this->unit->id,
  33. 'status' => 'active',
  34. ]);
  35. $contract = $this->service->create([
  36. 'student_id' => $student->id,
  37. 'unit_id' => $this->unit->id,
  38. 'status' => 'pending',
  39. 'total_value' => 5843.00,
  40. 'total_installments' => 13,
  41. 'total_due_date' => '2026-10-10',
  42. 'down_payment_value' => 500.00,
  43. 'down_payment_date' => '2026-09-15',
  44. ]);
  45. $installments = StudentContractInstallment::where('student_contract_id', $contract->id)
  46. ->orderBy('type')
  47. ->get();
  48. $downPayment = $installments->firstWhere('type', 'down_payment');
  49. $this->assertNotNull($downPayment);
  50. $this->assertSame('REF. ENTRADA', $downPayment->history);
  51. $this->assertSame(1, $downPayment->total_installments);
  52. $this->assertEquals(500.00, $downPayment->value);
  53. $this->assertSame('2026-09-15', $downPayment->due_date->format('Y-m-d'));
  54. $totalInstallments = $installments->where('type', 'total');
  55. $this->assertCount(13, $totalInstallments);
  56. // (5843 - 500) / 13 = 411.00
  57. $this->assertEquals(411.00, $totalInstallments->first()->value);
  58. }
  59. public function test_without_down_payment_total_installments_use_full_value(): void
  60. {
  61. $student = Student::create([
  62. 'name' => 'Aluno Sem Entrada',
  63. 'unit_id' => $this->unit->id,
  64. 'status' => 'active',
  65. ]);
  66. $contract = $this->service->create([
  67. 'student_id' => $student->id,
  68. 'unit_id' => $this->unit->id,
  69. 'status' => 'pending',
  70. 'total_value' => 1300.00,
  71. 'total_installments' => 13,
  72. 'total_due_date' => '2026-10-10',
  73. ]);
  74. $installments = StudentContractInstallment::where('student_contract_id', $contract->id)->get();
  75. $this->assertNull($installments->firstWhere('type', 'down_payment'));
  76. $totalInstallments = $installments->where('type', 'total');
  77. $this->assertCount(13, $totalInstallments);
  78. $this->assertEquals(100.00, $totalInstallments->first()->value);
  79. }
  80. private function makeUnit(): Unit
  81. {
  82. $country = Country::create(['name' => 'Brasil', 'code' => 'BR']);
  83. $state = State::create(['name' => 'Paraná', 'code' => 'PR', 'country_id' => $country->id]);
  84. $city = City::create(['name' => 'Maringá', 'country_id' => $country->id, 'state_id' => $state->id]);
  85. return Unit::create([
  86. 'fantasy_name' => 'Unidade Teste',
  87. 'social_reason' => 'Unidade Teste LTDA',
  88. 'cnpj' => '00000000000191',
  89. 'street' => 'Rua Teste',
  90. 'neighborhood' => 'Centro',
  91. 'postal_code' => '87000000',
  92. 'city_id' => $city->id,
  93. 'state_id' => $state->id,
  94. 'email' => 'unidade@teste.com',
  95. 'name_responsible' => 'Responsável Teste',
  96. ]);
  97. }
  98. }