The list could be narrowed by status, search and open-date, but not by patient — so a patient's own file had no way to ask which courses belong to them. `?record=` adds that bound. patientRecord is joined once and shared with the search branch; joining it twice under the same alias is a DQL error, and search already needed it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
125 lines
5.0 KiB
PHP
125 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace App\Treatment\Repository;
|
|
|
|
use App\ClinicService\Entity\ServiceItem;
|
|
use App\Patient\Entity\PatientRecord;
|
|
use App\Treatment\Entity\TreatmentCase;
|
|
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
|
|
use Doctrine\Persistence\ManagerRegistry;
|
|
|
|
/**
|
|
* @extends ServiceEntityRepository<TreatmentCase>
|
|
*/
|
|
class TreatmentCaseRepository extends ServiceEntityRepository
|
|
{
|
|
public function __construct(ManagerRegistry $registry)
|
|
{
|
|
parent::__construct($registry, TreatmentCase::class);
|
|
}
|
|
|
|
public function findByUuid(string $uuid): ?TreatmentCase
|
|
{
|
|
return $this->findOneBy(['uuid' => $uuid]);
|
|
}
|
|
|
|
/**
|
|
* پروندهٔ بازِ همین بیمار برای همین سرویس.
|
|
*
|
|
* نقطهٔ تصمیمِ «پروندهٔ دوم نساز»: بیماری که وسط دورهٔ لیزرش نوبت دیگری از همان
|
|
* سرویس میگیرد، باید جلسهٔ همان دوره را بگیرد، نه یک دورهٔ موازی.
|
|
*/
|
|
public function findOpenFor(PatientRecord $record, ServiceItem $service): ?TreatmentCase
|
|
{
|
|
return $this->findOneBy([
|
|
'patientRecord' => $record,
|
|
'serviceItem' => $service,
|
|
'status' => TreatmentCase::STATUS_ACTIVE,
|
|
]);
|
|
}
|
|
|
|
/** @return TreatmentCase[] */
|
|
/**
|
|
* @param ?string $q جستجو روی نام بیمار، موبایل، کد ملی، شمارهٔ پرونده و نام سرویس.
|
|
* منشی همان کلیدی را میزند که در فرم نوبت میزند، پس هر چهار
|
|
* شناسهٔ بیمار باید بگیرد نه فقط نام.
|
|
* @param ?string $recordUuid فقط دورههای همین بیمار — نمای «پروندهٔ بیمار».
|
|
*/
|
|
public function findForTenant(
|
|
string $entityType,
|
|
int $entityId,
|
|
?string $status = null,
|
|
?string $q = null,
|
|
?int $openedFrom = null,
|
|
?int $openedTo = null,
|
|
?string $recordUuid = null,
|
|
): array {
|
|
$qb = $this->createQueryBuilder('c')
|
|
->where('c.entityType = :type')
|
|
->andWhere('c.entityId = :id')
|
|
->setParameter('type', $entityType)
|
|
->setParameter('id', $entityId)
|
|
->orderBy('c.openedAt', 'DESC');
|
|
|
|
$hasSearch = $q !== null && $q !== '';
|
|
|
|
// `patientRecord` را یک بار join میکنیم؛ هم فیلتر بیمار و هم جستجو لازمش
|
|
// دارند و دو join با یک alias خطای DQL است.
|
|
if ($hasSearch || ($recordUuid !== null && $recordUuid !== '')) {
|
|
$qb->join('c.patientRecord', 'pr');
|
|
}
|
|
|
|
if ($recordUuid !== null && $recordUuid !== '') {
|
|
$qb->andWhere('pr.uuid = :record')->setParameter('record', $recordUuid);
|
|
}
|
|
|
|
if ($status !== null) {
|
|
$qb->andWhere('c.status = :status')->setParameter('status', $status);
|
|
}
|
|
|
|
// بازه روی تاریخِ باز شدن پرونده است، نه سررسید جلسه: سؤالِ این فهرست
|
|
// «چه پروندههایی در این بازه شروع شدند» است.
|
|
if ($openedFrom !== null) {
|
|
$qb->andWhere('c.openedAt >= :from')->setParameter('from', $openedFrom);
|
|
}
|
|
|
|
if ($openedTo !== null) {
|
|
$qb->andWhere('c.openedAt <= :to')->setParameter('to', $openedTo);
|
|
}
|
|
|
|
if ($hasSearch) {
|
|
/**
|
|
* پرسنل از دو راه میآید: کسی که به پرونده اختصاص یافته، و کسی که واقعاً
|
|
* جلسهای از آن را انجام داده. مدیر که نام اپراتور را میزند هر دو را
|
|
* میخواهد — «کارهای این نفر» شامل کارِ انجامشده هم هست.
|
|
*/
|
|
$assignedStaff = <<<'DQL'
|
|
EXISTS (
|
|
SELECT 1 FROM App\Treatment\Entity\TreatmentCaseStaff cs
|
|
JOIN cs.staff cst
|
|
WHERE cs.treatmentCase = c AND cst.fullName LIKE :q
|
|
)
|
|
DQL;
|
|
|
|
$performingStaff = <<<'DQL'
|
|
EXISTS (
|
|
SELECT 1 FROM App\Treatment\Entity\TreatmentSession ts
|
|
JOIN ts.performedBy tsp
|
|
WHERE ts.treatmentCase = c AND tsp.fullName LIKE :q
|
|
)
|
|
DQL;
|
|
|
|
$qb->join('pr.user', 'u')
|
|
->join('c.serviceItem', 'si')
|
|
->andWhere(
|
|
'u.realName LIKE :q OR u.mobileNumber LIKE :q OR u.nationalCode LIKE :q'
|
|
. ' OR pr.recordNumber LIKE :q OR si.name LIKE :q'
|
|
. ' OR ' . $assignedStaff . ' OR ' . $performingStaff,
|
|
)
|
|
->setParameter('q', '%' . $q . '%');
|
|
}
|
|
|
|
return $qb->getQuery()->getResult();
|
|
}
|
|
}
|