Pārlūkot izejas kodu

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

= 3 gadi atpakaļ
vecāks
revīzija
16d70d32c0

+ 153 - 0
app/Http/Controllers/AdminController.php

@@ -201,6 +201,159 @@ class AdminController extends Controller
         return view('app.admin.patients', compact('patients', 'filters'));
     }
 
+    public function partBPatients(Request $request){
+        
+        $filters = $request->all();
+        $patients = Client::whereNull('shadow_pro_id');
+
+      
+        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 . '%');
+                });
+            }
+        }
+
+        if ($request->input('mcp')) {
+            if($request->input('mcp') == 'NO_MCP'){
+                $patients = $patients->whereNull('mcp_pro_id');
+            }else{
+                $mcp = Pro::where('uid', trim($request->input('mcp')))->first();
+                if ($mcp) {
+                    $patients = $patients->where('mcp_pro_id', $mcp->id);
+                }
+            }
+        }
+
+        if ($request->input('na')) {
+            if($request->input('na') == 'NO_NA'){
+                $patients = $patients->whereNull('default_na_pro_id');
+            }else{
+                $na = Pro::where('uid', trim($request->input('na')))->first();
+                if ($na) {
+                    $patients = $patients->where('default_na_pro_id', $na->id);
+                }
+            }
+           
+        }
+
+        if ($request->input('next_appointment_category')) {
+            if($request->input('next_appointment_category') == 'NONE'){
+                $patients = $patients->whereNull('next_mcp_appointment_id');
+            }
+        }
+
+        if ($request->input('chart_number')) {
+            $patients = $patients->where('chart_number', 'ILIKE' , '%'.$request->input('chart_number').'%');
+        }
+
+        if ($request->input('home_address_state')) {
+
+            if($request->input('home_address_state') == 'NONE'){
+                $patients = $patients->whereNull('mailing_address_state');
+            }else if($request->input('home_address_state') == 'NOT_MD'){
+                $patients = $patients->where('mailing_address_state', '<>' , 'MD');
+            }else{
+                $patients = $patients->where('mailing_address_state', '=' , $request->input('home_address_state'));
+            }
+        }
+
+        $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_max', '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');
+
+        if($request->input('deductible')){
+            $keyName = $request->input('deductible');
+
+            switch($keyName) {
+                case 'EXACTLY':
+                        $patients = $patients->whereHas('latestClientPrimaryCoverage', function($q) use ($request){
+                            return $q->where('auto_medicare_mpb_deductible', '=', $request->input('deductible_value_1'));
+                        });
+                    break;
+                case 'LESS_THAN':
+                    if($request->input('deductible_value_1')) {
+                        $patients = $patients->whereHas('latestClientPrimaryCoverage', function($q) use ($request){
+                            return $q->where('auto_medicare_mpb_deductible', '<=', $request->input('deductible_value_1'));
+                        });
+                    }
+                    break;
+                case 'GREATER_THAN':
+                    if($request->input('deductible_value_1')) {
+                        $patients = $patients->whereHas('latestClientPrimaryCoverage', function($q) use ($request){
+                            return $q->where('auto_medicare_mpb_deductible', '>=', $request->input('deductible_value_1'));
+                        });
+                    }
+                    break;
+                case 'BETWEEN':
+                    $patients = $patients->whereHas('latestClientPrimaryCoverage', function($q) use ($request){
+                        return $q->where('auto_medicare_mpb_deductible', '>=', $request->input('deductible_value_1'))
+                        ->where('auto_medicare_mpb_deductible', '<=', $request->input('deductible_value_2'));
+                    });
+                    break;
+                case 'NOT_BETWEEN':
+                    if($request->input('deductible_value_1') && $request->input('deductible_value_2')) {
+                        $patients = $patients->whereHas('latestClientPrimaryCoverage', function($q) use ($request){
+
+                            return $q->where(function($qq) use ($request){
+                                return $qq->where('auto_medicare_mpb_deductible', '<', $request->input('deductible_value_1'))
+                                    ->orWhere('auto_medicare_mpb_deductible', '>', $request->input('deductible_value_2'));
+                            });
+                        });
+                    }
+                    break;
+            }
+        }
+
+        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;
+        }
+
+        $initiative = $request->input('initiative');
+        if($initiative){
+            $wildCardedInitiative = '%'.$initiative.'%';
+            $patients->where('initiative', 'ilike', $wildCardedInitiative);
+        }
+
+        $include_test_records = $request->input('include_test_records');
+        if(!$include_test_records){
+            $patients = $patients->where(function ($q) {
+                return $q->whereNull('client_engagement_status_category')
+                    ->orWhere('client_engagement_status_category', '<>', 'DUMMY');
+            });
+        }
+
+        
+        $with_claim_not_closed = $request->input('with_claim_not_closed');
+        if($with_claim_not_closed){
+            $patients = $patients->whereHas('notes', function ($q) {
+                return $q->where('is_claim_closed', false)
+                ->where('is_signed_by_hcp', true)
+                ->where('is_cancelled', false);
+            });
+        }
+
+        $patients = $patients->whereHas('latestClientPrimaryCoverage', function($cpcQuery){
+            return $cpcQuery->where('is_partbprimary', '=', 'YES');
+        });
+
+        $patients = $patients->orderBy('created_at', 'DESC')->paginate(25);
+        return view('app.admin.part_b_patients', compact('patients', 'filters'));
+    }
+
     public function notes(Request $request)
     {
         $notes = Note::paginate(5);

+ 10 - 0
app/Models/Client.php

@@ -103,6 +103,16 @@ class Client extends Model
             ->orderBy('created_at', 'desc');
     }
 
+    public function notesPendingClaimsClosed()
+    {
+        return $this->hasMany(Note::class, 'client_id', 'id')
+            ->where('is_claim_closed', false)
+            ->where('is_signed_by_hcp', true)
+            ->where('is_cancelled', false)
+            ->orderBy('effective_dateest', 'desc')
+            ->orderBy('created_at', 'desc');
+    }
+
     public function prescriptions()
     {
         return $this->hasMany(Erx::class, 'client_id', 'id')

+ 80 - 0
resources/views/app/admin/part_b_patients-table.blade.php

@@ -0,0 +1,80 @@
+
+<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">MCP</th>
+				<th class="border-0">Notes pending claims</th>
+				<th class="border-0">Deductible Remaining Amount</th>
+				<th class="border-0">Eligible Last Updated</th>
+				<th class="border-0"></th>
+			</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->mcp ?  $patient->mcp->name_first.' '.$patient->mcp->name_last : '-' }}</td>
+				<td>
+					@foreach($patient->notesPendingClaimsClosed as $note)
+						<div>
+							<a href="/patients/view/{{$note->client->uid}}/notes/view/{{$note->uid}}">
+									{{friendly_date($note->effective_dateest)}}
+							</a>
+						</div>
+					@endforeach
+				</td>
+				<td>
+					@if($patient->latestClientPrimaryCoverage)
+						{{$patient->latestClientPrimaryCoverage->auto_medicare_mpb_deductible}}
+					@else 
+						No data
+					@endif	
+				</td>
+				<td>
+					@if($patient->latestClientPrimaryCoverage)
+						{{friendly_date_time($patient->latestClientPrimaryCoverage->created_at)}}
+					@else 
+						No data
+					@endif	
+				</td>
+				<td>
+					<div moe relative>
+                        <a href="" start show class="">Refresh</a>
+
+                        <form url="/api/clientPrimaryCoverage/refreshCoverageForMedicare" class="mcp-theme-1">
+                            <input type="hidden" name="uid" value="{{$patient->latestClientPrimaryCoverage->uid}}" class="form-control input-sm" />
+                            <div class="form-group">
+                                <p>Refresh?</p>
+                            </div>
+                            <div class="form-group text-nowrap mb-0">
+                                <button class="btn btn-sm btn-primary" submit>Submt</button>
+                                <button class="btn btn-sm btn-default border" close>Close</button>
+                            </div>
+                        </form>
+                    </div>
+				</td>
+			</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>

+ 20 - 0
resources/views/app/admin/part_b_patients.blade.php

@@ -0,0 +1,20 @@
+@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
+                </strong>
+            </div>
+                <div class="p-3">
+                    @include('app.admin.part_b_patients_filters')
+                </div>
+                @include('app.admin.part_b_patients-table')
+            </div>
+        </div>
+    </div>
+@endsection

+ 262 - 0
resources/views/app/admin/part_b_patients_filters.blade.php

@@ -0,0 +1,262 @@
+<style>
+	#admin-part_b_patients-filters label {
+		font-weight: bold;
+	}
+
+	#admin-part_b_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: 10px;
+	}
+	.sm-section {
+		width: 125px !important;
+	}
+</style>
+<form id="admin-part_b_patients-filters" method="GET" action="{{ route('admin.part_b_patients') }}" 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>
+
+
+
+	<!-- 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>
+	@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>Deductible:</label>
+			<select name="deductible" class="form-control input-sm" v-model="filters.deductible">
+				<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.deductible" class="mt-2">
+				<div>
+					<input  name="deductible_value_1" v-model="filters.deductible_value_1" type="number" class="form-control input-sm" :placeholder="(filters.deductible === 'BETWEEN' || filters.deductible === 'NOT_BETWEEN') ? 'From' : 'Deductible'" />
+				</div>
+				<div v-show="filters.deductible === 'BETWEEN' || filters.deductible === 'NOT_BETWEEN'" class="mt-2">
+					<input name="deductible_value_2" v-model="filters.deductible_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>
+
+	<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="with_claim_not_closed"  v-model="filters.with_claim_not_closed">
+					With claim not closed
+				</label>
+			</div>
+		</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
+
+
+	
+	<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.part_b_patients')}}')" class="btn btn-link btn-sm text-danger">Clear</a>
+			</div>
+		</div>
+	</div>
+</form>
+
+<?php
+$loadedFilters = $filters;
+$allFilterKeys = [
+	'name',
+	
+	'status',
+	'initiative',
+	'insurance',
+	'include_test_records',
+	'with_claim_not_closed',
+	'deductible',
+	'deductible_value_1',
+	'deductible_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: '#admin-part_b_patients-filters',
+				delimiters: ['@{{', '}}'],
+				data: {
+					filters: <?= json_encode($loadedFilters) ?>
+				},
+				methods: {
+					init: function() {
+
+					},
+					doSubmit: function() {
+						fastLoad('{{ route('admin.part_b_patients') }}?' + $('#admin-part_b_patients-filters').serialize());
+						return false;
+					}
+				},
+				mounted: function() {
+					console.log(this.filters);
+					this.init();
+				},
+			});
+
+
+		}
+		addMCInitializer('admin-part_b_patients-filters', init, '#admin-part_b_patients-filters');
+	})();
+</script>

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

@@ -183,6 +183,7 @@
                             <a class="dropdown-item" href="{{ route('practice-management.memos') }}">Memos</a>
                             <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>
                         @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

@@ -199,6 +199,7 @@ Route::middleware('pro.auth')->group(function () {
         Route::get('dashboard', 'HomeController@dashboard_ADMIN')->name('dashboard');
 
         Route::get('patients', 'AdminController@patients')->name('patients');
+        Route::get('part_b_patients', 'AdminController@partBPatients')->name('part_b_patients');
         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');