Parcourir la source

Problems wizard (wip)

Vijayakrishnan il y a 3 ans
Parent
commit
13b051f097

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

@@ -312,6 +312,14 @@ class NoteController extends Controller
         return view('app.patient.medications-center', compact('patient', 'note'));
     }
 
+    public function problemsCenter(Request $request, Client $patient, Note $note) {
+        return view('app.patient.problems-center', compact('patient', 'note'));
+    }
+
+    public function goalsCenter(Request $request, Client $patient, Note $note) {
+        return view('app.patient.goals-center', compact('patient', 'note'));
+    }
+
     // TODO move to utility
     private function callJava($request, $endPoint, $data, $guestAccessCode = null)
     {

+ 522 - 0
resources/views/app/patient/goals-center.blade.php

@@ -0,0 +1,522 @@
+<?php
+
+use App\Models\Point;
+use App\Models\Client;
+use App\Models\Note;
+use App\Models\Segment;
+
+/** @var Client $patient */
+/** @var Note $note */
+
+$points = Point
+    ::where('client_id', $patient->id)
+    ->where('category', 'MEDICATION')
+    ->where('is_removed_due_to_entry_error', false)
+    ->orderBy('is_removed')
+    ->orderBy('removal_effective_date', 'DESC')
+    ->orderBy('created_at')
+    ->get();
+foreach ($points as $point) {
+    if ($point->data) {
+        $point->data = json_decode($point->data);
+    }
+}
+$medications = $points;
+
+?>
+
+<div class="mt-3 p-3 border-top min-height-500px" id="medications-center-{{$note->id}}">
+    <div>
+
+        <table class="table table-sm table-bordered table-striped mb-0 bg-white mb-2">
+            <thead>
+            <tr class="">
+                <th class="border-bottom-0 text-secondary">Name</th>
+                <th class="border-bottom-0 text-secondary">Frequency</th>
+                <th class="border-bottom-0 text-secondary">Active?</th>
+                <th class="border-bottom-0 text-secondary">Edit</th>
+                <th class="border-bottom-0 text-secondary">Delete</th>
+                <th class="border-bottom-0 text-secondary">Started</th>
+                <th class="border-bottom-0 text-secondary">Ended</th>
+                <th class="border-bottom-0 text-secondary">Last Review</th>
+                <th class="border-bottom-0 text-secondary">Last Plan</th>
+            </tr>
+            </thead>
+            <?php foreach($medications as $medication): ?>
+            <?php $point = $medication; ?>
+            <tr class="{{$medication->is_removed ? 'on-hover-opaque' : ''}}">
+                <td>
+                    <div class="d-flex align-items-baseline">
+                        @if($medication->is_removed)
+                            <i class="text-warning-mellow fa fa-circle text-sm on-hover-opaque mr-2"></i>
+                        @else
+                            <i class="text-success fa fa-circle text-sm on-hover-opaque mr-2"></i>
+                        @endif
+                        <div>
+                            <b><?= !!@($medication->data->name) ? @($medication->data->name) : '-' ?></b>
+                            @if(!$medication->is_removed && $medication->added_in_note_id === $note->id)
+                                <div class="mt-1 text-sm text-secondary">Added during this visit
+                                    @if($medication->addition_reason_category === 'ON_INTAKE')
+                                        (existing)
+                                    @elseif($medication->addition_reason_category === 'DURING_VISIT')
+                                        (new)
+                                    @endif
+                                </div>
+                            @endif
+                            @if($medication->is_removed && ($medication->added_in_note_id !== $note->id && $medication->removed_in_note_id === $note->id))
+                                <div class="mt-1 text-sm text-secondary">Discontinued during this visit</div>
+                            @endif
+                        </div>
+                    </div>
+                </td>
+                <td>
+                    <?= !!@($medication->data->frequency) ? @($medication->data->frequency) : '-' ?>
+                </td>
+                <td>
+                    @if($medication->is_removed)
+                        NO
+                    @else
+                        <b>YES</b>
+                    @endif
+                </td>
+                <td>
+                    @if($medication->added_in_note_id === $note->id)
+                        <div moe wide>
+                            <a start show href="#" title="Edit">Edit</a>
+                            <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-medication">
+                                <input type="hidden" name="uid" value="<?= $medication->uid ?>">
+                                <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                                <p class="mb-2"><b>Update Medication</b></p>
+
+                                <input type="hidden" name="data">
+
+                                <input type="hidden" data-name="medId" value="{{@$medication->data->medId}}">
+                                <input type="hidden" data-name="routedMedId" value="{{@$medication->data->routedMedId}}">
+                                <input type="hidden" data-name="routedDosageFormMedId" value="{{@$medication->data->routedDosageFormMedId}}">
+                                <input type="hidden" data-name="gcnSeqno" value="{{@$medication->data->gcnSeqno}}">
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Drug</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset prescription-medication"
+                                           data-name="name"
+                                           value="{{@$medication->data->name}}"
+                                           stag-suggest
+                                           stag-suggest-ep="/fdb-med-suggest-v2/json">
+                                </div>
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Frequency</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset"
+                                           data-option-list="frequency-options" data-field="frequency"
+                                           value="{{@$medication->data->frequency}}"
+                                           data-name="frequency">
+                                    <div id="frequency-options" class="data-option-list">
+                                        <div>Once a day</div>
+                                        <div>Twice a day</div>
+                                    </div>
+                                </div>
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Existing / New</label>
+                                    <select class="form-control form-control-sm" name="additionReasonCategory" required>
+                                        <option value="">-- select --</option>
+                                        <option value="ON_INTAKE" {{$medication->addition_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>Existing (Patient was already on this)</option>
+                                        <option value="DURING_VISIT" {{$medication->addition_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>New (Prescribed during this visit)</option>
+                                    </select>
+                                </div>
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Description</label>
+                                    <textarea rows="1" data-name="description" class="form-control form-control-sm">{{@$medication->data->description}}</textarea>
+                                </div>
+
+                                <div>
+                                    <button type="submit" class="btn-save-medication btn btn-sm btn-primary mr-2">Save</button>
+                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                </div>
+                            </form>
+                        </div>
+                    @endif
+                </td>
+                <td>
+                    @if(!$medication->is_removed)
+                        @if($medication->added_in_note_id === $note->id)
+                            <div moe>
+                                <a start show href="#" title="Delete">Delete</a>
+                                <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1">
+                                    <input type="hidden" name="uid" value="<?= $medication->uid ?>">
+                                    <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                                    <input type="hidden" name="isRemoved" value="1">
+                                    <input type="hidden" name="isRemovedDueToEntryError" value="1">
+                                    <input type="hidden" name="removalReasonMemo" value="Entry Error">
+                                    <input type="hidden" name="removalEffectiveDate" value="<?= date('Y-m-d') ?>">
+                                    <p class="mb-2"><b>Delete this medication?</b></p>
+                                    <div>
+                                        <button submit class="btn btn-sm btn-danger mr-2">Delete</button>
+                                        <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                        @else
+                            <div moe>
+                                <a start show href="#" title="Discontinue">Discontinue</a>
+                                <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1">
+                                    <input type="hidden" name="uid" value="<?= $medication->uid ?>">
+                                    <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                                    <input type="hidden" name="isRemoved" value="1">
+                                    <input type="hidden" name="isRemovedDueToEntryError" value="0">
+                                    <p class="mb-2"><b>Discontinue this medication?</b></p>
+                                    <div class="mb-2">
+                                        <label class="text-sm text-secondary mb-1">Already stopped / Stop now</label>
+                                        <select class="form-control form-control-sm" name="removalReasonCategory" required>
+                                            <option value="">-- select --</option>
+                                            <option value="ON_INTAKE">Already stopped (before this visit)</option>
+                                            <option value="DURING_VISIT">Stop now</option>
+                                        </select>
+                                    </div>
+                                    <div class="mb-2">
+                                        <label class="text-sm text-secondary mb-1">Removal Reason</label>
+                                        <textarea name="removalReasonMemo" class="form-control form-control-sm" rows="2"></textarea>
+                                    </div>
+                                    <div class="mb-2">
+                                        <label class="text-sm text-secondary mb-1">Removal Effective Date</label>
+                                        <input type="date" name="removalEffectiveDate"
+                                               value="<?= date('Y-m-d') ?>"
+                                               max="<?= date('Y-m-d') ?>"
+                                               class="form-control form-control-sm">
+                                    </div>
+                                    <div>
+                                        <button submit class="btn btn-sm btn-danger mr-2">Delete</button>
+                                        <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                        @endif
+                    @endif
+                </td>
+                <td>
+                    <?= !!@($medication->data->start_date) ? @($medication->data->start_date) : '-' ?>
+                    @if(!!@($medication->data->prescriber))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($medication->data->prescriber) ? @($medication->data->prescriber) : '-' ?></div>
+                    @endif
+                </td>
+                <td>
+                    <?= !!@($medication->removal_effective_date) ? @($medication->removal_effective_date) : '-' ?>
+                    @if(!!@($medication->removal_reason_memo))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($medication->removal_reason_memo) ? @($medication->removal_reason_memo) : '-' ?></div>
+                    @endif
+                </td>
+                <td>
+                    <div class="d-flex align-items-start">
+                        <div class="flex-grow-1">
+                            <?php
+                            $point = $medication;
+                            include resource_path('views/app/patient/segment-templates/_child_review/last-review.php');
+                            ?>
+                        </div>
+                        <a class="px-2 view-review-log"
+                           native target="_blank"
+                           open-in-stag-popup
+                           popup-style="stag-popup-md"
+                           title="Review log<?= !!@($medication->data->name) ? ' for ' . @($medication->data->name) : '' ?>"
+                           href="/point/review-log/<?= $medication->uid ?>?popupmode=1">
+                            <i class="fa fa-history"></i>
+                        </a>
+                    </div>
+                </td>
+                <td>
+                    <div class="d-flex align-items-start">
+                        <div class="flex-grow-1">
+                            <?php
+                            include resource_path('views/app/patient/segment-templates/_child_plan/last-plan.php');
+                            ?>
+                        </div>
+                        <a class="px-2 view-review-log"
+                           native target="_blank"
+                           open-in-stag-popup
+                           popup-style="stag-popup-md"
+                           title="Plan log<?= !!@($medication->data->name) ? ' for ' . @($medication->data->name) : '' ?>"
+                           href="/point/plan-log/<?= $medication->uid ?>?popupmode=1">
+                            <i class="fa fa-history"></i>
+                        </a>
+                    </div>
+                </td>
+            </tr>
+            <?php endforeach; ?>
+        </table>
+
+        <div class="d-flex align-items-center">
+            <div class="mt-1 w-100 border p-2 bg-aliceblue border-info rounded">
+                <!--<a href="#" start show class="btn btn-sm btn btn-outline-primary">+ Add new medication, prescribed during this visit</a>-->
+                <form action="/api/visitPoint/addTopLevel" class="mcp-theme-1 w-100" id="frm-add-medication">
+                    <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                    <input type="hidden" name="category" value="MEDICATION">
+                    <input type="hidden" name="data">
+
+                    <input type="hidden" data-name="medId">
+                    <input type="hidden" data-name="routedMedId">
+                    <input type="hidden" data-name="routedDosageFormMedId">
+                    <input type="hidden" data-name="gcnSeqno">
+
+                    <input type="hidden" name="additionReasonCategory">
+                    <input type="hidden" name="isRemoved">
+                    <input type="hidden" name="removalReasonCategory">
+                    <input type="hidden" name="isRemovedDueToEntryError">
+
+                    <p class="mb-2"><b>Add Medication</b></p>
+
+                    <div class="row">
+                        <div class="col-7">
+                            <div class="row mb-2">
+                                <div class="col-8 pr-0">
+                                    <label class="text-sm text-secondary mb-0">Name</label>
+                                    <input type="text"
+                                           data-name="name"
+                                           class="form-control form-control-sm"
+                                           stag-suggest
+                                           stag-suggest-bottom-left
+                                           stag-suggest-ep="/fdb-med-suggest-v2/json"
+                                           required>
+                                </div>
+                                <div class="col-4">
+                                    <label class="text-sm text-secondary mb-0">Frequency</label>
+                                    <input type="text" class="form-control form-control-sm" data-name="frequency"
+                                           data-option-list="frequency-options" autocomplete="off">
+                                    <div id="frequency-options" class="data-option-list">
+                                        <div>Once a day</div>
+                                        <div>Twice a day</div>
+                                    </div>
+                                </div>
+                            </div>
+                            <!--<div class="row mb-2">
+                                <div class="col-12">
+                                    <label class="text-sm text-secondary mb-0">Description</label>
+                                    <textarea rows="1" data-name="description" class="form-control form-control-sm"></textarea>
+                                </div>
+                            </div>-->
+                            <div class="row mb-2">
+                                <div class="col-12">
+                                    <label class="text-sm text-secondary mb-0">Historic / Preexisting / New</label>
+                                    <select class="form-control form-control-sm additionReasonCategory_ui" name="additionReasonCategory_ui" required>
+                                        <option value="">-- select --</option>
+                                        <option value="HISTORIC">Historic</option>
+                                        <option value="PRE_EXISTING">Preexisting</option>
+                                        <option value="NEW">New (Prescribed during this visit)</option>
+                                    </select>
+                                </div>
+                            </div>
+                            <div class="d-flex align-items-start mb-2">
+                                <div class="w-25">
+                                    <div class="start_date_ui" style="display: none">
+                                        <label class="text-sm text-secondary mb-0">Start Date</label>
+                                        <input type="date"
+                                               data-name="start_date"
+                                               class="form-control form-control-sm min-width-unset">
+                                    </div>
+                                </div>
+                                <div class="w-25 pl-2">
+                                    <div class="prescriber_ui" style="display: none">
+                                        <label class="text-sm text-secondary mb-0">Prescribed By</label>
+                                        <input type="text"
+                                               data-name="prescriber"
+                                               class="form-control form-control-sm min-width-unset">
+                                    </div>
+                                </div>
+                                <div class="w-25 pl-2">
+                                    <div class="removalEffectiveDate_ui" style="display: none">
+                                        <label class="text-sm text-secondary mb-0">End Date</label>
+                                        <input type="date"
+                                               name="removalEffectiveDate"
+                                               class="form-control form-control-sm min-width-unset">
+                                    </div>
+                                </div>
+                                <div class="w-25 pl-2">
+                                    <div class="removalReasonMemo_ui" style="display: none">
+                                        <label class="text-sm text-secondary mb-0">Removal By/Memo</label>
+                                        <input type="text"
+                                               name="removalReasonMemo"
+                                               class="form-control form-control-sm min-width-unset">
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-5 border-left">
+
+                        </div>
+                    </div>
+
+                    <div class="d-flex align-items-center">
+                        <button type="submit" class="btn btn-sm btn-primary mr-2 my-1">Save Medication</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    (function() {
+        function init() {
+            let parentSegment = $('#medications-center-{{$note->id}}');
+            parentSegment.find('input[stag-suggest][data-name="name"]')
+                .off('stag-suggest-selected')
+                .on('stag-suggest-selected', (_e, _input, _data) => {
+                    $(_input).closest('form').find('input[data-name="routedMedId"]').val(_data.routed_med_id);
+                    $(_input).closest('form').find('input[data-name="routedDosageFormMedId"]').val(_data.routed_dosage_form_med_id);
+                    $(_input).closest('form').find('input[data-name="gcnSeqno"]').val(_data.gcn_seqno);
+                    $(_input).closest('form').find('input[data-name="medId"]').val(_data.medid);
+                    return false;
+                });
+
+            parentSegment.find('.additionReasonCategory_ui')
+                .off('change')
+                .on('change', function() {
+
+                    let form = $(this).closest('form');
+
+                    // additionReasonCategory
+                    // isRemoved
+                    // removalReasonCategory
+                    form.find('[name="isRemovedDueToEntryError"]').val('0');
+
+                    form.find('.start_date_ui').hide();
+                    form.find('.prescriber_ui').hide();
+                    form.find('.removalEffectiveDate_ui').hide();
+                    form.find('.removalReasonMemo_ui').hide();
+
+                    if(this.value === 'HISTORIC') {
+                        form.find('[name="additionReasonCategory"]').val('ON_INTAKE');
+                        form.find('[name="isRemoved"]').val('1');
+                        form.find('.start_date_ui').show().find('input').val('');
+                        form.find('.prescriber_ui').show().find('input').val('');
+                        form.find('.removalEffectiveDate_ui').show().find('input').val('');
+                        form.find('.removalReasonMemo_ui').show().find('input').val('');
+                    }
+                    else if(this.value === 'PRE_EXISTING') {
+                        form.find('[name="additionReasonCategory"]').val('ON_INTAKE');
+                        form.find('[name="isRemoved"]').val('0');
+                        form.find('.start_date_ui').show().find('input').val('');
+                        form.find('.prescriber_ui').show().find('input').val('');
+                    }
+                    else if(this.value === 'NEW') {
+                        form.find('[name="additionReasonCategory"]').val('DURING_VISIT');
+                        form.find('[name="isRemoved"]').val('0');
+                        form.find('.start_date_ui').show().find('input').val('{{date('Y-m-d')}}');
+                        form.find('.prescriber_ui').show().find('input').val('{{$note->hcpPro->displayName()}}');
+                    }
+
+                });
+
+            parentSegment.find('#frm-add-medication')
+                .off('submit')
+                .on('submit', function () {
+
+                    let form = $(this);
+
+                    if (!form[0].checkValidity()) {
+                        form[0].reportValidity();
+                        return false;
+                    }
+
+                    // add [data-name] values to payload
+                    let dataField = form.find('[name="data"]').first();
+                    let parsed = null;
+                    if(dataField.val()) {
+                        parsed = JSON.parse(dataField.val());
+                    }
+                    form.find('[data-name]').each(function() {
+                        if(!parsed) parsed = {};
+
+                        let keys = $(this).attr('data-name').split('->');
+                        let currentNode = parsed;
+                        for (let i = 0; i < keys.length; i++) {
+                            if(i !== keys.length - 1) {
+                                if(typeof currentNode[keys[i]] === 'undefined') {
+                                    currentNode[keys[i]] = {};
+                                }
+                                currentNode = currentNode[keys[i]];
+                            }
+                            else {
+                                if($(this).is(':checkbox')) {
+                                    currentNode[keys[i]] = $(this).prop('checked');
+                                }
+                                else {
+                                    currentNode[keys[i]] = $(this).val();
+                                }
+                            }
+                        }
+
+                    });
+                    if(parsed) {
+                        dataField.val(JSON.stringify(parsed));
+                    }
+
+                    $.post(form.attr('action'), form.serialize(), _data => {
+                        if(!hasResponseError(_data)) {
+                            hideMask();
+                            refreshDynamicStagPopup();
+                            $('.visit-segment[data-segment-template-name="intake_medications"]').find('.refresh-segment').trigger('click');
+                        }
+                    }, 'json');
+                    return false;
+                });
+
+            parentSegment.find('.frm-edit-medication')
+                .off('submit')
+                .on('submit', function () {
+
+                    let form = $(this);
+
+                    if (!form[0].checkValidity()) {
+                        form[0].reportValidity();
+                        return false;
+                    }
+
+                    // add [data-name] values to payload
+                    let dataField = form.find('[name="data"]').first();
+                    let parsed = null;
+                    if(dataField.val()) {
+                        parsed = JSON.parse(dataField.val());
+                    }
+                    form.find('[data-name]').each(function() {
+                        if(!parsed) parsed = {};
+
+                        let keys = $(this).attr('data-name').split('->');
+                        let currentNode = parsed;
+                        for (let i = 0; i < keys.length; i++) {
+                            if(i !== keys.length - 1) {
+                                if(typeof currentNode[keys[i]] === 'undefined') {
+                                    currentNode[keys[i]] = {};
+                                }
+                                currentNode = currentNode[keys[i]];
+                            }
+                            else {
+                                if($(this).is(':checkbox')) {
+                                    currentNode[keys[i]] = $(this).prop('checked');
+                                }
+                                else {
+                                    currentNode[keys[i]] = $(this).val();
+                                }
+                            }
+                        }
+
+                    });
+                    if(parsed) {
+                        dataField.val(JSON.stringify(parsed));
+                    }
+
+                    $.post(form.attr('url'), form.serialize(), _data => {
+                        if(!hasResponseError(_data)) {
+                            hideMask();
+                            refreshDynamicStagPopup();
+                            $('.visit-segment[data-segment-template-name="intake_medications"]').find('.refresh-segment').trigger('click');
+                        }
+                    }, 'json');
+                    return false;
+                });
+
+            initStagSuggest();
+        }
+        addMCInitializer('medications-center-{{$note->id}}', init, '#medications-center-{{$note->id}}')
+    }).call(window);
+</script>

+ 24 - 0
resources/views/app/patient/note/dashboard.blade.php

@@ -2240,6 +2240,30 @@
                                 <span>Rx</span>
                             </div>
                         </div>
+                        <div class="nbt-container p-2 border-right border-info d-inline-flex align-self-stretch">
+                            <div native target="_blank"
+                                 class="c-pointer d-inline-flex align-items-center"
+                                 open-in-stag-popup
+                                 mc-initer="problems-center-{{$note->id}}"
+                                 title="Problems Center"
+                                 popup-style="wide overflow-visible"
+                                 href="/problems-center/{{$patient->uid}}/{{$note->uid}}">
+                                <i class="fa fa-bolt mr-1"></i>
+                                <span>Dx</span>
+                            </div>
+                        </div>
+                        <div class="nbt-container p-2 border-right border-info d-inline-flex align-self-stretch">
+                            <div native target="_blank"
+                                 class="c-pointer d-inline-flex align-items-center"
+                                 open-in-stag-popup
+                                 mc-initer="goals-center-{{$note->id}}"
+                                 title="Goals Center"
+                                 popup-style="wide overflow-visible"
+                                 href="/goals-center/{{$patient->uid}}/{{$note->uid}}">
+                                <i class="fa fa-bolt mr-1"></i>
+                                <span>Goals</span>
+                            </div>
+                        </div>
                     </div>
                     @endif
 

+ 486 - 0
resources/views/app/patient/problems-center.blade.php

@@ -0,0 +1,486 @@
+<?php
+
+use App\Models\Point;
+use App\Models\Client;
+use App\Models\Note;
+use App\Models\Segment;
+
+/** @var Client $patient */
+/** @var Note $note */
+
+$points = Point
+    ::where('client_id', $patient->id)
+    ->where('category', 'PROBLEM')
+    ->where('is_removed_due_to_entry_error', false)
+    ->orderBy('is_removed')
+    ->orderBy('removal_effective_date', 'DESC')
+    ->orderBy('created_at')
+    ->get();
+foreach ($points as $point) {
+    if ($point->data) {
+        $point->data = json_decode($point->data);
+    }
+}
+$problems = $points;
+
+?>
+
+<div class="mt-3 p-3 border-top min-height-500px" id="problems-center-{{$note->id}}">
+    <div>
+
+        <table class="table table-sm table-bordered table-striped mb-0 bg-white mb-2">
+            <thead>
+            <tr class="">
+                <th class="border-bottom-0 text-secondary">Name</th>
+                <th class="border-bottom-0 text-secondary">Active?</th>
+                <th class="border-bottom-0 text-secondary">Edit</th>
+                <th class="border-bottom-0 text-secondary">Delete</th>
+                <th class="border-bottom-0 text-secondary">Started</th>
+                <th class="border-bottom-0 text-secondary">Ended</th>
+                <th class="border-bottom-0 text-secondary">Last Review</th>
+                <th class="border-bottom-0 text-secondary">Last Plan</th>
+            </tr>
+            </thead>
+            <?php foreach($problems as $problem): ?>
+            <?php $point = $problem; ?>
+            <tr class="{{$problem->is_removed ? 'on-hover-opaque' : ''}}">
+                <td>
+                    <div class="d-flex align-items-baseline">
+                        @if($problem->is_removed)
+                            <i class="text-warning-mellow fa fa-circle text-sm on-hover-opaque mr-2"></i>
+                        @else
+                            <i class="text-success fa fa-circle text-sm on-hover-opaque mr-2"></i>
+                        @endif
+                        <div>
+                            <b><?= !!@($problem->data->name) ? @($problem->data->name) : '-' ?></b>
+                            @if(!$problem->is_removed && $problem->added_in_note_id === $note->id)
+                                <div class="mt-1 text-sm text-secondary">Added during this visit
+                                    @if($problem->addition_reason_category === 'ON_INTAKE')
+                                        (existing)
+                                    @elseif($problem->addition_reason_category === 'DURING_VISIT')
+                                        (new)
+                                    @endif
+                                </div>
+                            @endif
+                            @if($problem->is_removed && ($problem->added_in_note_id !== $note->id && $problem->removed_in_note_id === $note->id))
+                                <div class="mt-1 text-sm text-secondary">Discontinued during this visit</div>
+                            @endif
+                        </div>
+                    </div>
+                </td>
+                <td>
+                    @if($problem->is_removed)
+                        NO
+                    @else
+                        <b>YES</b>
+                    @endif
+                </td>
+                <td>
+                    @if($problem->added_in_note_id === $note->id)
+                        <div moe wide>
+                            <a start show href="#" title="Edit">Edit</a>
+                            <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-problem">
+                                <input type="hidden" name="uid" value="<?= $problem->uid ?>">
+                                <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                                <p class="mb-2"><b>Update Problem</b></p>
+
+                                <input type="hidden" name="data">
+
+                                <input type="hidden" data-name="dxid" value="{{@$problem->data->dxid}}">
+                                <input type="hidden" data-name="icd-type" value="{{@$problem->data->{'icd-type'} }}">
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Problem</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset"
+                                           data-name="name"
+                                           value="{{@$problem->data->name}}"
+                                           stag-suggest
+                                           stag-suggest-ep="/fdb-dx-suggest/json">
+                                </div>
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">ICD</label>
+                                    <select data-name="icd"
+                                            class="form-control form-control-sm"
+                                            disabled>
+                                    </select>
+                                </div>
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Existing / New</label>
+                                    <select class="form-control form-control-sm" name="additionReasonCategory" required>
+                                        <option value="">-- select --</option>
+                                        <option value="ON_INTAKE" {{$problem->addition_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>Existing (Patient was already on this)</option>
+                                        <option value="DURING_VISIT" {{$problem->addition_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>New (Prescribed during this visit)</option>
+                                    </select>
+                                </div>
+
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Description</label>
+                                    <textarea rows="1" data-name="description" class="form-control form-control-sm">{{@$problem->data->description}}</textarea>
+                                </div>
+
+                                <div>
+                                    <button type="submit" class="btn-save-problem btn btn-sm btn-primary mr-2">Save</button>
+                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                </div>
+                            </form>
+                        </div>
+                    @endif
+                </td>
+                <td>
+                    @if(!$problem->is_removed)
+                        @if($problem->added_in_note_id === $note->id)
+                            <div moe>
+                                <a start show href="#" title="Delete">Delete</a>
+                                <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1">
+                                    <input type="hidden" name="uid" value="<?= $problem->uid ?>">
+                                    <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                                    <input type="hidden" name="isRemoved" value="1">
+                                    <input type="hidden" name="isRemovedDueToEntryError" value="1">
+                                    <input type="hidden" name="removalReasonMemo" value="Entry Error">
+                                    <input type="hidden" name="removalEffectiveDate" value="<?= date('Y-m-d') ?>">
+                                    <p class="mb-2"><b>Delete this problem?</b></p>
+                                    <div>
+                                        <button submit class="btn btn-sm btn-danger mr-2">Delete</button>
+                                        <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                        @else
+                            <div moe>
+                                <a start show href="#" title="Discontinue">Delete</a>
+                                <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1">
+                                    <input type="hidden" name="uid" value="<?= $problem->uid ?>">
+                                    <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                                    <input type="hidden" name="isRemoved" value="1">
+                                    <input type="hidden" name="isRemovedDueToEntryError" value="0">
+                                    <p class="mb-2"><b>Delete this problem?</b></p>
+                                    <div class="mb-2">
+                                        <label class="text-sm text-secondary mb-1">Already inactive / Mark inactive now</label>
+                                        <select class="form-control form-control-sm" name="removalReasonCategory" required>
+                                            <option value="">-- select --</option>
+                                            <option value="ON_INTAKE">Already inactive (before this visit)</option>
+                                            <option value="DURING_VISIT">Mark inactive now</option>
+                                        </select>
+                                    </div>
+                                    <div class="mb-2">
+                                        <label class="text-sm text-secondary mb-1">Removal Reason</label>
+                                        <textarea name="removalReasonMemo" class="form-control form-control-sm" rows="2"></textarea>
+                                    </div>
+                                    <div class="mb-2">
+                                        <label class="text-sm text-secondary mb-1">Removal Effective Date</label>
+                                        <input type="date" name="removalEffectiveDate"
+                                               value="<?= date('Y-m-d') ?>"
+                                               max="<?= date('Y-m-d') ?>"
+                                               class="form-control form-control-sm">
+                                    </div>
+                                    <div>
+                                        <button submit class="btn btn-sm btn-danger mr-2">Delete</button>
+                                        <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                    </div>
+                                </form>
+                            </div>
+                        @endif
+                    @endif
+                </td>
+                <td>
+                    <?= !!@($problem->data->start_date) ? @($problem->data->start_date) : '-' ?>
+                </td>
+                <td>
+                    <?= !!@($problem->removal_effective_date) ? @($problem->removal_effective_date) : '-' ?>
+                    @if(!!@($problem->removal_reason_memo))
+                        <div class="mt-1 text-sm text-secondary"><?= !!@($problem->removal_reason_memo) ? @($problem->removal_reason_memo) : '-' ?></div>
+                    @endif
+                </td>
+                <td>
+                    <!-- todo include custom review for problem -->
+                </td>
+                <td>
+                    <div class="d-flex align-items-start">
+                        <div class="flex-grow-1">
+                            <?php
+                            include resource_path('views/app/patient/segment-templates/_child_plan/last-plan.php');
+                            ?>
+                        </div>
+                        <a class="px-2 view-review-log"
+                           native target="_blank"
+                           open-in-stag-popup
+                           popup-style="stag-popup-md"
+                           title="Plan log<?= !!@($problem->data->name) ? ' for ' . @($problem->data->name) : '' ?>"
+                           href="/point/plan-log/<?= $problem->uid ?>?popupmode=1">
+                            <i class="fa fa-history"></i>
+                        </a>
+                    </div>
+                </td>
+            </tr>
+            <?php endforeach; ?>
+        </table>
+
+        <div class="d-flex align-items-center">
+            <div class="mt-1 w-100 border p-2 bg-aliceblue border-info rounded">
+                <form action="/api/visitPoint/addTopLevel" class="mcp-theme-1 w-100" id="frm-add-problem">
+                    <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                    <input type="hidden" name="category" value="PROBLEM">
+                    <input type="hidden" name="data">
+
+                    <input type="hidden" data-name="dxid">
+                    <input type="hidden" data-name="icd-type">
+
+                    <input type="hidden" name="additionReasonCategory">
+                    <input type="hidden" name="isRemoved">
+                    <input type="hidden" name="removalReasonCategory">
+                    <input type="hidden" name="isRemovedDueToEntryError">
+
+                    <p class="mb-2"><b>Add Problem</b></p>
+
+                    <div class="row">
+                        <div class="col-7">
+                            <div class="row mb-2">
+                                <div class="col-8 pr-0">
+                                    <label class="text-sm text-secondary mb-0">Name</label>
+                                    <input type="text"
+                                           data-name="name"
+                                           class="form-control form-control-sm"
+                                           stag-suggest
+                                           stag-suggest-bottom-left
+                                           stag-suggest-ep="/fdb-dx-suggest/json"
+                                           required>
+                                </div>
+                                <div class="col-4">
+                                    <label class="text-sm text-secondary mb-0">ICD</label>
+                                    <select data-name="icd"
+                                            class="form-control form-control-sm"
+                                            disabled>
+                                    </select>
+                                </div>
+                            </div>
+                            <div class="row mb-2">
+                                <div class="col-12">
+                                    <label class="text-sm text-secondary mb-0">Historic / Preexisting / New</label>
+                                    <select class="form-control form-control-sm additionReasonCategory_ui" name="additionReasonCategory_ui" required>
+                                        <option value="">-- select --</option>
+                                        <option value="HISTORIC">Historic</option>
+                                        <option value="PRE_EXISTING">Preexisting</option>
+                                        <option value="NEW">New (Found during this visit)</option>
+                                    </select>
+                                </div>
+                            </div>
+                            <div class="d-flex align-items-start mb-2">
+                                <div class="w-25">
+                                    <div class="start_date_ui" style="display: none">
+                                        <label class="text-sm text-secondary mb-0">Start Date</label>
+                                        <input type="date"
+                                               data-name="start_date"
+                                               class="form-control form-control-sm min-width-unset">
+                                    </div>
+                                </div>
+                                <div class="w-25 pl-2">
+                                    <div class="removalEffectiveDate_ui" style="display: none">
+                                        <label class="text-sm text-secondary mb-0">End Date</label>
+                                        <input type="date"
+                                               name="removalEffectiveDate"
+                                               class="form-control form-control-sm min-width-unset">
+                                    </div>
+                                </div>
+                                <div class="w-25 pl-2">
+                                    <div class="removalReasonMemo_ui" style="display: none">
+                                        <label class="text-sm text-secondary mb-0">Removal Memo</label>
+                                        <input type="text"
+                                               name="removalReasonMemo"
+                                               class="form-control form-control-sm min-width-unset">
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-5 border-left">
+
+                        </div>
+                    </div>
+
+                    <div class="d-flex align-items-center">
+                        <button type="submit" class="btn btn-sm btn-primary mr-2 my-1">Save Problem</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    (function() {
+        function init() {
+
+            let parentSegment = $('#problems-center-{{$note->id}}');
+            parentSegment.find('input[stag-suggest][data-name="name"]')
+                .off('stag-suggest-selected')
+                .on('stag-suggest-selected', (_e, _input, _data) => {
+
+                    $(_input).closest('form').find('input[data-name="dxid"]').val(_data.dxid);
+
+                    let icdSelect = $(_input).closest('form').find('[data-name="icd"]').empty().prop('disabled', true);
+
+                    $.get('/fdb-dx-icds-for-dxid?dxid=' + _data.dxid, _data => {
+                        icdSelect
+                            .empty()
+                            .append('<option value="">-- select --</option>');
+                        for (let i = 0; i < _data.length; i++) {
+                            icdSelect.append('<option value="' + _data[i].search_icd_cd + '" data-icd-type="' + _data[i].icd_cd_type + '">' + _data[i].search_icd_cd + ' (' + (_data[i].icd_cd_type === '01' ? 'ICD-9' : 'ICD-10') + ') - ' + _data[i].icd_desc + '</option>')
+                        }
+                        icdSelect.prop('disabled', false);
+                        if (_data.length === 1) {
+                            icdSelect.val(_data[0].routed_med_id).trigger('change');
+                        }
+                    }, 'json');
+                });
+
+            // on route selection
+            parentSegment.find('[data-name="icd"]')
+                .off('change')
+                .on('change', function () {
+                    $(this).closest('form').find('input[data-name="icd-type"]').val($(this).find('option:selected').attr('data-icd-type'));
+                });
+
+            parentSegment.find('.additionReasonCategory_ui')
+                .off('change')
+                .on('change', function () {
+
+                    let form = $(this).closest('form');
+
+                    // additionReasonCategory
+                    // isRemoved
+                    // removalReasonCategory
+                    form.find('[name="isRemovedDueToEntryError"]').val('0');
+
+                    form.find('.start_date_ui').hide();
+                    form.find('.removalEffectiveDate_ui').hide();
+                    form.find('.removalReasonMemo_ui').hide();
+
+                    if (this.value === 'HISTORIC') {
+                        form.find('[name="additionReasonCategory"]').val('ON_INTAKE');
+                        form.find('[name="isRemoved"]').val('1');
+                        form.find('.start_date_ui').show().find('input').val('');
+                        form.find('.removalEffectiveDate_ui').show().find('input').val('');
+                        form.find('.removalReasonMemo_ui').show().find('input').val('');
+                    } else if (this.value === 'PRE_EXISTING') {
+                        form.find('[name="additionReasonCategory"]').val('ON_INTAKE');
+                        form.find('[name="isRemoved"]').val('0');
+                        form.find('.start_date_ui').show().find('input').val('');
+                    } else if (this.value === 'NEW') {
+                        form.find('[name="additionReasonCategory"]').val('DURING_VISIT');
+                        form.find('[name="isRemoved"]').val('0');
+                        form.find('.start_date_ui').show().find('input').val('{{date('Y-m-d')}}');
+                    }
+
+                });
+
+            parentSegment.find('#frm-add-problem')
+                .off('submit')
+                .on('submit', function () {
+
+                    let form = $(this);
+
+                    if (!form[0].checkValidity()) {
+                        form[0].reportValidity();
+                        return false;
+                    }
+
+                    // add [data-name] values to payload
+                    let dataField = form.find('[name="data"]').first();
+                    let parsed = null;
+                    if (dataField.val()) {
+                        parsed = JSON.parse(dataField.val());
+                    }
+                    form.find('[data-name]').each(function () {
+                        if (!parsed) parsed = {};
+
+                        let keys = $(this).attr('data-name').split('->');
+                        let currentNode = parsed;
+                        for (let i = 0; i < keys.length; i++) {
+                            if (i !== keys.length - 1) {
+                                if (typeof currentNode[keys[i]] === 'undefined') {
+                                    currentNode[keys[i]] = {};
+                                }
+                                currentNode = currentNode[keys[i]];
+                            } else {
+                                if ($(this).is(':checkbox')) {
+                                    currentNode[keys[i]] = $(this).prop('checked');
+                                } else {
+                                    currentNode[keys[i]] = $(this).val();
+                                }
+                            }
+                        }
+
+                    });
+                    if (parsed) {
+                        dataField.val(JSON.stringify(parsed));
+                    }
+
+                    $.post(form.attr('action'), form.serialize(), _data => {
+                        if (!hasResponseError(_data)) {
+                            hideMask();
+                            refreshDynamicStagPopup();
+                            $('.visit-segment[data-segment-template-name="intake_problems"]').find('.refresh-segment').trigger('click');
+                        }
+                    }, 'json');
+                    return false;
+                });
+
+            parentSegment.find('.frm-edit-problem')
+                .off('submit')
+                .on('submit', function () {
+
+                    let form = $(this);
+
+                    if (!form[0].checkValidity()) {
+                        form[0].reportValidity();
+                        return false;
+                    }
+
+                    // add [data-name] values to payload
+                    let dataField = form.find('[name="data"]').first();
+                    let parsed = null;
+                    if (dataField.val()) {
+                        parsed = JSON.parse(dataField.val());
+                    }
+                    form.find('[data-name]').each(function () {
+                        if (!parsed) parsed = {};
+
+                        let keys = $(this).attr('data-name').split('->');
+                        let currentNode = parsed;
+                        for (let i = 0; i < keys.length; i++) {
+                            if (i !== keys.length - 1) {
+                                if (typeof currentNode[keys[i]] === 'undefined') {
+                                    currentNode[keys[i]] = {};
+                                }
+                                currentNode = currentNode[keys[i]];
+                            } else {
+                                if ($(this).is(':checkbox')) {
+                                    currentNode[keys[i]] = $(this).prop('checked');
+                                } else {
+                                    currentNode[keys[i]] = $(this).val();
+                                }
+                            }
+                        }
+
+                    });
+                    if (parsed) {
+                        dataField.val(JSON.stringify(parsed));
+                    }
+
+                    $.post(form.attr('url'), form.serialize(), _data => {
+                        if (!hasResponseError(_data)) {
+                            hideMask();
+                            refreshDynamicStagPopup();
+                            $('.visit-segment[data-segment-template-name="intake_problems"]').find('.refresh-segment').trigger('click');
+                        }
+                    }, 'json');
+                    return false;
+                });
+
+            initStagSuggest();
+        }
+
+        addMCInitializer('problems-center-{{$note->id}}', init, '#problems-center-{{$note->id}}');
+    }).call(window);
+</script>

+ 2 - 0
routes/web.php

@@ -317,6 +317,8 @@ Route::middleware('pro.auth')->group(function () {
     Route::get('/note/pdf/{note}', 'NoteController@downloadAsPdf')->name('note-pdf');
     Route::get('/segment-summary/{segment}', 'NoteController@segmentSummary')->name('segment-summary');
     Route::get('/medications-center/{patient}/{note}', 'NoteController@medicationsCenter')->name('medications-center');
+    Route::get('/problems-center/{patient}/{note}', 'NoteController@problemsCenter')->name('problems-center');
+    Route::get('/goals-center/{patient}/{note}', 'NoteController@goalsCenter')->name('goals-center');
 
     //mb claim single view
     Route::get('mb-claims/view/{mbClaim}', 'PatientController@mbClaim')->name('mb-claim');