where('report_status', '=', ReportStatus::Approved->value); } public function setRadiologist(int $radiologist_id): self { $this->radiologist_id = $radiologist_id; return $this; } public function setStudyStatus(StudyLevelStatus $status): self { $this->studyStatus = $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->applyStudyStatus($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(['readingPhysician', 'assignedPhysician', 'orthancHost']); } 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) { $rad = $this->radiologist_id; $query = $query->where(function ($query) use ($rad) { $query->Where('assigned_physician_id', '=', $rad); $query->orWhere('reporting_physician_id', '=', $rad); }); } return $query; } private function applyStudyStatus(Builder $query): Builder { if ($this->studyStatus != null) { $query = $query->where('study_status', '=', $this->studyStatus->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) { $query = $query->where('is_archived', $this->archived); } return $query; } private function applyLocked(Builder $query): Builder { if ($this->locked != null) { $query = $query->where('is_locked', $this->locked); } 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, 'reported_at', $this->reportDateFrom, $this->reportDateTo); } return $query; } }