Prechádzať zdrojové kódy

Updated NA patients

Samson Mutunga 3 rokov pred
rodič
commit
8b5b028c2d

+ 12 - 27
app/Http/Controllers/DnaController.php

@@ -38,35 +38,21 @@ class DnaController extends Controller
         $filters = $request->all();
         $patients = Client::whereNull('shadow_pro_id')->where('default_na_pro_id', $this->performer->pro->id);
 
-        // filters
-        /*
-        array:18 [▼
-          "age_category" => "LESS_THAN"
-          "age_value_1" => "34"
-          "age_value_2" => null
-          "sex" => "M"
-          "bmi_category" => "BETWEEN"
-          "bmi_value_1" => "20"
-          "bmi_value_2" => "25"
-          "last_visit_category" => "LESS_THAN"
-          "last_visit_value_1" => "2021-10-14"
-          "last_visit_value_2" => null
-          "next_appointment_category" => "LESS_THAN"
-          "next_appointment_value_1" => "2021-10-15"
-          "status" => "ACTIVE"
-          "last_weighed_in_category" => "EXACTLY"
-          "last_weighed_in_value_1" => "2021-10-07"
-          "last_bp_category" => "BETWEEN"
-          "last_bp_value_1" => "2021-10-01"
-          "last_bp_value_2" => "2021-10-31"
-        ]
-        */
+        if ($request->input('name')) {
+            $name = trim($request->input('name'));
+            if ($name) {
+                $patients = $patients->where(function ($q) use ($name) {
+                    $q->where('name_first', 'ILIKE', '%' . $name . '%')
+                        ->orWhere('name_last', 'ILIKE', '%' . $name . '%');
+                });
+            }
+        }
 
         $this->filterMultiQuery($request, $patients, 'age_in_years', 'age_category', 'age_value_1', 'age_value_2');
         $this->filterSimpleQuery($request, $patients, 'sex', 'sex');
-        $this->filterMultiQuery($request, $patients, 'usual_bmi', 'bmi_category', 'bmi_value_1', 'bmi_value_2');
-        $this->filterMultiQuery($request, $patients, 'most_recent_weight_at', 'last_weighed_in_category', 'last_weighed_in_value_1', 'last_weighed_in_value_2');
-        $this->filterMultiQuery($request, $patients, 'most_recent_bp_at', 'last_bp_category', 'last_bp_value_1', 'last_bp_value_2');
+        $this->filterMultiQuery($request, $patients, 'usual_bmi_max', 'bmi_category', 'bmi_value_1', 'bmi_value_2');
+        $this->filterMultiQuery($request, $patients, 'most_recent_completed_mcp_note_date', 'last_visit_category', 'last_visit_value_1', 'last_visit_value_2'); 
+        $this->filterMultiQuery($request, $patients, 'next_mcp_appointment_date', 'next_appointment_category', 'next_appointment_value_1', 'next_appointment_value_2');
 
         switch($request->input('status')) {
             case 'ACTIVE':
@@ -79,7 +65,6 @@ class DnaController extends Controller
                 $patients->where('is_active', '<>', true);
                 break;
         }
-
         $patients = $patients->orderBy('created_at', 'DESC')->paginate(20);
         return view('app.dna.patients', compact('patients', 'filters'));
     }

+ 6 - 0
app/Models/Client.php

@@ -837,4 +837,10 @@ ORDER BY m.ts DESC
     public function coreNote(){
         return $this->hasOne(Note::class, 'id', 'core_note_id');
     }
+
+    public function mostRecentCompletedMcpNote(){
+        return $this->hasOne(Note::class, 'id', 'most_recent_completed_mcp_note_id');
+    }
+
+    
 }

+ 52 - 25
resources/views/app/dna/patients-table.blade.php

@@ -1,20 +1,21 @@
 <table class="table table-condensed p-0 m-0">
 	<thead class="bg-light">
 		<tr>
-			<th class="px-3 border-0">Chart #</th>
-			<th class="px-3 border-0">Name (F.I. LAST)</th>
+			<th class="px-3 border-0">#</th>
+			<th class="px-3 border-0">Name</th>
 			<th class="px-3 border-0">DOB</th>
-			<th class="px-3 border-0">Gender</th>
-			<th class="px-3 border-0">MCP</th>
+			<th class="px-3 border-0">Age</th>
+			<th class="px-3 border-0">Sex</th>
 			<th class="px-3 border-0">BMI</th>
 			<th class="px-3 border-0">Insurance</th>
+			<th class="px-3 border-0">MCP</th>
 			<th class="px-3 border-0">Last Visit</th>
 			<th class="px-3 border-0">Next Appt.</th>
 			<th class="px-3 border-0">Status</th>
 			<th class="px-3 border-0">CCM</th>
 			<th class="px-3 border-0">RPM</th>
-			<th class="px-3 border-0">Last Weight-In</th>
-			<th class="px-3 border-0">Last BP</th>
+			<th class="px-3 border-0 d-none">Last Weight-In</th>
+			<th class="px-3 border-0 d-none">Last BP</th>
 			<th class="px-3 border-0">Assigned On</th>
 		</tr>
 	</thead>
@@ -22,40 +23,66 @@
 		@foreach($patients as $patient)
 		<tr>
 			<td class="px-3">
-				<a href="{{route('patients.view.dashboard', $patient)}}">
+				<a native target="_blank" href="{{route('patients.view.dashboard', $patient)}}">
 					{{$patient->chart_number}}
 				</a>
 			</td>
 			<td>{{$patient->displayName()}}</td>
-			<td>{{ friendly_date_time($patient->dob, false) }} {{ $patient->age_in_years ? '(' . $patient->age_in_years . ' y.o)' : '(-)' }}</td>
+			<td class="text-nowrap">{{ friendly_date_time($patient->dob, false) }}</td>
+			<td>{{ $patient->age_in_years ?  $patient->age_in_years : '-' }}</td>
 			<td>{{ $patient->sex }}</td>
-			<td>{{ $patient->mcp->name_display }}</td>
-			<td>{{ $patient->usual_bmi }}</td>
+			<td>
+				<div class="d-flex flex-column">
+					@if($patient->usual_bmi_min && $patient->usual_bmi_max)
+					<small class="text-muted">BMI (Usual): <b>{{ $patient->usual_bmi_min }}</b> {{ $patient->usual_bmi_min_category }} to <b>{{ $patient->usual_bmi_max }}</b> {{ $patient->usual_bmi_max_category }}</small>
+					@endif
+					@if($patient->ideal_bmi)
+					<small class="text-muted">BMI (Ideal) <b>{{ $patient->ideal_bmi }}</b> {{ $patient->ideal_bmi_category }}</small>
+					@endif
+				</div>
+			</td>
 			<td>
 				<?php $coverageStatus = $patient->getPrimaryCoverageStatus(); ?>
-				@if($coverageStatus === 'YES')
-				<div class="text-nowrap">Covered <i class="fa fa-check-circle text-success"></i>
+				<div class="text-nowrap">
+					@if($coverageStatus === 'YES')
+					<i class="fa fa-check-circle text-success" data-toggle="tooltip" data-placement="bottom" title="Covered"></i>
+					@elseif($coverageStatus === 'NO')
+					<i class="fa fa-times text-danger" data-toggle="tooltip" data-placement="bottom" title="Not Covered"></i>
+					@else
+					<i class="fa fa-exclamation-triangle text-warning-mellow" data-toggle="tooltip" data-placement="bottom" title="Unknown"></i>
+					@endif
+					<?php $coverage = $patient->getPrimaryCoverage(); ?>
+					@if($coverage)
+					{{$coverage->insuranceDisplayName()}}
+					@endif
+				</div>
+			</td>
+			<td>
+				<div class="d-flex flex-column">
+					<span>{{ $patient->mcp->displayName() }}</span>
+					@if($patient->next_mcp_appointment_date)
+						<span>Next Appt. {{ friendly_date_time($patient->next_mcp_appointment_date) }}</span>
+					@endif
+					<?= $recentNote = $patient->mostRecentCompletedMcpNote; ?>
+					@if($recentNote)
+					<div>
+						Note: <a href="/patients/view/{{ $patient->uid }}/notes/view/{{ $recentNote->uid }}" class="font-weight-bold">
+                        {{ friendly_date_time($recentNote->effective_dateest, false) }}
+                    </a>
+					</div>
+					@endif
 				</div>
-				@elseif($coverageStatus === 'NO')
-				<div class="text-nowrap">Not Covered <i class="fa fa-times text-danger"></i></div>
-				@else
-				<div class="text-nowrap">Unknown <i class="fa fa-exclamation-triangle text-warning-mellow"></i></div>
-				@endif
-				<?php $coverage = $patient->getPrimaryCoverage(); ?>
-				@if($coverage)
-				{{$coverage->insuranceDisplayName()}}
-				@endif
 			</td>
 			<td>{{$patient->lastMcpAppointment ? friendly_date_time($patient->lastMcpAppointment->raw_date.' '.$patient->lastMcpAppointment->raw_start_time) : '-'}}</td>
 			<td>{{$patient->nextMcpAppointment ? friendly_date_time($patient->nextMcpAppointment->raw_date.' '.$patient->nextMcpAppointment->raw_start_time) : '-'}}</td>
 			<td>{{$patient->nextMcpAppointment ? $patient->nextMcpAppointment->status : '-'}}</td>
 			<td>{{$patient->is_enrolled_in_cm ? 'Yes' : 'No'}}</td>
 			<td>{{$patient->is_enrolled_in_rm ? 'Yes' : 'No'}}</td>
-			<td>
+			<td class="d-none">
 				<?php $m = $patient->lastMeasurementOfType('Wt. (lbs.)'); ?>
 				{{$m && $m->value ? round($m->value, 2) : '-'}}
 			</td>
-			<td>
+			<td class="d-none">
 				<?php $m = $patient->lastMeasurementOfType('BP'); ?>
 				{{$m && $m->value ? $m->value : '-'}}
 			</td>
@@ -65,12 +92,12 @@
 
 		@if(count($patients) === 0)
 		<tr>
-			<td colspan="14">No records found!</td>
+			<td colspan="16">No records found!</td>
 		</tr>
 		@endif
 	</tbody>
 
 </table>
 <div class="p-3">
-	{{$patients->links()}}
+	{{$patients->withQueryString()->links()}}
 </div>

+ 76 - 123
resources/views/app/dna/patients_filters.blade.php

@@ -6,10 +6,34 @@
 	#dna-patients-filters .mw-100px {
 		min-width: 100px;
 	}
+
+	.filter-container {
+		display: flex;
+		align-items: flex-start;
+		flex-wrap: wrap;
+	}
+
+	.filter-container>div {
+		width: 165px;
+	}
+
+	.filter-container>div:not(:last-child) {
+		margin-right: 15px;
+	}
+
+	.sm-section {
+		width: 125px !important;
+	}
 </style>
-<form id="dna-patients-filters" method="GET" action="{{ route('dna.patients') }}" class="row align-items-start" v-cloak>
+<form id="dna-patients-filters" method="GET" action="{{ route('dna.patients') }}" class="filter-container" v-cloak>
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Name:</label>
+			<input name="name" class="form-control input-sm" v-model="filters.name">
+		</div>
+	</div>
 	<!-- AGE	 -->
-	<div class="col-md-2">
+	<div class="sm-section">
 		<div class="form-group">
 			<label>Age:</label>
 			<select name="age_category" class="form-control input-sm" v-model="filters.age_category">
@@ -20,22 +44,18 @@
 				<option value="BETWEEN">Between</option>
 				<option value="NOT_BETWEEN">Not Between</option>
 			</select>
-		</div>
-	</div>
-	<div v-show="filters.age_category" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="age_value_1" v-model="filters.age_value_1" type="number" class="form-control input-sm" :placeholder="(filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN') ? 'From' : 'Age'" />
-		</div>
-	</div>
-	<div v-show="filters.age_category && (filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN')" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="age_value_2" v-model="filters.age_value_2" type="number" class="form-control input-sm" placeholder="To" />
+			<div v-show="filters.age_category" class="mt-2">
+				<div>
+					<input name="age_value_1" v-model="filters.age_value_1" type="number" class="form-control input-sm" :placeholder="(filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN') ? 'From' : 'Age'" />
+				</div>
+				<div v-show="filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="age_value_2" v-model="filters.age_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
 		</div>
 	</div>
 	<!-- SEX -->
-	<div class="col-md-2">
+	<div class="sm-section">
 		<div class="form-group">
 			<label>Sex:</label>
 			<select name="sex" class="form-control input-sm" v-model="filters.sex">
@@ -46,7 +66,7 @@
 		</div>
 	</div>
 	<!-- BMI -->
-	<div class="col-md-2">
+	<div class="sm-section">
 		<div class="form-group">
 			<label>BMI:</label>
 			<select name="bmi_category" class="form-control input-sm" v-model="filters.bmi_category">
@@ -57,25 +77,21 @@
 				<option value="BETWEEN">Between</option>
 				<option value="NOT_BETWEEN">Not Between</option>
 			</select>
-		</div>
-	</div>
-	<div v-show="filters.bmi_category" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="bmi_value_1" v-model="filters.bmi_value_1" type="number" class="form-control input-sm" :placeholder="(filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN') ? 'From' : 'BMI'" />
-		</div>
-	</div>
-	<div v-show="filters.bmi_category && (filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN')" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="bmi_value_2" v-model="filters.bmi_value_2" type="number" class="form-control input-sm" placeholder="To" />
+			<div v-show="filters.bmi_category" class="mt-2">
+				<div>
+					<input name="bmi_value_1" v-model="filters.bmi_value_1" type="number" class="form-control input-sm" :placeholder="(filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN') ? 'From' : 'BMI'" />
+				</div>
+				<div v-show="filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="bmi_value_2" v-model="filters.bmi_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
 		</div>
 	</div>
 
 	<!-- LAST VISIT -->
-	<div class="col-md-2">
+	<div class="sm-section">
 		<div class="form-group">
-			<label>Last Visit **:</label>
+			<label>Last Visit:</label>
 			<select name="last_visit_category" class="form-control input-sm" v-model="filters.last_visit_category">
 				<option value="">All</option>
 				<option value="EXACTLY">Exactly</option>
@@ -84,25 +100,21 @@
 				<option value="BETWEEN">Between</option>
 				<option value="NOT_BETWEEN">Not Between</option>
 			</select>
-		</div>
-	</div>
-	<div v-show="filters.last_visit_category" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="last_visit_value_1" v-model="filters.last_visit_value_1" type="date" class="form-control input-sm" :placeholder="(filters.last_visit_category === 'BETWEEN' || filters.last_visit_category === 'NOT_BETWEEN') ? 'From' : 'Last Visit'" />
-		</div>
-	</div>
-	<div v-show="filters.last_visit_category && (filters.last_visit_category === 'BETWEEN' || filters.last_visit_category === 'NOT_BETWEEN')" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="last_visit_value_2" v-model="filters.last_visit_value_2" type="date" class="form-control input-sm" placeholder="To" />
+			<div v-show="filters.last_visit_category" class="mt-2">
+				<div>
+					<input name="last_visit_value_1" v-model="filters.last_visit_value_1" type="date" class="form-control input-sm" :placeholder="(filters.last_visit_category === 'BETWEEN' || filters.last_visit_category === 'NOT_BETWEEN') ? 'From' : 'Last Visit'" />
+				</div>
+				<div v-show="filters.last_visit_category === 'BETWEEN' || filters.last_visit_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="last_visit_value_2" v-model="filters.last_visit_value_2" type="date" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
 		</div>
 	</div>
 
 	<!-- NEXT APPOINTMENT -->
-	<div class="col-md-2">
+	<div>
 		<div class="form-group">
-			<label>Next Appointment **:</label>
+			<label>Next Appointment:</label>
 			<select name="next_appointment_category" class="form-control input-sm" v-model="filters.next_appointment_category">
 				<option value="">All</option>
 				<option value="EXACTLY">Exactly</option>
@@ -111,23 +123,19 @@
 				<option value="BETWEEN">Between</option>
 				<option value="NOT_BETWEEN">Not Between</option>
 			</select>
-		</div>
-	</div>
-	<div v-if="filters.next_appointment_category" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="next_appointment_value_1" v-model="filters.next_appointment_value_1" type="date" class="form-control input-sm" :placeholder="(filters.next_appointment_category === 'BETWEEN' || filters.next_appointment_category === 'NOT_BETWEEN') ? 'From' : 'Next Appointment'" />
-		</div>
-	</div>
-	<div v-if="filters.next_appointment_category && (filters.next_appointment_category === 'BETWEEN' || filters.next_appointment_category === 'NOT_BETWEEN')" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="next_appointment_value_2" v-model="filters.next_appointment_value_2" type="date" class="form-control input-sm" placeholder="To" />
+			<div v-show="filters.next_appointment_category" class="mt-2">
+				<div>
+					<input name="next_appointment_value_1" v-model="filters.next_appointment_value_1" type="date" class="form-control input-sm" :placeholder="(filters.next_appointment_category === 'BETWEEN' || filters.next_appointment_category === 'NOT_BETWEEN') ? 'From' : 'Next Appt.'" />
+				</div>
+				<div v-show="filters.next_appointment_category === 'BETWEEN' || filters.next_appointment_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="next_appointment_value_2" v-model="filters.next_appointment_value_2" type="date" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
 		</div>
 	</div>
 
 	<!-- STATUS -->
-	<div class="col-md-2">
+	<div class="sm-section">
 		<div class="form-group">
 			<label>Status:</label>
 			<select name="status" class="form-control input-sm" v-model="filters.status">
@@ -139,65 +147,13 @@
 		</div>
 	</div>
 
-	<!-- LAST WEIGHED-IN -->
-	<div class="col-md-2">
-		<div class="form-group">
-			<label>Last Weighed-In:</label>
-			<select name="last_weighed_in_category" class="form-control input-sm" v-model="filters.last_weighed_in_category">
-				<option value="">All</option>
-				<option value="EXACTLY">Exactly</option>
-				<option value="LESS_THAN">Less Than</option>
-				<option value="GREATER_THAN">Greater Than</option>
-				<option value="BETWEEN">Between</option>
-				<option value="NOT_BETWEEN">Not Between</option>
-			</select>
-		</div>
-	</div>
-	<div v-if="filters.last_weighed_in_category" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="last_weighed_in_value_1" v-model="filters.last_weighed_in_value_1" type="date" class="form-control input-sm" :placeholder="(filters.last_weighed_in_category === 'BETWEEN' || filters.last_weighed_in_category === 'NOT_BETWEEN') ? 'From' : 'Enter Date'" />
-		</div>
-	</div>
-	<div v-if="filters.last_weighed_in_category && (filters.last_weighed_in_category === 'BETWEEN' || filters.last_weighed_in_category === 'NOT_BETWEEN')" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="last_weighed_in_value_2" v-model="filters.last_weighed_in_value_2" type="date" class="form-control input-sm" placeholder="To" />
-		</div>
-	</div>
-
-	<!-- LAST BP -->
-	<div class="col-md-2">
-		<div class="form-group">
-			<label>Last BP:</label>
-			<select name="last_bp_category" class="form-control input-sm" v-model="filters.last_bp_category">
-				<option value="">All</option>
-				<option value="EXACTLY">Exactly</option>
-				<option value="LESS_THAN">Less Than</option>
-				<option value="GREATER_THAN">Greater Than</option>
-				<option value="BETWEEN">Between</option>
-				<option value="NOT_BETWEEN">Not Between</option>
-			</select>
-		</div>
-	</div>
-	<div v-if="filters.last_bp_category" class="col-md-2">
-		<div class="form-group">
-			<label>&nbsp;</label>
-			<input name="last_bp_value_1" v-model="filters.last_bp_value_1" type="date" class="form-control input-sm" :placeholder="(filters.last_bp_category === 'BETWEEN' || filters.last_bp_category === 'NOT_BETWEEN') ? 'From' : 'Enter Date'" />
-		</div>
-	</div>
-	<div v-if="filters.last_bp_category && (filters.last_bp_category === 'BETWEEN' || filters.last_bp_category === 'NOT_BETWEEN')" class="col-md-2">
+	<div>
 		<div class="form-group">
 			<label>&nbsp;</label>
-			<input name="last_bp_value_2" v-model="filters.last_bp_value_2" type="date" class="form-control input-sm" placeholder="To" />
-		</div>
-	</div>
-
-	<div class="col-md-2">
-		<div class="form-group d-flex">
-			<label>&nbsp;</label>
-			<button type="button" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2 mw-100px">Apply Filters</button>
-			<a href="{{ route('dna.patients') }}" class="btn btn-danger btn-sm text-white mw-100px">Clear Filters</a>
+			<div class=" d-flex">
+				<button type="button" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2"><i class="fas fa-filter"></i> Filter</button>
+				<a href="#" v-on:click.prevent="fastLoad('{{route('dna.patients')}}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
 		</div>
 	</div>
 </form>
@@ -205,26 +161,23 @@
 <?php
 $loadedFilters = $filters;
 $allFilterKeys = [
+	'name',
 	'age_category',
 	'age_value_1',
 	'age_value_2',
 	'bmi_category',
 	'bmi_value_1',
-	'bmi_value_2',
-	'last_bp_category',
-	'last_bp_value_1',
-	'last_bp_value_2',
+	'bmi_value_2',	
 	'last_visit_category',
 	'last_visit_value_1',
 	'last_visit_value_2',
-	'last_weighed_in_category',
-	'last_weighed_in_value_1',
 	'next_appointment_category',
 	'next_appointment_value_1',
+	'next_appointment_value_2',
 	'sex',
 	'status',
 ];
-for ($i=0; $i < count($allFilterKeys); $i++) {
+for ($i = 0; $i < count($allFilterKeys); $i++) {
 	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
 		$loadedFilters[$allFilterKeys[$i]] = '';
 	}
@@ -241,10 +194,10 @@ for ($i=0; $i < count($allFilterKeys); $i++) {
 				},
 				methods: {
 					init: function() {
-						
+
 					},
 					doSubmit: function() {
-						fastLoad('{{ route('dna.patients') }}?' + $('#dna-patients-filters').serialize());
+						fastLoad('{{ route("dna.patients") }}?' + $('#dna-patients-filters').serialize());
 						return false;
 					}
 				},