diff --git a/assets/admin/pages/AppointmentCreatePage.tsx b/assets/admin/pages/AppointmentCreatePage.tsx
index 97178a50..b61546b2 100644
--- a/assets/admin/pages/AppointmentCreatePage.tsx
+++ b/assets/admin/pages/AppointmentCreatePage.tsx
@@ -217,11 +217,20 @@ export default function AppointmentCreatePage() {
-
-
-
-
+ {/^\d{10}$/.test((picked.user_national_code ?? '').replace(/\D/g, '')) ? (
+
+ کد ملی
+ {nationalCode}
+
+ ) : (
+ <>
+
+
+
+
+ >
+ )}
)}
>
diff --git a/docs/api/patient.md b/docs/api/patient.md
index 366a216f..1f950f70 100644
--- a/docs/api/patient.md
+++ b/docs/api/patient.md
@@ -45,9 +45,13 @@ Returns a paginated list of patient records belonging to the authenticated entit
"uuid": "...",
"entity_type": "doctor",
"entity_id": 5,
- "user": { "uuid": "...", "fullName": "علی رضایی", "phone": "09123456789" },
+ "user_uuid": "...",
+ "user_name": "علی رضایی",
+ "user_mobile": "09123456789",
+ "user_national_code": "0012345675",
+ "record_number": "1024",
+ "tags": [],
"created_by_type": "doctor",
- "created_by_id": 5,
"created_at": 1718375000
}
],
@@ -59,6 +63,8 @@ Returns a paginated list of patient records belonging to the authenticated entit
}
```
+> `user_national_code` منبعِ حقیقتش جدول `profiles` است (نه `users`). اگر روی خودِ کاربر خالی باشد، از پروفایل پر میشود؛ اگر هیچکدام نداشته باشند `null` است.
+
**Errors:**
| Code | HTTP | Description |
diff --git a/src/Patient/Controller/PatientController.php b/src/Patient/Controller/PatientController.php
index e02edc44..591efae4 100644
--- a/src/Patient/Controller/PatientController.php
+++ b/src/Patient/Controller/PatientController.php
@@ -542,12 +542,18 @@ class PatientController extends BaseController
$records = $this->recordRepo->findByEntity($entityType, $entityId, $page, $limit, $search, $filters);
$total = $this->recordRepo->countByEntity($entityType, $entityId, $search, $filters);
- return $this->paginated(
- array_map(fn(PatientRecord $r) => $r->toArray(), $records),
- $total,
- $page,
- $limit
- );
+ // کد ملی روی profiles ذخیره میشود نه users؛ اگر روی user خالی بود از پروفایل پر کن.
+ $userIds = array_map(fn(PatientRecord $r) => $r->getUser()->getId(), $records);
+ $profileCodes = $this->profileRepo->nationalCodesByUserIds($userIds);
+ $rows = array_map(function (PatientRecord $r) use ($profileCodes) {
+ $row = $r->toArray();
+ if (empty($row['user_national_code'])) {
+ $row['user_national_code'] = $profileCodes[$r->getUser()->getId()] ?? null;
+ }
+ return $row;
+ }, $records);
+
+ return $this->paginated($rows, $total, $page, $limit);
}
#[Route('/api/v1/patient', methods: ['POST'])]
diff --git a/src/UserProfile/Repository/UserProfileRepository.php b/src/UserProfile/Repository/UserProfileRepository.php
index 86a4b3ae..06cc6c35 100644
--- a/src/UserProfile/Repository/UserProfileRepository.php
+++ b/src/UserProfile/Repository/UserProfileRepository.php
@@ -29,6 +29,31 @@ class UserProfileRepository extends ServiceEntityRepository
return $this->findOneBy(['nationalCode' => $nationalCode]);
}
+ /**
+ * نگاشتِ userId → کد ملیِ ذخیرهشده روی پروفایل، فقط برای پروفایلهایی که کد ملی دارند.
+ * برای پر کردنِ گروهیِ کد ملی در لیست بیماران (کد ملی روی profiles است نه users).
+ *
+ * @param int[] $userIds
+ * @return array
+ */
+ public function nationalCodesByUserIds(array $userIds): array
+ {
+ if ($userIds === []) {
+ return [];
+ }
+ $rows = $this->createQueryBuilder('p')
+ ->select('IDENTITY(p.user) AS uid', 'p.nationalCode AS nc')
+ ->where('p.user IN (:ids)')->setParameter('ids', $userIds)
+ ->andWhere('p.nationalCode IS NOT NULL')
+ ->getQuery()->getArrayResult();
+
+ $map = [];
+ foreach ($rows as $r) {
+ $map[(int) $r['uid']] = (string) $r['nc'];
+ }
+ return $map;
+ }
+
public function save(UserProfile $profile, bool $flush = true): void
{
$this->getEntityManager()->persist($profile);
diff --git a/tests/Patient/PatientListNationalCodeTest.php b/tests/Patient/PatientListNationalCodeTest.php
new file mode 100644
index 00000000..5175ddc6
--- /dev/null
+++ b/tests/Patient/PatientListNationalCodeTest.php
@@ -0,0 +1,59 @@
+createUser(['ROLE_DOCTOR']);
+ $doctor = new Doctor($owner, 'دکتر تست');
+ $this->em->persist($doctor);
+ $this->em->flush();
+
+ return [$owner, $doctor];
+ }
+
+ public function testNationalCodeFromProfileIsReturned(): void
+ {
+ [$owner, $doctor] = $this->doctor();
+
+ $patient = $this->createUser(['ROLE_USER']);
+ // کد ملی فقط روی پروفایل، نه روی خود کاربر
+ $profile = new UserProfile($patient);
+ $profile->setNationalCode('0012345675');
+ $this->em->persist($profile);
+
+ $record = new PatientRecord('doctor', $doctor->getId(), $patient, 'doctor', $doctor->getId());
+ $this->em->persist($record);
+ $this->em->flush();
+
+ $res = $this->authJson('GET', '/api/v1/patients', $owner);
+ self::assertSame(200, $this->responseCode());
+ self::assertSame($record->getUuid(), $res['data'][0]['uuid']);
+ self::assertSame('0012345675', $res['data'][0]['user_national_code']);
+ }
+
+ public function testNullWhenNoNationalCodeAnywhere(): void
+ {
+ [$owner, $doctor] = $this->doctor();
+
+ $patient = $this->createUser(['ROLE_USER']);
+ $record = new PatientRecord('doctor', $doctor->getId(), $patient, 'doctor', $doctor->getId());
+ $this->em->persist($record);
+ $this->em->flush();
+
+ $res = $this->authJson('GET', '/api/v1/patients', $owner);
+ self::assertSame(200, $this->responseCode());
+ self::assertNull($res['data'][0]['user_national_code']);
+ }
+}