Files
alrahma_sunday_school_api/app/Services/Parents/ParentEventParticipationService.php
T
2026-06-09 02:32:58 -04:00

133 lines
4.3 KiB
PHP

<?php
namespace App\Services\Parents;
use App\Models\Event;
use App\Models\EventCharges;
use App\Models\Enrollment;
use App\Models\Student;
use App\Services\Invoices\InvoiceGenerationService;
class ParentEventParticipationService
{
public function __construct(
private ParentConfigService $configService,
private InvoiceGenerationService $invoiceGeneration
) {
}
public function overview(int $parentId): array
{
$context = $this->configService->context();
$schoolYear = $context['school_year'];
$semester = $context['semester'];
$activeEvents = Event::getActiveEvents($schoolYear, $semester) ?? [];
$chargesList = EventCharges::getChargesWithEventInfo($parentId, $schoolYear) ?? [];
$charges = [];
foreach ($chargesList as $charge) {
$key = $charge['student_id'] . ':' . $charge['event_id'];
$charges[$key] = [
'participation' => $charge['participation'],
'date' => $charge['updated_at'] ?? $charge['created_at'],
];
}
$students = Enrollment::getEnrolledStudents($parentId, $schoolYear);
return [
'activeEvents' => $activeEvents,
'charges' => $charges,
'yourStudents' => $students,
];
}
public function updateParticipation(int $parentId, array $participations): void
{
$context = $this->configService->context();
$schoolYear = $context['school_year'];
$semester = $context['semester'];
// First pass: parse + validate every `student_id:event_id` key and
// collect the student ids that this parent actually owns. This stops
// a parent from creating or deleting charges on another family's
// students by manipulating the participation keys.
$parsed = [];
$candidateStudentIds = [];
foreach ($participations as $key => $value) {
$parts = explode(':', (string) $key, 2);
if (count($parts) !== 2 || ! ctype_digit($parts[0]) || ! ctype_digit($parts[1])) {
continue;
}
$studentId = (int) $parts[0];
$eventId = (int) $parts[1];
if ($studentId <= 0 || $eventId <= 0) {
continue;
}
$normalized = strtolower(trim((string) $value));
if (! in_array($normalized, ['yes', 'no'], true)) {
continue;
}
$parsed[] = [
'student_id' => $studentId,
'event_id' => $eventId,
'value' => $normalized,
];
$candidateStudentIds[$studentId] = true;
}
if ($parsed === []) {
return;
}
$ownedIds = Student::query()
->where('parent_id', $parentId)
->whereIn('id', array_keys($candidateStudentIds))
->pluck('id')
->map(fn ($id) => (int) $id)
->all();
$ownedSet = array_flip($ownedIds);
foreach ($parsed as $row) {
if (! isset($ownedSet[$row['student_id']])) {
continue;
}
$existing = EventCharges::query()
->where('parent_id', $parentId)
->where('student_id', $row['student_id'])
->where('event_id', $row['event_id'])
->first();
if ($row['value'] === 'no') {
if ($existing) {
$existing->delete();
}
continue;
}
if ($existing) {
$existing->update(['participation' => $row['value']]);
} else {
$event = Event::getEvent($row['event_id'], $schoolYear);
EventCharges::query()->create([
'parent_id' => $parentId,
'student_id' => $row['student_id'],
'event_id' => $row['event_id'],
'participation' => $row['value'],
'charged' => $event['amount'] ?? 0,
'school_year' => $schoolYear,
'semester' => $semester,
'updated_by' => $parentId,
]);
}
}
$this->invoiceGeneration->generateInvoice($parentId, $schoolYear);
}
}