Переглянути джерело

Merge branch 'deb-josh-reports' of rav.triplestart.com:jmudaka/stagfe2

= 3 роки тому
батько
коміт
07c0e1d87f

+ 8 - 1
app/Http/Controllers/AdminController.php

@@ -421,6 +421,13 @@ class AdminController extends Controller
         $templateContent = file_get_contents($path);
         return $this->pass($templateContent);
     }
+    
+    public function bdtDevices(Request $request)
+    {
+        $filters = $request->all();
 
+        $bdtDevices = BDTDevice::paginate(20);
+        return view('app.admin.bdt_devices', compact('bdtDevices', 'filters'));
+    }
 
-}
+} 

+ 4 - 0
app/Models/BDTDevice.php

@@ -6,4 +6,8 @@ class BDTDevice extends Model
 {
     protected $table = 'bdt_device';
 
+    public function clientBDTDevice() {
+        return $this->hasOne(ClientBDTDevice::class, 'device_id', 'id');
+    }
+
 }

+ 4 - 0
app/Models/ClientBDTDevice.php

@@ -14,6 +14,10 @@ class ClientBDTDevice extends Model
         return $this->hasOne(Client::class, 'id', 'client_id');
     }
 
+    public function supplyOrders(){
+        return $this->hasMany(SupplyOrder::class, 'client_bdt_device_id', 'id');
+    }
+
     public function mostRecentMeasurement() {
         return $this->hasOne(ClientBDTMeasurement::class, 'id', 'most_recent_client_bdt_measurement_id');
     }

+ 21 - 0
resources/views/app/admin/bdt_devices.blade.php

@@ -0,0 +1,21 @@
+@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>
+                    BDT Devices
+                </strong>
+            </div>
+                <div class="p-3">
+                    {{-- @include('app.admin.bdt_devices_filters') --}}
+                    TODO: filters
+                </div>
+                @include('app.admin.bdt_devices_table')
+            </div>
+        </div>
+    </div>
+@endsection

+ 421 - 0
resources/views/app/admin/bdt_devices_filters.blade.php

@@ -0,0 +1,421 @@
+<style>
+	#bdt-devices-filters label {
+		font-weight: bold;
+	}
+
+	#bdt-devices-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: 10px;
+	}
+	.sm-section {
+		width: 125px !important;
+	}
+</style>
+<form id="bdt-devices-filters" method="GET" action="{{ route('admin.bdt_devices') }}" class="filter-container" v-cloak>
+	<div class="sm-section">
+		<div class="">
+			<label>Name:</label>
+			<input name="name" class="form-control input-sm" v-model="filters.name">
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>MCP:</label>
+			<select name="mcp" class="form-control min-width-unset" v-model="filters.mcp">
+				<option value="">--select--</option>
+				<option value="NO_MCP">No MCP</option>
+				<?php $mcpPros = \App\Models\Pro::where('is_active', true)->where('is_enrolled_as_mcp', true)->orderBy('name_display')->get(); ?>
+				@foreach($mcpPros as $mcpPro)
+					<option value="{{$mcpPro->uid}}">{{$mcpPro->name_display}}</option>
+				@endforeach
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>NA:</label>
+			<select name="na" class="form-control min-width-unset" v-model="filters.na">
+				<option value="">--select--</option>
+				<option value="NO_NA">No NA</option>
+				<?php $naPros = \App\Models\Pro::where('is_active', true)->where('is_considered_for_dna', true)->orWhere('pro_type', '=', 'ADMIN')->orderBy('name_display')->get(); ?>
+				@foreach($naPros as $naPro)
+					<option value="{{$naPro->uid}}">{{$naPro->name_display}}</option>
+				@endforeach
+			</select>
+		</div>
+	</div>
+
+	<!-- AGE	 -->
+	<div class="sm-section">
+		<div class="">
+			<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="">
+			<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="">
+			<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="">
+			<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 class="sm-section">
+		<div class="">
+			<label>Next Appt.:</label>
+			<select name="next_appointment_category" class="form-control input-sm" v-model="filters.next_appointment_category">
+				<option value="">All</option>
+				<option value="NONE">None</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 && filters.next_appointment_category !== 'NONE'" 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="">
+			<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>
+
+	@if($performer->pro->pro_type == 'ADMIN')
+	<div class="sm-section">
+		<div class="">
+			<label>Initiative:</label>
+			<input type="text" name="initiative" class="form-control input-sm" v-model="filters.initiative">
+		</div>
+	</div>
+	<div class="sm-section">
+		<div class="">
+			<label>Insurance:</label>
+			<select class="form-control"  name="insurance" v-model="filters.insurance">
+				<option value=""></option>
+				<option value="MEDICARE">Medicare (Part B)</option>
+				<option value="OTHER">Other</option>
+			</select>
+		</div>
+	</div>
+	@endif
+
+	<div class="sm-section">
+		<div class="">
+			<label>Chart #</label>
+			<input class="form-control"  name="chart_number" v-model="filters.chart_number">
+		</div>
+	</div>
+
+	<!-- Number of measurements	 -->
+	<div class="sm-section">
+		<div class="">
+			<label># Measurements:</label>
+			<select name="number_of_measurements" class="form-control input-sm" v-model="filters.number_of_measurements">
+				<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.number_of_measurements" class="mt-2">
+				<div>
+					<input  name="number_of_measurements_value_1" v-model="filters.number_of_measurements_value_1" type="number" class="form-control input-sm" :placeholder="(filters.number_of_measurements === 'BETWEEN' || filters.number_of_measurements === 'NOT_BETWEEN') ? 'From' : 'Number of measurements'" />
+				</div>
+				<div v-show="filters.number_of_measurements === 'BETWEEN' || filters.number_of_measurements === 'NOT_BETWEEN'" class="mt-2">
+					<input name="number_of_measurements_value_2" v-model="filters.number_of_measurements_value_2" type="number" class="form-control input-sm" placeholder="To" />
+				</div>
+			</div>
+		</div>
+	</div>
+	<div class="sm-section">
+		<div class="">
+			<label>Home Address State:</label>
+			<select name="home_address_state" class="form-control input-sm" v-model="filters.home_address_state">
+				<option value="">All</option>
+				<option value="NONE">Not Available</option>
+				<option value="NOT_MD">Not MD</option>
+				<option value="AL">Alabama</option>	
+				<option value="AK">Alaska</option>	
+				<option value="AZ">Arizona</option>	
+				<option value="AR">Arkansas</option>	
+				<option value="CA">California</option>	
+				<option value="CO">Colorado</option>	
+				<option value="CT">Connecticut</option>	
+				<option value="DE">Delaware</option>	
+				<option value="FL">Florida</option>	
+				<option value="GA">Georgia</option>	
+				<option value="HI">Hawaii</option>	
+				<option value="ID">Idaho</option>	
+				<option value="IL">Illinois</option>	
+				<option value="IN">Indiana</option>	
+				<option value="IA">Iowa</option>	
+				<option value="KS">Kansas</option>	
+				<option value="KY">Kentucky</option>	
+				<option value="LA">Louisiana</option>	
+				<option value="ME">Maine</option>	
+				<option value="MD">Maryland</option>	
+				<option value="MA">Massachusetts</option>	
+				<option value="MI">Michigan</option>	
+				<option value="MN">Minnesota</option>	
+				<option value="MS">Mississippi</option>	
+				<option value="MO">Missouri</option>	
+				<option value="MT">Montana</option>	
+				<option value="NE">Nebraska</option>	
+				<option value="NV">Nevada</option>	
+				<option value="NH">New Hampshire</option>	
+				<option value="NJ">New Jersey</option>	
+				<option value="NM">NewMexico</option>	
+				<option value="NY">New York</option>	
+				<option value="NC">North Carolina</option>	
+				<option value="ND">North Dakota</option>	
+				<option value="OH">Ohio</option>	
+				<option value="OK">Oklahoma</option>	
+				<option value="OR">Oregon</option>	
+				<option value="PA">Pennsylvania</option>	
+				<option value="RI">RhodeIsland</option>	
+				<option value="SC">South Carolina</option>	
+				<option value="SD">South Dakota</option>	
+				<option value="TN">Tennessee</option>	
+				<option value="TX">Texas</option>	
+				<option value="UT">Utah</option>	
+				<option value="VT">Vermont</option>	
+				<option value="VA">Virginia</option>	
+				<option value="WA">Washington</option>	
+				<option value="WV">West Virginia</option>	
+				<option value="WI">Wisconsin</option>	
+				<option value="WY">Wyoming</option>	
+			</select>
+		</div>
+	</div>
+
+	@if($performer->pro->pro_type == 'ADMIN')
+	<div class="sm-section">
+		<div class="">
+			<div class="checkbox mt-4 pt-2">
+				<label class="text-nowrap font-weight-normal mr-2">
+					<input type="checkbox" name="include_test_records"  v-model="filters.include_test_records">
+					Incl. Test Records
+				</label>
+			</div>
+		</div>
+	</div>
+	@endif
+
+
+	<!-- LAST WEIGHED-IN -->
+	<!-- <div class="col-md-2 d-none">
+		<div class="">
+			<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 d-none">
+		<div class="">
+			<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="">
+			<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('admin.bdt_devices')}}')" class="btn btn-link btn-sm text-danger">Clear</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',
+	'initiative',
+	'insurance',
+	'include_test_records',
+	'number_of_measurements',
+	'number_of_measurements_value_1',
+	'number_of_measurements_value_2',
+	'home_address_state',
+	'chart_number'
+];
+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: '#bdt-devices-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					init: function() {
+
+					},
+					doSubmit: function() {
+						fastLoad('{{ route('admin.bdt_devices') }}?' + $('#bdt-devices-filters').serialize());
+						return false;
+					}
+				},
+				mounted: function() {
+					console.log(this.filters);
+					this.init();
+				},
+			});
+
+
+		}
+		addMCInitializer('bdt-devices-filters', init, '#bdt-devices-filters');
+	})();
+</script>

+ 77 - 0
resources/views/app/admin/bdt_devices_table.blade.php

@@ -0,0 +1,77 @@
+	<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">IMEI</th>
+				<th class="border-0">Issued Yet?</th>
+				<th class="border-0">Client</th>
+				<th class="border-0">MCP</th>
+				<th class="border-0">Issue Date</th>
+				<th class="border-0">Supply Order Status</th>
+				<th class="border-0">Last Meas. Date</th>
+				<th class="border-0">Last Meas. Days Ago</th>
+			</tr>
+		</thead>
+		<tbody>
+			@foreach($bdtDevices as $bdtDevice)
+			<tr>
+				<td>{{$bdtDevice->imei}}</td>
+				<td>{{$bdtDevice->clientBDTDevice ? 'Yes': 'No'}}</td>
+				<td>
+					@if($bdtDevice->clientBDTDevice)
+					<a native target="_blank" href="{{route('patients.view.dashboard',$bdtDevice->clientBDTDevice->client)}}">
+						{{$bdtDevice->clientBDTDevice->client->displayName()}}
+					</a>
+					@else 
+						-
+					@endif 
+				</td>
+				<td>
+					@if($bdtDevice->clientBDTDevice && $bdtDevice->clientBDTDevice->client && $bdtDevice->clientBDTDevice->client->mcp)
+						{{$bdtDevice->clientBDTDevice->client->mcp->name_first}} {{$bdtDevice->clientBDTDevice->client->mcp->name_last}}
+					@else 
+						-
+					@endif 
+				</td>
+				<td>
+					@if($bdtDevice->clientBDTDevice)
+						{{friendly_date_time($bdtDevice->clientBDTDevice->created_at)}}
+					@else 
+						-
+					@endif 
+				</td>
+				<td>
+					@if($bdtDevice->clientBDTDevice)
+						{{count($bdtDevice->clientBDTDevice->supplyOrders)}}
+					@else 
+						-
+					@endif 	
+				</td>
+				<td>
+					@if($bdtDevice->clientBDTDevice)
+						{{friendly_date_time($bdtDevice->clientBDTDevice->mostRecentMeasurement->measurement->ts_date_time)}}
+					@else 
+						-
+					@endif 	
+				</td>
+				<td>
+					@if($bdtDevice->clientBDTDevice)
+						{{date_diff(date_create($bdtDevice->clientBDTDevice->mostRecentMeasurement->measurement->ts_date_time), date_create('now'))->days}}
+					@else 
+						-
+					@endif 	
+				</td>
+			</tr>
+			@endforeach
+
+			@if(count($bdtDevices) === 0)
+			<tr>
+				<td colspan="24">No records found!</td>
+			</tr>
+			@endif
+		</tbody>
+
+	</table>
+</div>
+<div class="p-3">
+	{{$bdtDevices->withQueryString()->links()}}
+</div>

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

@@ -185,6 +185,7 @@
                             <a class="dropdown-item" href="{{ route('practice-management.segmentTemplates') }}">Segment Templates</a>
                             <a class="dropdown-item" href="{{ route('practice-management.visitTemplates') }}">Visit Templates</a>
                             <a class="dropdown-item" href="{{ route('admin.part_b_patients') }}">Part B Patients</a>
+                            <a class="dropdown-item" href="{{ route('admin.bdt_devices') }}">BDT Devices</a>
                         @elseif($pro->is_enrolled_as_mcp && $pro->is_considered_for_mcp_assignment)
 
                             <a class="dropdown-item" href="{{ route('practice-management.financialTransactions') }}">Financial Transactions</a>

+ 1 - 0
routes/web.php

@@ -200,6 +200,7 @@ Route::middleware('pro.auth')->group(function () {
 
         Route::get('patients', 'AdminController@patients')->name('patients');
         Route::get('part_b_patients', 'AdminController@partBPatients')->name('part_b_patients');
+        Route::get('bdt_devices', 'AdminController@bdtDevices')->name('bdt_devices');
         Route::get('notes', 'AdminController@notes')->name('notes');
         Route::get('notes-pending-summary-suggestion', 'AdminController@notes_pending_summary_suggestion')->name('notes_pending_summary_suggestion');
         Route::get('notes-rejected-summary-suggestion', 'AdminController@notes_rejected_summary_suggestion')->name('notes_rejected_summary_suggestion');