radfusion/app/Services/Report/ReportManager.php
2025-01-23 18:03:49 +06:00

152 lines
4.2 KiB
PHP

<?php
namespace App\Services\Report;
use App\Domain\ACL\Permission;
use App\Domain\Report\ReportStatus;
use App\Models\Study;
use App\Models\StudyReport;
use App\Services\AuditTrail\Activity;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
final class ReportManager
{
public function __construct(private readonly Study $study, private ?StudyReport $report = null) {}
public static function make(int $study_id, ?StudyReport $report = null): static
{
return new self(Study::findOrFail($study_id), $report);
}
public static function fromReport(string $uuid): static
{
$report = StudyReport::accession($uuid)->firstOrFail();
return static::make($report->study_id, $report);
}
public static function ensureDownloadAccess(): void
{
abort_unless(me()->may([Permission::ReportEdit, Permission::ReportDictate, Permission::ReportApprove, Permission::ReportDownload]), 403);
}
public static function ensureEditAccess(): void
{
abort_unless(me()->may([Permission::ReportEdit, Permission::ReportDictate, Permission::ReportApprove]), 403);
}
public function getReports(): Collection
{
return $this->study->reports->sortByDesc('created_at');
}
public function createReport(string $content, ReportStatus $status): StudyReport
{
$report = StudyReport::make([
'study_id' => $this->study->id,
'organization_id' => $this->study->organization_id,
'department_id' => $this->study->department_id,
'report_status' => $status->value,
'read_by_id' => me()->id,
]);
$report->saveContent($content);
$report->save();
$report->refresh();
audit()
->on($this->study)
->did(Activity::Report_Save)
->notes($report->accession_number)
->log();
return $report;
}
public function finalizeReport(StudyReport $report): void
{
$report->setStatus(ReportStatus::Finalized);
audit()
->on($this->study)
->did(Activity::Report_Finalize)
->notes($report->accession_number)
->log();
$this->study->setReportStatus(ReportStatus::Finalized);
audit()
->on($this->study)
->did(Activity::Report_Finalize)
->log();
$this->study->unlockStudy();
audit()
->on($this->study)
->did(Activity::Study_Unlock)
->log();
}
public function check(): ?View
{
if (! $this->study->canEditReport()) {
return view('content.pages.notice', [
'color' => 'warning',
'title' => 'Read Completed',
'heading' => 'Read Completed',
'message' => 'The report has been finalized, and the study is now closed for any further modifications.',
]);
}
if (! $this->study->canObtainLock()) {
return view('content.pages.notice', [
'color' => 'danger',
'title' => 'Study Locked',
'heading' => 'Study Locked',
'message' => 'Study is locked by another user.',
]);
}
return null;
}
public function lockStudyIfRequired(): void
{
if ($this->study->isUnlocked()) {
$this->study->lockStudy();
audit()
->on($this->study)
->did(Activity::Study_Lock)
->log();
}
}
public function latestReport(): ?StudyReport
{
return StudyReport::forStudy($this->study)
->where('report_status', ReportStatus::Preliminary->value)
->select(['id', 'accession_number', 'file_path'])
->latest()
->first();
}
public function getStudy(): Study
{
return $this->study;
}
public function getReport(): ?StudyReport
{
return $this->report;
}
public function getReportForViewing(): ?StudyReport
{
audit()
->on($this->study)
->did(Activity::Report_View)
->log();
return $this->report;
}
}