client = $client ?? new OrthancRestClient; } public function scanStudies() { $this->study_ids = $this->client->getStudiesIds(); } private function checkUpdate(string $orthanc_uid): void { $row = DB::table('studies')->where('orthanc_uid', $orthanc_uid)->first(['id', 'study_status']); if ($row === null) { $this->insert_queue[] = $orthanc_uid; return; } if ($row->study_status < StudyLevelStatus::StudyArrived->value) { $this->update_queue[$orthanc_uid] = $row->id; } } public function filterStudies() { $this->insert_queue = []; $this->update_queue = []; foreach ($this->study_ids as $study_id) { $this->checkUpdate($study_id); } } private function fetchStudyDetails(string $orthanc_uid): ?array { $study = $this->client->getStudyDetails($orthanc_uid); if ($study == null) { return null; } $stats = $this->client->getStudyStatistics($orthanc_uid); $study['Statistics'] = $stats; return $study; } public function importStudies() { foreach ($this->update_queue as $orthanc_uid => $row_id) { $study = $this->fetchStudyDetails($orthanc_uid); if ($study == null) { continue; } $this->updateStudy($row_id, $study); } foreach ($this->insert_queue as $orthanc_uid) { $study = $this->fetchStudyDetails($orthanc_uid); if ($study == null) { continue; } $this->insertStudy($study); } } private function prepareData(mixed $study): array { $inst_name = data_get($study, 'MainDicomTags.InstitutionName'); $inst_id = InstituteMapper::map($inst_name); $data = [ 'orthanc_uid' => strtolower($study['ID']), 'is_locked' => false, 'is_active' => true, 'institution_name' => $inst_name, 'institute_id' => $inst_id, 'patient_uid' => $study['ParentPatient'], 'patient_id' => data_get($study, 'PatientMainDicomTags.PatientID'), 'patient_name' => data_get($study, 'PatientMainDicomTags.PatientName'), 'patient_sex' => data_get($study, 'PatientMainDicomTags.PatientSex'), 'accession_number' => data_get($study, 'MainDicomTags.AccessionNumber'), 'referring_physician_name' => data_get($study, 'MainDicomTags.ReferringPhysicianName'), 'study_id' => data_get($study, 'MainDicomTags.StudyID'), 'study_instance_uid' => data_get($study, 'MainDicomTags.StudyInstanceUID'), 'study_date' => DicomUtils::dateTimeToCarbon($study['MainDicomTags']['StudyDate'], $study['MainDicomTags']['StudyTime']), 'receive_date' => Carbon::parse($study['LastUpdate'], 'UTC'), 'study_modality' => data_get($study, 'RequestedTags.Modality'), 'body_part_examined' => data_get($study, 'RequestedTags.BodyPartExamined'), 'software_versions' => data_get($study, 'RequestedTags.SoftwareVersions'), 'station_name' => data_get($study, 'RequestedTags.StationName'), 'operators_name' => data_get($study, 'RequestedTags.OperatorsName'), 'manufacturer' => data_get($study, 'RequestedTags.Manufacturer'), 'manufacturer_model_name' => data_get($study, 'RequestedTags.ManufacturerModelName'), 'image_count' => data_get($study, 'Statistics.CountInstances'), 'series_count' => data_get($study, 'Statistics.CountSeries'), 'disk_size' => data_get($study, 'Statistics.DiskSize'), ]; if ($study['IsStable']) { $data['study_status'] = StudyLevelStatus::StudyArrived->value; } else { $data['study_status'] = StudyLevelStatus::Pending->value; } $dob = data_get($study, 'PatientMainDicomTags.PatientBirthDate'); if (trim($dob) != '') { $data['patient_birthdate'] = Carbon::parse($dob); } $descr = data_get($study, 'MainDicomTags.StudyDescription'); if ($descr == null) { $descr = data_get($study, 'RequestedTags.AcquisitionDeviceProcessingDescription'); } $data['study_description'] = trim($descr); return $data; } public function updateStudy(int $row_id, mixed $study): void { $data = $this->prepareData($study); unset($data['orthanc_uid']); Study::where('id', $row_id)->update($data); } public function insertStudy(mixed $study): void { $data = $this->prepareData($study); Study::create($data); } }