wip
This commit is contained in:
parent
19865fc178
commit
c92967c6ca
@ -12,6 +12,7 @@ class StudiesController extends HashidControllerBase
|
|||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$studies = UserStudyListerFactory::getLister()->all();
|
$studies = UserStudyListerFactory::getLister()->all();
|
||||||
|
dd($studies);
|
||||||
|
|
||||||
return view('staff.studies.index', compact('studies'));
|
return view('staff.studies.index', compact('studies'));
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ public function view()
|
|||||||
{
|
{
|
||||||
abort_unless(auth()->user()->can(Permission::StudyHistoryView) || auth()->user()->isAdmin(), 403);
|
abort_unless(auth()->user()->can(Permission::StudyHistoryView) || auth()->user()->isAdmin(), 403);
|
||||||
$this->decodeKeys();
|
$this->decodeKeys();
|
||||||
$details = StudyDetails::where('study_id', $this->key)->first();
|
$details = StudyDetails::historyOnly($this->key);
|
||||||
|
|
||||||
return view('staff.history.view', compact('details'));
|
return view('staff.history.view', compact('details'));
|
||||||
}
|
}
|
||||||
@ -22,7 +22,7 @@ public function edit()
|
|||||||
{
|
{
|
||||||
abort_unless(auth()->user()->can(Permission::StudyHistoryEdit) || auth()->user()->isAdmin(), 403);
|
abort_unless(auth()->user()->can(Permission::StudyHistoryEdit) || auth()->user()->isAdmin(), 403);
|
||||||
$this->decodeKeys();
|
$this->decodeKeys();
|
||||||
$details = StudyDetails::where('study_id', $this->key)->first();
|
$details = StudyDetails::historyOnly($this->key);
|
||||||
|
|
||||||
return view('staff.history.edit', compact('details'));
|
return view('staff.history.edit', compact('details'));
|
||||||
}
|
}
|
||||||
@ -31,8 +31,9 @@ public function save(StudyHistoryRequest $request)
|
|||||||
{
|
{
|
||||||
abort_unless(auth()->user()->can(Permission::StudyHistoryEdit) || auth()->user()->isAdmin(), 403);
|
abort_unless(auth()->user()->can(Permission::StudyHistoryEdit) || auth()->user()->isAdmin(), 403);
|
||||||
$this->decodeKeys();
|
$this->decodeKeys();
|
||||||
$details = StudyDetails::where('study_id', $this->key)->first();
|
$details = StudyDetails::historyOnly($this->key);
|
||||||
|
$details->update($request->validated());
|
||||||
|
|
||||||
return redirect()->route('staff.history.show', $this->key);
|
return redirect()->route('staff.history.view', _h($this->key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ public function rules(): array
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'study_id' => ['required', 'exists:studies'],
|
'study_id' => ['required', 'exists:studies'],
|
||||||
'user_id' => ['required', 'exists:users'],
|
|
||||||
'clinical_history' => ['nullable'],
|
'clinical_history' => ['nullable'],
|
||||||
'surgical_history' => ['nullable'],
|
'surgical_history' => ['nullable'],
|
||||||
'lab_results' => ['nullable'],
|
'lab_results' => ['nullable'],
|
||||||
|
@ -5,11 +5,14 @@
|
|||||||
use App\Models\Enums\Permission;
|
use App\Models\Enums\Permission;
|
||||||
use App\Models\Enums\ReportStatus;
|
use App\Models\Enums\ReportStatus;
|
||||||
use App\Models\Enums\StudyLevelStatus;
|
use App\Models\Enums\StudyLevelStatus;
|
||||||
|
use App\Models\Traits\HashableId;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
use Illuminate\Database\Eloquent\Relations\HasOne;
|
use Illuminate\Database\Eloquent\Relations\HasOne;
|
||||||
|
|
||||||
class Study extends BaseModel
|
class Study extends BaseModel
|
||||||
{
|
{
|
||||||
|
use HashableId;
|
||||||
|
|
||||||
protected function casts(): array
|
protected function casts(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
@ -13,7 +13,10 @@ public function study(): BelongsTo
|
|||||||
return $this->belongsTo(Study::class);
|
return $this->belongsTo(Study::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function casts()
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
protected function casts(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'properties' => 'array',
|
'properties' => 'array',
|
||||||
@ -21,4 +24,14 @@ protected function casts()
|
|||||||
'assignment_log' => 'array',
|
'assignment_log' => 'array',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function historyOnly(int $studyId): self
|
||||||
|
{
|
||||||
|
return self::where('study_id', $studyId)->first(['id', 'study_id', 'clinical_history', 'surgical_history', 'lab_results', 'clinical_diagnosis']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function seriesOnly(int $studyId): self
|
||||||
|
{
|
||||||
|
return self::where('study_id', $studyId)->first(['id', 'study_id', 'series']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
56
app/Models/Traits/HashableId.php
Normal file
56
app/Models/Traits/HashableId.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models\Traits;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Database\Eloquent\Builder;
|
||||||
|
|
||||||
|
trait HashableId
|
||||||
|
{
|
||||||
|
private const string HASHID_COLUMN_NAME = 'hash_id';
|
||||||
|
|
||||||
|
public static function idToHash(int $key): string
|
||||||
|
{
|
||||||
|
return _h($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get HashId column name.
|
||||||
|
*/
|
||||||
|
public function getHashColumnName(): string
|
||||||
|
{
|
||||||
|
return property_exists($this, 'hashColumnName')
|
||||||
|
? $this->hashColumnName
|
||||||
|
: self::HASHID_COLUMN_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHashAttribute(): ?string
|
||||||
|
{
|
||||||
|
return $this->exists
|
||||||
|
? $this->idToHash($this->getKey())
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function scopeByHash(Builder $query, string $hash): Builder
|
||||||
|
{
|
||||||
|
return $query->where($this->getQualifiedKeyName(), unhash_it($hash));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resolveRouteBinding($value, $field = null)
|
||||||
|
{
|
||||||
|
if ($field || is_numeric($value)) {
|
||||||
|
return parent::resolveRouteBinding($value, $field);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->byHash($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function byHashOrFail($hash): self
|
||||||
|
{
|
||||||
|
return self::query()->byHash($hash)->firstOrFail();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function byHash($hash): ?self
|
||||||
|
{
|
||||||
|
return self::query()->byHash($hash)->first();
|
||||||
|
}
|
||||||
|
}
|
75
app/Rules/ExistsByHashRule.php
Normal file
75
app/Rules/ExistsByHashRule.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use App\Models\Traits\HashableId;
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Contracts\Validation\ValidationRule;
|
||||||
|
use Illuminate\Contracts\Validation\ValidatorAwareRule;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Validation\Rules\Exists;
|
||||||
|
use Illuminate\Validation\Validator;
|
||||||
|
use InvalidArgumentException;
|
||||||
|
|
||||||
|
class ExistsByHash extends Exists implements ValidationRule, ValidatorAwareRule
|
||||||
|
{
|
||||||
|
/** @var Model&HashableId */
|
||||||
|
protected Model $model;
|
||||||
|
|
||||||
|
protected Validator $validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param class-string<Model&HashableId> $class
|
||||||
|
*/
|
||||||
|
public function __construct(string $class)
|
||||||
|
{
|
||||||
|
$this->model = new $class;
|
||||||
|
|
||||||
|
if (! method_exists($this->model, 'bootHashableId')) {
|
||||||
|
throw new InvalidArgumentException('Class does not use HashableId');
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($class, $this->model->shouldHashPersist() ? $this->model->getHashColumnName() : $this->model->getKeyName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validate(string $attribute, mixed $value, Closure $fail): void
|
||||||
|
{
|
||||||
|
if (! $value || (! $this->model->shouldHashPersist() && ! $value = $this->model::hashToId($value))) {
|
||||||
|
$this->fail($attribute, $fail);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$validator = validator(
|
||||||
|
[$attribute => $value],
|
||||||
|
[$attribute => $this->buildParentRule()]
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($validator->fails()) {
|
||||||
|
$this->fail($attribute, $fail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValidator($validator): static
|
||||||
|
{
|
||||||
|
$this->validator = $validator;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function buildParentRule(): Exists
|
||||||
|
{
|
||||||
|
return tap(new parent($this->table, $this->column), function (Exists $parent) {
|
||||||
|
$parent->wheres = $this->wheres;
|
||||||
|
$parent->using = $this->using;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function fail(string $attribute, Closure $fail): void
|
||||||
|
{
|
||||||
|
$fail($this->validator->customMessages["{$attribute}.existsByHash"] ?? 'validation.exists')
|
||||||
|
->translate([
|
||||||
|
'attribute' => $this->validator->getDisplayableAttribute($attribute),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
@ -11,29 +11,44 @@
|
|||||||
<div class="mt-10 sm:mt-0">
|
<div class="mt-10 sm:mt-0">
|
||||||
<h4>Clinical Information</h4>
|
<h4>Clinical Information</h4>
|
||||||
|
|
||||||
<h5>Clinical History</h5>
|
@dd($details)
|
||||||
<div class="p-4 border-gray-100">
|
|
||||||
{{ $details->clinical_history }}
|
|
||||||
</div>
|
|
||||||
<x-section-border />
|
|
||||||
|
|
||||||
<h5>surgical_history</h5>
|
<form action="{{ route('staff.history.save', _h($details->study_id)) }}" method="post">
|
||||||
<div class="p-4 border-gray-100">
|
@csrf
|
||||||
{{ $details->surgical_history }}
|
<input type="hidden" name="study_id" value="{{ $details->study_id }}">
|
||||||
</div>
|
<h5>Clinical History</h5>
|
||||||
<x-section-border />
|
<div class="p-4 border-gray-100">
|
||||||
|
<textarea name="clinical_history" id="clinical_history" cols="30" rows="10"
|
||||||
|
value="{!! $details->clinical_history !!}">
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<x-section-border/>
|
||||||
|
|
||||||
<h5>lab_results</h5>
|
<h5>surgical history</h5>
|
||||||
<div class="p-4 border-gray-100">
|
<div class="p-4 border-gray-100">
|
||||||
{{ $details->lab_results }}
|
<textarea name="surgical_history" id="surgical_history" cols="30" rows="10"
|
||||||
</div>
|
value="{!! $details->surgical_history !!}">
|
||||||
<x-section-border />
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<x-section-border/>
|
||||||
|
|
||||||
<h5>clinical_diagnosis</h5>
|
<h5>lab results</h5>
|
||||||
<div class="p-4 border-gray-100">
|
<div class="p-4 border-gray-100">
|
||||||
{{ $details->clinical_diagnosis }}
|
<textarea name="lab_results" id="lab_results" cols="30" rows="10"
|
||||||
</div>
|
value="{!! $details->lab_results !!}">
|
||||||
<x-section-border />
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<x-section-border/>
|
||||||
|
|
||||||
|
<h5>clinical diagnosis</h5>
|
||||||
|
<div class="p-4 border-gray-100">
|
||||||
|
<textarea name="clinical_diagnosis" id="clinical_diagnosis" cols="30" rows="10"
|
||||||
|
value="{!! $details->clinical_diagnosis !!}">
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit">Save</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<x-section-border/>
|
<x-section-border/>
|
||||||
|
|
||||||
|
@can(\App\Models\Enums\Permission::StudyHistoryEdit)
|
||||||
|
<a class="btn btn-sm" href="{{ route('staff.history.edit', _h($details->study_id)) }}">Edit</a>
|
||||||
|
@endcan
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user