瀏覽代碼

Process claims [wip]

Vijayakrishnan 4 年之前
父節點
當前提交
3f8b20af3d

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

@@ -6,6 +6,7 @@ use App\Models\AppSession;
 use App\Models\BillingReport;
 use App\Models\ClaimEDI;
 use App\Models\Handout;
+use App\Models\MBClaim;
 use App\Models\Measurement;
 use App\Models\Bill;
 use App\Models\Claim;
@@ -1026,6 +1027,41 @@ class PracticeManagementController extends Controller
         return  view('app.practice-management.claims', compact('claims', 'status'));
     }
 
+    public function processClaims(Request  $request) {
+        $status = '';
+
+        $claims = DB::select(DB::raw("
+SELECT claim.uid as uid,
+       DATE(claim.created_at) as created,
+       claim.status,
+       client.uid as client_uid,
+       (client.name_last || ' ' || client.name_first) as client ,
+       client.chart_number as client_chart_number,
+       (pro.name_last || ' ' || pro.name_first) as pro,
+       (SELECT string_agg(claim_line.cpt, ', ') FROM claim_line where claim_id = claim.id) as cpts,
+       (SELECT count(claim_line_icd.id) FROM claim_line_icd where claim_line_id IN (SELECT id FROM claim_line WHERE claim_id = claim.id)) as icds,
+       ROUND(claim.expected_total, 2) as expected_total
+FROM claim
+    join client on claim.client_id = client.id
+    join pro on claim.pro_id = pro.id
+--WHERE claim.status IS NULL OR claim.status = 'NEW'
+ORDER BY claim.created_at ASC
+--OFFSET 0 LIMIT 15
+"));
+
+        return  view('app.practice-management.process-claims', compact('claims', 'status'));
+    }
+
+    public function currentMbClaim(Request $request, $claimUid) {
+        $claim = Claim::where('uid', $claimUid)->first();
+        return json_encode(MBClaim::where('claim_version_id', $claim->currentVersion->id)->first());
+    }
+
+    public function currentClaimLines(Request $request, $claimUid) {
+        $claim = Claim::where('uid', $claimUid)->first();
+        return  view('app.practice-management._claim-lines', compact('claim'));
+    }
+
     public function packsMultiPrint(Request $request) {
         $packs = Pack
             ::select('pack.*')

+ 30 - 0
resources/views/app/practice-management/_claim-lines.blade.php

@@ -0,0 +1,30 @@
+<table class="table table-sm table-condensed mb-0 table-bordered">
+    <thead>
+    <tr class="bg-light">
+        <th class="border-0 width-100px">CPT</th>
+        <th class="border-0 width-100px">DOS</th>
+        <th class="border-0 text-nowrap">ICDs</th>
+    </tr>
+    </thead>
+    <tbody>
+    @foreach($claim->lines as $line)
+        <tr class="claim-line">
+            <td class="width-100px">{{$line->cpt}}
+                @if($line->numberOfUnits)
+                    <div>Units: <b>{{$line->numberOfUnits}}</b></div>
+                @endif
+            </td>
+            <td class="text-nowrap width-100px">{{friendlier_date($line->date_of_service)}}</td>
+            <td class="text-nowrap">
+                @if(count($line->claimLineIcds))
+                    @foreach($line->claimLineIcds as $icd)
+                        <span class="c-pointer border-secondary border-bottom mr-2" title="{{$icd->description}}">{{$icd->code}}</span>
+                    @endforeach
+                @else
+                    <p>No ICDs set</p>
+                @endif
+            </td>
+        </tr>
+    @endforeach
+    </tbody>
+</table>

+ 268 - 0
resources/views/app/practice-management/process-claims.blade.php

@@ -0,0 +1,268 @@
+@extends ('layouts/template')
+
+@section('content')
+    <div id="process-claims" class="px-3 mcp-theme-1 mt-3" v-cloak>
+        <div class="row">
+            <div class="col-9">
+                <div class="font-weight-bold py-3 font-size-16 text-secondary">
+                    <i class="fa fa-asterisk mr-2"></i>To Do
+                </div>
+                <div v-for="(claim, claimIndex) in claims" v-if="!claim.status || claim.status === 'NEW' || claim.status === 'PICKED_UP'">
+                    <div class="border rounded mb-3 border rounded mb-3 overflow-hidden"
+                         :class="currentClaim && currentClaim.uid === claim.uid ? 'border-info bg-white' : (claim.status === 'PICKED_UP' ? 'border-warning' : 'bg-light text-secondary')"
+                         v-on:click.prevent="setCurrentClaim(claimIndex)">
+                        <div class="d-flex align-items-center c-pointer">
+
+                            <b class="p-2 border-right mr-2 bg-aliceblue" :class="claim.status === 'PICKED_UP' ? 'text-dark' : 'text-secondary'">@{{ claim.created }}</b>
+
+                            <span class="text-secondary text-sm mr-1">Patient</span>
+                            <span>@{{ claim.client }}</span>
+
+                            <span class="mx-2 text-secondary">/</span>
+                            <span class="text-secondary text-sm mr-1">Pro</span>
+                            <span>@{{ claim.pro }}</span>
+
+                            <span class="mx-2 text-secondary">/</span>
+                            <span class="text-secondary text-sm mr-1">CPT</span>
+                            <span>@{{ claim.cpts }}</span>
+
+                            <span class="mx-2 text-secondary">/</span>
+                            <span>@{{ claim.icds }} ICDs</span>
+
+                            <span class="mx-2 text-secondary">/</span>
+                            <div class="d-inline-flex align-items-center font-weight-bold text-secondary">
+                                <span class="text-sm mr-1">$</span>
+                                <span>@{{ claim.expected_total ? claim.expected_total : 0 }}</span>
+                            </div>
+                            <div class="ml-auto px-2" v-if="currentClaim && currentClaim.uid === claim.uid">
+                                <button v-if="claim.status !== 'PICKED_UP'"
+                                        v-on:click.prevent="updateClaimStatus(claimIndex, 'PICKED_UP')"
+                                        class="btn btn-sm btn-info py-1 text-sm font-weight-bold">Pick Up</button>
+                                <button v-if="claim.status === 'PICKED_UP'"
+                                        v-on:click.prevent="updateClaimStatus(claimIndex, 'NEW')"
+                                        class="btn btn-sm btn-warning py-1 text-sm font-weight-bold">
+                                    <i class="fa fa-undo"></i>
+                                    Put Back
+                                </button>
+                                <button v-if="claim.status === 'PICKED_UP'"
+                                        v-on:click.prevent="updateClaimStatus(claimIndex, 'SUBMITTED')"
+                                        class="btn btn-sm btn-success py-1 text-sm font-weight-bold">
+                                    <i class="fa fa-arrow-right"></i>
+                                    Mark Done
+                                </button>
+                            </div>
+                        </div>
+                        <div class="border-top" v-if="currentClaim && currentClaim.uid === claim.uid">
+                            <div v-if="!currentMBClaim" class="p-2 text-secondary text-sm">Please wait ...</div>
+                            <div v-else>
+
+                                <div class="p-2">
+
+                                    <!--payer-->
+                                    <div class="d-flex align-items-center mb-1">
+                                        <div class="text-secondary mr-3 min-width-140px">Payer</div>
+                                        <b class="text-secondary">@{{ currentMBClaim.payer_name }}</b>
+                                    </div>
+
+                                    <hr class="my-2">
+
+                                    <!--patient/subscriber-->
+                                    <div class="d-flex align-items-center mb-1">
+                                        <div class="text-secondary mr-3 min-width-140px">Subscriber</div>
+                                        <b class="text-secondary">@{{ claim.client }}</b>
+                                        <span class="mx-1 text-secondary text-sm">/</span>
+                                        <span class="">@{{ currentMBClaim.subscriber_dob }}</span>
+                                        <span class="mx-1 text-secondary text-sm">/</span>
+                                        <span class="">@{{ currentMBClaim.subscriber_gender }}</span>
+                                    </div>
+                                    <div class="mb-2 pl-3">
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">Chart #</span>
+                                            @{{ claim.client_chart_number }}
+                                        </div>
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">MCN</span>
+                                            @{{ currentMBClaim.subscriber_identifier }}
+                                        </div>
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">Address</span>
+                                            @{{ currentMBClaim.subscriber_address_street_line1 }}
+                                            @{{ currentMBClaim.subscriber_address_street_line2 }}
+                                            @{{ currentMBClaim.subscriber_address_city }}
+                                            @{{ currentMBClaim.subscriber_address_state }}
+                                            @{{ currentMBClaim.subscriber_address_zip }}
+                                        </div>
+                                    </div>
+
+                                    <hr class="my-2">
+
+                                    <!--billing provider-->
+                                    <div class="d-flex align-items-center mb-1">
+                                        <div class="text-secondary mr-3 min-width-140px">Billing Provider</div>
+                                        <b class="text-secondary">@{{ currentMBClaim.billing_provider_entity }}</b>
+                                    </div>
+                                    <div class="mb-2 pl-3">
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">NPI</span>
+                                            @{{ currentMBClaim.billing_provider_npi }}
+                                        </div>
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">Tax ID / Type</span>
+                                            @{{ currentMBClaim.billing_provider_tax_id }}
+                                            /
+                                            @{{ currentMBClaim.billing_provider_tax_id_type }}
+                                        </div>
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">Taxonomy Code</span>
+                                            @{{ currentMBClaim.billing_provider_taxonomy_code }}
+                                        </div>
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">Address</span>
+                                            @{{ currentMBClaim.billing_provider_address_street_line1 }}
+                                            @{{ currentMBClaim.billing_provider_address_street_line2 }}
+                                            @{{ currentMBClaim.billing_provider_address_city }}
+                                            @{{ currentMBClaim.billing_provider_address_state }}
+                                            @{{ currentMBClaim.billing_provider_address_zip }}
+                                        </div>
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">MCN</span>
+                                            @{{ currentMBClaim.subscriber_identifier }}
+                                        </div>
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">Address</span>
+                                            @{{ currentMBClaim.subscriber_address_street_line1 }}
+                                            @{{ currentMBClaim.subscriber_address_street_line2 }}
+                                            @{{ currentMBClaim.subscriber_address_city }}
+                                            @{{ currentMBClaim.subscriber_address_state }}
+                                            @{{ currentMBClaim.subscriber_address_zip }}
+                                        </div>
+                                    </div>
+
+                                    <hr class="my-2">
+
+                                    <!--attending provider-->
+                                    <div class="d-flex align-items-center mb-1">
+                                        <div class="text-secondary mr-3 min-width-140px">Attending Provider</div>
+                                        <b class="text-secondary">@{{ currentMBClaim.attending_provider_first_name }} @{{ currentMBClaim.attending_provider_last_name }}</b>
+                                    </div>
+                                    <div class="mb-2 pl-3">
+                                        <div class="d-flex align-items-center">
+                                            <span class="text-secondary text-sm min-width-140px text-right pr-3">NPI</span>
+                                            @{{ currentMBClaim.attending_provider_npi }}
+                                        </div>
+                                    </div>
+
+                                    <hr class="my-2">
+
+                                    <!--cpt, doc, icd-->
+                                    <div class="d-flex align-items-start mb-1">
+                                        <div class="text-secondary mr-3 min-width-140px">CPT Codes</div>
+                                        <div v-html="currentClaimLines"></div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="col-3 border-left">
+                <div class="font-weight-bold py-3 font-size-16 text-success">
+                    <i class="fa fa-check mr-2"></i>Done
+                </div>
+                <div v-for="(claim, claimIndex) in claims" v-if="claim.status && claim.status !== 'NEW' && claim.status !== 'PICKED_UP'">
+                    <div class="border rounded mb-3 border rounded mb-3 overflow-hidden text-secondary">
+                        <div class="d-flex align-items-center c-pointer">
+
+                            <span class="text-secondary text-sm pl-2 py-2 font-weight-bold">@{{ claim.created }}</span>
+                            <span class="mx-1 text-secondary text-sm">/</span>
+                            <span class="text-sm">@{{ claim.client }}</span>
+                            <span class="mx-1 text-secondary text-sm">/</span>
+
+                            <div class="d-inline-flex align-items-center text-sm text-secondary">
+                                <span class="mr-1">$</span>
+                                <span>@{{ claim.expected_total ? claim.expected_total : 0 }}</span>
+                            </div>
+
+                            <div class="ml-auto px-2">
+                                <a href="#" v-on:click.prevent="updateClaimStatus(claimIndex, 'NEW')"
+                                        class="py-1 text-sm font-weight-bold">
+                                    <i class="fa fa-undo"></i>
+                                </a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <script>
+        (function() {
+            function init() {
+
+                window.processClaimsApp = new Vue({
+                    el: '#process-claims',
+                    delimiters: ['@{{', '}}'],
+                    data: {
+                        claims: {!! json_encode($claims) !!},
+                        currentClaim: null,
+                        currentMBClaim: null,
+                        currentClaimLines: null,
+                    },
+                    methods: {
+                        hasError: function (_data) {
+                            let msg = 'Unknown error!';
+                            if (_data) {
+                                if (_data.success) return false;
+                                else if (_data.message) msg = _data.message;
+                            }
+                            toastr.error(msg);
+                            return true;
+                        },
+                        setCurrentClaim: function(_index) {
+                            let claim = this.claims[_index];
+                            if(this.currentClaim && this.currentClaim.uid === claim.uid) return;
+                            this.currentMBClaim = null;
+                            this.currentClaimLines = null;
+                            $.get('/claims/current-mb-claim/' + claim.uid, (_data) => {
+                                this.currentMBClaim = _data;
+                                this.currentClaim = this.claims[_index];
+                                $.get('/claims/current-claim-lines/' + claim.uid, (_data) => {
+                                    this.currentClaimLines = _data;
+                                });
+                                console.log('ALIX', this.currentMBClaim);
+                            }, 'json');
+                        },
+                        updateClaimStatus: function(_index, _status) {
+                            let claim = this.claims[_index];
+                            $.post('/api/claim/updateStatus', {
+                                uid: claim.uid,
+                                status: _status,
+                            }, (_data) => {
+                                if(!this.hasError(_data)) {
+                                    claim.status = _status;
+                                    this.claims.splice(_index, 1, claim);
+                                    this.resetCurrentClaim();
+                                }
+                            }, 'json');
+                        },
+                        resetCurrentClaim: function() {
+                            if(this.claims && this.claims.length) {
+                                for (let i = 0; i < this.claims.length; i++) {
+                                    if (!this.claims[i].status || this.claims[i].status === 'NEW' || this.claims[i].status === 'PICKED_UP') {
+                                        this.setCurrentClaim(i);
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    mounted: function() {
+                        this.resetCurrentClaim();
+                    }
+                })
+
+            }
+            addMCInitializer('process-claims', init, '#process-claims');
+        }).call(window);
+    </script>
+@endsection

+ 5 - 0
routes/web.php

@@ -117,6 +117,7 @@ Route::middleware('pro.auth')->group(function () {
             Route::get('treatment-service-util', 'PracticeManagementController@treatmentServiceUtil')->name('treatmentServiceUtil');
 
             Route::get('claims', 'PracticeManagementController@claims')->name('claims');
+            Route::get('process-claims', 'PracticeManagementController@processClaims')->name('process-claims');
 
             // old supply-orders & shipments matrices
             // Route::get('supply-orders', 'PracticeManagementController@supplyOrders')->name('supply-orders');
@@ -233,6 +234,10 @@ Route::middleware('pro.auth')->group(function () {
     //mb claim single view
     Route::get('mb-claims/view/{mbClaim}', 'PatientController@mbClaim')->name('mb-claim');
 
+    // AJAX - used by process-claims
+    Route::get('claims/current-mb-claim/{claimUid}', 'PracticeManagementController@currentMbClaim')->name('current-mb-claim');
+    Route::get('claims/current-claim-lines/{claimUid}', 'PracticeManagementController@currentClaimLines')->name('current-claim-lines');
+
     // pro dashboard events (ajax)
     Route::get('pro-dashboard-event-dates/{from}/{to}', 'HomeController@dashboardAppointmentDates')->name('pro-dashboard-event-dates');
     Route::get('pro-dashboard-events/{from}/{to}', 'HomeController@dashboardAppointments')->name('pro-dashboard-events');