Selaa lähdekoodia

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

= 3 vuotta sitten
vanhempi
commit
043dd52a1a
34 muutettua tiedostoa jossa 1449 lisäystä ja 118 poistoa
  1. 106 0
      app/Http/Controllers/AdminController.php
  2. 3 0
      app/Http/Controllers/HomeController.php
  3. 39 9
      app/Http/Controllers/InvoiceController.php
  4. 19 0
      app/Http/Controllers/PatientController.php
  5. 4 0
      app/Models/Appointment.php
  6. 18 5
      app/Models/Client.php
  7. 4 0
      app/Models/Invoice.php
  8. 2 2
      app/Models/PaymentMethod.php
  9. 36 5
      resources/views/app/admin/patients-table-extended.blade.php
  10. 108 1
      resources/views/app/admin/patients_filters.blade.php
  11. 67 2
      resources/views/app/dashboard-admin.blade.php
  12. 263 0
      resources/views/app/generic-invoices/index.blade.php
  13. 51 0
      resources/views/app/invoice-center/_ic-add-payment-method-moe.blade.php
  14. 3 3
      resources/views/app/invoice-center/companies.blade.php
  15. 2 2
      resources/views/app/invoice-center/customers.blade.php
  16. 6 6
      resources/views/app/invoice-center/gift-cards.blade.php
  17. 1 1
      resources/views/app/invoice-center/ic-customer-portal.blade.php
  18. 3 56
      resources/views/app/invoice-center/ic-manage-account.blade.php
  19. 7 4
      resources/views/app/invoice-center/ic-pay-invoice.blade.php
  20. 4 4
      resources/views/app/invoice-center/ic-rhs.blade.php
  21. 2 2
      resources/views/app/invoice-center/invoices.blade.php
  22. 7 0
      resources/views/app/patient/care-month/dashboard.blade.php
  23. 8 10
      resources/views/app/patient/coverage_column_renderer.blade.php
  24. 101 0
      resources/views/app/patient/invoicing/companies.blade.php
  25. 97 0
      resources/views/app/patient/invoicing/customer-transactions.blade.php
  26. 150 0
      resources/views/app/patient/invoicing/invoice-transactions.blade.php
  27. 159 0
      resources/views/app/patient/invoicing/invoices.blade.php
  28. 84 0
      resources/views/app/patient/invoicing/layout.blade.php
  29. 3 0
      resources/views/app/patient/note/lhs-tree.blade.php
  30. 8 1
      resources/views/app/patient/note/partials/cpp-bills-claims-container.blade.php
  31. 58 2
      resources/views/layouts/invoice-center.blade.php
  32. 10 0
      resources/views/layouts/patient-header.blade.php
  33. 7 0
      resources/views/layouts/patient.blade.php
  34. 9 3
      routes/web.php

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

@@ -116,6 +116,112 @@ class AdminController extends Controller
         $this->filterMultiQuery($request, $patients, 'created_at', 'created_at', 'created_at_value_1', 'created_at_value_2');
         $this->filterMultiQuery($request, $patients, 'most_recent_completed_mcp_note_date', 'last_visit_category', 'last_visit_value_1', 'last_visit_value_2');
 
+        $fVal = $request->input('has_email');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("(email_address IS NOT NULL AND TRIM(email_address) != '')");
+            }
+            else {
+                $patients = $patients->whereRaw("(email_address IS NULL OR TRIM(email_address) = '')");
+            }
+        }
+
+        $fVal = $request->input('has_account');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("((SELECT COUNT(ac.id) FROM account_client ac WHERE ac.client_id = client.id) > 0)");
+            }
+            else {
+                $patients = $patients->whereRaw("((SELECT COUNT(ac.id) FROM account_client ac WHERE ac.client_id = client.id) = 0)");
+            }
+        }
+
+        $fVal = $request->input('has_default_mcp_company_pro');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("(default_mcp_company_pro_id IS NOT NULL)");
+            }
+            else {
+                $patients = $patients->whereRaw("(default_mcp_company_pro_id IS NULL)");
+            }
+        }
+
+        $fVal = $request->input('has_default_mcp_company_pro_payer');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("(default_mcp_company_pro_payer_id IS NOT NULL)");
+            }
+            else {
+                $patients = $patients->whereRaw("(default_mcp_company_pro_payer_id IS NULL)");
+            }
+        }
+
+        $fVal = $request->input('has_default_mcp_company_location');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("(default_mcp_company_location_id IS NOT NULL)");
+            }
+            else {
+                $patients = $patients->whereRaw("(default_mcp_company_location_id IS NULL)");
+            }
+        }
+
+        $fVal = $request->input('has_bp_device');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 1 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) > 0)");
+            }
+            else {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 1 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) = 0)");
+            }
+        }
+
+        $fVal = $request->input('has_weight_scale');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 2 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) > 0)");
+            }
+            else {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 2 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) = 0)");
+            }
+        }
+
+        $fVal = $request->input('has_pulse_ox');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 3 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) > 0)");
+            }
+            else {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 3 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) = 0)");
+            }
+        }
+
+        $fVal = $request->input('has_temp_fun');
+        if($fVal) {
+            if($fVal === 'YES') {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 4 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) > 0)");
+            }
+            else {
+                $patients = $patients->whereRaw("((SELECT count(sh.id) " .
+                    "FROM shipment sh LEFT JOIN supply_order so ON so.shipment_id = sh.id " .
+                    "WHERE so.product_id = 4 AND sh.status IN ('DELIVERED', 'DISPATCHED') AND so.client_id = client.id) = 0)");
+            }
+        }
+
         if($request->input('number_of_measurements')){
             $keyName = $request->input('number_of_measurements');
             $measurementCountQuery = '(SELECT COUNT(*) FROM measurement WHERE measurement.client_id = client.id AND is_active IS TRUE AND is_cellular IS TRUE AND is_cellular_zero IS NOT TRUE)';

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

@@ -1560,6 +1560,9 @@ WHERE measurement.label NOT IN ('SBP', 'DBP')
             $appointment->clientAge = $appointment->client->age_in_years;
             $appointment->clientSex = $appointment->client->sex;
 
+            $appointment->createdBy = $appointment->creator ? $appointment->creator->displayName() : '';
+            $appointment->createdAt = friendly_date($appointment->created_at);
+
             $appointment->started = false;
             $appointment->inHowManyHours = date_diff(date_create('now'), date_create($appointment->start_time), false)
                 ->format('%R%h h, %i m');

+ 39 - 9
app/Http/Controllers/InvoiceController.php

@@ -2,6 +2,7 @@
 
 namespace App\Http\Controllers;
 
+use App\Lib\Backend;
 use App\Models\AppSession;
 use App\Models\BillingReport;
 use App\Models\CareMonth;
@@ -45,8 +46,10 @@ use App\Models\ClientMemo;
 use Carbon\Carbon;
 use Cassandra\Custom;
 use Illuminate\Pagination\LengthAwarePaginator;
+use Illuminate\Support\Facades\Cookie;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Http;
+use MongoDB\Driver\Session;
 use PDF;
 use DateTime;
 use DateTimeZone;
@@ -131,25 +134,52 @@ class InvoiceController extends Controller
         return view ('app.invoice-center.invoice-transactions', compact('records', 'invoice'));
     }
 
-    public function icPayInvoice(Request $request, $invoiceSlug) {
-        $invoice = Invoice::where('payment_link_slug', $invoiceSlug)->where('is_active', true)->first();
+    private function getICCustomer($sessionKey) {
+        $customer = false;
+        if($sessionKey) {
+            Cookie::queue('sessionKey', $sessionKey);
+        }
+        else {
+            $session = get_current_session();
+            if(!$session) {
+                abort(403);
+            }
+            else {
+                $customer = Customer::where('id', $session->customer_id)->first();
+                if(!$customer) {
+                    abort(403);
+                }
+            }
+        }
+        return $customer;
+    }
+
+    public function icPayInvoice(Request $request, $invoiceUid, $sessionKey = '') {
+        $customer = $this->getICCustomer($sessionKey);
+        if(!$customer) {
+            return redirect(route('icPayInvoice', ['invoiceUid' => $invoiceUid]));
+        }
+        $invoice = Invoice::where('uid', $invoiceUid)->where('is_active', true)->first();
         if (!$invoice) abort(404);
-        $customer = $invoice->customer;
         $company = $customer->company;
         return view('app.invoice-center.ic-pay-invoice', compact('invoice', 'customer', 'company'));
     }
 
-    public function icCustomerPortal(Request $request, $customerSlug) {
-        $customer = Customer::where('slug', $customerSlug)->where('is_active', true)->first();
-        if (!$customer) abort(404);
+    public function icCustomerPortal(Request $request, $sessionKey = '') {
+        $customer = $this->getICCustomer($sessionKey);
+        if(!$customer) {
+            return redirect(route('icCustomerPortal'));
+        }
         $client = $customer->client;
         $company = $customer->company;
         return view('app.invoice-center.ic-customer-portal', compact('customer', 'company'));
     }
 
-    public function icManageAccount(Request $request, $customerSlug) {
-        $customer = Customer::where('slug', $customerSlug)->where('is_active', true)->first();
-        if (!$customer) abort(404);
+    public function icManageAccount(Request $request, $sessionKey = '') {
+        $customer = $this->getICCustomer($sessionKey);
+        if(!$customer) {
+            return redirect(route('icManageAccount'));
+        }
         $client = $customer->client;
         $company = $customer->company;
         return view('app.invoice-center.ic-manage-account', compact('customer', 'company', 'client'));

+ 19 - 0
app/Http/Controllers/PatientController.php

@@ -11,11 +11,13 @@ use App\Models\ClientInfoLine;
 use App\Models\ClientPrimaryCoverage;
 use App\Models\ClientProAccess;
 use App\Models\CompanyPro;
+use App\Models\Customer;
 use App\Models\Erx;
 use App\Models\Facility;
 use App\Models\Handout;
 use App\Models\HandoutClient;
 use App\Models\IncomingReport;
+use App\Models\Invoice;
 use App\Models\MBClaim;
 use App\Models\MBPayer;
 use App\Models\Note;
@@ -39,6 +41,23 @@ use PDF;
 class PatientController extends Controller
 {
 
+    public function invoicingCompanies(Request $request, Client $patient) {
+        return view('app.patient.invoicing.companies', compact('patient'));
+    }
+
+    public function invoicingInvoices(Request $request, Client $patient, Customer $customer) {
+        return view('app.patient.invoicing.invoices', compact('patient', 'customer'));
+    }
+
+    public function invoicingCustomerTransactions(Request $request, Client $patient, Customer $customer) {
+        return view('app.patient.invoicing.customer-transactions', compact('patient', 'customer'));
+    }
+
+    public function invoicingInvoiceTransactions(Request $request, Client $patient, Invoice $invoice) {
+        $customer = $invoice->customer;
+        return view('app.patient.invoicing.invoice-transactions', compact('patient', 'invoice', 'customer'));
+    }
+
     public function claimsResolver(Request $request, Client $patient)
     {
         $notes = $patient->notesAscending;

+ 4 - 0
app/Models/Appointment.php

@@ -18,6 +18,10 @@ class Appointment extends Model
         return $this->hasOne(Pro::class, 'id', 'pro_id');
     }
 
+    public function creator() {
+        return $this->hasOne(Pro::class, 'id', 'created_by_pro_id');
+    }
+
     public function confirmationRequests() {
         return $this->hasMany(AppointmentConfirmationRequest::class, 'appointment_id', 'id')
             ->orderBy('created_at', 'desc');

+ 18 - 5
app/Models/Client.php

@@ -392,6 +392,11 @@ class Client extends Model
         return $this->hasOne(Appointment::class, 'id', 'previous_mcp_appointment_id');
     }
 
+    public function mostRecentCompletedMcpNote()
+    {
+        return $this->hasOne(Note::class, 'id', 'most_recent_completed_mcp_note_id');
+    }
+
     public function lastMeasurementOfType($_type) {
         return Measurement::where('client_id', $this->id)
             ->whereNotNull('bdt_measurement_id')
@@ -458,6 +463,14 @@ class Client extends Model
             ->orderBy('created_at', 'desc');
     }
 
+    public function latestMemo()
+    {
+        return ClientMemo::where('client_id', $this->id)
+            ->where('is_cancelled', false)
+            ->orderBy('created_at', 'desc')
+            ->first();
+    }
+
     public function devices()
     {
         return $this->hasMany(ClientBDTDevice::class, 'client_id', 'id')
@@ -934,11 +947,6 @@ ORDER BY m.ts DESC
         return $this->hasOne(Note::class, 'id', 'core_note_id');
     }
 
-    public function mostRecentCompletedMcpNote(){
-        return $this->hasOne(Note::class, 'id', 'most_recent_completed_mcp_note_id');
-    }
-
-    
     public function nonCoreVisitNotes() {
         return $this->hasMany(Note::class, 'client_id', 'id')
             ->where('id', '<>', $this->core_note_id)
@@ -1045,4 +1053,9 @@ ORDER BY m.ts DESC
         return $this->hasOne(ClientRepFollowUp::class, 'id', 'client_rep_follow_up_id');
     }
 
+    public function customers() {
+        return $this->hasMany(Customer::class, 'client_id', 'id')
+            ->orderBy('created_at', 'desc');
+    }
+
 }

+ 4 - 0
app/Models/Invoice.php

@@ -17,4 +17,8 @@ class Invoice extends Model
     public function customer() {
         return $this->hasOne(Customer::class, 'id', 'customer_id');
     }
+
+    public function invoiceTransactions() {
+        return $this->hasMany(InvoiceTransaction::class, 'invoice_id', 'id')->orderBy('created_at', 'ASC');
+    }
 }

+ 2 - 2
app/Models/PaymentMethod.php

@@ -11,7 +11,7 @@ class PaymentMethod extends Model
     }
 
     public function displayName(){
-        // $parsed = json_decode($this->stripe_detail_json);
-        return "Ending: <b>{$this->card_last4}</b>; Expiry: {$this->expiration_month} / {$this->expiration_year}";
+        $parsed = json_decode($this->detail_json);
+        return "<b>{$parsed->card->brand}</b> ending in <b>{$parsed->card->last4}</b>, expiring {$parsed->card->exp_month} / {$parsed->card->exp_year}";
     }
 }

+ 36 - 5
resources/views/app/admin/patients-table-extended.blade.php

@@ -21,7 +21,7 @@
                 {{--<th class="border-9">Status</th>--}}
                 {{--<th class="border-0">Source</th>--}}
             @endif
-            <th class="border-0 text-secondary">Mailing Address State</th>
+            <th class="border-0 text-secondary">State</th>
             <th class="border-0 text-secondary">Insurance</th>
             @if($performer->pro->pro_type == 'ADMIN')
                 <th class="border-0 text-secondary">Ded.</th>
@@ -69,8 +69,24 @@
                     </a>
                 </td>
                 <td>
-                    <div class="d-flex align-items-center flex-nowrap">
+                    <div class="d-flex align-items-baseline flex-nowrap">
                         <span>{{$patient->displayName()}}</span>
+                        <?php $latestMemo = $patient->latestMemo(); ?>
+                        <div class="on-hover-show d-inline-block on-hover-opaque ml-auto mr-1">
+                            <i class="fa fa-info-circle ml-1 {{$latestMemo ? '' : 'opacity-35'}}"></i>
+                            <div class="on-hover-content py-2 pl-3 text-nowrap text-dark" style="left:0;right:auto;">
+                                @if($latestMemo)
+                                    <p class="mb-1 font-weight-bold text-secondary">Last Memo: {{$latestMemo->category}}</p>
+                                    <div class="text-wrap mb-1">{{$latestMemo->content}}</div>
+                                    <div class="text-secondary text-sm mb-1">{{friendly_date_time($latestMemo->created_at)}}</div>
+                                    @if($latestMemo->createdBy && $latestMemo->createdBy->pro)
+                                        <div class="text-secondary text-sm">By {{$latestMemo->createdBy->pro->displayName()}}</div>
+                                    @endif
+                                @else
+                                    <div class="text-secondary">No client memos.</div>
+                                @endif
+                            </div>
+                        </div>
                     </div>
                 </td>
 		        @if($pro->pro_type == 'ADMIN')
@@ -286,9 +302,24 @@
                         {{count($patient->activeNotes)}}
                     </div>
                 </td>
-                <td>{{$patient->nextMcpAppointment ? friendly_date_time($patient->nextMcpAppointment->raw_date.' '.$patient->nextMcpAppointment->raw_start_time) : '-'}}
+                <td>{{$patient->nextMcpAppointment ? friendly_date_time($patient->nextMcpAppointment->raw_date.' '.$patient->nextMcpAppointment->raw_start_time) : ''}}
+                    <span if-grid-view>
+                        @if($patient->nextMcpAppointment)
+                            {{--{{$patient->nextMcpAppointment->status}}--}}
+                        @elseif($patient->mostRecentCompletedMcpNote && $patient->mostRecentCompletedMcpNote->follow_up_not_needed_memo)
+                            <div class="w-100 text-nowrap overflow-hidden text-ellipsis max-width-170px" title="{{$patient->mostRecentCompletedMcpNote->follow_up_not_needed_memo}}">
+                                <b>No</b>
+                                {{$patient->mostRecentCompletedMcpNote->follow_up_not_needed_memo}}
+                            </div>
+                        @endif
+                    </span>
                     <div if-details-view>
-                        {{$patient->nextMcpAppointment ? $patient->nextMcpAppointment->status : '-'}}
+                        @if($patient->nextMcpAppointment)
+                            {{$patient->nextMcpAppointment->status}}
+                        @elseif($patient->mostRecentCompletedMcpNote && $patient->mostRecentCompletedMcpNote->follow_up_not_needed_memo)
+                            <b>No</b>
+                            {{$patient->mostRecentCompletedMcpNote->follow_up_not_needed_memo}}
+                        @endif
                     </div>
                 </td>
                 <td>{{ friendlier_date_time($patient->most_recent_cellular_bp_measurement_at) }}</td>
@@ -406,7 +437,7 @@
                     return false;
                 });
 
-            if(localStorage.adminPatientsTableFormat === 'grid') {
+            if(localStorage.adminPatientsTableFormat !== 'regular') {
                 $('#admin-patients-list-extended>table').addClass('stag-compact-grid');
             }
             else {

+ 108 - 1
resources/views/app/admin/patients_filters.blade.php

@@ -310,6 +310,105 @@
 		</div>
 	</div>
 
+	<div class="sm-section">
+		<div class="">
+			<label>Has Email:</label>
+			<select name="has_email" class="form-control input-sm" v-model="filters.has_email">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has Account:</label>
+			<select name="has_account" class="form-control input-sm" v-model="filters.has_account">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has C Pro:</label>
+			<select name="has_default_mcp_company_pro" class="form-control input-sm" v-model="filters.has_default_mcp_company_pro">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has C Pro Payer:</label>
+			<select name="has_default_mcp_company_pro_payer" class="form-control input-sm" v-model="filters.has_default_mcp_company_pro_payer">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has C Location:</label>
+			<select name="has_default_mcp_company_location" class="form-control input-sm" v-model="filters.has_default_mcp_company_location">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has BP Device:</label>
+			<select name="has_bp_device" class="form-control input-sm" v-model="filters.has_bp_device">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has Weight Scale:</label>
+			<select name="has_weight_scale" class="form-control input-sm" v-model="filters.has_weight_scale">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has Pulse Ox:</label>
+			<select name="has_pulse_ox" class="form-control input-sm" v-model="filters.has_pulse_ox">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
+	<div class="sm-section">
+		<div class="">
+			<label>Has Temp. Gun:</label>
+			<select name="has_temp_fun" class="form-control input-sm" v-model="filters.has_temp_fun">
+				<option value="">All</option>
+				<option value="YES">Yes</option>
+				<option value="NO">No</option>
+			</select>
+		</div>
+	</div>
+
 	@if($performer->pro->pro_type == 'ADMIN')
 	<div class="sm-section">
 		<div class="">
@@ -426,7 +525,15 @@ $allFilterKeys = [
 	'created_at',
 	'created_at_value_1',
 	'created_at_value_2',
-
+	'has_email',
+	'has_account',
+	'has_default_mcp_company_pro',
+	'has_default_mcp_company_pro_payer',
+	'has_default_mcp_company_location',
+	'has_bp_device',
+	'has_weight_scale',
+	'has_pulse_ox',
+	'has_temp_fun'
 ];
 for ($i=0; $i < count($allFilterKeys); $i++) {
 	if (!isset($loadedFilters[$allFilterKeys[$i]]) || !$loadedFilters[$allFilterKeys[$i]]) {

+ 67 - 2
resources/views/app/dashboard-admin.blade.php

@@ -460,7 +460,7 @@
                                         </div>
                                     </div>
                                 </div>
-                                <div v-for="event in events" class="align-items-end p-3 border rounded mb-3"
+                                {{--<div v-for="event in events" class="align-items-end p-3 border rounded mb-3"
                                      v-if="!filterPro || filterPro === event.proUid"
                                      :class="(event.dateYMD === selectedDate && (filterStatus === '' || filterStatus === event.status) ? 'd-flex' : 'd-none') + ' ' + (event.isClientShadowOfPro ? 'training-event' : '')">
                                     <div class="patient-avatar mr-3 align-self-center">
@@ -522,7 +522,72 @@
                                             @{{ event.inHowManyHours }}
                                         </div>
                                     </div>
-                                </div>
+                                </div>--}}
+
+
+                                <table class="table table-sm table-striped table-hover table-bordered" v-if="numEventsForDate>0">
+                                    <thead>
+                                    <tr>
+                                        <th class="border-bottom-0"></th>
+                                        <th class="border-bottom-0">Time</th>
+                                        <th class="border-bottom-0">Pro</th>
+                                        <th class="border-bottom-0">Patient</th>
+                                        <th class="border-bottom-0">Status</th>
+                                        <th class="border-bottom-0">Coverage</th>
+                                        <th class="border-bottom-0"></th>
+                                        <th class="border-bottom-0">Created By</th>
+                                        <th class="border-bottom-0">Created At</th>
+                                    </tr>
+                                    </thead>
+                                    <tbody>
+                                    <tr v-for="event in events" class=""
+                                         v-if="!filterPro || filterPro === event.proUid"
+                                         :class="(event.dateYMD === selectedDate && (filterStatus === '' || filterStatus === event.status) ? 'd-table-row' : 'd-none') + ' ' + (event.isClientShadowOfPro ? 'training-event' : '')">
+                                        <td class="align-middle">
+                                            <span v-if="event.isClientShadowOfPro">Training</span>
+                                            <span v-else>Clinical</span>
+                                        </td>
+                                        <td class="align-middle">
+                                            @{{ event.friendlyStartTime }} - @{{ event.friendlyEndTime }}
+                                            <span class="text-secondary">@{{ event.timezone }}</span>
+                                        </td>
+                                        <td class="align-middle">
+                                            @{{ event.proName }}
+                                        </td>
+                                        <td class="align-middle">
+                                            <a :href="'/patients/view/' + event.clientUid" class="font-weight-normal">@{{
+                                                event.clientName }}</a>
+                                            <span class="small d-inline-block pl-2 text-secondary font-weight-normal">@{{ event.clientSummary }}</span>
+                                        </td>
+                                        <td class="align-middle p-0">
+                                            <select v-model="event.newStatus"
+                                                    class="form-control form-control-sm bg-light w-100 rounded-0 border-0"
+                                                    v-on:change="updateStatus(event)">
+                                                <option value="PENDING">PENDING</option>
+                                                <option value="CONFIRMED">CONFIRMED</option>
+                                                <option value="CANCELLED">CANCELLED</option>
+                                                <option value="COMPLETED">COMPLETED</option>
+                                            </select>
+                                        </td>
+                                        <td class="align-middle">
+                                            @{{ event.coverage }}
+                                        </td>
+                                        <td class="align-middle">
+                                            <a :href="'/patients/view/' + event.clientUid + '/calendar/' + event.uid">
+                                                <i class="fa fa-edit"></i>
+                                                Edit
+                                            </a>
+                                        </td>
+                                        <td class="align-middle">
+                                            @{{ event.createdBy }}
+                                        </td>
+                                        <td class="align-middle">
+                                            @{{ event.createdAt }}
+                                        </td>
+                                    </tr>
+                                    </tbody>
+                                </table>
+
                                 <div v-if="numEventsForDate === 0" class="bg-light p-3 text-secondary border bounded">
                                     <span
                                         v-if="filterStatus === ''">You have no appointments on <b>@{{ selectedDate }}</b></span>

+ 263 - 0
resources/views/app/generic-invoices/index.blade.php

@@ -0,0 +1,263 @@
+<?php
+$invoices = \App\Models\Invoice::where($parentType === 'Note' ? 'note_id' : 'care_month_id', $parentID)->get();
+?>
+<div id="generic-invoices-{{$parentType}}-{{$parentID}}">
+    <div class="d-flex align-items-baseline pb-3">
+        <h4 class="font-weight-bold m-0">Invoices</h4>
+        <span class="text-secondary mx-2">|</span>
+        @if(!count($patient->customers))
+            <b>This patient is not added as a customer on any company yet.</b>
+        @else
+            <div moe>
+                <a href="" start show>
+                    + Add Invoice
+                </a>
+                <form url="/api/invoice/create" class="mcp-theme-1">
+                    <p class="mb-2 text-secondary font-weight-bold">Add Invoice</p>
+                    <input type="hidden" name="{{$parentType === 'Note' ? 'noteUid' : 'careMonthUid'}}" value="{{$parentUid}}">
+                    <div class="mb-2">
+                        <label class="text-sm text-secondary mb-1">Customer</label>
+                        <select name="customerUid" class="form-control form-control-sm" required>
+                            <option value="">-- select --</option>
+                            @foreach($patient->customers as $customer)
+                                <option value="{{$customer->uid}}">{{$customer->company->name}}</option>
+                            @endforeach
+                        </select>
+                    </div>
+                    <div class="mb-2">
+                        <label class="text-sm text-secondary mb-1">Amount</label>
+                        <input type="text"
+                               name="amount"
+                               autocomplete="off"
+                               class="form-control form-control-sm"
+                               required>
+                    </div>
+                    <div class="mb-2">
+                        <label class="text-sm text-secondary mb-1">Description</label>
+                        <textarea rows="2"
+                                  name="description"
+                                  autocomplete="off"
+                                  class="form-control form-control-sm" required></textarea>
+                    </div>
+                    <div>
+                        <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                        <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                    </div>
+                </form>
+            </div>
+        @endif
+        <span class="text-secondary mx-2">|</span>
+        <div moe>
+            <a href="" start show>
+                + Add Patient as Customer
+            </a>
+            <form url="/api/customer/create" class="mcp-theme-1">
+                <p class="mb-2 text-secondary font-weight-bold">Add As Customer</p>
+                <input type="hidden" name="clientUid" value="{{$patient->uid}}">
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Company</label>
+                    <input type="hidden" name="companyUid" value="{{@$company->uid}}">
+                    <input type="text"
+                           name="companyName"
+                           target-key="uid"
+                           target-field="companyUid"
+                           autocomplete="off"
+                           class="form-control form-control-sm"
+                           stag-suggest
+                           stag-suggest-ep="/company-suggest"
+                           value="{{@$company ? @$company->name : ''}}"
+                           {{@$company ? 'disabled readonly' : ''}}
+                           required>
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
+        </div>
+    </div>
+    @if(!count($invoices))
+        <div class="border p-2">This {{$parentType}} does not have any invoices yet.</div>
+    @else
+        <table class="table table-sm table-bordered table-striped m-0">
+            <thead>
+            <tr>
+                <th class="border-bottom-0"></th>
+                <th class="border-bottom-0">Company</th>
+                <th class="border-bottom-0">Created</th>
+                <th class="border-bottom-0">Amount</th>
+                <th class="border-bottom-0">Description</th>
+                <th class="border-bottom-0">Pay Link</th>
+                <th class="border-bottom-0">Paid</th>
+                <th class="border-bottom-0">Balance</th>
+                <th class="border-bottom-0">Active?</th>
+                <th class="border-bottom-0"></th>
+            </tr>
+            </thead>
+            <tbody>
+            <?php $i = 1; ?>
+            @foreach($invoices as $record)
+                <tr>
+                    <td>{{ $i++ }}</td>
+                    <td>{{ $record->customer->company->name }}</td>
+                    <td>{{ friendly_date($record->created_at) }}</td>
+                    <td>${{ is_null($record->amount) ? 0 : $record->amount }}
+                        <div moe relative class="ml-1">
+                            <a href="#" start show><i class="fa fa-edit on-hover-opaque"></i></a>
+                            <form url="/api/invoice/changeAmount">
+                                <input type="hidden" name="invoiceUid" value="{{$record->uid}}">
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Amount</label>
+                                    <input type="text"
+                                           name="amount"
+                                           autocomplete="off"
+                                           class="form-control form-control-sm"
+                                           value="{{$record->amount}}"
+                                           required>
+                                </div>
+                                <div>
+                                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                </div>
+                            </form>
+                        </div>
+                    </td>
+                    <td>{{ $record->description ?: '' }}
+                        <div moe relative class="ml-1">
+                            <a href="#" start show><i class="fa fa-edit on-hover-opaque"></i></a>
+                            <form url="/api/invoice/changeDescription">
+                                <input type="hidden" name="invoiceUid" value="{{$record->uid}}">
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Description</label>
+                                    <textarea rows="2"
+                                              name="description"
+                                              autocomplete="off"
+                                              class="form-control form-control-sm" required>{{$record->description}}</textarea>
+                                </div>
+                                <div>
+                                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                </div>
+                            </form>
+                        </div>
+                    </td>
+                    <td>
+                        <a href="#" data-invoice-uid="{{$record->uid}}" data-uid="{{$record->customer->uid}}" class="generate-and-visit-ic-pay" native target="_blank">Visit</a>
+                        <a href="#" data-invoice-uid="{{$record->uid}}" data-uid="{{$record->customer->uid}}" class="generate-and-copy-ic-pay-url ml-1" native target="_blank">Copy</a>
+                    </td>
+                    <td>${{ is_null($record->paid) ? 0 : $record->paid }}</td>
+                    <td>${{ is_null($record->balance) ? 0 : $record->balance }}</td>
+                    <td class="{{ !$record->is_active ? 'text-warning-dark' : ''}}">{{ $record->is_active ? 'Yes' : 'No' }}</td>
+                    <td>
+                        <div class="d-flex flex-wrap">
+                            @if($record->is_active)
+                                <div moe class="mr-2">
+                                    <a href="" start show>Deactivate</a>
+                                    <form url="/api/invoice/deactivate" class="mcp-theme-1" right>
+                                        <p class="mb-2 text-nowrap">Deactivate this invoice?</p>
+                                        <input type="hidden" name="uid" value="{{$record->uid}}">
+                                        <div>
+                                            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                        </div>
+                                    </form>
+                                </div>
+                            @else
+                                <div moe class="mr-2">
+                                    <a href="" start show>Reactivate</a>
+                                    <form url="/api/invoice/reactivate" class="mcp-theme-1" right>
+                                        <p class="mb-2 text-nowrap">Reactivate this invoice?</p>
+                                        <input type="hidden" name="uid" value="{{$record->uid}}">
+                                        <div>
+                                            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                        </div>
+                                    </form>
+                                </div>
+                            @endif
+                            <a href="{{route('patients.view.invoicing-invoice-transactions', ['patient' => $patient, 'invoice' => $record])}}" class="mr-2">Transactions</a>
+                        </div>
+                    </td>
+                </tr>
+            @endforeach
+            </tbody>
+        </table>
+    @endif
+</div>
+<script>
+    (function () {
+        function init() {
+            initStagSuggest();
+            let parentSegment = $('body');
+            parentSegment.find('input[stag-suggest][target-key][target-field]')
+                .off('stag-suggest-selected')
+                .on('stag-suggest-selected', (_e, _input, _data) => {
+                    _input = $(_input);
+                    _input.closest('form').find('input[name="' + _input.attr('target-field') + '"]').val(_data[_input.attr('target-key')]);
+                });
+            parentSegment.find('.copy-target')
+                .off('click.copy-target')
+                .on('click.copy-target', function() {
+                    copyTextToClipboard($(this).attr('data-target'));
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-visit-ic-portal')
+                .off('click.generate-and-visit-ic-portal')
+                .on('click.generate-and-visit-ic-portal', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            window.location.href = '/ic/home/' + _data.data;
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-copy-ic-portal-url')
+                .off('click.generate-and-copy-ic-portal-url')
+                .on('click.generate-and-copy-ic-portal-url', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            copyTextToClipboard('{{config('app.url')}}/ic/home/' + _data.data);
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-visit-ic-pay')
+                .off('click.generate-and-visit-ic-pay')
+                .on('click.generate-and-visit-ic-pay', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            window.location.href = '/ic/pay/' + $(this).attr('data-invoice-uid') + '/' + _data.data;
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-copy-ic-pay-url')
+                .off('click.generate-and-copy-ic-pay-url')
+                .on('click.generate-and-copy-ic-pay-url', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            copyTextToClipboard('{{config('app.url')}}/ic/pay/' + $(this).attr('data-invoice-uid') + '/' + _data.data);
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+        }
+        addMCInitializer('generic-invoices-{{$parentType}}-{{$parentID}}', init, '#generic-invoices-{{$parentType}}-{{$parentID}}')
+    }).call(window);
+</script>

+ 51 - 0
resources/views/app/invoice-center/_ic-add-payment-method-moe.blade.php

@@ -0,0 +1,51 @@
+<div moe relative>
+    <a start show href="#" class="text-nowrap">{{@$label ?: 'Add Payment Method'}}</a>
+    <form url="/api/paymentMethod/createCard">
+        <input type="hidden" name="customerUid" value="{{$customer->uid}}">
+        <p class="text-secondary font-weight-bold mb-1 text-nowrap">Add Payment Method</p>
+        <div class="mb-2">
+            <lable class="mb-1 text-secondary text-sm">Card Number</lable>
+            <input type="text" name="cardNumber" value="" class="form-control form-control-sm min-width-200px" required>
+        </div>
+        <div class="mb-2">
+            <lable class="mb-1 text-secondary text-sm">Expiry Date</lable>
+            <div class="d-flex align-items-start">
+                <select class="form-control form-control-sm" name="expirationMonth" required>
+                    <option value="">-- select --</option>
+                    <option value="1">January</option>
+                    <option value="2">February</option>
+                    <option value="3">March</option>
+                    <option value="4">April</option>
+                    <option value="5">May</option>
+                    <option value="6">June</option>
+                    <option value="7">July</option>
+                    <option value="8">August</option>
+                    <option value="9">September</option>
+                    <option value="10">October</option>
+                    <option value="11">November</option>
+                    <option value="12">December</option>
+                </select>
+                <select class="form-control form-control-sm ml-2" name="expirationYear" required>
+                    <option value="">-- select --</option>
+                    <option value="2022">2022</option>
+                    <option value="2023">2023</option>
+                    <option value="2024">2024</option>
+                    <option value="2025">2025</option>
+                    <option value="2026">2026</option>
+                </select>
+            </div>
+        </div>
+        <div class="mb-2">
+            <lable class="mb-1 text-secondary text-sm">CVV/CCV Number</lable>
+            <input type="text" name="ccv" value="" class="form-control form-control-sm min-width-200px" required>
+        </div>
+        <div class="mb-2">
+            <lable class="mb-1 text-secondary text-sm">Billing Zip</lable>
+            <input type="text" name="billingZip" value="" class="form-control form-control-sm min-width-200px">
+        </div>
+        <div class="d-flex align-items-center">
+            <button submit class="btn btn-sm btn-primary me-2">Submit</button>
+            <button cancel class="btn btn-sm btn-default">Cancel</button>
+        </div>
+    </form>
+</div>

+ 3 - 3
resources/views/app/invoice-center/companies.blade.php

@@ -11,7 +11,7 @@
                 <th class="border-bottom-0 width-300px">Name</th>
                 <th class="border-bottom-0">State</th>
                 <th class="border-bottom-0">Customers</th>
-                <th class="border-bottom-0">Gift Cards</th>
+                <th class="border-bottom-0">Vouchers</th>
                 <th class="border-bottom-0">Created</th>
             </tr>
             </thead>
@@ -36,9 +36,9 @@
                            class="mr-2"
                            open-in-stag-popup
                            update-parent
-                           title="{{$record->name}}: Gift Cards"
+                           title="{{$record->name}}: Vouchers"
                            popup-style="stag-popup-med overflow-visible"
-                           mc-initer="invoice-center">{{count($record->giftCards)}} gift card{{count($record->giftCards) === 1 ? '' : 's'}}</a>
+                           mc-initer="invoice-center">{{count($record->giftCards)}} voucher{{count($record->giftCards) === 1 ? '' : 's'}}</a>
                     </td>
                     <td>{{ friendly_date($record->created_at) }}</td>
                 </tr>

+ 2 - 2
resources/views/app/invoice-center/customers.blade.php

@@ -81,8 +81,8 @@
                     <td>${{ is_null($record->customer_balance) ? 0 : $record->customer_balance }}</td>
                     <td>${{ is_null($record->pending_invoices_balance_total) ? 0 : $record->pending_invoices_balance_total }}</td>
                     <td>
-                        <a href="{{route('icCustomerPortal', ['customerSlug' => $record->slug])}}" native target="_blank">Visit</a>
-                        <a href="#" data-target="{{route('icCustomerPortal', ['customerSlug' => $record->slug])}}" native target="_blank" class="copy-target ml-1">Copy</a>
+                        <a href="#" data-uid="{{$record->uid}}" class="generate-and-visit-ic-portal" native target="_blank">Visit</a>
+                        <a href="#" data-uid="{{$record->uid}}" class="generate-and-copy-ic-portal-url ml-1" native target="_blank">Copy</a>
                     </td>
                     <td>{{ friendly_date($record->created_at) }}</td>
                     <td class="{{ !$record->is_active ? 'text-warning-dark' : ''}}">{{ $record->is_active ? 'Yes' : 'No' }}</td>

+ 6 - 6
resources/views/app/invoice-center/gift-cards.blade.php

@@ -1,13 +1,13 @@
 @extends('layouts.invoice-center')
 @section('inner-content')
     <div class="d-flex mb-2 pb-2 align-items-center border-bottom">
-        <div class="font-size-14 font-weight-bold">Gift Cards</div>
+        <div class="font-size-14 font-weight-bold">Vouchers</div>
         <div moe class="ml-3">
             <a href="" start show class="btn btn-sm btn-primary font-weight-normal text-white">
-                + Add Gift Card
+                + Add Voucher
             </a>
             <form url="/api/giftCard/create" class="mcp-theme-1">
-                <p class="mb-2 text-secondary font-weight-bold">Add Gift Card</p>
+                <p class="mb-2 text-secondary font-weight-bold">Add Voucher</p>
                 <div class="mb-2">
                     <label class="text-sm text-secondary mb-1">Company</label>
                     <input type="hidden" name="companyUid" value="{{@$company->uid}}">
@@ -76,7 +76,7 @@
                             <div moe class="ml-3">
                                 <a href="" start show>Deactivate</a>
                                 <form url="/api/giftCard/deactivate" class="mcp-theme-1" right>
-                                    <p class="mb-2 text-nowrap">Deactivate this gift card?</p>
+                                    <p class="mb-2 text-nowrap">Deactivate this voucher?</p>
                                     <input type="hidden" name="uid" value="{{$record->uid}}">
                                     <div>
                                         <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
@@ -88,7 +88,7 @@
                             <div moe class="ml-3">
                                 <a href="" start show>Reactivate</a>
                                 <form url="/api/giftCard/reactivate" class="mcp-theme-1" right>
-                                    <p class="mb-2 text-nowrap">Reactivate this gift card?</p>
+                                    <p class="mb-2 text-nowrap">Reactivate this voucher?</p>
                                     <input type="hidden" name="uid" value="{{$record->uid}}">
                                     <div>
                                         <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
@@ -104,6 +104,6 @@
         </table>
         {{$records->withQueryString()->links()}}
     @else
-        <div class="text-secondary">No gift cards yet!</div>
+        <div class="text-secondary">No vouchers yet!</div>
     @endif
 @endsection

+ 1 - 1
resources/views/app/invoice-center/ic-customer-portal.blade.php

@@ -32,7 +32,7 @@
                     @foreach($customer->invoices as $invoice)
                         <tr>
                             <td>{{friendly_date($invoice->created_at)}}</td>
-                            <td><a href="{{route('icPayInvoice', ['invoiceSlug' => $invoice->payment_link_slug])}}">{{$invoice->description}}</a></td>
+                            <td><a href="{{route('icPayInvoice', ['invoiceUid' => $invoice->uid])}}">{{$invoice->description}}</a></td>
                             <td class="text-dark">${{!is_null($invoice->amount) ? $invoice->amount : 0}}</td>
                             <td class="text-success">${{!is_null($invoice->paid) ? $invoice->paid : 0}}</td>
                             <td class="font-weight-bold text-warning-dark">${{!is_null($invoice->balance) ? $invoice->balance : 0}}</td>

+ 3 - 56
resources/views/app/invoice-center/ic-manage-account.blade.php

@@ -3,7 +3,7 @@
     <div class="container mcp-theme-1">
         <div class="d-flex align-items-baseline mt-3 mb-2">
             <h3 class="font-size-16 font-weight-bold text-dark">Manage Account</h3>
-            <a href="{{route('icCustomerPortal', ['customerSlug' => $customer->slug])}}" class="ml-auto">
+            <a href="{{route('icCustomerPortal')}}" class="ml-auto">
                 <i class="fa fa-chevron-left"></i>
                 Back to Home
             </a>
@@ -13,61 +13,8 @@
             <div class="col-md-8">
                 <div class="d-flex align-items-baseline mt-4">
                     <h4 class="title-sm m-0">Payment Methods</h4>
-                    <div moe class="ml-3">
-                        <a start show href="#" class="text-nowrap">Add Payment Method</a>
-                        <form url="/api/paymentMethod/create">
-                            <input type="hidden" name="customerUid" value="{{$customer->uid}}">
-                            <input type="hidden" name="customerSlug" value="{{$customer->slug}}">
-                            <p class="text-secondary font-weight-bold mb-1 text-nowrap">Add Payment Method</p>
-                            <div class="mb-2">
-                                <lable class="mb-1 text-secondary text-sm">Card Number</lable>
-                                <input type="text" name="cardNumber" value="" class="form-control form-control-sm min-width-200px" required>
-                            </div>
-                            <div class="mb-2">
-                                <lable class="mb-1 text-secondary text-sm">Name nn Card</lable>
-                                <input type="text" name="nameOnCard" value="" class="form-control form-control-sm min-width-200px" required>
-                            </div>
-                            <div class="mb-2">
-                                <lable class="mb-1 text-secondary text-sm">Expiry Date</lable>
-                                <div class="d-flex align-items-start">
-                                    <select class="form-control form-control-sm" name="expirationMonth" required>
-                                        <option value="">-- select --</option>
-                                        <option value="1">January</option>
-                                        <option value="2">February</option>
-                                        <option value="3">March</option>
-                                        <option value="4">April</option>
-                                        <option value="5">May</option>
-                                        <option value="6">June</option>
-                                        <option value="7">July</option>
-                                        <option value="8">August</option>
-                                        <option value="9">September</option>
-                                        <option value="10">October</option>
-                                        <option value="11">November</option>
-                                        <option value="12">December</option>
-                                    </select>
-                                    <select class="form-control form-control-sm ml-2" name="expirationYear" required>
-                                        <option value="">-- select --</option>
-                                        <option value="2022">2022</option>
-                                        <option value="2023">2023</option>
-                                        <option value="2024">2024</option>
-                                        <option value="2025">2025</option>
-                                        <option value="2026">2026</option>
-                                    </select>
-                                </div>
-                            </div>
-                            <div class="mb-2">
-                                <lable class="mb-1 text-secondary text-sm">CVV/CCV Number</lable>
-                                <input type="text" name="ccv" value="" class="form-control form-control-sm min-width-200px" required>
-                            </div>
-                            <div class="mb-2">
-                                <lable class="mb-1 text-secondary text-sm">Billing Zip</lable>
-                                <input type="text" name="billingZip" value="" class="form-control form-control-sm min-width-200px">
-                            </div>
-                            <div class="d-flex align-items-center">
-                                <button submit class="btn btn-sm btn-primary me-2">Submit</button>
-                                <button cancel class="btn btn-sm btn-default">Cancel</button>
-                            </div>
-                        </form>
+                    <div class="ml-3">
+                        @include('app.invoice-center._ic-add-payment-method-moe')
                     </div>
                 </div>
                 <hr class="red-underline">

+ 7 - 4
resources/views/app/invoice-center/ic-pay-invoice.blade.php

@@ -3,7 +3,7 @@
 <div class="container mcp-theme-1">
     <div class="d-flex align-items-baseline mt-3 mb-2">
         <h3 class="font-size-16 font-weight-bold text-dark">Invoice</h3>
-        <a href="{{route('icCustomerPortal', ['customerSlug' => $customer->slug])}}" class="ml-auto">
+        <a href="{{route('icCustomerPortal')}}" class="ml-auto">
             <i class="fa fa-chevron-left"></i>
             Back to Home
         </a>
@@ -69,7 +69,7 @@
                                     </div>
                                 @else
                                     <div class="mt-3 border rounded border-secondary p-2 text-left text-warning-dark w-100">
-                                        <b>Cannot pay from your balance:</b> Your current balance (${{$customer->customer_balance}}) is less than the due amount (${{$invoice->balance}}). If you have a gift card, use its code on the right hand side to add funds to your balance.
+                                        <b>Cannot pay from your balance:</b> Your current balance (${{$customer->customer_balance}}) is less than the due amount (${{$invoice->balance}}). If you have a voucher, use its code on the right hand side to add funds to your balance.
                                     </div>
                                 @endif
                                 @if(count($customer->paymentMethods))
@@ -79,7 +79,6 @@
                                             <p class="mb-2 text-left">Pay Invoice</p>
                                             <input type="hidden" name="invoiceUid" value="{{$invoice->uid}}">
                                             <input type="hidden" name="amount" value="{{$invoice->balance}}">
-                                            <input type="hidden" name="paymentLinkSlug" value="{{$invoice->payment_link_slug}}">
                                             <div class="mb-2">
                                                 <label class="text-sm text-secondary mb-1">Payment Method</label>
                                                 <select name="paymentMethodUid" class="form-control form-control-sm" required>
@@ -97,7 +96,11 @@
                                     </div>
                                 @else
                                     <div class="mt-3 border rounded border-secondary p-2 text-left text-warning-dark w-100">
-                                        You have not setup any payment methods yet. <a href="/ic/manageAccount/{{$customer->slug}}">Click here</a> to set one up.
+                                        You have not setup any payment methods yet.
+                                        <div class="d-inline-block">
+                                            @include('app.invoice-center._ic-add-payment-method-moe', ['label' => 'Click here'])
+                                        </div>
+                                        to set one up.
                                     </div>
                                 @endif
                             </div>

+ 4 - 4
resources/views/app/invoice-center/ic-rhs.blade.php

@@ -4,13 +4,13 @@
         <span class="font-weight-bold text-dark">${{!is_null($customer->customer_balance) ? $customer->customer_balance : 0}}</span>
     </div>
     @if(request()->route()->getName() !== 'icManageAccount')
-        <a href="/ic/manageAccount/{{$customer->slug}}" class="font-weight-bold mb-3 d-block">Manage Payment Methods</a>
+        <a href="/ic/manageAccount" class="font-weight-bold mb-3 d-block">Manage Payment Methods</a>
     @endif
-    <h3 class="font-weight-bold mb-2 text-secondary">Redeem Gift Card</h3>
-    <div moe>
+    <h3 class="font-weight-bold mb-2 c-pointer" onclick="$('#gift-card-moe').toggle(); return false;">Redeem Voucher <span class="font-weight-normal text-sm">(click to show/hide)</span></h3>
+    <div moe id="gift-card-moe" style="display: none">
         <form url="/api/giftCard/redeem" show>
             <input type="hidden" name="customerUid" value="{{$customer->uid}}">
-            <p class="mb-2">If you have a gift card from {{$company->name}}, please enter its code below:</p>
+            <p class="mb-2">If you have a voucher from {{$company->name}}, please enter its code below:</p>
             <div class="mb-2">
                 <input type="text" name="code" placeholder="Code" class="form-control form-control-sm">
             </div>

+ 2 - 2
resources/views/app/invoice-center/invoices.blade.php

@@ -119,8 +119,8 @@
                         </div>
                     </td>
                     <td>
-                        <a href="{{route('icPayInvoice', ['invoiceSlug' => $record->payment_link_slug])}}" native target="_blank">Visit</a>
-                        <a href="#" data-target="{{route('icPayInvoice', ['invoiceSlug' => $record->payment_link_slug])}}" native target="_blank" class="copy-target ml-1">Copy</a>
+                        <a href="#" data-invoice-uid="{{$record->uid}}" data-uid="{{$record->customer->uid}}" class="generate-and-visit-ic-pay" native target="_blank">Visit</a>
+                        <a href="#" data-invoice-uid="{{$record->uid}}" data-uid="{{$record->customer->uid}}" class="generate-and-copy-ic-pay-url ml-1" native target="_blank">Copy</a>
                     </td>
                     <td>${{ is_null($record->paid) ? 0 : $record->paid }}</td>
                     <td>${{ is_null($record->balance) ? 0 : $record->balance }}</td>

+ 7 - 0
resources/views/app/patient/care-month/dashboard.blade.php

@@ -1208,6 +1208,13 @@
             @endif
 
         @endif
+
+        {{-- invoices --}}
+        @if($pro->pro_type === 'ADMIN')
+            <hr class="m-negator mt-4 mb-3">
+            @include('app.generic-invoices.index', ['patient' => $patient, 'parentType' => 'Care Month', 'parentID' => $careMonth->id, 'parentUid' => $careMonth->uid])
+        @endif
+
         @if($pro->pro_type === 'ADMIN')
         <hr class="m-negator mt-4 mb-3">
         <div>

+ 8 - 10
resources/views/app/patient/coverage_column_renderer.blade.php

@@ -24,7 +24,7 @@
         @endif
     @endif
 
-    <div class="ml-2">
+    <div class="ml-2 d-inline-flex align-items-baseline">
         @if($coverage)
             @if($coverage->plan_type === 'MEDICAID' && $coverage->mcdPayer)
                 <span class="{{ @$truncateName ? 'coverage-payer-name':'' }}"
@@ -40,16 +40,14 @@
             <small class="ml-2 text-muted">(No insurance)</small>
         @endif
         <div class="">
-            @if($coverage)
-                @if($coverage && $coverage->plan_type === 'MEDICARE')
-                    @if(@$patient->mpb_remaining !== null)
-                        <span class="text-muted d-block text-sm">Deductible: {{format_number(@$patient->mpb_remaining)}}</span>
-                    @endif
+            @if($coverage && $coverage->plan_type === 'MEDICARE')
+                @if(@$patient->mpb_remaining)
+                    <span class="text-muted d-block text-sm ml-1">(Ded: {{format_number(@$patient->mpb_remaining)}})</span>
                 @endif
-                @if($coverage->plan_type === 'COMMERCIAL')
-                    @if(@$coverage->deductible_amount !== null)
-                        <span class="text-muted d-block text-sm">Deductible: {{format_number(@$coverage->deductible_amount)}}</span>
-                    @endif
+            @endif
+            @if($coverage && $coverage->plan_type === 'COMMERCIAL')
+                @if(@$coverage->deductible_amount && !!+@$coverage->deductible_amount)
+                    <span class="text-muted d-block text-sm ml-1">(Ded: {{format_number(@$coverage->deductible_amount)}})</span>
                 @endif
             @endif
         </div>

+ 101 - 0
resources/views/app/patient/invoicing/companies.blade.php

@@ -0,0 +1,101 @@
+@extends ('app.patient.invoicing.layout')
+@section('invoicing-content')
+    <div class="d-flex align-items-baseline pb-3">
+        <h4 class="font-weight-bold m-0 font-size-16">Companies</h4>
+        <span class="text-secondary mx-2">|</span>
+        <div moe>
+            <a href="" start show class="font-weight-bold">
+                + Add
+            </a>
+            <form url="/api/customer/create" class="mcp-theme-1">
+                <p class="mb-2 text-secondary font-weight-bold">Add As Customer</p>
+                <input type="hidden" name="clientUid" value="{{$patient->uid}}">
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Company</label>
+                    <input type="hidden" name="companyUid" value="{{@$company->uid}}">
+                    <input type="text"
+                           name="companyName"
+                           target-key="uid"
+                           target-field="companyUid"
+                           autocomplete="off"
+                           class="form-control form-control-sm"
+                           stag-suggest
+                           stag-suggest-ep="/company-suggest"
+                           value="{{@$company ? @$company->name : ''}}"
+                           {{@$company ? 'disabled readonly' : ''}}
+                           required>
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
+        </div>
+    </div>
+    @if(!count($patient->customers))
+        <div class="border p-2">This patient is not registered as a customer in any company yet.</div>
+    @else
+        <table class="table table-sm table-bordered table-striped">
+            <thead>
+            <tr>
+                <th class="border-bottom-0"></th>
+                <th class="border-bottom-0">Company</th>
+                <th class="border-bottom-0">Customer<br>Balance</th>
+                <th class="border-bottom-0">Pending Invoices<br>Balance</th>
+                <th class="border-bottom-0">Portal</th>
+                <th class="border-bottom-0">Created</th>
+                <th class="border-bottom-0">Active?</th>
+                <th class="border-bottom-0"></th>
+            </tr>
+            </thead>
+            <tbody>
+            <?php $i = 1; ?>
+            @foreach($patient->customers as $record)
+                <tr>
+                    <td>{{ $i++ }}</td>
+                    <td>{{ $record->company ? $record->company->name : '-' }}</td>
+                    <td>${{ is_null($record->customer_balance) ? 0 : $record->customer_balance }}</td>
+                    <td>${{ is_null($record->pending_invoices_balance_total) ? 0 : $record->pending_invoices_balance_total }}</td>
+                    <td>
+                        <a href="#" data-uid="{{$record->uid}}" class="generate-and-visit-ic-portal" native target="_blank">Visit</a>
+                        <a href="#" data-uid="{{$record->uid}}" class="generate-and-copy-ic-portal-url ml-1" native target="_blank">Copy</a>
+                    </td>
+                    <td>{{ friendly_date($record->created_at) }}</td>
+                    <td class="{{ !$record->is_active ? 'text-warning-dark' : ''}}">{{ $record->is_active ? 'Yes' : 'No' }}</td>
+                    <td>
+                        <div class="d-flex flex-wrap">
+                            @if($record->is_active)
+                                <div moe class="mr-2">
+                                    <a href="" start show>Deactivate</a>
+                                    <form url="/api/customer/deactivate" class="mcp-theme-1" right>
+                                        <p class="mb-2 text-nowrap">Deactivate this customer?</p>
+                                        <input type="hidden" name="uid" value="{{$record->uid}}">
+                                        <div>
+                                            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                        </div>
+                                    </form>
+                                </div>
+                            @else
+                                <div moe class="mr-2">
+                                    <a href="" start show>Reactivate</a>
+                                    <form url="/api/customer/reactivate" class="mcp-theme-1" right>
+                                        <p class="mb-2 text-nowrap">Reactivate this customer?</p>
+                                        <input type="hidden" name="uid" value="{{$record->uid}}">
+                                        <div>
+                                            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                        </div>
+                                    </form>
+                                </div>
+                            @endif
+                            <a href="{{route('patients.view.invoicing-customer-transactions', ['patient' => $patient, 'customer' => $record])}}" class="mr-2">Transactions</a>
+                            <a href="{{route('patients.view.invoicing-invoices', ['patient' => $patient, 'customer' => $record])}}">Invoices</a>
+                        </div>
+                    </td>
+                </tr>
+            @endforeach
+            </tbody>
+        </table>
+    @endif
+@endsection

+ 97 - 0
resources/views/app/patient/invoicing/customer-transactions.blade.php

@@ -0,0 +1,97 @@
+@extends ('app.patient.invoicing.layout')
+@section('invoicing-content')
+    <div class="d-flex align-items-baseline pb-3">
+        <a href="{{route('patients.view.invoicing-companies', ['patient' => $patient])}}" class="mr-2"><i class="fa fa-chevron-left mr-1"></i> Back</a>
+        <h4 class="font-weight-bold m-0 font-size-16">{{$customer->company->name}} <i class="fa fa-chevron-right text-sm text-secondary mx-1"></i> Customer Transactions</h4>
+        <span class="text-secondary mx-2">|</span>
+        <div moe class="">
+            <a href="" start show class="font-weight-bold">
+                + Add Manual Plus
+            </a>
+            <form url="/api/customerTransaction/createManualPlus" class="mcp-theme-1">
+                <input type="hidden" name="customerUid" value="{{@$customer->uid}}">
+                <p class="mb-2 text-secondary font-weight-bold text-nowrap">Add Manual Plus</p>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Amount</label>
+                    <input type="text"
+                           name="amount"
+                           autocomplete="off"
+                           class="form-control form-control-sm"
+                           required>
+                </div>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Memo</label>
+                    <textarea rows="2"
+                              name="customMemo"
+                              autocomplete="off"
+                              class="form-control form-control-sm"></textarea>
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
+        </div>
+        <span class="text-secondary mx-2">|</span>
+        <div moe class="">
+            <a href="" start show class="font-weight-bold">
+                + Add Manual Minus
+            </a>
+            <form url="/api/customerTransaction/createManualMinus" class="mcp-theme-1">
+                <input type="hidden" name="customerUid" value="{{@$customer->uid}}">
+                <p class="mb-2 text-secondary font-weight-bold text-nowrap">Add Manual Minus</p>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Amount</label>
+                    <input type="text"
+                           name="amount"
+                           autocomplete="off"
+                           class="form-control form-control-sm"
+                           required>
+                </div>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Memo</label>
+                    <textarea rows="2"
+                              name="customMemo"
+                              autocomplete="off"
+                              class="form-control form-control-sm"></textarea>
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
+        </div>
+    </div>
+    @if(!count($customer->customerTransactions))
+        <div class="border p-2">This customer does not have any customer transactions yet.</div>
+    @else
+        <table class="table table-sm table-bordered table-striped">
+            <thead>
+            <tr>
+                <th class="border-bottom-0">Created <span class="font-weight-normal text-secondary text-sm">(newest first)</span></th>
+                <th class="border-bottom-0">Plus / Minus</th>
+                <th class="border-bottom-0">Amount</th>
+                <th class="border-bottom-0">Memo</th>
+                <th class="border-bottom-0">Type</th>
+                <th class="border-bottom-0">Starting<br>Balance</th>
+                <th class="border-bottom-0">Resulting<br>Balance</th>
+                <th class="border-bottom-0 w-50"></th>
+            </tr>
+            </thead>
+            <tbody>
+            @foreach($customer->customerTransactions as $record)
+                <tr>
+                    <td>{{ friendly_date_time_with_seconds($record->created_at) }}</td>
+                    <td>{{ sanitize_state_name($record->plus_or_minus) }}</td>
+                    <td>${{ is_null($record->amount) ? 0 : $record->amount }}</td>
+                    <td>{{ $record->custom_memo ?: '' }}</td>
+                    <td>{{ sanitize_state_name($record->reason_type)}}</td>
+                    <td>${{ is_null($record->starting_balance) ? 0 : $record->starting_balance }}</td>
+                    <td>${{ is_null($record->resulting_balance) ? 0 : $record->resulting_balance }}</td>
+                    <td></td>
+                </tr>
+            @endforeach
+            </tbody>
+        </table>
+    @endif
+@endsection

+ 150 - 0
resources/views/app/patient/invoicing/invoice-transactions.blade.php

@@ -0,0 +1,150 @@
+@extends ('app.patient.invoicing.layout')
+@section('invoicing-content')
+    <div class="d-flex align-items-baseline pb-3">
+        <a href="{{route('patients.view.invoicing-invoices', ['patient' => $patient, 'customer' => $customer])}}" class="mr-2"><i class="fa fa-chevron-left mr-1"></i> Back</a>
+        <h4 class="font-weight-bold m-0 font-size-16">{{$customer->company->name}} <i class="fa fa-chevron-right text-sm text-secondary mx-1"></i> Invoice Transactions</h4>
+        <span class="text-secondary mx-2">|</span>
+        <div moe class="">
+            <a href="" start show class="font-weight-bold">
+                + Add Manual Plus
+            </a>
+            <form url="/api/invoiceTransaction/createManualPlus" class="mcp-theme-1">
+                <p class="mb-2 text-secondary font-weight-bold text-nowrap">Add Manual Plus</p>
+                <input type="hidden" name="invoiceUid" value="{{$invoice->uid}}">
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Amount</label>
+                    <input type="text"
+                           name="amount"
+                           autocomplete="off"
+                           class="form-control form-control-sm"
+                           required>
+                </div>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Memo</label>
+                    <textarea rows="2"
+                              name="customMemo"
+                              autocomplete="off"
+                              class="form-control form-control-sm"></textarea>
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
+        </div>
+        <span class="text-secondary mx-2">|</span>
+        <div moe class="">
+            <a href="" start show class="font-weight-bold">
+                + Add Manual Minus
+            </a>
+            <form url="/api/invoiceTransaction/createManualMinus" class="mcp-theme-1">
+                <p class="mb-2 text-secondary font-weight-bold text-nowrap">Add Manual Minus</p>
+                <input type="hidden" name="invoiceUid" value="{{$invoice->uid}}">
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Amount</label>
+                    <input type="text"
+                           name="amount"
+                           autocomplete="off"
+                           class="form-control form-control-sm"
+                           required>
+                </div>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Memo</label>
+                    <textarea rows="2"
+                              name="customMemo"
+                              autocomplete="off"
+                              class="form-control form-control-sm"></textarea>
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
+        </div>
+    </div>
+    @if(!count($invoice->invoiceTransactions))
+        <div class="border p-2 mb-3 font-weight-bold">This invoice does not have any transactions yet.</div>
+    @else
+        <table class="table table-sm table-bordered table-striped mb-3">
+            <thead>
+            <tr>
+                <th class="border-bottom-0">Created</th>
+                <th class="border-bottom-0">Plus / Minus</th>
+                <th class="border-bottom-0">Amount</th>
+                <th class="border-bottom-0">Memo</th>
+                <th class="border-bottom-0">Starting<br>Balance</th>
+                <th class="border-bottom-0">Resulting<br>Balance</th>
+                <th class="border-bottom-0 w-50"></th>
+            </tr>
+            </thead>
+            <tbody>
+            @foreach($invoice->invoiceTransactions as $record)
+                <tr>
+                    <td>{{ friendly_date_time_with_seconds($record->created_at) }}</td>
+                    <td>{{ sanitize_state_name($record->plus_or_minus) }}</td>
+                    <td>${{ is_null($record->amount) ? 0 : $record->amount }}</td>
+                    <td>{{ $record->custom_memo ?: '' }}</td>
+                    <td>${{ is_null($record->starting_balance) ? 0 : $record->starting_balance }}</td>
+                    <td>${{ is_null($record->resulting_balance) ? 0 : $record->resulting_balance }}</td>
+                    <td></td>
+                </tr>
+            @endforeach
+            </tbody>
+        </table>
+    @endif
+    <div class="mb-2 border p-2 bg-aliceblue">
+        <div class="d-flex align-items-baseline">
+            <div class="mb-2 text-secondary font-weight-bold">Invoice Details</div>
+            <!--<span class="mx-2 text-secondary">|</span>
+            <a href="#" data-invoice-uid="{{$invoice->uid}}" data-uid="{{$invoice->customer->uid}}" class="generate-and-visit-ic-pay" native target="_blank">Visit Pay Link</a>-->
+            <span class="mx-2 text-secondary">|</span>
+            <a href="#" data-invoice-uid="{{$invoice->uid}}" data-uid="{{$invoice->customer->uid}}" class="generate-and-copy-ic-pay-url" native target="_blank">Copy Pay Link</a>
+        </div>
+        <table class="table table-sm table-bordered bg-white mb-0">
+            <thead>
+            <tr>
+                <th class="border-bottom-0 text-secondary bg-light">Date</th>
+                <th class="border-bottom-0 text-secondary bg-light">Company</th>
+                <th class="border-bottom-0 text-secondary bg-light">Particulars</th>
+                <th class="border-bottom-0 text-secondary bg-light">Total</th>
+                <th class="border-bottom-0 text-secondary bg-light">Paid</th>
+                <th class="border-bottom-0 text-secondary bg-light">Due</th>
+                <th class="border-bottom-0 text-secondary bg-light w-50"></th>
+            </tr>
+            </thead>
+            <tbody class="font-weight-normal">
+            <tr>
+                <td>{{friendly_date($invoice->created_at)}}</td>
+                <td>{{$customer->company->name}}</td>
+                <td>{{$invoice->description}}</td>
+                <td class="font-weight-bold text-dark">${{!is_null($invoice->amount) ? $invoice->amount : 0}}</td>
+                <td class="font-weight-bold text-success">${{!is_null($invoice->paid) ? $invoice->paid : 0}}</td>
+                <td class="font-weight-bold text-warning-dark">${{!is_null($invoice->balance) ? $invoice->balance : 0}}</td>
+                <td></td>
+            </tr>
+            <tr>
+                <td class="p-2 text-right" colspan="7">
+                    <div class="d-flex justify-content-start align-items-baseline mb-1">
+                        <span class="text-secondary">Total Amount: </span>
+                        <span class="width-50px text-left text-secondary font-weight-bold pl-2">${{!is_null($invoice->amount) ? $invoice->amount : 0}}</span>
+                    </div>
+                    <div class="d-flex justify-content-start align-items-baseline mb-1">
+                        <span class="text-secondary">Total Paid: </span>
+                        <span class="width-50px text-left text-secondary font-weight-bold pl-2">${{!is_null($invoice->paid) ? $invoice->paid : 0}}</span>
+                    </div>
+                    <div class="d-flex justify-content-start align-items-baseline">
+                        <span class="font-weight-bold text-secondary">Total Due: </span>
+                        <span class="width-50px text-left font-weight-bold pl-2 font-size-14">${{!is_null($invoice->balance) ? $invoice->balance : 0}}</span>
+                    </div>
+                    @if($invoice->balance <= 0)
+                        <div class="text-left font-weight-bold mt-1">
+                            <i class="fa fa-check text-success"></i>
+                            <span class="text-success">PAID</span>
+                        </div>
+                    @endif
+                </td>
+            </tr>
+            </tbody>
+        </table>
+    </div>
+@endsection

+ 159 - 0
resources/views/app/patient/invoicing/invoices.blade.php

@@ -0,0 +1,159 @@
+@extends ('app.patient.invoicing.layout')
+@section('invoicing-content')
+    <div class="d-flex align-items-baseline pb-3">
+        <a href="{{route('patients.view.invoicing-companies', ['patient' => $patient])}}" class="mr-2"><i class="fa fa-chevron-left mr-1"></i> Back</a>
+        <h4 class="font-weight-bold m-0 font-size-16">{{$customer->company->name}} <i class="fa fa-chevron-right text-sm text-secondary mx-1"></i> Invoices</h4>
+        <span class="text-secondary mx-2">|</span>
+        <div moe>
+            <a href="" start show class="font-weight-bold">
+                + Add
+            </a>
+            <form url="/api/invoice/create" class="mcp-theme-1">
+                <input type="hidden" name="customerUid" value="{{$customer->uid}}">
+                <p class="mb-2 text-secondary font-weight-bold">Add Invoice</p>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Amount</label>
+                    <input type="text"
+                           name="amount"
+                           autocomplete="off"
+                           class="form-control form-control-sm"
+                           required>
+                </div>
+                <div class="mb-2">
+                    <label class="text-sm text-secondary mb-1">Description</label>
+                    <textarea rows="2"
+                              name="description"
+                              autocomplete="off"
+                              class="form-control form-control-sm" required></textarea>
+                </div>
+                <div>
+                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                </div>
+            </form>
+        </div>
+    </div>
+    @if(!count($customer->invoices))
+        <div class="border p-2">This patient does not have any invoices from {{$customer->company->name}} yet.</div>
+    @else
+        <table class="table table-sm table-bordered table-striped">
+            <thead>
+            <tr>
+                <th class="border-bottom-0"></th>
+                <th class="border-bottom-0">Created</th>
+                <th class="border-bottom-0">Amount</th>
+                <th class="border-bottom-0">Description</th>
+                <th class="border-bottom-0">Context</th>
+                <th class="border-bottom-0">Pay Link</th>
+                <th class="border-bottom-0">Paid</th>
+                <th class="border-bottom-0">Balance</th>
+                <th class="border-bottom-0">Active?</th>
+                <th class="border-bottom-0"></th>
+            </tr>
+            </thead>
+            <tbody>
+            <?php $i = 1; ?>
+            @foreach($customer->invoices as $record)
+                <tr>
+                    <td>{{ $i++ }}</td>
+                    <td>{{ friendly_date($record->created_at) }}</td>
+                    <td>${{ is_null($record->amount) ? 0 : $record->amount }}
+                        <div moe relative class="ml-1">
+                            <a href="#" start show><i class="fa fa-edit on-hover-opaque"></i></a>
+                            <form url="/api/invoice/changeAmount">
+                                <input type="hidden" name="invoiceUid" value="{{$record->uid}}">
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Amount</label>
+                                    <input type="text"
+                                           name="amount"
+                                           autocomplete="off"
+                                           class="form-control form-control-sm"
+                                           value="{{$record->amount}}"
+                                           required>
+                                </div>
+                                <div>
+                                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                </div>
+                            </form>
+                        </div>
+                    </td>
+                    <td>{{ $record->description ?: '' }}
+                        <div moe relative class="ml-1">
+                            <a href="#" start show><i class="fa fa-edit on-hover-opaque"></i></a>
+                            <form url="/api/invoice/changeDescription">
+                                <input type="hidden" name="invoiceUid" value="{{$record->uid}}">
+                                <div class="mb-2">
+                                    <label class="text-sm text-secondary mb-1">Description</label>
+                                    <textarea rows="2"
+                                              name="description"
+                                              autocomplete="off"
+                                              class="form-control form-control-sm" required>{{$record->description}}</textarea>
+                                </div>
+                                <div>
+                                    <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                    <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                </div>
+                            </form>
+                        </div>
+                    </td>
+                    <td>
+                        @if($record->note_id || $record->care_month_id)
+                            @if($record->note_id)
+                                <?php $note = \App\Models\Note::where('id', $record->note_id)->first(); ?>
+                                <a href="{{ route('patients.view.notes.view.dashboard', ['patient' => $note->client, 'note' => $note]) }}">
+                                    Note
+                                </a>
+                            @else
+                                <?php $careMonth = \App\Models\CareMonth::where('id', $record->care_month_id)->first(); ?>
+                                <a href="{{route('patients.view.care-months.view.dashboard', ['patient' => $careMonth->client, 'careMonth' => $careMonth])}}">
+                                    Care Month
+                                </a>
+                            @endif
+                        @else
+                            -
+                        @endif
+                    </td>
+                    <td>
+                        <a href="#" data-invoice-uid="{{$record->uid}}" data-uid="{{$record->customer->uid}}" class="generate-and-visit-ic-pay" native target="_blank">Visit</a>
+                        <a href="#" data-invoice-uid="{{$record->uid}}" data-uid="{{$record->customer->uid}}" class="generate-and-copy-ic-pay-url ml-1" native target="_blank">Copy</a>
+                    </td>
+                    <td>${{ is_null($record->paid) ? 0 : $record->paid }}</td>
+                    <td>${{ is_null($record->balance) ? 0 : $record->balance }}</td>
+                    <td class="{{ !$record->is_active ? 'text-warning-dark' : ''}}">{{ $record->is_active ? 'Yes' : 'No' }}</td>
+                    <td>
+                        <div class="d-flex flex-wrap">
+                            @if($record->is_active)
+                                <div moe class="mr-2">
+                                    <a href="" start show>Deactivate</a>
+                                    <form url="/api/invoice/deactivate" class="mcp-theme-1" right>
+                                        <p class="mb-2 text-nowrap">Deactivate this invoice?</p>
+                                        <input type="hidden" name="uid" value="{{$record->uid}}">
+                                        <div>
+                                            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                        </div>
+                                    </form>
+                                </div>
+                            @else
+                                <div moe class="mr-2">
+                                    <a href="" start show>Reactivate</a>
+                                    <form url="/api/invoice/reactivate" class="mcp-theme-1" right>
+                                        <p class="mb-2 text-nowrap">Reactivate this invoice?</p>
+                                        <input type="hidden" name="uid" value="{{$record->uid}}">
+                                        <div>
+                                            <button submit class="btn btn-sm btn-primary mr-2">Submit</button>
+                                            <button cancel class="btn btn-sm btn-default border">Cancel</button>
+                                        </div>
+                                    </form>
+                                </div>
+                            @endif
+                            <a href="{{route('patients.view.invoicing-invoice-transactions', ['patient' => $patient, 'invoice' => $record])}}" class="mr-2">Transactions</a>
+                        </div>
+                    </td>
+                </tr>
+            @endforeach
+            </tbody>
+        </table>
+    @endif
+@endsection

+ 84 - 0
resources/views/app/patient/invoicing/layout.blade.php

@@ -0,0 +1,84 @@
+@extends ('layouts.patient')
+@section('inner-content')
+<div id="invoicing-{{$patient->uid}}">
+    @yield('invoicing-content')
+</div>
+<script>
+    (function () {
+        function init() {
+            initStagSuggest();
+            let parentSegment = $('body');
+            parentSegment.find('input[stag-suggest][target-key][target-field]')
+                .off('stag-suggest-selected')
+                .on('stag-suggest-selected', (_e, _input, _data) => {
+                    _input = $(_input);
+                    _input.closest('form').find('input[name="' + _input.attr('target-field') + '"]').val(_data[_input.attr('target-key')]);
+                });
+            parentSegment.find('.copy-target')
+                .off('click.copy-target')
+                .on('click.copy-target', function() {
+                    copyTextToClipboard($(this).attr('data-target'));
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-visit-ic-portal')
+                .off('click.generate-and-visit-ic-portal')
+                .on('click.generate-and-visit-ic-portal', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            window.location.href = '/ic/home/' + _data.data;
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-copy-ic-portal-url')
+                .off('click.generate-and-copy-ic-portal-url')
+                .on('click.generate-and-copy-ic-portal-url', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            copyTextToClipboard('{{config('app.url')}}/ic/home/' + _data.data);
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-visit-ic-pay')
+                .off('click.generate-and-visit-ic-pay')
+                .on('click.generate-and-visit-ic-pay', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            window.location.href = '/ic/pay/' + $(this).attr('data-invoice-uid') + '/' + _data.data;
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+
+            parentSegment.find('.generate-and-copy-ic-pay-url')
+                .off('click.generate-and-copy-ic-pay-url')
+                .on('click.generate-and-copy-ic-pay-url', function() {
+                    $.post('/api/session/proLogInAsCustomer', {
+                        customerUid: $(this).attr('data-uid')
+                    }, _data => {
+                        if(!hasResponseError(_data)) {
+                            copyTextToClipboard('{{config('app.url')}}/ic/pay/' + $(this).attr('data-invoice-uid') + '/' + _data.data);
+                            return false;
+                        }
+                    });
+                    return false;
+                });
+        }
+        addMCInitializer('invoicing-{{$patient->uid}}', init, '#invoicing-{{$patient->uid}}')
+    }).call(window);
+</script>
+@endsection
+

+ 3 - 0
resources/views/app/patient/note/lhs-tree.blade.php

@@ -68,6 +68,9 @@
         @if($pro->pro_type === 'ADMIN' || ($note->allyPro && $pro->id === $note->allyPro->id))
             <div class="note-tree-node"><a native="" target="_top" data-non-segment-target="NA Bills" href="#">NA Bills</a></div>
         @endif
+        @if($pro->pro_type === 'ADMIN')
+            <div class="note-tree-node"><a native="" target="_top" data-non-segment-target="Invoices" href="#">Invoices</a></div>
+        @endif
         <div class="note-tree-node"><a native="" target="_top" data-non-segment-target="Claims" href="#">Claims</a></div>
     @endif
     @if($note->is_signed_by_hcp)

+ 8 - 1
resources/views/app/patient/note/partials/cpp-bills-claims-container.blade.php

@@ -810,7 +810,14 @@
     {{-- generic bills --}}
     @if($pro->pro_type === 'ADMIN' || ($note->allyPro && $pro->id === $note->allyPro->id))
         <div class="screen-only" data-non-segment-section="NA Bills">
-        @include('app.generic-bills.inline', ['patient' => $patient, 'note' => $note, 'class' => 'p-3 border-bottom', 'label' => 'NA', 'entityType' => 'Note', 'entityUid' => $note->uid])
+            @include('app.generic-bills.inline', ['patient' => $patient, 'note' => $note, 'class' => 'p-3 border-bottom', 'label' => 'NA', 'entityType' => 'Note', 'entityUid' => $note->uid])
+        </div>
+    @endif
+
+    {{-- invoices --}}
+    @if($pro->pro_type === 'ADMIN')
+        <div class="screen-only p-3 border-bottom" data-non-segment-section="Invoices">
+            @include('app.generic-invoices.index', ['patient' => $patient, 'parentType' => 'Note', 'parentID' => $note->id, 'parentUid' => $note->uid])
         </div>
     @endif
 

+ 58 - 2
resources/views/layouts/invoice-center.blade.php

@@ -16,7 +16,7 @@ $routeName = request()->route()->getName();
 						<a class="nav-link {{ strpos($routeName, 'invoice-center.customers') === 0 ? 'active' : '' }}" href="{{ route('invoice-center.customers') }}">Customers</a>
 					</li>
 					<li class="nav-item">
-						<a class="nav-link {{ strpos($routeName, 'invoice-center.giftCards') === 0 ? 'active' : '' }}" href="{{ route('invoice-center.giftCards') }}">Gift Cards</a>
+						<a class="nav-link {{ strpos($routeName, 'invoice-center.giftCards') === 0 ? 'active' : '' }}" href="{{ route('invoice-center.giftCards') }}">Vouchers</a>
 					</li>
 					<li class="nav-item">
 						<a class="nav-link {{ strpos($routeName, 'invoice-center.invoices') === 0 ? 'active' : '' }}" href="{{ route('invoice-center.invoices') }}">Invoices</a>
@@ -54,8 +54,64 @@ $routeName = request()->route()->getName();
 						copyTextToClipboard($(this).attr('data-target'));
 						return false;
 					});
+
+			parentSegment.find('.generate-and-visit-ic-portal')
+					.off('click.generate-and-visit-ic-portal')
+					.on('click.generate-and-visit-ic-portal', function() {
+						$.post('/api/session/proLogInAsCustomer', {
+							customerUid: $(this).attr('data-uid')
+						}, _data => {
+							if(!hasResponseError(_data)) {
+								window.location.href = '/ic/home/' + _data.data;
+								return false;
+							}
+						});
+						return false;
+					});
+
+			parentSegment.find('.generate-and-copy-ic-portal-url')
+					.off('click.generate-and-copy-ic-portal-url')
+					.on('click.generate-and-copy-ic-portal-url', function() {
+						$.post('/api/session/proLogInAsCustomer', {
+							customerUid: $(this).attr('data-uid')
+						}, _data => {
+							if(!hasResponseError(_data)) {
+								copyTextToClipboard('{{config('app.url')}}/ic/home/' + _data.data);
+								return false;
+							}
+						});
+						return false;
+					});
+
+			parentSegment.find('.generate-and-visit-ic-pay')
+					.off('click.generate-and-visit-ic-pay')
+					.on('click.generate-and-visit-ic-pay', function() {
+						$.post('/api/session/proLogInAsCustomer', {
+							customerUid: $(this).attr('data-uid')
+						}, _data => {
+							if(!hasResponseError(_data)) {
+								window.location.href = '/ic/pay/' + $(this).attr('data-invoice-uid') + '/' + _data.data;
+								return false;
+							}
+						});
+						return false;
+					});
+
+			parentSegment.find('.generate-and-copy-ic-pay-url')
+					.off('click.generate-and-copy-ic-pay-url')
+					.on('click.generate-and-copy-ic-pay-url', function() {
+						$.post('/api/session/proLogInAsCustomer', {
+							customerUid: $(this).attr('data-uid')
+						}, _data => {
+							if(!hasResponseError(_data)) {
+								copyTextToClipboard('{{config('app.url')}}/ic/pay/' + $(this).attr('data-invoice-uid') + '/' + _data.data);
+								return false;
+							}
+						});
+						return false;
+					});
 		}
-		addMCInitializer('invoice-center', init)
+		addMCInitializer('invoice-center', init, '#invoice-center')
 	}).call(window);
 </script>
 @endsection

+ 10 - 0
resources/views/layouts/patient-header.blade.php

@@ -110,6 +110,16 @@ $addressParts .= implode(", ", $addressPart2);
                                 Created on <b>{{friendly_date_time($patient->created_at)}}</b>
                             </div>
                         @endif
+                        <?php $latestMemo = $patient->latestMemo(); ?>
+                        @if($latestMemo)
+                            <hr class="my-2">
+                            <p class="mb-1 font-weight-bold text-secondary">Last Memo: {{$latestMemo->category}}</p>
+                            <div class="text-wrap mb-1">{{$latestMemo->content}}</div>
+                            <div class="text-secondary text-sm mb-1">{{friendly_date_time($latestMemo->created_at)}}</div>
+                            @if($latestMemo->createdBy && $latestMemo->createdBy->pro)
+                                <div class="text-secondary text-sm">By {{$latestMemo->createdBy->pro->displayName()}}</div>
+                            @endif
+                        @endif
                     </div>
                 </div>
             </h6>

+ 7 - 0
resources/views/layouts/patient.blade.php

@@ -38,6 +38,13 @@ $isOldClient = (date_diff(date_create(config('app.point_impl_date')), date_creat
 							<a class="nav-link {{ strpos($routeName, 'patients.view.calendar') === 0 ? 'active' : '' }}" href="{{ route('patients.view.calendar', ['patient' => $patient]) }}">Calendar</a>
 						@endif
 					</li>
+
+					@if($pro->pro_type === 'ADMIN')
+						<li class="nav-item">
+							<a class="nav-link {{ strpos($routeName, 'patients.view.invoicing-') === 0 ? 'active' : '' }}" href="{{ route('patients.view.invoicing-companies', ['patient' => $patient]) }}" title="Deprecated">Invoicing</a>
+						</li>
+					@endif
+
 					<li class="nav-item">
 						<a class="nav-link {{ strpos($routeName, 'patients.view.appointments') === 0 ? 'active' : '' }}" href="{{ route('patients.view.appointments', ['patient' => $patient, 'forPro' => 'all', 'status' => 'all']) }}">Appointments</a>
 					</li>

+ 9 - 3
routes/web.php

@@ -588,6 +588,12 @@ Route::middleware('pro.auth')->group(function () {
             // tickets (old/deprecated)
             Route::get('tickets/{type?}/{currentTicket?}', 'PatientController@tickets')->name('patient-tickets');
 
+            // invoicing
+            Route::get('invoicing/companies', 'PatientController@invoicingCompanies')->name('invoicing-companies');
+            Route::get('invoicing/invoices/{customer}', 'PatientController@invoicingInvoices')->name('invoicing-invoices');
+            Route::get('invoicing/customer-transactions/{customer}', 'PatientController@invoicingCustomerTransactions')->name('invoicing-customer-transactions');
+            Route::get('invoicing/invoice-transactions/{invoice}', 'PatientController@invoicingInvoiceTransactions')->name('invoicing-invoice-transactions');
+
             // prescriptions (new)
             Route::get('prescriptions/{type?}/{currentErx?}', 'PatientController@prescriptions')->name('patient-prescriptions');
             Route::get('prescriptions-popup/{type?}/{currentErx?}', 'PatientController@prescriptionsPopup')->name('patient-prescriptions-popup');
@@ -782,6 +788,6 @@ Route::any("/nop", 'HomeController@nop')->name('nop');
 Route::get('/document-pdf/{uid}', 'DocumentsController@generateDocumentPDF')->name('generateDocumentPDF');
 
 // ic pages - client facing
-Route::get('/ic/home/{customerSlug}', 'InvoiceController@icCustomerPortal')->name('icCustomerPortal');
-Route::get('/ic/pay/{invoiceSlug}', 'InvoiceController@icPayInvoice')->name('icPayInvoice');
-Route::get('/ic/manageAccount/{customerSlug}', 'InvoiceController@icManageAccount')->name('icManageAccount');
+Route::get('/ic/home/{sessionKey?}', 'InvoiceController@icCustomerPortal')->name('icCustomerPortal');
+Route::get('/ic/pay/{invoiceUid}/{sessionKey?}', 'InvoiceController@icPayInvoice')->name('icPayInvoice');
+Route::get('/ic/manageAccount/{sessionKey?}', 'InvoiceController@icManageAccount')->name('icManageAccount');