This commit is contained in:
Dr Masroor Ehsan 2025-01-01 12:53:33 +06:00
parent 19865fc178
commit c92967c6ca
9 changed files with 193 additions and 26 deletions

View File

@ -12,6 +12,7 @@ class StudiesController extends HashidControllerBase
public function index()
{
$studies = UserStudyListerFactory::getLister()->all();
dd($studies);
return view('staff.studies.index', compact('studies'));
}

View File

@ -13,7 +13,7 @@ public function view()
{
abort_unless(auth()->user()->can(Permission::StudyHistoryView) || auth()->user()->isAdmin(), 403);
$this->decodeKeys();
$details = StudyDetails::where('study_id', $this->key)->first();
$details = StudyDetails::historyOnly($this->key);
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);
$this->decodeKeys();
$details = StudyDetails::where('study_id', $this->key)->first();
$details = StudyDetails::historyOnly($this->key);
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);
$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));
}
}

View File

@ -10,7 +10,6 @@ public function rules(): array
{
return [
'study_id' => ['required', 'exists:studies'],
'user_id' => ['required', 'exists:users'],
'clinical_history' => ['nullable'],
'surgical_history' => ['nullable'],
'lab_results' => ['nullable'],

View File

@ -5,11 +5,14 @@
use App\Models\Enums\Permission;
use App\Models\Enums\ReportStatus;
use App\Models\Enums\StudyLevelStatus;
use App\Models\Traits\HashableId;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
class Study extends BaseModel
{
use HashableId;
protected function casts(): array
{
return [

View File

@ -13,7 +13,10 @@ public function study(): BelongsTo
return $this->belongsTo(Study::class);
}
protected function casts()
/**
* @return array<string, string>
*/
protected function casts(): array
{
return [
'properties' => 'array',
@ -21,4 +24,14 @@ protected function casts()
'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']);
}
}

View 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();
}
}

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

View File

@ -11,29 +11,44 @@
<div class="mt-10 sm:mt-0">
<h4>Clinical Information</h4>
<h5>Clinical History</h5>
<div class="p-4 border-gray-100">
{{ $details->clinical_history }}
</div>
<x-section-border />
@dd($details)
<h5>surgical_history</h5>
<div class="p-4 border-gray-100">
{{ $details->surgical_history }}
</div>
<x-section-border />
<form action="{{ route('staff.history.save', _h($details->study_id)) }}" method="post">
@csrf
<input type="hidden" name="study_id" value="{{ $details->study_id }}">
<h5>Clinical History</h5>
<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>
<div class="p-4 border-gray-100">
{{ $details->lab_results }}
</div>
<x-section-border />
<h5>surgical history</h5>
<div class="p-4 border-gray-100">
<textarea name="surgical_history" id="surgical_history" cols="30" rows="10"
value="{!! $details->surgical_history !!}">
</textarea>
</div>
<x-section-border/>
<h5>clinical_diagnosis</h5>
<div class="p-4 border-gray-100">
{{ $details->clinical_diagnosis }}
</div>
<x-section-border />
<h5>lab results</h5>
<div class="p-4 border-gray-100">
<textarea name="lab_results" id="lab_results" cols="30" rows="10"
value="{!! $details->lab_results !!}">
</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>

View File

@ -35,6 +35,10 @@
</div>
<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>