173 lines
6.5 KiB
PHP
173 lines
6.5 KiB
PHP
<?php
|
|
|
|
namespace App\Support\MedicalReport;
|
|
|
|
use App\Models\HospitalUnit;
|
|
use Illuminate\Support\Facades\File;
|
|
use Illuminate\Support\Str;
|
|
|
|
class DepartmentCatalog
|
|
{
|
|
/**
|
|
* @var list<array<string, mixed>>|null
|
|
*/
|
|
private ?array $departments = null;
|
|
|
|
/**
|
|
* @return list<array<string, mixed>>
|
|
*/
|
|
public function departments(): array
|
|
{
|
|
if ($this->departments !== null) {
|
|
return $this->departments;
|
|
}
|
|
|
|
$directory = config('medical-report.source_directory');
|
|
|
|
if (! is_string($directory) || $directory === '' || ! is_dir($directory)) {
|
|
return $this->departments = [];
|
|
}
|
|
|
|
/** @var array<string, list<array{name: string, path: string, extension: string, canonical_name: string}>> $sourcesByCanonicalName */
|
|
$sourcesByCanonicalName = [];
|
|
|
|
foreach (File::files($directory) as $file) {
|
|
$sourceName = $file->getFilenameWithoutExtension();
|
|
$canonicalName = $this->canonicalName($sourceName);
|
|
$sourcesByCanonicalName[$canonicalName] ??= [];
|
|
$sourcesByCanonicalName[$canonicalName][] = [
|
|
'name' => $file->getFilename(),
|
|
'path' => $file->getPathname(),
|
|
'extension' => strtolower($file->getExtension()),
|
|
'canonical_name' => $canonicalName,
|
|
];
|
|
}
|
|
|
|
$reportingUnitSources = config('medical-report.reporting_unit_sources', []);
|
|
$departments = [];
|
|
|
|
$databaseReportingUnits = HospitalUnit::query()
|
|
->with('profile:id,name,sort_order')
|
|
->where('is_reporting_unit', true)
|
|
->where('is_active', true)
|
|
->get()
|
|
->sortBy([
|
|
fn (HospitalUnit $unit): int => $unit->profile?->sort_order ?? PHP_INT_MAX,
|
|
fn (HospitalUnit $unit): string => $unit->name,
|
|
])
|
|
->values();
|
|
$profileNamesByUnit = collect(config('medical-report.finance_profiles', []))
|
|
->flatMap(function (array $profile): array {
|
|
return collect($profile['units'] ?? [])
|
|
->filter(fn (mixed $unit): bool => is_string($unit) && trim($unit) !== '')
|
|
->mapWithKeys(fn (string $unit): array => [$unit => $profile['name']])
|
|
->all();
|
|
})
|
|
->all();
|
|
|
|
if ($databaseReportingUnits->isNotEmpty()) {
|
|
foreach ($databaseReportingUnits as $unit) {
|
|
$mappedSourceNames = $reportingUnitSources[$unit->name] ?? [$unit->name];
|
|
$sources = collect($mappedSourceNames)
|
|
->filter(fn (mixed $sourceName): bool => is_string($sourceName) && trim($sourceName) !== '')
|
|
->flatMap(fn (string $sourceName): array => $sourcesByCanonicalName[$sourceName] ?? [])
|
|
->sortBy(fn (array $source): int => match ($source['extension']) {
|
|
'xlsx' => 0,
|
|
'pdf' => 1,
|
|
default => 2,
|
|
})
|
|
->values()
|
|
->all();
|
|
|
|
if ($sources === []) {
|
|
continue;
|
|
}
|
|
|
|
$departments[] = [
|
|
'id' => $unit->id,
|
|
'key' => $unit->slug,
|
|
'name' => $unit->name,
|
|
'profile_name' => $unit->profile?->name,
|
|
'report_input_type' => $unit->report_input_type,
|
|
'report_input_type_label' => $this->reportInputTypeLabel($unit->report_input_type),
|
|
'template_name' => $sources[0]['canonical_name'] ?? $unit->name,
|
|
'sources' => array_map(fn (array $source): array => [
|
|
'name' => $source['name'],
|
|
'path' => $source['path'],
|
|
'extension' => $source['extension'],
|
|
], $sources),
|
|
];
|
|
}
|
|
|
|
return $this->departments = $departments;
|
|
}
|
|
|
|
foreach (config('medical-report.reporting_units', []) as $unitName) {
|
|
if (! is_string($unitName) || trim($unitName) === '') {
|
|
continue;
|
|
}
|
|
|
|
$mappedSourceNames = $reportingUnitSources[$unitName] ?? [$unitName];
|
|
$sources = collect($mappedSourceNames)
|
|
->filter(fn (mixed $sourceName): bool => is_string($sourceName) && trim($sourceName) !== '')
|
|
->flatMap(fn (string $sourceName): array => $sourcesByCanonicalName[$sourceName] ?? [])
|
|
->sortBy(fn (array $source): int => match ($source['extension']) {
|
|
'xlsx' => 0,
|
|
'pdf' => 1,
|
|
default => 2,
|
|
})
|
|
->values()
|
|
->all();
|
|
|
|
if ($sources === []) {
|
|
continue;
|
|
}
|
|
|
|
$departments[] = [
|
|
'key' => Str::slug(Str::ascii($unitName)),
|
|
'name' => $unitName,
|
|
'profile_name' => $profileNamesByUnit[$unitName] ?? null,
|
|
'report_input_type' => config('medical-report.reporting_unit_input_types.'.$unitName),
|
|
'report_input_type_label' => $this->reportInputTypeLabel(
|
|
config('medical-report.reporting_unit_input_types.'.$unitName)
|
|
),
|
|
'template_name' => $sources[0]['canonical_name'] ?? $unitName,
|
|
'sources' => array_map(fn (array $source): array => [
|
|
'name' => $source['name'],
|
|
'path' => $source['path'],
|
|
'extension' => $source['extension'],
|
|
], $sources),
|
|
];
|
|
}
|
|
|
|
return $this->departments = $departments;
|
|
}
|
|
|
|
public function canonicalName(string $sourceName): string
|
|
{
|
|
$aliases = config('medical-report.aliases', []);
|
|
|
|
if (is_array($aliases) && isset($aliases[$sourceName]) && is_string($aliases[$sourceName])) {
|
|
return $aliases[$sourceName];
|
|
}
|
|
|
|
return Str::of($sourceName)
|
|
->replaceMatches('/\s+/', ' ')
|
|
->trim()
|
|
->toString();
|
|
}
|
|
|
|
private function reportInputTypeLabel(?string $reportInputType): ?string
|
|
{
|
|
if ($reportInputType === null || $reportInputType === '') {
|
|
return null;
|
|
}
|
|
|
|
$label = config('medical-report.report_input_type_labels.'.$reportInputType);
|
|
|
|
return is_string($label) && $label !== ''
|
|
? $label
|
|
: $reportInputType;
|
|
}
|
|
}
|