Files
alrahma_sunday_school_api/app/Services/Students/StudentProfileService.php
T
2026-06-09 01:03:53 -04:00

135 lines
4.8 KiB
PHP

<?php
namespace App\Services\Students;
use App\Models\Student;
use App\Models\StudentAllergy;
use App\Models\StudentMedicalCondition;
use Illuminate\Support\Facades\DB;
class StudentProfileService
{
public function updateStudent(int $studentId, array $payload): array
{
$student = Student::query()->find($studentId);
if (!$student) {
return ['ok' => false, 'message' => 'Student not found.'];
}
$studentData = array_filter([
'school_id' => $payload['school_id'] ?? null,
'firstname' => $payload['firstname'] ?? null,
'lastname' => $payload['lastname'] ?? null,
'dob' => $payload['dob'] ?? null,
'age' => $payload['age'] ?? null,
'gender' => $payload['gender'] ?? null,
'registration_grade' => $payload['registration_grade'] ?? null,
'photo_consent' => $payload['photo_consent'] ?? null,
'parent_id' => $payload['parent_id'] ?? null,
'registration_date' => $payload['registration_date'] ?? null,
'tuition_paid' => $payload['tuition_paid'] ?? null,
'year_of_registration' => $payload['year_of_registration'] ?? null,
'school_year' => $payload['school_year'] ?? null,
'semester' => $payload['semester'] ?? null,
'is_new' => $payload['is_new'] ?? null,
'is_active' => $payload['is_active'] ?? null,
], static fn ($value) => $value !== null);
$conditionsInput = (string) ($payload['medical_conditions'] ?? '');
$allergiesInput = (string) ($payload['allergies'] ?? '');
$conditions = $this->normalizeHealthList($conditionsInput);
$allergies = $this->normalizeHealthList($allergiesInput);
$shouldSyncConditions = array_key_exists('medical_conditions', $payload);
$shouldSyncAllergies = array_key_exists('allergies', $payload);
DB::transaction(function () use ($student, $studentData, $conditions, $allergies): void {
if (!empty($studentData)) {
$student->update($studentData);
}
if ($shouldSyncConditions) {
$this->syncHealthList($student->id, StudentMedicalCondition::class, 'condition_name', $conditions);
}
if ($shouldSyncAllergies) {
$this->syncHealthList($student->id, StudentAllergy::class, 'allergy', $allergies);
}
});
return ['ok' => true, 'message' => 'Student updated successfully.'];
}
private function normalizeHealthList(string $value, int $maxLen = 100): array
{
$value = trim($value);
if ($value === '') {
return [];
}
$parts = preg_split('/[,\n;]+/u', $value, -1, PREG_SPLIT_NO_EMPTY) ?: [];
$out = [];
foreach ($parts as $part) {
$item = trim(preg_replace('/\s+/u', ' ', $part));
if ($item === '') {
continue;
}
if (preg_match('/^(none|n\/a|na|null|nil|no)$/i', $item)) {
continue;
}
$out[mb_strtolower($item, 'UTF-8')] = mb_substr($item, 0, $maxLen, 'UTF-8');
}
return array_values($out);
}
private function syncHealthList(int $studentId, string $modelClass, string $field, array $newValues): void
{
$model = new $modelClass();
$rows = $model->newQuery()->where('student_id', $studentId)->get(['id', $field])->toArray();
$current = [];
$byId = [];
foreach ($rows as $row) {
$val = (string) ($row[$field] ?? '');
$key = mb_strtolower(trim($val), 'UTF-8');
if ($key === '') {
continue;
}
$current[$key] = $val;
$byId[$key] = (int) ($row['id'] ?? 0);
}
$incoming = [];
foreach ($newValues as $value) {
$key = mb_strtolower(trim($value), 'UTF-8');
if ($key === '') {
continue;
}
$incoming[$key] = $value;
}
$toDeleteKeys = array_diff(array_keys($current), array_keys($incoming));
$toInsertKeys = array_diff(array_keys($incoming), array_keys($current));
if (!empty($toDeleteKeys)) {
$ids = array_map(fn ($key) => $byId[$key], $toDeleteKeys);
if (!empty($ids)) {
$model->newQuery()->whereIn('id', $ids)->delete();
}
}
if (!empty($toInsertKeys)) {
$batch = [];
foreach ($toInsertKeys as $key) {
$batch[] = [
'student_id' => $studentId,
$field => $incoming[$key],
];
}
if (!empty($batch)) {
$model->newQuery()->insert($batch);
}
}
}
}