282 lines
11 KiB
PHP
282 lines
11 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Http\Requests\UpdateMedicalReportSheetRequest;
|
|
use App\Http\Requests\UpdateMedicalReportStructuredTemplateRequest;
|
|
use App\Http\Requests\UpsertMedicalReportFormTemplateRequest;
|
|
use App\Models\HospitalUnit;
|
|
use App\Models\MedicalReport;
|
|
use App\Models\MedicalReportFormTemplate;
|
|
use App\Support\MedicalReport\EconomistWorkbook;
|
|
use App\Support\MedicalReport\FormTemplateBuilderPage;
|
|
use App\Support\MedicalReport\ReportWorkbook;
|
|
use App\Support\MedicalReport\StructuredTemplateRegistry;
|
|
use App\Support\MedicalReport\TemplateWorkbook;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Inertia\Inertia;
|
|
use Inertia\Response;
|
|
|
|
class MedicalReportController extends Controller
|
|
{
|
|
public function index(): RedirectResponse
|
|
{
|
|
$medicalReport = MedicalReport::query()->firstOrCreate(
|
|
['year' => 2026],
|
|
[
|
|
'name' => 'МЕД 2026',
|
|
'input_overrides' => [],
|
|
],
|
|
);
|
|
|
|
return to_route('medical-reports.show', $medicalReport);
|
|
}
|
|
|
|
public function show(
|
|
Request $request,
|
|
MedicalReport $medicalReport,
|
|
ReportWorkbook $reportWorkbook,
|
|
TemplateWorkbook $templateWorkbook,
|
|
): Response {
|
|
$departmentKeys = array_map(
|
|
fn (array $department): string => $department['key'],
|
|
$templateWorkbook->departments(),
|
|
);
|
|
$selectedDepartment = $request->string('department')->toString();
|
|
$selectedDepartment = in_array($selectedDepartment, $departmentKeys, true)
|
|
? $selectedDepartment
|
|
: ($departmentKeys[0] ?? null);
|
|
|
|
$pageData = $reportWorkbook->pageData(
|
|
$medicalReport,
|
|
$selectedDepartment,
|
|
$request->string('sheet')->toString(),
|
|
);
|
|
|
|
return Inertia::render('medical-reports/Show', $pageData);
|
|
}
|
|
|
|
public function update(
|
|
UpdateMedicalReportSheetRequest $request,
|
|
MedicalReport $medicalReport,
|
|
TemplateWorkbook $templateWorkbook,
|
|
): RedirectResponse {
|
|
$validated = $request->validated();
|
|
$departmentKey = $validated['department'];
|
|
$sheetKey = $validated['sheet'];
|
|
$allowedCoordinates = array_map(
|
|
fn (array $field): string => $field['coordinate'],
|
|
$templateWorkbook->sheet($sheetKey)['fields_by_department'][$departmentKey] ?? [],
|
|
);
|
|
|
|
$cleanValues = collect($validated['values'])
|
|
->filter(fn (mixed $value, string $coordinate): bool => in_array($coordinate, $allowedCoordinates, true))
|
|
->map(fn (mixed $value): string => trim((string) $value))
|
|
->filter(fn (string $value): bool => $value !== '')
|
|
->all();
|
|
|
|
$inputOverrides = $medicalReport->input_overrides ?? [];
|
|
$inputOverrides[$departmentKey] ??= [];
|
|
$inputOverrides[$departmentKey][$sheetKey] = $cleanValues;
|
|
|
|
$medicalReport->update([
|
|
'input_overrides' => $inputOverrides,
|
|
]);
|
|
|
|
return to_route('medical-reports.show', [
|
|
'medicalReport' => $medicalReport,
|
|
'department' => $departmentKey,
|
|
'sheet' => $sheetKey,
|
|
]);
|
|
}
|
|
|
|
public function updateStructured(
|
|
UpdateMedicalReportStructuredTemplateRequest $request,
|
|
MedicalReport $medicalReport,
|
|
StructuredTemplateRegistry $structuredTemplateRegistry,
|
|
): RedirectResponse {
|
|
$validated = $request->validated();
|
|
$departmentKey = $validated['department'];
|
|
$templateKey = $validated['template_key'];
|
|
$template = $structuredTemplateRegistry->templateForDepartment($departmentKey);
|
|
$inputOverrides = $medicalReport->input_overrides ?? [];
|
|
$inputOverrides['structured_departments'] ??= [];
|
|
$inputOverrides['structured_departments'][$departmentKey] ??= [];
|
|
|
|
if (isset($template['sections']) && is_array($template['sections'])) {
|
|
$sections = collect($template['sections'])
|
|
->mapWithKeys(function (array $section) use ($validated): array {
|
|
$fieldKeys = collect($section['fields'] ?? [])
|
|
->pluck('key')
|
|
->filter(fn (mixed $value): bool => is_string($value))
|
|
->values();
|
|
$entries = collect($validated['sections'][$section['key']]['entries'] ?? [])
|
|
->map(function (array $entry) use ($fieldKeys): array {
|
|
return $fieldKeys
|
|
->mapWithKeys(fn (string $fieldKey): array => [
|
|
$fieldKey => trim((string) ($entry[$fieldKey] ?? '')),
|
|
])
|
|
->all();
|
|
})
|
|
->filter(fn (array $entry): bool => collect($entry)->some(
|
|
fn (string $value): bool => $value !== ''
|
|
))
|
|
->values()
|
|
->all();
|
|
|
|
return [
|
|
$section['key'] => [
|
|
'entries' => $entries,
|
|
],
|
|
];
|
|
})
|
|
->all();
|
|
|
|
$inputOverrides['structured_departments'][$departmentKey][$templateKey] = [
|
|
'sections' => $sections,
|
|
];
|
|
} else {
|
|
$fieldKeys = collect($template['fields'] ?? [])
|
|
->pluck('key')
|
|
->filter(fn (mixed $value): bool => is_string($value))
|
|
->values();
|
|
$entries = collect($validated['entries'])
|
|
->map(function (array $entry) use ($fieldKeys): array {
|
|
return $fieldKeys
|
|
->mapWithKeys(fn (string $fieldKey): array => [
|
|
$fieldKey => trim((string) ($entry[$fieldKey] ?? '')),
|
|
])
|
|
->all();
|
|
})
|
|
->filter(fn (array $entry): bool => collect($entry)->some(
|
|
fn (string $value): bool => $value !== ''
|
|
))
|
|
->values()
|
|
->all();
|
|
|
|
$inputOverrides['structured_departments'][$departmentKey][$templateKey] = [
|
|
'entries' => $entries,
|
|
];
|
|
}
|
|
|
|
$medicalReport->update([
|
|
'input_overrides' => $inputOverrides,
|
|
]);
|
|
|
|
return to_route('medical-reports.show', [
|
|
'medicalReport' => $medicalReport,
|
|
'department' => $departmentKey,
|
|
]);
|
|
}
|
|
|
|
public function economists(
|
|
MedicalReport $medicalReport,
|
|
EconomistWorkbook $economistWorkbook,
|
|
): Response {
|
|
return Inertia::render('medical-reports/Economists', $economistWorkbook->pageData($medicalReport));
|
|
}
|
|
|
|
public function builder(
|
|
Request $request,
|
|
MedicalReport $medicalReport,
|
|
FormTemplateBuilderPage $formTemplateBuilderPage,
|
|
TemplateWorkbook $templateWorkbook,
|
|
): Response {
|
|
$departmentKeys = array_map(
|
|
fn (array $department): string => $department['key'],
|
|
$templateWorkbook->departments(),
|
|
);
|
|
$selectedDepartment = $request->string('department')->toString();
|
|
$selectedDepartment = in_array($selectedDepartment, $departmentKeys, true)
|
|
? $selectedDepartment
|
|
: ($departmentKeys[0] ?? null);
|
|
|
|
return Inertia::render(
|
|
'medical-reports/Builder',
|
|
$formTemplateBuilderPage->pageData($medicalReport, $selectedDepartment),
|
|
);
|
|
}
|
|
|
|
public function upsertBuilder(
|
|
UpsertMedicalReportFormTemplateRequest $request,
|
|
MedicalReport $medicalReport,
|
|
): RedirectResponse {
|
|
$validated = $request->validated();
|
|
$departmentKey = $validated['department'];
|
|
$hospitalUnitId = HospitalUnit::query()
|
|
->where('slug', $departmentKey)
|
|
->value('id');
|
|
$schema = $validated['schema'];
|
|
|
|
$normalizedSchema = [
|
|
'title' => $schema['title'],
|
|
'description' => $schema['description'] ?? '',
|
|
'sections' => collect($schema['sections'])
|
|
->map(function (array $section): array {
|
|
return [
|
|
'key' => $section['key'],
|
|
'title' => $section['title'],
|
|
'economist_label' => $section['economist_label'] ?? '',
|
|
'fields' => collect($section['fields'])
|
|
->map(fn (array $field): array => [
|
|
'key' => $field['key'],
|
|
'label' => $field['label'],
|
|
'type' => $field['type'],
|
|
])
|
|
->values()
|
|
->all(),
|
|
'export_metrics' => collect($section['export_metrics'] ?? [])
|
|
->map(fn (array $metric): array => [
|
|
'key' => $metric['key'],
|
|
'label' => $metric['label'],
|
|
'source_field' => $metric['source_field'],
|
|
'aggregation' => $metric['aggregation'],
|
|
'analysis_column' => $metric['analysis_column'] ?? null,
|
|
'row_mode' => $metric['row_mode'] ?? null,
|
|
'target_unit_slug' => $metric['target_unit_slug'] ?? null,
|
|
])
|
|
->values()
|
|
->all(),
|
|
'default_entries' => collect($section['default_entries'] ?? [])
|
|
->map(fn (array $entry): array => collect($entry)
|
|
->map(fn (mixed $value): string => trim((string) $value))
|
|
->all())
|
|
->values()
|
|
->all(),
|
|
];
|
|
})
|
|
->values()
|
|
->all(),
|
|
];
|
|
|
|
$template = MedicalReportFormTemplate::query()
|
|
->where(function ($query) use ($hospitalUnitId, $departmentKey): void {
|
|
if ($hospitalUnitId !== null) {
|
|
$query->where('hospital_unit_id', $hospitalUnitId)
|
|
->orWhere('department_key', $departmentKey);
|
|
|
|
return;
|
|
}
|
|
|
|
$query->where('department_key', $departmentKey);
|
|
})
|
|
->first() ?? new MedicalReportFormTemplate;
|
|
|
|
$template->fill([
|
|
'hospital_unit_id' => $hospitalUnitId,
|
|
'name' => $validated['name'],
|
|
'description' => $validated['description'] ?? '',
|
|
'department_key' => $departmentKey,
|
|
'schema' => $normalizedSchema,
|
|
'is_active' => true,
|
|
]);
|
|
$template->save();
|
|
|
|
return to_route('medical-reports.builder', [
|
|
'medicalReport' => $medicalReport,
|
|
'department' => $departmentKey,
|
|
]);
|
|
}
|
|
}
|