feat(patient): implement record number pattern management
- Add RecordNumberSettingsController for managing patient record number patterns. - Create RecordNumberPattern entity to represent the pattern configuration. - Implement RecordNumberPatternRepository for database interactions. - Develop RecordNumberGenerator service for generating and validating record numbers. - Add tests for record number generation, backfilling, and API interactions. - Ensure proper access control for viewing and updating patterns based on user roles.
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Patient;
|
||||
|
||||
use App\Auth\Entity\UserActiveContext;
|
||||
use App\Clinic\Entity\Clinic;
|
||||
use App\Patient\Entity\PatientRecord;
|
||||
use App\Patient\Entity\RecordNumberPattern;
|
||||
use App\Tests\ApiTestCase;
|
||||
|
||||
/**
|
||||
* پروندههای ساختهشده پیش از فعالشدن الگو، اولین بار که باز میشوند شماره میگیرند
|
||||
* (`GET /api/v1/patient/{uuid}`) و از آن به بعد همان شماره را نگه میدارند.
|
||||
*/
|
||||
class RecordNumberBackfillTest extends ApiTestCase
|
||||
{
|
||||
/** @return array{0: \App\Auth\Entity\User, 1: Clinic, 2: PatientRecord} */
|
||||
private function scenario(bool $patternEnabled): array
|
||||
{
|
||||
$owner = $this->createUser(['ROLE_CLINIC']);
|
||||
$clinic = new Clinic($owner);
|
||||
$this->em->persist($clinic);
|
||||
$this->em->persist(new UserActiveContext($owner, $clinic->getUuid(), 'clinic'));
|
||||
$this->em->flush();
|
||||
|
||||
$row = new RecordNumberPattern('clinic', $clinic->getId());
|
||||
$row->setPattern('OLD-{SEQ:3}')->setResetPolicy(RecordNumberPattern::RESET_NONE)->setEnabled($patternEnabled);
|
||||
$this->em->persist($row);
|
||||
|
||||
// پروندهٔ قدیمی: بدون شماره، دقیقاً مثل ردیفهای امروزِ دیتابیس.
|
||||
$patient = $this->createUser(['ROLE_USER']);
|
||||
$patient->setRealName('بیمار قدیمی');
|
||||
$record = new PatientRecord('clinic', $clinic->getId(), $patient, 'clinic', $clinic->getId());
|
||||
$this->em->persist($record);
|
||||
$this->em->flush();
|
||||
|
||||
self::assertNull($record->getRecordNumber());
|
||||
|
||||
return [$owner, $clinic, $record];
|
||||
}
|
||||
|
||||
/** ✅ موفق + ⚠️ مرزی: بار اول شماره میگیرد، بار دوم همان شماره برمیگردد. */
|
||||
public function testFirstOpenAssignsANumberAndTheSecondKeepsIt(): void
|
||||
{
|
||||
[$owner, , $record] = $this->scenario(true);
|
||||
$uri = '/api/v1/patient/' . $record->getUuid();
|
||||
|
||||
$first = $this->authJson('GET', $uri, $owner);
|
||||
self::assertSame(200, $this->responseCode());
|
||||
self::assertSame('OLD-001', $first['data']['record_number']);
|
||||
|
||||
$second = $this->authJson('GET', $uri, $owner);
|
||||
self::assertSame('OLD-001', $second['data']['record_number']);
|
||||
}
|
||||
|
||||
/** ⚠️ مرزی: بدون الگوی فعال، `GET` هیچ چیزی نمینویسد. */
|
||||
public function testDisabledPatternLeavesTheRecordUntouched(): void
|
||||
{
|
||||
[$owner, , $record] = $this->scenario(false);
|
||||
|
||||
$res = $this->authJson('GET', '/api/v1/patient/' . $record->getUuid(), $owner);
|
||||
self::assertSame(200, $this->responseCode());
|
||||
self::assertNull($res['data']['record_number']);
|
||||
}
|
||||
|
||||
/** ⚠️ مرزی: پروندهٔ شمارهدار دوباره شماره نمیگیرد و شمارنده مصرف نمیشود. */
|
||||
public function testAlreadyNumberedRecordDoesNotConsumeTheCounter(): void
|
||||
{
|
||||
[$owner, $clinic, $record] = $this->scenario(true);
|
||||
$record->setRecordNumber('MANUAL-7');
|
||||
$this->em->flush();
|
||||
|
||||
$res = $this->authJson('GET', '/api/v1/patient/' . $record->getUuid(), $owner);
|
||||
self::assertSame('MANUAL-7', $res['data']['record_number']);
|
||||
|
||||
$pattern = $this->em->getRepository(RecordNumberPattern::class)->findForPair('clinic', $clinic->getId());
|
||||
$this->em->refresh($pattern);
|
||||
self::assertSame(0, $pattern->getCounter());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user