Przeglądaj źródła

added client-ccm-rm-status report

= 3 lat temu
rodzic
commit
e8ef68fc41

+ 48 - 0
app/Http/Controllers/PracticeManagementController.php

@@ -2107,5 +2107,53 @@ ORDER BY c.name_last, c.name_first
     }
 
 
+    public function clientCcmRmStatus(Request $request){
+        $filters = $request->all();
+        $patients = Client::whereNull('shadow_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')->paginate(20);
+        return view('app.admin.client-ccm-rm-status', compact('patients', 'filters'));
+    }
 }

+ 116 - 0
resources/views/app/admin/client-ccm-rm-status-table.blade.php

@@ -0,0 +1,116 @@
+	<div class="table-responsive">
+	<table class="table table-striped p-0 m-0 table-sm border-top border-bottom text-nowrap">
+		<thead class="bg-light">
+			<tr>
+				<th class="border-0">#</th>
+				<th class="border-0">Name</th>
+				<th class="border-0">DOB</th>
+				<th class="border-0">Age</th>
+				<th class="border-0">Sex</th>
+				<th class="border-0">BMI</th>
+				<th class="border-0">Insurance</th>
+				<th class="border-0">Last Visit</th>
+				<th class="border-0">Next Appt.</th>
+				<th class="border-0">Status</th>
+
+				<th class="border-0">Is Eligible For CCM</th>
+				<th class="border-0">Is Enrolled In CCM</th>
+				<th class="border-0">CCM Setup Performed</th>
+
+				<th class="border-0">Is Eligible For RM</th>
+				<th class="border-0">Is Enrolled In RM</th>
+				<th class="border-0">RM Setup Performed</th>
+
+				@if($pro->pro_type == 'ADMIN')
+				<th class="border-0">MCP</th>
+				@endif
+			</tr>
+		</thead>
+		<tbody>
+			@foreach($patients as $patient)
+			<tr>
+				<td>
+					<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) }}</td>
+				<td>{{ $patient->age_in_years ?  $patient->age_in_years : '-' }}</td>
+				<td>{{ $patient->sex }}</td>
+				<td>
+					<div class="d-none d-dflex 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>
+					@include('app.patient.coverage_column_renderer', ['patient'=>$patient])
+				</td>
+				<td>
+					{{ friendly_date($patient->most_recent_completed_mcp_note_date) }}
+					{{-- {{$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>
+
+	
+
+	
+	YesNoOrUnknown isEligibleForRm = YesNoOrUnknown.UNKNOWN;
+	String whyNotEligibleForRmCategory;
+	String whyNotEligibleForRmMemo;
+
+	YesNoOrUnknown isEnrolledInRm = YesNoOrUnknown.UNKNOWN;
+
+	String whyNotEnrolledInRmCategory;
+	String whyNotEnrolledInRmMemo;
+
+	Boolean hasRmSetupBeenPerformed = Boolean.FALSE;
+
+	CareMonth rmSetupCareMonth;
+				<td>
+					YesNoOrUnknown isEligibleForCm = YesNoOrUnknown.UNKNOWN;
+					String whyNotEligibleForCmCategory;
+					String whyNotEligibleForCmMemo;
+				</td>
+				<td>
+					YesNoOrUnknown isEnrolledInCm = YesNoOrUnknown.UNKNOWN;
+					String cmEnrollmentConsentMethod;
+					String cmEnrollmentConsentMethodMemo;
+
+					String whyNotEnrolledInCmCategory;
+					String whyNotEnrolledInCmMemo;
+				</td>
+				<td>
+					Boolean hasCmSetupBeenPerformed = Boolean.FALSE;
+					Note cmSetupNote;
+				</td>
+				<td>
+					
+				</td>
+				<td></td>
+				<td></td>
+				
+				@if($pro->pro_type == 'ADMIN')
+				<td>{{$patient->mcp->display_name ?? '--'}}</td>
+				@endif
+			</tr>
+			@endforeach
+
+			@if(count($patients) === 0)
+			<tr>
+				<td colspan="24">No records found!</td>
+			</tr>
+			@endif
+		</tbody>
+
+	</table>
+</div>
+<div class="p-3">
+	{{$patients->withQueryString()->links()}}
+</div>

+ 22 - 0
resources/views/app/admin/client-ccm-rm-status.blade.php

@@ -0,0 +1,22 @@
+@extends ('layouts/template')
+
+@section('content')
+<div class="p-3 mcp-theme-1" id="patients-list">
+    <div class="card">
+
+        <div class="card-header px-3 py-2 d-flex align-items-center">
+            <strong class="mr-4">
+                <i class="fas fa-user"></i>
+                Patients CCM/RM Status
+            </strong>
+        </div>
+
+        <div class="card-body p-0">
+            <div class="p-3">
+                @include('app.admin.client_ccm_rm_status_filters')
+            </div>
+            @include('app.admin.client-ccm-rm-status-table')
+        </div>
+    </div>
+</div>
+@endsection

+ 271 - 0
resources/views/app/admin/client_ccm_rm_status_filters.blade.php

@@ -0,0 +1,271 @@
+<style>
+	#mcp-patients-filters label {
+		font-weight: bold;
+	}
+
+	#mcp-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="mcp-patients-filters" method="GET" action="{{ route('mcp.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="sm-section">
+		<div class="form-group">
+			<label>Age:</label>
+			<select name="age_category" class="form-control input-sm" v-model="filters.age_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 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="sm-section">
+		<div class="form-group">
+			<label>Sex:</label>
+			<select name="sex" class="form-control input-sm" v-model="filters.sex">
+				<option value="">All</option>
+				<option value="M">Male</option>
+				<option value="F">Female</option>
+			</select>
+		</div>
+	</div>
+	<!-- BMI -->
+	<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">
+				<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 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="sm-section">
+		<div class="form-group">
+			<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>
+				<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 v-show="filters.last_visit_category" class="mt-2">
+				<div>
+					<input  name="last_visit_value_1" v-model="filters.last_visit_value_1" type="number" 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="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<!-- NEXT APPOINTMENT -->
+	<div>
+		<div class="form-group">
+			<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>
+				<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 v-show="filters.next_appointment_category" class="mt-2">
+				<div>
+					<input  name="next_appointment_value_1" v-model="filters.next_appointment_value_1" type="number" 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="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<!-- STATUS -->
+	<div class="sm-section">
+		<div class="form-group">
+			<label>Status:</label>
+			<select name="status" class="form-control input-sm" v-model="filters.status">
+				<option value="">All</option>
+				<option value="ACTIVE">Active</option>
+				<option value="AWAITING_VISIT">Awaiting Visit</option>
+				<option value="INACTIVE">Inactive</option>
+			</select>
+		</div>
+	</div>
+
+	Filters 
+
+	isEligibleForCm 
+	isEnrolledInCm 
+	hasCmSetupBeenPerformed 
+
+	isEligibleForRm 
+	isEnrolledInRm 
+	hasRmSetupBeenPerformed 
+
+
+	<!-- 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 v-show="filters.last_weighed_in_category" class="mt-2">
+				<div>
+					<input  name="last_weighed_in_value_1" v-model="filters.last_weighed_in_value_1" type="number" class="form-control input-sm" :placeholder="(filters.last_weighed_in_category === 'BETWEEN' || filters.last_weighed_in_category === 'NOT_BETWEEN') ? 'From' : 'Last Weighed'" />
+				</div>
+				<div v-show="filters.last_weighed_in_category === 'BETWEEN' || filters.last_weighed_in_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="last_weighed_in_value_2" v-model="filters.last_weighed_in_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</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 v-show="filters.last_bp_category" class="mt-2">
+				<div>
+					<input  name="last_bp_value_1" v-model="filters.last_bp_value_1" type="number" class="form-control input-sm" :placeholder="(filters.last_bp_category === 'BETWEEN' || filters.last_bp_category === 'NOT_BETWEEN') ? 'From' : 'Last BP'" />
+				</div>
+				<div v-show="filters.last_bp_category === 'BETWEEN' || filters.last_bp_category === 'NOT_BETWEEN'" class="mt-2">
+					<input name="last_bp_value_2" v-model="filters.last_bp_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<div>
+		<div class="form-group">
+			<label>&nbsp;</label>
+			<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('mcp.patients')}}')" class="btn btn-link btn-sm text-danger">Clear Filters</a>
+			</div>
+		</div>
+	</div>
+</form>
+
+<?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',
+	'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() {
+			new Vue({
+				el: '#mcp-patients-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					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();
+				},
+			});
+
+
+		}
+		addMCInitializer('mcp-patients-filters', init, '#mcp-patients-filters');
+	})();
+</script>

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

@@ -163,6 +163,7 @@
                             <a class="dropdown-item" href="{{ route('practice-management.process-claims') }}">Process Claims</a>
                             <a class="dropdown-item" href="{{ route('practice-management.process-notes') }}">Process Notes</a>
                             <a class="dropdown-item" href="{{ route('practice-management.notes-processing-center') }}">Notes Processing Center</a>
+                            <a class="dropdown-item" href="{{ route('practice-management.client-ccm-rm-status') }}">Client CCM/RM Status</a>
                             @if($pro->id == '1' || $pro->id == '16')
                                 <a class="dropdown-item" href="{{ route('practice-management.treatmentServiceUtil') }}">Treatment Service Util.</a>
                             @endif

+ 1 - 0
routes/web.php

@@ -246,6 +246,7 @@ Route::middleware('pro.auth')->group(function () {
         Route::get('patients-accounts-invites', 'PracticeManagementController@patientsAccountsInvites')->name('patientsAccountsInvites');
         Route::get('clients-bdt-devices', 'PracticeManagementController@clientsBdtDevices')->name('clientsBdtDevices');
         Route::get('memos', 'PracticeManagementController@memos')->name('memos');
+        Route::get('client-ccm-rm-status', 'PracticeManagementController@clientCcmRmStatus')->name('client-ccm-rm-status');
 
         Route::middleware('pro.auth.admin')->group(function () {