135 lines
4.8 KiB
PHP
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);
|
|
}
|
|
}
|
|
}
|
|
}
|