Browse Source

RM context (wip)

Vijayakrishnan 3 years ago
parent
commit
fa727ef47f

+ 3 - 3
app/Http/Controllers/HomeController.php

@@ -261,7 +261,7 @@ class HomeController extends Controller
             ->count();
 
         // num measurements that need stamping
-        $keyNumbers['measurementsToBeStamped'] = count($this->performer()->pro->getMeasurements(true));
+        $keyNumbers['measurementsToBeStamped'] = $this->performer()->pro->getUnstampedMeasurements(true, null, null);
 
         // unacknowledged cancelled bills for authed pro
         $keyNumbers['unacknowledgedCancelledBills'] = Bill::where('hcp_pro_id', $performerProID)
@@ -465,7 +465,7 @@ WHERE measurement.label NOT IN ('SBP', 'DBP')
 " .
                 (
                 $performer->pro->pro_type != 'ADMIN' ? $ifNotAdmin : ''
-                )
+  )
             )
         );
 
@@ -500,7 +500,7 @@ WHERE measurement.label NOT IN ('SBP', 'DBP')
 " .
                 (
                 $performer->pro->pro_type != 'ADMIN' ? $ifNotAdmin : ''
-                )
+  )
             ) .
             " ORDER BY measurement.ts DESC LIMIT 20 OFFSET " . (($page - 1) * 20)
 

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

@@ -4,6 +4,7 @@ namespace App\Http\Controllers;
 
 use App\Models\AppSession;
 use App\Models\BillingReport;
+use App\Models\CareMonth;
 use App\Models\ClaimEDI;
 use App\Models\Handout;
 use App\Models\MBClaim;
@@ -668,6 +669,114 @@ class PracticeManagementController extends Controller
         return view('app.practice-management.billing-manager', compact('notes', 'allPros', 'expectedForHcp', 'targetPro', 'proUid', 'filters'));
     }
 
+    public function remoteMonitoring(Request $request) {
+
+        $performer = $this->performer();
+
+        $ym = ($request->input('y') ?: 'Y') . '-' . ($request->input('m') ?: 'm');
+        $careMonthStart = date($ym . '-01');
+
+        // filters
+        $filters = '';
+        $fmd = $request->input('fmd');
+        if($fmd && $fmd !== 'all') {
+            switch($fmd) {
+                case 'lt16':
+                    $filters .= ' AND care_month.number_of_days_with_remote_measurements < 16 ';
+                    break;
+                case 'gte16':
+                    $filters .= ' AND care_month.number_of_days_with_remote_measurements >= 16 ';
+                    break;
+            }
+        }
+        $fcomm = $request->input('fcomm');
+        if($fcomm && $fcomm !== 'all') {
+            switch($fcomm) {
+                case '0':
+                    $filters .= ' AND care_month.has_non_hcp_communicated_to_patient_about_rm = FALSE ';
+                    break;
+                case '1':
+                    $filters .= ' AND care_month.has_non_hcp_communicated_to_patient_about_rm = TRUE ';
+                    break;
+            }
+        }
+
+        $patients = DB::select(
+            DB::raw(
+                "
+SELECT client.name_first, client.name_last, client.uid as client_uid,
+       care_month.uid as care_month_uid,
+       care_month.id as care_month_id,
+       care_month.start_date,
+       care_month.number_of_days_with_remote_measurements,
+       care_month.has_non_hcp_communicated_to_patient_about_rm,
+       care_month.rm_num_measurements_not_stamped_by_mcp,
+       care_month.rm_num_measurements_not_stamped_by_non_hcp,
+       care_month.rm_num_measurements_not_stamped_by_rmm,
+       care_month.rm_num_measurements_not_stamped_by_rme,
+       client.mcp_pro_id,
+       client.default_na_pro_id,
+       client.rmm_pro_id,
+       client.rme_pro_id,
+       client.cell_number
+FROM care_month join client on care_month.client_id = client.id
+WHERE (
+          (client.mcp_pro_id = {$performer->pro->id})
+          OR (client.rmm_pro_id = {$performer->pro->id})
+          OR (client.rme_pro_id = {$performer->pro->id})
+          OR (client.default_na_pro_id = {$performer->pro->id})
+      )
+  AND EXTRACT(MONTH from care_month.start_date) = " . ($request->input('m') ?: 'EXTRACT(MONTH from now())') . "
+  AND EXTRACT(YEAR from care_month.start_date) = " . ($request->input('y') ?: 'EXTRACT(YEAR from now())') . "
+  {$filters}
+ORDER BY care_month.number_of_days_with_remote_measurements DESC NULLS LAST, client.name_first ASC, client.name_last ASC
+"
+            )
+        );
+
+        $timestamp = strtotime(date('Y-m-d'));
+        $daysRemaining = (int)date('t', $timestamp) - (int)date('j', $timestamp);
+
+        return view('app.practice-management.remote-monitoring', compact('patients', 'daysRemaining', 'careMonthStart'));
+    }
+
+    public function remoteMonitoringMeasurements(Request $request, CareMonth $careMonth) {
+
+        $performer = $this->performer();
+
+        date_default_timezone_set('US/Eastern');
+
+        $start = strtotime(date($careMonth->start_date));
+        $end = date_add(date_create(date($careMonth->start_date)), date_interval_create_from_date_string("1 month"))->getTimestamp();
+        $start *= 1000;
+        $end *= 1000;
+
+        $measurements = DB::select(
+            DB::raw(
+                "
+SELECT * FROM measurement RIGHT JOIN client on measurement.client_id = client.id
+WHERE
+    client.id = {$careMonth->client_id}
+    AND measurement.label IS NOT NULL  
+    AND measurement.label NOT IN ('SBP', 'DBP')
+    AND (measurement.is_cellular_zero = FALSE or measurement.is_cellular_zero IS NULL)
+    AND measurement.is_removed IS FALSE
+    AND measurement.client_bdt_measurement_id IS NOT NULL
+    AND measurement.ts >= {$start} AND measurement.ts < {$end}
+    AND (
+        (client.mcp_pro_id = {$performer->pro->id} AND measurement.has_been_stamped_by_mcp IS FALSE)
+        OR (client.rmm_pro_id = {$performer->pro->id} AND measurement.has_been_stamped_by_rmm IS FALSE)
+        OR (client.rme_pro_id = {$performer->pro->id} AND measurement.has_been_stamped_by_rme IS FALSE)
+        OR (client.default_na_pro_id = {$performer->pro->id} AND measurement.has_been_stamped_by_non_hcp IS FALSE)
+    )
+ORDER BY ts DESC
+"
+            )
+        );
+
+        return view('app.practice-management.remote-monitoring-measurements', compact('careMonth', 'measurements'));
+    }
+
     public function billMatrix(Request $request)
     {
         $bClients = [];

+ 80 - 1
app/Models/Pro.php

@@ -369,6 +369,85 @@ class Pro extends Model
         return $allowed ? $clientPrograms : FALSE;
     }
 
+    public function getUnstampedMeasurements($_countOnly, $skip, $limit)
+    {
+        $measurementsQuery = Measurement::where('is_removed', false)
+            ->join('client', 'client.id', '=', 'measurement.client_id')
+            ->whereNotNull('measurement.client_bdt_measurement_id')
+            ->whereNotNull('measurement.ts')
+            ->where('measurement.is_cellular_zero', false)
+            ->whereIn('measurement.client_id', $this->getMyClientIds())
+            ->where(function ($q) {
+                $q
+                    ->where(function ($q2) {
+                        $q2
+                            ->where('client.mcp_pro_id', $this->id)
+                            ->where('measurement.has_been_stamped_by_mcp', false);
+                    })
+                    ->orWhere(function ($q2) {
+                        $q2
+                            ->where('client.default_na_pro_id', $this->id)
+                            ->where('measurement.has_been_stamped_by_non_hcp', false);
+                    })
+                    ->orWhere(function ($q2) {
+                        $q2
+                            ->where('client.rmm_pro_id', $this->id)
+                            ->where('measurement.has_been_stamped_by_rmm', false);
+                    })
+                    ->orWhere(function ($q2) {
+                        $q2
+                            ->where('client.rme_pro_id', $this->id)
+                            ->where('measurement.has_been_stamped_by_rme', false);
+                    });
+            });
+
+        if($_countOnly) {
+            return $measurementsQuery->count();
+        }
+
+        $x = [];
+        $measurements = $measurementsQuery
+            ->orderBy('ts', 'desc')
+            ->skip($skip)
+            ->take($limit)
+            ->get();
+
+        // eager load stuff needed in JS
+        foreach ($measurements as $measurement) {
+//            if ($measurement->client_bdt_measurement_id) {
+//                $measurement->bdtMeasurement = $measurement->clientBDTMeasurement->measurement;
+//            }
+            unset($measurement->clientBDTMeasurement); // we do not need this travelling to the frontend
+
+            $client = [
+                "uid" => $measurement->client->uid,
+                "name" => $measurement->client->displayName(),
+            ];
+            $measurement->patient = $client;
+
+            $measurement->careMonth = $measurement->client->currentCareMonth();
+            $measurement->timestamp = friendlier_date_time($measurement->created_at);
+
+            unset($measurement->client); // we do not need this travelling to the frontend
+
+            if(@$measurement->detail_json) unset($measurement->detail_json);
+            if(@$measurement->canvas_data) unset($measurement->canvas_data);
+            if(@$measurement->latest_measurements) unset($measurement->latest_measurements);
+            if(@$measurement->info_lines) unset($measurement->info_lines);
+            if(@$measurement->canvas_data_backup) unset($measurement->canvas_data_backup);
+            if(@$measurement->migrated_canvas_data_backup) unset($measurement->migrated_canvas_data_backup);
+
+            // if($measurement->label == 'SBP' || $measurement->label = 'DBP'){
+            //     continue;
+            // }
+            $x[] = $measurement;
+        }
+
+        // dd($measurements);
+
+        return $measurements;
+    }
+
     public function getMeasurements($_onlyUnstamped = true)
     {
         $measurementsQuery = Measurement::where('is_removed', false);
@@ -389,7 +468,7 @@ class Pro extends Model
                         });
                 });
         }
-	$x = [];
+	    $x = [];
         $measurements = $measurementsQuery->orderBy('ts', 'desc')->paginate(50);
 
         // eager load stuff needed in JS

+ 3 - 0
public/css/style.css

@@ -1865,4 +1865,7 @@ form.non-interactive .form-content * {
     opacity: 0 !important;
     pointer-events: none;
     position: absolute;
+}
+table.dashboard-stats-table th {
+    padding: 0.5rem 0.75rem
 }

+ 32 - 8
resources/views/app/dashboard.blade.php

@@ -15,7 +15,7 @@
                         </strong>
                     </div>
                     <div class="card-body p-0">
-                        <table class="table mb-0">
+                        <table class="table mb-0 dashboard-stats-table">
                             <tbody>
                                 <tr>
                                     <th class="border-top-0 px-2 text-center">{{$keyNumbers['totalPatients']}}</th>
@@ -80,6 +80,12 @@
                                         </th>
                                     </tr>
                                 @endif
+                                <tr>
+                                    <th class="px-2 text-center">0</th>
+                                    <th class="pl-2">
+                                        <a native target="_top" href="#">RM Bills to Sign</a>
+                                    </th>
+                                </tr>
                             </tbody>
                         </table>
                     </div>
@@ -87,22 +93,40 @@
                 <div class="card mb-4">
                     <div class="card-header pl-2">
                         <strong>
-                            Remote Monitoring
+                            Remote Monitoring: {{friendly_month(date('Y-m-d'))}}
                         </strong>
                     </div>
                     <div class="card-body p-0">
-                        <table class="table mb-0">
+                        <table class="table mb-0 dashboard-stats-table">
                             <tbody>
                             <tr>
-                                <th class="px-2 text-center">{{$keyNumbers['measurementsToBeStamped']}}</th>
+                                <th class="px-2 text-center">0</th>
                                 <th class="pl-2">
-                                    <a native target="_top" href="#" v-on:click.prevent="tab='measurements'">Unstamped Measurements</a>
+                                    <a native target="_top" href="#">Patients with < 16 meas. days</a>
+                                </th>
+                            </tr>
+                            <tr>
+                                <th class="px-2 text-center">0</th>
+                                <th class="pl-2">
+                                    <a native target="_top" href="#">Patients with >= 16 meas. days</a>
                                 </th>
                             </tr>
                             <tr>
                                 <th class="px-2 text-center">0</th>
                                 <th class="pl-2">
-                                    <a native target="_top" href="#">RM Bills to Sign</a>
+                                    <a native target="_top" href="#">Patients with whom comm. not done</a>
+                                </th>
+                            </tr>
+                            <tr>
+                                <th class="px-2 text-center">0</th>
+                                <th class="pl-2">
+                                    <a native target="_top" href="#">Patients with whom comm. done</a>
+                                </th>
+                            </tr>
+                            <tr>
+                                <th class="px-2 text-center">{{$keyNumbers['measurementsToBeStamped']}}</th>
+                                <th class="pl-2">
+                                    <a native target="_top" href="#" v-on:click.prevent="tab='measurements'">Unstamped Measurements</a>
                                 </th>
                             </tr>
                             </tbody>
@@ -116,7 +140,7 @@
                         </strong>
                     </div>
                     <div class="card-body p-0">
-                        <table class="table mb-0">
+                        <table class="table mb-0 dashboard-stats-table">
                             <tbody>
                                 <tr>
                                     <th class="border-top-0 px-2">${{friendly_money($reimbursement['currentBalance'])}}</th>
@@ -152,7 +176,7 @@
                         </strong>
                     </div>
                     <div class="card-body p-0">
-                        <table class="table mb-0">
+                        <table class="table mb-0 dashboard-stats-table">
                             <tbody>
                             
                             <tr>

+ 75 - 0
resources/views/app/practice-management/remote-monitoring-measurements.blade.php

@@ -0,0 +1,75 @@
+<div class="mcp-theme-1 px-3 py-2 border-top mt-3" id="remote-monitoring-measurements-{{$careMonth->id}}">
+    <a class="btn btn-sm btn-primary text-white btn-stamp-all font-weight-bold" href="#">
+        Stamp All
+    </a>
+    <div class="mt-0 pb-1">
+        <table class="table table-striped table-sm table-bordered mt-2 mb-0">
+            <thead>
+            <tr>
+                <th class="px-2 text-secondary w-25">Date</th>
+                <th class="px-2 text-secondary w-25">Category</th>
+                <th class="px-2 text-secondary w-25">Value</th>
+                <th class="px-2 text-secondary">Actions</th>
+            </tr>
+            </thead>
+            <tbody>
+            @foreach($measurements as $measurement)
+                @if(!empty($measurement->label))
+                    @if(!in_array($measurement->label, ["SBP", "DBP"]))
+                        <tr>
+                            <td class="px-2">
+                                @if($measurement->ts)
+                                    <?php $timestampInSec = floor($measurement->ts / 1000); ?>
+                                    {{ friendly_date_time_short_with_tz_from_timestamp($timestampInSec, 'EASTERN') }}
+                                @else
+                                    {{ friendly_date_time_short_with_tz($measurement->effective_date, true, 'EASTERN') }}
+                                @endif
+                                EST
+                            </td>
+                            <td class="px-2">{{ $measurement->label }}</td>
+                            <td class="px-2">
+                                @if($measurement->label === 'BP')
+                                    {{ round($measurement->sbp_mm_hg, 2) }}/{{ round($measurement->dbp_mm_hg, 2) }} mmHg
+                                    <span class="font-weight-normal d-inline-block pl-2">Pulse:</span>
+                                    {{ $measurement->value_pulse }} {{ $measurement->value_irregular === 0?'Irregular':'' }} {{ $measurement->value_irregular === 1?'Regular':'' }}
+                                @elseif($measurement->label === 'Wt. (lbs.)')
+                                    {{ round($measurement->numeric_value, 2) }} lbs
+                                @else
+                                    {{ $measurement->value }}
+                                @endif
+                            </td>
+                            <td class="px-2">
+                                <a class="btn-stamp" href="#">
+                                    Stamp
+                                </a>
+                            </td>
+                        </tr>
+                    @endif
+                @endif
+            @endforeach
+            @if(!$measurements || count($measurements) === 0)
+                <tr>
+                    <td class="text-secondary p-0 border-0">
+                        No items to show
+                    </td>
+                </tr>
+            @endif
+            </tbody>
+        </table>
+    </div>
+</div>
+<script>
+    (function() {
+        function init() {
+            $('.stag-popup-content .stag-popup-title .btn-stamp-all').remove();
+            $('.btn-stamp-all')
+                .addClass('ml-3')
+                .insertAfter(
+                    $('#remote-monitoring-measurements-{{$careMonth->id}}')
+                        .closest('.stag-popup-content')
+                        .find('.stag-popup-title>span')
+                );
+        }
+        addMCInitializer('remote-monitoring-measurements-{{$careMonth->id}}', init, '#remote-monitoring-measurements-{{$careMonth->id}}')
+    }).call(window);
+</script>

+ 116 - 0
resources/views/app/practice-management/remote-monitoring.blade.php

@@ -0,0 +1,116 @@
+@extends ('layouts/template')
+
+@section('content')
+
+    <div class="p-3 mcp-theme-1" id="practice-billing-manager">
+
+        <div class="card">
+
+            <div class="card-header px-3 py-2 d-flex align-items-center">
+                <strong class="mr-4 font-size-14">
+                    <i class="fas fa-user-injured"></i>
+                    Remote Monitoring: {{friendly_month(date('Y-m-d'))}}
+                </strong>
+                <?php
+                $dateInput = [];
+                if(request()->input('m')) $dateInput[] = 'm=' . request()->input('m');
+                if(request()->input('y')) $dateInput[] = 'y=' . request()->input('y');
+                $dateInput = '&' . implode('&', $dateInput);
+                ?>
+                <select class="ml-auto max-width-200px form-control form-control-sm"
+                        onchange="fastLoad('/practice-management/remote-monitoring?fmd=' + this.value + '&fcomm={{request()->input('fcomm')}}{{$dateInput}}', true, false, false)">
+                    <option value="all" {{ !request()->input('fmd') || request()->input('fmd') === 'all' ? 'selected' : '' }}>All</option>
+                    <option value="lt16" {{ request()->input('fmd') === 'lt16' ? 'selected' : '' }}>Patients with &lt; 16 meas. days</option>
+                    <option value="gte16" {{ request()->input('fmd') === 'gte16' ? 'selected' : '' }}>Patients with &ge; 16 meas. days</option>
+                </select>
+                <select class="ml-3 max-width-200px form-control form-control-sm"
+                        onchange="fastLoad('/practice-management/remote-monitoring?fmd={{request()->input('fmd')}}&fcomm=' + this.value + '{{$dateInput}}', true, false, false)">
+                    <option value="all" {{ !request()->input('fcomm') || request()->input('fcomm') === 'all' ? 'selected' : '' }}>All</option>
+                    <option value="0" {{ request()->input('fcomm') === '0' ? 'selected' : '' }}>Patients with whom comm. not done</option>
+                    <option value="1" {{ request()->input('fcomm') === '1' ? 'selected' : '' }}>Patients with whom comm. done</option>
+                </select>
+            </div>
+            <div class="card-body p-0">
+                <table class="table table-sm table-condensed p-0 m-0">
+                    <thead class="bg-light">
+                    <tr>
+                        <th class="border-0">Patient</th>
+                        <th class="border-0">Relation</th>
+                        <th class="border-0">Measurement Days</th>
+                        <th class="border-0">Unstamped Measurements</th>
+                        @if(!$pro->is_hcp)
+                            <th class="border-0">Communicated With Patient</th>
+                        @endif
+                        <th class="border-0">Phone</th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    @foreach ($patients as $iPatient)
+                        <tr>
+                            <td class="">
+                                <a href="/patients/view/{{ $iPatient->client_uid }}">{{ $iPatient->name_first }} {{ $iPatient->name_last }}</a>
+                            </td>
+                            <td class="">
+                                @if($iPatient->mcp_pro_id === $pro->id)
+                                    <div>MCP</div>
+                                @endif
+                                @if($iPatient->default_na_pro_id === $pro->id)
+                                    <div>Default NA</div>
+                                @endif
+                                @if($iPatient->rmm_pro_id === $pro->id)
+                                    <div>RMM</div>
+                                @endif
+                                @if($iPatient->rme_pro_id === $pro->id)
+                                    <div>RME</div>
+                                @endif
+                            </td>
+                            <td class="">
+                                <span class="d-inline-block width-30px">{{$iPatient->number_of_days_with_remote_measurements ?: '0'}}</span>
+                                <span class="">
+                                <?php $moreMDNeeded = 16 - $iPatient->number_of_days_with_remote_measurements; ?>
+                                @if($iPatient->number_of_days_with_remote_measurements >= 16)
+                                    <i class="fa fa-check text-success" title="16 measurement days reached"></i>
+                                @elseif($daysRemaining >= $moreMDNeeded)
+                                    <i class="fa fa-exclamation-triangle text-warning-mellow" title="{{$moreMDNeeded}} more measurement day{{$moreMDNeeded > 1 ? 's' : ''}} needed"></i>
+                                @elseif($daysRemaining < $moreMDNeeded)
+                                    <i class="fa fa-exclamation-triangle text-secondary opacity-60" title="Can no longer reach 16 measurement days this month"></i>
+                                @endif
+                                </span>
+                            </td>
+                            <td class="">
+                                <?php $numUS = 0; ?>
+                                @if($iPatient->mcp_pro_id === $pro->id)
+                                    <?php $numUS = $iPatient->rm_num_measurements_not_stamped_by_mcp; ?>
+                                @elseif($iPatient->default_na_pro_id === $pro->id)
+                                    <?php $numUS = $iPatient->rm_num_measurements_not_stamped_by_non_hcp; ?>
+                                @elseif($iPatient->rmm_pro_id === $pro->id)
+                                    <?php $numUS = $iPatient->rm_num_measurements_not_stamped_by_rmm; ?>
+                                @elseif($iPatient->rme_pro_id === $pro->id)
+                                    <?php $numUS = $iPatient->rm_num_measurements_not_stamped_by_rme; ?>
+                                @endif
+                                <span class="d-inline-block width-30px">{{$numUS}}</span>
+                                @if($numUS)
+                                    <a native target="_blank"
+                                       open-in-stag-popup
+                                       update-parent
+                                       mc-initer="remote-monitoring-measurements-{{$iPatient->care_month_id}}"
+                                       title="{{ $iPatient->name_first }} {{ $iPatient->name_last }} / Unstamped Measurements / {{ friendly_month($careMonthStart) }}"
+                                       href="/remote-monitoring-measurements/{{$iPatient->care_month_uid}}">View</a>
+                                @endif
+                            </td>
+                            @if(!$pro->is_hcp)
+                                <td class="">
+                                    {{$iPatient->has_non_hcp_communicated_to_patient_about_rm ? 'Yes' : 'No'}}
+                                </td>
+                            @endif
+                            <td class="">
+                                {{$iPatient->cell_number}}
+                            </td>
+                        </tr>
+                    @endforeach
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    </div>
+@endsection

+ 5 - 0
routes/web.php

@@ -148,6 +148,9 @@ Route::middleware('pro.auth')->group(function () {
 
         Route::get('supply-orders/cancelled-but-unacknowledged', 'PracticeManagementController@supplyOrdersCancelledButUnacknowledged')->name('supply-orders-cancelled-but-unacknowledged');
         Route::get('supply-orders/unsigned', 'PracticeManagementController@supplyOrdersUnsigned')->name('supply-orders-unsigned');
+
+        Route::get('remote-monitoring', 'PracticeManagementController@remoteMonitoring')->name('remote-monitoring');
+
     });
 
     Route::middleware('pro.auth.admin')->group(function(){
@@ -312,6 +315,8 @@ Route::middleware('pro.auth')->group(function () {
     Route::get("/log_in_as", 'HomeController@logInAs')->name('log-in-as');
     Route::post("/process-log_in_as", 'HomeController@processLogInAs')->name('process-log-in-as');
     Route::post("/back_to_admin_pro", 'HomeController@backToAdminPro')->name('back-to-admin-pro');
+
+    Route::get('/remote-monitoring-measurements/{careMonth}', 'PracticeManagementController@remoteMonitoringMeasurements')->name('remote-monitoring-measurements');
 });
 
 Route::post("/process_form_submit", 'NoteController@processFormSubmit')->name('process_form_submit');