浏览代码

Dynamic questions engine (wip)

Vijayakrishnan 3 年之前
父节点
当前提交
32b0bf1f48

+ 5 - 0
app/Http/Controllers/NoteController.php

@@ -282,6 +282,11 @@ class NoteController extends Controller
         ];
     }
 
+    // edit hpi (structured)
+    public function editHPI(Note $note, Point $point) {
+        return view('app.patient.note.edit-hpi', compact('note', 'point'));
+    }
+
     // review log
     public function reviewLog(Point $point) {
         return view('app.patient.note.review-log', compact('point'));

+ 40 - 0
app/Models/Point.php

@@ -219,4 +219,44 @@ class Point extends Model
             ]
         ];
     }
+
+    public static function fillPointStateAndBadge(Point $point, Note $note)
+    {
+
+        // state
+        if (!$point->is_removed) {
+            $point->state = "ACTIVE";
+        } elseif ($point->is_removed) {
+            if (!$point->is_removed_due_to_entry_error) {
+                $point->state = "HISTORIC";
+            } else {
+                $point->state = "ENTRY_ERROR";
+            }
+        }
+
+        // added/removed info
+        if ($point->state === 'ACTIVE') {
+            if ($point->added_in_note_id === $note->id && $point->addition_reason_category === 'DURING_VISIT') {
+                $point->badge = 'Added During Visit';
+            } elseif ($point->added_in_note_id === $note->id && $point->addition_reason_category === 'ON_INTAKE') {
+                $point->badge = 'New Record - Pre-existing';
+            } elseif ($point->added_in_note_id !== $note->id) {
+                $point->badge = 'Record Present Before Visit';
+            }
+        } elseif ($point->state === 'HISTORIC') {
+            if ($point->removed_in_note_id === $note->id && $point->removal_reason_category === 'DURING_VISIT') {
+                $point->badge = 'Removed During Visit';
+            } elseif ($point->removed_in_note_id === $note->id && $point->removal_reason_category === 'ON_INTAKE') {
+                $point->badge = 'Marked Removed on Intake';
+            } elseif ($point->removed_in_note_id !== $note->id) {
+                $point->badge = 'Historic Record Removed In A Previous Visit';
+            }
+        } elseif ($point->state === 'ENTRY_ERROR') {
+            if ($point->removed_in_note_id === $note->id) {
+                $point->badge = 'Marked as Entry Error During Visit';
+            }
+        }
+
+        return $point;
+    }
 }

+ 13 - 0
resources/views/app/dq-engine/edit.blade.php

@@ -0,0 +1,13 @@
+{{--
+inputs:
+    template
+    data // any currently saved data
+    any other inputs like $note, $client
+--}}
+<?php
+$template = json_decode(file_get_contents(resource_path('views/app/dq-templates/' . $template)));
+?>
+@foreach ($template->lines as $line)
+    @include('app.dq-engine.line', compact('line'))
+@endforeach
+

+ 1 - 0
resources/views/app/dq-engine/field/date.blade.php

@@ -0,0 +1 @@
+<input type="date" class="form-control form-control-sm" id="">

+ 1 - 0
resources/views/app/dq-engine/field/numeric.blade.php

@@ -0,0 +1 @@
+<input type="number" class="form-control form-control-sm" id="">

+ 8 - 0
resources/views/app/dq-engine/field/radios.blade.php

@@ -0,0 +1,8 @@
+<div class="d-flex align-items-center">
+    @foreach(@$line->options as $option)
+        <label class="d-inline-flex align-items-center my-0 mr-3">
+            <input type="radio" value="{{$option}}" class="my-0 mr-1">
+            <span>{{$option}}</span>
+        </label>
+    @endforeach
+</div>

+ 6 - 0
resources/views/app/dq-engine/field/select.blade.php

@@ -0,0 +1,6 @@
+<select class="form-control form-control-sm" id="">
+    <option value="">-- select --</option>
+    @foreach(@$line->options as $option)
+        <option value="{{$option}}">{{$option}}</option>
+    @endforeach
+</select>

+ 1 - 0
resources/views/app/dq-engine/field/text.blade.php

@@ -0,0 +1 @@
+<textarea class="form-control form-control-sm" id="" rows="1"></textarea>

+ 1 - 0
resources/views/app/dq-engine/field/time.blade.php

@@ -0,0 +1 @@
+<input type="time" class="form-control form-control-sm" id="">

+ 11 - 0
resources/views/app/dq-engine/line.blade.php

@@ -0,0 +1,11 @@
+<div class="mb-2">
+    <label for="" class="mb-1 text-secondary">{{$line->helpText}}</label>
+    @include('app.dq-engine.field.' . $line->fieldType)
+    @if(@($line->lines) && count($line->lines))
+        <div class="pt-2 pl-4">
+            @foreach ($line->lines as $line)
+                @include('app.dq-engine.line', compact('line'))
+            @endforeach
+        </div>
+    @endif
+</div>

+ 5 - 0
resources/views/app/dq-engine/read.blade.php

@@ -0,0 +1,5 @@
+{{--
+inputs:
+    pointData
+--}}
+READ

+ 85 - 0
resources/views/app/dq-templates/hpi/core.json

@@ -0,0 +1,85 @@
+{
+  "lines": [
+    {
+      "key": "onset",
+      "helpText": "When did the problem begin?",
+      "resultSummary": "Onset: {value}",
+      "fieldType": "date"
+    },
+    {
+      "key": "location",
+      "helpText": "Where is the CC located?",
+      "resultSummary": "Location: {value}",
+      "fieldType": "time"
+    },
+    {
+      "key": "duration",
+      "helpText": "How long has the CC been going on for?",
+      "resultSummary": "Duration: {value}",
+      "fieldType": "text"
+    },
+    {
+      "key": "characterization",
+      "helpText": "How does the patient describe the CC?",
+      "resultSummary": "Characterization: {value}",
+      "fieldType": "text"
+    },
+    {
+      "key": "alleviating_factors",
+      "helpText": "What makes it better?",
+      "resultSummary": "Alleviating factors: {value}",
+      "fieldType": "text"
+    },
+    {
+      "key": "aggravating_factors",
+      "helpText": "What makes it worse?",
+      "resultSummary": "Aggravating factors: {value}",
+      "fieldType": "text"
+    },
+    {
+      "key": "radiation",
+      "helpText": "Does the CC move or stay in one location?",
+      "resultSummary": "Radiation: {value}",
+      "fieldType": "text"
+    },
+    {
+      "key": "temporal_factor",
+      "helpText": "Is the CC worse (or better) at a certain time of the day?",
+      "resultSummary": "Temporal factor: {value}",
+      "fieldType": "text"
+    },
+    {
+      "key": "severity",
+      "helpText": "Using a scale of 1 to 10, 1 being the least, 10 being the worst, how does the patient rate the CC?",
+      "resultSummary": "Severity: {value}",
+      "fieldType": "radios",
+      "options": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+    },
+    {
+      "key": "coping",
+      "helpText": "How do you cope?",
+      "resultSummary": "Coping: {value}",
+      "fieldType": "text"
+    },
+    {
+      "key": "emotional_impact",
+      "helpText": "How does this affect you emotionally?",
+      "resultSummary": "Emotional Impact: {value}",
+      "fieldType": "text"
+    }
+  ],
+  "dataMap": {
+    "onset" : null,
+    "location" : null,
+    "duration" :  null,
+    "characterization" : null,
+    "alleviating_factors" :  null,
+    "aggravating_factors" : null,
+    "radiation" :  null,
+    "temporal_factor" : null,
+    "severity" :  null,
+    "coping" : null,
+    "emotional_impact" :  null
+  },
+  "definition": null
+}

+ 80 - 0
resources/views/app/patient/note/edit-hpi.blade.php

@@ -0,0 +1,80 @@
+<div class="p-3">
+
+    <!-- basic info regarding problem for context -->
+    <?php
+    if ($point->data) {
+        $point->data = json_decode($point->data);
+    }
+    $point = \App\Models\Point::fillPointStateAndBadge($point, $note);
+    ?>
+    <div class="border bg-aliceblue d-flex align-items-baseline p-2 mb-3">
+        <b>{{$point->state}}</b>
+        @if($point->badge)
+            <span class="mx-2 text-secondary">|</span>
+            <span class="">{{$point->badge}}</span>
+        @endif
+        @if(@($point->data->start_date))
+            <span class="mx-2 text-secondary">|</span>
+            <span class="">Start: {{friendly_date($point->data->start_date)}}</span>
+        @endif
+        @if(@($point->removal_effective_date))
+            <span class="mx-2 text-secondary">|</span>
+            <span class="">End: {{friendly_date($point->removal_effective_date)}}</span>
+        @endif
+    </div>
+
+    <?php
+    $currentReview = '';
+    $currentValue = '';
+    $previousValue = '';
+    $previousChildReview = null;
+    if ($point->lastChildReview && $point->last_child_review_point_scoped_note_id === $note->id) {
+        $parsedReview = json_decode($point->lastChildReview->data);
+        $currentReview = $parsedReview;
+        if(@$parsedReview->value) {
+            $currentValue = $parsedReview->value;
+            $previousChildReview = \App\Models\Point::where('id', '<', $point->lastChildReview->id)
+                ->where('category', 'REVIEW')
+                ->where('parent_point_id', $point->id)
+                ->orderBy('id', 'DESC')
+                ->first();
+            if($previousChildReview && $previousChildReview->data) {
+                $parsedReview = json_decode($previousChildReview->data);
+                $previousValue = $parsedReview->value;
+            }
+        }
+    }
+    else {
+        $previousChildReview = \App\Models\Point::where('parent_point_id', $point->id)
+            ->where('category', 'REVIEW')
+            ->orderBy('id', 'DESC')
+            ->first();
+        if($previousChildReview && $previousChildReview->data) {
+            $parsedReview = json_decode($previousChildReview->data);
+            if(@$parsedReview->value) {
+                $previousValue = $parsedReview->value;
+            }
+        }
+    }
+    ?>
+
+    <?php if($previousValue): ?>
+    <div class="mb-2">
+        <div class="d-flex align-items-baseline mb-1">
+            <span class="text-secondary">Previous HPI - <?= friendlier_date($previousChildReview->created_at) ?></span>
+        </div>
+        <div class="p-2 bg-light border inline-html-container"><?= $previousValue ?></div>
+    </div>
+    <?php endif; ?>
+
+    <?php
+    if(!@$template) {
+        $template = 'hpi/core.json';
+    }
+    $patient = $note->client;
+    $data = $currentReview ? $currentReview : null;
+    ?>
+    @include('app.dq-engine.edit', compact('template', 'note', 'patient', 'point', 'data'))
+
+
+</div>

+ 21 - 9
resources/views/app/patient/problems-center.blade.php

@@ -74,15 +74,27 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                             include resource_path('views/app/patient/segment-templates/_child_review/last-review.php');
                             ?>
                         </div>
-                        <div class="d-inline-flex flex-nowrap">
-                            <a class="pl-2 view-review-log"
-                               native target="_blank"
-                               open-in-stag-popup
-                               popup-style="stag-popup-md"
-                               title="Review log<?= !!@($problem->data->name) ? ' for ' . @($problem->data->name) : '' ?>"
-                               href="/point/review-log/<?= $problem->uid ?>?popupmode=1">
-                                <i class="fa fa-history"></i>
-                            </a>
+                        <div>
+                            <div class="">
+                                <a class="pl-2 view-review-log"
+                                   native target="_blank"
+                                   open-in-stag-popup
+                                   popup-style="stag-popup-md"
+                                   title="Review log<?= !!@($problem->data->name) ? ' for ' . @($problem->data->name) : '' ?>"
+                                   href="/point/review-log/<?= $problem->uid ?>?popupmode=1">
+                                    <i class="fa fa-history"></i>
+                                </a>
+                            </div>
+                            <div class="">
+                                <a class="pl-2 view-review-log"
+                                   native target="_blank"
+                                   open-in-stag-popup
+                                   popup-style="stag-popup-md"
+                                   title="HPI<?= !!@($problem->data->name) ? ' for ' . @($problem->data->name) : '' ?> / <?= $patient->displayName() ?>"
+                                   href="/point/edit-hpi/<?= $note->uid ?>/<?= $problem->uid ?>?popupmode=1">
+                                    <i class="fa fa-plus-square"></i>
+                                </a>
+                            </div>
                         </div>
                     </div>
                 </td>

+ 1 - 0
routes/web.php

@@ -377,6 +377,7 @@ Route::middleware('pro.auth')->group(function () {
 
     });
 
+    Route::get('/point/edit-hpi/{note}/{point}', 'NoteController@editHPI')->name('point-edit-hpi');
     Route::get('/point/review-log/{point}', 'NoteController@reviewLog')->name('point-review-log');
     Route::get('/point/plan-log/{point}', 'NoteController@planLog')->name('point-plan-log');
     Route::get('/note/pdf/{note}', 'NoteController@downloadAsPdf')->name('note-pdf');