Browse Source

MCP patients list - filters impl

Vijayakrishnan 3 years ago
parent
commit
78cbd228eb

+ 88 - 5
app/Http/Controllers/McpController.php

@@ -37,11 +37,94 @@ class McpController extends Controller
 
     public function patients(Request $request)
     {
-        $patients = Client::whereNull('shadow_pro_id')
-            ->where('mcp_pro_id', $this->performer->pro->id)
-            ->orderBy('created_at', 'DESC')
-            ->get();
-        return view('app.mcp.patients', compact('patients'));
+        $filters = $request->all();
+        $patients = Client::whereNull('shadow_pro_id')->where('mcp_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"
+        ]
+        */
+
+        $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');
+
+        switch($request->input('status')) {
+            case 'ACTIVE':
+                $patients->where('is_active', true)->where('has_mcp_done_onboarding_visit', true);
+                break;
+            case 'AWAITING_VISIT':
+                $patients->where('is_active', true)->where('has_mcp_done_onboarding_visit', false);
+                break;
+            case 'INACTIVE':
+                $patients->where('is_active', '<>', true);
+                break;
+        }
+
+        $patients = $patients->orderBy('created_at', 'DESC')->get();
+        return view('app.mcp.patients', compact('patients', 'filters'));
+    }
+
+    private function filterSimpleQuery(Request $request, $query, $columnName, $valueName) {
+        if($request->input($valueName)) {
+            $query->where($columnName, $request->input($valueName));
+        }
+    }
+    private function filterMultiQuery(Request $request, $query, $columnName, $keyName, $valueName1, $valueName2) {
+        switch($request->input($keyName)) {
+            case 'EXACTLY':
+                if($request->input($valueName1)) {
+                    $query->where($columnName, $request->input($valueName1));
+                }
+                break;
+            case 'LESS_THAN':
+                if($request->input($valueName1)) {
+                    $query->where($columnName, '<', $request->input($valueName1));
+                }
+                break;
+            case 'GREATER_THAN':
+                if($request->input($valueName1)) {
+                    $query->where($columnName, '>', $request->input($valueName1));
+                }
+                break;
+            case 'BETWEEN':
+                if($request->input($valueName1) && $request->input($valueName2)) {
+                    $query
+                        ->where($columnName, '>=', $request->input($valueName1))
+                        ->where($columnName, '<=', $request->input($valueName2));
+                }
+                break;
+            case 'NOT_BETWEEN':
+                if($request->input($valueName1) && $request->input($valueName2)) {
+                    $query
+                        ->where(function ($q) use ($request, $columnName, $valueName1, $valueName2) {
+                            $q->where($columnName, '<', $request->input($valueName1))
+                                ->orWhere($columnName, '>', $request->input($valueName2));
+                        });
+                }
+                break;
+        }
     }
 
     public function notes(Request $request)

+ 1 - 1
resources/views/app/mcp/patients.blade.php

@@ -43,7 +43,7 @@
                             </a>
                         </td>
                         <td>{{$patient->displayName()}}</td>
-                        <td>{{ friendly_date_time($patient->dob, false) }}</td>
+                        <td>{{ friendly_date_time($patient->dob, false) }} {{ $patient->age_in_years ? '(' . $patient->age_in_years . ' y.o)' : '(-)' }}</td>
                         <td>{{ $patient->sex }}</td>
                         <td>{{ $patient->usual_bmi }}</td>
                         <td>

+ 58 - 34
resources/views/app/mcp/patients_filters.blade.php

@@ -22,16 +22,16 @@
 			</select>
 		</div>
 	</div>
-	<div v-if="filters.age_category" class="col-md-2">
+	<div v-show="filters.age_category" class="col-md-2">
 		<div class="form-group">
 			<label>&nbsp;</label>
-			<input name="age_value_1" value="{{ $age_value_1 ?? '' }}" type="number" class="form-control input-sm" :placeholder="(filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN') ? 'From' : 'Age'" />
+			<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-if="filters.age_category && (filters.age_category === 'BETWEEN' || filters.age_category === 'NOT_BETWEEN')" class="col-md-2">
+	<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" value="{{ $age_value_2 ?? '' }}" type="number" class="form-control input-sm" placeholder="To" />
+			<input name="age_value_2" v-model="filters.age_value_2" type="number" class="form-control input-sm" placeholder="To" />
 		</div>
 	</div>
 	<!-- SEX -->
@@ -39,7 +39,7 @@
 		<div class="form-group">
 			<label>Sex:</label>
 			<select name="sex" class="form-control input-sm" v-model="filters.sex">
-				<option value="ALL">All</option>
+				<option value="">All</option>
 				<option value="M">Male</option>
 				<option value="F">Female</option>
 			</select>
@@ -59,23 +59,23 @@
 			</select>
 		</div>
 	</div>
-	<div v-if="filters.bmi_category" class="col-md-2">
+	<div v-show="filters.bmi_category" class="col-md-2">
 		<div class="form-group">
 			<label>&nbsp;</label>
-			<input name="bmi_value_1" value="{{ $bmi_value_1 ?? '' }}" type="number" class="form-control input-sm" :placeholder="(filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN') ? 'From' : 'BMI'" />
+			<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-if="filters.bmi_category && (filters.bmi_category === 'BETWEEN' || filters.bmi_category === 'NOT_BETWEEN')" class="col-md-2">
+	<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" value="{{ $bmi_value_2 ?? '' }}" type="number" class="form-control input-sm" placeholder="To" />
+			<input name="bmi_value_2" v-model="filters.bmi_value_2" type="number" class="form-control input-sm" placeholder="To" />
 		</div>
 	</div>
 
 	<!-- LAST VISIT -->
 	<div class="col-md-2">
 		<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>
@@ -86,23 +86,23 @@
 			</select>
 		</div>
 	</div>
-	<div v-if="filters.last_visit_category" class="col-md-2">
+	<div v-show="filters.last_visit_category" class="col-md-2">
 		<div class="form-group">
 			<label>&nbsp;</label>
-			<input name="last_visit_value_1" value="{{ $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'" />
+			<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-if="filters.last_visit_category && (filters.last_visit_category === 'BETWEEN' || filters.last_visit_category === 'NOT_BETWEEN')" class="col-md-2">
+	<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" value="{{ $last_visit_value_2 ?? '' }}" type="date" class="form-control input-sm" placeholder="To" />
+			<input name="last_visit_value_2" v-model="filters.last_visit_value_2" type="date" class="form-control input-sm" placeholder="To" />
 		</div>
 	</div>
 
 	<!-- NEXT APPOINTMENT -->
 	<div class="col-md-2">
 		<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>
@@ -116,13 +116,13 @@
 	<div v-if="filters.next_appointment_category" class="col-md-2">
 		<div class="form-group">
 			<label>&nbsp;</label>
-			<input name="next_appointment_value_1" value="{{ $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'" />
+			<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" value="{{ $next_appointment_value_2 ?? '' }}" type="date" class="form-control input-sm" placeholder="To" />
+			<input name="next_appointment_value_2" v-model="filters.next_appointment_value_2" type="date" class="form-control input-sm" placeholder="To" />
 		</div>
 	</div>
 
@@ -131,7 +131,7 @@
 		<div class="form-group">
 			<label>Status:</label>
 			<select name="status" class="form-control input-sm" v-model="filters.status">
-				<option value="ALL">All</option>
+				<option value="">All</option>
 				<option value="ACTIVE">Active</option>
 				<option value="AWAITING_VISIT">Awaiting Visit</option>
 				<option value="INACTIVE">Inactive</option>
@@ -156,13 +156,13 @@
 	<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" value="{{ $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'" />
+			<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" value="{{ $last_weighed_in_value_2 ?? '' }}" type="date" class="form-control input-sm" placeholder="To" />
+			<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>
 
@@ -183,49 +183,73 @@
 	<div v-if="filters.last_bp_category" class="col-md-2">
 		<div class="form-group">
 			<label>&nbsp;</label>
-			<input name="last_bp_value_1" value="{{ $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'" />
+			<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 class="form-group">
 			<label>&nbsp;</label>
-			<input name="last_bp_value_2" value="{{ $last_bp_value_2 ?? '' }}" type="date" class="form-control input-sm" placeholder="To" />
+			<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="submit" class="btn btn-primary btn-sm mr-2 mw-100px">Apply Filters</button>
+			<button type="button" v-on:click.prevent="doSubmit()" class="btn btn-primary btn-sm mr-2 mw-100px">Apply Filters</button>
 			<a href="{{ route('mcp.patients') }}" class="btn btn-danger btn-sm text-white mw-100px">Clear Filters</a>
 		</div>
 	</div>
 </form>
 
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'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',
+	'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',
+	'sex',
+	'status',
+];
+for ($i=0; $i < count($allFilterKeys); $i++) {
+	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {
+		$loadedFilters[$allFilterKeys[$i]] = '';
+	}
+}
+?>
 <script>
 	(function() {
 		function init() {
-			window.apapp = new Vue({
+			new Vue({
 				el: '#mcp-patients-filters',
 				delimiters: ['@{{', '}}'],
 				data: {
-					filters: {
-						age_category: "<?= $age_category ?? '' ?>",
-						bmi_category: "<?= $bmi_category ?? '' ?>",
-						last_visit_category: "<?= $last_visit_category ?? '' ?>",
-						next_appointment_category: "<?= $next_appointment_category ?? '' ?>",
-						last_weighed_in_category: "<?= $last_weighed_in_category ?? '' ?>",
-						last_bp_category: "<?= $last_bp_category ?? '' ?>",
-						sex: "<?= $sex ?? '' ?>",
-						status: "<?= $status ?? '' ?>"
-					}
+					filters: <?= json_encode($loadedFilters) ?>
 				},
 				methods: {
 					init: function() {
 						
+					},
+					doSubmit: function() {
+						fastLoad('{{ route('mcp.patients') }}?' + $('#mcp-patients-filters').serialize());
+						return false;
 					}
 				},
 				mounted: function() {
+					console.log(this.filters);
 					this.init();
 				},
 			});