From 13bf9453e5cb38d0cece9a7310f03f2aba0aa060 Mon Sep 17 00:00:00 2001 From: hamed <15238-genius.ha@users.noreply.drupalcode.org> Date: Wed, 15 Jul 2026 20:33:15 +0330 Subject: [PATCH] feat(appointment): ensure existing profile name is used over modal input for patient name --- .../Controller/MyAppointmentsController.php | 6 ++- .../AppointmentCreateReserveTest.php | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/Appointment/Controller/MyAppointmentsController.php b/src/Appointment/Controller/MyAppointmentsController.php index bf6d8997..5fcfc891 100644 --- a/src/Appointment/Controller/MyAppointmentsController.php +++ b/src/Appointment/Controller/MyAppointmentsController.php @@ -123,7 +123,11 @@ class MyAppointmentsController extends BaseController if (isset($data['deposit_amount_rials'])) { $appointment->setDepositAmountRials((int) $data['deposit_amount_rials']); } - $appointment->setPatientName($patientName); + // The resolver returns the patient keyed on national code, so its profile + // name is the real identity. Snapshot that (not the free-typed modal name) + // so the appointment never diverges from an existing profile; fall back to + // the entered name only for a brand-new patient without a stored name. + $appointment->setPatientName($patient->getRealName() ?: $patientName); $appointment->setPatientMobile($mobile); if ($isReserve) { diff --git a/tests/Appointment/AppointmentCreateReserveTest.php b/tests/Appointment/AppointmentCreateReserveTest.php index 3081ba73..41674800 100644 --- a/tests/Appointment/AppointmentCreateReserveTest.php +++ b/tests/Appointment/AppointmentCreateReserveTest.php @@ -89,6 +89,43 @@ class AppointmentCreateReserveTest extends ApiTestCase self::assertCount(0, $regular['data']); } + public function testExistingProfileNameWinsOverModalInput(): void + { + [$owner, $doctor] = $this->doctor(); + $nationalCode = '00' . str_pad((string) random_int(0, 99_999_999), 8, '0', STR_PAD_LEFT); + $mobile = '09' . random_int(100000000, 999999999); + $start = time() + 86_400; + + // First booking registers the patient's profile under their real name. + $this->authJson('POST', '/api/v1/my/appointment', $owner, [ + 'doctor_uuid' => $doctor->getUuid(), + 'slot_start' => $start, + 'slot_end' => $start + 1_800, + 'patient_mobile' => $mobile, + 'patient_name' => 'علی احمدی', + 'patient_national_code' => $nationalCode, + ]); + self::assertSame(201, $this->responseCode()); + + // Second booking uses the same national code but a mistyped modal name. + $start2 = $start + 3_600; + $this->authJson('POST', '/api/v1/my/appointment', $owner, [ + 'doctor_uuid' => $doctor->getUuid(), + 'slot_start' => $start2, + 'slot_end' => $start2 + 1_800, + 'patient_mobile' => $mobile, + 'patient_name' => 'نام غلط', + 'patient_national_code' => $nationalCode, + ]); + self::assertSame(201, $this->responseCode()); + + // Every listed appointment must show the profile name, never the mistype. + $list = $this->authJson('GET', '/api/v1/my/appointments?limit=50', $owner); + $names = array_column($list['data'], 'patient_name'); + self::assertContains('علی احمدی', $names); + self::assertNotContains('نام غلط', $names); + } + public function testUnknownServiceUuidIs422(): void { [$owner, $doctor] = $this->doctor();