Browse Source

Admin > Accounting Items (wip)

Vijayakrishnan Krishnan 2 days ago
parent
commit
80de3e7bf0

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

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Models\AccountingItem;
 use App\Models\AppSetting;
 use App\Models\Claim;
 use App\Models\Lead;
@@ -949,4 +950,137 @@ class AdminController extends Controller
             "data" => null
         ]);
     }
+
+    public function accountingItems(Request $request) {
+
+        if($request->input('_ql')) DB::enableQueryLog();
+
+        $columns = [
+            'ai.id',
+            'ai.uid',
+            'ai.entity_type',
+            'ai.entity_id',
+            'ai.entity_uid',
+            'ai.pro_id',
+            'ai.client_id',
+            'ai.note_id',
+            'ai.care_month_id',
+            'ai.bill_id',
+            'ai.supply_order_id',
+            'ai.positive_or_negative',
+            'ai.memo',
+            'ai.expected_value',
+            'ai.received_value',
+            'ai.created_at',
+            'ai.last_updated_at',
+            'ai.is_open',
+            'ai.is_active',
+            'cl.uid as client_uid',
+            'cl.name_first as client_name_first',
+            'cl.name_last as client_name_last',
+            'p.uid as pro_uid',
+            'p.name_first as pro_name_first',
+            'p.name_last as pro_name_last',
+            'n.uid as note_uid',
+            'cm.uid as care_month_uid',
+            'o.uid as supply_order_uid',
+            'b.uid as bill_uid',
+        ];
+
+        $tables = [
+            'accounting_item ai',
+            'LEFT JOIN client cl ON cl.id = ai.client_id',
+            'LEFT JOIN pro p ON p.id = ai.pro_id',
+            'LEFT JOIN note n ON n.id = ai.note_id',
+            'LEFT JOIN supply_order o ON o.id = ai.supply_order_id',
+            'LEFT JOIN care_month cm ON cm.id = ai.care_month_id',
+            'LEFT JOIN bill b ON b.id = ai.bill_id',
+        ];
+
+        $conditions = ["ai.id > 0"];
+        $params = [];
+
+        if($request->input('type') == 'revenue')
+            $conditions[] = 'ai.positive_or_negative = 0';
+        elseif($request->input('type') == 'cost')
+            $conditions[] = 'ai.positive_or_negative = 1';
+
+        if($request->input('context')) {
+            $conditions[] = 'ai.entity_type = :context';
+            $params['context'] = $request->input('context');
+        }
+
+        if($request->input('open') == 'open')
+            $conditions[] = 'ai.is_open IS TRUE';
+        elseif($request->input('open') == 'closed')
+            $conditions[] = 'ai.is_open IS FALSE';
+
+        if($request->input('active') == 'active')
+            $conditions[] = 'ai.is_active IS TRUE';
+        elseif($request->input('active') == 'inactive')
+            $conditions[] = 'ai.is_active IS FALSE';
+
+        // execute
+        $columns = implode(",\n", $columns);
+        $tables = implode("\n", $tables);
+        $conditions = implode(" AND\n", $conditions);
+
+        $pagination = "";
+        if($request->input('paginate')) {
+            $page = $request->get('page', 1);
+            $size = $request->get('size', 25);
+            $pagination = "OFFSET ".(($page - 1) * $size) . " LIMIT $size";
+        }
+
+        $countSql = "SELECT count(ai.id) as count FROM $tables WHERE $conditions";
+        $countResult = DB::select($countSql, $params);
+
+        $dataSql = "SELECT 
+                $columns 
+            FROM 
+                $tables 
+            WHERE 
+                $conditions 
+            ORDER BY 
+                ai.created_at DESC
+            $pagination";
+        $dataResult = DB::select($dataSql, $params);
+
+        $revenueTotalSql = "SELECT 
+                SUM(COALESCE(ai.expected_value, 0)) as total_expected_value, SUM(COALESCE(ai.received_value, 0)) as total_received_value
+            FROM
+                $tables
+            WHERE
+                $conditions AND ai.positive_or_negative = 0";
+        $revenueTotalResult = DB::select($revenueTotalSql, $params);
+
+        $costTotalSql = "SELECT 
+                SUM(COALESCE(ai.expected_value, 0)) as total_expected_value, SUM(COALESCE(ai.received_value, 0)) as total_received_value
+            FROM
+                $tables
+            WHERE
+                $conditions AND ai.positive_or_negative = 1";
+        $costTotalResult = DB::select($costTotalSql, $params);
+
+        $expectedTotal = $revenueTotalResult[0]->total_expected_value - $costTotalResult[0]->total_expected_value;
+        $receivedTotal = $revenueTotalResult[0]->total_received_value - $costTotalResult[0]->total_received_value;
+
+        $paginator = null;
+        if($request->input('paginate')) {
+            $paginator = new LengthAwarePaginator($dataResult, $countResult[0]->count, $size, $page);
+            $paginator->setPath(route('accounting-items'));
+        }
+
+        $html = view('app.admin.accounting-items', [
+            'total' => $countResult[0]->count,
+            'records' => $dataResult,
+            'paginator' => $paginator,
+            'expected_total' => $expectedTotal,
+            'received_total' => $receivedTotal,
+        ]);
+
+        if($request->input('_ql')) printQueryLog(DB::getQueryLog());
+
+        return $html;
+    }
 }

+ 14 - 1
app/Models/AccountingItem.php

@@ -13,7 +13,20 @@ class AccountingItem extends Model
     }
 
     public function pro() {
-        return $this->hasOne(Account::class, 'id', 'pro_id');
+        return $this->hasOne(Pro::class, 'id', 'pro_id');
+    }
+
+    public function note() {
+        return $this->hasOne(Note::class, 'id', 'note_id');
+    }
+    public function careMonth() {
+        return $this->hasOne(CareMonth::class, 'id', 'care_month_id');
+    }
+    public function bill() {
+        return $this->hasOne(Bill::class, 'id', 'bill_id');
+    }
+    public function supplyOrder() {
+        return $this->hasOne(SupplyOrder::class, 'id', 'supply_order_id');
     }
 
 }

+ 230 - 0
resources/views/app/admin/accounting-items.blade.php

@@ -0,0 +1,230 @@
+@extends ('layouts/template')
+
+@section('content')
+    <?php
+    function selectIf($_cond) {
+        return $_cond ? 'selected' : '';
+    }
+    if(request()->input('_ql')) \Illuminate\Support\Facades\DB::enableQueryLog();
+    ?>
+    <style>
+        .posneg {
+            width: 10px;
+            display: inline-block;
+            text-align: center;
+            font-size: 12px !important;
+            font-weight: bold;
+        }
+    </style>
+    <div class="p-3 mcp-theme-1" id="accounting-items-container">
+        <div class="card">
+
+            <div class="card-header px-2 py-2 d-flex align-items-center">
+                <strong class="mr-4 font-size-14">
+                    <i class="fas fa-user"></i>
+                    Accounting Items
+                </strong>
+            </div>
+            <div class="card-body px-2 py-3 d-flex align-items-center">
+                <form action="" id="accounting-items-filter-form" class="d-flex align-items-center">
+                    <div class="d-inline-flex align-items-baseline mr-3">
+                        <span class="text-secondary mr-2">Type</span>
+                        <select name="type" class="form-control form-control-sm max-width-110px min-width-unset">
+                            <option value="" {{ selectIf(!request()->input('type')) }}>All</option>
+                            <option value="revenue" {{ selectIf(request()->input('type') == 'revenue') }}>Revenue (+)</option>
+                            <option value="cost" {{ selectIf(request()->input('type') == 'cost') }}>Cost (-)</option>
+                        </select>
+                    </div>
+                    <div class="d-inline-flex align-items-baseline mr-3">
+                        <span class="text-secondary mr-2">Context</span>
+                        <select name="context" class="form-control form-control-sm max-width-110px min-width-unset">
+                            <option value="" {{ selectIf(!request()->input('context')) }}>All</option>
+                            <option value="Note" {{ selectIf(request()->input('context') == 'Note') }}>Note</option>
+                            <option value="CareMonth" {{ selectIf(request()->input('context') == 'CareMonth') }}>CareMonth</option>
+                            <option value="Bill" {{ selectIf(request()->input('context') == 'Bill') }}>Bill</option>
+                            <option value="SupplyOrder" {{ selectIf(request()->input('context') == 'SupplyOrder') }}>SupplyOrder</option>
+                        </select>
+                    </div>
+                    <div class="d-inline-flex align-items-baseline mr-3">
+                        <span class="text-secondary mr-2">Open</span>
+                        <select name="open" class="form-control form-control-sm max-width-110px min-width-unset">
+                            <option value="" {{ selectIf(!request()->input('open')) }}>All</option>
+                            <option value="open" {{ selectIf(request()->input('open') == 'open') }}>Open</option>
+                            <option value="closed" {{ selectIf(request()->input('open') == 'closed') }}>Closed</option>
+                        </select>
+                    </div>
+                    <div class="d-inline-flex align-items-baseline mr-3">
+                        <span class="text-secondary mr-2">Active</span>
+                        <select name="active" class="form-control form-control-sm max-width-110px min-width-unset">
+                            <option value="" {{ selectIf(!request()->input('active')) }}>All</option>
+                            <option value="active" {{ selectIf(request()->input('active') == 'active') }}>Active</option>
+                            <option value="inactive" {{ selectIf(request()->input('active') == 'inactive') }}>Inactive</option>
+                        </select>
+                    </div>
+                    <label class="d-inline-flex align-items-center mr-3 mb-0">
+                        <input type="checkbox" name="paginate" class="mr-1" {{request()->input('paginate') ? 'checked' : ''}}>
+                        <span>Paginate</span>
+                    </label>
+                </form>
+            </div>
+            <div class="card-body p-0">
+                <table class="table table-sm table-striped border-0 mb-0">
+                    <thead class="bg-light">
+                    <tr>
+                        <th class="border-bottom-0 width-200px">Created</th>
+                        <th class="border-bottom-0">Type</th>
+                        <th class="border-bottom-0">Context</th>
+                        <th class="border-bottom-0">Pro</th>
+                        <th class="border-bottom-0">Client</th>
+                        <th class="border-bottom-0 width-60px text-right">Expected</th>
+                        <th class="border-bottom-0 width-60px text-right">Actual</th>
+                        <th class="border-bottom-0 text-center">Open</th>
+                        <th class="border-bottom-0">Memo</th>
+                        <th class="border-bottom-0">Active</th>
+                        <th class="border-bottom-0 width-200px">Updated</th>
+                        <th class="border-bottom-0">&nbsp;</th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    @foreach($records as $record)
+                        <tr>
+                            <td class="">
+                                {{friendly_date_time($record->created_at)}}
+                            </td>
+                            <td class="">
+                                {{$record->positive_or_negative == 0 ? 'Revenue' : 'Cost'}}
+                            </td>
+                            <td class="">
+                                @switch($record->entity_type)
+                                    @case('Note')
+                                        <a href="{{route('patients.view.notes.view.dashboard', ['patient' => $record->client_uid, 'note' => $record->note_uid])}}">Note</a>
+                                        @break
+
+                                    @case('CareMonth')
+                                        <a href="{{route('patients.view.care-months.view.dashboard', ['patient' => $record->client_uid, 'careMonth' => $record->care_month_uid])}}">Care Month</a>
+                                        @break
+
+                                    @case('SupplyOrder')
+                                        <a href="{{route('patients.view.supply-orders', ['patient' => $record->client_uid, 'supplyOrder' => $record->supply_order_uid])}}">Supply Order</a>
+                                        @break
+
+                                    @default
+                                        {{$record->entity_type}}
+                                @endswitch
+                            </td>
+                            <td class="border-bottom-0">
+                                {{implode(', ', [$record->pro_name_last, $record->pro_name_first])}}
+                            </td>
+                            <td class="border-bottom-0">
+                                @if($record->client_uid)
+                                    <a native target="_blank" href="{{route('patients.view.dashboard', $record->client_uid)}}">
+                                        {{implode(', ', [$record->client_name_last, $record->client_name_first])}}
+                                    </a>
+                                @endif
+                            </td>
+                            <td class="border-bottom-0 width-60px text-right">
+                                @if($record->expected_value)
+                                    <span class="posneg">{{$record->positive_or_negative == 0 ? '+' : '-'}}</span>
+                                    {{'$' . $record->expected_value}}
+                                @endif
+                            </td>
+                            <td class="border-bottom-0 width-60px text-right">
+                                @if($record->received_value)
+                                    <span class="posneg">{{$record->positive_or_negative == 0 ? '+' : '-'}}</span>
+                                    {{'$' . $record->received_value}}
+                                @endif
+                            </td>
+                            <td class="border-bottom-0 text-center">
+                                {{$record->is_open ? 'Yes' : 'No'}}
+                            </td>
+                            <td class="border-bottom-0">
+                                {{$record->memo ? $record->memo : ''}}
+                            </td>
+                            <td class="border-bottom-0">
+                                {{$record->is_active ? 'Yes' : 'No'}}
+                            </td>
+                            <td class="">
+                                {{friendly_date_time($record->last_updated_at)}}
+                            </td>
+                            <td class="border-bottom-0">
+                                <div class="d-flex">
+                                    @include('app.patient.partials.create-edit-accounting-item', ['entityType' => $record->entity_type, 'entityUid' => $record->entity_uid, 'record' => $record])
+                                    <span class="mx-2 text-secondary">|</span>
+                                    @if($record->is_active)
+                                        <div moe relative="">
+                                            <a start show class="py-0 mb-3">Deactivate</a>
+                                            <form url="/api/accountingItem/deactivate" class="mcp-theme-1" right="">
+                                                <input type="hidden" name="uid" value="{{$record->uid}}">
+                                                <p>Deactivate this record?</p>
+                                                <div>
+                                                    <button submit class="btn btn-sm btn-primary mr-1">Submit</button>
+                                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                                </div>
+                                            </form>
+                                        </div>
+                                    @else
+                                        <div moe relative="">
+                                            <a start show class="py-0 mb-3">Reactivate</a>
+                                            <form url="/api/accountingItem/reactivate" class="mcp-theme-1" right="">
+                                                <input type="hidden" name="uid" value="{{$record->uid}}">
+                                                <p>Reactivate this record?</p>
+                                                <div>
+                                                    <button submit class="btn btn-sm btn-primary mr-1">Submit</button>
+                                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                                </div>
+                                            </form>
+                                        </div>
+                                    @endif
+                                </div>
+                            </td>
+                        </tr>
+                    @endforeach
+                    @if(count($records))
+                        <tr>
+                            <td class="border-bottom-0 text-right" colspan="5">
+                                Total (from all pages):
+                            </td>
+                            <td class="border-bottom-0 width-60px text-right font-weight-bold">
+                                <span class="posneg">{{$expected_total >= 0 ? '+' : '-'}}</span>
+                                {{'$' . abs($expected_total)}}
+                            </td>
+                            <td class="border-bottom-0 width-60px text-right font-weight-bold">
+                                <span class="posneg">{{$received_total >= 0 ? '+' : '-'}}</span>
+                                {{'$' . abs($received_total)}}
+                            </td>
+                            <td class="border-bottom-0 text-right" colspan="5">
+                            </td>
+                        </tr>
+                    @endif
+                    </tbody>
+                </table>
+
+                @if(request()->input('paginate') && $paginator->lastPage() > 1)
+                    <div class="pt-3 px-3 d-flex justify-content-start">
+                        {{ $paginator->withQueryString()->links() }}
+                    </div>
+                @endif
+            </div>
+
+        </div>
+    </div>
+
+    <?php
+    if(request()->input('_ql')) printQueryLog(DB::getQueryLog());
+    ?>
+
+    <script>
+        (function() {
+            function init() {
+                $('#accounting-items-filter-form')
+                    .find('input, select')
+                        .off('change')
+                        .on('change', function() {
+                            $(this).closest('form').submit();
+                        });
+            }
+            addMCInitializer('accounting-items', init, '#accounting-items-container');
+        }).call(window);
+    </script>
+@endsection
+

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

@@ -238,6 +238,7 @@
                         </a>
                         <div class="dropdown-menu mcp-theme-1 no-overflow-menu p-0" aria-labelledby="practice-management">
 
+                            <a class="dropdown-item" href="{{ route('accounting-items') }}">Accounting Items</a>
                             <a class="dropdown-item" href="{{ route('practice-management.claims-report') }}">Claims Report</a>
                             <a class="dropdown-item" href="{{ route('practice-management.problems-report') }}">Problems Report</a>
                             <a class="dropdown-item" href="{{ route('practice-management.coverages') }}">Coverage Center</a>

+ 2 - 0
routes/web.php

@@ -703,6 +703,8 @@ Route::middleware('pro.auth')->group(function () {
 
     Route::get('/manage-accounting-items-for-bill/{bill}', 'AdminController@manageAccountingItemsForBill')->name('manage-accounting-items-for-bill');
 
+    Route::get('/accounting-items', 'AdminController@accountingItems')->name('accounting-items');
+
     Route::post('/put-claim-property', 'AdminController@putClaimProperty')->name('put-claim-property');
     Route::post('/put-app-setting', 'AdminController@putAppSetting')->name('put-app-setting');