Files
econom-calculator/app/Support/MedicalReport/DepartmentCatalog.php
brusnitsyn 3edc8e667e
Some checks failed
tests / ci (8.5) (push) Has been cancelled
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
first commit
2026-04-03 17:20:05 +09:00

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;
}
}