From c92967c6ca31eaeeb25eeae89bc8edc119e12854 Mon Sep 17 00:00:00 2001 From: Dr Masroor Ehsan Date: Wed, 1 Jan 2025 12:53:33 +0600 Subject: [PATCH] wip --- .../Controllers/Staff/StudiesController.php | 1 + .../Staff/StudyHistoryController.php | 9 ++- app/Http/Requests/StudyHistoryRequest.php | 1 - app/Models/Study.php | 3 + app/Models/StudyDetails.php | 15 +++- app/Models/Traits/HashableId.php | 56 ++++++++++++++ app/Rules/ExistsByHashRule.php | 75 +++++++++++++++++++ resources/views/staff/history/edit.blade.php | 55 +++++++++----- resources/views/staff/history/view.blade.php | 4 + 9 files changed, 193 insertions(+), 26 deletions(-) create mode 100644 app/Models/Traits/HashableId.php create mode 100644 app/Rules/ExistsByHashRule.php diff --git a/app/Http/Controllers/Staff/StudiesController.php b/app/Http/Controllers/Staff/StudiesController.php index 0f960ca..54a594e 100644 --- a/app/Http/Controllers/Staff/StudiesController.php +++ b/app/Http/Controllers/Staff/StudiesController.php @@ -12,6 +12,7 @@ class StudiesController extends HashidControllerBase public function index() { $studies = UserStudyListerFactory::getLister()->all(); + dd($studies); return view('staff.studies.index', compact('studies')); } diff --git a/app/Http/Controllers/Staff/StudyHistoryController.php b/app/Http/Controllers/Staff/StudyHistoryController.php index 2db439c..3bddd58 100644 --- a/app/Http/Controllers/Staff/StudyHistoryController.php +++ b/app/Http/Controllers/Staff/StudyHistoryController.php @@ -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)); } } diff --git a/app/Http/Requests/StudyHistoryRequest.php b/app/Http/Requests/StudyHistoryRequest.php index b9f24ca..4962818 100644 --- a/app/Http/Requests/StudyHistoryRequest.php +++ b/app/Http/Requests/StudyHistoryRequest.php @@ -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'], diff --git a/app/Models/Study.php b/app/Models/Study.php index 66bb6c1..c3c71d9 100644 --- a/app/Models/Study.php +++ b/app/Models/Study.php @@ -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 [ diff --git a/app/Models/StudyDetails.php b/app/Models/StudyDetails.php index 90322de..83e4ccc 100644 --- a/app/Models/StudyDetails.php +++ b/app/Models/StudyDetails.php @@ -13,7 +13,10 @@ public function study(): BelongsTo return $this->belongsTo(Study::class); } - protected function casts() + /** + * @return array + */ + 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']); + } } diff --git a/app/Models/Traits/HashableId.php b/app/Models/Traits/HashableId.php new file mode 100644 index 0000000..029772b --- /dev/null +++ b/app/Models/Traits/HashableId.php @@ -0,0 +1,56 @@ +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(); + } +} diff --git a/app/Rules/ExistsByHashRule.php b/app/Rules/ExistsByHashRule.php new file mode 100644 index 0000000..9ce52f3 --- /dev/null +++ b/app/Rules/ExistsByHashRule.php @@ -0,0 +1,75 @@ + $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), + ]); + } +} diff --git a/resources/views/staff/history/edit.blade.php b/resources/views/staff/history/edit.blade.php index aa8422d..793725a 100644 --- a/resources/views/staff/history/edit.blade.php +++ b/resources/views/staff/history/edit.blade.php @@ -11,29 +11,44 @@

Clinical Information

-
Clinical History
-
- {{ $details->clinical_history }} -
- + @dd($details) -
surgical_history
-
- {{ $details->surgical_history }} -
- +
+ @csrf + +
Clinical History
+
+ +
+ -
lab_results
-
- {{ $details->lab_results }} -
- +
surgical history
+
+ +
+ -
clinical_diagnosis
-
- {{ $details->clinical_diagnosis }} -
- +
lab results
+
+ +
+ + +
clinical diagnosis
+
+ +
+ + +
diff --git a/resources/views/staff/history/view.blade.php b/resources/views/staff/history/view.blade.php index 9f71eab..f84f5eb 100644 --- a/resources/views/staff/history/view.blade.php +++ b/resources/views/staff/history/view.blade.php @@ -35,6 +35,10 @@ + @can(\App\Models\Enums\Permission::StudyHistoryEdit) + Edit + @endcan +