10, 'parent_name' => 'Yusuf, Layla'], ]; } protected function loadFamilyStudents(int $parentId, string $schoolYear, string $semester, array $options): array { return [ 'students' => [ ['student_id' => 1, 'student_name' => 'Mariam', 'grade_level' => '1'], ['student_id' => 2, 'student_name' => 'Yahya', 'grade_level' => '2'], ['student_id' => 4, 'student_name' => 'Youth Student', 'grade_level' => 'Youth 1'], ], 'all_students' => [ ['student_id' => 1, 'student_name' => 'Mariam', 'grade_level' => '1', 'billable' => true, 'excluded_reason' => null], ['student_id' => 2, 'student_name' => 'Yahya', 'grade_level' => '2', 'billable' => true, 'excluded_reason' => null], ['student_id' => 4, 'student_name' => 'Youth Student', 'grade_level' => 'Youth 1', 'billable' => true, 'excluded_reason' => null], ['student_id' => 3, 'student_name' => 'Event Only', 'grade_level' => '3', 'billable' => false, 'excluded_reason' => 'event_only'], ], 'warnings' => ['1 event-only student(s) excluded from tuition.'], ]; } protected function getTuitionConfig(): array { return [ 'grade_fee' => 9, 'first_student_fee' => '350.00', 'second_student_fee' => '200.00', 'youth_fee' => '200.00', 'new_tuition_full_amount' => $this->unitPriceOverride ?? '350.00', 'new_tuition_youth_amount' => $this->youthUnitPriceOverride ?? '200.00', 'new_tuition_second_student_discount' => '50.00', 'new_tuition_third_student_discount' => '50.00', 'new_tuition_fourth_plus_discount' => '100.00', ]; } }; $result = $service->calculate('2025-2026', 'Fall', 'compare', [ 'include_payment_pending' => true, 'include_withdrawn_mode' => 'refund_deadline', 'unit_price' => '400.00', 'youth_unit_price' => '200.00', ]); $this->assertSame(1, $result['summary']['family_count']); $this->assertSame(4, $result['summary']['student_count']); $this->assertSame(3, $result['summary']['billable_student_count']); $this->assertSame('750.00', $result['summary']['old_projected_tuition']); $this->assertSame('950.00', $result['summary']['new_projected_tuition']); $this->assertSame('750.00', $result['summary']['old_projected_income']); $this->assertSame('950.00', $result['summary']['new_projected_income']); $this->assertSame('400.00', $result['summary']['unit_price']); $this->assertSame('200.00', $result['summary']['youth_unit_price']); $this->assertSame('event_only', $result['families'][0]['student_details'][3]['excluded_reason']); } }