Files
econom-calculator/app/Http/Controllers/MedicalReportController.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

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,
]);
}
}