where('report_status', '=', ReportStatus::Approved->value); } public function setRadiologist(int $radiologist_id): self { $this->radiologist_id = $radiologist_id; return $this; } public function setWorkflowLevel(WorkflowLevel $status): self { $this->workflowLevel = $status; return $this; } public function setReportStatus(ReportStatus $status): self { $this->reportStatus = $status; return $this; } public function query(?int $user_id = null): Builder { $query = $this->buildQuery($user_id); // $query = $this->applySort($query); // $query = $this->applyRadiologist($query); return $query; } public function get(?int $user_id = null): LengthAwarePaginator { $query = $this->buildQuery($user_id); $query = $this->applySort($query); $query = $this->applySearch($query); $query = $this->applyRadiologist($query); $query = $this->applyWorkflowLevel($query); $query = $this->applyReportStatus($query); $query = $this->applyArchived($query); $query = $this->applyLocked($query); $query = $this->applyDateFilters($query); return $query->paginate($this->getPageSize($user_id)); } public function setArchived(bool $archived): self { $this->archived = $archived; return $this; } public function setLocked(bool $locked): self { $this->locked = $locked; return $this; } public function setPerPage(int $size): self { $this->perPage = $size; return $this; } public function setSortOrder(string $order): self { $this->sortColumns = []; if (filled($order)) { $orders = explode(',', $order); foreach ($orders as $sort) { $column = ltrim($sort, '-'); $dir = ($sort[0] === '-') ? 'desc' : 'asc'; $this->sortColumns[] = [$column => $dir]; } } return $this; } public function setSearchTerm(string $search): self { $this->searchTerm = trim(strtolower($search)); return $this; } public function setStudyDate(string $from, ?string $to = null): self { $this->studyDateFrom = $from; $this->studyDateTo = $to; return $this; } public function setReceiveDate(string $from, ?string $to = null): self { $this->receiveDateFrom = $from; $this->receiveDateTo = $to; return $this; } public function setReportDate(string $from, ?string $to = null): self { $this->reportDateFrom = $from; $this->reportDateTo = $to; return $this; } protected function getStudiesQuery(): Builder { if ($this->archived === null) { $q = Study::active(); } else { $q = Study::query(); } return $q->with([ 'organization:id,name', 'department:id,name', 'dicomServer', 'readingPhysician:id,display_name,profile_photo_path,first_name,last_name,created_at', 'assignedPhysicians:id,display_name,profile_photo_path,first_name,last_name,created_at', 'lockingPhysician:id,display_name,profile_photo_path,first_name,last_name,created_at', 'reports', ]); } protected function applySort(Builder $query): Builder { if (! empty($this->sortColumns)) { foreach ($this->sortColumns as $column => $dir) { $query = $query->orderBy($column, $dir); } return $query; } return $query ->orderByDesc('priority') ->orderByDesc('received_at'); } abstract protected function buildQuery(?int $user_id = null): Builder; private function applyRadiologist(Builder $query): Builder { if ($this->radiologist_id !== null) { $userId = $this->radiologist_id; $query = Study::buildRadiologistQuery($query, $userId); /* $query->where(function (Builder $q) use ($userId) { $q->where('reading_physician_id', $userId) ->orWhere('locking_physician_id', $userId) ->orWhere('approving_physician_id', $userId) ->orWhereHas('assignedPhysicians', function (Builder $subQuery) use ($userId) { $subQuery->where('user_id', $userId); }); }); */ /* $query = $query->where(function ($qry) use ($rad) { // TODO: $query->Where('assigned_physician_id', '=', $rad); $qry->whereHas('assignedPhysicians', function ($subQuery) use ($rad) { $subQuery->where('assignedPhysicians.user_id', '=', $rad); })->with(['assignedPhysicians' => function ($q) use ($rad) { $q->where('assignedPhysicians.user_id', '=', $rad); }]); #$qry->orWhere('locking_physician_id', '=', $rad); #$qry->orWhere('reading_physician_id', '=', $rad); #$qry->orWhere('approving_physician_id', '=', $rad); }); */ } return $query; } private function applyWorkflowLevel(Builder $query): Builder { if ($this->workflowLevel != null) { $query = $query->where('workflow_level', '=', $this->workflowLevel->value); } return $query; } private function applyReportStatus(Builder $query): Builder { if ($this->reportStatus != null) { $query = $query->where('report_status', '=', $this->reportStatus->value); } return $query; } private function getPageSize(?int $user_id = null): int { return $this->perPage ?? user_per_page($user_id); } private function applySearch(Builder $query): Builder { if (filled($this->searchTerm)) { $search = "%{$this->searchTerm}%"; $query = $query->where(function ($query) use ($search) { $query->orWhere('patient_name', 'like', $search); $query->orWhere('patient_id', 'like', $search); $query->orWhere('accession_number', 'like', $search); $query->orWhere('study_description', 'like', $search); $query->orWhere('body_part_examined', 'like', $search); }); } return $query; } private function applyArchived(Builder $query): Builder { if ($this->archived != null) { if ($this->archived) { $query = $query->archived(); } else { $query = $query->active(); } } return $query; } private function applyLocked(Builder $query): Builder { if ($this->locked != null) { if ((bool) $this->locked) { $query = $query->whereNotNull('locked_at'); } else { $query = $query->whereNull('locked_at'); } } return $query; } private function applyDateFilter(Builder $query, string $column, string $from, ?string $to): Builder { if (filled($from)) { $start = Carbon::parse($from); if (filled($to)) { $query = $query->whereBetween($column, [$start->toDateString(), Carbon::parse($to)->toDateString()]); } else { $query = $query->where($column, '=', $start->toDateString()); } } return $query; } private function applyDateFilters(Builder $query): Builder { if (filled($this->studyDateFrom)) { $query = $this->applyDateFilter($query, 'study_date', $this->studyDateFrom, $this->studyDateTo); } if (filled($this->receiveDateFrom)) { $query = $this->applyDateFilter($query, 'received_at', $this->receiveDateFrom, $this->receiveDateTo); } if (filled($this->reportDateFrom)) { $query = $this->applyDateFilter($query, 'read_at', $this->reportDateFrom, $this->reportDateTo); } return $query; } }