浏览代码

Merge branch 'dev' of https://rav.triplestart.com/jmudaka/stagfe2 into dev

unknown 3 年之前
父节点
当前提交
0debe6bfbf
共有 62 个文件被更改,包括 2481 次插入2309 次删除
  1. 73 9
      app/Helpers/fdb.php
  2. 7 0
      app/Http/Controllers/ClauseController.php
  3. 21 9
      app/Http/Controllers/FDBPGController.php
  4. 18 3
      app/Http/Controllers/HomeController.php
  5. 4 0
      app/Http/Controllers/NoteController.php
  6. 4 2
      app/Http/Controllers/StatTreeController.php
  7. 6 3
      app/Http/Controllers/StatTreeLineController.php
  8. 3 0
      app/Models/Client.php
  9. 51 0
      app/Models/Point.php
  10. 1 1
      app/Models/StatTree.php
  11. 2 1
      app/Models/StatTreeLineClause.php
  12. 1 1
      config/app.php
  13. 46 4
      public/css/style.css
  14. 22 1
      public/js/stag-suggest.js
  15. 39 0
      resources/views/app/fdb-pg/allergy-vigilance.blade.php
  16. 45 0
      resources/views/app/fdb-pg/dx-vigilance.blade.php
  17. 129 0
      resources/views/app/fdb-pg/rx-vigilance.blade.php
  18. 97 490
      resources/views/app/patient/allergies-center.blade.php
  19. 16 6
      resources/views/app/patient/canvas-sections/vitals/form.blade.php
  20. 4 6
      resources/views/app/patient/care-month/_matrix.blade.php
  21. 326 0
      resources/views/app/patient/careteam-center.blade.php
  22. 83 523
      resources/views/app/patient/goals-center.blade.php
  23. 84 522
      resources/views/app/patient/medications-center.blade.php
  24. 24 12
      resources/views/app/patient/note/dashboard.blade.php
  25. 22 0
      resources/views/app/patient/note/dashboard_script.blade.php
  26. 3 3
      resources/views/app/patient/note/segment_script.blade.php
  27. 5 5
      resources/views/app/patient/note/sign-confirmation.blade.php
  28. 2 0
      resources/views/app/patient/notes.blade.php
  29. 8 3
      resources/views/app/patient/page-sections/vitals/form.blade.php
  30. 1 1
      resources/views/app/patient/prescriptions-popup/hcp-pro-form.blade.php
  31. 25 10
      resources/views/app/patient/prescriptions-popup/list-popup.blade.php
  32. 4 1
      resources/views/app/patient/prescriptions-popup/logistics-form.blade.php
  33. 1 1
      resources/views/app/patient/prescriptions-popup/pro-status-form.blade.php
  34. 1 1
      resources/views/app/patient/prescriptions-popup/transmit-form.blade.php
  35. 1 1
      resources/views/app/patient/prescriptions/hcp-pro-form.blade.php
  36. 22 8
      resources/views/app/patient/prescriptions/list.blade.php
  37. 6 1
      resources/views/app/patient/prescriptions/logistics-form.blade.php
  38. 1 1
      resources/views/app/patient/prescriptions/pro-status-form.blade.php
  39. 1 0
      resources/views/app/patient/primary-coverage.blade.php
  40. 122 510
      resources/views/app/patient/problems-center.blade.php
  41. 1 1
      resources/views/app/patient/segment-templates/chief_complaint/summary.blade.php
  42. 2 14
      resources/views/app/patient/segment-templates/intake_goals/summary.blade.php
  43. 9 1
      resources/views/app/patient/segment-templates/medrisk_vigilence/summary.blade.php
  44. 18 2
      resources/views/app/patient/segment-templates/plan_allergies/summary.blade.php
  45. 18 2
      resources/views/app/patient/segment-templates/plan_care_team/summary.blade.php
  46. 11 15
      resources/views/app/patient/segment-templates/plan_goals/summary.blade.php
  47. 21 1
      resources/views/app/patient/segment-templates/plan_medications/summary.blade.php
  48. 31 4
      resources/views/app/patient/segment-templates/plan_problems/summary.blade.php
  49. 8 3
      resources/views/app/patient/segment-templates/vitals/edit.blade.php
  50. 221 0
      resources/views/app/patient/wizard-partials/common-fields.blade.php
  51. 383 0
      resources/views/app/patient/wizard-partials/common-script.blade.php
  52. 2 2
      resources/views/app/stat-tree/clauses/list.blade.php
  53. 1 1
      resources/views/app/stat-tree/clauses/replace-all.blade.php
  54. 0 2
      resources/views/app/stat-tree/stat-tree-lines/single.blade.php
  55. 0 2
      resources/views/app/stat-tree/stat-trees/create.blade.php
  56. 0 2
      resources/views/app/stat-tree/stat-trees/list.blade.php
  57. 0 2
      resources/views/app/stat-tree/stat-trees/single.blade.php
  58. 124 116
      resources/views/app/stat-tree/stat-trees/sub/dashboard.blade.php
  59. 32 0
      resources/views/layouts/patient.blade.php
  60. 2 0
      resources/views/layouts/template.blade.php
  61. 5 0
      routes/web.php
  62. 261 0
      spec/stat-tree-report-builder-spec.txt

+ 73 - 9
app/Helpers/fdb.php

@@ -62,7 +62,7 @@ if(!function_exists('precautions_info')) {
 }
 
 if(!function_exists('contraindications_info')) {
-    function contraindications_info($_drugs) {
+    function contraindications_info($_drugs, $_problems) {
 
         $result = [];
 
@@ -99,20 +99,28 @@ ORDER BY r1.routed_med_id, r3.dxid_desc56, r2.ddxcn_sl
                 $ciMap[$rxMap[$ci->routed_med_id]] = [];
             }
 
+            $flag = false;
+            foreach ($_problems as $_problem) {
+                if($_problem->data->dxid === $ci->dxid) {
+                    $flag = true;
+                    break;
+                }
+            }
+
             $ciMap[$rxMap[$ci->routed_med_id]][] = [
+                "dxid" => $ci->dxid,
                 "dxid_desc56" => $ci->dxid_desc56,
+                "flag" => $flag
             ];
         }
 
-        $result = $ciMap;
-
-        return $result;
+        return $ciMap;
 
     }
 }
 
 if(!function_exists('drug_allergy_info')) {
-    function drug_allergy_info($_drugs, $_allergies) {
+    function drug_allergy_info($_drugs, $_allergies, $_rxPivot = true) {
         $output = [];
 
         /*
@@ -134,23 +142,27 @@ if(!function_exists('drug_allergy_info')) {
             foreach ($_drugs as $rxItem) {
                 if($allergy->data->damConceptIdType == 6) { // ingredient
                     if (drugAllergyIngredientAllergenVsSingleRx($allergy, $rxItem)) {
-                        $output[] = "<b>{$rxItem->data->name}</b> can cause allergic reactions since the patient is allergic to <b>{$allergy->data->name}</b>.";
+                        $output[] = "<b>{$rxItem->data->name}</b> can cause allergic reactions " . ($_rxPivot ? 'since' : 'if') . " the patient is allergic to <b>{$allergy->data->name}</b>.";
                     }
                 }
                 else if($allergy->data->damConceptIdType == 2) { // medication
                     if (drugAllergyMedicationAllergenVsSingleRx($allergy, $rxItem)) {
-                        $output[] = "<b>{$rxItem->data->name}</b> can cause allergic reactions since the patient is allergic to <b>{$allergy->data->name}</b>.";
+                        $output[] = "<b>{$rxItem->data->name}</b> (medication) can cause allergic reactions " . ($_rxPivot ? 'since' : 'if') . " the patient is allergic to <b>{$allergy->data->name}</b>.";
                     }
                 }
                 else if($allergy->data->damConceptIdType == 1) { // allergen group
                     if (drugAllergyGroupAllergenVsSingleRx($allergy, $rxItem)) {
-                        $output[] = "<b>{$rxItem->data->name}</b> can cause allergic reactions since the patient is allergic to <b>{$allergy->data->name}</b>.";
+                        $output[] = "<b>{$rxItem->data->name}</b> can cause allergic reactions " . ($_rxPivot ? 'since' : 'if') . " the patient is allergic to <b>{$allergy->data->name}</b>.";
                     }
                 }
             }
         }
 
-        return implode("<br>", $output);
+        if(!count($output)) return '';
+
+        return "<ol class='pl-0 ml-3 mb-0'>" . implode("", array_map(function ($_x) {
+                return "<li class='mb-1'>" . $_x . "</li>";
+            }, $output)) . "</ol>";
     }
 }
 if(!function_exists('drugAllergyIngredientAllergenVsSingleRx')) {
@@ -307,6 +319,31 @@ if(!function_exists('drug_drug_interaction_info')) {
         return implode("<br>", $output);
     }
 }
+if(!function_exists('drug_drug_interaction_info_with_pivot')) {
+    function drug_drug_interaction_info_with_pivot($_pivot, $_drugs) {
+
+        if(!count($_drugs)) return "";
+
+        $leftIndex = 0;
+
+        $output = [];
+
+        for ($i=0; $i<count($_drugs); $i++) {
+            $output[] = drugDrugInteractionSinglePair($_pivot, $_drugs[$i]);
+        }
+
+        $output = array_filter($output, function($_x) {
+            return !!$_x;
+        });
+
+        if(!count($output)) return '';
+
+        return "<ol class='pl-0 ml-3 mb-0'>" . implode("", array_map(function ($_x) {
+                return "<li class='mb-1'>" . $_x . "</li>";
+            }, $output)) . "</ol>";
+
+    }
+}
 if(!function_exists('drugDrugInteractionSinglePair')) {
     function drugDrugInteractionSinglePair($_rx1, $_rx2)
     {
@@ -492,6 +529,33 @@ if(!function_exists('duplicate_therapy_info')) {
     }
 }
 
+if(!function_exists('duplicate_therapy_info_with_pivot')) {
+    function duplicate_therapy_info_with_pivot($_pivot, $_drugs) {
+
+        $_pivot->dpt = getDptClassFromGcnSeqNo($_pivot->data->gcnSeqno);
+
+        $dptClasses = [];
+        foreach ($_drugs as $drug) {
+            $drug->dpt = getDptClassFromGcnSeqNo($drug->data->gcnSeqno);
+        }
+
+        $leftIndex = 0;
+        $matches = [];
+        for ($i = 0; $i < count($_drugs); $i++) {
+            $compareResult = compareDPTs($_pivot->dpt, $_drugs[$i]->dpt);
+            foreach ($compareResult as $c) {
+                $matches[] = "<b>{$_pivot->data->name}</b> and <b>{$_drugs[$i]->data->name}</b> both participate in the duplicate therapy class <b>{$c->dpt_class_desc}</b> (duplicates allowed: {$c->dpt_allowance})";
+            }
+        }
+
+        if(!count($matches)) return '';
+
+        return "<ol class='pl-0 ml-3 mb-0'>" . implode("", array_map(function ($_x) {
+                return "<li class='mb-1'>" . $_x . "</li>";
+            }, $matches)) . "</ol>";
+    }
+}
+
 if (!function_exists('getDptClassFromGcnSeqNo')) {
     function getDptClassFromGcnSeqNo($_gcnSeqNo)
     {

+ 7 - 0
app/Http/Controllers/ClauseController.php

@@ -7,6 +7,9 @@ use App\Models\Clause;
 use Illuminate\Http\JsonResponse;
 use Illuminate\Support\Facades\DB;
 use Ramsey\Uuid\Uuid;
+use App\Models\StatTree;
+use App\Models\StatTreeLine;
+use App\Models\StatTreeLineClause;
 
 class ClauseController extends Controller
 {
@@ -33,6 +36,10 @@ class ClauseController extends Controller
         $rows = json_decode($data);
 
         Clause::truncate();
+        //Should we truncate related data?
+        StatTree::truncate();
+        StatTreeLine::truncate();
+        StatTreeLineClause::truncate();
 
         for($i = 0; $i < count($rows); $i++){
             $row = $rows[$i];

+ 21 - 9
app/Http/Controllers/FDBPGController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Models\Client;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\DB;
 
@@ -244,8 +245,9 @@ ORDER BY r1.dam_concept_id_desc
         $term = $request->input('term') ? trim($request->input('term')) : '';
         if (empty($term)) return '';
         $matches = DB::connection('pgsql_fdb')->select("
-SELECT r1.dam_concept_id, r1.dam_concept_id_typ, r1.dam_concept_id_desc as text
-FROM rdamca0_concept r1
+SELECT r1.dam_concept_id, r1.dam_concept_id_typ, r1.dam_concept_id_desc as text,
+r2.dam_concept_id_typ_desc as sub_text
+FROM rdamca0_concept r1 join rdamcd0_picklist_con_typ_desc r2 on r1.dam_concept_id_typ = r2.dam_concept_id_typ
 WHERE (r1.dam_concept_id_desc ILIKE :term)
 ORDER BY r1.dam_concept_id_desc
 ",
@@ -699,21 +701,21 @@ WHERE r1.side_a_gcn_seqno in ($gcnSeqnos) AND r1.side_b_gcn_seqno in ($gcnSeqnos
     }
 
         private function getDptClassFromGcnSeqNo($_gcnSeqNo) {
-            return DB::connection('pgsql_fdb')->select("
+        return DB::connection('pgsql_fdb')->select("
     SELECT distinct r1.dpt_class_id, r2.dpt_allowance, r2.dpt_class_desc
     FROM RDPTGC0_GCNSEQNO_LINK r1
     JOIN RDPTCL0_CLASS_ID r2 on r1.dpt_class_id = r2.dpt_class_id
     WHERE r1.gcn_seqno = :gcnSeqNo
                 ",
-                ['gcnSeqNo' => $_gcnSeqNo]
-            );
-        }
+            ['gcnSeqNo' => $_gcnSeqNo]
+        );
+    }
 
         private function compareDPTs($_dptArray1, $_dptArray2) {
         $output = [];
-        for ($i=0; $i<count($_dptArray1); $i++) {
-            for ($j=0; $j<count($_dptArray2); $j++) {
-                if($_dptArray1[$i]->dpt_class_id == $_dptArray2[$j]->dpt_class_id) {
+        for ($i = 0; $i < count($_dptArray1); $i++) {
+            for ($j = 0; $j < count($_dptArray2); $j++) {
+                if ($_dptArray1[$i]->dpt_class_id == $_dptArray2[$j]->dpt_class_id) {
                     $output[] = json_decode(json_encode([
                         "dpt_allowance" => $_dptArray1[$i]->dpt_allowance,
                         "dpt_class_desc" => $_dptArray1[$i]->dpt_class_desc
@@ -723,4 +725,14 @@ WHERE r1.side_a_gcn_seqno in ($gcnSeqnos) AND r1.side_b_gcn_seqno in ($gcnSeqnos
         }
         return $output;
     }
+
+    public function rxVigilance(Request $request, Client $patient) {
+        return view('app.fdb-pg.rx-vigilance', compact('patient'));
+    }
+    public function dxVigilance(Request $request, Client $patient) {
+        return view('app.fdb-pg.dx-vigilance', compact('patient'));
+    }
+    public function allergyVigilance(Request $request, Client $patient) {
+        return view('app.fdb-pg.allergy-vigilance', compact('patient'));
+    }
 }

+ 18 - 3
app/Http/Controllers/HomeController.php

@@ -1592,10 +1592,25 @@ WHERE measurement.label NOT IN ('SBP', 'DBP')
     {
         $term = $request->input('term') ? trim($request->input('term')) : '';
         if (empty($term)) return '';
+
+        $terms = explode(' ', $term);
+        $terms = array_filter($terms, function($_x) {
+            return !!trim($_x);
+        });
+
+        $whereCondition = [];
+        $whereParams = [];
+        for ($i = 0; $i < count($terms); $i++) {
+            $whereCondition[] = "(name ILIKE :term{$i} OR address_city ILIKE :term{$i} OR address_state ILIKE :term{$i} OR address_zip ILIKE :term{$i})";
+            $whereParams["term{$i}"] = '%' . $terms[$i] . '%';
+        }
+        $whereCondition = implode(" AND ", $whereCondition);
+
         $matches = DB::select(
-            "SELECT (name || ' ' || address_city || ' ' || address_state) as text, name, address_city as city, address_state as state, address_zip as zip, phone, fax FROM facility WHERE name ILIKE :term ORDER BY name",
-            ['term' => '%' . $term . '%']
-        );
+            "SELECT (name || ' ' || address_city || ' ' || address_state || ' ' || address_zip) as text, 
+       address_line1 as text2,
+       name, address_city as city, address_state as state, address_zip as zip, phone, fax FROM facility 
+       WHERE {$whereCondition} ORDER BY name", $whereParams);
         return json_encode([
             "success" => true,
             "data" => $matches

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

@@ -332,6 +332,10 @@ class NoteController extends Controller
         return view('app.patient.allergies-center', compact('patient', 'note'));
     }
 
+    public function careteamCenter(Request $request, Client $patient, Note $note) {
+        return view('app.patient.careteam-center', compact('patient', 'note'));
+    }
+
     // TODO move to utility
     private function callJava($request, $endPoint, $data, $guestAccessCode = null)
     {

+ 4 - 2
app/Http/Controllers/StatTreeController.php

@@ -71,6 +71,7 @@ class StatTreeController extends Controller
         $rows = json_decode($data, true);
 
         $statTree = StatTree::where('id', $statTreeID)->first();
+        $model = $statTree->model;
         DB::beginTransaction();
         DB::statement("DELETE FROM stat_tree_line WHERE stat_tree_id = :stat_tree_id", ['stat_tree_id' => $statTree->id]);
 
@@ -92,10 +93,10 @@ class StatTreeController extends Controller
                 $cell = $row[$i];
                 if(!$cell || empty($cell)) continue;
 
-                $clause = Clause::where('label', $cell)->first();
+                $clause = Clause::where('label', $cell)->where('model', 'ilike', $model)->first();
                 if(!$clause){
                     DB::rollBack();
-                    return $this->fail('No clause record found!');
+                    return $this->fail('No clause record found for ' . $cell);
                 }
                 $nextStatLineClauseId = DB::select("select nextval('stat_tree_line_clause_id_seq')");
                 $statTreeLineClause = new StatTreeLineClause;
@@ -105,6 +106,7 @@ class StatTreeController extends Controller
                 $statTreeLineClause->clause_id = $clause->id;
                 $statTreeLineClause->clause_label = $cell;
                 $statTreeLineClause->position_index = $i;
+                $statTreeLineClause->detail_json = json_encode(['model' => $model]);
                 $statTreeLineClause->save();
 
             }

+ 6 - 3
app/Http/Controllers/StatTreeLineController.php

@@ -7,6 +7,7 @@ use Illuminate\Http\Request;
 use App\Models\StatTree;
 use App\Models\StatTreeLine;
 use App\Models\Client;
+use App\Models\Pro;
 
 class StatTreeLineController extends Controller
 {
@@ -58,7 +59,7 @@ class StatTreeLineController extends Controller
         $statTreeLine = StatTreeLine::where('id', $statTreeLineID)->first();
         if (!$statTreeLine) return $this->fail('Invalid stat tree line!');
 
-        $query = $this->applyStatTreeLineQueryClauses($statTreeLine);
+        $query = $this->applyStatTreeLineQueryClauses($statTreeLine);        
         if ($query) {
             $statTreeLine->last_refresh_count = $query->count();
             $statTreeLine->save();
@@ -73,10 +74,12 @@ class StatTreeLineController extends Controller
 
         $model = $statTreeLine->statTree->model;
         $query = null;
-        if ($model === 'client') {
+        if (strcasecmp($model, 'client') == 0) {
             $query = Client::query();
         }
-
+        if (strcasecmp($model, 'pro') == 0) {
+            $query = Pro::query();
+        }
         if (!$query) return null;
 
         $clauses = [];

+ 3 - 0
app/Models/Client.php

@@ -93,6 +93,7 @@ class Client extends Model
     public function notes()
     {
         return $this->hasMany(Note::class, 'client_id', 'id')
+            ->where('id', '<>', $this->core_note_id)
             ->orderBy('effective_dateest', 'desc');
     }
 
@@ -129,6 +130,7 @@ class Client extends Model
     {
         return $this->hasMany(Note::class, 'client_id', 'id')
             ->where('is_cancelled', false)
+            ->where('id', '<>', $this->core_note_id)
             ->orderBy('effective_dateest', 'desc');
     }
 
@@ -136,6 +138,7 @@ class Client extends Model
     {
         return $this->hasMany(Note::class, 'client_id', 'id')
             ->where('is_cancelled', true)
+            ->where('id', '<>', $this->core_note_id)
             ->orderBy('effective_dateest', 'desc');
     }
 

+ 51 - 0
app/Models/Point.php

@@ -166,4 +166,55 @@ class Point extends Model
         }
         return $points;
     }
+
+    public static function getPointsOfCategoryExtended(Client $_patient, String $_category, Note $_note) {
+        $points = Point
+            ::where('client_id', $_patient->id)
+            ->where('category', $_category)
+            ->where(function ($q) use($_note) {
+                $q
+                    ->where('is_removed_due_to_entry_error', false)
+                    ->orWhere('removed_in_note_id', '<>', $_note->id);
+            })
+            ->orderBy('is_removed')
+            ->orderBy('added_in_note_id', 'DESC')
+            ->orderBy('removal_effective_date', 'DESC')
+            ->orderByRaw('removed_in_note_id DESC NULLS FIRST')
+            ->orderBy('created_at')
+            ->get();
+
+        $pointsByType = [
+            "new" => [],
+            "preExisting" => [],
+            "historic" => [],
+            "eeFromOtherNote" => []
+        ];
+
+        foreach ($points as $point) {
+            if ($point->data) {
+                $point->data = json_decode($point->data);
+            }
+
+            if(!$point->is_removed && $point->added_in_note_id === $_note->id) {
+                $point->state = 1;
+                $pointsByType["new"][] = $point;
+            }
+            elseif(!$point->is_removed && $point->added_in_note_id !== $_note->id) {
+                $point->state = 2;
+                $pointsByType["preExisting"][] = $point;
+            }
+            elseif($point->is_removed && !$point->is_removed_due_to_entry_error) {
+                $point->state = 3;
+                $pointsByType["historic"][] = $point;
+            }
+            elseif($point->is_removed_due_to_entry_error) {
+                $point->state = 4;
+                $pointsByType["eeFromOtherNote"][] = $point;
+            }
+        }
+
+        $points = array_merge($pointsByType["new"], $pointsByType["preExisting"], $pointsByType["historic"], $pointsByType["eeFromOtherNote"]);
+
+        return $points;
+    }
 }

+ 1 - 1
app/Models/StatTree.php

@@ -17,6 +17,6 @@ class StatTree extends Model
     }
 
     public function lines(){
-        return $this->hasMany(StatTreeLine::class, 'stat_tree_id', 'id');
+        return $this->hasMany(StatTreeLine::class, 'stat_tree_id', 'id')->orderBy('id', 'ASC');
     }
 }

+ 2 - 1
app/Models/StatTreeLineClause.php

@@ -11,7 +11,8 @@ class StatTreeLineClause extends Model
     public $timestamps = false;
 
     public function clause(){
-        return $this->hasOne(Clause::class, 'id', 'clause_id');
+        $detailJson = json_decode($this->detail_json);
+        return $this->hasOne(Clause::class, 'label', 'clause_label')->where('model', 'ilike', $detailJson->model);
     }
 
 }

+ 1 - 1
config/app.php

@@ -65,7 +65,7 @@ return [
 
     'hrm2_url' => env('HRM2_URL'),
 
-    'asset_version' => 19,
+    'asset_version' => 20,
 
     'temp_dir' => env('TEMP_DIR'),
 

+ 46 - 4
public/css/style.css

@@ -231,6 +231,9 @@ body>nav.navbar {
 [moe][wide] form, [moe][wide] [url] {
     width: 550px;
 }
+[moe][huge] form, [moe][huge] [url] {
+    width: 750px;
+}
 [moe][bottom] form {
     bottom: 100%;
 }
@@ -591,15 +594,15 @@ input.search_field, textarea.search_field {
     z-index: 9999;
 }
 .suggestions-outer {
-    top: calc(100% + 2px);
+    top: calc(100% + 1px);
     background: #fff;
     border-radius: 3px;
     border: 1px solid #ccc;
     z-index: 9999;
     max-height: 220px;
-    overflow-y: auto;
-    min-width: calc(100% - 0.5rem);
-    right: 0.5rem;
+    overflow-y: overlay;
+    min-width: 100%;
+    right: 0;
 }
 [stag-suggest-bottom-left]~.stag-suggestions-container .suggestions-outer {
     bottom: 30px;
@@ -1482,6 +1485,8 @@ table.table-edit-sheet .ql-editor[contenteditable] {
     max-width: 250px;
     box-shadow: 0 0 3px #ddd;
     border-top: 0;
+    max-height: 200px;
+    overflow-y: auto;
 }
 .data-option-list>div {
     cursor: pointer;
@@ -1621,6 +1626,9 @@ canvas.pdf-viewer-page.pdf-preview-page {
 .bg-aliceblue {
     background: aliceblue !important;
 }
+.text-danger-dark {
+    color: #8b1621 !important;
+}
 .filter-head input[type="date"]::-webkit-calendar-picker-indicator {
     display: none;
     -webkit-appearance: none;
@@ -1961,6 +1969,9 @@ table.dashboard-stats-table th {
 .min-height-300px {
     min-height: 300px;
 }
+.max-height-400px {
+    max-height: 400px;
+}
 .min-height-500px {
     min-height: 500px;
 }
@@ -1983,6 +1994,11 @@ body.in-iframe .main-row > .sidebar {
 .strike-through {
     text-decoration: line-through;
 }
+.visit-segment .strike-through {
+    color: #8b1621 !important;
+    text-decoration: none !important;
+    opacity: 0.9;
+}
 
 /* visit-moe */
 [visit-moe] [url]:not([show]){
@@ -2176,4 +2192,30 @@ body.in-iframe .main-row > .sidebar {
 }
 .visit-segment tr:hover .vitals-copy-trigger {
     display: flex;
+}
+[tab-links] {
+
+}
+[tab-links] [tab-link] {
+    padding: 0.5rem 0.75rem;
+    border: 1px solid #ccc;
+    color: #222;
+    background: #eee;
+    text-decoration: none;
+}
+[tab-links] [tab-link]:not(:last-child) {
+    border-right: 0;
+}
+[tab-links] [tab-link]:not(.tab-link-active):hover {
+    background: #f7f7f7;
+}
+[tab-links] [tab-link].tab-link-active {
+    font-weight: bold;
+    background: #fff;
+}
+tr.relevant-to-visit td:nth-child(1) {
+    background: aliceblue;
+}
+tr.relevant-to-visit td:nth-child(2) {
+    color: #17a2b8;
 }

+ 22 - 1
public/js/stag-suggest.js

@@ -18,7 +18,7 @@
         var lastTerm = '';
         var returnedFunction = debounce(function (elem) {
             let term = elem.val();
-            if (!!term && lastTerm !== term) {
+            if (!!term) {
                 let ep = $(elem).attr('stag-suggest-ep');
                 $.get(ep + '?term=' + $.trim(term), function (_data) {
 
@@ -53,6 +53,23 @@
                             }
                             item.data('suggest-data', _data.data[i]);
                             item.html(_data.data[i].text);
+                            if(_data.data[i].sub_text) {
+                                item.append($('<span/>')
+                                    .addClass('ml-1 text-sm text-secondary')
+                                    .append('(')
+                                    .append(_data.data[i].sub_text)
+                                    .append(')')
+                                );
+                            }
+                            if(_data.data[i].text2) {
+                                item.append($('<div/>')
+                                    .addClass('text-sm text-secondary')
+                                    .html(_data.data[i].text2)
+                                );
+                            }
+                            if(_data.data[i].tooltip) {
+                                item.attr('title', _data.data[i].tooltip);
+                            }
                             suggestionsOuter.append(item);
                         }
                     }
@@ -192,6 +209,10 @@
             .off('mousedown.stag-suggest-outer-click')
             .on('mousedown.stag-suggest-outer-click', function (_e) {
                 let elem = $(_e.target);
+                // if mousedown is on the input whose stag-suggest is on display, ignore
+                if(elem.is('[stag-suggest]') && elem.next('.stag-suggestions-container').find('>.suggestions-outer').is(':visible')) {
+                    return false;
+                }
                 if(!elem.is('.stag-suggestions-container') && !elem.closest('.stag-suggestions-container').length) {
                     if($('.stag-suggestions-container .suggestions-outer:not(.d-none)').length) {
                         $('.stag-suggestions-container .suggestions-outer').addClass('d-none');

+ 39 - 0
resources/views/app/fdb-pg/allergy-vigilance.blade.php

@@ -0,0 +1,39 @@
+<?php
+
+// info from patient chart
+$drugs = \App\Models\Point::getPointsOfCategory($patient, "MEDICATION");
+
+// filter out drugs without fdb info on them
+$drugs = $drugs->filter(function ($_drug) {
+    return @$_drug->data &&
+        $_drug->data->name &&
+        $_drug->data->medId &&
+        $_drug->data->routedMedId &&
+        $_drug->data->routedDosageFormMedId &&
+        $_drug->data->gcnSeqno;
+});
+
+// get pivot allergy
+$pivotAllergy = json_decode(json_encode([
+    "data" => [
+        "name" => request()->input('name'),
+        "damConceptId" => request()->input('damConceptId'),
+        "damConceptIdType" => request()->input('damConceptIdType')
+    ]
+]));
+
+// dam
+$dam = drug_allergy_info($drugs, [$pivotAllergy], false);
+
+?>
+
+@if(!!$dam)
+    <div class="p-3 mb-3 mt-2 border bg-white mr-0">
+        <p class="font-weight-bold m-0 font-size-14 text-info">Drug Allergy Notes</p>
+        <div class="mt-3">
+            {!! $dam !!}
+        </div>
+    </div>
+@endif
+
+

+ 45 - 0
resources/views/app/fdb-pg/dx-vigilance.blade.php

@@ -0,0 +1,45 @@
+<?php
+
+// info from patient chart
+$drugs = \App\Models\Point::getPointsOfCategory($patient, "MEDICATION");
+
+// filter out drugs without fdb info on them
+$drugs = $drugs->filter(function ($_drug) {
+    return @$_drug->data &&
+        $_drug->data->name &&
+        $_drug->data->medId &&
+        $_drug->data->routedMedId &&
+        $_drug->data->routedDosageFormMedId &&
+        $_drug->data->gcnSeqno;
+});
+
+// get pivot drug
+$pivotDx = json_decode(json_encode([
+    "data" => [
+        "name" => request()->input('name'),
+        "dxid" => request()->input('dxid'),
+    ]
+]));
+
+// contraindications
+// TODO: check against patient's dx
+$contraindications = contraindications_info($drugs, [$pivotDx]);
+
+?>
+
+@if(count($contraindications))
+    <div class="p-3 mb-3 mt-2 border bg-white mr-0">
+        <p class="font-weight-bold m-0 font-size-14 text-info">Contraindications</p>
+        @foreach($contraindications as $drug => $contraindication)
+            <div class="mt-3">
+                <p class="font-weight-bold mb-2">{{$drug}}</p>
+                <div class="flex-grow-1 d-inline-flex flex-wrap">
+                    @foreach($contraindication as $ci)
+                        <span class="mr-2 px-2 py-0 border bg-light mb-1 {{@$ci['flag'] ? 'text-danger border-danger' : ''}}">{{$ci['dxid_desc56']}}</span>
+                    @endforeach
+                </div>
+            </div>
+        @endforeach
+    </div>
+@endif
+

+ 129 - 0
resources/views/app/fdb-pg/rx-vigilance.blade.php

@@ -0,0 +1,129 @@
+<?php
+
+// info from patient chart
+$drugs = \App\Models\Point::getPointsOfCategory($patient, "MEDICATION");
+$allergies = \App\Models\Point::getPointsOfCategory($patient, "ALLERGY");
+$problems = \App\Models\Point::getPointsOfCategory($patient, "PROBLEM");
+
+// filter out drugs without fdb info on them
+$drugs = $drugs->filter(function ($_drug) {
+    return @$_drug->data &&
+        $_drug->data->name &&
+        $_drug->data->medId &&
+        $_drug->data->routedMedId &&
+        $_drug->data->routedDosageFormMedId &&
+        $_drug->data->gcnSeqno;
+});
+
+// filter out allergies without fdb info on them
+$allergies = $allergies->filter(function ($_allergy) {
+    return @$_allergy->data &&
+        $_allergy->data->name &&
+        $_allergy->data->damConceptId &&
+        $_allergy->data->damConceptIdType;
+});
+
+// filter out problems without fdb info on them
+$problems = $problems->filter(function ($_problem) {
+    return @$_problem->data &&
+        $_problem->data->name &&
+        $_problem->data->dxid;
+});
+
+// get pivot drug
+$pivotRx = json_decode(json_encode([
+    "data" => [
+        "name" => request()->input('name'),
+        "medId" => request()->input('medId'),
+        "routedMedId" => request()->input('routedMedId'),
+        "routedDosageFormMedId" => request()->input('routedDosageFormMedId'),
+        "gcnSeqno" => request()->input('gcnSeqno'),
+    ]
+]));
+
+// other drugs
+$otherDrugs = $drugs->filter(function ($_drug) {
+    return $_drug->data->medId !== request()->input('medId') ||
+        $_drug->data->gcnSeqno !== request()->input('gcnSeqno');
+});
+
+// side effects
+$sideeffects = side_effects_info([$pivotRx]);
+
+// contraindications
+// TODO: check against patient's dx
+$contraindications = contraindications_info([$pivotRx], $problems);
+
+// dpt
+// TODO: check against patient's other drugs
+$dptInfo = duplicate_therapy_info_with_pivot($pivotRx, $otherDrugs);
+
+// ddi
+// TODO: check against patient's other drugs
+$ddi = drug_drug_interaction_info_with_pivot($pivotRx, $otherDrugs);
+
+// dam
+$dam = drug_allergy_info([$pivotRx], $allergies);
+
+?>
+
+@if(!!$dptInfo)
+    <div class="p-3 mb-3 mt-2 border bg-white mr-0">
+        <p class="font-weight-bold m-0 font-size-14 text-info">Duplicate Therapy Notes</p>
+        <div class="mt-3">
+            {!! $dptInfo !!}
+        </div>
+    </div>
+@endif
+
+@if(!!$dam)
+    <div class="p-3 mb-3 mt-2 border bg-white mr-0">
+        <p class="font-weight-bold m-0 font-size-14 text-info">Drug Allergy Notes</p>
+        <div class="mt-3">
+            {!! $dam !!}
+        </div>
+    </div>
+@endif
+
+@if(!!$ddi)
+    </div>
+    <div class="p-3 mb-3 mt-2 border bg-white mr-0">
+        <p class="font-weight-bold m-0 font-size-14 text-info">Drug-Drug Interaction Notes</p>
+        <div class="mt-3">
+            {!! $ddi !!}
+        </div>
+    </div>
+@endif
+
+@if(count($sideeffects))
+    <div class="p-3 mb-3 mt-2 border bg-white mr-0">
+        <p class="font-weight-bold m-0 font-size-14 text-info">Side Effects</p>
+        @foreach($sideeffects as $drug => $sideeffect)
+            <div class="mt-3">
+                <p class="font-weight-bold mb-2">{{$drug}}</p>
+                <div class="flex-grow-1 d-inline-flex flex-wrap">
+                    @foreach($sideeffect as $se)
+                        <span class="mr-2 px-2 py-0 border bg-light mb-1">{{$se['dxid_desc56']}}</span>
+                    @endforeach
+                </div>
+            </div>
+        @endforeach
+    </div>
+@endif
+
+@if(count($contraindications))
+    <div class="p-3 mb-3 mt-2 border bg-white mr-0">
+        <p class="font-weight-bold m-0 font-size-14 text-info">Contraindications</p>
+        @foreach($contraindications as $drug => $contraindication)
+            <div class="mt-3">
+                <p class="font-weight-bold mb-2">{{$drug}}</p>
+                <div class="flex-grow-1 d-inline-flex flex-wrap">
+                    @foreach($contraindication as $ci)
+                        <span class="mr-2 px-2 py-0 border bg-light mb-1 {{@$ci['flag'] ? 'text-danger border-danger' : ''}}">{{$ci['dxid_desc56']}}</span>
+                    @endforeach
+                </div>
+            </div>
+        @endforeach
+    </div>
+@endif
+

+ 97 - 490
resources/views/app/patient/allergies-center.blade.php

@@ -8,20 +8,7 @@ use App\Models\Segment;
 /** @var Client $patient */
 /** @var Note $note */
 
-$points = Point
-    ::where('client_id', $patient->id)
-    ->where('category', 'ALLERGY')
-    ->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);
-    }
-}
-$allergies = $points;
+$allergies = Point::getPointsOfCategoryExtended($patient, 'ALLERGY', $note);
 ?>
 
 <div class="mt-3 p-3 border-top min-height-500px" id="allergies-center-{{$note->id}}">
@@ -36,24 +23,24 @@ $allergies = $points;
                 @endif
                 <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">Started</th>
                 <th class="border-bottom-0 text-secondary">Ended</th>
-                <th class="border-bottom-0 text-secondary w-25">Last Review</th>
-                <th class="border-bottom-0 text-secondary w-25">Last Plan</th>
+                <th class="border-bottom-0 text-secondary w-25">Review</th>
+                <th class="border-bottom-0 text-secondary w-25">Plan</th>
+                <th class="border-bottom-0 text-secondary">Edit</th>
             </tr>
             </thead>
-            <?php $prevRowRemoved = -1; ?>
+            <?php $prevRowState = -1; ?>
             <?php foreach($allergies as $allergy): ?>
             <?php $point = $allergy; ?>
-            @if($prevRowRemoved !== -1 && $prevRowRemoved !== $allergy->is_removed)
+            @if($prevRowState !== -1 && $prevRowState !== $allergy->state)
                 <tr>
                     <td colspan="9" class="px-0 pt-1 pb-0 on-hover-opaque bg-secondary"></td>
                 </tr>
             @endif
-            <?php $prevRowRemoved = $allergy->is_removed; ?>
+            <?php $prevRowState = $allergy->state; ?>
             <?php $rel = $allergy->relevanceToNote($note); ?>
-            <tr class="">
+            <tr class="{{$rel ? 'relevant-to-visit' : ''}}">
                 @if($patient->core_note_id !== $note->id)
                 <td class="text-center">
                     <a href="#" class="toggle-relevance"
@@ -71,10 +58,14 @@ $allergies = $points;
                 @endif
                 <td>
                     <div class="d-flex align-items-baseline">
-                        @if($allergy->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>
+                        @if($allergy->state === 1)
+                            <i class="text-success fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($allergy->state === 2)
+                            <i class="text-info fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($allergy->state === 3)
+                            <i class="text-warning-mellow fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($allergy->state === 4)
+                            <i class="text-secondary fa fa-circle text-sm on-hover-opaque mr-2"></i>
                         @endif
                         <div>
                             <b><?= !!@($allergy->data->name) ? @($allergy->data->name) : '-' ?></b>
@@ -113,135 +104,11 @@ $allergies = $points;
                         <b>YES</b>
                     @endif
                 </td>
-                <td>
-                    <div moe wide>
-                        <a start show href="#" title="Edit">Edit</a>
-                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-allergy">
-                            <input type="hidden" name="uid" value="<?= $allergy->uid ?>">
-                            <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
-                            <p class="mb-2"><b>Update Allergy</b></p>
-
-                            @if($allergy->added_in_note_id === $note->id)
-
-                                <input type="hidden" name="data">
-
-                                <input type="hidden" data-name="damConceptId" value="{{@$allergy->data->damConceptId}}">
-                                <input type="hidden" data-name="damConceptIdType" value="{{@$allergy->data->damConceptIdType}}">
-
-                                <div class="mb-2">
-                                    <label class="text-sm mb-0">Name</label>
-                                    <input type="text" data-name="name" class="form-control form-control-sm"
-                                           value="{{@$allergy->data->name}}"
-                                           stag-suggest
-                                           stag-suggest-ep="/fdb-allergy-suggest/json">
-                                </div>
-
-                                <div class="row mb-2">
-                                    <div class="col-6 pr-0">
-                                        <label class="text-sm mb-0">Start Date</label>
-                                        <input type="date"
-                                               data-name="start_date"
-                                               value="{{@$allergy->data->start_date}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                    <div class="col-6">
-                                        <label class="text-sm mb-0">Added By</label>
-                                        <input type="text"
-                                               data-name="prescriber"
-                                               value="{{@$allergy->data->prescriber}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                </div>
-
-                            @else
-
-                                <div class="mb-2 bg-light p-2 border">
-                                    <p class="mb-1 font-weight-bold">
-                                        {{ @$allergy->data->name }}
-                                    </p>
-                                    @if($patient->core_note_id !== $note->id)
-                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the allergy was added prior to this visit.</div>
-                                    @else
-                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the allergy was added on a previous visit.</div>
-                                    @endif
-                                </div>
-
-                            @endif
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$allergy->addition_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$allergy->addition_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           value="{{$allergy->addition_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is allergy active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="">-- select --</option>
-                                        <option value="0" {{!$allergy->is_removed ? 'selected' : ''}}>Yes</option>
-                                        <option value="1" {{$allergy->is_removed ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                                <div class="col-6 is_removed_ui_1" style="display: none">
-                                    <label class="text-sm mb-0 min-width-unset">Is entry error?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemovedDueToEntryError">
-                                        <option value="1" {{$allergy->is_removed_due_to_entry_error ? 'selected' : ''}}>Yes</option>
-                                        <option value="0" {{!$allergy->is_removed_due_to_entry_error ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                            </div>
-
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$allergy->removal_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$allergy->removal_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           value="{{$allergy->removal_effective_date ? $allergy->removal_effective_date : ''}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           value="{{$allergy->removal_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <div>
-                                <button type="submit" class="btn-save-allergy btn btn-sm btn-primary mr-2">Save</button>
-                                <button cancel class="btn btn-sm btn-default border">Cancel</button>
-                            </div>
-                        </form>
-                    </div>
-                </td>
                 <td>
                     <?= !!@($allergy->data->start_date) ? friendly_date($allergy->data->start_date) : '-' ?>
+                    @if(!!@($allergy->data->prescriber))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($allergy->data->prescriber) ? @($allergy->data->prescriber) : '-' ?></div>
+                    @endif
                 </td>
                 <td>
                     <?= !!@($allergy->removal_effective_date) ? friendly_date($allergy->removal_effective_date) : '-' ?>
@@ -258,7 +125,7 @@ $allergies = $points;
                             ?>
                         </div>
                         <div class="d-inline-flex flex-nowrap">
-                            <a class="px-2 view-review-log"
+                            <a class="pl-2 view-review-log"
                                native target="_blank"
                                open-in-stag-popup
                                popup-style="stag-popup-md"
@@ -267,10 +134,10 @@ $allergies = $points;
                                 <i class="fa fa-history"></i>
                             </a>
                             <?php
-                            $segment = $note->getSegmentByInternalName('intake_allergies');
+                            /*$segment = $note->getSegmentByInternalName('intake_allergies');
                             if($segment) {
                                 include resource_path('views/app/patient/segment-templates/_child_review/edit-review.php');
-                            }
+                            }*/
                             ?>
                         </div>
                     </div>
@@ -283,7 +150,7 @@ $allergies = $points;
                             ?>
                         </div>
                         <div class="d-inline-flex flex-nowrap">
-                            <a class="px-2 view-review-log"
+                            <a class="pl-2 view-review-log"
                                native target="_blank"
                                open-in-stag-popup
                                popup-style="stag-popup-md"
@@ -292,20 +159,67 @@ $allergies = $points;
                                 <i class="fa fa-history"></i>
                             </a>
                             <?php
-                            $segment = $note->getSegmentByInternalName('plan_allergies');
+                            /*$segment = $note->getSegmentByInternalName('plan_allergies');
                             if($segment) {
                                 include resource_path('views/app/patient/segment-templates/_child_plan/edit-plan.php');
-                            }
+                            }*/
                             ?>
                         </div>
                     </div>
                 </td>
+                <td>
+                    <div moe huge relative>
+                        <a start show href="#" title="Edit">Edit</a>
+                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-allergy" right>
+                            <input type="hidden" name="uid" value="<?= $allergy->uid ?>">
+                            <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                            <p class="mb-2"><b>Update Allergy</b></p>
+
+                            <input type="hidden" name="data" value='{{json_encode($allergy->data)}}'>
+
+                            @if($allergy->added_in_note_id === $note->id)
+
+                                <input type="hidden" data-name="damConceptId" value="{{@$allergy->data->damConceptId}}">
+                                <input type="hidden" data-name="damConceptIdType" value="{{@$allergy->data->damConceptIdType}}">
+
+                                <div class="mb-2">
+                                    <label class="text-sm mb-0">Name</label>
+                                    <input type="text" data-name="name" class="form-control form-control-sm"
+                                           value="{{@$allergy->data->name}}"
+                                           stag-suggest
+                                           stag-suggest-ep="/fdb-allergy-suggest/json">
+                                </div>
+
+                            @else
+
+                                <div class="mb-2 bg-light p-2 border">
+                                    <p class="mb-1 font-weight-bold">
+                                        {{ @$allergy->data->name }}
+                                    </p>
+                                    @if($patient->core_note_id !== $note->id)
+                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the allergy was added prior to this visit.</div>
+                                    @else
+                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the allergy was added on a previous visit.</div>
+                                    @endif
+                                </div>
+
+                            @endif
+
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'allergy', 'point' => $allergy, 'addVerbPT' => 'Diagnosed'])
+
+                            <div class="mt-3 pt-2 d-flex align-items-center border-top">
+                                <button type="submit" class="btn-save-allergy btn btn-sm btn-primary mr-2">Save</button>
+                                <button cancel class="btn btn-sm bg-light btn-default border">Cancel</button>
+                            </div>
+                        </form>
+                    </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">
+            <div class="mt-1 w-100 border p-3 bg-aliceblue border-info rounded">
                 <form action="/api/visitPoint/addTopLevel" class="mcp-theme-1 w-100" id="frm-add-allergy">
                     <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
                     <input type="hidden" name="category" value="ALLERGY">
@@ -314,96 +228,27 @@ $allergies = $points;
                     <input type="hidden" data-name="damConceptId">
                     <input type="hidden" data-name="damConceptIdType">
 
-                    <p class="mb-2"><b>Add Allergy</b></p>
+                    <input type="hidden" name="isRemovedDueToEntryError" value="0">
 
                     <div class="row">
-                        <div class="col-7">
-                            <div class="row mb-2">
-                                <div class="col-12">
-                                    <label class="text-sm mb-0">Name</label>
-                                    <input type="text" data-name="name" class="form-control form-control-sm"
-                                           stag-suggest
-                                           stag-suggest-ep="/fdb-allergy-suggest/json"
-                                           required>
-                                </div>
-                            </div>
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0">Start Date</label>
-                                    <input type="date"
-                                           data-name="start_date"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-6">
-                                    <label class="text-sm mb-0">Added By</label>
-                                    <input type="text"
-                                           data-name="prescriber"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-                            <!--<div class="mb-2">
-                                <label class="text-sm mb-1">Description</label>
-                                <textarea rows="1" data-name="description" class="form-control form-control-sm"></textarea>
-                            </div>-->
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
+                        <div class="col-8">
+                            <p class="mb-2"><b>Add Allergy</b></p>
+                            <div class="mb-2">
+                                <label class="text-sm mb-0">Name</label>
+                                <input type="text" data-name="name" class="form-control form-control-sm"
+                                       stag-suggest
+                                       stag-suggest-ep="/fdb-allergy-suggest/json"
+                                       required>
                             </div>
 
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is allergy active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="0" selected>Yes</option>
-                                        <option value="1">No</option>
-                                    </select>
-                                </div>
-                                <input type="hidden" name="isRemovedDueToEntryError" value="0">
-                            </div>
-
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
+                            <?php $point = null; ?>
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'allergy', 'addVerbPT' => 'Diagnosed'])
 
                         </div>
-                        <div class="col-5 border-left">
+                        <div class="col-4 border-left">
+                            <div class="fdb-allergy-vigilance max-height-400px overflow-auto">
 
+                            </div>
                         </div>
                     </div>
 
@@ -418,62 +263,6 @@ $allergies = $points;
 
 <script>
     (function() {
-        function initVisitMoeRTEs() {
-            $('.stag-popup [visit-moe]').find('[note-rte]:not(.ql-container)').each(function() {
-
-                let noteRTE = $(this);
-
-                $(this).wrap(
-                    $('<div class="border-left border-right rte-holder"/>')
-                        .attr('data-shortcuts', '')
-                );
-
-                // give a unique id to this editor instance
-                var editorID = Math.ceil(Math.random() * 99999),
-                    fieldName = $(this).attr('data-field-name') ? $(this).attr('data-field-name') : 'free_text';
-
-                var el = this;
-                var existingContent = $(el).html();
-                var quill = new Quill(el, {
-                    theme: 'snow',
-                    modules: stagQuillConfig
-                });
-
-                var toolbar = $(quill.container).prev('.ql-toolbar');
-
-                // add button for new shortcut
-                if(!noteRTE.is('[use-shortcuts]') || !noteRTE.attr('use-shortcuts')) {
-                    var newSCButton = $('<button class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
-                        'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
-                    toolbar.append(newSCButton);
-                }
-
-                quill.root.innerHTML = existingContent;
-
-                let onTextChange = function(delta, oldDelta, source) {
-                    var content = quill.root.innerHTML;
-                    let dataObject = {};
-                    dataObject[fieldName] = content;
-                    var dataValue = JSON.stringify(dataObject);
-                    let pElem = $(el).closest('[visit-moe]');
-                    if(!pElem.length) {
-                        pElem = $(el).closest('form');
-                    }
-                    pElem.find('input[name=data]').val(dataValue);
-                };
-
-                quill.on('text-change', onTextChange);
-
-                $(quill.container)
-                    .find('.ql-editor[contenteditable]')
-                    .attr('data-field', fieldName)
-                    .attr('data-editor-id', editorID)
-                    .attr('with-shortcuts', 1);
-
-                // set value initially
-                onTextChange();
-            });
-        }
         function init() {
             let parentSegment = $('#allergies-center-{{$note->id}}');
             parentSegment.find('input[stag-suggest][data-name="name"]')
@@ -481,205 +270,23 @@ $allergies = $points;
                 .on('stag-suggest-selected', (_e, _input, _data) => {
                     _input.closest('form').find('input[data-name="damConceptId"]').val(_data.dam_concept_id);
                     _input.closest('form').find('input[data-name="damConceptIdType"]').val(_data.dam_concept_id_typ);
-                });
-
-            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();
-                        form.find('.removalEffectiveDate_ui').show();
-                        form.find('.removalReasonMemo_ui').show();
-                    }
-                    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();
-                    }
-                    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('[name="isRemoved"], [name="isRemovedDueToEntryError"]')
-                .off('change')
-                .on('change', function () {
-                    let form = $(this).closest('form');
-
-                    form.find('.is_removed_ui_1').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1') {
-                        form.find('.is_removed_ui_1').show();
-                    }
-
-                    form.find('.is_removed_ui_2').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1' && form.find('[name="isRemovedDueToEntryError"]').val() !== '1') {
-                        form.find('.is_removed_ui_2').show();
-                    }
-                    return false;
-                });
-
-            parentSegment.find('#frm-add-allergy')
-                .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_allergies"]').find('.refresh-segment').trigger('click');
-                        }
-                    }, 'json');
-                    return false;
-                });
-
-            parentSegment.find('.frm-edit-allergy')
-                .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();
-                                }
-                            }
-                        }
 
+                    $('.fdb-allergy-vigilance').html('<span class="text-secondary font-italic">Please wait ...</span>');
+                    $.post('/fdb-allergy-vigilance/{{$patient->uid}}', {
+                        _token: '{{csrf_token()}}',
+                        name: _input.val(),
+                        damConceptId: _data.dam_concept_id,
+                        damConceptIdType: _data.dam_concept_id_typ
+                    }, _data => {
+                        $('.fdb-allergy-vigilance').html(_data);
                     });
-                    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_allergies"]').find('.refresh-segment').trigger('click');
-                        }
-                    }, 'json');
-                    return false;
                 });
 
-            parentSegment.find('.toggle-relevance')
-                .off('click.toggle-relevance')
-                .on('click.toggle-relevance', function () {
-                    if(+$(this).attr('data-relevant') === 0) {
-                        $.post('/api/visitPoint/markPointRelevantToNote', {
-                            noteUid: '{{$note->uid}}',
-                            pointUid: $(this).attr('data-point-uid')
-                        }, _data => {
-                            if(!hasResponseError(_data)) {
-                                refreshDynamicStagPopup();
-                            }
-                        }, 'json');
-                    }
-                    else {
-                        if($(this).attr('data-rel-uid')) {
-                            $.post('/api/visitPoint/undoMarkPointRelevantToNote', {
-                                uid: $(this).attr('data-rel-uid')
-                            }, _data => {
-                                if(!hasResponseError(_data)) {
-                                    refreshDynamicStagPopup();
-                                }
-                            }, 'json');
-                        }
-                        else {
-                            console.log('Error - missing rel uid');
-                        }
-                    }
-                    return false;
-                });
-
-            initStagSuggest();
-
-            parentSegment.find('.additionReasonCategory_ui').trigger('change');
-            parentSegment.find('[name="isRemoved"]').trigger('change');
+            @include('app.patient.wizard-partials.common-script', ['label' => 'allergy'])
 
             initSegmentMoes($('#allergies-center-{{$note->id}}'));
-            initVisitMoeRTEs();
+            __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
         }
         addMCInitializer('allergies-center-{{$note->id}}', init, '#allergies-center-{{$note->id}}');
     }).call(window);

+ 16 - 6
resources/views/app/patient/canvas-sections/vitals/form.blade.php

@@ -125,9 +125,14 @@ $formID = rand(0, 100000);
                                data-option-list="smokingStatus"
                                v-on:change="autoDate(items['smokingStatus'], 'smokingStatus')" v-on:keyup="autoDate(items['smokingStatus'], 'smokingStatus')">
                         <div id="smoking-status-options" class="data-option-list">
-                            <div>Current</div>
-                            <div>Former</div>
-                            <div>Never</div>
+                            <div>Current every day smoker</div>
+                            <div>Former some day smoker</div>
+                            <div>Former smoker</div>
+                            <div>Never smoker</div>
+                            <div>Smoker, current status unknown</div>
+                            <div>Unknown if ever smoked</div>
+                            <div>Heavy tobacco smoker</div>
+                            <div>Light tobacco smoker</div>
                         </div>
                     @else
                         <input type="text"
@@ -157,9 +162,14 @@ $formID = rand(0, 100000);
                        :data-option-list="index === 'smokingStatus'"
                        v-on:change="autoDate(item, index)" v-on:keyup="autoDate(item, index)">
                 <div id="smoking-status-options" class="data-option-list">
-                    <div>Current</div>
-                    <div>Former</div>
-                    <div>Never</div>
+                    <div>Current every day smoker</div>
+                    <div>Former some day smoker</div>
+                    <div>Former smoker</div>
+                    <div>Never smoker</div>
+                    <div>Smoker, current status unknown</div>
+                    <div>Unknown if ever smoked</div>
+                    <div>Heavy tobacco smoker</div>
+                    <div>Light tobacco smoker</div>
                 </div>
                 <input type="text" :data-index="index" v-if="index === 'bmi'" readonly
                        class="form-control form-control-sm vitals-title"

+ 4 - 6
resources/views/app/patient/care-month/_matrix.blade.php

@@ -28,11 +28,9 @@ foreach ($days as $k => $day) {
 ?>
 
 <div id="cm-matrix-{{$patient->id}}">
-<div class="d-flex align-items-baseline">
-    <a class="font-weight-bold" href="#" tab-link="matrix">Care Month Matrix</a>
-    <span class="mx-2 text-secondary text-sm">|</span>
+<div class="d-flex align-items-baseline" tab-links>
+    <a class="tab-link-active" href="#" tab-link="matrix">Care Month Matrix</a>
     <a class="" href="#" tab-link="bmi-summary">BMI/Weight Management Settings</a>
-    <span class="mx-2 text-secondary text-sm">|</span>
     <a class="" href="#" tab-link="bp-summary">BP Management Settings</a>
 </div>
 <table class="table table-condensed table-sm table-bordered my-3 cm-tab" tab-key="matrix">
@@ -307,8 +305,8 @@ foreach ($days as $k => $day) {
                 .off('click')
                 .on('click', function () {
                     let tab = $(this).attr('tab-link');
-                    $(this).siblings().removeClass('font-weight-bold');
-                    $(this).addClass('font-weight-bold');
+                    $(this).siblings().removeClass('tab-link-active');
+                    $(this).addClass('tab-link-active');
                     $('.cm-tab').addClass('d-none');
                     $('.cm-tab[tab-key="' + tab + '"]').removeClass('d-none');
                     return false;

+ 326 - 0
resources/views/app/patient/careteam-center.blade.php

@@ -0,0 +1,326 @@
+<?php
+
+use App\Models\Point;
+use App\Models\Client;
+use App\Models\Note;
+use App\Models\Segment;
+
+/** @var Client $patient */
+/** @var Note $note */
+
+$careTeamMembers = Point::getPointsOfCategoryExtended($patient, 'CARE_TEAM_MEMBER', $note);
+?>
+
+<div class="mt-3 p-3 border-top min-height-500px" id="careteam-center-{{$note->id}}">
+    <div>
+
+        <table class="table table-sm table-bordered table-striped mb-0 bg-white mb-2">
+            <thead>
+            <tr class="">
+                @if($patient->core_note_id !== $note->id)
+                <th class="border-bottom-0 text-secondary text-center width-30px">Rel.</th>
+                @endif
+                <th class="border-bottom-0 text-secondary">Name</th>
+                <th class="border-bottom-0 text-secondary">Details</th>
+                <th class="border-bottom-0 text-secondary">Contact</th>
+                <th class="border-bottom-0 text-secondary">Ended</th>
+                <th class="border-bottom-0 text-secondary w-25">Review</th>
+                <th class="border-bottom-0 text-secondary w-25">Plan</th>
+                <th class="border-bottom-0 text-secondary">Edit</th>
+            </tr>
+            </thead>
+            <?php $prevRowState = -1; ?>
+            <?php foreach($careTeamMembers as $careTeamMember): ?>
+            <?php $point = $careTeamMember; ?>
+            @if($prevRowState !== -1 && $prevRowState !== $careTeamMember->state)
+                <tr>
+                    <td colspan="9" class="px-0 pt-1 pb-0 on-hover-opaque bg-secondary"></td>
+                </tr>
+            @endif
+            <?php $prevRowState = $careTeamMember->state; ?>
+            <?php $rel = $careTeamMember->relevanceToNote($note); ?>
+            <tr class="{{$rel ? 'relevant-to-visit' : ''}}">
+                @if($patient->core_note_id !== $note->id)
+                <td class="text-center">
+                    <a href="#" class="toggle-relevance"
+                       data-relevant="{{$rel ? '1' : '0'}}"
+                       data-rel-uid="{{$rel ? $rel->uid : ''}}"
+                       data-point-uid="{{$careTeamMember->uid}}"
+                       title="Mark as{{$rel ? ' not ' : ' '}}relevant to this visit">
+                        @if($rel)
+                            <i class="fa fa-star text-sm text-info"></i>
+                        @else
+                            <i class="fa fa-star text-sm text-secondary on-hover-opaque"></i>
+                        @endif
+                    </a>
+                </td>
+                @endif
+                <td>
+                    <div class="d-flex align-items-baseline">
+                        @if($careTeamMember->state === 1)
+                            <i class="text-success fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($careTeamMember->state === 2)
+                            <i class="text-info fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($careTeamMember->state === 3)
+                            <i class="text-warning-mellow fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($careTeamMember->state === 4)
+                            <i class="text-secondary fa fa-circle text-sm on-hover-opaque mr-2"></i>
+                        @endif
+                        <div>
+                            <b><?= !!@($careTeamMember->data->name) ? @($careTeamMember->data->name) : '-' ?></b>
+                            @if($careTeamMember->added_in_note_id === $note->id)
+                                <div class="mt-1 text-sm text-secondary">
+                                    Added
+                                    @if($patient->core_note_id !== $note->id)
+                                        during this visit
+                                    @else
+                                        from the patient's chart
+                                    @endif
+                                    @if($careTeamMember->addition_reason_category === 'ON_INTAKE')
+                                        (existing)
+                                    @elseif($careTeamMember->addition_reason_category === 'DURING_VISIT')
+                                        (new)
+                                    @endif
+                                </div>
+                            @endif
+                            @if($careTeamMember->is_removed && $careTeamMember->removed_in_note_id === $note->id)
+                                <div class="mt-1 text-sm text-secondary">
+                                    Removed
+                                    @if($patient->core_note_id !== $note->id)
+                                        during this visit
+                                    @else
+                                        from the patient's chart
+                                    @endif
+                                </div>
+                            @endif
+                        </div>
+                    </div>
+                </td>
+                    <td>
+                        <?= !!@($careTeamMember->data->specialty) ? @($careTeamMember->data->specialty) : '-' ?><br>
+                        <?= !!@($careTeamMember->data->organization) ? @($careTeamMember->data->organization) : '-' ?>
+                    </td>
+                    <td>
+                        <?= !!@($careTeamMember->data->phone) ? @($careTeamMember->data->phone) : '-' ?><br>
+                        <?= !!@($careTeamMember->data->fax) ? @($careTeamMember->data->fax) : '-' ?>
+                    </td>
+                <td>
+                    @if($careTeamMember->is_removed)
+                        NO
+                    @else
+                        <b>YES</b>
+                    @endif
+                </td>
+                <td>
+                    <?= !!@($careTeamMember->data->start_date) ? friendly_date($careTeamMember->data->start_date) : '-' ?>
+                    @if(!!@($careTeamMember->data->prescriber))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($careTeamMember->data->prescriber) ? @($careTeamMember->data->prescriber) : '-' ?></div>
+                    @endif
+                </td>
+                <td>
+                    <?= !!@($careTeamMember->removal_effective_date) ? friendly_date($careTeamMember->removal_effective_date) : '-' ?>
+                    @if(!!@($careTeamMember->removal_reason_memo))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($careTeamMember->removal_reason_memo) ? @($careTeamMember->removal_reason_memo) : '-' ?></div>
+                    @endif
+                </td>
+                <td>
+                    <div class="d-flex align-items-start">
+                        <div class="flex-grow-1">
+                            <?php
+                            $point = $careTeamMember;
+                            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<?= !!@($careTeamMember->data->name) ? ' for ' . @($careTeamMember->data->name) : '' ?>"
+                               href="/point/review-log/<?= $careTeamMember->uid ?>?popupmode=1">
+                                <i class="fa fa-history"></i>
+                            </a>
+                        </div>
+                    </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>
+                        <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="Plan log<?= !!@($careTeamMember->data->name) ? ' for ' . @($careTeamMember->data->name) : '' ?>"
+                               href="/point/plan-log/<?= $careTeamMember->uid ?>?popupmode=1">
+                                <i class="fa fa-history"></i>
+                            </a>
+                        </div>
+                    </div>
+                </td>
+                <td>
+                    <div moe huge relative>
+                        <a start show href="#" title="Edit">Edit</a>
+                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-care-team-member" right>
+                            <input type="hidden" name="uid" value="<?= $careTeamMember->uid ?>">
+                            <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                            <p class="mb-2"><b>Update Care Team Member</b></p>
+
+                            <input type="hidden" name="data" value='{{json_encode($careTeamMember->data)}}'>
+
+                            @if($careTeamMember->added_in_note_id === $note->id)
+
+                                <div class="row mb-2">
+                                    <div class="col-6 pr-0">
+                                        <label class="text-sm text-secondary mb-1">Name</label>
+                                        <input type="text" class="form-control form-control-sm min-width-unset"
+                                               data-name="name"
+                                               value="{{@$careTeamMember->data->name}}">
+                                    </div>
+                                    <div class="col-6">
+                                        <label class="text-sm text-secondary mb-1">Specialty</label>
+                                        <input type="text" class="form-control form-control-sm min-width-unset"
+                                               data-name="specialty"
+                                               value="{{@$careTeamMember->data->specialty}}">
+                                    </div>
+                                </div>
+
+                                <div class="row mb-2">
+                                    <div class="col-6 pr-0">
+                                        <label class="text-sm text-secondary mb-1">Organization</label>
+                                        <input type="text" class="form-control form-control-sm min-width-unset"
+                                               data-name="organization"
+                                               value="{{@$careTeamMember->data->organization}}">
+                                    </div>
+                                    <div class="col-3 pr-0">
+                                        <label class="text-sm text-secondary mb-1">Phone</label>
+                                        <input type="text" class="form-control form-control-sm min-width-unset"
+                                               data-name="phone"
+                                               value="{{@$careTeamMember->data->phone}}">
+                                    </div>
+                                    <div class="col-3">
+                                        <label class="text-sm text-secondary mb-1">Fax</label>
+                                        <input type="text" class="form-control form-control-sm min-width-unset"
+                                               data-name="fax"
+                                               value="{{@$careTeamMember->data->fax}}">
+                                    </div>
+                                </div>
+
+                            @else
+
+                                <div class="mb-2 bg-light p-2 border">
+                                    <p class="mb-1 font-weight-bold">
+                                        {{ @$careTeamMember->data->name }}
+                                        {{ @$careTeamMember->data->specialty }}
+                                        {{ @$careTeamMember->data->organization }}
+                                    </p>
+                                    @if($patient->core_note_id !== $note->id)
+                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the care team member was added prior to this visit.</div>
+                                    @else
+                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the care team member was added on a previous visit.</div>
+                                    @endif
+                                </div>
+
+                            @endif
+
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'care-team-member', 'point' => $careTeamMember])
+
+                            <div class="mt-3 pt-2 d-flex align-items-center border-top">
+                                <button type="submit" class="btn-save-care-team-member btn btn-sm btn-primary mr-2">Save</button>
+                                <button cancel class="btn btn-sm bg-light btn-default border">Cancel</button>
+                            </div>
+                        </form>
+                    </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-care-team-member">
+                    <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
+                    <input type="hidden" name="category" value="CARE_TEAM_MEMBER">
+                    <input type="hidden" name="data">
+
+                    <input type="hidden" name="isRemovedDueToEntryError" value="0">
+
+                    <p class="mb-2"><b>Add Care Team Member</b></p>
+
+                    <div class="row">
+                        <div class="col-8">
+
+                            <div class="row mb-2">
+                                <div class="col-6 pr-0">
+                                    <label class="text-sm text-secondary mb-1">Name</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset"
+                                           data-name="name">
+                                </div>
+                                <div class="col-6">
+                                    <label class="text-sm text-secondary mb-1">Specialty</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset"
+                                           data-name="specialty">
+                                </div>
+                            </div>
+
+                            <div class="row mb-2">
+                                <div class="col-6 pr-0">
+                                    <label class="text-sm text-secondary mb-1">Organization</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset"
+                                           data-name="organization">
+                                </div>
+                                <div class="col-3 pr-0">
+                                    <label class="text-sm text-secondary mb-1">Phone</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset"
+                                           data-name="phone">
+                                </div>
+                                <div class="col-3">
+                                    <label class="text-sm text-secondary mb-1">Fax</label>
+                                    <input type="text" class="form-control form-control-sm min-width-unset"
+                                           data-name="fax">
+                                </div>
+                            </div>
+
+                            <?php $point = null; ?>
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'care-team-member'])
+
+                        </div>
+                        <div class="col-4 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 Care Team Member</button>
+                    </div>
+                </form>
+            </div>
+        </div>
+    </div>
+</div>
+
+<script>
+    (function() {
+        function init() {
+            let parentSegment = $('#careteam-center-{{$note->id}}');
+
+            parentSegment.find('select[data-name="category"]')
+                .off('change')
+                .on('change', function() {
+                    $(this).closest('form').find('.help-text').addClass('d-none');
+                    $(this).closest('form').find('.help-text[data-category="' + this.value + '"]').removeClass('d-none');
+                })
+                .trigger('change');
+
+            @include('app.patient.wizard-partials.common-script', ['label' => 'care-team-member'])
+
+            initSegmentMoes($('#careteam-center-{{$note->id}}'));
+            __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
+        }
+        addMCInitializer('careteam-center-{{$note->id}}', init, '#careteam-center-{{$note->id}}');
+    }).call(window);
+</script>

+ 83 - 523
resources/views/app/patient/goals-center.blade.php

@@ -8,22 +8,7 @@ use App\Models\Segment;
 /** @var Client $patient */
 /** @var Note $note */
 
-$points = Point
-    ::where('client_id', $patient->id)
-    ->where('category', 'GOAL')
-    ->where('is_removed_due_to_entry_error', false)
-    ->orderBy('category')
-    ->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);
-    }
-}
-$goals = $points;
-
+$goals = Point::getPointsOfCategoryExtended($patient, 'GOAL', $note);
 ?>
 
 <div class="mt-3 p-3 border-top min-height-500px" id="goals-center-{{$note->id}}">
@@ -36,26 +21,25 @@ $goals = $points;
                 <th class="border-bottom-0 text-secondary text-center width-30px">Rel.</th>
                 @endif
                 <th class="border-bottom-0 text-secondary">Goal</th>
-                <th class="border-bottom-0 text-secondary">Category</th>
-                <th class="border-bottom-0 text-secondary w-25">Directions</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">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 w-25">Review</th>
+                <th class="border-bottom-0 text-secondary w-25">Plan</th>
+                <th class="border-bottom-0 text-secondary">Edit</th>
             </tr>
             </thead>
-            <?php $prevRowRemoved = -1; ?>
+            <?php $prevRowState = -1; ?>
             <?php foreach($goals as $goal): ?>
             <?php $point = $goal; ?>
-            @if($prevRowRemoved !== -1 && $prevRowRemoved !== $goal->is_removed)
+            @if($prevRowState !== -1 && $prevRowState !== $goal->state)
                 <tr>
-                    <td colspan="10" class="px-0 pt-1 pb-0 on-hover-opaque bg-secondary"></td>
+                    <td colspan="9" class="px-0 pt-1 pb-0 on-hover-opaque bg-secondary"></td>
                 </tr>
             @endif
-            <?php $prevRowRemoved = $goal->is_removed; ?>
+            <?php $prevRowState = $goal->state; ?>
             <?php $rel = $goal->relevanceToNote($note); ?>
-            <tr class="">
+            <tr class="{{$rel ? 'relevant-to-visit' : ''}}">
                 @if($patient->core_note_id !== $note->id)
                 <td class="text-center">
                     <a href="#" class="toggle-relevance"
@@ -73,10 +57,14 @@ $goals = $points;
                 @endif
                 <td>
                     <div class="d-flex align-items-baseline">
-                        @if($goal->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>
+                        @if($goal->state === 1)
+                            <i class="text-success fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($goal->state === 2)
+                            <i class="text-info fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($goal->state === 3)
+                            <i class="text-warning-mellow fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($goal->state === 4)
+                            <i class="text-secondary fa fa-circle text-sm on-hover-opaque mr-2"></i>
                         @endif
                         <div>
                             <b><?= !!@($goal->data->goal) ? @($goal->data->goal) : '-' ?></b>
@@ -109,7 +97,49 @@ $goals = $points;
                     </div>
                 </td>
                 <td>
-                    <?= !!@($goal->data->category) ? @($goal->data->category) : '-' ?>
+                    @if($goal->is_removed)
+                        NO
+                    @else
+                        <b>YES</b>
+                    @endif
+                </td>
+                <td>
+                    <?= !!@($goal->data->start_date) ? friendly_date($goal->data->start_date) : '-' ?>
+                    @if(!!@($goal->data->prescriber))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($goal->data->prescriber) ? @($goal->data->prescriber) : '-' ?></div>
+                    @endif
+                </td>
+                <td>
+                    <?= !!@($goal->removal_effective_date) ? friendly_date($goal->removal_effective_date) : '-' ?>
+                    @if(!!@($goal->removal_reason_memo))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($goal->removal_reason_memo) ? @($goal->removal_reason_memo) : '-' ?></div>
+                    @endif
+                </td>
+                <td>
+                    <div class="d-flex align-items-start">
+                        <div class="flex-grow-1">
+                            <?php
+                            $point = $goal;
+                            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<?= !!@($goal->data->goal) ? ' for ' . @($goal->data->goal) : '' ?>"
+                               href="/point/review-log/<?= $goal->uid ?>?popupmode=1">
+                                <i class="fa fa-history"></i>
+                            </a>
+                            <?php
+                            /*$segment = $note->getSegmentByInternalName('intake_goals');
+                            if($segment) {
+                                include resource_path('views/app/patient/segment-templates/_child_review/edit-review.php');
+                            }*/
+                            ?>
+                        </div>
+                    </div>
                 </td>
                 <td>
                     <div class="d-flex align-items-start">
@@ -119,7 +149,7 @@ $goals = $points;
                             ?>
                         </div>
                         <div class="d-inline-flex flex-nowrap">
-                            <a class="px-2 view-review-log"
+                            <a class="pl-2 view-review-log"
                                native target="_blank"
                                open-in-stag-popup
                                popup-style="stag-popup-md"
@@ -128,34 +158,27 @@ $goals = $points;
                                 <i class="fa fa-history"></i>
                             </a>
                             <?php
-                            $segment = $note->getSegmentByInternalName('plan_goals');
+                            /*$segment = $note->getSegmentByInternalName('plan_goals');
                             if($segment) {
                                 include resource_path('views/app/patient/segment-templates/_child_plan/edit-plan.php');
-                            }
+                            }*/
                             ?>
                         </div>
                     </div>
                 </td>
                 <td>
-                    @if($goal->is_removed)
-                        NO
-                    @else
-                        <b>YES</b>
-                    @endif
-                </td>
-                <td>
-                    <div moe wide>
+                    <div moe huge relative>
                         <a start show href="#" title="Edit">Edit</a>
-                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-goal">
+                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-goal" right>
                             <input type="hidden" name="uid" value="<?= $goal->uid ?>">
                             <input type="hidden" name="noteUid" value="<?= $note->uid ?>">
                             <p class="mb-2"><b>Update Goal</b></p>
 
-                            @if($goal->added_in_note_id === $note->id)
+                            <input type="hidden" name="data" value='{{json_encode($goal->data)}}'>
 
-                                <input type="hidden" name="data">
+                            @if($goal->added_in_note_id === $note->id)
 
-                                <div class="mb-2">
+                                {{--<div class="mb-2">
                                     <label class="text-sm text-secondary mb-1">Category</label>
                                     <select type="text" data-name="category" class="form-control form-control-sm">
                                         <option value="">-- select --</option>
@@ -225,7 +248,7 @@ $goals = $points;
 
                                 <div class="bg-light border mb-2 p-2 help-text d-none" data-category="OTHER">
                                     <div class="">Ensure that the goal is Specific, Measurable, Attainable, Realistic and Time-Connected.</div>
-                                </div>
+                                </div>--}}
 
                                 <div class="mb-2">
                                     <label class="text-sm text-secondary mb-1">Goal</label>
@@ -234,28 +257,11 @@ $goals = $points;
                                            value="{{@$goal->data->goal}}">
                                 </div>
 
-                                <div class="row mb-2">
-                                    <div class="col-6 pr-0">
-                                        <label class="text-sm mb-0">Start Date</label>
-                                        <input type="date"
-                                               data-name="start_date"
-                                               value="{{@$goal->data->start_date}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                    <div class="col-6">
-                                        <label class="text-sm mb-0">Added By</label>
-                                        <input type="text"
-                                               data-name="prescriber"
-                                               value="{{@$goal->data->prescriber}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                </div>
-
                             @else
 
                                 <div class="mb-2 bg-light p-2 border">
                                     <p class="mb-1 font-weight-bold">
-                                        {{ @$goal->data->name }}
+                                        {{ @$goal->data->goal }}
                                     </p>
                                     @if($patient->core_note_id !== $note->id)
                                         <div class="text-secondary text-sm">Clinical details cannot be modified since the goal was added prior to this visit.</div>
@@ -266,116 +272,15 @@ $goals = $points;
 
                             @endif
 
-                            <hr class="my-3">
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'goal', 'point' => $goal])
 
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$goal->addition_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$goal->addition_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           value="{{$goal->addition_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is goal active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="">-- select --</option>
-                                        <option value="0" {{!$goal->is_removed ? 'selected' : ''}}>Yes</option>
-                                        <option value="1" {{$goal->is_removed ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                                <div class="col-6 is_removed_ui_1" style="display: none">
-                                    <label class="text-sm mb-0 min-width-unset">Is entry error?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemovedDueToEntryError">
-                                        <option value="1" {{$goal->is_removed_due_to_entry_error ? 'selected' : ''}}>Yes</option>
-                                        <option value="0" {{!$goal->is_removed_due_to_entry_error ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                            </div>
-
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$goal->removal_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$goal->removal_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           value="{{$goal->removal_effective_date ? $goal->removal_effective_date : ''}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           value="{{$goal->removal_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <div>
+                            <div class="mt-3 pt-2 d-flex align-items-center border-top">
                                 <button type="submit" class="btn-save-goal btn btn-sm btn-primary mr-2">Save</button>
-                                <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                <button cancel class="btn btn-sm bg-light btn-default border">Cancel</button>
                             </div>
                         </form>
                     </div>
                 </td>
-                <td>
-                    <?= !!@($goal->data->start_date) ? friendly_date($goal->data->start_date) : '-' ?>
-                    @if(!!@($goal->data->prescriber))
-                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($goal->data->prescriber) ? @($goal->data->prescriber) : '-' ?></div>
-                    @endif
-                </td>
-                <td>
-                    <?= !!@($goal->removal_effective_date) ? friendly_date($goal->removal_effective_date) : '-' ?>
-                    @if(!!@($goal->removal_reason_memo))
-                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($goal->removal_reason_memo) ? @($goal->removal_reason_memo) : '-' ?></div>
-                    @endif
-                </td>
-                <td>
-                    <div class="d-flex align-items-start">
-                        <div class="flex-grow-1">
-                            <?php
-                            $point = $goal;
-                            include resource_path('views/app/patient/segment-templates/_child_review/last-review.php');
-                            ?>
-                        </div>
-                        <div class="d-inline-flex flex-nowrap">
-                            <a class="px-2 view-review-log"
-                               native target="_blank"
-                               open-in-stag-popup
-                               popup-style="stag-popup-md"
-                               title="Review log<?= !!@($goal->data->goal) ? ' for ' . @($goal->data->goal) : '' ?>"
-                               href="/point/review-log/<?= $goal->uid ?>?popupmode=1">
-                                <i class="fa fa-history"></i>
-                            </a>
-                            <?php
-                            $segment = $note->getSegmentByInternalName('intake_goals');
-                            if($segment) {
-                                include resource_path('views/app/patient/segment-templates/_child_review/edit-review.php');
-                            }
-                            ?>
-                        </div>
-                    </div>
-                </td>
             </tr>
             <?php endforeach; ?>
         </table>
@@ -387,14 +292,16 @@ $goals = $points;
                     <input type="hidden" name="category" value="GOAL">
                     <input type="hidden" name="data">
 
+                    <input type="hidden" name="isRemovedDueToEntryError" value="0">
+
                     <p class="mb-2"><b>Add Goal</b></p>
 
                     <div class="row">
-                        <div class="col-7">
+                        <div class="col-9">
                             <div class="row mb-2">
                                 <div class="col-12">
 
-                                    <div class="mb-2">
+                                    {{--<div class="mb-2">
                                         <label class="text-sm text-secondary mb-1">Category</label>
                                         <select type="text" data-name="category" class="form-control form-control-sm">
                                             <option value="">-- select --</option>
@@ -464,7 +371,7 @@ $goals = $points;
 
                                     <div class="bg-light border mb-2 p-2 help-text d-none" data-category="OTHER">
                                         <div class="">Ensure that the goal is Specific, Measurable, Attainable, Realistic and Time-Connected.</div>
-                                    </div>
+                                    </div>--}}
 
                                     <label class="text-sm text-secondary mb-0">Goal</label>
                                     <input type="text"
@@ -474,89 +381,11 @@ $goals = $points;
                                 </div>
                             </div>
 
-                            <div class="mb-2">
-                                <label class="text-sm mb-1">Directions</label>
-                                <div note-rte
-                                     class="form-group mb-2 border-left border-right rte-holder bg-white"
-                                     data-field-name="value"></div>
-                            </div>
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0">Start Date</label>
-                                    <input type="date"
-                                           data-name="start_date"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-6">
-                                    <label class="text-sm mb-0">Added By</label>
-                                    <input type="text"
-                                           data-name="prescriber"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-                            <!--<div class="mb-2">
-                                <label class="text-sm mb-1">Description</label>
-                                <textarea rows="1" data-name="description" class="form-control form-control-sm"></textarea>
-                            </div>-->
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is goal active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="0" selected>Yes</option>
-                                        <option value="1">No</option>
-                                    </select>
-                                </div>
-                                <input type="hidden" name="isRemovedDueToEntryError" value="0">
-                            </div>
-
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
+                            <?php $point = null; ?>
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'goal'])
 
                         </div>
-                        <div class="col-5 border-left">
+                        <div class="col-3 border-left">
 
                         </div>
                     </div>
@@ -572,58 +401,6 @@ $goals = $points;
 
 <script>
     (function() {
-        function initRTEs(_collection) {
-            _collection.each(function() {
-
-                $(this).wrap(
-                    $('<div class="border-left border-right rte-holder"/>')
-                        .attr('data-shortcuts', '')
-                );
-
-                // give a unique id to this editor instance
-                var editorID = Math.ceil(Math.random() * 99999),
-                    fieldName = $(this).attr('data-field-name') ? $(this).attr('data-field-name') : 'free_text';
-
-                var el = this;
-                var existingContent = $(el).html();
-                var quill = new Quill(el, {
-                    theme: 'snow',
-                    modules: stagQuillConfig
-                });
-
-                var toolbar = $(quill.container).prev('.ql-toolbar');
-
-                // add button for new shortcut
-                var newSCButton = $('<button class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
-                    'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
-                toolbar.append(newSCButton);
-
-                quill.root.innerHTML = existingContent;
-
-                let onTextChange = function(delta, oldDelta, source) {
-                    var content = quill.root.innerHTML;
-                    let dataObject = {};
-                    dataObject[fieldName] = content;
-                    var dataValue = JSON.stringify(dataObject);
-                    let pElem = $(el).closest('[visit-moe]');
-                    if(!pElem.length) {
-                        pElem = $(el).closest('form');
-                    }
-                    pElem.find('input[name=data]').val(dataValue);
-                };
-
-                quill.on('text-change', onTextChange);
-
-                $(quill.container)
-                    .find('.ql-editor[contenteditable]')
-                    .attr('data-field', fieldName)
-                    .attr('data-editor-id', editorID)
-                    .attr('with-shortcuts', 1);
-
-                // set value initially
-                onTextChange();
-            });
-        }
         function init() {
             let parentSegment = $('#goals-center-{{$note->id}}');
 
@@ -635,227 +412,10 @@ $goals = $points;
                 })
                 .trigger('change');
 
-            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();
-                        form.find('.prescriber_ui').show();
-                        form.find('.removalEffectiveDate_ui').show();
-                        form.find('.removalReasonMemo_ui').show();
-                    }
-                    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();
-                        form.find('.prescriber_ui').show();
-                    }
-                    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('[name="isRemoved"], [name="isRemovedDueToEntryError"]')
-                .off('change')
-                .on('change', function () {
-                    let form = $(this).closest('form');
-
-                    form.find('.is_removed_ui_1').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1') {
-                        form.find('.is_removed_ui_1').show();
-                    }
-
-                    form.find('.is_removed_ui_2').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1' && form.find('[name="isRemovedDueToEntryError"]').val() !== '1') {
-                        form.find('.is_removed_ui_2').show();
-                    }
-                    return false;
-                });
-
-            parentSegment.find('#frm-add-goal')
-                .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());
-                    }
-
-                    // store plan content
-                    let planContent = parsed.value ? parsed.value : '';
-                    if(!$.trim($('<div/>').html(planContent).text())) {
-                        toastr.error('Directions cannot be empty');
-                        return false;
-                    }
-                    if(parsed.value) delete parsed.value;
-
-                    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)) {
-
-                            // save child plan
-                            $.post('/api/visitPoint/upsertChildPlan', {
-                                uid: _data.data,
-                                segmentUid: '{{$note->getSegmentByInternalName('plan_goals')->uid}}',
-                                data: JSON.stringify({value: planContent})
-                            }, _data => {
-                                if(!hasResponseError(_data)) {
-                                    hideMask();
-                                    refreshDynamicStagPopup();
-                                }
-                            }, 'json');
-
-                            $('.visit-segment[data-segment-template-name="intake_goals"]').find('.refresh-segment').trigger('click');
-                        }
-                    }, 'json');
-                    return false;
-                });
-
-            parentSegment.find('.frm-edit-goal')
-                .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_goals"]').find('.refresh-segment').trigger('click');
-                        }
-                    }, 'json');
-                    return false;
-                });
-
-            parentSegment.find('.toggle-relevance')
-                .off('click.toggle-relevance')
-                .on('click.toggle-relevance', function () {
-                    if(+$(this).attr('data-relevant') === 0) {
-                        $.post('/api/visitPoint/markPointRelevantToNote', {
-                            noteUid: '{{$note->uid}}',
-                            pointUid: $(this).attr('data-point-uid')
-                        }, _data => {
-                            if(!hasResponseError(_data)) {
-                                refreshDynamicStagPopup();
-                            }
-                        }, 'json');
-                    }
-                    else {
-                        if($(this).attr('data-rel-uid')) {
-                            $.post('/api/visitPoint/undoMarkPointRelevantToNote', {
-                                uid: $(this).attr('data-rel-uid')
-                            }, _data => {
-                                if(!hasResponseError(_data)) {
-                                    refreshDynamicStagPopup();
-                                }
-                            }, 'json');
-                        }
-                        else {
-                            console.log('Error - missing rel uid');
-                        }
-                    }
-                    return false;
-                });
-
-            initStagSuggest();
-
-            parentSegment.find('.additionReasonCategory_ui').trigger('change');
-            parentSegment.find('[name="isRemoved"]').trigger('change');
+            @include('app.patient.wizard-partials.common-script', ['label' => 'goal'])
 
             initSegmentMoes($('#goals-center-{{$note->id}}'));
-            initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
+            __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
         }
         addMCInitializer('goals-center-{{$note->id}}', init, '#goals-center-{{$note->id}}');
     }).call(window);

+ 84 - 522
resources/views/app/patient/medications-center.blade.php

@@ -8,20 +8,7 @@ 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;
+$medications = Point::getPointsOfCategoryExtended($patient, 'MEDICATION', $note);
 
 ?>
 
@@ -35,25 +22,25 @@ $medications = $points;
                 <th class="border-bottom-0 text-secondary text-center width-30px">Rel.</th>
                 @endif
                 <th class="border-bottom-0 text-secondary">Name</th>
-                <th class="border-bottom-0 text-secondary w-25">Directions</th>
+                <th class="border-bottom-0 text-secondary w-25">Plan</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">Started</th>
                 <th class="border-bottom-0 text-secondary">Ended</th>
-                <th class="border-bottom-0 text-secondary w-25">Last Review</th>
+                <th class="border-bottom-0 text-secondary w-25">Review</th>
+                <th class="border-bottom-0 text-secondary">Edit</th>
             </tr>
             </thead>
-            <?php $prevRowRemoved = -1; ?>
+            <?php $prevRowState = -1; ?>
             <?php foreach($medications as $medication): ?>
             <?php $point = $medication; ?>
-            @if($prevRowRemoved !== -1 && $prevRowRemoved !== $medication->is_removed)
+            @if($prevRowState !== -1 && $prevRowState !== $medication->state)
                 <tr>
                     <td colspan="10" class="px-0 pt-1 pb-0 on-hover-opaque bg-secondary"></td>
                 </tr>
             @endif
-            <?php $prevRowRemoved = $medication->is_removed; ?>
+            <?php $prevRowState = $medication->state; ?>
             <?php $rel = $medication->relevanceToNote($note); ?>
-            <tr class="{{$medication->is_removed ? '' : ''}}">
+            <tr class="{{$rel ? 'relevant-to-visit' : ''}}">
                 @if($patient->core_note_id !== $note->id)
                 <td class="text-center">
                     <a href="#" class="toggle-relevance"
@@ -71,10 +58,14 @@ $medications = $points;
                 @endif
                 <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
+                        @if($medication->state === 1)
                             <i class="text-success fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($medication->state === 2)
+                            <i class="text-info fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($medication->state === 3)
+                            <i class="text-warning-mellow fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($medication->state === 4)
+                            <i class="text-secondary fa fa-circle text-sm on-hover-opaque mr-2"></i>
                         @endif
                         <div>
                             <b><?= !!@($medication->data->name) ? @($medication->data->name) : '-' ?></b>
@@ -114,7 +105,7 @@ $medications = $points;
                             ?>
                         </div>
                         <div class="d-inline-flex flex-nowrap">
-                            <a class="px-2 view-review-log"
+                            <a class="pl-2 view-review-log"
                                native target="_blank"
                                open-in-stag-popup
                                popup-style="stag-popup-md"
@@ -123,10 +114,10 @@ $medications = $points;
                                 <i class="fa fa-history"></i>
                             </a>
                             <?php
-                            $segment = $note->getSegmentByInternalName('plan_medications');
+                            /*$segment = $note->getSegmentByInternalName('plan_medications');
                             if($segment) {
                                 include resource_path('views/app/patient/segment-templates/_child_plan/edit-plan.php');
-                            }
+                            }*/
                             ?>
                         </div>
                     </div>
@@ -139,16 +130,54 @@ $medications = $points;
                     @endif
                 </td>
                 <td>
-                    <div moe wide>
+                    <?= !!@($medication->data->start_date) ? friendly_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) ? friendly_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>
+                        <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<?= !!@($medication->data->name) ? ' for ' . @($medication->data->name) : '' ?>"
+                               href="/point/review-log/<?= $medication->uid ?>?popupmode=1">
+                                <i class="fa fa-history"></i>
+                            </a>
+                            <?php
+                            /*$segment = $note->getSegmentByInternalName('intake_medications');
+                            if($segment) {
+                                include resource_path('views/app/patient/segment-templates/_child_review/edit-review.php');
+                            }*/
+                            ?>
+                        </div>
+                    </div>
+                </td>
+                <td>
+                    <div moe huge relative>
                         <a start show href="#" title="Edit">Edit</a>
-                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-medication">
+                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-medication" right>
                             <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>
 
-                            @if($medication->added_in_note_id === $note->id)
+                            <input type="hidden" name="data" value='{{json_encode($medication->data)}}'>
 
-                                <input type="hidden" name="data">
+                            @if($medication->added_in_note_id === $note->id)
 
                                 <input type="hidden" data-name="medId" value="{{@$medication->data->medId}}">
                                 <input type="hidden" data-name="routedMedId" value="{{@$medication->data->routedMedId}}">
@@ -164,28 +193,6 @@ $medications = $points;
                                            stag-suggest-ep="/fdb-med-suggest-v2/json">
                                 </div>
 
-                                <div class="row mb-2">
-                                    <div class="col-6 pr-0">
-                                        <label class="text-sm mb-0">Start Date</label>
-                                        <input type="date"
-                                               data-name="start_date"
-                                               value="{{@$medication->data->start_date}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                    <div class="col-6">
-                                        <label class="text-sm mb-0">Prescribed By</label>
-                                        <input type="text"
-                                               data-name="prescriber"
-                                               value="{{@$medication->data->prescriber}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                </div>
-
-                                <!--<div class="mb-2">
-                                    <label class="text-sm mb-1">Description</label>
-                                    <textarea rows="1" data-name="description" class="form-control form-control-sm">{{@$medication->data->description}}</textarea>
-                                </div>-->
-
                             @else
 
                                 <div class="mb-2 bg-light p-2 border">
@@ -201,123 +208,21 @@ $medications = $points;
 
                             @endif
 
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$medication->addition_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$medication->addition_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           value="{{$medication->addition_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is medication active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="">-- select --</option>
-                                        <option value="0" {{!$medication->is_removed ? 'selected' : ''}}>Yes</option>
-                                        <option value="1" {{$medication->is_removed ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                                <div class="col-6 is_removed_ui_1" style="display: none">
-                                    <label class="text-sm mb-0 min-width-unset">Is entry error?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemovedDueToEntryError">
-                                        <option value="1" {{$medication->is_removed_due_to_entry_error ? 'selected' : ''}}>Yes</option>
-                                        <option value="0" {{!$medication->is_removed_due_to_entry_error ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                            </div>
-
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$medication->removal_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$medication->removal_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           value="{{$medication->removal_effective_date ? $medication->removal_effective_date : ''}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           value="{{$medication->removal_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'medication', 'point' => $medication, 'addVerbPT' => 'Prescribed'])
 
                             <div class="mt-3 pt-2 d-flex align-items-center border-top">
                                 <button type="submit" class="btn-save-medication btn btn-sm btn-primary mr-2">Save</button>
                                 <button cancel class="btn btn-sm bg-light btn-default border">Cancel</button>
-                                <!--<button type="button" class="ml-auto btn btn-sm btn-danger btn-mark-as-ee" data-uid="{{$medication->uid}}">Mark as Entry Error</button>-->
                             </div>
                         </form>
                     </div>
                 </td>
-                <td>
-                    <?= !!@($medication->data->start_date) ? friendly_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) ? friendly_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>
-                        <div class="d-inline-flex flex-nowrap">
-                            <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>
-                            <?php
-                            $segment = $note->getSegmentByInternalName('intake_medications');
-                            if($segment) {
-                                include resource_path('views/app/patient/segment-templates/_child_review/edit-review.php');
-                            }
-                            ?>
-                        </div>
-                    </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">
+            <div class="mt-1 w-100 border p-3 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 ?>">
@@ -329,12 +234,13 @@ $medications = $points;
                     <input type="hidden" data-name="routedDosageFormMedId">
                     <input type="hidden" data-name="gcnSeqno">
 
-                    <p class="mb-2"><b>Add Medication</b></p>
+                    <input type="hidden" name="isRemovedDueToEntryError" value="0">
 
                     <div class="row">
-                        <div class="col-7">
+                        <div class="col-8">
+                            <p class="mb-2"><b>Add Medication</b></p>
                             <div class="mb-2">
-                                <label class="text-sm mb-0">Name</label>
+                                <label class="mb-0">Name</label>
                                 <input type="text"
                                        data-name="name"
                                        class="form-control form-control-sm"
@@ -343,96 +249,20 @@ $medications = $points;
                                        stag-suggest-ep="/fdb-med-suggest-v2/json"
                                        required>
                             </div>
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0">Start Date</label>
-                                    <input type="date"
-                                           data-name="start_date"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-6">
-                                    <label class="text-sm mb-0">Prescribed By</label>
-                                    <input type="text"
-                                           data-name="prescriber"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-                            <!--<div class="mb-2">
-                                <label class="text-sm mb-1">Description</label>
-                                <textarea rows="1" data-name="description" class="form-control form-control-sm"></textarea>
-                            </div>-->
-
-                            @if($patient->core_note_id !== $note->id)
-                            <div class="mb-2">
-                                <label class="text-sm mb-1">Directions</label>
-                                <div note-rte
-                                     class="form-group mb-2 border-left border-right rte-holder bg-white"
-                                     data-field-name="value"></div>
-                            </div>
-                            @endif
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
 
-                            <hr class="my-3">
+                            <?php $point = null; ?>
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'medication', 'addVerbPT' => 'Prescribed'])
 
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is medication active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="0" selected>Yes</option>
-                                        <option value="1">No</option>
-                                    </select>
-                                </div>
-                                <input type="hidden" name="isRemovedDueToEntryError" value="0">
-                            </div>
-
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
                         </div>
-                        <div class="col-5 border-left">
+                        <div class="col-4 border-left">
+                            <div class="fdb-rx-vigilance max-height-400px overflow-auto">
 
+                            </div>
                         </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>
+                        <button type="submit" class="btn btn-sm btn-primary mr-2 mt-1">Save Medication</button>
                     </div>
                 </form>
             </div>
@@ -442,62 +272,6 @@ $medications = $points;
 
 <script>
     (function() {
-        function initRTEs(_collection) {
-            _collection.each(function() {
-
-                let noteRTE = $(this);
-
-                $(this).wrap(
-                    $('<div class="border-left border-right rte-holder"/>')
-                        .attr('data-shortcuts', '')
-                );
-
-                // give a unique id to this editor instance
-                var editorID = Math.ceil(Math.random() * 99999),
-                    fieldName = $(this).attr('data-field-name') ? $(this).attr('data-field-name') : 'free_text';
-
-                var el = this;
-                var existingContent = $(el).html();
-                var quill = new Quill(el, {
-                    theme: 'snow',
-                    modules: stagQuillConfig
-                });
-
-                var toolbar = $(quill.container).prev('.ql-toolbar');
-
-                // add button for new shortcut
-                if(!noteRTE.is('[use-shortcuts]') || !noteRTE.attr('use-shortcuts')) {
-                    var newSCButton = $('<button class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
-                        'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
-                    toolbar.append(newSCButton);
-                }
-
-                quill.root.innerHTML = existingContent;
-
-                let onTextChange = function(delta, oldDelta, source) {
-                    var content = quill.root.innerHTML;
-                    let dataObject = {};
-                    dataObject[fieldName] = content;
-                    var dataValue = JSON.stringify(dataObject);
-                    let pElem = $(el).closest('[visit-moe]');
-                    if(!pElem.length) {
-                        pElem = $(el).closest('form');
-                    }
-                    pElem.find('input[name=data]').val(dataValue);
-                };
-
-                quill.on('text-change', onTextChange);
-
-                $(quill.container)
-                    .find('.ql-editor[contenteditable]')
-                    .attr('data-field', fieldName)
-                    .attr('data-editor-id', editorID)
-                    .attr('with-shortcuts', 1);
-
-                // set value initially
-                onTextChange();
-            });
-        }
         function init() {
             let parentSegment = $('#medications-center-{{$note->id}}');
             parentSegment.find('input[stag-suggest][data-name="name"]')
@@ -507,235 +281,23 @@ $medications = $points;
                     $(_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();
-                        form.find('.prescriber_ui').show();
-                        form.find('.removalEffectiveDate_ui').show();
-                        form.find('.removalReasonMemo_ui').show();
-                    }
-                    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();
-                        form.find('.prescriber_ui').show();
-                    }
-                    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('[name="isRemoved"], [name="isRemovedDueToEntryError"]')
-                .off('change')
-                .on('change', function () {
-                    let form = $(this).closest('form');
-
-                    form.find('.is_removed_ui_1').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1') {
-                        form.find('.is_removed_ui_1').show();
-                    }
-
-                    form.find('.is_removed_ui_2').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1' && form.find('[name="isRemovedDueToEntryError"]').val() !== '1') {
-                        form.find('.is_removed_ui_2').show();
-                    }
-                    return false;
-                });
-
-            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());
-                    }
-
-                    @if($patient->core_note_id !== $note->id)
-                    // store plan content
-                    let planContent = parsed.value ? parsed.value : '';
-                    if(!$.trim($('<div/>').html(planContent).text())) {
-                        toastr.error('Directions cannot be empty');
-                        return false;
-                    }
-                    if(parsed.value) delete parsed.value;
-                    @endif
-
-                    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();
-                                }
-                            }
-                        }
 
+                    $('.fdb-rx-vigilance').html('<span class="text-secondary font-italic">Please wait ...</span>');
+                    $.post('/fdb-rx-vigilance/{{$patient->uid}}', {
+                        _token: '{{csrf_token()}}',
+                        medId: _data.medid,
+                        routedMedId: _data.routed_med_id,
+                        routedDosageFormMedId: _data.routed_dosage_form_med_id,
+                        gcnSeqno: _data.gcn_seqno,
+                        name: _input.val(),
+                    }, _data => {
+                        $('.fdb-rx-vigilance').html(_data);
                     });
-                    if(parsed) {
-                        dataField.val(JSON.stringify(parsed));
-                    }
-
-                    $.post(form.attr('action'), form.serialize(), _data => {
-                        if(!hasResponseError(_data)) {
-
-                            hideMask();
-
-                            // save child plan
-                            @if($patient->core_note_id !== $note->id)
-                                debugger
-                            $.post('/api/visitPoint/upsertChildPlan', {
-                                uid: _data.data,
-                                segmentUid: '{{$note->getSegmentByInternalName('plan_medications')->uid}}',
-                                data: JSON.stringify({value: planContent})
-                            }, _data => {
-                                if(!hasResponseError(_data)) {
-                                    refreshDynamicStagPopup();
-                                }
-                            }, 'json');
-                            @else
-                            refreshDynamicStagPopup();
-                            @endif
 
-                            $('.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;
-                });
-
-            parentSegment.find('.toggle-relevance')
-                .off('click.toggle-relevance')
-                .on('click.toggle-relevance', function () {
-                    if(+$(this).attr('data-relevant') === 0) {
-                        $.post('/api/visitPoint/markPointRelevantToNote', {
-                            noteUid: '{{$note->uid}}',
-                            pointUid: $(this).attr('data-point-uid')
-                        }, _data => {
-                            if(!hasResponseError(_data)) {
-                                refreshDynamicStagPopup();
-                            }
-                        }, 'json');
-                    }
-                    else {
-                        if($(this).attr('data-rel-uid')) {
-                            $.post('/api/visitPoint/undoMarkPointRelevantToNote', {
-                                uid: $(this).attr('data-rel-uid')
-                            }, _data => {
-                                if(!hasResponseError(_data)) {
-                                    refreshDynamicStagPopup();
-                                }
-                            }, 'json');
-                        }
-                        else {
-                            console.log('Error - missing rel uid');
-                        }
-                    }
-                    return false;
-                });
-
-            initStagSuggest();
-
-            parentSegment.find('.additionReasonCategory_ui').trigger('change');
-            parentSegment.find('[name="isRemoved"]').trigger('change');
+            @include('app.patient.wizard-partials.common-script', ['label' => 'medication'])
 
             // custom buttons on title bar
             $('.button-container').remove();
@@ -773,7 +335,7 @@ $medications = $points;
             buttonContainer.insertAfter(titleElem);
 
             initSegmentMoes(parentSegment);
-            initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
+            __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
         }
         addMCInitializer('medications-center-{{$note->id}}', init, '#medications-center-{{$note->id}}');
     }).call(window);

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

@@ -2253,13 +2253,13 @@
 
                     @if($isVisitTemplateBased)
                     <div class="position-sticky note-bottom-toolbar border-top border-info p-0 bg-aliceblue d-flex align-items-stretch">
-                        <div class="nbt-container px-2 py-1 border-right border-info">
+                        <div class="nbt-container border-right border-info">
                             <!-- render mrv segment here -->
                             <?php $segment = null; ?>
                             @foreach($note->segments as $segment)
                                 @if($segment->segmentTemplate->internal_name === 'medrisk_vigilence')
                                     <div native target="_blank"
-                                         class="d-block c-pointer mrv-trigger d-flex align-items-center"
+                                         class="d-block c-pointer mrv-trigger d-flex align-items-center px-2 py-1"
                                          open-in-stag-popup
                                          title="MedRisk Vigilance"
                                          popup-style="stag-popup-md"
@@ -2270,9 +2270,9 @@
                                 @endif
                             @endforeach
                         </div>
-                        <div class="nbt-container px-2 py-1 border-right border-info d-inline-flex align-self-stretch">
+                        <div class="nbt-container border-right border-info d-inline-flex align-self-stretch">
                             <div native target="_blank"
-                                 class="c-pointer d-inline-flex align-items-center"
+                                 class="c-pointer d-inline-flex align-items-center medications-center-trigger px-2 py-1"
                                  open-in-stag-popup
                                  mc-initer="medications-center-{{$note->id}}"
                                  title="Medications Center"
@@ -2282,9 +2282,9 @@
                                 <span>Rx</span>
                             </div>
                         </div>
-                        <div class="nbt-container px-2 py-1 border-right border-info d-inline-flex align-self-stretch">
+                        <div class="nbt-container border-right border-info d-inline-flex align-self-stretch">
                             <div native target="_blank"
-                                 class="c-pointer d-inline-flex align-items-center"
+                                 class="c-pointer d-inline-flex align-items-center problems-center-trigger px-2 py-1"
                                  open-in-stag-popup
                                  mc-initer="problems-center-{{$note->id}}"
                                  title="Problems Center"
@@ -2294,9 +2294,9 @@
                                 <span>Dx</span>
                             </div>
                         </div>
-                        <div class="nbt-container px-2 py-1 border-right border-info d-inline-flex align-self-stretch">
+                        <div class="nbt-container border-right border-info d-inline-flex align-self-stretch">
                             <div native target="_blank"
-                                 class="c-pointer d-inline-flex align-items-center"
+                                 class="c-pointer d-inline-flex align-items-center goals-center-trigger px-2 py-1"
                                  open-in-stag-popup
                                  mc-initer="goals-center-{{$note->id}}"
                                  title="Goals Center"
@@ -2306,9 +2306,9 @@
                                 <span>Goals</span>
                             </div>
                         </div>
-                        <div class="nbt-container px-2 py-1 border-right border-info d-inline-flex align-self-stretch">
+                        <div class="nbt-container border-right border-info d-inline-flex align-self-stretch">
                             <div native target="_blank"
-                                 class="c-pointer d-inline-flex align-items-center"
+                                 class="c-pointer d-inline-flex align-items-center allergies-center-trigger px-2 py-1"
                                  open-in-stag-popup
                                  mc-initer="allergies-center-{{$note->id}}"
                                  title="Allergies Center"
@@ -2318,8 +2318,20 @@
                                 <span>Allergies</span>
                             </div>
                         </div>
-                        <div class="nbt-container px-2 py-1 border-right border-info d-inline-flex align-self-stretch">
-                            <div class="position-relative on-click-menu d-inline-flex align-items-center">
+                        <div class="nbt-container border-right border-info d-inline-flex align-self-stretch">
+                            <div native target="_blank"
+                                 class="c-pointer d-inline-flex align-items-center careteam-center-trigger px-2 py-1"
+                                 open-in-stag-popup
+                                 mc-initer="careteam-center-{{$note->id}}"
+                                 title="Careteam Center"
+                                 popup-style="wide overflow-visible"
+                                 href="/careteam-center/{{$patient->uid}}/{{$note->uid}}">
+                                <i class="fa fa-bolt mr-1"></i>
+                                <span>Care Team</span>
+                            </div>
+                        </div>
+                        <div class="nbt-container border-right border-info d-inline-flex align-self-stretch">
+                            <div class="position-relative on-click-menu d-inline-flex align-items-center px-2 py-1">
                                 <span class="">Lifestyle <i class="fa fa-caret-up"></i></span>
                                 <div menu bottom class="bg-white border">
                                     <a href="#" class="ls-segment-trigger px-2 py-1 text-nowrap d-block" data-target="lifestyle_general">General</a>

+ 22 - 0
resources/views/app/patient/note/dashboard_script.blade.php

@@ -117,6 +117,28 @@
                         // TODO: do this in the proper place
                         if(editParent.is('[data-segment-template-name="medrisk_vigilence"]')) return false;
 
+                        // TEMP: show wizard for allergies, rx, dx, goals
+                        if(editParent.is('[data-segment-template-name="plan_allergies"]') ||
+                            editParent.is('[data-segment-template-name="intake_allergies"]')) {
+                            $('.note-bottom-toolbar .allergies-center-trigger').trigger('click');
+                            return false;
+                        }
+                        else if(editParent.is('[data-segment-template-name="plan_problems"]') ||
+                            editParent.is('[data-segment-template-name="intake_problems"]')) {
+                            $('.note-bottom-toolbar .problems-center-trigger').trigger('click');
+                            return false;
+                        }
+                        else if(editParent.is('[data-segment-template-name="plan_medications"]') ||
+                            editParent.is('[data-segment-template-name="intake_medications"]')) {
+                            $('.note-bottom-toolbar .medications-center-trigger').trigger('click');
+                            return false;
+                        }
+                        else if(editParent.is('[data-segment-template-name="plan_goals"]') ||
+                            editParent.is('[data-segment-template-name="intake_goals"]')) {
+                            $('.note-bottom-toolbar .goals-center-trigger').trigger('click');
+                            return false;
+                        }
+
                         // TEMP: open in popup if LS segment
                         if(editParent.is('[data-segment-template-name^="lifestyle_"]')) {
                             showStagPopup('segment-popup-' + editParent.attr('data-segment-template-name'), true);

+ 3 - 3
resources/views/app/patient/note/segment_script.blade.php

@@ -1,7 +1,7 @@
 <script>
     (function() {
 
-        function updateAllSegmentsInResponse(_response, _updateListeners = true) {
+        window.updateAllSegmentsInResponse = function(_response, _updateListeners = true) {
             if(!hasResponseError(_response)) {
 
                 // refresh primary segment (where uid is _response.data.uid)
@@ -37,7 +37,7 @@
             }
         }
 
-        function updateSegmentByUid(_uid, _summaryHtml, _editHtml) {
+        window.updateSegmentByUid = function(_uid, _summaryHtml, _editHtml) {
             let segment = $('.note-section[data-segment-uid="' + _uid + '"]');
             if(segment && segment.length) {
                 segment.find('.summary-container').html(_summaryHtml);
@@ -63,7 +63,7 @@
             }
         }
 
-        function updateSegmentFromObject(_object) {
+        window.updateSegmentFromObject = function(_object) {
             let segment = $('.note-section[data-segment-uid="' + _object.segmentUid + '"]');
             if(segment && segment.length) {
                 segment.find('.summary-container').html(_object.summaryHtml);

+ 5 - 5
resources/views/app/patient/note/sign-confirmation.blade.php

@@ -159,22 +159,22 @@
 
         function init() {
 
-            if($('.relevant-without-review.block-signing[data-target-segment]').length) {
+            /*if($('.relevant-without-review.block-signing[data-target-segment]').length) {
                 alert('Review missing for one or more problems relevant to this note!');
                 closeStagPopup(true);
                 $('.note-tree-node [data-segment-internal-name="' + $('.relevant-without-review.block-signing[data-target-segment]').first().attr('data-target-segment') + '"]').trigger('click');
                 return false;
-            }
+            }*/
 
-            if($('.relevant-without-plan.block-signing[data-target-segment]').length) {
+            /*if($('.relevant-without-plan.block-signing[data-target-segment]').length) {
                 alert('Plan missing for one or more problems relevant to this note!');
                 closeStagPopup(true);
                 $('.note-tree-node [data-segment-internal-name="' + $('.relevant-without-plan.block-signing[data-target-segment]').first().attr('data-target-segment') + '"]').trigger('click');
                 return false;
-            }
+            }*/
 
             if($('.no-relevant-with-icd.block-signing[data-target-segment]').length) {
-                alert('Need at least 1 relevant problem with an ICD before the note can be signed.');
+                alert('Need at least 1 relevant problem (with ICD) with associated HPI before the note can be signed.');
                 closeStagPopup(true);
                 $('.note-tree-node [data-segment-internal-name="' + $('.no-relevant-with-icd.block-signing[data-target-segment]').first().attr('data-target-segment') + '"]').trigger('click');
                 return false;

+ 2 - 0
resources/views/app/patient/notes.blade.php

@@ -8,6 +8,7 @@
             <span class="font-weight-bold text-secondary">Notes</span>
             @if($patient->getPrimaryCoverageStatus() === 'YES')
                 <span class="mx-2 text-secondary">|</span>
+                {{--
                 <div moe>
                     <a start show class="py-0 mb-3">Add</a>
 
@@ -60,6 +61,7 @@
                     </form>
                 </div>
                 <span class="mx-2 text-secondary">|</span>
+                --}}
                 <div moe>
                 <a start show class="py-0 mb-3 text-info font-weight-bold">Add Visit</a>
                 <form url="/api/visit/create"

+ 8 - 3
resources/views/app/patient/page-sections/vitals/form.blade.php

@@ -136,9 +136,14 @@ $formID = rand(0, 100000);
                                    data-option-list="smokingStatus"
                                    v-on:change="autoDate(items['smokingStatus'], 'smokingStatus')" v-on:keyup="autoDate(items['smokingStatus'], 'smokingStatus')">
                             <div id="smoking-status-options" class="data-option-list">
-                                <div>Current</div>
-                                <div>Former</div>
-                                <div>Never</div>
+                                <div>Current every day smoker</div>
+                                <div>Former some day smoker</div>
+                                <div>Former smoker</div>
+                                <div>Never smoker</div>
+                                <div>Smoker, current status unknown</div>
+                                <div>Unknown if ever smoked</div>
+                                <div>Heavy tobacco smoker</div>
+                                <div>Light tobacco smoker</div>
                             </div>
                         @else
                             <input type="text"

+ 1 - 1
resources/views/app/patient/prescriptions-popup/hcp-pro-form.blade.php

@@ -1,7 +1,7 @@
 <div class="stag-popup stag-popup-sm mcp-theme-1 min-height-unset" stag-popup-key="pp-hcp-pro-popup">
     <form method="POST" action="" class="overflow-visible">
         <h3 class="stag-popup-title mb-2">
-            <span>HCP Pro</span>
+            <span>Prescribed By</span>
             <a href="#" class="ml-auto text-secondary"
                onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
         </h3>

+ 25 - 10
resources/views/app/patient/prescriptions-popup/list-popup.blade.php

@@ -270,7 +270,10 @@
 
             <hr class="my-3">
             <div class="pb-2 d-flex align-items-center">
-                <span class="min-width-140px text-secondary text-sm">Logistics</span>
+                <span v-if="currentPrescription.erx_category === 'DRUG'" class="min-width-140px text-secondary text-sm">Pharmacy</span>
+                <span v-else-if="currentPrescription.erx_category === 'LAB'" class="min-width-140px text-secondary text-sm">Lab</span>
+                <span v-else-if="currentPrescription.erx_category === 'IMAGING'" class="min-width-140px text-secondary text-sm">Lab</span>
+                <span v-else class="min-width-140px text-secondary text-sm">Logistics</span>
                 <div class="d-inline-flex align-items-baseline flex-grow-1">
                     <a class="mr-2" href="#" v-on:click.prevent="editLogisticsDetails(currentPrescription)"><i class="fa fa-edit on-hover-opaque"></i></a>
                     <div v-if="currentPrescription.logistics_detail_json" class="d-flex align-items-baseline">
@@ -284,7 +287,7 @@
                 </div>
             </div>
             <div class="pb-2 d-flex align-items-center">
-                <span class="min-width-140px text-secondary text-sm">HCP Pro</span>
+                <span class="min-width-140px text-secondary text-sm">Prescribed By</span>
                 <div class="d-inline-flex align-items-baseline flex-grow-1">
                     <a v-if="!currentPrescription.has_hcp_pro_signed" class="mr-2" href="#" v-on:click.prevent="editHcpPro(currentPrescription)"><i class="fa fa-edit on-hover-opaque"></i></a>
                     <span v-else class="mr-2" title="Cannot edit. Prescription already signed."><i class="fa fa-edit on-hover-opaque text-secondary"></i></span>
@@ -305,7 +308,7 @@
                 </div>
             </div>
             <div class="pb-2 d-flex align-items-center">
-                <span class="min-width-140px text-secondary text-sm">Pro Status</span>
+                <span class="min-width-140px text-secondary text-sm">Prescription Status</span>
                 <div class="d-inline-flex align-items-baseline">
                     <a class="mr-2" href="#" v-on:click.prevent="editProStatus(currentPrescription)"><i class="fa fa-edit on-hover-opaque"></i></a>
                     <div v-if="currentPrescription.pro_declared_status" class="d-flex align-items-baseline">
@@ -906,7 +909,7 @@ GROUP BY erx_category");
                             _numPages = 1;
                             _page = 1;
 
-                            $('#transmit-pdf-preview>canvas').remove();
+                            $('#pp-transmit-pdf-preview>canvas').remove();
 
                             let url = _url;
                             let pdfjsLib = window['pdfjs-dist/build/pdf'];
@@ -928,7 +931,7 @@ GROUP BY erx_category");
                                 // create canvas
                                 let canvasElement = $('<canvas/>')
                                     .addClass('pdf-viewer-page pdf-preview-page')
-                                    .appendTo('#transmit-pdf-preview');
+                                    .appendTo('#pp-transmit-pdf-preview');
 
                                 let canvas = canvasElement[0];
                                 let viewport = page.getViewport({scale: 0.75});
@@ -995,17 +998,29 @@ GROUP BY erx_category");
                         return true;
                     },
                     addExistingDrugToERx: function(_uid) {
+                        let existing = this.existingDrugs.filter(_x => {
+                            return _x.uid === _uid;
+                        });
+                        if(!existing || !existing.length) return false;
+                        existing = existing[0];
+
+                        // require dispense and refills
+                        if(!existing.data.dispense) {
+                            toastr.error('Dispense cannot be blank');
+                            return false;
+                        }
+                        if(!existing.data.refills) {
+                            toastr.error('Refills cannot be blank');
+                            return false;
+                        }
+
                         if(!this.currentPrescription.clinical_detail_json) {
                             this.currentPrescription.clinical_detail_json = {};
                         }
                         if(!this.currentPrescription.clinical_detail_json.items) {
                             this.currentPrescription.clinical_detail_json.items = [];
                         }
-                        let existing = this.existingDrugs.filter(_x => {
-                            return _x.uid === _uid;
-                        });
-                        if(!existing || !existing.length) return false;
-                        existing = existing[0];
+
                         this.currentPrescription.clinical_detail_json.items.push({
                             medication: existing.data.name,
                             dispense: existing.data.dispense,

+ 4 - 1
resources/views/app/patient/prescriptions-popup/logistics-form.blade.php

@@ -1,7 +1,10 @@
 <div class="stag-popup stag-popup-sm mcp-theme-1" stag-popup-key="pp-logistics-popup">
     <form method="POST" action="" class="overflow-visible min-height-300px">
         <h3 class="stag-popup-title mb-2">
-            <span>Logistics</span>
+            <span v-if="currentPrescription && currentPrescription.erx_category === 'DRUG'">Pharmacy</span>
+            <span v-else-if="currentPrescription && currentPrescription.erx_category === 'LAB'">Lab</span>
+            <span v-else-if="currentPrescription && currentPrescription.erx_category === 'IMAGING'">Lab</span>
+            <span v-else>Logistics</span>
             <a href="#" class="ml-auto text-secondary"
                onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
         </h3>

+ 1 - 1
resources/views/app/patient/prescriptions-popup/pro-status-form.blade.php

@@ -1,7 +1,7 @@
 <div class="stag-popup stag-popup-sm mcp-theme-1 min-height-unset" stag-popup-key="pp-pro-status-popup">
     <form method="POST" action="" class="overflow-visible">
         <h3 class="stag-popup-title mb-2">
-            <span>Pro Declared Status</span>
+            <span>Prescription Status</span>
             <a href="#" class="ml-auto text-secondary"
                onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
         </h3>

+ 1 - 1
resources/views/app/patient/prescriptions-popup/transmit-form.blade.php

@@ -7,7 +7,7 @@
         </h3>
         <div class="mb-3 pb-3 border-bottom">
             <p class="text-secondary text-sm mb-2 text-center">Document Preview</p>
-            <div id="transmit-pdf-preview">
+            <div id="pp-transmit-pdf-preview">
 
             </div>
         </div>

+ 1 - 1
resources/views/app/patient/prescriptions/hcp-pro-form.blade.php

@@ -1,7 +1,7 @@
 <div class="stag-popup stag-popup-sm mcp-theme-1 min-height-unset" stag-popup-key="hcp-pro-popup">
     <form method="POST" action="" class="overflow-visible">
         <h3 class="stag-popup-title mb-2">
-            <span>HCP Pro</span>
+            <span>Prescribed By</span>
             <a href="#" class="ml-auto text-secondary"
                onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
         </h3>

+ 22 - 8
resources/views/app/patient/prescriptions/list.blade.php

@@ -279,7 +279,10 @@
 
             <hr class="my-3">
             <div class="pb-2 d-flex align-items-center">
-                <span class="min-width-140px text-secondary text-sm">Logistics</span>
+                <span v-if="currentPrescription.erx_category === 'DRUG'" class="min-width-140px text-secondary text-sm">Pharmacy</span>
+                <span v-else-if="currentPrescription.erx_category === 'LAB'" class="min-width-140px text-secondary text-sm">Lab</span>
+                <span v-else-if="currentPrescription.erx_category === 'IMAGING'" class="min-width-140px text-secondary text-sm">Lab</span>
+                <span v-else class="min-width-140px text-secondary text-sm">Logistics</span>
                 <div class="d-inline-flex align-items-baseline flex-grow-1">
                     <a class="mr-2" href="#" v-on:click.prevent="editLogisticsDetails(currentPrescription)"><i class="fa fa-edit on-hover-opaque"></i></a>
                     <div v-if="currentPrescription.logistics_detail_json" class="d-flex align-items-baseline">
@@ -293,7 +296,7 @@
                 </div>
             </div>
             <div class="pb-2 d-flex align-items-center">
-                <span class="min-width-140px text-secondary text-sm">HCP Pro</span>
+                <span class="min-width-140px text-secondary text-sm">Prescribed By</span>
                 <div class="d-inline-flex align-items-baseline flex-grow-1">
                     <a v-if="!currentPrescription.has_hcp_pro_signed" class="mr-2" href="#" v-on:click.prevent="editHcpPro(currentPrescription)"><i class="fa fa-edit on-hover-opaque"></i></a>
                     <span v-else class="mr-2" title="Cannot edit. Prescription already signed."><i class="fa fa-edit on-hover-opaque text-secondary"></i></span>
@@ -314,7 +317,7 @@
                 </div>
             </div>
             <div class="pb-2 d-flex align-items-center">
-                <span class="min-width-140px text-secondary text-sm">Pro Status</span>
+                <span class="min-width-140px text-secondary text-sm">Prescription Status</span>
                 <div class="d-inline-flex align-items-baseline">
                     <a class="mr-2" href="#" v-on:click.prevent="editProStatus(currentPrescription)"><i class="fa fa-edit on-hover-opaque"></i></a>
                     <div v-if="currentPrescription.pro_declared_status" class="d-flex align-items-baseline">
@@ -1013,17 +1016,28 @@ GROUP BY erx_category");
                         return true;
                     },
                     addExistingDrugToERx: function(_uid) {
+                        let existing = this.existingDrugs.filter(_x => {
+                            return _x.uid === _uid;
+                        });
+                        if(!existing || !existing.length) return false;
+                        existing = existing[0];
+
+                        // require dispense and refills
+                        if(!existing.data.dispense) {
+                            toastr.error('Dispense cannot be blank');
+                            return false;
+                        }
+                        if(!existing.data.refills) {
+                            toastr.error('Refills cannot be blank');
+                            return false;
+                        }
+
                         if(!this.currentPrescription.clinical_detail_json) {
                             this.currentPrescription.clinical_detail_json = {};
                         }
                         if(!this.currentPrescription.clinical_detail_json.items) {
                             this.currentPrescription.clinical_detail_json.items = [];
                         }
-                        let existing = this.existingDrugs.filter(_x => {
-                            return _x.uid === _uid;
-                        });
-                        if(!existing || !existing.length) return false;
-                        existing = existing[0];
                         this.currentPrescription.clinical_detail_json.items.push({
                             medication: existing.data.name,
                             dispense: existing.data.dispense,

+ 6 - 1
resources/views/app/patient/prescriptions/logistics-form.blade.php

@@ -1,7 +1,12 @@
 <div class="stag-popup stag-popup-sm mcp-theme-1" stag-popup-key="logistics-popup">
     <form method="POST" action="" class="overflow-visible min-height-300px">
         <h3 class="stag-popup-title mb-2">
-            <span>Logistics</span>
+
+            <span v-if="currentPrescription && currentPrescription.erx_category === 'DRUG'">Pharmacy</span>
+            <span v-else-if="currentPrescription && currentPrescription.erx_category === 'LAB'">Lab</span>
+            <span v-else-if="currentPrescription && currentPrescription.erx_category === 'IMAGING'">Lab</span>
+            <span v-else>Logistics</span>
+
             <a href="#" class="ml-auto text-secondary"
                onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
         </h3>

+ 1 - 1
resources/views/app/patient/prescriptions/pro-status-form.blade.php

@@ -1,7 +1,7 @@
 <div class="stag-popup stag-popup-sm mcp-theme-1 min-height-unset" stag-popup-key="pro-status-popup">
     <form method="POST" action="" class="overflow-visible">
         <h3 class="stag-popup-title mb-2">
-            <span>Pro Declared Status</span>
+            <span>Prescription Status</span>
             <a href="#" class="ml-auto text-secondary"
                onclick="return closeStagPopup()"><i class="fa fa-times-circle"></i></a>
         </h3>

+ 1 - 0
resources/views/app/patient/primary-coverage.blade.php

@@ -26,6 +26,7 @@
             $cpc->auto_detail_json = json_decode($cpc->auto_detail_json);
         @endphp
         <div class="d-flex mb-2">
+            <h1>Is Covered: {{$cpc->is_covered}}</h1>
             @if($cpc->plan_type == 'MEDICARE')
                 @include('app.patient.primary-coverage-refresh', ['endpoint'=>'refreshCoverageForMedicare'])
                 <span class="mx-2 text-secondary text-sm">|</span>

+ 122 - 510
resources/views/app/patient/problems-center.blade.php

@@ -8,21 +8,7 @@ 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;
-
+$problems = Point::getPointsOfCategoryExtended($patient, 'PROBLEM', $note);
 $ccSegment = $note->getSegmentByInternalName('chief_complaint');
 ?>
 
@@ -49,24 +35,24 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                 @endif
                 <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">Started</th>
                 <th class="border-bottom-0 text-secondary">Ended</th>
-                <th class="border-bottom-0 text-secondary w-25">Last Review</th>
-                <th class="border-bottom-0 text-secondary w-25">Last Plan</th>
+                <th class="border-bottom-0 text-secondary w-25">HPI</th>
+                <th class="border-bottom-0 text-secondary w-25">Plan</th>
+                <th class="border-bottom-0 text-secondary">Edit</th>
             </tr>
             </thead>
-            <?php $prevRowRemoved = -1; ?>
+            <?php $prevRowState = -1; ?>
             <?php foreach($problems as $problem): ?>
             <?php $point = $problem; ?>
-            @if($prevRowRemoved !== -1 && $prevRowRemoved !== $problem->is_removed)
+            @if($prevRowState !== -1 && $prevRowState !== $problem->state)
                 <tr>
                     <td colspan="9" class="px-0 pt-1 pb-0 on-hover-opaque bg-secondary"></td>
                 </tr>
             @endif
-            <?php $prevRowRemoved = $problem->is_removed; ?>
+            <?php $prevRowState = $problem->state; ?>
             <?php $rel = $problem->relevanceToNote($note); ?>
-            <tr class="">
+            <tr class="{{$rel ? 'relevant-to-visit' : ''}}">
                 @if($patient->core_note_id !== $note->id)
                 <td class="text-center">
                     <a href="#" class="toggle-relevance"
@@ -84,10 +70,14 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                 @endif
                 <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>
+                        @if($problem->state === 1)
+                            <i class="text-success fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($problem->state === 2)
+                            <i class="text-info fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($problem->state === 3)
+                            <i class="text-warning-mellow fa fa-circle text-sm on-hover-opaque mr-2 active-record"></i>
+                        @elseif($problem->state === 4)
+                            <i class="text-secondary fa fa-circle text-sm on-hover-opaque mr-2"></i>
                         @endif
                         <div>
                             <b><?= !!@($problem->data->name) ? @($problem->data->name) : '-' ?></b>
@@ -116,6 +106,11 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                                     @endif
                                 </div>
                             @endif
+                            @if($rel)
+                                <div class="mt-1">
+                                    <span class="text-sm text-white bg-info rounded px-2 py-1 font-weight-bold">Visit reason</span>
+                                </div>
+                            @endif
                         </div>
                     </div>
                 </td>
@@ -126,143 +121,11 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                         <b>YES</b>
                     @endif
                 </td>
-                <td>
-                    <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>
-
-                            @if($problem->added_in_note_id === $note->id)
-
-                                <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-0">ICD</label>
-                                    <select data-name="icd"
-                                            class="form-control form-control-sm"
-                                            disabled>
-                                    </select>
-                                </div>
-
-                                <div class="row mb-2">
-                                    <div class="col-6 pr-0">
-                                        <label class="text-sm mb-0">Start Date</label>
-                                        <input type="date"
-                                               data-name="start_date"
-                                               value="{{@$problem->data->start_date}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                    <div class="col-6">
-                                        <label class="text-sm mb-0">Added By</label>
-                                        <input type="text"
-                                               data-name="prescriber"
-                                               value="{{@$problem->data->prescriber}}"
-                                               class="form-control form-control-sm min-width-unset">
-                                    </div>
-                                </div>
-
-                            @else
-
-                                <div class="mb-2 bg-light p-2 border">
-                                    <p class="mb-1 font-weight-bold">
-                                        {{ @$problem->data->name }}
-                                    </p>
-                                    @if($patient->core_note_id !== $note->id)
-                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the problem was added prior to this visit.</div>
-                                    @else
-                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the problem was added on a previous visit.</div>
-                                    @endif
-                                </div>
-
-                            @endif
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$problem->addition_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$problem->addition_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           value="{{$problem->addition_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is problem active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="">-- select --</option>
-                                        <option value="0" {{!$problem->is_removed ? 'selected' : ''}}>Yes</option>
-                                        <option value="1" {{$problem->is_removed ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                                <div class="col-6 is_removed_ui_1" style="display: none">
-                                    <label class="text-sm mb-0 min-width-unset">Is entry error?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemovedDueToEntryError">
-                                        <option value="1" {{$problem->is_removed_due_to_entry_error ? 'selected' : ''}}>Yes</option>
-                                        <option value="0" {{!$problem->is_removed_due_to_entry_error ? 'selected' : ''}}>No</option>
-                                    </select>
-                                </div>
-                            </div>
-
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE" {{$problem->removal_reason_category === 'ON_INTAKE' ? 'selected' : ''}}>On Intake</option>
-                                        <option value="DURING_VISIT" {{$problem->removal_reason_category === 'DURING_VISIT' ? 'selected' : ''}}>During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           value="{{$problem->removal_effective_date ? $problem->removal_effective_date : ''}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           value="{{$problem->removal_reason_memo}}"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </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>
-                </td>
                 <td>
                     <?= !!@($problem->data->start_date) ? friendly_date($problem->data->start_date) : '-' ?>
+                    @if(!!@($problem->data->prescriber))
+                        <div class="mt-1 text-sm text-secondary">By: <?= !!@($problem->data->prescriber) ? @($problem->data->prescriber) : '-' ?></div>
+                    @endif
                 </td>
                 <td>
                     <?= !!@($problem->removal_effective_date) ? friendly_date($problem->removal_effective_date) : '-' ?>
@@ -279,7 +142,7 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                             ?>
                         </div>
                         <div class="d-inline-flex flex-nowrap">
-                            <a class="px-2 view-review-log"
+                            <a class="pl-2 view-review-log"
                                native target="_blank"
                                open-in-stag-popup
                                popup-style="stag-popup-md"
@@ -288,10 +151,10 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                                 <i class="fa fa-history"></i>
                             </a>
                             <?php
-                            $segment = $note->getSegmentByInternalName('intake_problems');
+                            /*$segment = $note->getSegmentByInternalName('intake_problems');
                             if($segment) {
                                 include resource_path('views/app/patient/segment-templates/_child_review/edit-review.php');
-                            }
+                            }*/
                             ?>
                         </div>
                     </div>
@@ -304,7 +167,7 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                             ?>
                         </div>
                         <div class="d-inline-flex flex-nowrap">
-                            <a class="px-2 view-review-log"
+                            <a class="pl-2 view-review-log"
                                native target="_blank"
                                open-in-stag-popup
                                popup-style="stag-popup-md"
@@ -313,20 +176,78 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                                 <i class="fa fa-history"></i>
                             </a>
                             <?php
-                            $segment = $note->getSegmentByInternalName('plan_problems');
+                            /*$segment = $note->getSegmentByInternalName('plan_problems');
                             if($segment) {
                                 include resource_path('views/app/patient/segment-templates/_child_plan/edit-plan.php');
-                            }
+                            }*/
                             ?>
                         </div>
                     </div>
                 </td>
+                <td>
+                    <div moe huge relative>
+                        <a start show href="#" title="Edit">Edit</a>
+                        <form url="/api/visitPoint/updateTopLevel" class="mcp-theme-1 frm-edit-problem" right>
+                            <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" value='{{json_encode($problem->data)}}'>
+
+                            @if($problem->added_in_note_id === $note->id)
+
+                                <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-0">ICD</label>
+                                    <input type="text"
+                                           data-name="icd"
+                                           data-option-list
+                                           class="form-control form-control-sm"
+                                           value="{{@$problem->data->icd}}">
+                                    <div class="data-option-list"></div>
+                                </div>
+
+                            @else
+
+                                <div class="mb-2 bg-light p-2 border">
+                                    <p class="mb-1 font-weight-bold">
+                                        {{ @$problem->data->name }}
+                                    </p>
+                                    @if($patient->core_note_id !== $note->id)
+                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the problem was added prior to this visit.</div>
+                                    @else
+                                        <div class="text-secondary text-sm">Clinical details cannot be modified since the problem was added on a previous visit.</div>
+                                    @endif
+                                </div>
+
+                            @endif
+
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'problem', 'point' => $problem, 'reviewLabel' => 'HPI', 'addVerbPT' => 'Diagnosed'])
+
+                            <div class="mt-3 pt-2 d-flex align-items-center border-top">
+                                <button type="submit" class="btn-save-problem btn btn-sm btn-primary mr-2">Save</button>
+                                <button cancel class="btn btn-sm bg-light btn-default border">Cancel</button>
+                            </div>
+                        </form>
+                    </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">
+            <div class="mt-1 w-100 border p-3 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">
@@ -335,10 +256,11 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                     <input type="hidden" data-name="dxid">
                     <input type="hidden" data-name="icd-type">
 
-                    <p class="mb-2"><b>Add Problem</b></p>
+                    <input type="hidden" name="isRemovedDueToEntryError" value="0">
 
                     <div class="row">
-                        <div class="col-7">
+                        <div class="col-8">
+                            <p class="mb-2"><b>Add Problem</b></p>
                             <div class="row mb-2">
                                 <div class="col-8 pr-0">
                                     <label class="text-sm text-secondary mb-0">Name</label>
@@ -352,94 +274,28 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
                                 </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-6 pr-0">
-                                    <label class="text-sm mb-0">Start Date</label>
-                                    <input type="date"
-                                           data-name="start_date"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-6">
-                                    <label class="text-sm mb-0">Added By</label>
                                     <input type="text"
-                                           data-name="prescriber"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-                            <!--<div class="mb-2">
-                                <label class="text-sm mb-1">Description</label>
-                                <textarea rows="1" data-name="description" class="form-control form-control-sm"></textarea>
-                            </div>-->
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0">When Added</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="additionReasonCategory" required>
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-8">
-                                    <label class="text-sm mb-0 min-width-unset">Addition Memo</label>
-                                    <input type="text"
-                                           name="additionReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
-
-                            <hr class="my-3">
-
-                            <div class="row mb-2">
-                                <div class="col-6 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">Is problem active?</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="isRemoved" required>
-                                        <option value="0" selected>Yes</option>
-                                        <option value="1">No</option>
-                                    </select>
+                                           data-name="icd"
+                                           data-option-list
+                                           class="form-control form-control-sm"
+                                           disabled>
+                                    <div class="data-option-list"></div>
                                 </div>
-                                <input type="hidden" name="isRemovedDueToEntryError" value="0">
                             </div>
 
-                            <div class="row mb-2 is_removed_ui_2" style="display: none">
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">When Removed</label>
-                                    <select class="form-control form-control-sm min-width-unset" name="removalReasonCategory">
-                                        <option value="">-- select --</option>
-                                        <option value="ON_INTAKE">On Intake</option>
-                                        <option value="DURING_VISIT">During Visit</option>
-                                    </select>
-                                </div>
-                                <div class="col-4 pr-0">
-                                    <label class="text-sm mb-0 min-width-unset">End Date</label>
-                                    <input type="date"
-                                           name="removalEffectiveDate"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                                <div class="col-4">
-                                    <label class="text-sm mb-0 min-width-unset">Removal By/Memo</label>
-                                    <input type="text"
-                                           name="removalReasonMemo"
-                                           class="form-control form-control-sm min-width-unset">
-                                </div>
-                            </div>
+                            <?php $point = null; ?>
+                            @include('app.patient.wizard-partials.common-fields', ['label' => 'problem', 'reviewLabel' => 'HPI', 'addVerbPT' => 'Diagnosed'])
 
                         </div>
-                        <div class="col-5 border-left">
+                        <div class="col-4 border-left">
+                            <div class="fdb-dx-vigilance max-height-400px overflow-auto">
 
+                            </div>
                         </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>
+                        <button type="submit" class="btn btn-sm btn-primary mr-2 mt-1">Save Problem</button>
                     </div>
                 </form>
             </div>
@@ -449,278 +305,38 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
 
 <script>
     (function() {
-        function initVisitMoeRTEs() {
-            $('.stag-popup [visit-moe]').find('[note-rte]:not(.ql-container)').each(function() {
-
-                let noteRTE = $(this);
-
-                $(this).wrap(
-                    $('<div class="border-left border-right rte-holder"/>')
-                        .attr('data-shortcuts', '')
-                );
-
-                // give a unique id to this editor instance
-                var editorID = Math.ceil(Math.random() * 99999),
-                    fieldName = $(this).attr('data-field-name') ? $(this).attr('data-field-name') : 'free_text';
-
-                var el = this;
-                var existingContent = $(el).html();
-                var quill = new Quill(el, {
-                    theme: 'snow',
-                    modules: stagQuillConfig
-                });
-
-                var toolbar = $(quill.container).prev('.ql-toolbar');
-
-                // add button for new shortcut
-                if(!noteRTE.is('[use-shortcuts]') || !noteRTE.attr('use-shortcuts')) {
-                    var newSCButton = $('<button class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
-                        'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
-                    toolbar.append(newSCButton);
-                }
-
-                quill.root.innerHTML = existingContent;
-
-                let onTextChange = function(delta, oldDelta, source) {
-                    var content = quill.root.innerHTML;
-                    let dataObject = {};
-                    dataObject[fieldName] = content;
-                    var dataValue = JSON.stringify(dataObject);
-                    let pElem = $(el).closest('[visit-moe]');
-                    if(!pElem.length) {
-                        pElem = $(el).closest('form');
-                    }
-                    pElem.find('input[name=data]').val(dataValue);
-                };
-
-                quill.on('text-change', onTextChange);
-
-                $(quill.container)
-                    .find('.ql-editor[contenteditable]')
-                    .attr('data-field', fieldName)
-                    .attr('data-editor-id', editorID)
-                    .attr('with-shortcuts', 1);
-
-                // set value initially
-                onTextChange();
-            });
-        }
         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);
+                    let icdSelect = $(_input).closest('form').find('[data-name="icd"]').val('').prop('disabled', true);
+                    icdSelect.next('.data-option-list').empty();
+
+                    $('.fdb-dx-vigilance').html('<span class="text-secondary font-italic">Please wait ...</span>');
+                    $.post('/fdb-dx-vigilance/{{$patient->uid}}', {
+                        _token: '{{csrf_token()}}',
+                        dxid: _data.dxid,
+                        name: _input.val(),
+                    }, _data => {
+                        $('.fdb-dx-vigilance').html(_data);
+                    });
+
                     $.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].search_icd_cd).trigger('change');
-                        }
-                    }, 'json');
-                });
-
-            // on route selection
-            parentSegment.find('input[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();
-                        form.find('.removalEffectiveDate_ui').show();
-                        form.find('.removalReasonMemo_ui').show();
-                    }
-                    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();
-                    }
-                    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('[name="isRemoved"], [name="isRemovedDueToEntryError"]')
-                .off('change')
-                .on('change', function () {
-                    let form = $(this).closest('form');
-
-                    form.find('.is_removed_ui_1').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1') {
-                        form.find('.is_removed_ui_1').show();
-                    }
-
-                    form.find('.is_removed_ui_2').hide();
-                    if(form.find('[name="isRemoved"]').val() === '1' && form.find('[name="isRemovedDueToEntryError"]').val() !== '1') {
-                        form.find('.is_removed_ui_2').show();
-                    }
-                    return false;
-                });
-
-            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(_data[i].icd_cd_type !== '01') {
+                                icdSelect.next('.data-option-list').append($('<div/>').text(_data[i].search_icd_cd));
                             }
                         }
-
-                    });
-                    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');
-                        }
+                        icdSelect.prop('disabled', false);
                     }, 'json');
-                    return false;
                 });
 
-            parentSegment.find('.toggle-relevance')
-                .off('click.toggle-relevance')
-                .on('click.toggle-relevance', function () {
-                    if(+$(this).attr('data-relevant') === 0) {
-                        $.post('/api/visitPoint/markPointRelevantToNote', {
-                            noteUid: '{{$note->uid}}',
-                            pointUid: $(this).attr('data-point-uid')
-                        }, _data => {
-                            if(!hasResponseError(_data)) {
-                                refreshDynamicStagPopup();
-                            }
-                        }, 'json');
-                    }
-                    else {
-                        if($(this).attr('data-rel-uid')) {
-                            $.post('/api/visitPoint/undoMarkPointRelevantToNote', {
-                                uid: $(this).attr('data-rel-uid')
-                            }, _data => {
-                                if(!hasResponseError(_data)) {
-                                    refreshDynamicStagPopup();
-                                }
-                            }, 'json');
-                        }
-                        else {
-                            console.log('Error - missing rel uid');
-                        }
-                    }
-                    return false;
-                });
+            @include('app.patient.wizard-partials.common-script', ['label' => 'problem'])
 
+            @if($patient->core_note_id !== $note->id)
             parentSegment.find('.regenerate-cc')
                 .off('click.regenerate-cc')
                 .on('click.regenerate-cc', function () {
@@ -743,14 +359,10 @@ $ccSegment = $note->getSegmentByInternalName('chief_complaint');
 
                     return false;
                 });
-
-            initStagSuggest();
-
-            parentSegment.find('.additionReasonCategory_ui').trigger('change');
-            parentSegment.find('[name="isRemoved"]').trigger('change');
+            @endif
 
             initSegmentMoes($('#problems-center-{{$note->id}}'));
-            initVisitMoeRTEs();
+            __initRTEs(parentSegment.find('[note-rte]:not(.ql-container)'));
         }
         addMCInitializer('problems-center-{{$note->id}}', init, '#problems-center-{{$note->id}}');
     }).call(window);

+ 1 - 1
resources/views/app/patient/segment-templates/chief_complaint/summary.blade.php

@@ -10,7 +10,7 @@ if ($point && !!@$point->data) {
 }
 
 if(!$parsed || !@$parsed->free_text) {
-    $problemPoints = Point::getPointsOfCategory($patient, 'PROBLEM');
+    $problemPoints = Point::getPointsOfCategoryExtended($patient, 'PROBLEM', $note);
     $problemNames = [];
     foreach ($problemPoints as $problemPoint) {
         if($problemPoint->relevanceToNote($note)) {

+ 2 - 14
resources/views/app/patient/segment-templates/intake_goals/summary.blade.php

@@ -6,25 +6,14 @@ use App\Models\Point;
 
 $goals = Point::getIntakePointsOfCategory($patient, 'GOAL', $note);
 
-$grouped = [];
-foreach($goals as $goal) {
-    if(!@($goal->data->category)) continue;
-    if(!isset($grouped[$goal->data->category])) {
-        $grouped[$goal->data->category] = [];
-    }
-    $grouped[$goal->data->category][] = $goal;
-}
-
 $numRelevant = 0;
 
 ?>
 
-<?php if (!count($grouped)): ?>
+<?php if (!count($goals)): ?>
     <div class="text-secondary">No goals</div>
 <?php else: ?>
-    <?php foreach($grouped as $k => $group): ?>
-        <b><?= $k ?></b>
-        <?php foreach($group as $goal): ?>
+    <?php foreach($goals as $goal): ?>
             <?php $rel = $goal->relevanceToNote($note); ?>
             <div class="pl-2 mb-2">
                 <div class="d-flex align-items-baseline">
@@ -58,7 +47,6 @@ $numRelevant = 0;
                 <?php endif; ?>
             </div>
         <?php endforeach; ?>
-    <?php endforeach; ?>
     @if($numRelevant)
         <div class="d-flex align-items-baseline text-info mr-1 mt-3">
             <span class="text-sm mr-1"><i class="fa fa-star text-sm"></i></span>

+ 9 - 1
resources/views/app/patient/segment-templates/medrisk_vigilence/summary.blade.php

@@ -3,6 +3,7 @@
 // info from patient chart
 $drugs = \App\Models\Point::getPointsOfCategory($patient, "MEDICATION");
 $allergies = \App\Models\Point::getPointsOfCategory($patient, "ALLERGY");
+$problems = \App\Models\Point::getPointsOfCategory($patient, "PROBLEM");
 
 // filter out drugs without fdb info on them
 $drugs = $drugs->filter(function($_drug) {
@@ -22,11 +23,18 @@ $allergies = $allergies->filter(function($_allergy) {
         $_allergy->data->damConceptIdType;
 });
 
+// filter out problems without fdb info on them
+$problems = $problems->filter(function($_allergy) {
+    return @$_allergy->data &&
+        $_allergy->data->name &&
+        $_allergy->data->dxid;
+});
+
 // side effects
 $sideeffects = side_effects_info($drugs);
 
 // contraindications
-$contraindications = contraindications_info($drugs);
+$contraindications = contraindications_info($drugs, $problems);
 
 // dpt
 $dptInfo = duplicate_therapy_info($drugs);

+ 18 - 2
resources/views/app/patient/segment-templates/plan_allergies/summary.blade.php

@@ -4,9 +4,10 @@ use App\Models\Point;
 
 /** @var \App\Models\Client $patient */
 
-$allergies = Point::getPlanPointsOfCategory($patient, 'ALLERGY', $note);
+$allergies = Point::getPointsOfCategoryExtended($patient, 'ALLERGY', $note);
 
 $numRelevant = 0;
+$numVisible = 0;
 ?>
 
 <?php if (!count($allergies)): ?>
@@ -15,6 +16,16 @@ $numRelevant = 0;
     <?php foreach ($allergies as $allergy): ?>
         <?php if($allergy->is_removed && $allergy->is_removed_due_to_entry_error) continue; ?>
         <?php $rel = $allergy->relevanceToNote($note); ?>
+        <?php $review = $allergy->childPlanAddedInNote($note); ?>
+
+        <!--show only if: relevant || added-in-note || removed-in-note || added-plan-in-note-->
+        @if($rel ||
+            (!$allergy->is_removed && $allergy->added_in_note_id === $note->id) ||
+            ($allergy->is_removed && $allergy->removed_in_note_id === $note->id) ||
+            !!$review
+            )
+
+            <?php $numVisible++; ?>
         <div class="mb-2">
             <div class="d-flex align-items-baseline">
                 @if($rel)
@@ -41,7 +52,6 @@ $numRelevant = 0;
                     <?php endif;?>
                 <?php endif; ?>
             </div>
-            <?php $review = $allergy->childPlanAddedInNote($note); ?>
             <?php if(!!$review): ?>
             <div class="pl-3 mt-1">
                 <div class="text-secondary font-weight-bold">Plan</div>
@@ -51,7 +61,13 @@ $numRelevant = 0;
             <div class="relevant-without-plan text-danger text-sm mt-1" data-target-segment="<?= $segment->segmentTemplate->internal_name ?>"><i class="fa fa-exclamation-triangle mr-1"></i>Plan missing</div>
             <?php endif; ?>
         </div>
+        @endif
     <?php endforeach; ?>
+    @if(!$numVisible)
+        <div class="d-flex align-items-baseline mr-1">
+            <span class="text-secondary">No allergies</span>
+        </div>
+    @endif
     @if($numRelevant)
         <div class="d-flex align-items-baseline text-info mr-1 mt-3">
             <span class="text-sm mr-1"><i class="fa fa-star text-sm"></i></span>

+ 18 - 2
resources/views/app/patient/segment-templates/plan_care_team/summary.blade.php

@@ -4,9 +4,10 @@ use App\Models\Point;
 
 /** @var \App\Models\Client $patient */
 
-$careTeamMembers = Point::getPlanPointsOfCategory($patient, 'CARE_TEAM_MEMBER', $note);
+$careTeamMembers = Point::getPointsOfCategoryExtended($patient, 'CARE_TEAM_MEMBER', $note);
 
 $numRelevant = 0;
+$numVisible = 0;
 ?>
 
 <?php if (!count($careTeamMembers)): ?>
@@ -15,6 +16,16 @@ $numRelevant = 0;
     <?php foreach($careTeamMembers as $careTeamMember): ?>
         <?php if($careTeamMember->is_removed && $careTeamMember->is_removed_due_to_entry_error) continue; ?>
         <?php $rel = $careTeamMember->relevanceToNote($note); ?>
+        <?php $review = $careTeamMember->childPlanAddedInNote($note); ?>
+
+        <!--show only if: relevant || added-in-note || removed-in-note || added-plan-in-note-->
+        @if($rel ||
+            (!$careTeamMember->is_removed && $careTeamMember->added_in_note_id === $note->id) ||
+            ($careTeamMember->is_removed && $careTeamMember->removed_in_note_id === $note->id) ||
+            !!$review
+            )
+
+            <?php $numVisible++; ?>
         <div class="mb-2">
             <div class="d-flex align-items-baseline">
                 @if($rel)
@@ -45,7 +56,6 @@ $numRelevant = 0;
                     <?php endif;?>
                 <?php endif; ?>
             </div>
-            <?php $review = $careTeamMember->childPlanAddedInNote($note); ?>
             <?php if(!!$review): ?>
             <div class="pl-3 mt-1">
                 <div class="text-secondary font-weight-bold">Plan</div>
@@ -55,7 +65,13 @@ $numRelevant = 0;
             <div class="relevant-without-plan text-danger text-sm mt-1" data-target-segment="<?= $segment->segmentTemplate->internal_name ?>"><i class="fa fa-exclamation-triangle mr-1"></i>Plan missing</div>
             <?php endif; ?>
         </div>
+        @endif
     <?php endforeach; ?>
+    @if(!$numVisible)
+        <div class="d-flex align-items-baseline mr-1">
+            <span class="text-secondary">No care team members</span>
+        </div>
+    @endif
     @if($numRelevant)
         <div class="d-flex align-items-baseline text-info mr-1 mt-3">
             <span class="text-sm mr-1"><i class="fa fa-star text-sm"></i></span>

+ 11 - 15
resources/views/app/patient/segment-templates/plan_goals/summary.blade.php

@@ -4,27 +4,24 @@ use App\Models\Point;
 
 /** @var \App\Models\Client $patient */
 
-$goals = Point::getPlanPointsOfCategory($patient, 'GOAL', $note);
+$goals = Point::getPointsOfCategoryExtended($patient, 'GOAL', $note);
 
-$grouped = [];
-foreach($goals as $goal) {
-    if(!@($goal->data->category)) continue;
-    if($goal->is_removed && $goal->is_removed_due_to_entry_error) continue;
-    if(!isset($grouped[$goal->data->category])) {
-        $grouped[$goal->data->category] = [];
-    }
-    $grouped[$goal->data->category][] = $goal;
-}
+$goals = array_filter($goals, function ($_x) use ($note) {
+    $rel = $_x->relevanceToNote($note);
+    $review = $_x->childPlanAddedInNote($note);
+    return ($rel ||
+        (!$_x->is_removed && $_x->added_in_note_id === $note->id) ||
+        ($_x->is_removed && $_x->removed_in_note_id === $note->id) ||
+        !!$review);
+});
 
 $numRelevant = 0;
 ?>
 
-<?php if (!count($grouped)): ?>
+<?php if (!count($goals)): ?>
     <div class="text-secondary">No goals</div>
 <?php else: ?>
-    <?php foreach($grouped as $k => $group): ?>
-        <b><?= $k ?></b>
-        <?php foreach ($group as $goal): ?>
+    <?php foreach ($goals as $goal): ?>
             <?php $rel = $goal->relevanceToNote($note); ?>
             <div class="pl-2 mb-2">
                 <div class="d-flex align-items-baseline">
@@ -62,7 +59,6 @@ $numRelevant = 0;
                 <?php endif; ?>
             </div>
         <?php endforeach; ?>
-    <?php endforeach; ?>
     @if($numRelevant)
         <div class="d-flex align-items-baseline text-info mr-1 mt-3">
             <span class="text-sm mr-1"><i class="fa fa-star text-sm"></i></span>

+ 21 - 1
resources/views/app/patient/segment-templates/plan_medications/summary.blade.php

@@ -4,9 +4,10 @@ use App\Models\Point;
 
 /** @var \App\Models\Client $patient */
 
-$medications = Point::getPlanPointsOfCategory($patient, 'MEDICATION', $note);
+$medications = Point::getPointsOfCategoryExtended($patient, 'MEDICATION', $note);
 
 $numRelevant = 0;
+$numVisible = 0;
 ?>
 
 <?php if (!count($medications)): ?>
@@ -15,6 +16,17 @@ $numRelevant = 0;
     <?php foreach ($medications as $medication): ?>
         <?php if($medication->is_removed && $medication->is_removed_due_to_entry_error) continue; ?>
         <?php $rel = $medication->relevanceToNote($note); ?>
+        <?php $review = $medication->childPlanAddedInNote($note); ?>
+
+        <!--show only if: relevant || added-in-note || removed-in-note || added-plan-in-note-->
+        @if($rel ||
+            (!$medication->is_removed && $medication->added_in_note_id === $note->id) ||
+            ($medication->is_removed && $medication->removed_in_note_id === $note->id) ||
+            !!$review
+            )
+
+            <?php $numVisible++; ?>
+
         <div class="mb-2">
             <div class="d-flex align-items-baseline">
                 @if($rel)
@@ -50,7 +62,15 @@ $numRelevant = 0;
             <div class="relevant-without-plan text-danger text-sm mt-1" data-target-segment="<?= $segment->segmentTemplate->internal_name ?>"><i class="fa fa-exclamation-triangle mr-1"></i>Plan missing</div>
             <?php endif; ?>
         </div>
+
+        @endif
+
     <?php endforeach; ?>
+    @if(!$numVisible)
+        <div class="d-flex align-items-baseline mr-1">
+            <span class="text-secondary">No medications</span>
+        </div>
+    @endif
     @if($numRelevant)
         <div class="d-flex align-items-baseline text-info mr-1 mt-3">
             <span class="text-sm mr-1"><i class="fa fa-star text-sm"></i></span>

+ 31 - 4
resources/views/app/patient/segment-templates/plan_problems/summary.blade.php

@@ -4,9 +4,10 @@ use App\Models\Point;
 
 /** @var \App\Models\Client $patient */
 
-$problems = Point::getPlanPointsOfCategory($patient, 'PROBLEM', $note);
+$problems = Point::getPointsOfCategoryExtended($patient, 'PROBLEM', $note);
 
 $numRelevant = 0;
+$numVisible = 0;
 $numRelevantWithICD = 0;
 ?>
 
@@ -16,6 +17,17 @@ $numRelevantWithICD = 0;
     <?php foreach ($problems as $problem): ?>
         <?php if($problem->is_removed && $problem->is_removed_due_to_entry_error) continue; ?>
         <?php $rel = $problem->relevanceToNote($note); ?>
+        <?php $review = $problem->childPlanAddedInNote($note); ?>
+        <?php $hpi = $problem->childReviewAddedInNote($note); ?>
+
+        <!--show only if: relevant || added-in-note || removed-in-note || added-plan-in-note-->
+        @if($rel ||
+            (!$problem->is_removed && $problem->added_in_note_id === $note->id) ||
+            ($problem->is_removed && $problem->removed_in_note_id === $note->id) ||
+            !!$review
+            )
+
+            <?php $numVisible++; ?>
         <div class="mb-2">
             <div class="d-flex align-items-baseline">
                 @if($rel)
@@ -23,7 +35,7 @@ $numRelevantWithICD = 0;
                         <i class="fa fa-star"></i>
                     </span>
                     <?php $numRelevant++; ?>
-                    @if(!!@($problem->data->icd) && !$problem->is_removed)
+                    @if(!!@($problem->data->icd) && !!$hpi)
                         <?php $numRelevantWithICD++; ?>
                     @endif
                 @endif
@@ -46,7 +58,16 @@ $numRelevantWithICD = 0;
                     <?php endif;?>
                 <?php endif; ?>
             </div>
-            <?php $review = $problem->childPlanAddedInNote($note); ?>
+            <?php if(!!$hpi): ?>
+            <div class="pl-3 mt-1">
+                <div class="text-secondary font-weight-bold">HPI</div>
+                <div>{!! $hpi->data->value !!}</div>
+            </div>
+            <?php elseif($rel): ?>
+            <div class="relevant-without-review block-signing text-danger text-sm mt-1" data-target-segment="<?= $segment->segmentTemplate->internal_name ?>">
+                <i class="fa fa-exclamation-triangle mr-1"></i>HPI missing
+            </div>
+            <?php endif; ?>
             <?php if(!!$review): ?>
             <div class="pl-3 mt-1">
                 <div class="text-secondary font-weight-bold">Plan</div>
@@ -58,7 +79,13 @@ $numRelevantWithICD = 0;
             </div>
             <?php endif; ?>
         </div>
+        @endif
     <?php endforeach; ?>
+    @if(!$numVisible)
+        <div class="d-flex align-items-baseline mr-1">
+            <span class="text-secondary">No problems</span>
+        </div>
+    @endif
     @if($numRelevant)
         <div class="d-flex align-items-baseline text-info mr-1 mt-3">
             <span class="text-sm mr-1"><i class="fa fa-star text-sm"></i></span>
@@ -66,7 +93,7 @@ $numRelevantWithICD = 0;
         </div>
     @endif
     @if(!$numRelevantWithICD)
-        <div class="no-relevant-with-icd block-signing text-danger mt-1 text-sm" data-target-segment="<?= $segment->segmentTemplate->internal_name ?>"><i class="fa fa-exclamation-triangle mr-1"></i>Need at least 1 relevant problem with an ICD before the note can be signed</div>
+        <div class="no-relevant-with-icd block-signing text-danger mt-1 text-sm" data-target-segment="<?= $segment->segmentTemplate->internal_name ?>"><i class="fa fa-exclamation-triangle mr-1"></i>Need at least 1 relevant problem (with ICD) with associated HPI before the note can be signed</div>
     @endif
 <?php endif; ?>
 

+ 8 - 3
resources/views/app/patient/segment-templates/vitals/edit.blade.php

@@ -143,9 +143,14 @@ $copyTriggerAdded = [];
                                        placeholder="{{$v}}"
                                        data-option-list="smokingStatus" value="{{$contentData['smokingStatus']}}">
                                 <div id="smoking-status-options" class="data-option-list">
-                                    <div>Current</div>
-                                    <div>Former</div>
-                                    <div>Never</div>
+                                    <div>Current every day smoker</div>
+                                    <div>Former some day smoker</div>
+                                    <div>Former smoker</div>
+                                    <div>Never smoker</div>
+                                    <div>Smoker, current status unknown</div>
+                                    <div>Unknown if ever smoked</div>
+                                    <div>Heavy tobacco smoker</div>
+                                    <div>Light tobacco smoker</div>
                                 </div>
                             @elseif($k === 'systolicBP')
                                 <div class="d-flex align-items-center bg-white">

+ 221 - 0
resources/views/app/patient/wizard-partials/common-fields.blade.php

@@ -0,0 +1,221 @@
+<div class="mb-2">
+    <span class="">Is this {{$label}} active?</span>
+    <div class="d-flex align-items-baseline mt-1">
+        <label class="my-0 d-inline-flex align-items-center">
+            <input type="radio" name="isRemoved" value="0" {{$point && !$point->is_removed ? 'checked' : ''}}>
+            <span class="ml-1">Yes</span>
+        </label>
+        <label class="ml-3 my-0 d-inline-flex align-items-center">
+            <input type="radio" name="isRemoved" value="1" {{$point && $point->is_removed ? 'checked' : ''}}>
+            <span class="ml-1">No</span>
+        </label>
+    </div>
+</div>
+
+<div if-active class="d-none">
+
+    <hr class="mb-2 mt-0">
+
+    <div class="mb-2">
+        <span class="">Is this pre-existing, or being {{@$addVerbPT ?: 'added'}} during this visit?</span>
+        <div class="d-flex align-items-baseline mt-1">
+            <label class="my-0 d-inline-flex align-items-center">
+                <input type="radio" name="additionReasonCategory" value="ON_INTAKE"
+                        {{$point && $point->addition_reason_category === 'ON_INTAKE' ? 'checked' : ''}}
+                        {{0 && $point && $point->added_in_note_id !== $note->id ? 'readonly disabled' : ''}}>
+                <span class="ml-1">Pre-existing</span>
+            </label>
+            <label class="ml-3 my-0 d-inline-flex align-items-center">
+                <input type="radio" name="additionReasonCategory" value="DURING_VISIT"
+                        {{$point && $point->addition_reason_category === 'DURING_VISIT' ? 'checked' : ''}}
+                        {{0 && $point && $point->added_in_note_id !== $note->id ? 'readonly disabled' : ''}}>
+                <span class="ml-1">{{@$addVerbPT ? ucwords($addVerbPT) : 'Added'}} during this visit (as part of my plan)</span>
+            </label>
+        </div>
+    </div>
+
+</div>
+
+<div if-not-active class="d-none">
+
+    <hr class="mb-2 mt-0">
+
+    @if(@$point)
+        <div class="mb-2">
+            <span class="">Is this {{$label}} being removed due to an entry error?</span>
+            <div class="d-flex align-items-baseline mt-1">
+                <label class="my-0 d-inline-flex align-items-center">
+                    <input type="radio" name="isRemovedDueToEntryError" value="1" {{$point && $point->is_removed_due_to_entry_error === '1' ? 'checked' : ''}}>
+                    <span class="ml-1">Yes</span>
+                </label>
+                <label class="ml-3 my-0 d-inline-flex align-items-center">
+                    <input type="radio" name="isRemovedDueToEntryError" value="0" {{$point && $point->is_removed_due_to_entry_error === '0' ? 'checked' : ''}}>
+                    <span class="ml-1">No</span>
+                </label>
+            </div>
+        </div>
+    @endif
+
+    <div {{@$point ? 'if-not-entry-error class="d-none"' : ''}}>
+
+        <div class="mb-2">
+            <span class="">Was this {{$label}} removed PRIOR to this visit or DURING this visit?</span>
+            <div class="d-flex align-items-baseline mt-1">
+                <label class="my-0 d-inline-flex align-items-center">
+                    <input type="radio" name="removalReasonCategory" value="ON_INTAKE" {{$point && $point->removal_reason_category === 'ON_INTAKE' ? 'checked' : ''}}>
+                    <span class="ml-1">Prior to visit</span>
+                </label>
+                <label class="ml-3 my-0 d-inline-flex align-items-center">
+                    <input type="radio" name="removalReasonCategory" value="DURING_VISIT" {{$point && $point->removal_reason_category === 'DURING_VISIT' ? 'checked' : ''}}>
+                    <span class="ml-1">Removed during this visit (as part of my plan)</span>
+                </label>
+            </div>
+        </div>
+
+    </div>
+
+</div>
+
+<div {{@$point ? 'if-not-entry-error class="d-none"' : ''}}>
+    <div if-addition-or-removal-on-intake-or-during-visit class="d-none">
+        <div class="row mb-2">
+            <div class="col-6 pr-0">
+                <label class="text-sm mb-0">Start Date</label>
+                <input type="date"
+                       data-name="start_date"
+                       value="{{@$point->data ? @$point->data->start_date : ''}}"
+                       class="form-control form-control-sm min-width-unset">
+            </div>
+            <div class="col-6">
+                <label class="text-sm mb-0">{{@$addVerbPT ? ucwords($addVerbPT) : 'Added'}} By</label>
+                <input type="text"
+                       data-name="prescriber"
+                       value="{{@$point->data ? @$point->data->prescriber : ''}}"
+                       class="form-control form-control-sm min-width-unset">
+            </div>
+        </div>
+        <div if-not-active class="d-none">
+            <div if-removal-on-intake-or-during-visit class="d-none">
+                <div class="row mb-2">
+                    <div class="col-6 pr-0">
+                        <label class="text-sm mb-0">End Date</label>
+                        <input type="date"
+                               name="removalEffectiveDate"
+                               value="{{@$point->removal_effective_date}}"
+                               class="form-control form-control-sm min-width-unset">
+                    </div>
+                    <div class="col-6">
+                        <label class="text-sm mb-0">Removal By/Memo</label>
+                        <input type="text"
+                               name="removalReasonMemo"
+                               value="{{@$point->removal_reason_memo}}"
+                               class="form-control form-control-sm min-width-unset">
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
+
+<div {{@$point ? 'if-not-entry-error class="d-none"' : ''}}>
+    <div if-active-or-not-active class="d-none">
+
+    @if($patient->core_note_id !== $note->id)
+        <div class="row mb-2">
+            <div class="col-6 pr-0">
+                <?php
+                $currentValue = '';
+                $previousValue = '';
+                $previousChildReview = null;
+                if (@$point) {
+                    if ($point->lastChildReview && $point->last_child_review_point_scoped_note_id === $note->id) {
+                        $parsedReview = json_decode($point->lastChildReview->data);
+                        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;
+                            }
+                        }
+                    }
+                }
+                ?>
+                <label class="text-sm mb-1">{{@$reviewLabel ? $reviewLabel : 'Review'}}</label>
+                <div note-rte
+                     class="form-group mb-2 border-left border-right rte-holder bg-white"
+                     data-field-name="reviewValue"><?= $currentValue ?></div>
+                <?php if($previousValue): ?>
+                <div class="mb-2">
+                    <div class="d-flex align-items-baseline mb-1">
+                        <span class="text-sm text-secondary">Previous {{@$reviewLabel ? $reviewLabel : 'Review'}} / <?= friendlier_date($previousChildReview->created_at) ?> (click to copy)</span>
+                    </div>
+                    <div class="p-2 bg-light border inline-html-container click-to-copy"><?= $previousValue ?></div>
+                </div>
+                <div class="d-none disallow-if-review-same-as" compare-width="reviewValue"><?= str_compact($previousValue) ?></div>
+                <?php endif; ?>
+            </div>
+            <div class="col-6">
+                <?php
+                $currentValue = '';
+                $previousValue = '';
+                $previousChildPlan = null;
+                if (@$point) {
+                    if ($point->lastChildPlan && $point->last_child_plan_point_scoped_note_id === $note->id) {
+                        $parsedPlan = json_decode($point->lastChildPlan->data);
+                        $currentValue = $parsedPlan->value;
+                        $previousChildPlan = \App\Models\Point::where('id', '<', $point->lastChildPlan->id)
+                            ->where('category', 'PLAN')
+                            ->where('parent_point_id', $point->id)
+                            ->orderBy('id', 'DESC')
+                            ->first();
+                        if ($previousChildPlan && $previousChildPlan->data) {
+                            $parsedPlan = json_decode($previousChildPlan->data);
+                            $previousValue = $parsedPlan->value;
+                        }
+                    } else {
+                        $previousChildPlan = \App\Models\Point::where('parent_point_id', $point->id)
+                            ->where('category', 'PLAN')
+                            ->orderBy('id', 'DESC')
+                            ->first();
+                        if ($previousChildPlan && $previousChildPlan->data) {
+                            $parsedPlan = json_decode($previousChildPlan->data);
+                            $previousValue = $parsedPlan->value;
+                        }
+                    }
+                }
+                ?>
+                <label class="text-sm mb-1">Plan</label>
+                <div note-rte
+                     class="form-group mb-2 border-left border-right rte-holder bg-white"
+                     data-field-name="planValue"><?= $currentValue ?></div>
+                <?php if($previousValue): ?>
+                <div class="mb-2">
+                    <div class="d-flex align-items-baseline mb-1">
+                        <span class="text-sm text-secondary">Previous Plan / <?= friendlier_date($previousChildPlan->created_at) ?> (click to copy)</span>
+                    </div>
+                    <div class="p-2 bg-light border inline-html-container click-to-copy"><?= $previousValue ?></div>
+                </div>
+                <div class="d-none disallow-if-plan-same-as" compare-width="planValue"><?= str_compact($previousValue) ?></div>
+                <?php endif; ?>
+            </div>
+        </div>
+    @endif
+
+    </div>
+</div>

+ 383 - 0
resources/views/app/patient/wizard-partials/common-script.blade.php

@@ -0,0 +1,383 @@
+function __reset(_input) {
+    _input.val(_input.attr('value') ? _input.attr('value') : '');
+}
+
+function __initRTEs(_collection) {
+    _collection.each(function() {
+
+        let noteRTE = $(this);
+
+        $(this).wrap(
+            $('<div class="border-left border-right rte-holder"/>')
+                .attr('data-shortcuts', '')
+        );
+
+        // give a unique id to this editor instance
+        var editorID = Math.ceil(Math.random() * 99999),
+            fieldName = $(this).attr('data-field-name') ? $(this).attr('data-field-name') : 'free_text';
+
+        var el = this;
+        var existingContent = $(el).html();
+        var quill = new Quill(el, {
+            theme: 'snow',
+            modules: stagQuillConfig
+        });
+
+        var toolbar = $(quill.container).prev('.ql-toolbar');
+
+        // add button for new shortcut
+        if(!noteRTE.is('[use-shortcuts]') || !noteRTE.attr('use-shortcuts')) {
+            var newSCButton = $('<button class="btn bg-white btn-sm btn-default text-primary w-auto px-2 border py-0 ' +
+                'text-sm add-shortcut" data-editor-id="' + editorID + '">+ Shortcut</button>');
+            toolbar.append(newSCButton);
+        }
+
+        quill.root.innerHTML = existingContent;
+
+        let onTextChange = function(delta, oldDelta, source) {
+            var content = quill.root.innerHTML;
+            let dataObject = {};
+            dataObject[fieldName] = content;
+            var dataValue = JSON.stringify(dataObject);
+            let pElem = $(el).closest('[visit-moe]');
+            if(!pElem.length) {
+                pElem = $(el).closest('form');
+            }
+            let v = pElem.find('input[name=data]').val();
+            if(!!v) {
+                try {
+                    v = JSON.parse(v);
+                    v[fieldName] = content;
+                    v = JSON.stringify(v);
+                }
+                catch (e) {
+                    v = JSON.stringify(dataObject);
+                }
+            }
+            else {
+                v = JSON.stringify(dataObject);
+            }
+            pElem.find('input[name=data]').val(v);
+        };
+
+        quill.on('text-change', onTextChange);
+
+        $(quill.container)
+            .find('.ql-editor[contenteditable]')
+            .attr('data-field', fieldName)
+            .attr('data-editor-id', editorID)
+            .attr('with-shortcuts', 1);
+
+        // set value initially
+        onTextChange();
+    });
+}
+
+parentSegment.find('[name="isRemoved"]')
+    .off('change')
+    .on('change', function () {
+        let form = $(this).closest('form');
+        form.find('[if-active-or-not-active], [if-active], [if-not-active]').addClass('d-none');
+        if(form.find('[name="isRemoved"]:checked').length) form.find('[if-active-or-not-active]').removeClass('d-none');
+        if(form.find('[name="isRemoved"]:checked').val() === '1') form.find('[if-not-active]').removeClass('d-none');
+        else if(form.find('[name="isRemoved"]:checked').val() === '0') {
+            form.find('[if-active]').removeClass('d-none');
+            form.find('[name="removalEffectiveDate"]').val('');
+            form.find('[name="removalReasonMemo"]').val('');
+        }
+        return false;
+    })
+    .trigger('change');
+
+parentSegment.find('[name="additionReasonCategory"]')
+    .off('change')
+    .on('change', function () {
+        let form = $(this).closest('form');
+        form.find('[if-addition-on-intake-or-during-visit], [if-addition-on-intake], [if-addition-during-visit]').addClass('d-none');
+        if(form.find('[name="additionReasonCategory"]:checked').length) form.find('[if-addition-on-intake-or-during-visit]').removeClass('d-none');
+        form.find('[if-addition-or-removal-on-intake-or-during-visit]').addClass('d-none');
+        if(form.find('[name="additionReasonCategory"]:checked').length || form.find('[name="removalReasonCategory"]:checked').length) {
+            form.find('[if-addition-or-removal-on-intake-or-during-visit]').removeClass('d-none');
+        }
+        if(form.find('[name="additionReasonCategory"]:checked').val() === 'ON_INTAKE') {
+            form.find('[if-addition-on-intake]').removeClass('d-none');
+            __reset(form.find('[data-name="start_date"]'));
+            __reset(form.find('[data-name="prescriber"]'));
+        }
+        else if(form.find('[name="additionReasonCategory"]:checked').val() === 'DURING_VISIT') {
+            form.find('[if-addition-during-visit]').removeClass('d-none');
+            form.find('[data-name="start_date"]').val('{{$patient->core_note_id !== $note->id ? $note->effective_dateest : date("Y-m-d")}}');
+            form.find('[data-name="prescriber"]').val('{{$patient->core_note_id !== $note->id ? ($note->hcpPro ? $note->hcpPro->displayName() : "")  : ""}}');
+        }
+        return false;
+    })
+    .trigger('change');
+
+parentSegment.find('[name="removalReasonCategory"]')
+    .off('change')
+    .on('change', function () {
+        let form = $(this).closest('form');
+        form.find('[if-removal-on-intake-or-during-visit], [if-removal-on-intake], [if-removal-during-visit]').addClass('d-none');
+        if(form.find('[name="removalReasonCategory"]:checked').length) form.find('[if-removal-on-intake-or-during-visit]').removeClass('d-none');
+        form.find('[if-addition-or-removal-on-intake-or-during-visit]').addClass('d-none');
+        if(form.find('[name="additionReasonCategory"]:checked').length || form.find('[name="removalReasonCategory"]:checked').length) {
+            form.find('[if-addition-or-removal-on-intake-or-during-visit]').removeClass('d-none');
+        }
+        if(form.find('[name="removalReasonCategory"]:checked').val() === 'ON_INTAKE') {
+            form.find('[if-removal-on-intake]').removeClass('d-none');
+            __reset(form.find('[name="removalEffectiveDate"]'));
+            __reset(form.find('[name="removalReasonMemo"]'));
+        }
+        else if(form.find('[name="removalReasonCategory"]:checked').val() === 'DURING_VISIT') {
+            form.find('[if-removal-during-visit]').removeClass('d-none');
+            form.find('[name="removalEffectiveDate"]').val('{{$patient->core_note_id !== $note->id ? $note->effective_dateest : date("Y-m-d")}}');
+            form.find('[name="removalReasonMemo"]').val('{{$patient->core_note_id !== $note->id ? ($note->hcpPro ? $note->hcpPro->displayName() : "")  : ""}}');
+        }
+        return false;
+    })
+    .trigger('change');
+
+parentSegment.find('[name="isRemovedDueToEntryError"]')
+    .off('change')
+    .on('change', function () {
+        let form = $(this).closest('form');
+        form.find('[if-not-entry-error]').removeClass('d-none');
+        if(form.find('[name="isRemovedDueToEntryError"]:checked').val() === '1') form.find('[if-not-entry-error]').addClass('d-none');
+        return false;
+    })
+    .trigger('change');
+
+parentSegment.find('#frm-add-{{$label}}')
+    .off('submit')
+    .on('submit', function () {
+
+        let form = $(this);
+
+        if (!form[0].checkValidity()) {
+            form[0].reportValidity();
+            return false;
+        }
+
+        if(!form.find('[name="additionReasonCategory"]:checked').length) {
+            form.find('[name="additionReasonCategory"][value="ON_INTAKE"]').prop('checked', true);
+        }
+
+        // add [data-name] values to payload
+        let dataField = form.find('[name="data"]').first();
+        let parsed = null;
+        if(dataField.val()) {
+            parsed = JSON.parse(dataField.val());
+        }
+
+        @if($patient->core_note_id !== $note->id)
+        // store plan content
+        let planContent = parsed && parsed.planValue ? parsed.planValue : '';
+        let reviewContent = parsed && parsed.reviewValue ? parsed.reviewValue : '';
+        // if(!$.trim($('<div/>').html(planContent).text())) {
+        //     toastr.error('Directions cannot be empty');
+        //     return false;
+        // }
+        if(parsed.planValue) delete parsed.planValue;
+        if(parsed.reviewValue) delete parsed.reviewValue;
+        @endif
+
+        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));
+        }
+
+        let payload = {};
+        form.serializeArray().map(x => {payload[x.name] = x.value;});
+        @if($patient->core_note_id !== $note->id)
+        if(!!reviewContent) {
+            payload.childReviewData = JSON.stringify({
+                value: reviewContent
+            })
+        }
+        if(!!planContent) {
+            payload.childPlanData = JSON.stringify({
+                value: planContent
+            })
+        }
+        @endif
+
+        $.post(form.attr('action'), payload, _data => {
+            if(!hasResponseError(_data)) {
+                hideMask();
+                refreshDynamicStagPopup();
+                $('.visit-segment[data-segment-template-name="intake_{{$label}}s"]').find('.refresh-segment').trigger('click');
+                $('.visit-segment[data-segment-template-name="plan_{{$label}}s"]').find('.refresh-segment').trigger('click');
+            }
+        }, 'json');
+        return false;
+    });
+
+parentSegment.find('.frm-edit-{{$label}}')
+    .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());
+        }
+
+        @if($patient->core_note_id !== $note->id)
+        let reviewContent = parsed && parsed.reviewValue ? parsed.reviewValue : '';
+
+        let compareWith = false;
+        if(form.find('.disallow-if-review-same-as')) {
+            compareWith = $.trim(form.find('.disallow-if-review-same-as').text());
+            if(compareWith && reviewContent) {
+                let newValue = $('<div/>').html(reviewContent).text().replace(/[^a-zA-Z0-9]/g, '');
+                if(newValue === compareWith) {
+                    alert('New review should be different from the previous review!');
+                    return false;
+                }
+            }
+        }
+
+        let planContent = parsed && parsed.planValue ? parsed.planValue : '';
+
+        compareWith = false;
+        if(form.find('.disallow-if-plan-same-as')) {
+            compareWith = $.trim(form.find('.disallow-if-plan-same-as').text());
+            if(compareWith && planContent) {
+                let newValue = $('<div/>').html(planContent).text().replace(/[^a-zA-Z0-9]/g, '');
+                if(newValue === compareWith) {
+                    alert('New plan should be different from the previous plan!');
+                    return false;
+                }
+            }
+        }
+
+        if(parsed.planValue) delete parsed.planValue;
+        if(parsed.reviewValue) delete parsed.reviewValue;
+        @endif
+
+        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));
+        }
+
+        let payload = {};
+        form.serializeArray().map(x => {payload[x.name] = x.value;});
+        @if($patient->core_note_id !== $note->id)
+        if(!!reviewContent) {
+            payload.childReviewData = JSON.stringify({
+                value: reviewContent
+            })
+        }
+        if(!!planContent) {
+            payload.childPlanData = JSON.stringify({
+                value: planContent
+            })
+        }
+        // if added/removed during-visit, require plan
+        /*if(form.find('[name="isRemovedDueToEntryError"]:checked').val() !== '1' &&
+            ((form.find('[name="isRemoved"]:checked').val() === '0' && form.find('[name="additionReasonCategory"]:checked').val() === 'DURING_VISIT') ||
+            (form.find('[name="isRemoved"]:checked').val() === '1' && form.find('[name="removalReasonCategory"]:checked').val() === 'DURING_VISIT'))
+        ) {
+            if(!planContent) {
+                alert('Updates during visit require an accompanying plan!');
+                return false;
+            }
+        }*/
+        @endif
+
+        $.post(form.attr('url'), payload, _data => {
+            if(!hasResponseError(_data)) {
+                hideMask();
+                refreshDynamicStagPopup();
+                $('.visit-segment[data-segment-template-name="intake_{{$label}}s"]').find('.refresh-segment').trigger('click');
+                $('.visit-segment[data-segment-template-name="plan_{{$label}}s"]').find('.refresh-segment').trigger('click');
+            }
+        }, 'json');
+        return false;
+    });
+
+parentSegment.find('.toggle-relevance')
+    .off('click.toggle-relevance')
+    .on('click.toggle-relevance', function () {
+        if (+$(this).attr('data-relevant') === 0) {
+            $.post('/api/visitPoint/markPointRelevantToNote', {
+                noteUid: '{{$note->uid}}',
+                pointUid: $(this).attr('data-point-uid')
+            }, _data => {
+                if (!hasResponseError(_data)) {
+                    refreshDynamicStagPopup();
+                    $('.visit-segment[data-segment-template-name="intake_{{$label}}s"]').find('.refresh-segment').trigger('click');
+                    $('.visit-segment[data-segment-template-name="plan_{{$label}}s"]').find('.refresh-segment').trigger('click');
+                }
+            }, 'json');
+        } else {
+            if ($(this).attr('data-rel-uid')) {
+                $.post('/api/visitPoint/undoMarkPointRelevantToNote', {
+                    uid: $(this).attr('data-rel-uid')
+                }, _data => {
+                    if (!hasResponseError(_data)) {
+                        refreshDynamicStagPopup();
+                        $('.visit-segment[data-segment-template-name="intake_{{$label}}s"]').find('.refresh-segment').trigger('click');
+                        $('.visit-segment[data-segment-template-name="plan_{{$label}}s"]').find('.refresh-segment').trigger('click');
+                    }
+                }, 'json');
+            } else {
+                console.log('Error - missing rel uid');
+            }
+        }
+        return false;
+    });
+
+initStagSuggest();

+ 2 - 2
resources/views/app/stat-tree/clauses/list.blade.php

@@ -1,6 +1,5 @@
 @extends ('layouts/template')
 @section('content')
-<main role="main" class="stag-content px-0">
     <div class="p-3 mcp-theme-1">
         <div class="row">
             <div class="col-12">
@@ -23,6 +22,7 @@
                                         <thead class="bg-light">
                                             <tr>
                                                 <th class="border-0">Position Index</th>
+                                                <th class="border-0">Model</th>
                                                 <th class="border-0">Label</th>
                                                 <th class="border-0">Question</th>
                                                 <th class="border-0">Answer</th>
@@ -33,6 +33,7 @@
                                             @foreach($clauses as $clause)
                                             <tr>
                                                 <td>{{ $clause->position_index }}</td>
+                                                <td>{{$clause->model}}</td>
                                                 <td>{{$clause->label}}</td>
                                                 <td>{{$clause->question}}</td>
                                                 <td>{{ $clause->answer }}</td>
@@ -49,6 +50,5 @@
             </div>
         </div>
     </div>
-</main>
 
 @endsection

+ 1 - 1
resources/views/app/stat-tree/clauses/replace-all.blade.php

@@ -1,7 +1,7 @@
 @extends ('layouts/template')
 @section('content')
 
-<main id="replaceAllComponent" role="main" class="stag-content px-0" v-cloak>
+<main id="replaceAllComponent" v-cloak>
     <div class="p-3 mcp-theme-1">
         <div class="card">
             <div class="card-header">

+ 0 - 2
resources/views/app/stat-tree/stat-tree-lines/single.blade.php

@@ -1,6 +1,5 @@
 @extends ('layouts/template')
 @section('content')
-<main role="main" class="stag-content px-0">
     <div class="p-3 mcp-theme-1">
         <div class="card">
             <div class="card-header">
@@ -35,6 +34,5 @@
             </div>
         </div>
     </div>
-</main>
 
 @endsection

+ 0 - 2
resources/views/app/stat-tree/stat-trees/create.blade.php

@@ -1,7 +1,6 @@
 @extends ('layouts/template')
 @section('content')
 <div id="statTreeComponent" v-cloak>
-    <main role="main" class="stag-content px-0">
         <div class="p-3 mcp-theme-1">
             <div class="card">
                 <div class="card-header">
@@ -34,7 +33,6 @@
                 </div>
             </div>
         </div>
-    </main>
 </div>
 
 <script type="text/javascript">

+ 0 - 2
resources/views/app/stat-tree/stat-trees/list.blade.php

@@ -1,7 +1,6 @@
 @extends ('layouts/template')
 @section('content')
 
-<main role="main" class="stag-content px-0">
     <div class="p-3 mcp-theme-1">
         <div class="row">
             <div class="col-12">
@@ -48,6 +47,5 @@
             </div>
         </div>
     </div>
-</main>
 
 @endsection

+ 0 - 2
resources/views/app/stat-tree/stat-trees/single.blade.php

@@ -1,7 +1,6 @@
 @extends ('layouts/template')
 @section('content')
 
-<main role="main" class="stag-content px-0">
     <div class="p-3 mcp-theme-1">
         <div class="card">
             <div class="card-header">
@@ -30,6 +29,5 @@
             </div>
         </div>
     </div>
-</main>
 
 @endsection

+ 124 - 116
resources/views/app/stat-tree/stat-trees/sub/dashboard.blade.php

@@ -1,131 +1,135 @@
 @extends('app.stat-tree.stat-trees.single')
 @section('page')
 
-<div id="app" class="row">
-    @if(count($statTree->lines))
-    <div class="col-12">
-        <div class="d-flex align-items-center justify-content-between mb-2">
-            <h6 class="font-weight-bold">Lines</h6>
-            <div>
-                <a href="#" @click="refreshTreeCountQueries" class="btn btn-sm btn-danger text-white">
-                <span v-if="!refreshing"><i class="fas fa-sync-alt"></i> Refresh Counts</span> 
-                <span v-else><i class="fas fa-circle-notch fa-spin"></i> Refreshing...</span> 
-                </a>
+<div id="statTreeViewPage">
+    <div id="statTreeView" class="row">
+        @if(count($statTree->lines))
+        <div class="col-12">
+            <div class="d-flex align-items-center justify-content-between mb-2">
+                <h6 class="font-weight-bold">Lines</h6>
+                <div>
+                    <button @click="refreshTreeCountQueries" class="btn btn-sm btn-danger text-white">
+                        <span v-if="!refreshing"><i class="fas fa-sync-alt"></i> Refresh Counts</span>
+                        <span v-else><i class="fas fa-circle-notch fa-spin"></i> Refreshing...</span>
+                    </button>
+                </div>
+            </div>
+            <div class="table-responsive">
+                <table class="table table-condensed border p-0 m-0">
+                    <thead class="bg-light">
+                        <tr>
+                            <th class="border-bottom-0">#</th>
+                            <th class="border-bottom-0">Model</th>
+                            <th class="border-bottom-0">Clauses</th>
+                            <th class="border-bottom-0">Query</th>
+                            <th class="border-bottom-0">Count</th>
+                            <th class="border-bottom-0">Actions</th>
+                        </tr>
+                    </thead>
+                    <tbody>
+                        @foreach($statTree->lines as $line)
+                        <tr>
+                            <td>
+                                <a href="{{ route('practice-management.statTreeLines.view.dashboard', $line) }}" target="_blank">
+                                    {{ $line->tree_order_position_index }}
+                                </a>
+                            </td>
+                            <td>{{ ucwords($line->statTree->model) }}</td>
+                            <td>
+                                @foreach($line->lineClauses as $c)
+                                | {{ $c->clause_label }}
+                                @endforeach
+                            </td>
+                            <td>
+                                SELECT COUNT(*) FROM {{ $statTree->model }} WHERE
+                                @foreach($line->lineClauses as $c)
+                                {{ $c->clause->clause_text ?? '' }} @if(!$loop->last) AND @endif
+                                @endforeach
+                            </td>
+                            <td>
+                                <span id="line-{{ $line->id }}">{{ $line->last_refresh_count }}</span>
+                            </td>
+                            <td>
+                                <a href="#" data-id="{{$line->id}}" refresh-line-query native>Refresh</a>
+                            </td>
+                        </tr>
+                        @endforeach
+                    </tbody>
+                </table>
             </div>
         </div>
-        <div class="table-responsive">
-            <table class="table table-condensed border p-0 m-0">
-                <thead class="bg-light">
-                    <tr>
-                        <th class="border-bottom-0">#</th>
-                        <th class="border-bottom-0">Clauses</th>
-                        <th class="border-bottom-0">Query</th>
-                        <th class="border-bottom-0">Count</th>
-                        <th class="border-bottom-0">Actions</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    @foreach($statTree->lines as $line)
-                    <tr>
-                        <td>
-                            <a href="{{ route('practice-management.statTreeLines.view.dashboard', $line) }}">
-                                {{ $line->tree_order_position_index }}
-                            </a>
-                        </td>
-                        <td>
-                            @foreach($line->lineClauses as $c)
-                            | {{ $c->clause_label }}
-                            @endforeach
-                        </td>
-                        <td>
-                            SELECT COUNT(*) FROM {{ $statTree->model }} WHERE
-                            @foreach($line->lineClauses as $c)
-                            {{ $c->clause->clause_text ?? '' }} @if(!$loop->last) AND @endif
-                            @endforeach
-                        </td>
-                        <td>
-                            <span id="line-{{ $line->id }}">{{ $line->last_refresh_count }}</span>
-                        </td>
-                        <td>
-                            <a href="#" data-id="{{$line->id}}" refresh-line-query>Refresh</a>
-                        </td>
-                    </tr>
-                    @endforeach
-                </tbody>
-            </table>
-        </div>
-    </div>
-    @endif
+        @endif
 
-    <div class="col-12">
-        <h6 class="font-weight-bold bg-light p-3 mt-3">Replace Stat Tree Lines</h6>
-        <div class="row">
-            <div class="col-md-6">
-                <div class="bg-white p-3">
-                    <h6 class="font-weight-bold">TSV</h6>
-                    <div class="input-group">
-                        <textarea v-model="content" class="form-control" rows="10" @keyup="splitContents"></textarea>
+        <div class="col-12">
+            <h6 class="font-weight-bold bg-light p-3 mt-3">Replace Stat Tree Lines</h6>
+            <div class="row">
+                <div class="col-md-6">
+                    <div class="bg-white p-3">
+                        <h6 class="font-weight-bold">TSV</h6>
+                        <div class="input-group">
+                            <textarea v-model="content" class="form-control" rows="10" @keyup="splitContents"></textarea>
+                        </div>
                     </div>
                 </div>
-            </div>
-            <div class="col-md-6">
-                <div class="bg-white p-3">
-                    <h6 class="font-weight-bold">JSON Structure</h6>
-                    <textarea class="form-control" rows="10">@{{jsonStructure}}</textarea>
+                <div class="col-md-6">
+                    <div class="bg-white p-3">
+                        <h6 class="font-weight-bold">JSON Structure</h6>
+                        <textarea class="form-control" rows="10">@{{jsonStructure}}</textarea>
+                    </div>
                 </div>
             </div>
-        </div>
-        <template v-if="rows.length">
-            <div class="row my-3">
-                <div class="col">
-                    <div class="bg-white p-3">
-                        <h6 class="font-weight-bold">Table output:</h6>
-                        <div class="table-responsive">
-                            <table class="table table-bordered table-hover">
-                                <tbody>
-                                    <tr v-for="(row, rowIndex) in rows">
-                                        <td v-for="(column, columnIndex) in columns[rowIndex]">
-                                            <input class="border-0" type="text" v-model="columns[rowIndex][columnIndex]" @keyup="updateColumns(rowIndex, columnIndex)">
-                                        </td>
-                                        </td>
-                                </tbody>
-                            </table>
+            <template v-if="rows.length">
+                <div class="row my-3">
+                    <div class="col">
+                        <div class="bg-white p-3">
+                            <h6 class="font-weight-bold">Table output:</h6>
+                            <div class="table-responsive">
+                                <table class="table table-bordered table-hover">
+                                    <tbody>
+                                        <tr v-for="(row, rowIndex) in rows">
+                                            <td v-for="(column, columnIndex) in columns[rowIndex]">
+                                                <input class="border-0" type="text" v-model="columns[rowIndex][columnIndex]" @keyup="updateColumns(rowIndex, columnIndex)">
+                                            </td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
-        </template>
-        <div class="row">
-            <div class="col-md-12">
-                <div class="px-3">
-                    <button type="button" class="btn btn-sm btn-primary" @click="submit">Submit</button>
-                    <button type="button" class="btn btn-sm btn-secondary" @click="generateAutoFilledJson">Fill</button>
+            </template>
+            <div class="row">
+                <div class="col-md-12">
+                    <div class="px-3">
+                        <button type="button" class="btn btn-sm btn-primary" @click="submit">Submit</button>
+                        <button type="button" class="btn btn-sm btn-secondary" @click="generateAutoFilledJson">Fill</button>
+                    </div>
                 </div>
             </div>
         </div>
-    </div>
 
+    </div>
 </div>
 
-<script src="{{ asset('js/tsvToArray.js') }}"></script>
-
-<script type="text/javascript">
-    var app = new Vue({
-        el: '#app',
-        data: {
-            content: '',
-            rowSplitter: '\n',
-            columnSplitter: '\t',
-            rows: [],
-            columns: [],
-            maxColumn: 0,
-            jsonStructure: '',
-            isAutoFilled: false,
-            refreshing: false,
-            refreshingLine: false
-        },
-        delimiters: ['@{{', '}}'],
-        methods: {
+<script>
+    (function() {
+        function init() {
+            new Vue({
+                el: '#statTreeView',
+                data: {
+                    content: '',
+                    rowSplitter: '\n',
+                    columnSplitter: '\t',
+                    rows: [],
+                    columns: [],
+                    maxColumn: 0,
+                    jsonStructure: '',
+                    isAutoFilled: false,
+                    refreshing: false,
+                    refreshingLine: false
+                },
+                delimiters: ['@{{', '}}'],
+                methods: {
             updateColumns(rowIndex, columnIndex) {
                 try {
                     this.rows[rowIndex] = this.columns[rowIndex].join(this.columnSplitter);
@@ -205,8 +209,9 @@
                 }, function(response) {
                     self.refreshing = false;
                     if (response.success) {
-                        // location.href = "{{ route('practice-management.statTrees.view.dashboard', $statTree) }}";
-                        location.reload();
+                        fastLoad("{{ route('practice-management.statTrees.view.dashboard', $statTree) }}");
+                        //fastReload()
+
                     } else {
                         toastr.error(response.message);
                     }
@@ -214,7 +219,7 @@
             },
             initRefreshLineQuery: function() {
                 var self = this;
-                
+
                 $('[refresh-line-query]').click(function() {
                     var element = $(this);
                     var id = element.data('id');
@@ -242,10 +247,10 @@
         mounted: function() {
             this.init();
         },
-        updated: function(){
+        updated: function() {
             var self = this;
-            self.$nextTick(function(){
-                
+            self.$nextTick(function() {
+
             });
         },
         watch: {
@@ -260,7 +265,10 @@
                 })
             }
         }
-    });
+            });
+        }
+        addMCInitializer('statTreeView', init, '#statTreeViewPage')
+    }).call(window);
 </script>
 
 @endsection

+ 32 - 0
resources/views/layouts/patient.blade.php

@@ -532,6 +532,38 @@ $isVisitNote = ($routeName === 'patients.view.notes.view.dashboard' && @$note &&
                                                 @endif
                                             @endif
                                         </div>
+											<div>
+												<label>Engagement Status:</label>
+												<b>{{$patient->client_engagement_status_category ? ucwords(strtolower(str_replace('_', ' ', $patient->client_engagement_status_category))) : '-'}}</b>
+												<div moe class="ml-2 hide-inside-popup">
+													<a start show><i class="fa fa-edit"></i></a>
+													<form url="/api/client/updateClientEngagementAssessmentStatus" class="mcp-theme-1">
+														<input type="hidden" name="uid" value="{{$patient->uid}}">
+														<div class="mb-2">
+															<label class="mb-1 text-secondary text-sm">Status</label>
+															<select name="category" class="form-control form-control-sm">
+																<option value=""> --select--</option>
+																<option {{ $patient->client_engagement_status_category === 'ACTIVE' ? 'selected' : '' }} value="ACTIVE">Active</option>
+																<option {{ $patient->client_engagement_status_category === 'INACTIVE' ? 'selected' : '' }} value="INACTIVE">Inactive</option>
+																<option {{ $patient->client_engagement_status_category === 'ENTRY_ERROR' ? 'selected' : '' }} value="ENTRY_ERROR">Entry Error</option>
+																<option {{ $patient->client_engagement_status_category === 'DUMMY' ? 'selected' : '' }} value="DUMMY">Dummy</option>
+																<option {{ $patient->client_engagement_status_category === 'DECEASED' ? 'selected' : '' }} value="DECEASED">Deceased</option>
+																<option {{ $patient->client_engagement_status_category === 'DUPLICATE' ? 'selected' : '' }} value="DUPLICATE">Duplicate</option>
+																<option {{ $patient->client_engagement_status_category === 'NO_LONGER_INTERESTED' ? 'selected' : '' }} value="NO_LONGER_INTERESTED">No Longer Interested</option>
+																<option {{ $patient->client_engagement_status_category === 'BAD_RECORD' ? 'selected' : '' }} value="BAD_RECORD">Bad Record</option>
+															</select>
+														</div>
+														<div class="mb-2">
+															<label class="mb-1 text-secondary text-sm">Memo</label>
+															<textarea class="form-control form-control-sm" name="memo"></textarea>
+														</div>
+														<div>
+															<button submit class="btn btn-sm btn-primary mr-1">Submit</button>
+															<button cancel class="btn btn-sm btn-default border">Cancel</button>
+														</div>
+													</form>
+												</div>
+											</div>
                                         </div>
                                     </section>
                                     {{--<section>

+ 2 - 0
resources/views/layouts/template.blade.php

@@ -64,6 +64,8 @@
     {{-- pdfjs --}}
     <script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script>
 
+    <script src="{{ asset('js/tsvToArray.js') }}"></script>
+
     {{-- WebSockets --}}
     <script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.0/sockjs.min.js"
             integrity="sha512-5yJ548VSnLflcRxWNqVWYeQZnby8D8fJTmYRLyvs445j1XmzR8cnWi85lcHx3CUEeAX+GrK3TqTfzOO6LKDpdw=="

+ 5 - 0
routes/web.php

@@ -386,6 +386,7 @@ Route::middleware('pro.auth')->group(function () {
     Route::get('/problems-center/{patient}/{note}', 'NoteController@problemsCenter')->name('problems-center');
     Route::get('/goals-center/{patient}/{note}', 'NoteController@goalsCenter')->name('goals-center');
     Route::get('/allergies-center/{patient}/{note}', 'NoteController@allergiesCenter')->name('allergies-center');
+    Route::get('/careteam-center/{patient}/{note}', 'NoteController@careteamCenter')->name('careteam-center');
 
     Route::get('/problems-quick-add/{patient}/{note}', 'NoteController@problemsQuickAdd')->name('problems-quick-add');
 
@@ -489,6 +490,10 @@ Route::middleware('pro.auth')->group(function () {
     Route::any('/fdb-drug-coadministration', 'FDBPGController@drugCoadministration');
     Route::any('/fdb-duplicate-therapy', 'FDBPGController@duplicateTherapy');
 
+    Route::any('/fdb-rx-vigilance/{patient}', 'FDBPGController@rxVigilance');
+    Route::any('/fdb-dx-vigilance/{patient}', 'FDBPGController@dxVigilance');
+    Route::any('/fdb-allergy-vigilance/{patient}', 'FDBPGController@allergyVigilance');
+
     Route::get('/search-payer/json', 'PayerController@searchPayerV2JSON')->name('searchPayerV2JSON');
     Route::get('/search-facility/json', 'HomeController@facilitySuggestJSON')->name('facilitySuggestJSON');
 

+ 261 - 0
spec/stat-tree-report-builder-spec.txt

@@ -0,0 +1,261 @@
+
+	clause
+		model
+		label
+		question
+		answer
+		clause_text
+		position_index // for rendering, no logical consequence
+
+			EXAMPLE:
+
+				MODEL | QUESTION / LABEL | ANSWER | CLAUSE_TEXT
+[MODEL][TAB][QUESTION][TAB][ANSWER][TAB][QUERY]
+Client	Active?	YES	(is_active IS TRUE)
+Client	Active?	NO	(is_active IS FALSE)
+Client	MCP assigned?	YES	(mcp_pro_id IS NOT NULL)
+Client	MCP assigned?	NO	(mcp_pro_id IS NULL)
+Client	Future MCP appointment?	YES	()
+Client	Future MCP appointment?	NO	()
+Client	MCB Primary?	YES	()
+Client	MCB Primary?	NO	()
+Client	Has active RM device?	YES	()
+Client	Has active RM device?	NO	()
+Client	Active device type?	Weight	()
+Client	Active device type?	BP	()
+Client	Active device type?	Weight ONLY	()
+Client	Active device type?	BP ONLY	()
+Client	Active device type?	Weight + BP	()
+Client	Type 2 Diabetic	-	()
+Pro	Active?	YES	(is_active IS TRUE)
+Pro	Active?	NO	(is_active IS FALSE)
+Pro	Is HCP?	YES	(is_hcp IS TRUE)
+Pro	Is HCP?	NO	(is_hcp IS NOT TRUE)
+
+			WORK:::::::::::::::
+
+				- FRONTEND: paste a tsv into a textarea and see it as a table.
+				- BACKEND PHP: take in a tsv, foreach over and spit it back as a JSON.
+
+	stat_tree
+		name
+		model
+		slug
+		max_line_length
+		last_refreshed_at
+		tsv_text_for_lines
+
+			EXAMPLE tsv_text_for_lines:
+			
+[QUESTION][SPACE][ANSWER]
+Active? YES
+	MCP assigned? YES
+		MCB Primary? NO
+			Has active RM device? YES
+	MCP assigned? NO
+		MCB Primary? YES
+Active? NO
+	MCB Primary? YES
+		Has active RM device? YES
+		Has active RM device? NO
+	MCB Primary? NO
+		Has active RM device? YES
+		Has active RM device? NO
+	Has active RM device? YES
+	Has active RM device? NO
+//Pros
+Active? YES
+	Is HCP? YES
+	Is HCP? NO
+Active? NO
+	Is HCP? YES
+	Is HCP? NO
+
+
+	stat_tree_line
+		stat_tree_id
+		tree_order_position_index
+		last_refresh_count
+		tsv_text_for_report_columns
+
+			EXAMPLE tsv_text_for_report_columns:
+
+				LABEL | DISPLAY_KEY | DISPLAY_FUNCTION | RECORD_ROUTE_NAME
+
+	stat_tree_line_clause
+		stat_tree_line_id
+		clause_id
+		clause_label
+		position_index
+
+	stat_tree_line_report_column
+		stat_tree_line_id
+		label
+		position_index
+		display_key // if super simple
+		display_function // if custom on model
+		record_route_name
+
+------------------------------------------------------------------------------------------------
+
+	api/clause/replaceAll
+		tsvText
+
+			LOGIC:
+
+				delete all lines
+				foreach line, create record
+
+	api/statTree/create
+		name
+		table
+		slug
+
+			LOGIC:
+
+				confirm no duplicate
+				create statTree
+
+	api/statTree/delete
+		uid
+
+			LOGIC:
+
+				delete it
+
+	api/statTree/updateBasic // can't change table
+		uid
+		name
+		slug
+
+			LOGIC:
+
+				confirm no duplicate
+				update
+
+	api/statTree/refreshCount
+		uid
+
+			LOGIC:
+
+				public function refreshCount($statTreeID){
+					$statTree = StatTree::get($statTreeID);
+					foreach($statTree->lines as $line){
+						this->updateStatTreeLineCount($line);
+					}
+					$statTree->last_refreshed_at = now();
+				}
+
+				private function refreshCount($line){
+					$table = $line->statTree->table;
+					$query = "SELECT COUNT(*) FROM $table WHERE ";
+					$allClauses = $line->statTreeLineClauses;
+					for($i = 0; $i < count($allClauses); $i++){
+						$query .= $allClauses[$i] . ($i == count($allClauses) - 1 ? '' : ' AND ');
+					}
+					$count = runRawSqlSafelyForCount($query);
+					$line->last_refresh_count = $count;
+					return count;
+				}
+
+	api/statTree/replaceAllLines
+		uid
+		tsvText
+
+			LOGIC:
+
+				EXAMPLE tsv_text_for_lines:
+
+					Active patient? YES
+						MCP assigned? YES
+							MCB Primary? NO
+								Has active RM device? YES
+						MCP assigned? NO
+							MCB Primary? YES
+					Active patient? NO
+						MCB Primary? YES
+							Has active RM device? YES	
+							Has active RM device? NO	
+						MCB Primary? NO
+							Has active RM device? YES
+							Has active RM device? NO
+						Has active RM device? YES	
+						Has active RM device? NO
+
+				public function replaceAllLines($statTree, $tsvText){
+					// fill in missing blanks down the rows
+					// foreach fully filled row, create a stat_tree_line
+				}
+
+
+	api/statTreeLine/replaceAllReportColumns
+		uid
+		tsvText
+
+			LOGIC:
+
+				EXAMPLE tsv_text_for_report_columns:
+
+					LABEL | DISPLAY_KEY | DISPLAY_FUNCTION | RECORD_ROUTE_NAME
+
+					public function replaceAllReportColumns($statTreeLine, $tsvText){
+						// fill in missing blanks down the rows
+					}
+
+------------------------------------------------------------------------------------------------
+
+/stat-tree/{{$statTree->slug}}
+
+	Stat Tree: {{ $statTree->name }} | Last refreshed: {{ $statTree->last_refreshed_at }}
+
+	<table>
+		<tr>
+			@for($i = 0; $statTree->max_line_length - 2; $i++)
+				<th></th>
+			@endfor
+			<th>Count</th>
+		</tr>
+		@foreach($statTree->lines as $line) // ->lines returns by tree_order_position_index
+			@for($i = 0; $statTree->max_line_length - 2; $i++)
+				<td>
+					{{ $i == $line->all_clauses_length - 1 ? $line->clause->label : '-' }}
+				</td>
+			@endfor
+			<td>{{ $line->last_refresh_count }}</td>
+		@endforeach
+	</table>
+
+------------------------------------------------------------------------------------------------
+
+/dynamic-stat-tree/{{statTree->slug}}?top-level-filters=(BASE64OFTHEM)
+
+	Top level filters:
+		-(WHERE mcp_pro_id=2)
+
+	// render same thing as static stat-tree, but with this filter and dynamic count
+
+------------------------------------------------------------------------------------------------
+
+/stat-tree-line/{{uid}}
+
+	Stat Tree: {{ $statTree->name }}
+	Table: {{ $line-> }}
+	Line: {{ $line->all_clauses_text }}
+
+	@foreach($columns as $column)
+		<th></th>
+
+	@foreach($records as $record)
+		@foreach($columns as $column)
+		<td>{{ $record->{{$column->display_function ? $column->display_function : $column->display_key }} }}</td>
+
+	(PAGINATE)
+
+------------------------------------------------------------------------------------------------
+
+/dynamic-stat-tree-line/{{uid}}?top-level-filters=(BASE64OFTHEM)
+
+	Top level filters:
+		-(WHERE mcp_pro_id=2)
+
+	// render same thing as static stat-tree-line, but with this filter